From 41cf2fa69b8ff60f1b1633b68f47434075d00d75 Mon Sep 17 00:00:00 2001 From: peter1138 Date: Wed, 18 Apr 2007 18:37:40 +0000 Subject: [PATCH] (svn r9671) -Codechange: Implement NewGRF callback 36, which allows changing of various properties which were previously static. Vehicle max speed and train power/te/running costs are adjustable. --- src/aircraft.h | 6 ++++++ src/aircraft_cmd.cpp | 24 ++++++++++++++++++++++++ src/newgrf_callbacks.h | 4 ++++ src/newgrf_engine.cpp | 11 +++++++++++ src/newgrf_engine.h | 4 ++++ src/ship_cmd.cpp | 2 +- src/train_cmd.cpp | 33 ++++++++++++++++++++------------- src/vehicle.cpp | 2 ++ src/vehicle.h | 1 + 9 files changed, 73 insertions(+), 14 deletions(-) diff --git a/src/aircraft.h b/src/aircraft.h index 46ccdb211d..eb11f755a8 100644 --- a/src/aircraft.h +++ b/src/aircraft.h @@ -109,4 +109,10 @@ void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height); */ void UpdateAirplanesOnNewStation(const Station *st); +/** Update cached values of an aircraft. + * Currently caches callback 36 max speed. + * @param v Vehicle + */ +void UpdateAircraftCache(Vehicle *v); + #endif /* AIRCRAFT_H */ diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 90d7044603..1acf9dd4c5 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -393,6 +393,8 @@ int32 CmdBuildAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) v->vehicle_flags = 0; if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); + UpdateAircraftCache(v); + VehiclePositionChanged(v); VehiclePositionChanged(u); @@ -862,6 +864,21 @@ static void PlayAircraftSound(const Vehicle* v) } } + +void UpdateAircraftCache(Vehicle *v) +{ + uint max_speed = GetVehicleProperty(v, 0x0C, 0); + if (max_speed != 0) { + /* Convert from original units to (approx) km/h */ + max_speed = (max_speed * 129) / 10; + + v->u.air.cached_max_speed = max_speed; + } else { + v->u.air.cached_max_speed = 0xFFFF; + } +} + + /** * Special velocities for aircraft */ @@ -885,6 +902,11 @@ static int UpdateAircraftSpeed(Vehicle *v, uint speed_limit = SPEED_LIMIT_NONE, uint spd = v->acceleration * 16; byte t; + if (v->u.air.cached_max_speed < speed_limit) { + if (v->cur_speed < speed_limit) hard_limit = false; + speed_limit = v->u.air.cached_max_speed; + } + speed_limit = min(speed_limit, v->max_speed); v->subspeed = (t=v->subspeed) + (byte)spd; @@ -1856,8 +1878,10 @@ static bool AirportMove(Vehicle *v, const AirportFTAClass *apc) /* we have arrived in an important state (eg terminal, hangar, etc.) */ if (current->heading == v->u.air.state) { byte prev_pos = v->u.air.pos; // location could be changed in state, so save it before-hand + byte prev_state = v->u.air.state; _aircraft_state_handlers[v->u.air.state](v, apc); if (v->u.air.state != FLYING) v->u.air.previous_pos = prev_pos; + if (v->u.air.state != prev_state) UpdateAircraftCache(v); return true; } diff --git a/src/newgrf_callbacks.h b/src/newgrf_callbacks.h index afdead10ed..05327ea881 100644 --- a/src/newgrf_callbacks.h +++ b/src/newgrf_callbacks.h @@ -133,6 +133,10 @@ enum CallbackID { /* Called monthly on production changes, so it can be adjusted more frequently */ CBID_INDUSTRY_MONTHLYPROD_CHANGE= 0x35, // not yet implemented + /* Called to modify various vehicle properties. Callback parameter 1 + * specifies the property index, as used in Action 0, to change. */ + CBID_VEHICLE_MODIFY_PROPERTY = 0x36, + /* Called to determine text to display after cargo name */ CBID_INDUSTRY_CARGO_SUFFIX = 0x37, // not yet implemented diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index a75107f66e..14802dfd68 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -935,6 +935,17 @@ uint16 GetVehicleCallbackParent(uint16 callback, uint32 param1, uint32 param2, E return group->g.callback.result; } + +/* Callback 36 handler */ +uint GetVehicleProperty(const Vehicle *v, uint8 property, uint orig_value) +{ + uint16 callback = GetVehicleCallback(CBID_VEHICLE_MODIFY_PROPERTY, property, 0, v->engine_type, v); + if (callback != CALLBACK_FAILED) return callback; + + return orig_value; +} + + static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_random_bits, bool first) { const SpriteGroup *group; diff --git a/src/newgrf_engine.h b/src/newgrf_engine.h index 5d24e76abc..4f3c4d5474 100644 --- a/src/newgrf_engine.h +++ b/src/newgrf_engine.h @@ -35,6 +35,10 @@ bool UsesWagonOverride(const Vehicle *v); #define GetCustomVehicleSprite(v, direction) GetCustomEngineSprite(v->engine_type, v, direction) #define GetCustomVehicleIcon(et, direction) GetCustomEngineSprite(et, NULL, direction) +/* Handler to Evaluate callback 36. If the callback fails (i.e. most of the + * time) orig_value is returned */ +uint GetVehicleProperty(const Vehicle *v, uint8 property, uint orig_value); + enum VehicleTrigger { VEHICLE_TRIGGER_NEW_CARGO = 1, /* Externally triggered only for the first vehicle in chain */ diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 19f8d19c50..02d0c1f2d2 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -406,7 +406,7 @@ static bool ShipAccelerate(Vehicle *v) uint spd; byte t; - spd = min(v->cur_speed + 1, v->max_speed); + spd = min(v->cur_speed + 1, GetVehicleProperty(v, 0x0B, v->max_speed)); /*updates statusbar only if speed have changed to save CPU time */ if (spd != v->cur_speed) { diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 4855ef8e07..81f0b513d1 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -63,7 +63,7 @@ byte FreightWagonMult(CargoID cargo) */ void TrainPowerChanged(Vehicle* v) { - uint32 power = 0; + uint32 total_power = 0; uint32 max_te = 0; for (const Vehicle *u = v; u != NULL; u = u->next) { @@ -76,19 +76,22 @@ void TrainPowerChanged(Vehicle* v) const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type); - if (engine_has_power && rvi_u->power != 0) { - power += rvi_u->power; - /* Tractive effort in (tonnes * 1000 * 10 =) N */ - max_te += (u->u.rail.cached_veh_weight * 10000 * rvi_u->tractive_effort) / 256; + if (engine_has_power) { + uint16 power = GetVehicleProperty(u, 0x0B, rvi_u->power); + if (power != 0) { + total_power += power; + /* Tractive effort in (tonnes * 1000 * 10 =) N */ + max_te += (u->u.rail.cached_veh_weight * 10000 * GetVehicleProperty(u, 0x1F, rvi_u->tractive_effort)) / 256; + } } if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) { - power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power; + total_power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power; } } - if (v->u.rail.cached_power != power || v->u.rail.cached_max_te != max_te) { - v->u.rail.cached_power = power; + if (v->u.rail.cached_power != total_power || v->u.rail.cached_max_te != max_te) { + v->u.rail.cached_power = total_power; v->u.rail.cached_max_te = max_te; InvalidateWindow(WC_VEHICLE_DETAILS, v->index); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); @@ -208,9 +211,10 @@ void TrainConsistChanged(Vehicle* v) } /* max speed is the minimum of the speed limits of all vehicles in the consist */ - if ((rvi_u->railveh_type != RAILVEH_WAGON || _patches.wagon_speed_limits) && - rvi_u->max_speed != 0 && !UsesWagonOverride(u)) - max_speed = min(rvi_u->max_speed, max_speed); + if ((rvi_u->railveh_type != RAILVEH_WAGON || _patches.wagon_speed_limits) && !UsesWagonOverride(u)) { + uint16 speed = GetVehicleProperty(u, 0x09, rvi_u->max_speed); + if (speed != 0) max_speed = min(speed, max_speed); + } } /* check the vehicle length (callback) */ @@ -3473,8 +3477,11 @@ int32 GetTrainRunningCost(const Vehicle *v) do { const RailVehicleInfo *rvi = RailVehInfo(v->engine_type); - if (rvi->running_cost_base > 0) - cost += rvi->running_cost_base * _price.running_rail[rvi->running_cost_class]; + + byte cost_factor = GetVehicleProperty(v, 0x0D, rvi->running_cost_base); + if (cost_factor == 0) continue; + + cost += cost_factor * _price.running_rail[rvi->running_cost_class]; } while ((v = GetNextVehicle(v)) != NULL); return cost; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index e6ccce3235..b902014fa3 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -251,6 +251,8 @@ void AfterLoadVehicles() Vehicle *rotor = shadow->next; rotor->cur_image = GetRotorImage(v); } + + UpdateAircraftCache(v); } break; default: break; diff --git a/src/vehicle.h b/src/vehicle.h index 8757b14f92..b198d5b5ad 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -166,6 +166,7 @@ enum { struct VehicleAir { uint16 crashed_counter; + uint16 cached_max_speed; byte pos; byte previous_pos; StationID targetairport;