@@ -22,13 +22,12 @@ enum TownEffect {
};
struct CargoSpec {
uint8 bitnum;
CargoLabel label;
uint32 grfid;
uint8 legend_colour;
uint8 rating_colour;
uint8 weight;
uint16 initial_payment;
uint8 transit_days[2];
@@ -43,12 +42,13 @@ struct CargoSpec {
StringID quantifier;
StringID abbrev;
SpriteID sprite;
uint16 classes;
const struct GRFFile *grffile; ///< NewGRF where 'group' belongs to
const struct SpriteGroup *group;
bool IsValid() const;
@@ -1729,13 +1729,13 @@ static bool CargoChangeInfo(uint cid, in
CargoSpec *cs = &_cargo[cid + i];
switch (prop) {
case 0x08: /* Bit number of cargo */
cs->bitnum = grf_load_byte(&buf);
if (cs->IsValid()) {
cs->grfid = _cur_grffile->grfid;
cs->grffile = _cur_grffile;
SetBit(_cargo_mask, cid + i);
} else {
ClrBit(_cargo_mask, cid + i);
}
break;
@@ -3042,12 +3042,13 @@ static void CanalMapSpriteGroup(byte *bu
if (cf >= CF_END) {
grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
continue;
_water_feature[cf].grffile = _cur_grffile;
_water_feature[cf].group = _cur_grffile->spritegroups[groupid];
static void StationMapSpriteGroup(byte *buf, uint8 idcount)
@@ -3195,13 +3196,13 @@ static void CargoMapSpriteGroup(byte *bu
if (cid >= NUM_CARGO) {
grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
CargoSpec *cs = &_cargo[cid];
cs->group = _cur_grffile->spritegroups[groupid];
/* Action 0x03 */
@@ -68,13 +68,13 @@ static const SpriteGroup *CanalResolveRe
if (group->g.real.num_loaded == 0) return NULL;
return group->g.real.loaded[0];
static void NewCanalResolver(ResolverObject *res, TileIndex tile)
static void NewCanalResolver(ResolverObject *res, TileIndex tile, const GRFFile *grffile)
{
res->GetRandomBits = &CanalGetRandomBits;
res->GetTriggers = &CanalGetTriggers;
res->SetTriggers = &CanalSetTriggers;
res->GetVariable = &CanalGetVariable;
res->ResolveReal = &CanalResolveReal;
@@ -85,21 +85,22 @@ static void NewCanalResolver(ResolverObj
res->callback_param1 = 0;
res->callback_param2 = 0;
res->last_value = 0;
res->trigger = 0;
res->reseed = 0;
res->count = 0;
res->grffile = grffile;
SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile)
ResolverObject object;
const SpriteGroup *group;
NewCanalResolver(&object, tile);
NewCanalResolver(&object, tile, _water_feature[feature].grffile);
group = Resolve(_water_feature[feature].group, &object);
if (group == NULL || group->type != SGT_RESULT) return 0;
return group->g.result.sprite;
@@ -18,12 +18,13 @@ enum CanalFeature {
CF_END,
struct WaterFeature {
const GRFFile *grffile; ///< newgrf where 'group' belongs to
uint8 callbackmask;
uint8 flags;
/** Table of canal 'feature' sprite groups */
@@ -64,12 +64,13 @@ static void NewCargoResolver(ResolverObj
res->grffile = cs->grffile;
SpriteID GetCustomCargoSprite(const CargoSpec *cs)
@@ -436,22 +436,12 @@ static void VehicleSetTriggers(const Res
assert(object->trigger != 0);
if (v != NULL) v->waiting_triggers = triggers;
static uint32 GetGRFParameter(EngineID engine_type, byte parameter)
const GRFFile *file = GetEngineGRF(engine_type);
if (file == NULL) return 0;
if (parameter >= file->param_end) return 0;
return file->param[parameter];
static uint8 LiveryHelper(EngineID engine, const Vehicle *v)
const Livery *l;
if (v == NULL) {
if (!IsValidPlayerID(_current_player)) return 0;
@@ -476,13 +466,12 @@ static uint32 VehicleGetVariable(const R
case 0x43: return _current_player | (LiveryHelper(object->u.vehicle.self_type, NULL) << 24); // Owner information
case 0x46: return 0; // Motion counter
case 0x48: return GetEngine(object->u.vehicle.self_type)->flags; // Vehicle Type Info
case 0x49: return _cur_year; // 'Long' format build year
case 0xC4: return Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR; // Build year
case 0xDA: return INVALID_VEHICLE; // Next vehicle
case 0x7F: return GetGRFParameter(object->u.vehicle.self_type, parameter); // Read GRF parameter
*available = false;
return UINT_MAX;
@@ -629,14 +618,12 @@ static uint32 VehicleGetVariable(const R
for (; v != NULL; v = v->Next()) {
if (GetEngine(v->engine_type)->internal_id == parameter) count++;
return count;
case 0x7F: return GetGRFParameter(v->engine_type, parameter); // Read GRF parameter
case 0xFE:
case 0xFF: {
uint16 modflags = 0;
if (v->type == VEH_TRAIN) {
const Vehicle *u = IsTrainWagon(v) && HasBit(v->vehicle_flags, VRF_POWEREDWAGON) ? v->First() : v;
@@ -829,12 +816,15 @@ static inline void NewVehicleResolver(Re
const Engine *e = GetEngine(engine_type);
res->grffile = (e != NULL ? e->grffile : NULL);
/** Retrieve the SpriteGroup for the specified vehicle.
* If the vehicle is not specified, the purchase list group for the engine is
* chosen. For trains, an additional engine override lookup is performed.
@@ -110,13 +110,13 @@ static const SpriteGroup *GenericCallbac
static inline void NewGenericResolver(ResolverObject *res)
static inline void NewGenericResolver(ResolverObject *res, const GRFFile *grffile)
res->GetRandomBits = &GenericCallbackGetRandomBits;
res->GetTriggers = &GenericCallbackGetTriggers;
res->SetTriggers = &GenericCallbackSetTriggers;
res->GetVariable = &GenericCallbackGetVariable;
res->ResolveReal = &GenericCallbackResolveReal;
@@ -125,12 +125,13 @@ static inline void NewGenericResolver(Re
/** Follow a generic feature callback list and return the first successful
* answer
* @param feature GRF Feature of callback
@@ -163,13 +164,13 @@ static uint16 GetGenericCallbackResult(u
* 'Execute' an AI purchase selection callback
*/
uint16 GetAiPurchaseCallbackResult(uint8 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)
NewGenericResolver(&object);
NewGenericResolver(&object, *file);
object.callback = CBID_GENERIC_AI_PURCHASE_SELECTION;
object.u.generic.cargo_type = cargo_type;
object.u.generic.default_selection = default_selection;
object.u.generic.src_industry = src_industry;
object.u.generic.dst_industry = dst_industry;
@@ -180,21 +180,12 @@ static uint32 GetNumHouses(HouseID house
town_id_count = town->building_counts.id_count[house_id];
town_class_count = town->building_counts.class_count[class_id];
return map_class_count << 24 | town_class_count << 16 | map_id_count << 8 | town_id_count;
static uint32 GetGRFParameter(HouseID house_id, byte parameter)
const HouseSpec *hs = GetHouseSpecs(house_id);
const GRFFile *file = hs->grffile;
uint32 GetNearbyTileInformation(byte parameter, TileIndex tile)
tile = GetNearbyTile(parameter, tile);
return GetNearbyTileInformation(tile);
@@ -366,15 +357,12 @@ static uint32 HouseGetVariable(const Res
/* Cargo acceptance history of nearby stations */
/*case 0x64: not implemented yet */
/* Distance test for some house types */
case 0x65: return GetDistanceFromNearbyHouse(parameter, tile, object->u.house.house_id);
/* Read GRF parameter */
case 0x7F: return GetGRFParameter(object->u.house.house_id, parameter);
DEBUG(grf, 1, "Unhandled house property 0x%X", variable);
@@ -407,12 +395,15 @@ static void NewHouseResolver(ResolverObj
res->grffile = (hs != NULL ? hs->grffile : NULL);
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile)
@@ -38,21 +38,12 @@ IndustryType MapNewGRFIndustryType(Indus
if (grf_type == IT_INVALID) return IT_INVALID;
if (!HasBit(grf_type, 7)) return GB(grf_type, 0, 6);
return _industry_mngr.GetID(GB(grf_type, 0, 6), grf_id);
static uint32 GetGRFParameter(IndustryType ind_id, byte parameter)
const IndustrySpec *indspec = GetIndustrySpec(ind_id);
const GRFFile *file = indspec->grf_prop.grffile;
/**
* Finds the distance for the closest tile with water/land given a tile
* @param tile the tile to find the distance too
* @param water whether to find water or land
* @note FAILS when an industry should be seen as water
@@ -227,14 +218,12 @@ uint32 IndustryGetVariable(const Resolve
return TownGetVariable(variable, parameter, available, t);
if (industry == NULL) {
/* industry does not exist, only use those variables that are "safe" */
switch (variable) {
case 0x7F: return GetGRFParameter(type, parameter);
/* Manhattan distance of closes dry/water tile */
case 0x43: return GetClosestWaterDistance(tile, (indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) == 0);
DEBUG(grf, 1, "Unhandled property 0x%X (no available industry) in callback 0x%x", variable, object->callback);
@@ -315,15 +304,12 @@ uint32 IndustryGetVariable(const Resolve
case 0x67:
case 0x68: return GetCountAndDistanceOfClosestInstance(parameter, variable == 0x68 ? GB(GetRegister(0x101), 0, 8) : 0, industry);
/* Get a variable from the persistent storage */
case 0x7C: return industry->psa.Get(parameter);
/* Industry structure access*/
case 0x80: return industry->xy;
case 0x81: return GB(industry->xy, 8, 8);
/* Pointer to the town the industry is associated with */
case 0x82: return industry->town->index;
case 0x83:
@@ -427,12 +413,15 @@ static void NewIndustryResolver(Resolver
const IndustrySpec *indspec = GetIndustrySpec(type);
res->grffile = (indspec != NULL ? indspec->grf_prop.grffile : NULL);
uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile)
@@ -27,21 +27,12 @@
#include "animated_tile_func.h"
#include "water.h"
#include "table/sprites.h"
#include "table/strings.h"
static uint32 GetGRFParameter(IndustryGfx indtile_id, byte parameter)
const IndustryTileSpec *indtspec = GetIndustryTileSpec(indtile_id);
const GRFFile *file = indtspec->grf_prop.grffile;
* Based on newhouses equivalent, but adapted for newindustries
* @param parameter from callback. It's in fact a pair of coordinates
* @param tile TileIndex from which the callback was initiated
* @param index of the industry been queried for
* @return a construction of bits obeying the newgrf format
@@ -107,15 +98,12 @@ static uint32 IndustryTileGetVariable(co
return 0xFFFFFFFF;
/* Get industry tile ID at offset */
case 0x62 : return GetIndustryIDAtOffset(GetNearbyTile(parameter, tile), inds);
case 0x7F: return GetGRFParameter(GetIndustryGfx(tile), parameter);
DEBUG(grf, 1, "Unhandled industry tile property 0x%X", variable);
return (uint32)-1;
@@ -171,12 +159,15 @@ static void NewIndustryTileResolver(Reso
const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
res->grffile = (its != NULL ? its->grf_prop.grffile : NULL);
void IndustryDrawTileLayout(const TileInfo *ti, const SpriteGroup *group, byte rnd_color, byte stage, IndustryGfx gfx)
const DrawTileSprites *dts = group->g.layout.dts;
const DrawTileSeqStruct *dtss;
@@ -94,12 +94,16 @@ static inline uint32 GetVariable(const R
case 0x1C: return object->last_value;
case 0x5F: return (object->GetRandomBits(object) << 8) | object->GetTriggers(object);
case 0x7D: return _temp_store.Get(parameter);
case 0x7F:
if (object == NULL || object->grffile == NULL || parameter >= object->grffile->param_end) return 0;
return object->grffile->param[parameter];
/* Not a common variable, so evalute the feature specific variables */
default: return object->GetVariable(object, variable, parameter, available);
@@ -215,12 +215,14 @@ struct ResolverObject {
VarSpriteGroupScope scope;
bool info_view; ///< Indicates if the item is being drawn in an info window
BaseStorageArray *psa; ///< The persistent storage array of this resolved object.
const GRFFile *grffile; ///< GRFFile the resolved SpriteGroup belongs to
union {
struct {
const struct Vehicle *self;
const struct Vehicle *parent;
EngineID self_type;
} vehicle;
@@ -587,12 +587,13 @@ static void NewStationResolver(ResolverO
res->grffile = (statspec != NULL ? statspec->grffile : NULL);
static const SpriteGroup *ResolveStation(ResolverObject *object)
CargoID ctype = CT_DEFAULT_NA;
/* $Id$ */
/** @file cargo_const.h Table of all default cargo types */
#define MK(bt, label, c, e, f, g, h, fr, te, ks1, ks2, ks3, ks4, ks5, l, m) \
{bt, label, 0, c, c, e, f, {g, h}, fr, te, 0, 0, ks1, ks2, ks3, ks4, ks5, l, m, NULL}
{bt, label, c, c, e, f, {g, h}, fr, te, 0, 0, ks1, ks2, ks3, ks4, ks5, l, m, NULL, NULL}
static const CargoSpec _default_cargo[] = {
MK( 0, 'PASS', 152, 1, 3185, 0, 24, false, TE_PASSENGERS,
STR_000F_PASSENGERS, STR_002F_PASSENGER, STR_PASSENGERS, STR_QUANTITY_PASSENGERS, STR_ABBREV_PASSENGERS,
SPR_CARGO_PASSENGER, CC_PASSENGERS ),
MK( 1, 'COAL', 32, 16, 5916, 7, 255, true, TE_NONE,
Status change: