Merge branch 'house_placing' into jgrpp
# Conflicts: # src/settings_gui.cpp # src/settings_type.h # src/town_gui.cpp
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "newgrf_text.h"
|
||||
#include "newgrf_town.h"
|
||||
#include "newgrf_sound.h"
|
||||
#include "command_func.h"
|
||||
#include "company_func.h"
|
||||
#include "company_base.h"
|
||||
#include "town.h"
|
||||
@@ -25,6 +26,9 @@
|
||||
#include "newgrf_cargo.h"
|
||||
#include "station_base.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
@@ -34,17 +38,56 @@ static HouseClassMapping _class_mapping[HOUSE_CLASS_MAX];
|
||||
|
||||
HouseOverrideManager _house_mngr(NEW_HOUSE_OFFSET, NUM_HOUSES, INVALID_HOUSE_ID);
|
||||
|
||||
/** How a house is being placed. */
|
||||
enum TownExpansionBits {
|
||||
TEB_NONE = 0, ///< House is already placed or it's a GUI house, not placing currently.
|
||||
TEB_CREATING_TOWN = 1 << 0, ///< House is being placed while a town is being created.
|
||||
TEB_EXPANDING_TOWN = 1 << 1, ///< House is being placed while a town is expanding.
|
||||
TEB_PLACING_MANUALLY = 1 << 2, ///< House is being placed manually.
|
||||
};
|
||||
|
||||
static std::vector<uint32> _gui_house_cache;
|
||||
|
||||
void InitializeHouses()
|
||||
{
|
||||
_gui_house_cache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get animation frame for a GUI house.
|
||||
* @param house House to query.
|
||||
* @param variant House variant to get the frame for.
|
||||
* @param image_type House image type.
|
||||
* @return Animation frame to be used when drawing the house.
|
||||
*/
|
||||
static byte CacheGetGUIHouseAnimFrame(HouseID house, HouseVariant variant, HouseImageType image_type)
|
||||
{
|
||||
if (image_type == HIT_HOUSE_TILE) return 0;
|
||||
|
||||
if (!HasBit(HouseSpec::Get(house)->callback_mask, CBM_HOUSE_SETUP_VARIANT)) return 0;
|
||||
|
||||
uint32 key = house << 23 | variant << 15 | image_type << 13;
|
||||
std::vector<uint32>::iterator pos = std::lower_bound(_gui_house_cache.begin(), _gui_house_cache.end(), key);
|
||||
if (pos != _gui_house_cache.end() && ((*pos) & ~0xFF) == key) return (byte)*pos;
|
||||
|
||||
uint16 callback_result = GetHouseCallback(CBID_HOUSE_SETUP_VARIANT, 0, variant, house, NULL, INVALID_TILE, image_type, variant);
|
||||
byte frame = (callback_result < 0xFD) ? callback_result : 0;
|
||||
_gui_house_cache.insert(pos, key | frame);
|
||||
return frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor of a house scope resolver.
|
||||
* @param ro Surrounding resolver.
|
||||
* @param house_id House type being queried.
|
||||
* @param tile %Tile containing the house.
|
||||
* @param town %Town containing the house.
|
||||
* @param placing Whether the houe is being placed currently (house construction check or house variant setup).
|
||||
* @param not_yet_constructed House is still under construction.
|
||||
* @param initial_random_bits Random bits during construction checks.
|
||||
* @param watched_cargo_triggers Cargo types that triggered the watched cargo callback.
|
||||
*/
|
||||
HouseScopeResolver::HouseScopeResolver(ResolverObject &ro, HouseID house_id, TileIndex tile, Town *town,
|
||||
HouseScopeResolver::HouseScopeResolver(ResolverObject &ro, HouseID house_id, TileIndex tile, Town *town, bool placing,
|
||||
bool not_yet_constructed, uint8 initial_random_bits, uint32 watched_cargo_triggers)
|
||||
: ScopeResolver(ro)
|
||||
{
|
||||
@@ -68,14 +111,14 @@ static const GRFFile *GetHouseSpecGrf(HouseID house_id)
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a resolver for a house.
|
||||
* Construct a resolver for a house tile.
|
||||
* @param house_id House to query.
|
||||
* @param tile %Tile containing the house. INVALID_TILE to query a house type rather then a certian house tile.
|
||||
* @param town %Town containing the house.
|
||||
* @param tile %Tile containing the house. #INVALID_TILE to query a GUI house rather then a certain house tile.
|
||||
* @param town %Town containing the house. \c NULL if querying a GUI house.
|
||||
* @param callback Callback ID.
|
||||
* @param param1 First parameter (var 10) of the callback.
|
||||
* @param param2 Second parameter (var 18) of the callback.
|
||||
* @param not_yet_constructed House is still under construction.
|
||||
* @param not_yet_constructed House is still under construction (do not use for GUI houses).
|
||||
* @param initial_random_bits Random bits during construction checks.
|
||||
* @param watched_cargo_triggers Cargo types that triggered the watched cargo callback.
|
||||
*/
|
||||
@@ -84,17 +127,35 @@ HouseResolverObject::HouseResolverObject(HouseID house_id, TileIndex tile, Town
|
||||
bool not_yet_constructed, uint8 initial_random_bits, uint32 watched_cargo_triggers)
|
||||
: ResolverObject(GetHouseSpecGrf(house_id), callback, param1, param2)
|
||||
{
|
||||
assert((tile != INVALID_TILE) == (town != NULL));
|
||||
assert(tile == INVALID_TILE || (not_yet_constructed ? IsValidTile(tile) : GetHouseType(tile) == house_id && Town::GetByTile(tile) == town));
|
||||
assert(not_yet_constructed ? IsValidTile(tile) : IsTileType(tile, MP_HOUSE));
|
||||
|
||||
this->house_scope = (tile != INVALID_TILE) ?
|
||||
(ScopeResolver*)new HouseScopeResolver(*this, house_id, tile, town, not_yet_constructed, initial_random_bits, watched_cargo_triggers) :
|
||||
(ScopeResolver*)new FakeHouseScopeResolver(*this, house_id);
|
||||
this->house_scope = new HouseScopeResolver(*this, house_id, tile, town, not_yet_constructed || callback == CBID_HOUSE_SETUP_VARIANT, not_yet_constructed, initial_random_bits, watched_cargo_triggers);
|
||||
this->town_scope = new TownScopeResolver(*this, town, not_yet_constructed); // Don't access StorePSA if house is not yet constructed.
|
||||
this->root_spritegroup = HouseSpec::Get(house_id)->grf_prop.spritegroup[0];
|
||||
}
|
||||
|
||||
this->town_scope = (town != NULL) ?
|
||||
(ScopeResolver*)new TownScopeResolver(*this, town, not_yet_constructed) : // Don't access StorePSA if house is not yet constructed.
|
||||
(ScopeResolver*)new FakeTownScopeResolver(*this);
|
||||
/**
|
||||
* Construct a resolver for a GUI house.
|
||||
* @param house_id House to query.
|
||||
* @param variant House variant.
|
||||
* @param image_type House context.
|
||||
* @param callback Callback ID.
|
||||
* @param param1 First parameter (var 10) of the callback.
|
||||
* @param param2 Second parameter (var 18) of the callback.
|
||||
*/
|
||||
HouseResolverObject::HouseResolverObject(HouseID house_id, HouseVariant variant, HouseImageType image_type,
|
||||
CallbackID callback, uint32 param1, uint32 param2)
|
||||
: ResolverObject(GetHouseSpecGrf(house_id), callback, param1, param2)
|
||||
{
|
||||
assert(image_type != HIT_HOUSE_TILE);
|
||||
|
||||
byte anim_frame = 0;
|
||||
if (callback != CBID_HOUSE_SETUP_VARIANT) { // prevent endless recursion from CacheGetGUIHouseAnimFrame
|
||||
anim_frame = CacheGetGUIHouseAnimFrame(house_id, variant, image_type);
|
||||
}
|
||||
|
||||
this->house_scope = new FakeHouseScopeResolver(*this, house_id, image_type, anim_frame);
|
||||
this->town_scope = new FakeTownScopeResolver(*this);
|
||||
this->root_spritegroup = HouseSpec::Get(house_id)->grf_prop.spritegroup[0];
|
||||
}
|
||||
|
||||
@@ -330,6 +391,26 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32 GetHouseIDClassInfo(HouseID house, bool is_own_house)
|
||||
{
|
||||
const HouseSpec *hs = HouseSpec::Get(house);
|
||||
/* Information about the grf local classid if the house has a class */
|
||||
uint houseclass = 0;
|
||||
if (hs->class_id != HOUSE_NO_CLASS) {
|
||||
houseclass = (is_own_house ? 1 : 2) << 8;
|
||||
houseclass |= _class_mapping[hs->class_id].class_id;
|
||||
}
|
||||
/* old house type or grf-local houseid */
|
||||
uint local_houseid = 0;
|
||||
if (house < NEW_HOUSE_OFFSET) {
|
||||
local_houseid = house;
|
||||
} else {
|
||||
local_houseid = (is_own_house ? 1 : 2) << 8;
|
||||
local_houseid |= hs->grf_prop.local_id;
|
||||
}
|
||||
return houseclass << 16 | local_houseid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note Used by the resolver to get values for feature 07 deterministic spritegroups.
|
||||
*/
|
||||
@@ -351,8 +432,12 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI
|
||||
/* Number of this type of building on the map. */
|
||||
case 0x44: return GetNumHouses(this->house_id, this->town);
|
||||
|
||||
/* Whether the town is being created or just expanded. */
|
||||
case 0x45: return _generating_world ? 1 : 0;
|
||||
/* Whether the town is being created or just expanded and whether the house is being placed manually. */
|
||||
case 0x45:
|
||||
if (!this->placing) return TEB_NONE;
|
||||
if (_current_company != OWNER_TOWN) return TEB_PLACING_MANUALLY;
|
||||
if (_generating_world) return TEB_CREATING_TOWN;
|
||||
return TEB_EXPANDING_TOWN;
|
||||
|
||||
/* Current animation frame. */
|
||||
case 0x46: return IsTileType(this->tile, MP_HOUSE) ? GetAnimationFrame(this->tile) : 0;
|
||||
@@ -417,22 +502,8 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI
|
||||
case 0x66: {
|
||||
TileIndex testtile = GetNearbyTile(parameter, this->tile);
|
||||
if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF;
|
||||
HouseSpec *hs = HouseSpec::Get(GetHouseType(testtile));
|
||||
/* Information about the grf local classid if the house has a class */
|
||||
uint houseclass = 0;
|
||||
if (hs->class_id != HOUSE_NO_CLASS) {
|
||||
houseclass = (hs->grf_prop.grffile == this->ro.grffile ? 1 : 2) << 8;
|
||||
houseclass |= _class_mapping[hs->class_id].class_id;
|
||||
}
|
||||
/* old house type or grf-local houseid */
|
||||
uint local_houseid = 0;
|
||||
if (this->house_id < NEW_HOUSE_OFFSET) {
|
||||
local_houseid = this->house_id;
|
||||
} else {
|
||||
local_houseid = (hs->grf_prop.grffile == this->ro.grffile ? 1 : 2) << 8;
|
||||
local_houseid |= hs->grf_prop.local_id;
|
||||
}
|
||||
return houseclass << 16 | local_houseid;
|
||||
HouseID test_id = GetHouseType(testtile);
|
||||
return GetHouseIDClassInfo(test_id, GetHouseSpecGrf(test_id) == this->ro.grffile);
|
||||
}
|
||||
|
||||
/* GRFID of nearby house tile */
|
||||
@@ -445,6 +516,10 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI
|
||||
* in case the newgrf was removed. */
|
||||
return _house_mngr.GetGRFID(house_id);
|
||||
}
|
||||
|
||||
/* Visualization context of the house. */
|
||||
case 0x68:
|
||||
return HIT_HOUSE_TILE;
|
||||
}
|
||||
|
||||
DEBUG(grf, 1, "Unhandled house variable 0x%X", variable);
|
||||
@@ -467,19 +542,19 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI
|
||||
case 0x41: return 0;
|
||||
|
||||
/* Town zone */
|
||||
case 0x42: return FIND_FIRST_BIT(HouseSpec::Get(this->house_id)->building_availability & HZ_ZONALL); // first available
|
||||
case 0x42: return FindFirstBit(HouseSpec::Get(this->house_id)->building_availability & HZ_ZONALL); // last available
|
||||
|
||||
/* Terrain type */
|
||||
case 0x43: return _settings_game.game_creation.landscape == LT_ARCTIC && (HouseSpec::Get(house_id)->building_availability & (HZ_SUBARTC_ABOVE | HZ_SUBARTC_BELOW)) == HZ_SUBARTC_ABOVE ? 4 : 0;
|
||||
|
||||
/* Number of this type of building on the map. */
|
||||
case 0x44: return 0;
|
||||
case 0x44: return 0x01010101;
|
||||
|
||||
/* Whether the town is being created or just expanded. */
|
||||
case 0x45: return 0;
|
||||
/* Whether the town is being created or just expanded and whether the house is being placed manually. */
|
||||
case 0x45: return TEB_NONE;
|
||||
|
||||
/* Current animation frame. */
|
||||
case 0x46: return 0;
|
||||
case 0x46: return this->anim_frame;
|
||||
|
||||
/* Position of the house */
|
||||
case 0x47: return 0xFFFFFFFF;
|
||||
@@ -488,7 +563,13 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI
|
||||
case 0x60: return 0;
|
||||
|
||||
/* Building counts for new houses with id = parameter. */
|
||||
case 0x61: return 0;
|
||||
case 0x61: {
|
||||
HouseID test_north = _house_mngr.GetID(parameter, this->ro.grffile->grfid);
|
||||
GetHouseNorthPart(test_north);
|
||||
HouseID cur_north = this->house_id;
|
||||
GetHouseNorthPart(cur_north);
|
||||
return test_north == cur_north ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Land info for nearby tiles. */
|
||||
case 0x62: return 0;
|
||||
@@ -503,10 +584,20 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI
|
||||
case 0x65: return 0;
|
||||
|
||||
/* Class and ID of nearby house tile */
|
||||
case 0x66: return 0xFFFFFFFF;
|
||||
case 0x66: {
|
||||
HouseID nearby_house = this->GetHouseNearbyPart(parameter);
|
||||
if (nearby_house == INVALID_HOUSE_ID) return 0xFFFFFFFF;
|
||||
return GetHouseIDClassInfo(nearby_house, true);
|
||||
}
|
||||
|
||||
/* GRFID of nearby house tile */
|
||||
case 0x67: return 0xFFFFFFFF;
|
||||
case 0x67:
|
||||
if (this->GetHouseNearbyPart(parameter) == INVALID_HOUSE_ID) return 0xFFFFFFFF;
|
||||
return this->ro.grffile->grfid;
|
||||
|
||||
/* Visualization context of the house. */
|
||||
case 0x68:
|
||||
return this->image_type;
|
||||
}
|
||||
|
||||
DEBUG(grf, 1, "Unhandled house variable 0x%X", variable);
|
||||
@@ -515,27 +606,66 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile,
|
||||
bool not_yet_constructed, uint8 initial_random_bits, uint32 watched_cargo_triggers)
|
||||
HouseID FakeHouseScopeResolver::GetHouseNearbyPart(byte offset) const
|
||||
{
|
||||
HouseResolverObject object(house_id, tile, town, callback, param1, param2,
|
||||
not_yet_constructed, initial_random_bits, watched_cargo_triggers);
|
||||
return object.ResolveCallback();
|
||||
if (offset == 0) return this->house_id;
|
||||
|
||||
int8 x = GB(offset, 0, 4);
|
||||
int8 y = GB(offset, 4, 4);
|
||||
if (x >= 8) x -= 16;
|
||||
if (y >= 8) y -= 16;
|
||||
|
||||
HouseID house = this->house_id;
|
||||
TileIndexDiffC diff = GetHouseNorthPartDiffC(house); // modifies 'house'!
|
||||
x -= diff.x;
|
||||
y -= diff.y;
|
||||
if (!IsInsideBS(x, 0, 2) || !IsInsideBS(y, 0, 2)) return INVALID_HOUSE_ID;
|
||||
|
||||
BuildingFlags flags = HouseSpec::Get(house)->building_flags;
|
||||
if (x > 0 && !(flags & BUILDING_2_TILES_X)) return INVALID_HOUSE_ID;
|
||||
if (y > 0 && !(flags & BUILDING_2_TILES_Y)) return INVALID_HOUSE_ID;
|
||||
|
||||
house += x + y;
|
||||
if (flags & TILE_SIZE_2x2) house += y;
|
||||
return house;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a house callback.
|
||||
*
|
||||
* Callback can be done for a certain house tile or for a GUI house.
|
||||
*
|
||||
* @param callback The callback to perform.
|
||||
* @param param1 The first parameter.
|
||||
* @param param2 The second parameter.
|
||||
* @param house_id The house to do the callback for.
|
||||
* @param town The town the house is located in, \c NULL to query a town-less house (GUI houses).
|
||||
* @param tile The tile associated with the callback, #INVALID_TILE when querying a tile-less house (GUI houses).
|
||||
* @param image_type House context.
|
||||
* @param variant House variant (GUI houses only)
|
||||
* @return The callback result.
|
||||
*/
|
||||
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile, HouseImageType image_type, HouseVariant variant)
|
||||
{
|
||||
return (image_type == HIT_HOUSE_TILE) ?
|
||||
HouseResolverObject(house_id, tile, town, callback, param1, param2).ResolveCallback() :
|
||||
HouseResolverObject(house_id, variant, image_type, callback, param1, param2).ResolveCallback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of a house.
|
||||
* @param house House type.
|
||||
* @param tile Tile where the house is located. INVALID_TILE to get the general name of houses of the given type.
|
||||
* @param house_id House type.
|
||||
* @param tile Tile where the house is located. #INVALID_TILE to get general name (GUI houses).
|
||||
* @param variant GUI house variant, only when \c tile is #INVALID_TILE.
|
||||
* @return Name of the house.
|
||||
*/
|
||||
StringID GetHouseName(HouseID house_id, TileIndex tile)
|
||||
StringID GetHouseName(HouseID house_id, TileIndex tile, HouseVariant variant)
|
||||
{
|
||||
const HouseSpec *hs = HouseSpec::Get(house_id);
|
||||
bool house_completed = (tile == INVALID_TILE) || IsHouseCompleted(tile);
|
||||
Town *t = (tile == INVALID_TILE) ? NULL : Town::GetByTile(tile);
|
||||
|
||||
uint16 callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house_id, t, tile);
|
||||
uint16 callback_res = (tile != INVALID_TILE) ?
|
||||
GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, IsHouseCompleted(tile) ? 1 : 0, 0, house_id, Town::GetByTile(tile), tile, HIT_HOUSE_TILE) :
|
||||
GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, 0, 0, house_id, NULL, INVALID_TILE, HIT_GUI_HOUSE_PREVIEW, variant);
|
||||
if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
|
||||
if (callback_res > 0x400) {
|
||||
ErrorUnknownCallbackResult(hs->grf_prop.grffile->grfid, CBID_HOUSE_CUSTOM_NAME, callback_res);
|
||||
@@ -548,12 +678,21 @@ StringID GetHouseName(HouseID house_id, TileIndex tile)
|
||||
return hs->building_name;
|
||||
}
|
||||
|
||||
static inline PaletteID GetHouseColour(HouseID house_id, TileIndex tile = INVALID_TILE)
|
||||
/**
|
||||
* Get colour palette to be used to draw a house.
|
||||
*
|
||||
* @param house_id Type of the house.
|
||||
* @param image_type Context in which the house is being drawn.
|
||||
* @param tile Tile where the house is located. #INVALID_TILE when drawing houses in GUI.
|
||||
* @param variant GUI house variant, only when \c tile is #INVALID_TILE.
|
||||
* @return The palette.
|
||||
*/
|
||||
static PaletteID GetHouseColour(HouseID house_id, HouseImageType image_type, TileIndex tile = INVALID_TILE, HouseVariant variant = HOUSE_NO_VARIANT)
|
||||
{
|
||||
const HouseSpec *hs = HouseSpec::Get(house_id);
|
||||
if (HasBit(hs->callback_mask, CBM_HOUSE_COLOUR)) {
|
||||
Town *t = (tile != INVALID_TILE) ? Town::GetByTile(tile) : NULL;
|
||||
uint16 callback = GetHouseCallback(CBID_HOUSE_COLOUR, 0, 0, house_id, t, tile);
|
||||
uint16 callback = GetHouseCallback(CBID_HOUSE_COLOUR, 0, 0, house_id, t, tile, image_type, variant);
|
||||
if (callback != CALLBACK_FAILED) {
|
||||
/* If bit 14 is set, we should use a 2cc colour map, else use the callback value. */
|
||||
return HasBit(callback, 14) ? GB(callback, 0, 8) + SPR_2CCMAP_BASE : callback;
|
||||
@@ -566,7 +705,7 @@ static void DrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *grou
|
||||
{
|
||||
const DrawTileSprites *dts = group->ProcessRegisters(&stage);
|
||||
|
||||
PaletteID palette = GetHouseColour(house_id, ti->tile);
|
||||
PaletteID palette = GetHouseColour(house_id, HIT_HOUSE_TILE, ti->tile);
|
||||
|
||||
SpriteID image = dts->ground.sprite;
|
||||
PaletteID pal = dts->ground.pal;
|
||||
@@ -581,12 +720,12 @@ static void DrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *grou
|
||||
DrawNewGRFTileSeq(ti, dts, TO_HOUSES, stage, palette);
|
||||
}
|
||||
|
||||
static void DrawTileLayoutInGUI(int x, int y, const TileLayoutSpriteGroup *group, HouseID house_id, bool ground)
|
||||
static void DrawTileLayoutInGUI(int x, int y, const TileLayoutSpriteGroup *group, HouseID house_id, HouseVariant variant, HouseImageType image_type, bool ground)
|
||||
{
|
||||
byte stage = TOWN_HOUSE_COMPLETED;
|
||||
const DrawTileSprites *dts = group->ProcessRegisters(&stage);
|
||||
|
||||
PaletteID palette = GetHouseColour(house_id);
|
||||
PaletteID palette = GetHouseColour(house_id, image_type, INVALID_TILE, variant);
|
||||
|
||||
if (ground) {
|
||||
PalSpriteID image = dts->ground;
|
||||
@@ -627,19 +766,20 @@ void DrawNewHouseTile(TileInfo *ti, HouseID house_id)
|
||||
}
|
||||
}
|
||||
|
||||
void DrawNewHouseTileInGUI(int x, int y, HouseID house_id, bool ground)
|
||||
void DrawNewHouseTileInGUI(int x, int y, HouseID house_id, HouseVariant variant, HouseImageType image_type, bool ground)
|
||||
{
|
||||
HouseResolverObject object(house_id);
|
||||
HouseResolverObject object(house_id, variant, image_type);
|
||||
const SpriteGroup *group = object.Resolve();
|
||||
if (group != NULL && group->type == SGT_TILELAYOUT) {
|
||||
DrawTileLayoutInGUI(x, y, (const TileLayoutSpriteGroup*)group, house_id, ground);
|
||||
DrawTileLayoutInGUI(x, y, (const TileLayoutSpriteGroup*)group, house_id, variant, image_type, ground);
|
||||
}
|
||||
}
|
||||
|
||||
/* Simple wrapper for GetHouseCallback to keep the animation unified. */
|
||||
uint16 GetSimpleHouseCallback(CallbackID callback, uint32 param1, uint32 param2, const HouseSpec *spec, Town *town, TileIndex tile, uint32 extra_data)
|
||||
{
|
||||
return GetHouseCallback(callback, param1, param2, spec - HouseSpec::Get(0), town, tile, false, 0, extra_data);
|
||||
HouseResolverObject object(spec - HouseSpec::Get(0), tile, town, callback, param1, param2, false, 0, extra_data);
|
||||
return object.ResolveCallback();
|
||||
}
|
||||
|
||||
/** Helper class for animation control. */
|
||||
@@ -659,6 +799,15 @@ void AnimateNewHouseTile(TileIndex tile)
|
||||
HouseAnimationBase::AnimateTile(hs, Town::GetByTile(tile), tile, HasBit(hs->extra_flags, CALLBACK_1A_RANDOM_BITS));
|
||||
}
|
||||
|
||||
void AnimateNewHouseSetupVariant(TileIndex tile, byte variant)
|
||||
{
|
||||
const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
|
||||
|
||||
if (HasBit(hs->callback_mask, CBM_HOUSE_SETUP_VARIANT)) {
|
||||
HouseAnimationBase::ChangeAnimationFrame(CBID_HOUSE_SETUP_VARIANT, hs, Town::GetByTile(tile), tile, 0, variant);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimateNewHouseConstruction(TileIndex tile)
|
||||
{
|
||||
const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
|
||||
@@ -671,21 +820,29 @@ void AnimateNewHouseConstruction(TileIndex tile)
|
||||
/**
|
||||
* Check if GRF allows a given house to be constructed (callback 17)
|
||||
* @param house_id house type
|
||||
* @param variant house variant
|
||||
* @param tile tile where the house is about to be placed
|
||||
* @param t town in which we are building
|
||||
* @param random_bits feature random bits for the house
|
||||
* @return false if callback 17 disallows construction, true in other cases
|
||||
*/
|
||||
bool HouseAllowsConstruction(HouseID house_id, TileIndex tile, Town *t, byte random_bits)
|
||||
CommandCost HouseAllowsConstruction(HouseID house_id, HouseVariant variant, TileIndex tile, Town *t, byte random_bits)
|
||||
{
|
||||
const HouseSpec *hs = HouseSpec::Get(house_id);
|
||||
if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) {
|
||||
uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house_id, t, tile, true, random_bits);
|
||||
if (callback_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) {
|
||||
return false;
|
||||
}
|
||||
if (variant > hs->num_variants) return CMD_ERROR;
|
||||
|
||||
if (!HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) return CommandCost();
|
||||
|
||||
HouseResolverObject object(house_id, tile, t, CBID_HOUSE_ALLOW_CONSTRUCTION, 0, variant, true, random_bits);
|
||||
uint16 callback_res = object.ResolveCallback();
|
||||
if (callback_res == CALLBACK_FAILED) return CommandCost();
|
||||
|
||||
if (hs->grf_prop.grffile->grf_version < 9) {
|
||||
if (Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) return CommandCost();
|
||||
return CommandCost(STR_ERROR_SITE_UNSUITABLE);
|
||||
}
|
||||
return true;
|
||||
|
||||
return GetErrorMessageFromLocationCallbackResult(callback_res, hs->grf_prop.grffile, STR_ERROR_SITE_UNSUITABLE);
|
||||
}
|
||||
|
||||
bool CanDeleteHouse(TileIndex tile)
|
||||
|
Reference in New Issue
Block a user