diff options
-rw-r--r-- | src/newgrf.cpp | 8 | ||||
-rw-r--r-- | src/newgrf_canal.cpp | 1 | ||||
-rw-r--r-- | src/newgrf_cargo.cpp | 1 | ||||
-rw-r--r-- | src/newgrf_engine.cpp | 28 | ||||
-rw-r--r-- | src/newgrf_generic.cpp | 1 | ||||
-rw-r--r-- | src/newgrf_house.cpp | 1 | ||||
-rw-r--r-- | src/newgrf_industries.cpp | 1 | ||||
-rw-r--r-- | src/newgrf_industrytiles.cpp | 1 | ||||
-rw-r--r-- | src/newgrf_spritegroup.cpp | 1 | ||||
-rw-r--r-- | src/newgrf_spritegroup.h | 4 | ||||
-rw-r--r-- | src/newgrf_station.cpp | 1 |
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) |