88 /* Tractive effort in (tonnes * 1000 * 10 =) N */ |
88 /* Tractive effort in (tonnes * 1000 * 10 =) N */ |
89 max_te += (u->u.rail.cached_veh_weight * 10000 * GetVehicleProperty(u, 0x1F, rvi_u->tractive_effort)) / 256; |
89 max_te += (u->u.rail.cached_veh_weight * 10000 * GetVehicleProperty(u, 0x1F, rvi_u->tractive_effort)) / 256; |
90 } |
90 } |
91 } |
91 } |
92 |
92 |
93 if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) { |
93 if (HasBit(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) { |
94 total_power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power; |
94 total_power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power; |
95 } |
95 } |
96 } |
96 } |
97 |
97 |
98 if (v->u.rail.cached_power != total_power || v->u.rail.cached_max_te != max_te) { |
98 if (v->u.rail.cached_power != total_power || v->u.rail.cached_max_te != max_te) { |
123 if (!IsArticulatedPart(u)) { |
123 if (!IsArticulatedPart(u)) { |
124 /* vehicle weight is the sum of the weight of the vehicle and the weight of its cargo */ |
124 /* vehicle weight is the sum of the weight of the vehicle and the weight of its cargo */ |
125 vweight += GetVehicleProperty(u, 0x16, RailVehInfo(u->engine_type)->weight); |
125 vweight += GetVehicleProperty(u, 0x16, RailVehInfo(u->engine_type)->weight); |
126 |
126 |
127 /* powered wagons have extra weight added */ |
127 /* powered wagons have extra weight added */ |
128 if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON)) |
128 if (HasBit(u->u.rail.flags, VRF_POWEREDWAGON)) |
129 vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight; |
129 vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight; |
130 } |
130 } |
131 |
131 |
132 /* consist weight is the sum of the weight of all vehicles in the consist */ |
132 /* consist weight is the sum of the weight of all vehicles in the consist */ |
133 weight += vweight; |
133 weight += vweight; |
195 } |
195 } |
196 } |
196 } |
197 |
197 |
198 if (!IsArticulatedPart(u)) { |
198 if (!IsArticulatedPart(u)) { |
199 /* Check powered wagon / visual effect callback */ |
199 /* Check powered wagon / visual effect callback */ |
200 if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_TRAIN_WAGON_POWER)) { |
200 if (HasBit(EngInfo(u->engine_type)->callbackmask, CBM_TRAIN_WAGON_POWER)) { |
201 uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u); |
201 uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u); |
202 |
202 |
203 if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback; |
203 if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback; |
204 } |
204 } |
205 |
205 |
206 if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON && |
206 if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON && |
207 UsesWagonOverride(u) && !HASBIT(u->u.rail.cached_vis_effect, 7)) { |
207 UsesWagonOverride(u) && !HasBit(u->u.rail.cached_vis_effect, 7)) { |
208 /* wagon is powered */ |
208 /* wagon is powered */ |
209 SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status |
209 SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status |
210 } else { |
210 } else { |
211 CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON); |
211 CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON); |
212 } |
212 } |
217 v->u.rail.compatible_railtypes |= GetRailTypeInfo(u->u.rail.railtype)->powered_railtypes; |
217 v->u.rail.compatible_railtypes |= GetRailTypeInfo(u->u.rail.railtype)->powered_railtypes; |
218 } |
218 } |
219 |
219 |
220 /* Some electric engines can be allowed to run on normal rail. It happens to all |
220 /* Some electric engines can be allowed to run on normal rail. It happens to all |
221 * existing electric engines when elrails are disabled and then re-enabled */ |
221 * existing electric engines when elrails are disabled and then re-enabled */ |
222 if (HASBIT(u->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL)) { |
222 if (HasBit(u->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL)) { |
223 u->u.rail.railtype = RAILTYPE_RAIL; |
223 u->u.rail.railtype = RAILTYPE_RAIL; |
224 u->u.rail.compatible_railtypes |= (1 << RAILTYPE_RAIL); |
224 u->u.rail.compatible_railtypes |= (1 << RAILTYPE_RAIL); |
225 } |
225 } |
226 |
226 |
227 /* max speed is the minimum of the speed limits of all vehicles in the consist */ |
227 /* max speed is the minimum of the speed limits of all vehicles in the consist */ |
238 |
238 |
239 u->u.rail.user_def_data = GetVehicleProperty(u, 0x25, rvi_u->user_def_data); |
239 u->u.rail.user_def_data = GetVehicleProperty(u, 0x25, rvi_u->user_def_data); |
240 |
240 |
241 /* check the vehicle length (callback) */ |
241 /* check the vehicle length (callback) */ |
242 uint16 veh_len = CALLBACK_FAILED; |
242 uint16 veh_len = CALLBACK_FAILED; |
243 if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) { |
243 if (HasBit(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) { |
244 veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, u->engine_type, u); |
244 veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, u->engine_type, u); |
245 } |
245 } |
246 if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor; |
246 if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor; |
247 veh_len = Clamp(veh_len, 0, u->Next() == NULL ? 7 : 5); // the clamp on vehicles not the last in chain is stricter, as too short wagons can break the 'follow next vehicle' code |
247 veh_len = Clamp(veh_len, 0, u->Next() == NULL ? 7 : 5); // the clamp on vehicles not the last in chain is stricter, as too short wagons can break the 'follow next vehicle' code |
248 u->u.rail.cached_veh_length = 8 - veh_len; |
248 u->u.rail.cached_veh_length = 8 - veh_len; |
384 num++; |
384 num++; |
385 drag_coeff += 3; |
385 drag_coeff += 3; |
386 |
386 |
387 if (u->u.rail.track == TRACK_BIT_DEPOT) max_speed = min(max_speed, 61); |
387 if (u->u.rail.track == TRACK_BIT_DEPOT) max_speed = min(max_speed, 61); |
388 |
388 |
389 if (HASBIT(u->u.rail.flags, VRF_GOINGUP)) { |
389 if (HasBit(u->u.rail.flags, VRF_GOINGUP)) { |
390 incl += u->u.rail.cached_veh_weight * 60; //3% slope, quite a bit actually |
390 incl += u->u.rail.cached_veh_weight * 60; //3% slope, quite a bit actually |
391 } else if (HASBIT(u->u.rail.flags, VRF_GOINGDOWN)) { |
391 } else if (HasBit(u->u.rail.flags, VRF_GOINGDOWN)) { |
392 incl -= u->u.rail.cached_veh_weight * 60; |
392 incl -= u->u.rail.cached_veh_weight * 60; |
393 } |
393 } |
394 } |
394 } |
395 |
395 |
396 v->max_speed = max_speed; |
396 v->max_speed = max_speed; |
461 int Train::GetImage(Direction direction) const |
461 int Train::GetImage(Direction direction) const |
462 { |
462 { |
463 int img = this->spritenum; |
463 int img = this->spritenum; |
464 int base; |
464 int base; |
465 |
465 |
466 if (HASBIT(this->u.rail.flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction); |
466 if (HasBit(this->u.rail.flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction); |
467 |
467 |
468 if (is_custom_sprite(img)) { |
468 if (is_custom_sprite(img)) { |
469 base = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img))); |
469 base = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img))); |
470 if (base != 0) return base; |
470 if (base != 0) return base; |
471 img = orig_rail_vehicle_info[this->engine_type].image_index; |
471 img = orig_rail_vehicle_info[this->engine_type].image_index; |
699 if (!Vehicle::AllocateList(vl, num_vehicles)) |
699 if (!Vehicle::AllocateList(vl, num_vehicles)) |
700 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
700 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
701 |
701 |
702 Vehicle *v = vl[0]; |
702 Vehicle *v = vl[0]; |
703 |
703 |
704 UnitID unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_TRAIN); |
704 UnitID unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_TRAIN); |
705 if (unit_num > _patches.max_trains) |
705 if (unit_num > _patches.max_trains) |
706 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
706 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
707 |
707 |
708 if (flags & DC_EXEC) { |
708 if (flags & DC_EXEC) { |
709 DiagDirection dir = GetRailDepotDirection(tile); |
709 DiagDirection dir = GetRailDepotDirection(tile); |
772 |
772 |
773 TrainConsistChanged(v); |
773 TrainConsistChanged(v); |
774 UpdateTrainAcceleration(v); |
774 UpdateTrainAcceleration(v); |
775 UpdateTrainGroupID(v); |
775 UpdateTrainGroupID(v); |
776 |
776 |
777 if (!HASBIT(p2, 1)) { // check if the cars should be added to the new vehicle |
777 if (!HasBit(p2, 1)) { // check if the cars should be added to the new vehicle |
778 NormalizeTrainVehInDepot(v); |
778 NormalizeTrainVehInDepot(v); |
779 } |
779 } |
780 |
780 |
781 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); |
781 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); |
782 RebuildVehicleLists(); |
782 RebuildVehicleLists(); |
970 } |
970 } |
971 |
971 |
972 if (IsRearDualheaded(src)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR); |
972 if (IsRearDualheaded(src)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR); |
973 |
973 |
974 /* when moving all wagons, we can't have the same src_head and dst_head */ |
974 /* when moving all wagons, we can't have the same src_head and dst_head */ |
975 if (HASBIT(p2, 0) && src_head == dst_head) return CommandCost(); |
975 if (HasBit(p2, 0) && src_head == dst_head) return CommandCost(); |
976 |
976 |
977 { |
977 { |
978 int max_len = _patches.mammoth_trains ? 100 : 9; |
978 int max_len = _patches.mammoth_trains ? 100 : 9; |
979 |
979 |
980 /* check if all vehicles in the source train are stopped inside a depot. */ |
980 /* check if all vehicles in the source train are stopped inside a depot. */ |
991 if (dst_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED); |
991 if (dst_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED); |
992 } |
992 } |
993 |
993 |
994 /* We are moving between rows, so only count the wagons from the source |
994 /* We are moving between rows, so only count the wagons from the source |
995 * row that are being moved. */ |
995 * row that are being moved. */ |
996 if (HASBIT(p2, 0)) { |
996 if (HasBit(p2, 0)) { |
997 const Vehicle *u; |
997 const Vehicle *u; |
998 for (u = src_head; u != src && u != NULL; u = GetNextVehicle(u)) |
998 for (u = src_head; u != src && u != NULL; u = GetNextVehicle(u)) |
999 src_len--; |
999 src_len--; |
1000 } else { |
1000 } else { |
1001 /* If moving only one vehicle, just count that. */ |
1001 /* If moving only one vehicle, just count that. */ |
1047 v->group_id = src->group_id; |
1047 v->group_id = src->group_id; |
1048 src->group_id = DEFAULT_GROUP; |
1048 src->group_id = DEFAULT_GROUP; |
1049 } |
1049 } |
1050 } |
1050 } |
1051 |
1051 |
1052 if (HASBIT(p2, 0)) { |
1052 if (HasBit(p2, 0)) { |
1053 /* unlink ALL wagons */ |
1053 /* unlink ALL wagons */ |
1054 if (src != src_head) { |
1054 if (src != src_head) { |
1055 Vehicle *v = src_head; |
1055 Vehicle *v = src_head; |
1056 while (GetNextVehicle(v) != src) v = GetNextVehicle(v); |
1056 while (GetNextVehicle(v) != src) v = GetNextVehicle(v); |
1057 GetLastEnginePart(v)->SetNext(NULL); |
1057 GetLastEnginePart(v)->SetNext(NULL); |
1341 |
1341 |
1342 /* (6.) Borked AI. If it sells an engine it expects all wagons lined |
1342 /* (6.) Borked AI. If it sells an engine it expects all wagons lined |
1343 * up on a new line to be added to the newly built loco. Replace it is. |
1343 * up on a new line to be added to the newly built loco. Replace it is. |
1344 * Totally braindead cause building a new engine adds all loco-less |
1344 * Totally braindead cause building a new engine adds all loco-less |
1345 * engines to its train anyways */ |
1345 * engines to its train anyways */ |
1346 if (p2 == 2 && HASBIT(ori_subtype, Train_Front)) { |
1346 if (p2 == 2 && HasBit(ori_subtype, Train_Front)) { |
1347 Vehicle *tmp; |
1347 Vehicle *tmp; |
1348 for (v = first; v != NULL; v = tmp) { |
1348 for (v = first; v != NULL; v = tmp) { |
1349 tmp = GetNextVehicle(v); |
1349 tmp = GetNextVehicle(v); |
1350 DoCommand(v->tile, v->index | INVALID_VEHICLE << 16, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE); |
1350 DoCommand(v->tile, v->index | INVALID_VEHICLE << 16, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE); |
1351 } |
1351 } |
1462 CLRBIT(*swap_flag1, VRF_GOINGDOWN); |
1462 CLRBIT(*swap_flag1, VRF_GOINGDOWN); |
1463 CLRBIT(*swap_flag2, VRF_GOINGUP); |
1463 CLRBIT(*swap_flag2, VRF_GOINGUP); |
1464 CLRBIT(*swap_flag2, VRF_GOINGDOWN); |
1464 CLRBIT(*swap_flag2, VRF_GOINGDOWN); |
1465 |
1465 |
1466 /* Reverse the rail-flags (if needed) */ |
1466 /* Reverse the rail-flags (if needed) */ |
1467 if (HASBIT(flag1, VRF_GOINGUP)) { |
1467 if (HasBit(flag1, VRF_GOINGUP)) { |
1468 SETBIT(*swap_flag2, VRF_GOINGDOWN); |
1468 SETBIT(*swap_flag2, VRF_GOINGDOWN); |
1469 } else if (HASBIT(flag1, VRF_GOINGDOWN)) { |
1469 } else if (HasBit(flag1, VRF_GOINGDOWN)) { |
1470 SETBIT(*swap_flag2, VRF_GOINGUP); |
1470 SETBIT(*swap_flag2, VRF_GOINGUP); |
1471 } |
1471 } |
1472 if (HASBIT(flag2, VRF_GOINGUP)) { |
1472 if (HasBit(flag2, VRF_GOINGUP)) { |
1473 SETBIT(*swap_flag1, VRF_GOINGDOWN); |
1473 SETBIT(*swap_flag1, VRF_GOINGDOWN); |
1474 } else if (HASBIT(flag2, VRF_GOINGDOWN)) { |
1474 } else if (HasBit(flag2, VRF_GOINGDOWN)) { |
1475 SETBIT(*swap_flag1, VRF_GOINGUP); |
1475 SETBIT(*swap_flag1, VRF_GOINGUP); |
1476 } |
1476 } |
1477 } |
1477 } |
1478 |
1478 |
1479 static void ReverseTrainSwapVeh(Vehicle *v, int l, int r) |
1479 static void ReverseTrainSwapVeh(Vehicle *v, int l, int r) |
1638 if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR; |
1638 if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR; |
1639 |
1639 |
1640 if (p2) { |
1640 if (p2) { |
1641 /* turn a single unit around */ |
1641 /* turn a single unit around */ |
1642 |
1642 |
1643 if (IsMultiheaded(v) || HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) { |
1643 if (IsMultiheaded(v) || HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) { |
1644 return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT); |
1644 return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT); |
1645 } |
1645 } |
1646 |
1646 |
1647 Vehicle *front = v->First(); |
1647 Vehicle *front = v->First(); |
1648 /* make sure the vehicle is stopped in the depot */ |
1648 /* make sure the vehicle is stopped in the depot */ |
1703 */ |
1703 */ |
1704 CommandCost CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1704 CommandCost CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1705 { |
1705 { |
1706 CargoID new_cid = GB(p2, 0, 8); |
1706 CargoID new_cid = GB(p2, 0, 8); |
1707 byte new_subtype = GB(p2, 8, 8); |
1707 byte new_subtype = GB(p2, 8, 8); |
1708 bool only_this = HASBIT(p2, 16); |
1708 bool only_this = HasBit(p2, 16); |
1709 |
1709 |
1710 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
1710 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
1711 |
1711 |
1712 Vehicle *v = GetVehicle(p1); |
1712 Vehicle *v = GetVehicle(p1); |
1713 |
1713 |
1729 if (!CanRefitTo(v->engine_type, new_cid)) continue; |
1729 if (!CanRefitTo(v->engine_type, new_cid)) continue; |
1730 |
1730 |
1731 if (v->cargo_cap != 0) { |
1731 if (v->cargo_cap != 0) { |
1732 uint16 amount = CALLBACK_FAILED; |
1732 uint16 amount = CALLBACK_FAILED; |
1733 |
1733 |
1734 if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) { |
1734 if (HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) { |
1735 /* Back up the vehicle's cargo type */ |
1735 /* Back up the vehicle's cargo type */ |
1736 CargoID temp_cid = v->cargo_type; |
1736 CargoID temp_cid = v->cargo_type; |
1737 byte temp_subtype = v->cargo_subtype; |
1737 byte temp_subtype = v->cargo_subtype; |
1738 v->cargo_type = new_cid; |
1738 v->cargo_type = new_cid; |
1739 v->cargo_subtype = new_subtype; |
1739 v->cargo_subtype = new_subtype; |
1900 if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR; |
1900 if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR; |
1901 |
1901 |
1902 if (v->vehstatus & VS_CRASHED) return CMD_ERROR; |
1902 if (v->vehstatus & VS_CRASHED) return CMD_ERROR; |
1903 |
1903 |
1904 if (v->current_order.type == OT_GOTO_DEPOT) { |
1904 if (v->current_order.type == OT_GOTO_DEPOT) { |
1905 if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) { |
1905 if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OFB_HALT_IN_DEPOT)) { |
1906 /* We called with a different DEPOT_SERVICE setting. |
1906 /* We called with a different DEPOT_SERVICE setting. |
1907 * Now we change the setting to apply the new one and let the vehicle head for the same depot. |
1907 * Now we change the setting to apply the new one and let the vehicle head for the same depot. |
1908 * Note: the if is (true for requesting service == true for ordered to stop in depot) */ |
1908 * Note: the if is (true for requesting service == true for ordered to stop in depot) */ |
1909 if (flags & DC_EXEC) { |
1909 if (flags & DC_EXEC) { |
1910 CLRBIT(v->current_order.flags, OFB_PART_OF_ORDERS); |
1910 CLRBIT(v->current_order.flags, OFB_PART_OF_ORDERS); |
1914 return CommandCost(); |
1914 return CommandCost(); |
1915 } |
1915 } |
1916 |
1916 |
1917 if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders |
1917 if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders |
1918 if (flags & DC_EXEC) { |
1918 if (flags & DC_EXEC) { |
1919 if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) { |
1919 if (HasBit(v->current_order.flags, OFB_PART_OF_ORDERS)) { |
1920 v->cur_order_index++; |
1920 v->cur_order_index++; |
1921 } |
1921 } |
1922 |
1922 |
1923 v->current_order.type = OT_DUMMY; |
1923 v->current_order.type = OT_DUMMY; |
1924 v->current_order.flags = 0; |
1924 v->current_order.flags = 0; |
1972 |
1972 |
1973 do { |
1973 do { |
1974 const RailVehicleInfo *rvi = RailVehInfo(v->engine_type); |
1974 const RailVehicleInfo *rvi = RailVehInfo(v->engine_type); |
1975 int effect_offset = GB(v->u.rail.cached_vis_effect, 0, 4) - 8; |
1975 int effect_offset = GB(v->u.rail.cached_vis_effect, 0, 4) - 8; |
1976 byte effect_type = GB(v->u.rail.cached_vis_effect, 4, 2); |
1976 byte effect_type = GB(v->u.rail.cached_vis_effect, 4, 2); |
1977 bool disable_effect = HASBIT(v->u.rail.cached_vis_effect, 6); |
1977 bool disable_effect = HasBit(v->u.rail.cached_vis_effect, 6); |
1978 |
1978 |
1979 /* no smoke? */ |
1979 /* no smoke? */ |
1980 if ((rvi->railveh_type == RAILVEH_WAGON && effect_type == 0) || |
1980 if ((rvi->railveh_type == RAILVEH_WAGON && effect_type == 0) || |
1981 disable_effect || |
1981 disable_effect || |
1982 v->vehstatus & VS_HIDDEN) { |
1982 v->vehstatus & VS_HIDDEN) { |
2258 DEBUG(yapf, 4, "[NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0); |
2258 DEBUG(yapf, 4, "[NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0); |
2259 } |
2259 } |
2260 /* handle "path not found" state */ |
2260 /* handle "path not found" state */ |
2261 if (path_not_found) { |
2261 if (path_not_found) { |
2262 /* PF didn't find the route */ |
2262 /* PF didn't find the route */ |
2263 if (!HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) { |
2263 if (!HasBit(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) { |
2264 /* it is first time the problem occurred, set the "path not found" flag */ |
2264 /* it is first time the problem occurred, set the "path not found" flag */ |
2265 SETBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION); |
2265 SETBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION); |
2266 /* and notify user about the event */ |
2266 /* and notify user about the event */ |
2267 if (_patches.lost_train_warn && v->owner == _local_player) { |
2267 if (_patches.lost_train_warn && v->owner == _local_player) { |
2268 SetDParam(0, v->unitnumber); |
2268 SetDParam(0, v->unitnumber); |
2273 0); |
2273 0); |
2274 } |
2274 } |
2275 } |
2275 } |
2276 } else { |
2276 } else { |
2277 /* route found, is the train marked with "path not found" flag? */ |
2277 /* route found, is the train marked with "path not found" flag? */ |
2278 if (HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) { |
2278 if (HasBit(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) { |
2279 /* clear the flag as the PF's problem was solved */ |
2279 /* clear the flag as the PF's problem was solved */ |
2280 CLRBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION); |
2280 CLRBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION); |
2281 /* can we also delete the "News" item somehow? */ |
2281 /* can we also delete the "News" item somehow? */ |
2282 } |
2282 } |
2283 } |
2283 } |
2491 |
2491 |
2492 static int UpdateTrainSpeed(Vehicle *v) |
2492 static int UpdateTrainSpeed(Vehicle *v) |
2493 { |
2493 { |
2494 uint accel; |
2494 uint accel; |
2495 |
2495 |
2496 if (v->vehstatus & VS_STOPPED || HASBIT(v->u.rail.flags, VRF_REVERSING)) { |
2496 if (v->vehstatus & VS_STOPPED || HasBit(v->u.rail.flags, VRF_REVERSING)) { |
2497 if (_patches.realistic_acceleration) { |
2497 if (_patches.realistic_acceleration) { |
2498 accel = GetTrainAcceleration(v, AM_BRAKE) * 2; |
2498 accel = GetTrainAcceleration(v, AM_BRAKE) * 2; |
2499 } else { |
2499 } else { |
2500 accel = v->acceleration * -2; |
2500 accel = v->acceleration * -2; |
2501 } |
2501 } |
2627 static bool CheckCompatibleRail(const Vehicle *v, TileIndex tile) |
2627 static bool CheckCompatibleRail(const Vehicle *v, TileIndex tile) |
2628 { |
2628 { |
2629 return |
2629 return |
2630 IsTileOwner(tile, v->owner) && ( |
2630 IsTileOwner(tile, v->owner) && ( |
2631 !IsFrontEngine(v) || |
2631 !IsFrontEngine(v) || |
2632 HASBIT(v->u.rail.compatible_railtypes, GetRailType(tile)) |
2632 HasBit(v->u.rail.compatible_railtypes, GetRailType(tile)) |
2633 ); |
2633 ); |
2634 } |
2634 } |
2635 |
2635 |
2636 struct RailtypeSlowdownParams { |
2636 struct RailtypeSlowdownParams { |
2637 byte small_turn, large_turn; |
2637 byte small_turn, large_turn; |
2837 /* Not inside depot */ |
2837 /* Not inside depot */ |
2838 |
2838 |
2839 if (IsFrontEngine(v) && !TrainCheckIfLineEnds(v)) return; |
2839 if (IsFrontEngine(v) && !TrainCheckIfLineEnds(v)) return; |
2840 |
2840 |
2841 uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); |
2841 uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); |
2842 if (HASBIT(r, VETS_CANNOT_ENTER)) { |
2842 if (HasBit(r, VETS_CANNOT_ENTER)) { |
2843 goto invalid_rail; |
2843 goto invalid_rail; |
2844 } |
2844 } |
2845 if (HASBIT(r, VETS_ENTERED_STATION)) { |
2845 if (HasBit(r, VETS_ENTERED_STATION)) { |
2846 TrainEnterStation(v, r >> VETS_STATION_ID_OFFSET); |
2846 TrainEnterStation(v, r >> VETS_STATION_ID_OFFSET); |
2847 return; |
2847 return; |
2848 } |
2848 } |
2849 |
2849 |
2850 if (v->current_order.type == OT_LEAVESTATION) { |
2850 if (v->current_order.type == OT_LEAVESTATION) { |
2940 gp.y = (gp.y & ~0xF) | b[1]; |
2940 gp.y = (gp.y & ~0xF) | b[1]; |
2941 Direction chosen_dir = (Direction)b[2]; |
2941 Direction chosen_dir = (Direction)b[2]; |
2942 |
2942 |
2943 /* Call the landscape function and tell it that the vehicle entered the tile */ |
2943 /* Call the landscape function and tell it that the vehicle entered the tile */ |
2944 uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); |
2944 uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); |
2945 if (HASBIT(r, VETS_CANNOT_ENTER)) { |
2945 if (HasBit(r, VETS_CANNOT_ENTER)) { |
2946 goto invalid_rail; |
2946 goto invalid_rail; |
2947 } |
2947 } |
2948 |
2948 |
2949 if (IsLevelCrossingTile(v->tile) && v->Next() == NULL) { |
2949 if (IsLevelCrossingTile(v->tile) && v->Next() == NULL) { |
2950 UnbarCrossing(v->tile); |
2950 UnbarCrossing(v->tile); |
2951 MarkTileDirtyByTile(v->tile); |
2951 MarkTileDirtyByTile(v->tile); |
2952 } |
2952 } |
2953 |
2953 |
2954 if (IsFrontEngine(v)) v->load_unload_time_rem = 0; |
2954 if (IsFrontEngine(v)) v->load_unload_time_rem = 0; |
2955 |
2955 |
2956 if (!HASBIT(r, VETS_ENTERED_WORMHOLE)) { |
2956 if (!HasBit(r, VETS_ENTERED_WORMHOLE)) { |
2957 v->tile = gp.new_tile; |
2957 v->tile = gp.new_tile; |
2958 |
2958 |
2959 if (GetTileRailType(gp.new_tile) != GetTileRailType(gp.old_tile)) { |
2959 if (GetTileRailType(gp.new_tile) != GetTileRailType(gp.old_tile)) { |
2960 TrainPowerChanged(v->First()); |
2960 TrainPowerChanged(v->First()); |
2961 } |
2961 } |
2977 if (!(v->vehstatus & VS_HIDDEN)) { |
2977 if (!(v->vehstatus & VS_HIDDEN)) { |
2978 v->cur_speed = |
2978 v->cur_speed = |
2979 min(v->cur_speed, GetBridge(GetBridgeType(v->tile))->speed); |
2979 min(v->cur_speed, GetBridge(GetBridgeType(v->tile))->speed); |
2980 } |
2980 } |
2981 |
2981 |
2982 if (!(IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) || !HASBIT(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) { |
2982 if (!(IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) || !HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) { |
2983 v->x_pos = gp.x; |
2983 v->x_pos = gp.x; |
2984 v->y_pos = gp.y; |
2984 v->y_pos = gp.y; |
2985 VehiclePositionChanged(v); |
2985 VehiclePositionChanged(v); |
2986 if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v); |
2986 if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v); |
2987 continue; |
2987 continue; |
3530 } |
3530 } |
3531 } |
3531 } |
3532 |
3532 |
3533 FOR_ALL_VEHICLES(v) { |
3533 FOR_ALL_VEHICLES(v) { |
3534 if (v->type == VEH_TRAIN) { |
3534 if (v->type == VEH_TRAIN) { |
3535 if (HASBIT(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) { |
3535 if (HasBit(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) { |
3536 Vehicle *u = v; |
3536 Vehicle *u = v; |
3537 |
3537 |
3538 BEGIN_ENUM_WAGONS(u) { |
3538 BEGIN_ENUM_WAGONS(u) { |
3539 const RailVehicleInfo *rvi = RailVehInfo(u->engine_type); |
3539 const RailVehicleInfo *rvi = RailVehInfo(u->engine_type); |
3540 |
3540 |