summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/newgrf.cpp8
-rw-r--r--src/newgrf_canal.cpp1
-rw-r--r--src/newgrf_cargo.cpp1
-rw-r--r--src/newgrf_engine.cpp28
-rw-r--r--src/newgrf_generic.cpp1
-rw-r--r--src/newgrf_house.cpp1
-rw-r--r--src/newgrf_industries.cpp1
-rw-r--r--src/newgrf_industrytiles.cpp1
-rw-r--r--src/newgrf_spritegroup.cpp1
-rw-r--r--src/newgrf_spritegroup.h4
-rw-r--r--src/newgrf_station.cpp1
11 files changed, 46 insertions, 2 deletions
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 5d405b483..23cf67c14 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -2584,13 +2584,19 @@ static void NewSpriteGroup(byte *buf, int len)
/* Randomized Sprite Group */
case 0x80: // Self scope
case 0x83: // Parent scope
+ case 0x84: // Relative scope
{
- if (!check_length(bufend - buf, 7, "NewSpriteGroup (Randomized) (1)")) return;
+ if (!check_length(bufend - buf, HasBit(type, 2) ? 8 : 7, "NewSpriteGroup (Randomized) (1)")) return;
group = AllocateSpriteGroup();
group->type = SGT_RANDOMIZED;
group->g.random.var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
+ if (HasBit(type, 2) && feature <= GSF_AIRCRAFT) {
+ group->g.random.var_scope = VSG_SCOPE_RELATIVE;
+ group->g.random.count = grf_load_byte(&buf);
+ }
+
uint8 triggers = grf_load_byte(&buf);
group->g.random.triggers = GB(triggers, 0, 7);
group->g.random.cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
diff --git a/src/newgrf_canal.cpp b/src/newgrf_canal.cpp
index df3d7630c..50c60e524 100644
--- a/src/newgrf_canal.cpp
+++ b/src/newgrf_canal.cpp
@@ -85,6 +85,7 @@ static void NewCanalResolver(ResolverObject *res, TileIndex tile)
res->last_value = 0;
res->trigger = 0;
res->reseed = 0;
+ res->count = 0;
}
diff --git a/src/newgrf_cargo.cpp b/src/newgrf_cargo.cpp
index d43f61019..67630ee6d 100644
--- a/src/newgrf_cargo.cpp
+++ b/src/newgrf_cargo.cpp
@@ -64,6 +64,7 @@ static void NewCargoResolver(ResolverObject *res, const CargoSpec *cs)
res->last_value = 0;
res->trigger = 0;
res->reseed = 0;
+ res->count = 0;
}
diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp
index ef31b976c..f36f3e52a 100644
--- a/src/newgrf_engine.cpp
+++ b/src/newgrf_engine.cpp
@@ -400,7 +400,32 @@ enum {
/* Vehicle Resolver Functions */
static inline const Vehicle *GRV(const ResolverObject *object)
{
- return object->scope == VSG_SCOPE_SELF ? object->u.vehicle.self : object->u.vehicle.parent;
+ switch (object->scope) {
+ default: NOT_REACHED();
+ case VSG_SCOPE_SELF: return object->u.vehicle.self;
+ case VSG_SCOPE_PARENT: return object->u.vehicle.parent;
+ case VSG_SCOPE_RELATIVE: {
+ const Vehicle *v;
+ switch (GB(object->count, 6, 2)) {
+ default: NOT_REACHED();
+ case 0x00: // count back (away from the engine), starting at this vehicle
+ case 0x01: // count forward (toward the engine), starting at this vehicle
+ v = object->u.vehicle.self;
+ break;
+ case 0x02: // count back, starting at the engine
+ v = object->u.vehicle.parent;
+ break;
+ case 0x03: // count back, starting at the first vehicle in this chain of vehicles with the same ID, as for vehicle variable 41
+ v = object->u.vehicle.parent;
+ while (v != NULL && v->engine_type != object->u.vehicle.self->engine_type) v = v->Next();
+ break;
+ }
+ uint32 count = GB(object->count, 0, 4);
+ if (count == 0) count = GetRegister(0x100);
+ while (v != NULL && count-- != 0) v = (GB(object->count, 6, 2) == 0x01) ? v->Previous() : v->Next();
+ return v;
+ }
+ }
}
@@ -816,6 +841,7 @@ static inline void NewVehicleResolver(ResolverObject *res, EngineID engine_type,
res->last_value = 0;
res->trigger = 0;
res->reseed = 0;
+ res->count = 0;
}
diff --git a/src/newgrf_generic.cpp b/src/newgrf_generic.cpp
index 8d515d713..0097979e3 100644
--- a/src/newgrf_generic.cpp
+++ b/src/newgrf_generic.cpp
@@ -125,6 +125,7 @@ static inline void NewGenericResolver(ResolverObject *res)
res->last_value = 0;
res->trigger = 0;
res->reseed = 0;
+ res->count = 0;
}
diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp
index 251207c19..e59097f70 100644
--- a/src/newgrf_house.cpp
+++ b/src/newgrf_house.cpp
@@ -291,6 +291,7 @@ static void NewHouseResolver(ResolverObject *res, HouseID house_id, TileIndex ti
res->last_value = 0;
res->trigger = 0;
res->reseed = 0;
+ res->count = 0;
}
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile)
diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp
index 618458d6b..d77cfb8a6 100644
--- a/src/newgrf_industries.cpp
+++ b/src/newgrf_industries.cpp
@@ -410,6 +410,7 @@ static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *i
res->last_value = 0;
res->trigger = 0;
res->reseed = 0;
+ res->count = 0;
}
uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile)
diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp
index 4b229f7e3..1303a6460 100644
--- a/src/newgrf_industrytiles.cpp
+++ b/src/newgrf_industrytiles.cpp
@@ -170,6 +170,7 @@ static void NewIndustryTileResolver(ResolverObject *res, IndustryGfx gfx, TileIn
res->last_value = 0;
res->trigger = 0;
res->reseed = 0;
+ res->count = 0;
}
void IndustryDrawTileLayout(const TileInfo *ti, const SpriteGroup *group, byte rnd_color, byte stage, IndustryGfx gfx)
diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp
index 65e8f29e2..a132a0cc6 100644
--- a/src/newgrf_spritegroup.cpp
+++ b/src/newgrf_spritegroup.cpp
@@ -256,6 +256,7 @@ static inline const SpriteGroup *ResolveRandom(const SpriteGroup *group, Resolve
byte index;
object->scope = group->g.random.var_scope;
+ object->count = group->g.random.count;
if (object->trigger != 0) {
/* Handle triggers */
diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h
index 4a3baa0f4..d3fcde0f6 100644
--- a/src/newgrf_spritegroup.h
+++ b/src/newgrf_spritegroup.h
@@ -48,6 +48,8 @@ enum VarSpriteGroupScope {
VSG_SCOPE_SELF,
/* Engine of consists for vehicles, city for stations. */
VSG_SCOPE_PARENT,
+ /* Any vehicle in the consist (vehicles only) */
+ VSG_SCOPE_RELATIVE,
};
enum DeterministicSpriteGroupSize {
@@ -128,6 +130,7 @@ struct RandomizedSpriteGroup {
RandomizedSpriteGroupCompareMode cmp_mode; ///< Check for these triggers:
byte triggers;
+ byte count;
byte lowest_randbit; ///< Look for this in the per-object randomized bitmask:
byte num_groups; ///< must be power of 2
@@ -201,6 +204,7 @@ struct ResolverObject {
bool procedure_call; ///< true if we are currently resolving a var 0x7E procedure result.
byte trigger;
+ byte count;
uint32 last_value;
uint32 reseed;
VarSpriteGroupScope scope;
diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp
index aefef9ed1..5162f6028 100644
--- a/src/newgrf_station.cpp
+++ b/src/newgrf_station.cpp
@@ -571,6 +571,7 @@ static void NewStationResolver(ResolverObject *res, const StationSpec *statspec,
res->last_value = 0;
res->trigger = 0;
res->reseed = 0;
+ res->count = 0;
}
static const SpriteGroup *ResolveStation(ResolverObject *object)