summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/aircraft.h6
-rw-r--r--src/aircraft_cmd.cpp24
-rw-r--r--src/newgrf_callbacks.h4
-rw-r--r--src/newgrf_engine.cpp11
-rw-r--r--src/newgrf_engine.h4
-rw-r--r--src/ship_cmd.cpp2
-rw-r--r--src/train_cmd.cpp33
-rw-r--r--src/vehicle.cpp2
-rw-r--r--src/vehicle.h1
9 files changed, 73 insertions, 14 deletions
diff --git a/src/aircraft.h b/src/aircraft.h
index 46ccdb211..eb11f755a 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 90d704460..1acf9dd4c 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 afdead10e..05327ea88 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 a75107f66..14802dfd6 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 5d24e76ab..4f3c4d547 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 19f8d19c5..02d0c1f2d 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 4855ef8e0..81f0b513d 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 e6ccce323..b902014fa 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 8757b14f9..b198d5b5a 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;