src/train_cmd.cpp
changeset 6943 1914f26aee04
parent 6924 f2ac2b1f5d06
child 6950 14ecb0acdfb4
equal deleted inserted replaced
6942:9a0a07c109d0 6943:1914f26aee04
   500 		}
   500 		}
   501 	}
   501 	}
   502 	DrawSprite(image, pal, x, y);
   502 	DrawSprite(image, pal, x, y);
   503 }
   503 }
   504 
   504 
   505 static int32 CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags)
   505 static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags)
   506 {
   506 {
   507 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   507 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   508 
   508 
   509 	const RailVehicleInfo *rvi = RailVehInfo(engine);
   509 	const RailVehicleInfo *rvi = RailVehInfo(engine);
   510 	int32 value = (GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8;
   510 	CommandCost value = (GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8;
   511 
   511 
   512 	uint num_vehicles = 1 + CountArticulatedParts(engine);
   512 	uint num_vehicles = 1 + CountArticulatedParts(engine);
   513 
   513 
   514 	if (!(flags & DC_QUERY_COST)) {
   514 	if (!(flags & DC_QUERY_COST)) {
   515 		Vehicle *vl[11]; // Allow for wagon and upto 10 artic parts.
   515 		Vehicle *vl[11]; // Allow for wagon and upto 10 artic parts.
   609 				break;
   609 				break;
   610 		}
   610 		}
   611 	}
   611 	}
   612 }
   612 }
   613 
   613 
   614 static int32 EstimateTrainCost(EngineID engine, const RailVehicleInfo* rvi)
   614 static CommandCost EstimateTrainCost(EngineID engine, const RailVehicleInfo* rvi)
   615 {
   615 {
   616 	return GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5;
   616 	return GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5;
   617 }
   617 }
   618 
   618 
   619 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
   619 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
   649  * @param flags type of operation
   649  * @param flags type of operation
   650  * @param p1 engine type id
   650  * @param p1 engine type id
   651  * @param p2 bit 0 when set, the train will get number 0, otherwise it will get a free number
   651  * @param p2 bit 0 when set, the train will get number 0, otherwise it will get a free number
   652  *           bit 1 prevents any free cars from being added to the train
   652  *           bit 1 prevents any free cars from being added to the train
   653  */
   653  */
   654 int32 CmdBuildRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   654 CommandCost CmdBuildRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   655 {
   655 {
   656 	/* Check if the engine-type is valid (for the player) */
   656 	/* Check if the engine-type is valid (for the player) */
   657 	if (!IsEngineBuildable(p1, VEH_TRAIN, _current_player)) return_cmd_error(STR_RAIL_VEHICLE_NOT_AVAILABLE);
   657 	if (!IsEngineBuildable(p1, VEH_TRAIN, _current_player)) return_cmd_error(STR_RAIL_VEHICLE_NOT_AVAILABLE);
   658 
   658 
   659 	/* Check if the train is actually being built in a depot belonging
   659 	/* Check if the train is actually being built in a depot belonging
   671 	/* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
   671 	/* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
   672 	if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
   672 	if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
   673 
   673 
   674 	if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(p1, tile, flags);
   674 	if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(p1, tile, flags);
   675 
   675 
   676 	int32 value = EstimateTrainCost(p1, rvi);
   676 	CommandCost value = EstimateTrainCost(p1, rvi);
   677 
   677 
   678 	uint num_vehicles =
   678 	uint num_vehicles =
   679 		(rvi->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) +
   679 		(rvi->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) +
   680 		CountArticulatedParts(p1);
   680 		CountArticulatedParts(p1);
   681 
   681 
   907  * @param p1 various bitstuffed elements
   907  * @param p1 various bitstuffed elements
   908  * - p1 (bit  0 - 15) source vehicle index
   908  * - p1 (bit  0 - 15) source vehicle index
   909  * - p1 (bit 16 - 31) what wagon to put the source wagon AFTER, XXX - INVALID_VEHICLE to make a new line
   909  * - p1 (bit 16 - 31) what wagon to put the source wagon AFTER, XXX - INVALID_VEHICLE to make a new line
   910  * @param p2 (bit 0) move all vehicles following the source vehicle
   910  * @param p2 (bit 0) move all vehicles following the source vehicle
   911  */
   911  */
   912 int32 CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   912 CommandCost CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   913 {
   913 {
   914 	VehicleID s = GB(p1, 0, 16);
   914 	VehicleID s = GB(p1, 0, 16);
   915 	VehicleID d = GB(p1, 16, 16);
   915 	VehicleID d = GB(p1, 16, 16);
   916 
   916 
   917 	if (!IsValidVehicleID(s)) return CMD_ERROR;
   917 	if (!IsValidVehicleID(s)) return CMD_ERROR;
  1160  * @param tile unused
  1160  * @param tile unused
  1161  * @param flags type of operation
  1161  * @param flags type of operation
  1162  * @param p1 train to start/stop
  1162  * @param p1 train to start/stop
  1163  * @param p2 unused
  1163  * @param p2 unused
  1164  */
  1164  */
  1165 int32 CmdStartStopTrain(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1165 CommandCost CmdStartStopTrain(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1166 {
  1166 {
  1167 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1167 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1168 
  1168 
  1169 	Vehicle *v = GetVehicle(p1);
  1169 	Vehicle *v = GetVehicle(p1);
  1170 
  1170 
  1201  * - p2 = 1: sell the vehicle and all vehicles following it in the chain
  1201  * - p2 = 1: sell the vehicle and all vehicles following it in the chain
  1202              if the wagon is dragged, don't delete the possibly belonging rear-engine to some front
  1202              if the wagon is dragged, don't delete the possibly belonging rear-engine to some front
  1203  * - p2 = 2: when selling attached locos, rearrange all vehicles after it to separate lines;
  1203  * - p2 = 2: when selling attached locos, rearrange all vehicles after it to separate lines;
  1204  *           all wagons of the same type will go on the same line. Used by the AI currently
  1204  *           all wagons of the same type will go on the same line. Used by the AI currently
  1205  */
  1205  */
  1206 int32 CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1206 CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1207 {
  1207 {
  1208 	/* Check if we deleted a vehicle window */
  1208 	/* Check if we deleted a vehicle window */
  1209 	Window *w = NULL;
  1209 	Window *w = NULL;
  1210 
  1210 
  1211 	if (!IsValidVehicleID(p1) || p2 > 2) return CMD_ERROR;
  1211 	if (!IsValidVehicleID(p1) || p2 > 2) return CMD_ERROR;
  1233 		}
  1233 		}
  1234 		InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
  1234 		InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
  1235 		RebuildVehicleLists();
  1235 		RebuildVehicleLists();
  1236 	}
  1236 	}
  1237 
  1237 
  1238 	int32 cost = 0;
  1238 	CommandCost cost = 0;
  1239 	switch (p2) {
  1239 	switch (p2) {
  1240 		case 0: case 2: { /* Delete given wagon */
  1240 		case 0: case 2: { /* Delete given wagon */
  1241 			bool switch_engine = false;    // update second wagon to engine?
  1241 			bool switch_engine = false;    // update second wagon to engine?
  1242 			byte ori_subtype = v->subtype; // backup subtype of deleted wagon in case DeleteVehicle() changes
  1242 			byte ori_subtype = v->subtype; // backup subtype of deleted wagon in case DeleteVehicle() changes
  1243 
  1243 
  1614  * @param tile unused
  1614  * @param tile unused
  1615  * @param flags type of operation
  1615  * @param flags type of operation
  1616  * @param p1 train to reverse
  1616  * @param p1 train to reverse
  1617  * @param p2 if true, reverse a unit in a train (needs to be in a depot)
  1617  * @param p2 if true, reverse a unit in a train (needs to be in a depot)
  1618  */
  1618  */
  1619 int32 CmdReverseTrainDirection(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1619 CommandCost CmdReverseTrainDirection(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1620 {
  1620 {
  1621 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1621 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1622 
  1622 
  1623 	Vehicle *v = GetVehicle(p1);
  1623 	Vehicle *v = GetVehicle(p1);
  1624 
  1624 
  1663  * @param tile unused
  1663  * @param tile unused
  1664  * @param flags type of operation
  1664  * @param flags type of operation
  1665  * @param p1 train to ignore the red signal
  1665  * @param p1 train to ignore the red signal
  1666  * @param p2 unused
  1666  * @param p2 unused
  1667  */
  1667  */
  1668 int32 CmdForceTrainProceed(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1668 CommandCost CmdForceTrainProceed(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1669 {
  1669 {
  1670 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1670 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1671 
  1671 
  1672 	Vehicle *v = GetVehicle(p1);
  1672 	Vehicle *v = GetVehicle(p1);
  1673 
  1673 
  1686  * - p2 = (bit 0-7) - the new cargo type to refit to
  1686  * - p2 = (bit 0-7) - the new cargo type to refit to
  1687  * - p2 = (bit 8-15) - the new cargo subtype to refit to
  1687  * - p2 = (bit 8-15) - the new cargo subtype to refit to
  1688  * - p2 = (bit 16) - refit only this vehicle
  1688  * - p2 = (bit 16) - refit only this vehicle
  1689  * @return cost of refit or error
  1689  * @return cost of refit or error
  1690  */
  1690  */
  1691 int32 CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1691 CommandCost CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1692 {
  1692 {
  1693 	CargoID new_cid = GB(p2, 0, 8);
  1693 	CargoID new_cid = GB(p2, 0, 8);
  1694 	byte new_subtype = GB(p2, 8, 8);
  1694 	byte new_subtype = GB(p2, 8, 8);
  1695 	bool only_this = HASBIT(p2, 16);
  1695 	bool only_this = HASBIT(p2, 16);
  1696 
  1696 
  1704 	/* Check cargo */
  1704 	/* Check cargo */
  1705 	if (new_cid >= NUM_CARGO) return CMD_ERROR;
  1705 	if (new_cid >= NUM_CARGO) return CMD_ERROR;
  1706 
  1706 
  1707 	SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
  1707 	SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
  1708 
  1708 
  1709 	int32 cost = 0;
  1709 	CommandCost cost = 0;
  1710 	uint num = 0;
  1710 	uint num = 0;
  1711 
  1711 
  1712 	do {
  1712 	do {
  1713 		/* XXX: We also refit all the attached wagons en-masse if they
  1713 		/* XXX: We also refit all the attached wagons en-masse if they
  1714 		 * can be refitted. This is how TTDPatch does it.  TODO: Have
  1714 		 * can be refitted. This is how TTDPatch does it.  TODO: Have
  1870  * @param p1 train to send to the depot
  1870  * @param p1 train to send to the depot
  1871  * @param p2 various bitmasked elements
  1871  * @param p2 various bitmasked elements
  1872  * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
  1872  * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
  1873  * - p2 bit 8-10 - VLW flag (for mass goto depot)
  1873  * - p2 bit 8-10 - VLW flag (for mass goto depot)
  1874  */
  1874  */
  1875 int32 CmdSendTrainToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1875 CommandCost CmdSendTrainToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1876 {
  1876 {
  1877 	if (p2 & DEPOT_MASS_SEND) {
  1877 	if (p2 & DEPOT_MASS_SEND) {
  1878 		/* Mass goto depot requested */
  1878 		/* Mass goto depot requested */
  1879 		if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR;
  1879 		if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR;
  1880 		return SendAllVehiclesToDepot(VEH_TRAIN, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1);
  1880 		return SendAllVehiclesToDepot(VEH_TRAIN, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1);
  3387 			if (tile != 0) v->dest_tile = tile;
  3387 			if (tile != 0) v->dest_tile = tile;
  3388 		}
  3388 		}
  3389 
  3389 
  3390 		if ((v->vehstatus & VS_STOPPED) == 0) {
  3390 		if ((v->vehstatus & VS_STOPPED) == 0) {
  3391 			/* running costs */
  3391 			/* running costs */
  3392 			int32 cost = GetTrainRunningCost(v) / 364;
  3392 			CommandCost cost = GetTrainRunningCost(v) / 364;
  3393 
  3393 
  3394 			v->profit_this_year -= cost >> 8;
  3394 			v->profit_this_year -= cost >> 8;
  3395 
  3395 
  3396 			SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
  3396 			SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
  3397 			SubtractMoneyFromPlayerFract(v->owner, cost);
  3397 			SubtractMoneyFromPlayerFract(v->owner, cost);