1
0
Fork 0

Change: Allow sprite resolver to evaluate non-existent houses.

This could previous be done but only with a town and tile in mind, but for drawing in the UI, neither of those exist yet.
pull/12684/head
Peter Nelson 2024-05-14 17:29:58 +01:00 committed by Peter Nelson
parent d99c1337a2
commit b731ab0632
2 changed files with 39 additions and 12 deletions

View File

@ -105,11 +105,14 @@ void ResetHouses()
*/ */
HouseResolverObject::HouseResolverObject(HouseID house_id, TileIndex tile, Town *town, HouseResolverObject::HouseResolverObject(HouseID house_id, TileIndex tile, Town *town,
CallbackID callback, uint32_t param1, uint32_t param2, CallbackID callback, uint32_t param1, uint32_t param2,
bool not_yet_constructed, uint8_t initial_random_bits, CargoTypes watched_cargo_triggers) bool not_yet_constructed, uint8_t initial_random_bits, CargoTypes watched_cargo_triggers, int view)
: ResolverObject(GetHouseSpecGrf(house_id), callback, param1, param2), : ResolverObject(GetHouseSpecGrf(house_id), callback, param1, param2),
house_scope(*this, house_id, tile, town, not_yet_constructed, initial_random_bits, watched_cargo_triggers), house_scope(*this, house_id, tile, town, not_yet_constructed, initial_random_bits, watched_cargo_triggers, view),
town_scope(*this, town, not_yet_constructed) // Don't access StorePSA if house is not yet constructed. town_scope(*this, town, not_yet_constructed) // Don't access StorePSA if house is not yet constructed.
{ {
/* Tile must be valid and a house tile, unless not yet constructed in which case it may also be INVALID_TILE. */
assert((IsValidTile(tile) && (not_yet_constructed || IsTileType(tile, MP_HOUSE))) || (not_yet_constructed && tile == INVALID_TILE));
this->root_spritegroup = HouseSpec::Get(house_id)->grf_prop.spritegroup[0]; this->root_spritegroup = HouseSpec::Get(house_id)->grf_prop.spritegroup[0];
} }
@ -210,14 +213,12 @@ void DecreaseBuildingCount(Town *t, HouseID house_id)
/* virtual */ uint32_t HouseScopeResolver::GetRandomBits() const /* virtual */ uint32_t HouseScopeResolver::GetRandomBits() const
{ {
/* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */ /* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */
assert(IsValidTile(this->tile) && (this->not_yet_constructed || IsTileType(this->tile, MP_HOUSE)));
return this->not_yet_constructed ? this->initial_random_bits : GetHouseRandomBits(this->tile); return this->not_yet_constructed ? this->initial_random_bits : GetHouseRandomBits(this->tile);
} }
/* virtual */ uint32_t HouseScopeResolver::GetTriggers() const /* virtual */ uint32_t HouseScopeResolver::GetTriggers() const
{ {
/* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */ /* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */
assert(IsValidTile(this->tile) && (this->not_yet_constructed || IsTileType(this->tile, MP_HOUSE)));
return this->not_yet_constructed ? 0 : GetHouseTriggers(this->tile); return this->not_yet_constructed ? 0 : GetHouseTriggers(this->tile);
} }
@ -362,6 +363,32 @@ static uint32_t GetDistanceFromNearbyHouse(uint8_t parameter, TileIndex tile, Ho
*/ */
/* virtual */ uint32_t HouseScopeResolver::GetVariable(uint8_t variable, [[maybe_unused]] uint32_t parameter, bool *available) const /* virtual */ uint32_t HouseScopeResolver::GetVariable(uint8_t variable, [[maybe_unused]] uint32_t parameter, bool *available) const
{ {
if (this->tile == INVALID_TILE) {
/* House does not yet exist, nor is it being planned to exist. Provide some default values intead. */
switch (variable) {
case 0x40: return TOWN_HOUSE_COMPLETED | this->view << 2; /* Construction stage. */
case 0x41: return 0;
case 0x42: return 0;
case 0x43: return 0;
case 0x44: return 0;
case 0x45: return _generating_world ? 1 : 0;
case 0x46: return 0;
case 0x47: return 0;
case 0x60: return 0;
case 0x61: return 0;
case 0x62: return 0;
case 0x63: return 0;
case 0x64: return 0;
case 0x65: return 0;
case 0x66: return 0xFFFFFFFF; /* Class and ID of nearby house. */
case 0x67: return 0;
}
Debug(grf, 1, "Unhandled house variable 0x{:X}", variable);
*available = false;
return UINT_MAX;
}
switch (variable) { switch (variable) {
/* Construction stage. */ /* Construction stage. */
case 0x40: return (IsTileType(this->tile, MP_HOUSE) ? GetHouseBuildingStage(this->tile) : 0) | TileHash2Bit(TileX(this->tile), TileY(this->tile)) << 2; case 0x40: return (IsTileType(this->tile, MP_HOUSE) ? GetHouseBuildingStage(this->tile) : 0) | TileHash2Bit(TileX(this->tile), TileY(this->tile)) << 2;
@ -481,12 +508,10 @@ static uint32_t GetDistanceFromNearbyHouse(uint8_t parameter, TileIndex tile, Ho
} }
uint16_t GetHouseCallback(CallbackID callback, uint32_t param1, uint32_t param2, HouseID house_id, Town *town, TileIndex tile, uint16_t GetHouseCallback(CallbackID callback, uint32_t param1, uint32_t param2, HouseID house_id, Town *town, TileIndex tile,
bool not_yet_constructed, uint8_t initial_random_bits, CargoTypes watched_cargo_triggers) bool not_yet_constructed, uint8_t initial_random_bits, CargoTypes watched_cargo_triggers, int view)
{ {
assert(IsValidTile(tile) && (not_yet_constructed || IsTileType(tile, MP_HOUSE)));
HouseResolverObject object(house_id, tile, town, callback, param1, param2, HouseResolverObject object(house_id, tile, town, callback, param1, param2,
not_yet_constructed, initial_random_bits, watched_cargo_triggers); not_yet_constructed, initial_random_bits, watched_cargo_triggers, view);
return object.ResolveCallback(); return object.ResolveCallback();
} }

View File

@ -24,6 +24,7 @@ struct HouseScopeResolver : public ScopeResolver {
bool not_yet_constructed; ///< True for construction check. bool not_yet_constructed; ///< True for construction check.
uint16_t initial_random_bits; ///< Random bits during construction checks. uint16_t initial_random_bits; ///< Random bits during construction checks.
CargoTypes watched_cargo_triggers; ///< Cargo types that triggered the watched cargo callback. CargoTypes watched_cargo_triggers; ///< Cargo types that triggered the watched cargo callback.
int view; ///< View when house does yet exist.
/** /**
* Constructor of a house scope resolver. * Constructor of a house scope resolver.
@ -36,9 +37,9 @@ struct HouseScopeResolver : public ScopeResolver {
* @param watched_cargo_triggers Cargo types that triggered the watched cargo callback. * @param watched_cargo_triggers Cargo types that triggered the watched cargo callback.
*/ */
HouseScopeResolver(ResolverObject &ro, HouseID house_id, TileIndex tile, Town *town, HouseScopeResolver(ResolverObject &ro, HouseID house_id, TileIndex tile, Town *town,
bool not_yet_constructed, uint8_t initial_random_bits, CargoTypes watched_cargo_triggers) bool not_yet_constructed, uint8_t initial_random_bits, CargoTypes watched_cargo_triggers, int view)
: ScopeResolver(ro), house_id(house_id), tile(tile), town(town), not_yet_constructed(not_yet_constructed), : ScopeResolver(ro), house_id(house_id), tile(tile), town(town), not_yet_constructed(not_yet_constructed),
initial_random_bits(initial_random_bits), watched_cargo_triggers(watched_cargo_triggers) initial_random_bits(initial_random_bits), watched_cargo_triggers(watched_cargo_triggers), view(view)
{ {
} }
@ -54,7 +55,7 @@ struct HouseResolverObject : public ResolverObject {
HouseResolverObject(HouseID house_id, TileIndex tile, Town *town, HouseResolverObject(HouseID house_id, TileIndex tile, Town *town,
CallbackID callback = CBID_NO_CALLBACK, uint32_t param1 = 0, uint32_t param2 = 0, CallbackID callback = CBID_NO_CALLBACK, uint32_t param1 = 0, uint32_t param2 = 0,
bool not_yet_constructed = false, uint8_t initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0); bool not_yet_constructed = false, uint8_t initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0, int view = 0);
ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, uint8_t relative = 0) override ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, uint8_t relative = 0) override
{ {
@ -94,13 +95,14 @@ void InitializeBuildingCounts();
void InitializeBuildingCounts(Town *t); void InitializeBuildingCounts(Town *t);
void IncreaseBuildingCount(Town *t, HouseID house_id); void IncreaseBuildingCount(Town *t, HouseID house_id);
void DecreaseBuildingCount(Town *t, HouseID house_id); void DecreaseBuildingCount(Town *t, HouseID house_id);
std::span<const uint> GetBuildingHouseIDCounts();
void DrawNewHouseTile(TileInfo *ti, HouseID house_id); void DrawNewHouseTile(TileInfo *ti, HouseID house_id);
void AnimateNewHouseTile(TileIndex tile); void AnimateNewHouseTile(TileIndex tile);
void AnimateNewHouseConstruction(TileIndex tile); void AnimateNewHouseConstruction(TileIndex tile);
uint16_t GetHouseCallback(CallbackID callback, uint32_t param1, uint32_t param2, HouseID house_id, Town *town, TileIndex tile, uint16_t GetHouseCallback(CallbackID callback, uint32_t param1, uint32_t param2, HouseID house_id, Town *town, TileIndex tile,
bool not_yet_constructed = false, uint8_t initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0); bool not_yet_constructed = false, uint8_t initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0, int view = 0);
void WatchedCargoCallback(TileIndex tile, CargoTypes trigger_cargoes); void WatchedCargoCallback(TileIndex tile, CargoTypes trigger_cargoes);
bool CanDeleteHouse(TileIndex tile); bool CanDeleteHouse(TileIndex tile);