NewGRF: Add generic town callback to set town zone radii

pull/507/head
Jonathan G Rennison 1 year ago
parent 93c34775e4
commit ae99f667b0

@ -6194,6 +6194,10 @@ static void NewSpriteGroup(ByteReader *buf)
break;
}
case GSF_FAKE_TOWNS:
act_group = NewCallbackResultSpriteGroupNoTransform(CALLBACK_FAILED);
break;
/* Loading of Tile Layout and Production Callback groups would happen here */
default: grfmsg(1, "NewSpriteGroup: Unsupported feature %s, skipping", GetFeatureString(feature));
}

@ -282,6 +282,11 @@ enum CallbackID {
/** Called to determine the engine name to show. */
CBID_VEHICLE_NAME = 0x161, // 15 bit callback
/** Extended/non-standard callbacks follow */
/** Called to set town zones */
XCBID_TOWN_ZONES = 0xEC008001,
};
/**

@ -1642,6 +1642,7 @@ const char *GetNewGRFCallbackName(CallbackID cbid)
CBID(CBID_INDUSTRY_PROD_CHANGE_BUILD)
CBID(CBID_VEHICLE_SPAWN_VISUAL_EFFECT)
CBID(CBID_VEHICLE_NAME)
CBID(XCBID_TOWN_ZONES)
default: return nullptr;
}
}

@ -64,6 +64,7 @@ extern const GRFFeatureInfo _grf_feature_list[] = {
GRFFeatureInfo("more_action2_ids", 1, GFTOF_MORE_ACTION2_IDS),
GRFFeatureInfo("town_feature", 1),
GRFFeatureInfo("town_uncapped_variables", 1),
GRFFeatureInfo("town_zone_callback", 1, GFTOF_TOWN_ZONE_CALLBACK),
GRFFeatureInfo(),
};

@ -99,6 +99,7 @@ enum Action2VariableRemapIds {
enum GRFFeatureTestObservationFlag : uint8 {
GFTOF_MORE_OBJECTS_PER_GRF = 0,
GFTOF_MORE_ACTION2_IDS,
GFTOF_TOWN_ZONE_CALLBACK,
GFTOF_INVALID = 0xFF,
};

@ -13,7 +13,10 @@
#include "industrytype.h"
#include "core/random_func.hpp"
#include "newgrf_sound.h"
#include "newgrf_town.h"
#include "newgrf_extension.h"
#include "water_map.h"
#include "string_func.h"
#include <list>
#include "safeguards.h"
@ -261,3 +264,38 @@ void AmbientSoundEffectCallback(TileIndex tile)
if (callback != CALLBACK_FAILED) PlayTileSound(grf_file, callback, tile);
}
uint16 GetTownZonesCallback(Town *t)
{
TownResolverObject object(nullptr, t, true);
object.callback = XCBID_TOWN_ZONES;
const uint16 MAX_RETURN_VERSION = 0;
for (GenericCallbackList::const_iterator it = _gcl[GSF_FAKE_TOWNS].begin(); it != _gcl[GSF_FAKE_TOWNS].end(); ++it) {
if (!HasBit(it->file->observed_feature_tests, GFTOF_TOWN_ZONE_CALLBACK)) continue;
object.grffile = it->file;
object.root_spritegroup = it->group;
uint16 result = object.ResolveCallback();
if (result == CALLBACK_FAILED || result > MAX_RETURN_VERSION) continue;
return result;
}
return CALLBACK_FAILED;
}
void DumpGenericCallbackSpriteGroups(GrfSpecFeature feature, DumpSpriteGroupPrinter print)
{
SpriteGroupDumper dumper(print);
bool first = true;
for (GenericCallbackList::const_iterator it = _gcl[feature].begin(); it != _gcl[feature].end(); ++it) {
if (!first) print(nullptr, DSGPO_PRINT, 0, "");
char buffer[64];
seprintf(buffer, lastof(buffer), "GRF: %08X, town zone cb enabled: %s",
BSWAP32(it->file->grfid), HasBit(it->file->observed_feature_tests, GFTOF_TOWN_ZONE_CALLBACK) ? "yes" : "no");
print(nullptr, DSGPO_PRINT, 0, buffer);
first = false;
dumper.DumpSpriteGroup(it->group, 0);
}
}

@ -49,6 +49,7 @@ void AddGenericCallback(GrfSpecFeature feature, const GRFFile *file, const Sprit
uint16 GetAiPurchaseCallbackResult(GrfSpecFeature feature, CargoID cargo_type, uint8 default_selection, IndustryType src_industry, IndustryType dst_industry, uint8 distance, AIConstructionEvent event, uint8 count, uint8 station_size, const GRFFile **file);
void AmbientSoundEffectCallback(TileIndex tile);
uint16 GetTownZonesCallback(Town *t);
/** Play an ambient sound effect for an empty tile. */
static inline void AmbientSoundEffect(TileIndex tile)

