train_cmd.c
changeset 3956 92362ba224b7
parent 3955 b96f96b31403
child 3977 513433ebd092
equal deleted inserted replaced
3955:b96f96b31403 3956:92362ba224b7
   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;