NewGRF: Add generic town callback to set town zone radii

This commit is contained in:
Jonathan G Rennison
2023-03-11 02:24:50 +00:00
parent 93c34775e4
commit ae99f667b0
10 changed files with 89 additions and 14 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -13,7 +13,10 @@
#include "industrytype.h" #include "industrytype.h"
#include "core/random_func.hpp" #include "core/random_func.hpp"
#include "newgrf_sound.h" #include "newgrf_sound.h"
#include "newgrf_town.h"
#include "newgrf_extension.h"
#include "water_map.h" #include "water_map.h"
#include "string_func.h"
#include <list> #include <list>
#include "safeguards.h" #include "safeguards.h"
@@ -261,3 +264,38 @@ void AmbientSoundEffectCallback(TileIndex tile)
if (callback != CALLBACK_FAILED) PlayTileSound(grf_file, callback, 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);
}
}

View File

@@ -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); 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); void AmbientSoundEffectCallback(TileIndex tile);
uint16 GetTownZonesCallback(Town *t);
/** Play an ambient sound effect for an empty tile. */ /** Play an ambient sound effect for an empty tile. */
static inline void AmbientSoundEffect(TileIndex tile) static inline void AmbientSoundEffect(TileIndex tile)

View File

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

View File

@@ -1593,6 +1593,7 @@ static const NIVariable _niv_towns[] = {
class NIHTown : public NIHelper { class NIHTown : public NIHelper {
bool IsInspectable(uint index) const override { return Town::IsValidID(index); } 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; } uint GetParent(uint index) const override { return UINT32_MAX; }
const void *GetInstance(uint index)const override { return Town::Get(index); } const void *GetInstance(uint index)const override { return Town::Get(index); }
const void *GetSpec(uint index) const override { return nullptr; } 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 = { static const NIFeature _nif_town = {

View File

@@ -2052,21 +2052,37 @@ void UpdateTownRadius(Town *t)
{121, 81, 0, 49, 36}, // 88 {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; int mass = t->cache.num_houses / 8;
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[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[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[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[3] = mass * _settings_game.economy.city_zone_3_mult;
t->cache.squared_town_zone_radius[4] = mass * _settings_game.economy.city_zone_4_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) { } else {
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[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[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[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[3] = mass * _settings_game.economy.town_zone_3_mult;
t->cache.squared_town_zone_radius[4] = mass * _settings_game.economy.town_zone_4_mult; t->cache.squared_town_zone_radius[4] = mass * _settings_game.economy.town_zone_4_mult;
} else if (t->cache.num_houses < 92) { }
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)); 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 { } else {
int mass = t->cache.num_houses / 8; int mass = t->cache.num_houses / 8;