(svn r20942) -Feature [NewGRF]: make it possible to distinguish player built/randomly placed industries in the location and land slope check callbacks

This commit is contained in:
rubidium 2010-10-16 13:15:54 +00:00
parent a1b4f0b4c3
commit 0b67a7ccd5
5 changed files with 36 additions and 23 deletions

View File

@ -1312,10 +1312,11 @@ bool IsSlopeRefused(Slope current, Slope refused)
* @param type Type of the industry. * @param type Type of the industry.
* @param initial_random_bits The random bits the industry is going to have after construction. * @param initial_random_bits The random bits the industry is going to have after construction.
* @param founder Industry founder * @param founder Industry founder
* @param creation_type The circumstances the industry is created under.
* @param [out] custom_shape_check Perform custom check for the site. * @param [out] custom_shape_check Perform custom check for the site.
* @return Failed or succeeded command. * @return Failed or succeeded command.
*/ */
static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, uint itspec_index, int type, uint16 initial_random_bits, Owner founder, bool *custom_shape_check = NULL) static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, uint itspec_index, int type, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type, bool *custom_shape_check = NULL)
{ {
bool refused_slope = false; bool refused_slope = false;
bool custom_shape = false; bool custom_shape = false;
@ -1347,7 +1348,7 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil
if (HasBit(its->callback_mask, CBM_INDT_SHAPE_CHECK)) { if (HasBit(its->callback_mask, CBM_INDT_SHAPE_CHECK)) {
custom_shape = true; custom_shape = true;
CommandCost ret = PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index, initial_random_bits, founder); CommandCost ret = PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index, initial_random_bits, founder, creation_type);
if (ret.Failed()) return ret; if (ret.Failed()) return ret;
} else { } else {
Slope tileh = GetTileSlope(cur_tile, NULL); Slope tileh = GetTileSlope(cur_tile, NULL);
@ -1673,12 +1674,13 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
* @param seed random seed (possibly) used by industries * @param seed random seed (possibly) used by industries
* @param initial_random_bits The random bits the industry is going to have after construction. * @param initial_random_bits The random bits the industry is going to have after construction.
* @param founder Founder of the industry * @param founder Founder of the industry
* @param creation_type The circumstances the industry is created under.
* @param [out] ip Pointer to store newly created industry. * @param [out] ip Pointer to store newly created industry.
* @return Succeeded or failed command. * @return Succeeded or failed command.
* *
* @post \c *ip contains the newly created industry if all checks are successful and the \a flags request actual creation, else it contains \c NULL afterwards. * @post \c *ip contains the newly created industry if all checks are successful and the \a flags request actual creation, else it contains \c NULL afterwards.
*/ */
static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, DoCommandFlag flags, const IndustrySpec *indspec, uint itspec_index, uint32 random_var8f, uint16 random_initial_bits, Owner founder, Industry **ip) static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, DoCommandFlag flags, const IndustrySpec *indspec, uint itspec_index, uint32 random_var8f, uint16 random_initial_bits, Owner founder, IndustryAvailabilityCallType creation_type, Industry **ip)
{ {
assert(itspec_index < indspec->num_table); assert(itspec_index < indspec->num_table);
const IndustryTileTable *it = indspec->table[itspec_index]; const IndustryTileTable *it = indspec->table[itspec_index];
@ -1687,12 +1689,12 @@ static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, Do
*ip = NULL; *ip = NULL;
SmallVector<ClearedObjectArea, 1> object_areas(_cleared_object_areas); SmallVector<ClearedObjectArea, 1> object_areas(_cleared_object_areas);
CommandCost ret = CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, random_initial_bits, founder, &custom_shape_check); CommandCost ret = CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, random_initial_bits, founder, creation_type, &custom_shape_check);
_cleared_object_areas = object_areas; _cleared_object_areas = object_areas;
if (ret.Failed()) return ret; if (ret.Failed()) return ret;
if (HasBit(GetIndustrySpec(type)->callback_mask, CBM_IND_LOCATION)) { if (HasBit(GetIndustrySpec(type)->callback_mask, CBM_IND_LOCATION)) {
ret = CheckIfCallBackAllowsCreation(tile, type, itspec_index, random_var8f, random_initial_bits, founder); ret = CheckIfCallBackAllowsCreation(tile, type, itspec_index, random_var8f, random_initial_bits, founder, creation_type);
} else { } else {
ret = _check_new_industry_procs[indspec->check_proc](tile); ret = _check_new_industry_procs[indspec->check_proc](tile);
} }
@ -1775,7 +1777,7 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
* because parameter evaluation order is not guaranteed in the c++ standard * because parameter evaluation order is not guaranteed in the c++ standard
*/ */
tile = RandomTile(); tile = RandomTile();
CommandCost ret = CreateNewIndustryHelper(tile, it, flags, indspec, RandomRange(indspec->num_table), random_var8f, random_initial_bits, cur_company.GetOriginalValue(), &ind); CommandCost ret = CreateNewIndustryHelper(tile, it, flags, indspec, RandomRange(indspec->num_table), random_var8f, random_initial_bits, cur_company.GetOriginalValue(), IACT_PROSPECTCREATION, &ind);
if (ret.Succeeded()) break; if (ret.Succeeded()) break;
} }
} }
@ -1792,11 +1794,11 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
do { do {
if (--count < 0) return ret; if (--count < 0) return ret;
if (--num < 0) num = indspec->num_table - 1; if (--num < 0) num = indspec->num_table - 1;
ret = CheckIfIndustryTilesAreFree(tile, itt[num], num, it, random_initial_bits, _current_company); ret = CheckIfIndustryTilesAreFree(tile, itt[num], num, it, random_initial_bits, _current_company, IACT_USERCREATION);
_cleared_object_areas = object_areas; _cleared_object_areas = object_areas;
} while (ret.Failed()); } while (ret.Failed());
ret = CreateNewIndustryHelper(tile, it, flags, indspec, num, random_var8f, random_initial_bits, _current_company, &ind); ret = CreateNewIndustryHelper(tile, it, flags, indspec, num, random_var8f, random_initial_bits, _current_company, IACT_USERCREATION, &ind);
if (ret.Failed()) return ret; if (ret.Failed()) return ret;
} }
@ -1817,14 +1819,21 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
} }
static Industry *CreateNewIndustry(TileIndex tile, IndustryType type) /**
* Create a new industry of random layout.
* @param tile The location to build the industry.
* @param type The industry type to build.
* @param creation_type The circumstances the industry is created under.
* @return the created industry or NULL if it failed.
*/
static Industry *CreateNewIndustry(TileIndex tile, IndustryType type, IndustryAvailabilityCallType creation_type)
{ {
const IndustrySpec *indspec = GetIndustrySpec(type); const IndustrySpec *indspec = GetIndustrySpec(type);
uint32 seed = Random(); uint32 seed = Random();
uint32 seed2 = Random(); uint32 seed2 = Random();
Industry *i = NULL; Industry *i = NULL;
CommandCost ret = CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, RandomRange(indspec->num_table), seed, GB(seed2, 0, 16), OWNER_NONE, &i); CommandCost ret = CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, RandomRange(indspec->num_table), seed, GB(seed2, 0, 16), OWNER_NONE, creation_type, &i);
assert(i != NULL || ret.Failed()); assert(i != NULL || ret.Failed());
return i; return i;
} }
@ -1918,11 +1927,11 @@ static void AdvertiseIndustryOpening(Industry *ind)
* @param try_hard Try very hard to find a place. (Used to place at least one industry per type.) * @param try_hard Try very hard to find a place. (Used to place at least one industry per type.)
* @return Pointer to created industry, or \c NULL if creation failed. * @return Pointer to created industry, or \c NULL if creation failed.
*/ */
static Industry *PlaceIndustry(IndustryType type, bool try_hard) static Industry *PlaceIndustry(IndustryType type, IndustryAvailabilityCallType creation_type, bool try_hard)
{ {
uint tries = try_hard ? 10000u : 2000u; uint tries = try_hard ? 10000u : 2000u;
for (; tries > 0; tries--) { for (; tries > 0; tries--) {
Industry *ind = CreateNewIndustry(RandomTile(), type); Industry *ind = CreateNewIndustry(RandomTile(), type, creation_type);
if (ind != NULL) return ind; if (ind != NULL) return ind;
} }
return NULL; return NULL;
@ -1938,7 +1947,7 @@ static void PlaceInitialIndustry(IndustryType type, bool try_hard)
Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE); Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
IncreaseGeneratingWorldProgress(GWP_INDUSTRY); IncreaseGeneratingWorldProgress(GWP_INDUSTRY);
PlaceIndustry(type, try_hard); PlaceIndustry(type, IACT_MAPGENERATION, try_hard);
cur_company.Restore(); cur_company.Restore();
} }
@ -2070,7 +2079,7 @@ static void MaybeNewIndustry()
} }
/* try to create 2000 times this industry */ /* try to create 2000 times this industry */
Industry *ind = PlaceIndustry(cumulative_probs[j].ind, false); Industry *ind = PlaceIndustry(cumulative_probs[j].ind, IACT_RANDOMCREATION, false);
if (ind == NULL) return; if (ind == NULL) return;
AdvertiseIndustryOpening(ind); AdvertiseIndustryOpening(ind);

