(svn r22569) -Feature: [NewGRF] Persistent storage for towns.

replace/41b28d7194a279bdc17475d4fbe2ea6ec885a466
terkhen 13 years ago
parent 7ffc8c0173
commit a619ad3789

@ -259,7 +259,7 @@ static uint32 HouseGetVariable(const ResolverObject *object, byte variable, byte
HouseID house_id = object->u.house.house_id;
if (object->scope == VSG_SCOPE_PARENT) {
return TownGetVariable(variable, parameter, available, town);
return TownGetVariable(variable, parameter, available, town, object->grffile);
}
switch (variable) {
@ -360,6 +360,21 @@ static const SpriteGroup *HouseResolveReal(const ResolverObject *object, const R
return NULL;
}
/**
* Store a value into the persistent storage of the object's parent.
* @param object Object that we want to query.
* @param pos Position in the persistent storage to use.
* @param value Value to store.
*/
void HouseStorePSA(ResolverObject *object, uint pos, int32 value)
{
/* Houses have no persistent storage. */
if (object->scope != VSG_SCOPE_PARENT || object->u.house.not_yet_constructed) return;
/* Pass the request on to the town of the house */
TownStorePSA(object->u.house.town, object->grffile, pos, value);
}
/**
* NewHouseResolver():
*
@ -372,6 +387,7 @@ static void NewHouseResolver(ResolverObject *res, HouseID house_id, TileIndex ti
res->SetTriggers = HouseSetTriggers;
res->GetVariable = HouseGetVariable;
res->ResolveReal = HouseResolveReal;
res->StorePSA = HouseStorePSA;
res->u.house.tile = tile;
res->u.house.town = town;

@ -191,7 +191,7 @@ uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte par
return UINT_MAX;
}
return TownGetVariable(variable, parameter, available, t);
return TownGetVariable(variable, parameter, available, t, object->grffile);
}
if (industry == NULL) {
@ -385,7 +385,13 @@ static void IndustrySetTriggers(const ResolverObject *object, int triggers)
void IndustryStorePSA(ResolverObject *object, uint pos, int32 value)
{
Industry *ind = object->u.industry.ind;
if (object->scope != VSG_SCOPE_SELF || ind->index == INVALID_INDUSTRY) return;
if (ind->index == INVALID_INDUSTRY) return;
if (object->scope != VSG_SCOPE_SELF) {
/* Pass the request on to the town of the industry. */
TownStorePSA(ind->town, object->grffile, pos, value);
return;
}
if (ind->psa == NULL) {
/* There is no need to create a storage if the value is zero. */
@ -459,7 +465,7 @@ uint32 IndustryLocationGetVariable(const ResolverObject *object, byte variable,
TileIndex tile = object->u.industry.tile;
if (object->scope == VSG_SCOPE_PARENT) {
return TownGetVariable(variable, parameter, available, industry->town);
return TownGetVariable(variable, parameter, available, industry->town, object->grffile);
}
switch (variable) {

@ -224,7 +224,7 @@ static uint32 ObjectGetVariable(const ResolverObject *object, byte variable, byt
if (object->scope == VSG_SCOPE_PARENT) {
/* Pass the request on to the town of the object */
return TownGetVariable(variable, parameter, available, (o == NULL) ? ClosestTownFromTile(tile, UINT_MAX) : o->town);
return TownGetVariable(variable, parameter, available, (o == NULL) ? ClosestTownFromTile(tile, UINT_MAX) : o->town, object->grffile);
}
/* We get the town from the object, or we calculate the closest
@ -358,6 +358,22 @@ static const SpriteGroup *GetObjectSpriteGroup(const ObjectSpec *spec, const Obj
}
/**
* Store a value into the persistent storage of the object's parent.
* @param object Object that we want to query.
* @param pos Position in the persistent storage to use.
* @param value Value to store.
*/
void ObjectStorePSA(ResolverObject *object, uint pos, int32 value)
{
/* Objects have no persistent storage. */
Object *o = object->u.object.o;
if (object->scope != VSG_SCOPE_PARENT || o == NULL) return;
/* Pass the request on to the town of the object */
TownStorePSA(o->town, object->grffile, pos, value);
}
/**
* Returns a resolver object to be used with feature 0F spritegroups.
*/
@ -368,6 +384,7 @@ static void NewObjectResolver(ResolverObject *res, const ObjectSpec *spec, Objec
res->SetTriggers = ObjectSetTriggers;
res->GetVariable = ObjectGetVariable;
res->ResolveReal = ObjectResolveReal;
res->StorePSA = ObjectStorePSA;
res->u.object.o = o;
res->u.object.tile = tile;

@ -275,7 +275,7 @@ static uint32 StationGetVariable(const ResolverObject *object, byte variable, by
return UINT_MAX;
}
return TownGetVariable(variable, parameter, available, t);
return TownGetVariable(variable, parameter, available, t, object->grffile);
}
if (st == NULL) {
@ -517,6 +517,21 @@ static const SpriteGroup *StationResolveReal(const ResolverObject *object, const
}
/**
* Store a value into the persistent storage of the object's parent.
* @param object Object that we want to query.
* @param pos Position in the persistent storage to use.
* @param value Value to store.
*/
void StationStorePSA(ResolverObject *object, uint pos, int32 value)
{
/* Stations have no persistent storage. */
BaseStation *st = object->u.station.st;
if (object->scope != VSG_SCOPE_PARENT || st == NULL) return;
TownStorePSA(st->town, object->grffile, pos, value);
}
static void NewStationResolver(ResolverObject *res, const StationSpec *statspec, BaseStation *st, TileIndex tile)
{
res->GetRandomBits = StationGetRandomBits;
@ -524,6 +539,7 @@ static void NewStationResolver(ResolverObject *res, const StationSpec *statspec,
res->SetTriggers = StationSetTriggers;
res->GetVariable = StationGetVariable;
res->ResolveReal = StationResolveReal;
res->StorePSA = StationStorePSA;
res->u.station.st = st;
res->u.station.statspec = statspec;

@ -12,6 +12,8 @@
#include "stdafx.h"
#include "debug.h"
#include "town.h"
#include "newgrf.h"
#include "newgrf_spritegroup.h"
/**
* This function implements the town variables that newGRF defines.
@ -19,9 +21,10 @@
* @param parameter unused
* @param available will return false if ever the variable asked for does not exist
* @param t is of course the town we are inquiring
* @param caller_grffile #GRFFile of the entity asking for a town variable.
* @return the value stored in the corresponding variable
*/
uint32 TownGetVariable(byte variable, byte parameter, bool *available, Town *t)
uint32 TownGetVariable(byte variable, byte parameter, bool *available, Town *t, const GRFFile *caller_grffile)
{
switch (variable) {
/* Larger towns */
@ -33,6 +36,23 @@ uint32 TownGetVariable(byte variable, byte parameter, bool *available, Town *t)
/* Town index */
case 0x41: return t->index;
/* Get a variable from the persistent storage */
case 0x7C: {
/* Check the persistent storage for the GrfID stored in register 100h. */
uint32 grfid = GetRegister(0x100);
if (grfid == 0xFFFFFFFF) {
if (caller_grffile == NULL) return 0;
grfid = caller_grffile->grfid;
}
std::list<PersistentStorage *>::iterator iter;
for (iter = t->psa_list.begin(); iter != t->psa_list.end(); iter++) {
if ((*iter)->grfid == grfid) return (*iter)->GetValue(parameter);
}
return 0;
}
/* Town properties */
case 0x80: return t->xy;
case 0x81: return GB(t->xy, 8, 8);
@ -106,3 +126,39 @@ uint32 TownGetVariable(byte variable, byte parameter, bool *available, Town *t)
*available = false;
return UINT_MAX;
}
/**
* Store a value in town persistent storage.
* @param t Town owning the persistent storage.
* @param caller_grffile #GRFFile of the entity that wants to use the storage.
* @param pos Position to write at.
* @param value Value to write.
* @return the value stored in the corresponding variable
*/
void TownStorePSA(Town *t, const GRFFile *caller_grffile, uint pos, int32 value)
{
assert(t != NULL);
/* We can't store anything if the caller has no #GRFFile. */
if (caller_grffile == NULL) return;
/* Check the persistent storage for the GrfID stored in register 100h. */
uint32 grfid = GetRegister(0x100);
/* A NewGRF can only write in the persistent storage associated to its own GRFID. */
if (grfid == 0xFFFFFFFF) grfid = caller_grffile->grfid;
if (grfid != caller_grffile->grfid) return;
/* Check if the storage exists. */
std::list<PersistentStorage *>::iterator iter;
for (iter = t->psa_list.begin(); iter != t->psa_list.end(); iter++) {
if ((*iter)->grfid == grfid) {
(*iter)->StoreValue(pos, value);
return;
}
}
/* Create a new storage. */
PersistentStorage *psa = new PersistentStorage(grfid);
psa->StoreValue(pos, value);
t->psa_list.push_back(psa);
}

@ -15,8 +15,9 @@
#include "town_type.h"
/* Currently there is no direct town resolver; we only need to get town
* variable results from inside stations, house tiles and industry tiles. */
uint32 TownGetVariable(byte variable, byte parameter, bool *available, Town *t);
* variable results from inside stations, house tiles and industries,
* and to check the town's persistent storage. */
uint32 TownGetVariable(byte variable, byte parameter, bool *available, Town *t, const GRFFile *caller_grffile);
void TownStorePSA(Town *t, const GRFFile *caller_grffile, uint pos, int32 value);
#endif /* NEWGRF_TOWN_H */

@ -433,7 +433,7 @@ class NIHTown : public NIHelper {
const void *GetInstance(uint index)const { return Town::Get(index); }
const void *GetSpec(uint index) const { return NULL; }
void SetStringParameters(uint index) const { this->SetSimpleStringParameters(STR_TOWN_NAME, index); }
uint Resolve(uint index, uint var, uint param, bool *avail) const { return TownGetVariable(var, param, avail, Town::Get(index)); }
uint Resolve(uint index, uint var, uint param, bool *avail) const { return TownGetVariable(var, param, avail, Town::Get(index), NULL); }
};
static const NIFeature _nif_town = {

@ -95,6 +95,9 @@ Town::~Town()
}
}
/* Clear the persistent storage list. */
this->psa_list.clear();
DeleteSubsidyWith(ST_TOWN, this->index);
DeleteNewGRFInspectWindow(GSF_FAKE_TOWNS, this->index);
CargoPacket::InvalidateAllFrom(ST_TOWN, this->index);

Loading…
Cancel
Save