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,
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),
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.
{
/* 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];
}
@ -210,14 +213,12 @@ void DecreaseBuildingCount(Town *t, HouseID house_id)
/* virtual */ uint32_t HouseScopeResolver::GetRandomBits() const
{
/* 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);
}
/* virtual */ uint32_t HouseScopeResolver::GetTriggers() const
{
/* 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);
}
@ -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
{
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) {
/* Construction stage. */
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,
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,
not_yet_constructed, initial_random_bits, watched_cargo_triggers);
not_yet_constructed, initial_random_bits, watched_cargo_triggers, view);
return object.ResolveCallback();
}

View File

@ -24,6 +24,7 @@ struct HouseScopeResolver : public ScopeResolver {
bool not_yet_constructed; ///< True for construction check.
uint16_t initial_random_bits; ///< Random bits during construction checks.
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.
@ -36,9 +37,9 @@ struct HouseScopeResolver : public ScopeResolver {
* @param watched_cargo_triggers Cargo types that triggered the watched cargo callback.
*/
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),
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,
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
{
@ -94,13 +95,14 @@ void InitializeBuildingCounts();
void InitializeBuildingCounts(Town *t);
void IncreaseBuildingCount(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 AnimateNewHouseTile(TileIndex tile);
void AnimateNewHouseConstruction(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);
bool CanDeleteHouse(TileIndex tile);