NewGRF: Add generic town callback to set town zone radii
This commit is contained in:
@@ -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;
|
||||
|
Reference in New Issue
Block a user