61 * Recalculates the cached total power of a train. Should be called when the consist is changed |
61 * Recalculates the cached total power of a train. Should be called when the consist is changed |
62 * @param v First vehicle of the consist. |
62 * @param v First vehicle of the consist. |
63 */ |
63 */ |
64 void TrainPowerChanged(Vehicle* v) |
64 void TrainPowerChanged(Vehicle* v) |
65 { |
65 { |
66 uint32 power = 0; |
66 uint32 total_power = 0; |
67 uint32 max_te = 0; |
67 uint32 max_te = 0; |
68 |
68 |
69 for (const Vehicle *u = v; u != NULL; u = u->next) { |
69 for (const Vehicle *u = v; u != NULL; u = u->next) { |
70 /* Power is not added for articulated parts */ |
70 /* Power is not added for articulated parts */ |
71 if (IsArticulatedPart(u)) continue; |
71 if (IsArticulatedPart(u)) continue; |
74 bool engine_has_power = HasPowerOnRail(u->u.rail.railtype, railtype); |
74 bool engine_has_power = HasPowerOnRail(u->u.rail.railtype, railtype); |
75 bool wagon_has_power = HasPowerOnRail(v->u.rail.railtype, railtype); |
75 bool wagon_has_power = HasPowerOnRail(v->u.rail.railtype, railtype); |
76 |
76 |
77 const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type); |
77 const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type); |
78 |
78 |
79 if (engine_has_power && rvi_u->power != 0) { |
79 if (engine_has_power) { |
80 power += rvi_u->power; |
80 uint16 power = GetVehicleProperty(u, 0x0B, rvi_u->power); |
81 /* Tractive effort in (tonnes * 1000 * 10 =) N */ |
81 if (power != 0) { |
82 max_te += (u->u.rail.cached_veh_weight * 10000 * rvi_u->tractive_effort) / 256; |
82 total_power += power; |
|
83 /* Tractive effort in (tonnes * 1000 * 10 =) N */ |
|
84 max_te += (u->u.rail.cached_veh_weight * 10000 * GetVehicleProperty(u, 0x1F, rvi_u->tractive_effort)) / 256; |
|
85 } |
83 } |
86 } |
84 |
87 |
85 if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) { |
88 if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) { |
86 power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power; |
89 total_power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power; |
87 } |
90 } |
88 } |
91 } |
89 |
92 |
90 if (v->u.rail.cached_power != power || v->u.rail.cached_max_te != max_te) { |
93 if (v->u.rail.cached_power != total_power || v->u.rail.cached_max_te != max_te) { |
91 v->u.rail.cached_power = power; |
94 v->u.rail.cached_power = total_power; |
92 v->u.rail.cached_max_te = max_te; |
95 v->u.rail.cached_max_te = max_te; |
93 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
96 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
94 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
97 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
95 } |
98 } |
96 } |
99 } |
206 u->u.rail.railtype = RAILTYPE_RAIL; |
209 u->u.rail.railtype = RAILTYPE_RAIL; |
207 u->u.rail.compatible_railtypes |= (1 << RAILTYPE_RAIL); |
210 u->u.rail.compatible_railtypes |= (1 << RAILTYPE_RAIL); |
208 } |
211 } |
209 |
212 |
210 /* max speed is the minimum of the speed limits of all vehicles in the consist */ |
213 /* max speed is the minimum of the speed limits of all vehicles in the consist */ |
211 if ((rvi_u->railveh_type != RAILVEH_WAGON || _patches.wagon_speed_limits) && |
214 if ((rvi_u->railveh_type != RAILVEH_WAGON || _patches.wagon_speed_limits) && !UsesWagonOverride(u)) { |
212 rvi_u->max_speed != 0 && !UsesWagonOverride(u)) |
215 uint16 speed = GetVehicleProperty(u, 0x09, rvi_u->max_speed); |
213 max_speed = min(rvi_u->max_speed, max_speed); |
216 if (speed != 0) max_speed = min(speed, max_speed); |
|
217 } |
214 } |
218 } |
215 |
219 |
216 /* check the vehicle length (callback) */ |
220 /* check the vehicle length (callback) */ |
217 uint16 veh_len = CALLBACK_FAILED; |
221 uint16 veh_len = CALLBACK_FAILED; |
218 if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) { |
222 if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) { |
1979 |
1983 |
1980 TrainFindDepotData tfdd = FindClosestTrainDepot(v, 0); |
1984 TrainFindDepotData tfdd = FindClosestTrainDepot(v, 0); |
1981 if (tfdd.best_length == (uint)-1) return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO); |
1985 if (tfdd.best_length == (uint)-1) return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO); |
1982 |
1986 |
1983 if (flags & DC_EXEC) { |
1987 if (flags & DC_EXEC) { |
|
1988 if (v->current_order.type == OT_LOADING) v->LeaveStation(); |
|
1989 |
1984 v->dest_tile = tfdd.tile; |
1990 v->dest_tile = tfdd.tile; |
1985 v->current_order.type = OT_GOTO_DEPOT; |
1991 v->current_order.type = OT_GOTO_DEPOT; |
1986 v->current_order.flags = OF_NON_STOP; |
1992 v->current_order.flags = OF_NON_STOP; |
1987 if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT); |
1993 if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT); |
1988 v->current_order.dest = GetDepotByTile(tfdd.tile)->index; |
1994 v->current_order.dest = GetDepotByTile(tfdd.tile)->index; |
1989 v->current_order.refit_cargo = CT_INVALID; |
1995 v->current_order.refit_cargo = CT_INVALID; |
1990 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
1996 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
1991 /* If there is no depot in front, reverse automatically */ |
1997 /* If there is no depot in front, reverse automatically */ |
1992 if (tfdd.reverse) |
1998 if (tfdd.reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION); |
1993 DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION); |
|
1994 } |
1999 } |
1995 |
2000 |
1996 return 0; |
2001 return 0; |
1997 } |
2002 } |
1998 |
2003 |
2982 v->progress = 255 - 100; |
2987 v->progress = 255 - 100; |
2983 if (++v->load_unload_time_rem < _patches.wait_oneway_signal * 20) return; |
2988 if (++v->load_unload_time_rem < _patches.wait_oneway_signal * 20) return; |
2984 } else if (HasSignalOnTrackdir(gp.new_tile, i)) { |
2989 } else if (HasSignalOnTrackdir(gp.new_tile, i)) { |
2985 v->cur_speed = 0; |
2990 v->cur_speed = 0; |
2986 v->subspeed = 0; |
2991 v->subspeed = 0; |
2987 v->progress = 255-10; |
2992 v->progress = 255 - 10; |
2988 if (++v->load_unload_time_rem < _patches.wait_twoway_signal * 73) { |
2993 if (++v->load_unload_time_rem < _patches.wait_twoway_signal * 73) { |
2989 TileIndex o_tile = gp.new_tile + TileOffsByDiagDir(enterdir); |
2994 TileIndex o_tile = gp.new_tile + TileOffsByDiagDir(enterdir); |
2990 VehicleAtSignalData vasd; |
2995 VehicleAtSignalData vasd; |
2991 vasd.tile = o_tile; |
2996 vasd.tile = o_tile; |
2992 vasd.direction = ReverseDir(dir); |
2997 vasd.direction = ReverseDir(dir); |
3105 /** |
3110 /** |
3106 * Deletes/Clears the last wagon of a crashed train. It takes the engine of the |
3111 * Deletes/Clears the last wagon of a crashed train. It takes the engine of the |
3107 * train, then goes to the last wagon and deletes that. Each call to this function |
3112 * train, then goes to the last wagon and deletes that. Each call to this function |
3108 * will remove the last wagon of a crashed train. If this wagon was on a crossing, |
3113 * will remove the last wagon of a crashed train. If this wagon was on a crossing, |
3109 * or inside a tunnel, recalculate the signals as they might need updating |
3114 * or inside a tunnel, recalculate the signals as they might need updating |
3110 * @param v the @Vehicle of which last wagon is to be removed |
3115 * @param v the Vehicle of which last wagon is to be removed |
3111 */ |
3116 */ |
3112 static void DeleteLastWagon(Vehicle *v) |
3117 static void DeleteLastWagon(Vehicle *v) |
3113 { |
3118 { |
3114 /* Go to the last wagon and delete the link pointing there |
3119 /* Go to the last wagon and delete the link pointing there |
3115 * *u is then the one-before-last wagon, and *v the last |
3120 * *u is then the one-before-last wagon, and *v the last |
3471 { |
3476 { |
3472 int32 cost = 0; |
3477 int32 cost = 0; |
3473 |
3478 |
3474 do { |
3479 do { |
3475 const RailVehicleInfo *rvi = RailVehInfo(v->engine_type); |
3480 const RailVehicleInfo *rvi = RailVehInfo(v->engine_type); |
3476 if (rvi->running_cost_base > 0) |
3481 |
3477 cost += rvi->running_cost_base * _price.running_rail[rvi->running_cost_class]; |
3482 byte cost_factor = GetVehicleProperty(v, 0x0D, rvi->running_cost_base); |
|
3483 if (cost_factor == 0) continue; |
|
3484 |
|
3485 cost += cost_factor * _price.running_rail[rvi->running_cost_class]; |
3478 } while ((v = GetNextVehicle(v)) != NULL); |
3486 } while ((v = GetNextVehicle(v)) != NULL); |
3479 |
3487 |
3480 return cost; |
3488 return cost; |
3481 } |
3489 } |
3482 |
3490 |