src/waypoint.cpp
branchnoai
changeset 9694 e72987579514
parent 9631 8a2d1c2ceb88
child 9701 d1ac22c62f64
equal deleted inserted replaced
9693:31fcaa5375a1 9694:e72987579514
    24 #include "yapf/yapf.h"
    24 #include "yapf/yapf.h"
    25 #include "date.h"
    25 #include "date.h"
    26 #include "newgrf.h"
    26 #include "newgrf.h"
    27 #include "string.h"
    27 #include "string.h"
    28 #include "strings.h"
    28 #include "strings.h"
       
    29 #include "misc/autoptr.hpp"
    29 
    30 
    30 enum {
    31 enum {
    31 	MAX_WAYPOINTS_PER_TOWN = 64,
    32 	MAX_WAYPOINTS_PER_TOWN = 64,
    32 };
    33 };
    33 
    34 
    34 /**
    35 DEFINE_OLD_POOL_GENERIC(Waypoint, Waypoint)
    35  * Called if a new block is added to the waypoint-pool
    36 
    36  */
       
    37 static void WaypointPoolNewBlock(uint start_item)
       
    38 {
       
    39 	Waypoint *wp;
       
    40 
       
    41 	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
       
    42 	 * TODO - This is just a temporary stage, this will be removed. */
       
    43 	for (wp = GetWaypoint(start_item); wp != NULL; wp = (wp->index + 1U < GetWaypointPoolSize()) ? GetWaypoint(wp->index + 1U) : NULL) wp->index = start_item++;
       
    44 }
       
    45 
       
    46 DEFINE_OLD_POOL(Waypoint, Waypoint, WaypointPoolNewBlock, NULL)
       
    47 
       
    48 /**
       
    49  * Create a new waypoint
       
    50  * @return a pointer to the newly created Waypoint */
       
    51 static Waypoint* AllocateWaypoint()
       
    52 {
       
    53 	Waypoint *wp;
       
    54 
       
    55 	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
       
    56 	 * TODO - This is just a temporary stage, this will be removed. */
       
    57 	for (wp = GetWaypoint(0); wp != NULL; wp = (wp->index + 1U < GetWaypointPoolSize()) ? GetWaypoint(wp->index + 1U) : NULL) {
       
    58 		if (!IsValidWaypoint(wp)) {
       
    59 			uint index = wp->index;
       
    60 
       
    61 			memset(wp, 0, sizeof(*wp));
       
    62 			wp->index = index;
       
    63 
       
    64 			return wp;
       
    65 		}
       
    66 	}
       
    67 
       
    68 	/* Check if we can add a block to the pool */
       
    69 	if (AddBlockToPool(&_Waypoint_pool)) return AllocateWaypoint();
       
    70 
       
    71 	return NULL;
       
    72 }
       
    73 
    37 
    74 /**
    38 /**
    75  * Update the sign for the waypoint
    39  * Update the sign for the waypoint
    76  * @param wp Waypoint to update sign */
    40  * @param wp Waypoint to update sign */
    77 static void UpdateWaypointSign(Waypoint* wp)
    41 static void UpdateWaypointSign(Waypoint* wp)
   101 	Waypoint *wp;
    65 	Waypoint *wp;
   102 
    66 
   103 	FOR_ALL_WAYPOINTS(wp) {
    67 	FOR_ALL_WAYPOINTS(wp) {
   104 		UpdateWaypointSign(wp);
    68 		UpdateWaypointSign(wp);
   105 	}
    69 	}
   106 }
       
   107 
       
   108 /**
       
   109  * Internal handler to delete a waypoint
       
   110  * @param wp Waypoint to delete
       
   111  */
       
   112 void DestroyWaypoint(Waypoint *wp)
       
   113 {
       
   114 	RemoveOrderFromAllVehicles(OT_GOTO_WAYPOINT, wp->index);
       
   115 
       
   116 	if (wp->string != STR_NULL) DeleteName(wp->string);
       
   117 
       
   118 	RedrawWaypointSign(wp);
       
   119 }
    70 }
   120 
    71 
   121 /**
    72 /**
   122  * Set the default name for a waypoint
    73  * Set the default name for a waypoint
   123  * @param wp Waypoint to work on
    74  * @param wp Waypoint to work on
   204  * distingush between "Flat land required" and "land sloped in wrong direction"
   155  * distingush between "Flat land required" and "land sloped in wrong direction"
   205  */
   156  */
   206 CommandCost CmdBuildTrainWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   157 CommandCost CmdBuildTrainWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   207 {
   158 {
   208 	Waypoint *wp;
   159 	Waypoint *wp;
       
   160 	AutoPtrT<Waypoint> wp_auto_delete;
   209 	Slope tileh;
   161 	Slope tileh;
   210 	Axis axis;
   162 	Axis axis;
   211 
   163 
   212 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   164 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   213 
   165 
   234 	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
   186 	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
   235 
   187 
   236 	/* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */
   188 	/* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */
   237 	wp = FindDeletedWaypointCloseTo(tile);
   189 	wp = FindDeletedWaypointCloseTo(tile);
   238 	if (wp == NULL) {
   190 	if (wp == NULL) {
   239 		wp = AllocateWaypoint();
   191 		wp = new Waypoint(tile);
   240 		if (wp == NULL) return CMD_ERROR;
   192 		if (wp == NULL) return CMD_ERROR;
       
   193 
       
   194 		wp_auto_delete = wp;
   241 
   195 
   242 		wp->town_index = 0;
   196 		wp->town_index = 0;
   243 		wp->string = STR_NULL;
   197 		wp->string = STR_NULL;
   244 		wp->town_cn = 0;
   198 		wp->town_cn = 0;
   245 	}
   199 	}
   262 			wp->grfid = 0;
   216 			wp->grfid = 0;
   263 			wp->localidx = 0;
   217 			wp->localidx = 0;
   264 		}
   218 		}
   265 
   219 
   266 		wp->deleted = 0;
   220 		wp->deleted = 0;
   267 		wp->xy = tile;
       
   268 		wp->build_date = _date;
   221 		wp->build_date = _date;
   269 
   222 
   270 		if (wp->town_index == 0) MakeDefaultWaypointName(wp);
   223 		if (wp->town_index == 0) MakeDefaultWaypointName(wp);
   271 
   224 
   272 		UpdateWaypointSign(wp);
   225 		UpdateWaypointSign(wp);
   273 		RedrawWaypointSign(wp);
   226 		RedrawWaypointSign(wp);
   274 		YapfNotifyTrackLayoutChange(tile, AxisToTrack(axis));
   227 		YapfNotifyTrackLayoutChange(tile, AxisToTrack(axis));
       
   228 		wp_auto_delete.Detach();
   275 	}
   229 	}
   276 
   230 
   277 	return CommandCost(_price.build_train_depot);
   231 	return CommandCost(_price.build_train_depot);
   278 }
   232 }
   279 
   233 
   441 	if (!DrawStationTile(x, y, railtype, AXIS_X, STAT_CLASS_WAYP, stat_id)) {
   395 	if (!DrawStationTile(x, y, railtype, AXIS_X, STAT_CLASS_WAYP, stat_id)) {
   442 		DrawDefaultWaypointSprite(x, y, railtype);
   396 		DrawDefaultWaypointSprite(x, y, railtype);
   443 	}
   397 	}
   444 }
   398 }
   445 
   399 
       
   400 Waypoint::Waypoint(TileIndex tile)
       
   401 {
       
   402 	this->xy = tile;
       
   403 }
       
   404 
       
   405 Waypoint::~Waypoint()
       
   406 {
       
   407 	RemoveOrderFromAllVehicles(OT_GOTO_WAYPOINT, this->index);
       
   408 
       
   409 	RedrawWaypointSign(this);
       
   410 	this->xy = 0;
       
   411 
       
   412 	this->QuickFree();
       
   413 }
       
   414 
       
   415 void Waypoint::QuickFree()
       
   416 {
       
   417 	if (this->string != STR_NULL) DeleteName(this->string);
       
   418 }
       
   419 
       
   420 bool Waypoint::IsValid() const
       
   421 {
       
   422 	return this->xy != 0;
       
   423 }
       
   424 
       
   425 
   446 /**
   426 /**
   447  * Fix savegames which stored waypoints in their old format
   427  * Fix savegames which stored waypoints in their old format
   448  */
   428  */
   449 void FixOldWaypoints()
   429 void FixOldWaypoints()
   450 {
   430 {
   461 	}
   441 	}
   462 }
   442 }
   463 
   443 
   464 void InitializeWaypoints()
   444 void InitializeWaypoints()
   465 {
   445 {
   466 	CleanPool(&_Waypoint_pool);
   446 	_Waypoint_pool.CleanPool();
   467 	AddBlockToPool(&_Waypoint_pool);
   447 	_Waypoint_pool.AddBlockToPool();
   468 }
   448 }
   469 
   449 
   470 static const SaveLoad _waypoint_desc[] = {
   450 static const SaveLoad _waypoint_desc[] = {
   471 	SLE_CONDVAR(Waypoint, xy,         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
   451 	SLE_CONDVAR(Waypoint, xy,         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
   472 	SLE_CONDVAR(Waypoint, xy,         SLE_UINT32,                  6, SL_MAX_VERSION),
   452 	SLE_CONDVAR(Waypoint, xy,         SLE_UINT32,                  6, SL_MAX_VERSION),
   496 static void Load_WAYP()
   476 static void Load_WAYP()
   497 {
   477 {
   498 	int index;
   478 	int index;
   499 
   479 
   500 	while ((index = SlIterateArray()) != -1) {
   480 	while ((index = SlIterateArray()) != -1) {
   501 		Waypoint *wp;
   481 		Waypoint *wp = new (index) Waypoint();
   502 
       
   503 		if (!AddBlockIfNeeded(&_Waypoint_pool, index))
       
   504 			error("Waypoints: failed loading savegame: too many waypoints");
       
   505 
       
   506 		wp = GetWaypoint(index);
       
   507 		SlObject(wp, _waypoint_desc);
   482 		SlObject(wp, _waypoint_desc);
   508 	}
   483 	}
   509 }
   484 }
   510 
   485 
   511 extern const ChunkHandler _waypoint_chunk_handlers[] = {
   486 extern const ChunkHandler _waypoint_chunk_handlers[] = {