prevent ship block upon placing dock, lock and ship depot patch

Forum for technical discussions regarding development. If you have a general suggestion, problem or comment, please use one of the other forums.

Moderator: OpenTTD Developers

Post Reply
xarick
Transport Coordinator
Transport Coordinator
Posts: 341
Joined: 26 Feb 2015 00:52

prevent ship block upon placing dock, lock and ship depot patch

Post by xarick »

The main purpose of this patch is to help AIs, by preventing placement of docks, locks and ship depots in a way which could result in nearby ships becoming blocked.

On v1, the placement of docks is less restrictive regarding the slope configuration of the watered tile in front of the dock, but from v2 onwards I removed this. I posted that as a separate patch here: viewtopic.php?f=33&t=75221

v3:
- Really check for ships, and not for any kind of vehicle. v2 could forbid placement if it was finding a train in the rail portion of a tile that could also have water.
- Fixed a bug introduced on v2, it was not checking for vehicles if the tile was not water when I was trying to check for aqueduct (bad coding skills).

v2:
- Changed the detection method for tiles that contain water tracks, hopefully for the better. v1 was not accounting for aqueduct heads, rail tracks that also contained water on the other half of the tile and buoys.
- Reverted the change regarding easiness for placing docks.


Some random screenshots about the development thinking:

Image
Water tracks represented by rail where a ship cannot be when placing locks

Image
Water tracks represented by rail where a ship cannot be when placing locks, ship depots and docks, but with incomplete checks regarding docks

Image
Water tracks represented by rail where a ship cannot be when placing docks, after figuring out that docks needed more checks.
Attachments
prevent ship block upon placing dock, lock and ship depot v1 r27632.patch
(5.27 KiB) Downloaded 83 times
prevent ship block upon placing dock, lock and ship depot v2 r27654.patch
(5.31 KiB) Downloaded 81 times
prevent ship block upon placing dock, lock and ship depot v3 r27654.patch
(6.31 KiB) Downloaded 80 times
Last edited by xarick on 06 Sep 2016 12:20, edited 4 times in total.
Formerly known as Samu
J0anJosep
Traffic Manager
Traffic Manager
Posts: 139
Joined: 06 Aug 2011 15:51
Location: Spain

Re: prevent ship block upon placing dock, lock and ship depot patch

Post by J0anJosep »

Great work! Any improvement for ships is always welcomed!

Some time ago I did some work with water tiles and I came across the same problem. I was trying to store the "water tracks" for each tile of the map. As building or modifying water tiles can make some tracks unavailable, I had to check if there was any ship around the tiles. This was very similar to what you are trying to do now. I attach the corresponding patch.

Probably the results of both patches are not the same, as I changed the behaviour of locks, depots, docks... but maybe you find some new ideas you can use in your patch.
Attachments
ensurenoshipsaround.diff
(1.39 KiB) Downloaded 95 times
Formerly known as Juanjo
xarick
Transport Coordinator
Transport Coordinator
Posts: 341
Joined: 26 Feb 2015 00:52

Re: prevent ship block upon placing dock, lock and ship depot patch

Post by xarick »

Hmm, I see your approach is global. Everything that makes use of EnsureNoVehicleOnGround will be doing that ship check. I kind of like the idea of a global approach, but at the same time, it's risky, without knowing for sure if it's going to get desired results.

My approach is only limited to locks, docks and ship depots placement.

I'm currently testing your approach. Be back later.

EDIT: Thanks for reminding me of Aqueduct and Buoy tiles, I totally forgot about them. It's not too obvious to work with water tiles.


EDIT2: Here's a list of everything that uses EnsureNoVehicleOnGround, according to View Call Hierarchy by Visual Studio

station_cmd.cpp - CheckBuildableTile(TileIndex tile, uint invalid_dirs, int & allowed_z, bool allow_steep, bool check_bridge)
industry_cmd.cpp - CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable * it, uint itspec_index, int type, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type, bool * custom_shape_check)
rail_cmd.cpp - ClearTile_Track(TileIndex tile, DoCommandFlag flags)
water_cmd.cpp - ClearTile_Water(TileIndex tile, DoCommandFlag flags)
object_cmd.cpp - CmdBuildObject(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
road_cmd.cpp - CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char * text)
rail_cmd.cpp - CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char * text)
rail_cmd.cpp - CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char * text)
rail_cmd.cpp - CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char * text)
rail_cmd.cpp - CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char * text)
disaster_vehicle.cpp - DisasterClearSquare(TileIndex tile)
water_cmd.cpp - DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag flags)
waypoint_cmd.cpp - IsValidTileForWaypoint(TileIndex tile, Axis axis, StationID * waypoint)
station_cmd.cpp - RemoveAirport(TileIndex tile, DoCommandFlag flags)
waypoint_cmd.cpp - RemoveBuoy(TileIndex tile, DoCommandFlag flags)
station_cmd.cpp - RemoveDock(TileIndex tile, DoCommandFlag flags)
station_cmd.cpp - RemoveFromRailBaseStation(TileArea ta, SmallVector<T *, 4U> &affected_stations, DoCommandFlag flags, Money removal_cost, bool keep_rail)
water_cmd.cpp - RemoveLock(TileIndex tile, DoCommandFlag flags)
road_cmd.cpp - RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits pieces, RoadType rt, bool crossing_check, bool town_check = true)
road_cmd.cpp - RemoveRoadDepot(TileIndex tile, DoCommandFlag flags)
station_cmd.cpp - RemoveRoadStop(TileIndex tile, DoCommandFlag flags)
water_cmd.cpp - RemoveShipDepot(TileIndex tile, DoCommandFlag flags)
rail_cmd.cpp - RemoveTrainDepot(TileIndex tile, DoCommandFlag flags)
road_cmd.cpp - TileLoop_Road(TileIndex tile)

I've edited part of your code and it now looks like this:

Code: Select all

Index: src/vehicle.cpp
===================================================================
--- src/vehicle.cpp	(revision 27653)
+++ src/vehicle.cpp	(working copy)
@@ -47,6 +47,7 @@
 #include "effectvehicle_base.h"
 #include "vehiclelist.h"
 #include "bridge_map.h"
+#include "tunnelbridge_map.h"
 #include "tunnel_map.h"
 #include "depot_map.h"
 #include "gamelog.h"
@@ -481,6 +482,19 @@
 	 */
 	Vehicle *v = VehicleFromPos(tile, &z, &EnsureNoVehicleProcZ, true);
 	if (v != NULL) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
+
+	if ((TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0)) & TRACK_BIT_ALL) != TRACK_BIT_NONE) {
+		Ship *s;
+		FOR_ALL_SHIPS(s) {
+			if (DistanceManhattan(tile, s->tile) != 1) continue;
+			/* Don't care about ships on aqueducts. Those kind of tiles don't cause problems. */
+			/* The same can be applied to locks and ship depots. */
+			if (IsTileType(s->tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(s->tile) == TRANSPORT_WATER ||
+				IsTileType(s->tile, MP_WATER) && IsLock(s->tile) || IsShipDepotTile(s->tile)) continue;			
+			if (s->state & DiagdirReachesTracks(DiagdirBetweenTiles(tile, s->tile))) return_cmd_error(STR_ERROR_SHIP_IN_THE_WAY);
+		}
+	}
+
 	return CommandCost();
 }


Now, to make sure if that whole list of functions are behaving as intended will be the hardest part.
Attachments
ensurenoshipsaround edited v1 r27653.patch
(1.24 KiB) Downloaded 87 times
Formerly known as Samu
Post Reply

Return to “OpenTTD Development”

Who is online

Users browsing this forum: No registered users and 28 guests