@ -11,6 +11,7 @@
#include "debug.h"
#include "town.h"
#include "newgrf_town.h"
#include "newgrf_extension.h"
#include "safeguards.h"

@ -1593,6 +1593,7 @@ static const NIVariable _niv_towns[] = {
class NIHTown : public NIHelper {
bool IsInspectable(uint index) const override { return Town::IsValidID(index); }
bool ShowSpriteDumpButton(uint index) const override { return true; }
uint GetParent(uint index) const override { return UINT32_MAX; }
const void *GetInstance(uint index)const override { return Town::Get(index); }
const void *GetSpec(uint index) const override { return nullptr; }
@ -1660,6 +1661,12 @@ class NIHTown : public NIHelper {
}
}
}
/* virtual */ void SpriteDump(uint index, DumpSpriteGroupPrinter print) const override
{
extern void DumpGenericCallbackSpriteGroups(GrfSpecFeature feature, DumpSpriteGroupPrinter print);
DumpGenericCallbackSpriteGroups(GSF_FAKE_TOWNS, std::move(print));
}
};
static const NIFeature _nif_town = {

@ -2052,21 +2052,37 @@ void UpdateTownRadius(Town *t)
{121, 81, 0, 49, 36}, // 88
};
if (_settings_game.economy.town_zone_calc_mode && t->larger_town) {
if (_settings_game.economy.town_zone_calc_mode) {
int mass = t->cache.num_houses / 8;
t->cache.squared_town_zone_radius[0] = mass * _settings_game.economy.city_zone_0_mult;
t->cache.squared_town_zone_radius[1] = mass * _settings_game.economy.city_zone_1_mult;
t->cache.squared_town_zone_radius[2] = mass * _settings_game.economy.city_zone_2_mult;
t->cache.squared_town_zone_radius[3] = mass * _settings_game.economy.city_zone_3_mult;
t->cache.squared_town_zone_radius[4] = mass * _settings_game.economy.city_zone_4_mult;
} else if (_settings_game.economy.town_zone_calc_mode) {
int mass = t->cache.num_houses / 8;
t->cache.squared_town_zone_radius[0] = mass * _settings_game.economy.town_zone_0_mult;
t->cache.squared_town_zone_radius[1] = mass * _settings_game.economy.town_zone_1_mult;
t->cache.squared_town_zone_radius[2] = mass * _settings_game.economy.town_zone_2_mult;
t->cache.squared_town_zone_radius[3] = mass * _settings_game.economy.town_zone_3_mult;
t->cache.squared_town_zone_radius[4] = mass * _settings_game.economy.town_zone_4_mult;
} else if (t->cache.num_houses < 92) {
if (t->larger_town) {
t->cache.squared_town_zone_radius[0] = mass * _settings_game.economy.city_zone_0_mult;
t->cache.squared_town_zone_radius[1] = mass * _settings_game.economy.city_zone_1_mult;
t->cache.squared_town_zone_radius[2] = mass * _settings_game.economy.city_zone_2_mult;
t->cache.squared_town_zone_radius[3] = mass * _settings_game.economy.city_zone_3_mult;
t->cache.squared_town_zone_radius[4] = mass * _settings_game.economy.city_zone_4_mult;
} else {
t->cache.squared_town_zone_radius[0] = mass * _settings_game.economy.town_zone_0_mult;
t->cache.squared_town_zone_radius[1] = mass * _settings_game.economy.town_zone_1_mult;
t->cache.squared_town_zone_radius[2] = mass * _settings_game.economy.town_zone_2_mult;
t->cache.squared_town_zone_radius[3] = mass * _settings_game.economy.town_zone_3_mult;
t->cache.squared_town_zone_radius[4] = mass * _settings_game.economy.town_zone_4_mult;
}
return;
}
MemSetT(t->cache.squared_town_zone_radius, 0, lengthof(t->cache.squared_town_zone_radius));
uint16 cb_result = GetTownZonesCallback(t);
if (cb_result == 0) {
t->cache.squared_town_zone_radius[0] = GetRegister(0x100);
t->cache.squared_town_zone_radius[1] = GetRegister(0x101);
t->cache.squared_town_zone_radius[2] = GetRegister(0x102);
t->cache.squared_town_zone_radius[3] = GetRegister(0x103);
t->cache.squared_town_zone_radius[4] = GetRegister(0x104);
return;
}
if (t->cache.num_houses < 92) {
memcpy(t->cache.squared_town_zone_radius, _town_squared_town_zone_radius_data[t->cache.num_houses / 4], sizeof(t->cache.squared_town_zone_radius));
} else {
int mass = t->cache.num_houses / 8;

Loading…
Cancel
Save