src/road_cmd.cpp
branchgamebalance
changeset 9913 e79cd19772dd
parent 9912 1ac8aac92385
equal deleted inserted replaced
9912:1ac8aac92385 9913:e79cd19772dd
   105  *                    it. Makes it possible to test whether the road bits can
   105  *                    it. Makes it possible to test whether the road bits can
   106  *                    be removed from a level crossing without physically
   106  *                    be removed from a level crossing without physically
   107  *                    removing the tram bits before the test.
   107  *                    removing the tram bits before the test.
   108  * @param p2 unused
   108  * @param p2 unused
   109  */
   109  */
   110 int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   110 CommandCost CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   111 {
   111 {
   112 	/* cost for removing inner/edge -roads */
   112 	/* cost for removing inner/edge -roads */
   113 	static const uint16 road_remove_cost[2] = {50, 18};
   113 	static const uint16 road_remove_cost[2] = {50, 18};
   114 
   114 
   115 	Town *t;
   115 	Town *t;
   164 
   164 
   165 	if (!IsTileType(tile, MP_STREET)) {
   165 	if (!IsTileType(tile, MP_STREET)) {
   166 		/* If it's the last roadtype, just clear the whole tile */
   166 		/* If it's the last roadtype, just clear the whole tile */
   167 		if (rts == RoadTypeToRoadTypes(rt)) return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   167 		if (rts == RoadTypeToRoadTypes(rt)) return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   168 
   168 
   169 		int32 cost;
   169 		CommandCost cost;
   170 		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
   170 		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
   171 			TileIndex other_end = IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile);
   171 			TileIndex other_end = IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile);
   172 			/* Pay for *every* tile of the bridge or tunnel */
   172 			/* Pay for *every* tile of the bridge or tunnel */
   173 			cost = (DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile) + 1) * _eco->GetPrice(CEconomy::REMOVE_ROAD);
   173 			cost = (DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile) + 1) * _eco->GetPrice(CEconomy::REMOVE_ROAD);
   174 			if (flags & DC_EXEC) {
   174 			if (flags & DC_EXEC) {
   299 		ROAD_ALL
   299 		ROAD_ALL
   300 	},
   300 	},
   301 };
   301 };
   302 
   302 
   303 
   303 
   304 static uint32 CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existing)
   304 static CommandCost CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existing)
   305 {
   305 {
   306 	RoadBits road_bits;
   306 	RoadBits road_bits;
   307 
   307 
   308 	if (IsSteepSlope(tileh)) {
   308 	if (IsSteepSlope(tileh)) {
   309 		if (existing == 0) {
   309 		if (existing == 0) {
   344  * @param p1 bit 0..3 road pieces to build (RoadBits)
   344  * @param p1 bit 0..3 road pieces to build (RoadBits)
   345  *           bit 4..5 road type
   345  *           bit 4..5 road type
   346  *           bit 6..7 disallowed directions to toggle
   346  *           bit 6..7 disallowed directions to toggle
   347  * @param p2 the town that is building the road (0 if not applicable)
   347  * @param p2 the town that is building the road (0 if not applicable)
   348  */
   348  */
   349 int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   349 CommandCost CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   350 {
   350 {
   351 	int32 cost = 0;
   351 	CommandCost cost = 0;
   352 	int32 ret;
   352 	CommandCost ret;
   353 	RoadBits existing = ROAD_NONE;
   353 	RoadBits existing = ROAD_NONE;
   354 	RoadBits all_bits = ROAD_NONE;
   354 	RoadBits all_bits = ROAD_NONE;
   355 	Slope tileh;
   355 	Slope tileh;
   356 
   356 
   357 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   357 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   555  * @param totype      The railtype we want to convert to
   555  * @param totype      The railtype we want to convert to
   556  * @param exec        Switches between test and execute mode
   556  * @param exec        Switches between test and execute mode
   557  * @return            The cost and state of the operation
   557  * @return            The cost and state of the operation
   558  * @retval CMD_ERROR  An error occured during the operation.
   558  * @retval CMD_ERROR  An error occured during the operation.
   559  */
   559  */
   560 int32 DoConvertStreetRail(TileIndex tile, RailType totype, bool exec)
   560 CommandCost DoConvertStreetRail(TileIndex tile, RailType totype, bool exec)
   561 {
   561 {
   562 	/* not a railroad crossing? */
   562 	/* not a railroad crossing? */
   563 	if (!IsLevelCrossing(tile)) return CMD_ERROR;
   563 	if (!IsLevelCrossing(tile)) return CMD_ERROR;
   564 
   564 
   565 	/* not owned by me? */
   565 	/* not owned by me? */
   589  * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
   589  * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
   590  * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
   590  * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
   591  * - p2 = (bit 3 + 4) - road type
   591  * - p2 = (bit 3 + 4) - road type
   592  * - p2 = (bit 5) - set road direction
   592  * - p2 = (bit 5) - set road direction
   593  */
   593  */
   594 int32 CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
   594 CommandCost CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
   595 {
   595 {
   596 	TileIndex start_tile, tile;
   596 	TileIndex start_tile, tile;
   597 	int32 cost, ret;
   597 	CommandCost cost, ret;
   598 	bool had_bridge = false;
   598 	bool had_bridge = false;
   599 	bool had_success = false;
   599 	bool had_success = false;
   600 	DisallowedRoadDirections drd = DRD_NORTHBOUND;
   600 	DisallowedRoadDirections drd = DRD_NORTHBOUND;
   601 
   601 
   602 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   602 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   669  * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1)
   669  * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1)
   670  * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
   670  * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
   671  * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
   671  * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
   672  * - p2 = (bit 3 + 4) - road type
   672  * - p2 = (bit 3 + 4) - road type
   673  */
   673  */
   674 int32 CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
   674 CommandCost CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
   675 {
   675 {
   676 	TileIndex start_tile, tile;
   676 	TileIndex start_tile, tile;
   677 	int32 cost, ret;
   677 	CommandCost cost, ret;
   678 
   678 
   679 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   679 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   680 
   680 
   681 	if (p1 >= MapSize()) return CMD_ERROR;
   681 	if (p1 >= MapSize()) return CMD_ERROR;
   682 
   682 
   706 		if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
   706 		if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
   707 
   707 
   708 		/* try to remove the halves. */
   708 		/* try to remove the halves. */
   709 		if (bits != 0) {
   709 		if (bits != 0) {
   710 			ret = DoCommand(tile, rt << 4 | bits, 0, flags, CMD_REMOVE_ROAD);
   710 			ret = DoCommand(tile, rt << 4 | bits, 0, flags, CMD_REMOVE_ROAD);
   711 			if (!CmdFailed(ret)) cost += ret;
   711 			if (CmdSucceeded(ret)) cost += ret;
   712 		}
   712 		}
   713 
   713 
   714 		if (tile == end_tile) break;
   714 		if (tile == end_tile) break;
   715 
   715 
   716 		tile += HASBIT(p2, 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
   716 		tile += HASBIT(p2, 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
   727  * @param p2 unused
   727  * @param p2 unused
   728  *
   728  *
   729  * @todo When checking for the tile slope,
   729  * @todo When checking for the tile slope,
   730  * distingush between "Flat land required" and "land sloped in wrong direction"
   730  * distingush between "Flat land required" and "land sloped in wrong direction"
   731  */
   731  */
   732 int32 CmdBuildRoadDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   732 CommandCost CmdBuildRoadDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   733 {
   733 {
   734 	int32 cost;
   734 	CommandCost cost;
   735 	Depot *dep;
   735 	Depot *dep;
   736 	Slope tileh;
   736 	Slope tileh;
   737 
   737 
   738 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   738 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   739 
   739 
   769 		MarkTileDirtyByTile(tile);
   769 		MarkTileDirtyByTile(tile);
   770 	}
   770 	}
   771 	return cost;
   771 	return cost;
   772 }
   772 }
   773 
   773 
   774 static int32 RemoveRoadDepot(TileIndex tile, uint32 flags)
   774 static CommandCost RemoveRoadDepot(TileIndex tile, uint32 flags)
   775 {
   775 {
   776 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
   776 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
   777 		return CMD_ERROR;
   777 		return CMD_ERROR;
   778 
   778 
   779 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
   779 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
   781 	if (flags & DC_EXEC) DeleteDepot(GetDepotByTile(tile));
   781 	if (flags & DC_EXEC) DeleteDepot(GetDepotByTile(tile));
   782 
   782 
   783 	return _eco->GetPrice(CEconomy::REMOVE_ROAD_DEPOT, tile, true);
   783 	return _eco->GetPrice(CEconomy::REMOVE_ROAD_DEPOT, tile, true);
   784 }
   784 }
   785 
   785 
   786 static int32 ClearTile_Road(TileIndex tile, byte flags)
   786 static CommandCost ClearTile_Road(TileIndex tile, byte flags)
   787 {
   787 {
   788 	switch (GetRoadTileType(tile)) {
   788 	switch (GetRoadTileType(tile)) {
   789 		case ROAD_TILE_NORMAL: {
   789 		case ROAD_TILE_NORMAL: {
   790 			RoadBits b = GetAllRoadBits(tile);
   790 			RoadBits b = GetAllRoadBits(tile);
   791 
   791 
   795 			if ((M(b) & (M(ROAD_NW) | M(ROAD_SW) | M(ROAD_SE) | M(ROAD_NE))) ||
   795 			if ((M(b) & (M(ROAD_NW) | M(ROAD_SW) | M(ROAD_SE) | M(ROAD_NE))) ||
   796 			    ((flags & DC_AI_BUILDING) && IsTileOwner(tile, OWNER_TOWN)) ||
   796 			    ((flags & DC_AI_BUILDING) && IsTileOwner(tile, OWNER_TOWN)) ||
   797 			    !(flags & DC_AUTO)
   797 			    !(flags & DC_AUTO)
   798 				) {
   798 				) {
   799 				RoadTypes rts = GetRoadTypes(tile);
   799 				RoadTypes rts = GetRoadTypes(tile);
   800 				int32 ret = 0;
   800 				CommandCost ret = 0;
   801 				for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
   801 				for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
   802 					if (HASBIT(rts, rt)) {
   802 					if (HASBIT(rts, rt)) {
   803 						int32 tmp_ret = DoCommand(tile, rt << 4 | GetRoadBits(tile, rt), 0, flags, CMD_REMOVE_ROAD);
   803 						CommandCost tmp_ret = DoCommand(tile, rt << 4 | GetRoadBits(tile, rt), 0, flags, CMD_REMOVE_ROAD);
   804 						if (CmdFailed(tmp_ret)) return tmp_ret;
   804 						if (CmdFailed(tmp_ret)) return tmp_ret;
   805 						ret += tmp_ret;
   805 						ret += tmp_ret;
   806 					}
   806 					}
   807 				}
   807 				}
   808 				return ret;
   808 				return ret;
   811 		}
   811 		}
   812 #undef M
   812 #undef M
   813 
   813 
   814 		case ROAD_TILE_CROSSING: {
   814 		case ROAD_TILE_CROSSING: {
   815 			RoadTypes rts = GetRoadTypes(tile);
   815 			RoadTypes rts = GetRoadTypes(tile);
   816 			int32 ret = 0;
   816 			CommandCost ret = 0;
   817 
   817 
   818 			if (flags & DC_AUTO) return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
   818 			if (flags & DC_AUTO) return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
   819 
   819 
   820 			/* Must iterate over the roadtypes in a reverse manner because
   820 			/* Must iterate over the roadtypes in a reverse manner because
   821 			 * tram tracks must be removed before the road bits. */
   821 			 * tram tracks must be removed before the road bits. */
   822 			for (RoadType rt = ROADTYPE_HWAY; rt >= ROADTYPE_ROAD; rt--) {
   822 			for (RoadType rt = ROADTYPE_HWAY; rt >= ROADTYPE_ROAD; rt--) {
   823 				if (HASBIT(rts, rt)) {
   823 				if (HASBIT(rts, rt)) {
   824 					int32 tmp_ret = DoCommand(tile, 1 << 6 | rt << 4 | GetCrossingRoadBits(tile), 0, flags, CMD_REMOVE_ROAD);
   824 					CommandCost tmp_ret = DoCommand(tile, 1 << 6 | rt << 4 | GetCrossingRoadBits(tile), 0, flags, CMD_REMOVE_ROAD);
   825 					if (CmdFailed(tmp_ret)) return tmp_ret;
   825 					if (CmdFailed(tmp_ret)) return tmp_ret;
   826 					ret += tmp_ret;
   826 					ret += tmp_ret;
   827 				}
   827 				}
   828 			}
   828 			}
   829 
   829