# HG changeset patch # User glx # Date 1206653776 0 # Node ID b6f8dc6a246f3bd624d41b9323a4e325da833a97 # Parent c7afa0b1df35a3dac1a18c84a7457b63796288dd (svn r12452) -Feature: [NewGRF] Add random action 2 type 84. For vehicles only. diff -r c7afa0b1df35 -r b6f8dc6a246f src/newgrf.cpp --- a/src/newgrf.cpp Thu Mar 27 19:02:18 2008 +0000 +++ b/src/newgrf.cpp Thu Mar 27 21:36:16 2008 +0000 @@ -2584,13 +2584,19 @@ /* 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 -r c7afa0b1df35 -r b6f8dc6a246f src/newgrf_canal.cpp --- a/src/newgrf_canal.cpp Thu Mar 27 19:02:18 2008 +0000 +++ b/src/newgrf_canal.cpp Thu Mar 27 21:36:16 2008 +0000 @@ -85,6 +85,7 @@ res->last_value = 0; res->trigger = 0; res->reseed = 0; + res->count = 0; } diff -r c7afa0b1df35 -r b6f8dc6a246f src/newgrf_cargo.cpp --- a/src/newgrf_cargo.cpp Thu Mar 27 19:02:18 2008 +0000 +++ b/src/newgrf_cargo.cpp Thu Mar 27 21:36:16 2008 +0000 @@ -64,6 +64,7 @@ res->last_value = 0; res->trigger = 0; res->reseed = 0; + res->count = 0; } diff -r c7afa0b1df35 -r b6f8dc6a246f src/newgrf_engine.cpp --- a/src/newgrf_engine.cpp Thu Mar 27 19:02:18 2008 +0000 +++ b/src/newgrf_engine.cpp Thu Mar 27 21:36:16 2008 +0000 @@ -400,7 +400,32 @@ /* 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 @@ res->last_value = 0; res->trigger = 0; res->reseed = 0; + res->count = 0; } diff -r c7afa0b1df35 -r b6f8dc6a246f src/newgrf_generic.cpp --- a/src/newgrf_generic.cpp Thu Mar 27 19:02:18 2008 +0000 +++ b/src/newgrf_generic.cpp Thu Mar 27 21:36:16 2008 +0000 @@ -125,6 +125,7 @@ res->last_value = 0; res->trigger = 0; res->reseed = 0; + res->count = 0; } diff -r c7afa0b1df35 -r b6f8dc6a246f src/newgrf_house.cpp --- a/src/newgrf_house.cpp Thu Mar 27 19:02:18 2008 +0000 +++ b/src/newgrf_house.cpp Thu Mar 27 21:36:16 2008 +0000 @@ -291,6 +291,7 @@ 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 -r c7afa0b1df35 -r b6f8dc6a246f src/newgrf_industries.cpp --- a/src/newgrf_industries.cpp Thu Mar 27 19:02:18 2008 +0000 +++ b/src/newgrf_industries.cpp Thu Mar 27 21:36:16 2008 +0000 @@ -410,6 +410,7 @@ 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 -r c7afa0b1df35 -r b6f8dc6a246f src/newgrf_industrytiles.cpp --- a/src/newgrf_industrytiles.cpp Thu Mar 27 19:02:18 2008 +0000 +++ b/src/newgrf_industrytiles.cpp Thu Mar 27 21:36:16 2008 +0000 @@ -170,6 +170,7 @@ 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 -r c7afa0b1df35 -r b6f8dc6a246f src/newgrf_spritegroup.cpp --- a/src/newgrf_spritegroup.cpp Thu Mar 27 19:02:18 2008 +0000 +++ b/src/newgrf_spritegroup.cpp Thu Mar 27 21:36:16 2008 +0000 @@ -256,6 +256,7 @@ byte index; object->scope = group->g.random.var_scope; + object->count = group->g.random.count; if (object->trigger != 0) { /* Handle triggers */ diff -r c7afa0b1df35 -r b6f8dc6a246f src/newgrf_spritegroup.h --- a/src/newgrf_spritegroup.h Thu Mar 27 19:02:18 2008 +0000 +++ b/src/newgrf_spritegroup.h Thu Mar 27 21:36:16 2008 +0000 @@ -48,6 +48,8 @@ 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 @@ 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 @@ 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 -r c7afa0b1df35 -r b6f8dc6a246f src/newgrf_station.cpp --- a/src/newgrf_station.cpp Thu Mar 27 19:02:18 2008 +0000 +++ b/src/newgrf_station.cpp Thu Mar 27 21:36:16 2008 +0000 @@ -571,6 +571,7 @@ res->last_value = 0; res->trigger = 0; res->reseed = 0; + res->count = 0; } static const SpriteGroup *ResolveStation(ResolverObject *object)