View File

@ -458,9 +458,10 @@ uint32 IndustryLocationGetVariable(const ResolverObject *object, byte variable,
* @param seed Seed for the random generator. * @param seed Seed for the random generator.
* @param initial_random_bits The random bits the industry is going to have after construction. * @param initial_random_bits The random bits the industry is going to have after construction.
* @param founder Industry founder * @param founder Industry founder
* @param creation_type The circumstances the industry is created under.
* @return Succeeded or failed command. * @return Succeeded or failed command.
*/ */
CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint layout, uint32 seed, uint16 initial_random_bits, Owner founder) CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint layout, uint32 seed, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type)
{ {
const IndustrySpec *indspec = GetIndustrySpec(type); const IndustrySpec *indspec = GetIndustrySpec(type);
@ -480,6 +481,7 @@ CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uin
NewIndustryResolver(&object, tile, &ind, type); NewIndustryResolver(&object, tile, &ind, type);
object.GetVariable = IndustryLocationGetVariable; object.GetVariable = IndustryLocationGetVariable;
object.callback = CBID_INDUSTRY_LOCATION; object.callback = CBID_INDUSTRY_LOCATION;
object.callback_param2 = creation_type;
_industry_creation_random_bits = seed; _industry_creation_random_bits = seed;
group = SpriteGroup::Resolve(GetIndustrySpec(type)->grf_prop.spritegroup[0], &object); group = SpriteGroup::Resolve(GetIndustrySpec(type)->grf_prop.spritegroup[0], &object);

View File

@ -31,6 +31,7 @@ enum IndustryAvailabilityCallType {
IACT_MAPGENERATION, ///< during random map generation IACT_MAPGENERATION, ///< during random map generation
IACT_RANDOMCREATION, ///< during creation of random ingame industry IACT_RANDOMCREATION, ///< during creation of random ingame industry
IACT_USERCREATION, ///< from the Fund/build window IACT_USERCREATION, ///< from the Fund/build window
IACT_PROSPECTCREATION, ///< from the Fund/build using prospecting
}; };
/* in newgrf_industry.cpp */ /* in newgrf_industry.cpp */
@ -38,7 +39,7 @@ uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte par
uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile); uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile);
uint32 GetIndustryIDAtOffset(TileIndex new_tile, const Industry *i, uint32 cur_grfid); uint32 GetIndustryIDAtOffset(TileIndex new_tile, const Industry *i, uint32 cur_grfid);
void IndustryProductionCallback(Industry *ind, int reason); void IndustryProductionCallback(Industry *ind, int reason);
CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint layout, uint32 seed, uint16 initial_random_bits, Owner founder); CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint layout, uint32 seed, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type);
bool CheckIfCallBackAllowsAvailability(IndustryType type, IndustryAvailabilityCallType creation_type); bool CheckIfCallBackAllowsAvailability(IndustryType type, IndustryAvailabilityCallType creation_type);
bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type); bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type);

