summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engine.h1
-rw-r--r--lang/english.txt2
-rw-r--r--newgrf.c6
-rw-r--r--table/engines.h3
-rw-r--r--train_cmd.c95
-rw-r--r--train_gui.c12
-rw-r--r--vehicle.h1
7 files changed, 76 insertions, 44 deletions
diff --git a/engine.h b/engine.h
index a0b355874..2fa6b9eb0 100644
--- a/engine.h
+++ b/engine.h
@@ -27,6 +27,7 @@ typedef struct RailVehicleInfo {
// kind of visual effect to generate for a vehicle (default, steam, diesel, electric).
// Same goes for the callback result, which atm is only used to check if a wagon is powered.
byte shorten_factor; // length on main map for this type is 8 - shorten_factor
+ byte tractive_effort; ///< Tractive effort coefficient
byte user_def_data; ///! Property 0x25: "User-defined bit mask" Used only for (very few) NewGRF vehicles
} RailVehicleInfo;
diff --git a/lang/english.txt b/lang/english.txt
index 3306dedc6..59d22d20d 100644
--- a/lang/english.txt
+++ b/lang/english.txt
@@ -2604,6 +2604,7 @@ STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER :{BLACK}Cost: {C
STR_885C_BROKEN_DOWN :{RED}Broken down
STR_885D_AGE_RUNNING_COST_YR :{BLACK}Age: {LTBLUE}{STRING2}{BLACK} Running Cost: {LTBLUE}{CURRENCY}/yr
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Weight: {LTBLUE}{WEIGHT_S} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY}
+STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Weight: {LTBLUE}{WEIGHT_S} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE}
STR_885F_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY} (last year: {CURRENCY})
STR_8860_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA}
STR_8861_STOPPED :{RED}Stopped
@@ -3045,6 +3046,7 @@ STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Powered
STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Refittable to: {GOLD}
STR_PURCHASE_INFO_ALL_TYPES :All cargo types
STR_PURCHASE_INFO_ALL_BUT :All but {GOLD}
+STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Tractive Effort: {GOLD}{FORCE}
########### String for New Landscape Generator
diff --git a/newgrf.c b/newgrf.c
index 60a16a46b..ea91c1e33 100644
--- a/newgrf.c
+++ b/newgrf.c
@@ -416,6 +416,10 @@ static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf
FOR_EACH_OBJECT ei[i].callbackmask = grf_load_byte(&buf);
break;
+ case 0x1F: /* Tractive effort coefficient */
+ FOR_EACH_OBJECT rvi[i].tractive_effort = grf_load_byte(&buf);
+ break;
+
case 0x21: /* Shorter vehicle */
FOR_EACH_OBJECT rvi[i].shorten_factor = grf_load_byte(&buf);
break;
@@ -466,7 +470,6 @@ static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf
/* TODO */
/* Fall-through for unimplemented one byte long properties. */
- case 0x1F: /* Tractive effort */
case 0x20: /* Air drag */
case 0x26: /* Retire vehicle early */
/* TODO */
@@ -3692,3 +3695,4 @@ void LoadNewGRF(uint load_index, uint file_index)
CalculateRefitMasks();
}
+
diff --git a/table/engines.h b/table/engines.h
index 40389082a..08c4cea00 100644
--- a/table/engines.h
+++ b/table/engines.h
@@ -341,8 +341,9 @@ const EngineInfo orig_engine_info[] = {
* @param i capacity
* @param j cargo_type
* @param k ai_rank
+ * Tractive effort coefficient by default is the same as TTDPatch, 0.30*256=76
*/
-#define RVI(a, b, c, d, e, f, g, h, i, j, k) { a, b, c, d, e, f, g, h, h, i, j, k, 0, 0, 0, 0, 0 }
+#define RVI(a, b, c, d, e, f, g, h, i, j, k) { a, b, c, d, e, f, g, h, h, i, j, k, 0, 0, 0, 0, 76, 0 }
#define M RVI_MULTIHEAD
#define W RVI_WAGON
#define S 0
diff --git a/train_cmd.c b/train_cmd.c
index 5a4148f92..c1c5746bb 100644
--- a/train_cmd.c
+++ b/train_cmd.c
@@ -55,41 +55,6 @@ byte FreightWagonMult(CargoID cargo)
/**
- * Recalculates the cached weight of a train and its vehicles. Should be called each time the cargo on
- * the consist changes.
- * @param v First vehicle of the consist.
- */
-static void TrainCargoChanged(Vehicle* v)
-{
- Vehicle *u;
- uint32 weight = 0;
-
- for (u = v; u != NULL; u = u->next) {
- const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
- uint32 vweight = (_cargoc.weights[u->cargo_type] * u->cargo_count * FreightWagonMult(u->cargo_type)) / 16;
-
- // Vehicle weight is not added for articulated parts.
- if (!IsArticulatedPart(u)) {
- // vehicle weight is the sum of the weight of the vehicle and the weight of its cargo
- vweight += rvi->weight;
-
- // powered wagons have extra weight added
- if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON))
- vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight;
- }
-
- // consist weight is the sum of the weight of all vehicles in the consist
- weight += vweight;
-
- // store vehicle weight in cache
- u->u.rail.cached_veh_weight = vweight;
- };
-
- // store consist weight in cache
- v->u.rail.cached_weight = weight;
-}
-
-/**
* Recalculates the cached total power of a train. Should be called when the consist is changed
* @param v First vehicle of the consist.
*/
@@ -97,6 +62,7 @@ void TrainPowerChanged(Vehicle* v)
{
Vehicle* u;
uint32 power = 0;
+ uint32 max_te = 0;
for (u = v; u != NULL; u = u->next) {
const RailVehicleInfo *rvi_u;
@@ -116,19 +82,65 @@ void TrainPowerChanged(Vehicle* v)
rvi_u = RailVehInfo(u->engine_type);
- if (engine_has_power) power += rvi_u->power;
+ 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 (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) {
power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power;
}
}
- if (v->u.rail.cached_power != power) {
+ if (v->u.rail.cached_power != power || v->u.rail.cached_max_te != max_te) {
v->u.rail.cached_power = power;
+ v->u.rail.cached_max_te = max_te;
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
}
}
+
+/**
+ * Recalculates the cached weight of a train and its vehicles. Should be called each time the cargo on
+ * the consist changes.
+ * @param v First vehicle of the consist.
+ */
+static void TrainCargoChanged(Vehicle* v)
+{
+ Vehicle *u;
+ uint32 weight = 0;
+
+ for (u = v; u != NULL; u = u->next) {
+ const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
+ uint32 vweight = (_cargoc.weights[u->cargo_type] * u->cargo_count * FreightWagonMult(u->cargo_type)) / 16;
+
+ // Vehicle weight is not added for articulated parts.
+ if (!IsArticulatedPart(u)) {
+ // vehicle weight is the sum of the weight of the vehicle and the weight of its cargo
+ vweight += rvi->weight;
+
+ // powered wagons have extra weight added
+ if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON))
+ vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight;
+ }
+
+ // consist weight is the sum of the weight of all vehicles in the consist
+ weight += vweight;
+
+ // store vehicle weight in cache
+ u->u.rail.cached_veh_weight = vweight;
+ };
+
+ // store consist weight in cache
+ v->u.rail.cached_weight = weight;
+
+ /* Now update train power (tractive effort is dependent on weight) */
+ TrainPowerChanged(v);
+}
+
+
/**
* Recalculates the cached stuff of a train. Should be called each time a vehicle is added
* to/removed from the chain, and when the game is loaded.
@@ -231,9 +243,7 @@ void TrainConsistChanged(Vehicle* v)
// store consist weight/max speed in cache
v->u.rail.cached_max_speed = max_speed;
- TrainPowerChanged(v);
-
- // recalculate cached weights too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added)
+ // recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added)
TrainCargoChanged(v);
}
@@ -307,6 +317,7 @@ static int GetTrainAcceleration(Vehicle *v, bool mode)
int curvecount[2] = {0, 0};
int sum = 0;
int numcurve = 0;
+ int max_te = v->u.rail.cached_max_te; // [N]
speed *= 10;
speed /= 16;
@@ -407,6 +418,7 @@ static int GetTrainAcceleration(Vehicle *v, bool mode)
force = power / speed; //[N]
force *= 22;
force /= 10;
+ if (mode == AM_ACCEL && force > max_te) force = max_te;
break;
case RAILTYPE_MAGLEV:
@@ -415,7 +427,8 @@ static int GetTrainAcceleration(Vehicle *v, bool mode)
}
} else {
//"kickoff" acceleration
- force = max(power, (mass * 8) + resistance);
+ force = (mode == AM_ACCEL && v->u.rail.railtype != RAILTYPE_MAGLEV) ? min(max_te, power) : power;
+ force = max(force, (mass * 8) + resistance);
}
if (force <= 0) force = 10000;
diff --git a/train_gui.c b/train_gui.c
index f3e461bbc..479d0a0c4 100644
--- a/train_gui.c
+++ b/train_gui.c
@@ -232,6 +232,13 @@ void DrawTrainEnginePurchaseInfo(int x, int y, uint w, EngineID engine_number)
DrawString(x,y, STR_PURCHASE_INFO_SPEED_POWER, 0);
y += 10;
+ /* Max tractive effort - not applicable if old acceleration or maglev */
+ if (_patches.realistic_acceleration && e->railtype != RAILTYPE_MAGLEV) {
+ SetDParam(0, ((rvi->weight << multihead) * 10 * rvi->tractive_effort) / 256);
+ DrawString(x, y, STR_PURCHASE_INFO_MAX_TE, 0);
+ y += 10;
+ }
+
/* Running cost */
SetDParam(0, (rvi->running_cost_base * _price.running_rail[rvi->running_cost_class] >> 8) << multihead);
DrawString(x,y, STR_PURCHASE_INFO_RUNNINGCOST, 0);
@@ -939,7 +946,10 @@ static void DrawTrainDetailsWindow(Window *w)
SetDParam(2, v->u.rail.cached_max_speed);
SetDParam(1, v->u.rail.cached_power);
SetDParam(0, v->u.rail.cached_weight);
- DrawString(x, 25, STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, 0);
+ SetDParam(3, v->u.rail.cached_max_te / 1000);
+ DrawString(x, 25, (_patches.realistic_acceleration && v->u.rail.railtype != RAILTYPE_MAGLEV) ?
+ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :
+ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, 0);
SetDParam(0, v->profit_this_year);
SetDParam(1, v->profit_last_year);
diff --git a/vehicle.h b/vehicle.h
index 80f3939c4..10ca04903 100644
--- a/vehicle.h
+++ b/vehicle.h
@@ -62,6 +62,7 @@ typedef struct VehicleRail {
// cached values, recalculated when the cargo on a train changes (in addition to the conditions above)
uint32 cached_weight; // total weight of the consist.
uint32 cached_veh_weight; // weight of the vehicle.
+ uint32 cached_max_te; // max tractive effort of consist
/**
* Position/type of visual effect.
* bit 0 - 3 = position of effect relative to vehicle. (0 = front, 8 = centre, 15 = rear)