165 if (!IsArticulatedPart(u)) { |
165 if (!IsArticulatedPart(u)) { |
166 // check if its a powered wagon |
166 // check if its a powered wagon |
167 CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON); |
167 CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON); |
168 |
168 |
169 /* Check powered wagon / visual effect callback */ |
169 /* Check powered wagon / visual effect callback */ |
170 if (HASBIT(rvi_u->callbackmask, CBM_WAGON_POWER)) { |
170 if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_WAGON_POWER)) { |
171 uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u); |
171 uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u); |
172 |
172 |
173 if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback; |
173 if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback; |
174 } |
174 } |
175 |
175 |
192 max_speed = min(rvi_u->max_speed, max_speed); |
192 max_speed = min(rvi_u->max_speed, max_speed); |
193 } |
193 } |
194 |
194 |
195 // check the vehicle length (callback) |
195 // check the vehicle length (callback) |
196 veh_len = CALLBACK_FAILED; |
196 veh_len = CALLBACK_FAILED; |
197 if (HASBIT(rvi_u->callbackmask, CBM_VEHICLE_LENGTH)) |
197 if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) { |
198 veh_len = GetVehicleCallback(CBID_TRAIN_VEHICLE_LENGTH, 0, 0, u->engine_type, u); |
198 veh_len = GetVehicleCallback(CBID_TRAIN_VEHICLE_LENGTH, 0, 0, u->engine_type, u); |
199 if (veh_len == CALLBACK_FAILED) |
199 } |
200 veh_len = rvi_u->shorten_factor; |
200 if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor; |
201 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 |
201 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 |
202 u->u.rail.cached_veh_length = 8 - veh_len; |
202 u->u.rail.cached_veh_length = 8 - veh_len; |
203 v->u.rail.cached_total_length += u->u.rail.cached_veh_length; |
203 v->u.rail.cached_total_length += u->u.rail.cached_veh_length; |
204 |
204 |
205 }; |
205 }; |
472 } |
472 } |
473 } |
473 } |
474 DrawSprite(image | image_ormod, x, y); |
474 DrawSprite(image | image_ormod, x, y); |
475 } |
475 } |
476 |
476 |
477 static uint CountArticulatedParts(const RailVehicleInfo *rvi, EngineID engine_type) |
477 static uint CountArticulatedParts(EngineID engine_type) |
478 { |
478 { |
479 uint16 callback; |
479 uint16 callback; |
480 uint i; |
480 uint i; |
481 |
481 |
482 if (!HASBIT(rvi->callbackmask, CBM_ARTIC_ENGINE)) return 0; |
482 if (!HASBIT(EngInfo(engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return 0; |
483 |
483 |
484 for (i = 1; i < 10; i++) { |
484 for (i = 1; i < 10; i++) { |
485 callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, engine_type, NULL); |
485 callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, engine_type, NULL); |
486 if (callback == CALLBACK_FAILED || callback == 0xFF) break; |
486 if (callback == CALLBACK_FAILED || callback == 0xFF) break; |
487 } |
487 } |
488 |
488 |
489 return i - 1; |
489 return i - 1; |
490 } |
490 } |
491 |
491 |
492 static void AddArticulatedParts(const RailVehicleInfo *rvi, Vehicle **vl) |
492 static void AddArticulatedParts(Vehicle **vl) |
493 { |
493 { |
494 const RailVehicleInfo *rvi_artic; |
494 const RailVehicleInfo *rvi_artic; |
495 EngineID engine_type; |
495 EngineID engine_type; |
496 Vehicle *v = vl[0]; |
496 Vehicle *v = vl[0]; |
497 Vehicle *u = v; |
497 Vehicle *u = v; |
498 uint16 callback; |
498 uint16 callback; |
499 bool flip_image; |
499 bool flip_image; |
500 uint i; |
500 uint i; |
501 |
501 |
502 if (!HASBIT(rvi->callbackmask, CBM_ARTIC_ENGINE)) return; |
502 if (!HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return; |
503 |
503 |
504 for (i = 1; i < 10; i++) { |
504 for (i = 1; i < 10; i++) { |
505 callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, v->engine_type, NULL); |
505 callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, v->engine_type, NULL); |
506 if (callback == CALLBACK_FAILED || callback == 0xFF) return; |
506 if (callback == CALLBACK_FAILED || callback == 0xFF) return; |
507 |
507 |
555 SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); |
555 SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); |
556 |
556 |
557 rvi = RailVehInfo(engine); |
557 rvi = RailVehInfo(engine); |
558 value = (rvi->base_cost * _price.build_railwagon) >> 8; |
558 value = (rvi->base_cost * _price.build_railwagon) >> 8; |
559 |
559 |
560 num_vehicles = 1 + CountArticulatedParts(rvi, engine); |
560 num_vehicles = 1 + CountArticulatedParts(engine); |
561 |
561 |
562 if (!(flags & DC_QUERY_COST)) { |
562 if (!(flags & DC_QUERY_COST)) { |
563 Vehicle *vl[11]; // Allow for wagon and upto 10 artic parts. |
563 Vehicle *vl[11]; // Allow for wagon and upto 10 artic parts. |
564 Vehicle* v; |
564 Vehicle* v; |
565 int x; |
565 int x; |
622 v->build_year = _cur_year; |
622 v->build_year = _cur_year; |
623 v->type = VEH_Train; |
623 v->type = VEH_Train; |
624 v->cur_image = 0xAC2; |
624 v->cur_image = 0xAC2; |
625 v->random_bits = VehicleRandomBits(); |
625 v->random_bits = VehicleRandomBits(); |
626 |
626 |
627 AddArticulatedParts(rvi, vl); |
627 AddArticulatedParts(vl); |
628 |
628 |
629 _new_vehicle_id = v->index; |
629 _new_vehicle_id = v->index; |
630 |
630 |
631 VehiclePositionChanged(v); |
631 VehiclePositionChanged(v); |
632 TrainConsistChanged(GetFirstVehicleInChain(v)); |
632 TrainConsistChanged(GetFirstVehicleInChain(v)); |
728 if (rvi->flags & RVI_WAGON) return CmdBuildRailWagon(p1, tile, flags); |
728 if (rvi->flags & RVI_WAGON) return CmdBuildRailWagon(p1, tile, flags); |
729 |
729 |
730 value = EstimateTrainCost(rvi); |
730 value = EstimateTrainCost(rvi); |
731 |
731 |
732 num_vehicles = (rvi->flags & RVI_MULTIHEAD) ? 2 : 1; |
732 num_vehicles = (rvi->flags & RVI_MULTIHEAD) ? 2 : 1; |
733 num_vehicles += CountArticulatedParts(rvi, p1); |
733 num_vehicles += CountArticulatedParts(p1); |
734 |
734 |
735 if (!(flags & DC_QUERY_COST)) { |
735 if (!(flags & DC_QUERY_COST)) { |
736 Vehicle *vl[12]; // Allow for upto 10 artic parts and dual-heads |
736 Vehicle *vl[12]; // Allow for upto 10 artic parts and dual-heads |
737 if (!AllocateVehicles(vl, num_vehicles) || IsOrderPoolFull()) |
737 if (!AllocateVehicles(vl, num_vehicles) || IsOrderPoolFull()) |
738 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
738 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
798 * vl[0] is the front and vl[1] is the rear |
798 * vl[0] is the front and vl[1] is the rear |
799 */ |
799 */ |
800 vl[0]->u.rail.other_multiheaded_part = vl[1]; |
800 vl[0]->u.rail.other_multiheaded_part = vl[1]; |
801 vl[1]->u.rail.other_multiheaded_part = vl[0]; |
801 vl[1]->u.rail.other_multiheaded_part = vl[0]; |
802 } else { |
802 } else { |
803 AddArticulatedParts(rvi, vl); |
803 AddArticulatedParts(vl); |
804 } |
804 } |
805 |
805 |
806 TrainConsistChanged(v); |
806 TrainConsistChanged(v); |
807 UpdateTrainAcceleration(v); |
807 UpdateTrainAcceleration(v); |
808 |
808 |
1664 |
1664 |
1665 if (p2) { |
1665 if (p2) { |
1666 // turn a single unit around |
1666 // turn a single unit around |
1667 Vehicle *front; |
1667 Vehicle *front; |
1668 |
1668 |
1669 if (IsMultiheaded(v) || HASBIT(RailVehInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) { |
1669 if (IsMultiheaded(v) || HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) { |
1670 return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT); |
1670 return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT); |
1671 } |
1671 } |
1672 |
1672 |
1673 front = GetFirstVehicleInChain(v); |
1673 front = GetFirstVehicleInChain(v); |
1674 // make sure the vehicle is stopped in the depot |
1674 // make sure the vehicle is stopped in the depot |
1754 |
1754 |
1755 if (v->cargo_cap != 0) { |
1755 if (v->cargo_cap != 0) { |
1756 const RailVehicleInfo *rvi = RailVehInfo(v->engine_type); |
1756 const RailVehicleInfo *rvi = RailVehInfo(v->engine_type); |
1757 uint16 amount = CALLBACK_FAILED; |
1757 uint16 amount = CALLBACK_FAILED; |
1758 |
1758 |
1759 if (HASBIT(rvi->callbackmask, CBM_REFIT_CAPACITY)) { |
1759 if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) { |
1760 /* Check the 'refit capacity' callback */ |
1760 /* Check the 'refit capacity' callback */ |
1761 CargoID temp_cid = v->cargo_type; |
1761 CargoID temp_cid = v->cargo_type; |
1762 v->cargo_type = new_cid; |
1762 v->cargo_type = new_cid; |
1763 amount = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, v->engine_type, v); |
1763 amount = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, v->engine_type, v); |
1764 v->cargo_type = temp_cid; |
1764 v->cargo_type = temp_cid; |