View File

@ -258,9 +258,10 @@ extern bool IsSlopeRefused(Slope current, Slope refused);
* @param itspec_index Layout. * @param itspec_index Layout.
* @param initial_random_bits Random bits of industry after construction * @param initial_random_bits Random bits of industry after construction
* @param founder Industry founder * @param founder Industry founder
* @param creation_type The circumstances the industry is created under.
* @return Suceeded or failed command. * @return Suceeded or failed command.
*/ */
CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, uint itspec_index, uint16 initial_random_bits, Owner founder) CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, uint itspec_index, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type)
{ {
Industry ind; Industry ind;
ind.index = INVALID_INDUSTRY; ind.index = INVALID_INDUSTRY;
@ -270,7 +271,7 @@ CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind
ind.random = initial_random_bits; ind.random = initial_random_bits;
ind.founder = founder; ind.founder = founder;
uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, itspec_index, gfx, &ind, ind_tile); uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, creation_type << 8 | itspec_index, gfx, &ind, ind_tile);
if (callback_res == CALLBACK_FAILED) { if (callback_res == CALLBACK_FAILED) {
if (!IsSlopeRefused(GetTileSlope(ind_tile, NULL), its->slopes_refused)) return CommandCost(); if (!IsSlopeRefused(GetTileSlope(ind_tile, NULL), its->slopes_refused)) return CommandCost();
return_cmd_error(STR_ERROR_SITE_UNSUITABLE); return_cmd_error(STR_ERROR_SITE_UNSUITABLE);

View File

@ -20,7 +20,7 @@
bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const IndustryTileSpec *inds); bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const IndustryTileSpec *inds);
uint16 GetIndustryTileCallback(CallbackID callback, uint32 param1, uint32 param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile); uint16 GetIndustryTileCallback(CallbackID callback, uint32 param1, uint32 param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile);
CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, uint itspec_index, uint16 initial_random_bits, Owner founder); CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, uint itspec_index, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type);
void AnimateNewIndustryTile(TileIndex tile); void AnimateNewIndustryTile(TileIndex tile);
bool StartStopIndustryTileAnimation(TileIndex tile, IndustryAnimationTrigger iat, uint32 random = Random()); bool StartStopIndustryTileAnimation(TileIndex tile, IndustryAnimationTrigger iat, uint32 random = Random());