src/waypoint.cpp
branchgamebalance
changeset 9908 0fa543611bbe
parent 9903 dc85aaa556ae
child 9913 e79cd19772dd
equal deleted inserted replaced
9907:3b068c3a1c74 9908:0fa543611bbe
     1 /* $Id$ */
     1 /* $Id$ */
       
     2 
       
     3 /** @file waypoint.cpp */
     2 
     4 
     3 #include "stdafx.h"
     5 #include "stdafx.h"
     4 #include "openttd.h"
     6 #include "openttd.h"
     5 
     7 
     6 #include "command.h"
     8 #include "command.h"
     7 #include "functions.h"
     9 #include "functions.h"
     8 #include "gfx.h"
    10 #include "gfx.h"
       
    11 #include "landscape.h"
     9 #include "map.h"
    12 #include "map.h"
    10 #include "order.h"
    13 #include "order.h"
    11 #include "rail_map.h"
    14 #include "rail_map.h"
    12 #include "bridge_map.h"
    15 #include "bridge_map.h"
    13 #include "saveload.h"
    16 #include "saveload.h"
    18 #include "variables.h"
    21 #include "variables.h"
    19 #include "table/strings.h"
    22 #include "table/strings.h"
    20 #include "vehicle.h"
    23 #include "vehicle.h"
    21 #include "yapf/yapf.h"
    24 #include "yapf/yapf.h"
    22 #include "date.h"
    25 #include "date.h"
       
    26 #include "newgrf.h"
    23 
    27 
    24 enum {
    28 enum {
    25 	MAX_WAYPOINTS_PER_TOWN = 64,
    29 	MAX_WAYPOINTS_PER_TOWN = 64,
    26 };
    30 };
    27 
    31 
    37 	for (wp = GetWaypoint(start_item); wp != NULL; wp = (wp->index + 1U < GetWaypointPoolSize()) ? GetWaypoint(wp->index + 1U) : NULL) wp->index = start_item++;
    41 	for (wp = GetWaypoint(start_item); wp != NULL; wp = (wp->index + 1U < GetWaypointPoolSize()) ? GetWaypoint(wp->index + 1U) : NULL) wp->index = start_item++;
    38 }
    42 }
    39 
    43 
    40 DEFINE_OLD_POOL(Waypoint, Waypoint, WaypointPoolNewBlock, NULL)
    44 DEFINE_OLD_POOL(Waypoint, Waypoint, WaypointPoolNewBlock, NULL)
    41 
    45 
    42 /* Create a new waypoint */
    46 /**
       
    47  * Create a new waypoint
       
    48  * @return a pointer to the newly created Waypoint */
    43 static Waypoint* AllocateWaypoint()
    49 static Waypoint* AllocateWaypoint()
    44 {
    50 {
    45 	Waypoint *wp;
    51 	Waypoint *wp;
    46 
    52 
    47 	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
    53 	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
    61 	if (AddBlockToPool(&_Waypoint_pool)) return AllocateWaypoint();
    67 	if (AddBlockToPool(&_Waypoint_pool)) return AllocateWaypoint();
    62 
    68 
    63 	return NULL;
    69 	return NULL;
    64 }
    70 }
    65 
    71 
    66 /* Update the sign for the waypoint */
    72 /**
       
    73  * Update the sign for the waypoint
       
    74  * @param wp Waypoint to update sign */
    67 static void UpdateWaypointSign(Waypoint* wp)
    75 static void UpdateWaypointSign(Waypoint* wp)
    68 {
    76 {
    69 	Point pt = RemapCoords2(TileX(wp->xy) * TILE_SIZE, TileY(wp->xy) * TILE_SIZE);
    77 	Point pt = RemapCoords2(TileX(wp->xy) * TILE_SIZE, TileY(wp->xy) * TILE_SIZE);
    70 	SetDParam(0, wp->index);
    78 	SetDParam(0, wp->index);
    71 	UpdateViewportSignPos(&wp->sign, pt.x, pt.y - 0x20, STR_WAYPOINT_VIEWPORT);
    79 	UpdateViewportSignPos(&wp->sign, pt.x, pt.y - 0x20, STR_WAYPOINT_VIEWPORT);
    72 }
    80 }
    73 
    81 
    74 /* Redraw the sign of a waypoint */
    82 /**
       
    83  * Redraw the sign of a waypoint
       
    84  * @param wp Waypoint to redraw sign */
    75 static void RedrawWaypointSign(const Waypoint* wp)
    85 static void RedrawWaypointSign(const Waypoint* wp)
    76 {
    86 {
    77 	MarkAllViewportsDirty(
    87 	MarkAllViewportsDirty(
    78 		wp->sign.left - 6,
    88 		wp->sign.left - 6,
    79 		wp->sign.top,
    89 		wp->sign.top,
    80 		wp->sign.left + (wp->sign.width_1 << 2) + 12,
    90 		wp->sign.left + (wp->sign.width_1 << 2) + 12,
    81 		wp->sign.top + 48);
    91 		wp->sign.top + 48);
    82 }
    92 }
    83 
    93 
    84 /* Update all signs */
    94 /**
       
    95  * Update all signs
       
    96  */
    85 void UpdateAllWaypointSigns()
    97 void UpdateAllWaypointSigns()
    86 {
    98 {
    87 	Waypoint *wp;
    99 	Waypoint *wp;
    88 
   100 
    89 	FOR_ALL_WAYPOINTS(wp) {
   101 	FOR_ALL_WAYPOINTS(wp) {
    90 		UpdateWaypointSign(wp);
   102 		UpdateWaypointSign(wp);
    91 	}
   103 	}
    92 }
   104 }
    93 
   105 
    94 /* Internal handler to delete a waypoint */
   106 /**
       
   107  * Internal handler to delete a waypoint
       
   108  * @param wp Waypoint to delete
       
   109  */
    95 void DestroyWaypoint(Waypoint *wp)
   110 void DestroyWaypoint(Waypoint *wp)
    96 {
   111 {
    97 	RemoveOrderFromAllVehicles(OT_GOTO_WAYPOINT, wp->index);
   112 	RemoveOrderFromAllVehicles(OT_GOTO_WAYPOINT, wp->index);
    98 
   113 
    99 	if (wp->string != STR_NULL) DeleteName(wp->string);
   114 	if (wp->string != STR_NULL) DeleteName(wp->string);
   100 
   115 
   101 	RedrawWaypointSign(wp);
   116 	RedrawWaypointSign(wp);
   102 }
   117 }
   103 
   118 
   104 /* Set the default name for a waypoint */
   119 /**
       
   120  * Set the default name for a waypoint
       
   121  * @param wp Waypoint to work on
       
   122  */
   105 static void MakeDefaultWaypointName(Waypoint* wp)
   123 static void MakeDefaultWaypointName(Waypoint* wp)
   106 {
   124 {
   107 	Waypoint *local_wp;
   125 	Waypoint *local_wp;
   108 	bool used_waypoint[MAX_WAYPOINTS_PER_TOWN];
   126 	bool used_waypoint[MAX_WAYPOINTS_PER_TOWN];
   109 	int i;
   127 	int i;
   125 
   143 
   126 	wp->string = STR_NULL;
   144 	wp->string = STR_NULL;
   127 	wp->town_cn = i;
   145 	wp->town_cn = i;
   128 }
   146 }
   129 
   147 
   130 /* Find a deleted waypoint close to a tile. */
   148 /**
       
   149  * Find a deleted waypoint close to a tile.
       
   150  * @param tile to search from
       
   151  */
   131 static Waypoint *FindDeletedWaypointCloseTo(TileIndex tile)
   152 static Waypoint *FindDeletedWaypointCloseTo(TileIndex tile)
   132 {
   153 {
   133 	Waypoint *wp, *best = NULL;
   154 	Waypoint *wp, *best = NULL;
   134 	uint thres = 8;
   155 	uint thres = 8;
   135 
   156 
   160 
   181 
   161 		if (wp->grfid == 0) continue;
   182 		if (wp->grfid == 0) continue;
   162 
   183 
   163 		for (i = 0; i < GetNumCustomStations(STAT_CLASS_WAYP); i++) {
   184 		for (i = 0; i < GetNumCustomStations(STAT_CLASS_WAYP); i++) {
   164 			const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, i);
   185 			const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, i);
   165 			if (statspec != NULL && statspec->grfid == wp->grfid && statspec->localidx == wp->localidx) {
   186 			if (statspec != NULL && statspec->grffile->grfid == wp->grfid && statspec->localidx == wp->localidx) {
   166 				wp->stat_id = i;
   187 				wp->stat_id = i;
   167 				break;
   188 				break;
   168 			}
   189 			}
   169 		}
   190 		}
   170 	}
   191 	}
   171 }
   192 }
   172 
   193 
   173 /** Convert existing rail to waypoint. Eg build a waypoint station over
   194 /** Convert existing rail to waypoint. Eg build a waypoint station over
   174  * piece of rail
   195  * piece of rail
   175  * @param tile tile where waypoint will be built
   196  * @param tile tile where waypoint will be built
       
   197  * @param flags type of operation
   176  * @param p1 graphics for waypoint type, 0 indicates standard graphics
   198  * @param p1 graphics for waypoint type, 0 indicates standard graphics
   177  * @param p2 unused
   199  * @param p2 unused
   178  *
   200  *
   179  * @todo When checking for the tile slope,
   201  * @todo When checking for the tile slope,
   180  * distingush between "Flat land required" and "land sloped in wrong direction"
   202  * distingush between "Flat land required" and "land sloped in wrong direction"
   228 
   250 
   229 		statspec = GetCustomStationSpec(STAT_CLASS_WAYP, p1);
   251 		statspec = GetCustomStationSpec(STAT_CLASS_WAYP, p1);
   230 
   252 
   231 		if (statspec != NULL) {
   253 		if (statspec != NULL) {
   232 			wp->stat_id = p1;
   254 			wp->stat_id = p1;
   233 			wp->grfid = statspec->grfid;
   255 			wp->grfid = statspec->grffile->grfid;
   234 			wp->localidx = statspec->localidx;
   256 			wp->localidx = statspec->localidx;
   235 		} else {
   257 		} else {
   236 			// Specified custom graphics do not exist, so use default.
   258 			/* Specified custom graphics do not exist, so use default. */
   237 			wp->stat_id = 0;
   259 			wp->stat_id = 0;
   238 			wp->grfid = 0;
   260 			wp->grfid = 0;
   239 			wp->localidx = 0;
   261 			wp->localidx = 0;
   240 		}
   262 		}
   241 
   263 
   251 	}
   273 	}
   252 
   274 
   253 	return _eco->GetPrice(CEconomy::BUILD_TRAIN_DEPOT);
   275 	return _eco->GetPrice(CEconomy::BUILD_TRAIN_DEPOT);
   254 }
   276 }
   255 
   277 
   256 /* Daily loop for waypoints */
   278 /**
       
   279  * Daily loop for waypoints
       
   280  */
   257 void WaypointsDailyLoop()
   281 void WaypointsDailyLoop()
   258 {
   282 {
   259 	Waypoint *wp;
   283 	Waypoint *wp;
   260 
   284 
   261 	/* Check if we need to delete a waypoint */
   285 	/* Check if we need to delete a waypoint */
   262 	FOR_ALL_WAYPOINTS(wp) {
   286 	FOR_ALL_WAYPOINTS(wp) {
   263 		if (wp->deleted != 0 && --wp->deleted == 0) DeleteWaypoint(wp);
   287 		if (wp->deleted != 0 && --wp->deleted == 0) DeleteWaypoint(wp);
   264 	}
   288 	}
   265 }
   289 }
   266 
   290 
   267 /* Remove a waypoint */
   291 /**
       
   292  * Remove a waypoint
       
   293  * @param tile from which to remove waypoint
       
   294  * @param flags type of operation
       
   295  * @param justremove will indicate if it is removed from rail or if rails are removed too
       
   296  * @return cost of operation or error
       
   297  */
   268 int32 RemoveTrainWaypoint(TileIndex tile, uint32 flags, bool justremove)
   298 int32 RemoveTrainWaypoint(TileIndex tile, uint32 flags, bool justremove)
   269 {
   299 {
   270 	Waypoint *wp;
   300 	Waypoint *wp;
   271 
   301 
   272 	/* Make sure it's a waypoint */
   302 	/* Make sure it's a waypoint */
   295 	}
   325 	}
   296 
   326 
   297 	return _eco->GetPrice(CEconomy::REMOVE_TRAIN_DEPOT);
   327 	return _eco->GetPrice(CEconomy::REMOVE_TRAIN_DEPOT);
   298 }
   328 }
   299 
   329 
   300 /** Delete a waypoint
   330 /**
       
   331  * Delete a waypoint
   301  * @param tile tile where waypoint is to be deleted
   332  * @param tile tile where waypoint is to be deleted
       
   333  * @param flags type of operation
   302  * @param p1 unused
   334  * @param p1 unused
   303  * @param p2 unused
   335  * @param p2 unused
       
   336  * @return cost of operation or error
   304  */
   337  */
   305 int32 CmdRemoveTrainWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   338 int32 CmdRemoveTrainWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   306 {
   339 {
   307 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   340 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   308 	return RemoveTrainWaypoint(tile, flags, true);
   341 	return RemoveTrainWaypoint(tile, flags, true);
   309 }
   342 }
   310 
   343 
   311 /** Rename a waypoint.
   344 /**
       
   345  * Rename a waypoint.
   312  * @param tile unused
   346  * @param tile unused
       
   347  * @param flags type of operation
   313  * @param p1 id of waypoint
   348  * @param p1 id of waypoint
   314  * @param p2 unused
   349  * @param p2 unused
       
   350  * @return cost of operation or error
   315  */
   351  */
   316 int32 CmdRenameWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   352 int32 CmdRenameWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   317 {
   353 {
   318 	Waypoint *wp;
   354 	Waypoint *wp;
   319 
   355 
   347 		}
   383 		}
   348 	}
   384 	}
   349 	return 0;
   385 	return 0;
   350 }
   386 }
   351 
   387 
   352 /* This hacks together some dummy one-shot Station structure for a waypoint. */
   388 /**
       
   389  * This hacks together some dummy one-shot Station structure for a waypoint.
       
   390  * @param tile on which to work
       
   391  * @return pointer to a Station
       
   392  */
   353 Station *ComposeWaypointStation(TileIndex tile)
   393 Station *ComposeWaypointStation(TileIndex tile)
   354 {
   394 {
   355 	Waypoint *wp = GetWaypointByTile(tile);
   395 	Waypoint *wp = GetWaypointByTile(tile);
   356 
   396 
   357 	/* instead of 'static Station stat' use byte array to avoid Station's destructor call upon exit. As
   397 	/* instead of 'static Station stat' use byte array to avoid Station's destructor call upon exit. As
   365 	stat.build_date = wp->build_date;
   405 	stat.build_date = wp->build_date;
   366 
   406 
   367 	return &stat;
   407 	return &stat;
   368 }
   408 }
   369 
   409 
   370 /* Draw a waypoint */
   410 /**
       
   411  * Draw a waypoint
       
   412  * @param x coordinate
       
   413  * @param y coordinate
       
   414  * @param stat_id station id
       
   415  * @param railtype RailType to use for
       
   416  */
   371 void DrawWaypointSprite(int x, int y, int stat_id, RailType railtype)
   417 void DrawWaypointSprite(int x, int y, int stat_id, RailType railtype)
   372 {
   418 {
   373 	x += 33;
   419 	x += 33;
   374 	y += 17;
   420 	y += 17;
   375 
   421 
   376 	if (!DrawStationTile(x, y, railtype, AXIS_X, STAT_CLASS_WAYP, stat_id)) {
   422 	if (!DrawStationTile(x, y, railtype, AXIS_X, STAT_CLASS_WAYP, stat_id)) {
   377 		DrawDefaultWaypointSprite(x, y, railtype);
   423 		DrawDefaultWaypointSprite(x, y, railtype);
   378 	}
   424 	}
   379 }
   425 }
   380 
   426 
   381 /* Fix savegames which stored waypoints in their old format */
   427 /**
       
   428  * Fix savegames which stored waypoints in their old format
       
   429  */
   382 void FixOldWaypoints()
   430 void FixOldWaypoints()
   383 {
   431 {
   384 	Waypoint *wp;
   432 	Waypoint *wp;
   385 
   433 
   386 	/* Convert the old 'town_or_string', to 'string' / 'town' / 'town_cn' */
   434 	/* Convert the old 'town_or_string', to 'string' / 'town' / 'town_cn' */