src/newgrf_station.cpp
branchnoai
changeset 9724 b39bc69bb2f2
parent 9723 eee46cb39750
child 9732 f8eb3e208514
equal deleted inserted replaced
9723:eee46cb39750 9724:b39bc69bb2f2
     7 #include "variables.h"
     7 #include "variables.h"
     8 #include "tile_cmd.h"
     8 #include "tile_cmd.h"
     9 #include "landscape.h"
     9 #include "landscape.h"
    10 #include "debug.h"
    10 #include "debug.h"
    11 #include "sprite.h"
    11 #include "sprite.h"
    12 #include "table/sprites.h"
       
    13 #include "table/strings.h"
       
    14 #include "station.h"
    12 #include "station.h"
    15 #include "station_map.h"
    13 #include "station_map.h"
    16 #include "newgrf.h"
    14 #include "newgrf.h"
    17 #include "newgrf_callbacks.h"
    15 #include "newgrf_callbacks.h"
    18 #include "newgrf_commons.h"
    16 #include "newgrf_commons.h"
    21 #include "cargotype.h"
    19 #include "cargotype.h"
    22 #include "town_map.h"
    20 #include "town_map.h"
    23 #include "newgrf_town.h"
    21 #include "newgrf_town.h"
    24 #include "gfx_func.h"
    22 #include "gfx_func.h"
    25 #include "date_func.h"
    23 #include "date_func.h"
    26 
    24 #include "player_func.h"
    27 static StationClass station_classes[STAT_CLASS_MAX];
    25 
       
    26 #include "table/sprites.h"
       
    27 #include "table/strings.h"
       
    28 
       
    29 static StationClass _station_classes[STAT_CLASS_MAX];
    28 
    30 
    29 enum {
    31 enum {
    30 	MAX_SPECLIST = 255,
    32 	MAX_SPECLIST = 255,
    31 };
    33 };
    32 
    34 
    36  * entry, for standard stations and waypoints.
    38  * entry, for standard stations and waypoints.
    37  */
    39  */
    38 void ResetStationClasses()
    40 void ResetStationClasses()
    39 {
    41 {
    40 	for (StationClassID i = STAT_CLASS_BEGIN; i < STAT_CLASS_MAX; i++) {
    42 	for (StationClassID i = STAT_CLASS_BEGIN; i < STAT_CLASS_MAX; i++) {
    41 		station_classes[i].id = 0;
    43 		_station_classes[i].id = 0;
    42 		station_classes[i].name = STR_EMPTY;
    44 		_station_classes[i].name = STR_EMPTY;
    43 		station_classes[i].stations = 0;
    45 		_station_classes[i].stations = 0;
    44 
    46 
    45 		free(station_classes[i].spec);
    47 		free(_station_classes[i].spec);
    46 		station_classes[i].spec = NULL;
    48 		_station_classes[i].spec = NULL;
    47 	}
    49 	}
    48 
    50 
    49 	/* Set up initial data */
    51 	/* Set up initial data */
    50 	station_classes[0].id = 'DFLT';
    52 	_station_classes[0].id = 'DFLT';
    51 	station_classes[0].name = STR_STAT_CLASS_DFLT;
    53 	_station_classes[0].name = STR_STAT_CLASS_DFLT;
    52 	station_classes[0].stations = 1;
    54 	_station_classes[0].stations = 1;
    53 	station_classes[0].spec = MallocT<StationSpec*>(1);
    55 	_station_classes[0].spec = MallocT<StationSpec*>(1);
    54 	station_classes[0].spec[0] = NULL;
    56 	_station_classes[0].spec[0] = NULL;
    55 
    57 
    56 	station_classes[1].id = 'WAYP';
    58 	_station_classes[1].id = 'WAYP';
    57 	station_classes[1].name = STR_STAT_CLASS_WAYP;
    59 	_station_classes[1].name = STR_STAT_CLASS_WAYP;
    58 	station_classes[1].stations = 1;
    60 	_station_classes[1].stations = 1;
    59 	station_classes[1].spec = MallocT<StationSpec*>(1);
    61 	_station_classes[1].spec = MallocT<StationSpec*>(1);
    60 	station_classes[1].spec[0] = NULL;
    62 	_station_classes[1].spec[0] = NULL;
    61 }
    63 }
    62 
    64 
    63 /**
    65 /**
    64  * Allocate a station class for the given class id.
    66  * Allocate a station class for the given class id.
    65  * @param cls A 32 bit value identifying the class.
    67  * @param cls A 32 bit value identifying the class.
    66  * @return Index into station_classes of allocated class.
    68  * @return Index into _station_classes of allocated class.
    67  */
    69  */
    68 StationClassID AllocateStationClass(uint32 cls)
    70 StationClassID AllocateStationClass(uint32 cls)
    69 {
    71 {
    70 	for (StationClassID i = STAT_CLASS_BEGIN; i < STAT_CLASS_MAX; i++) {
    72 	for (StationClassID i = STAT_CLASS_BEGIN; i < STAT_CLASS_MAX; i++) {
    71 		if (station_classes[i].id == cls) {
    73 		if (_station_classes[i].id == cls) {
    72 			/* ClassID is already allocated, so reuse it. */
    74 			/* ClassID is already allocated, so reuse it. */
    73 			return i;
    75 			return i;
    74 		} else if (station_classes[i].id == 0) {
    76 		} else if (_station_classes[i].id == 0) {
    75 			/* This class is empty, so allocate it to the ClassID. */
    77 			/* This class is empty, so allocate it to the ClassID. */
    76 			station_classes[i].id = cls;
    78 			_station_classes[i].id = cls;
    77 			return i;
    79 			return i;
    78 		}
    80 		}
    79 	}
    81 	}
    80 
    82 
    81 	grfmsg(2, "StationClassAllocate: already allocated %d classes, using default", STAT_CLASS_MAX);
    83 	grfmsg(2, "StationClassAllocate: already allocated %d classes, using default", STAT_CLASS_MAX);
    84 
    86 
    85 /** Set the name of a custom station class */
    87 /** Set the name of a custom station class */
    86 void SetStationClassName(StationClassID sclass, StringID name)
    88 void SetStationClassName(StationClassID sclass, StringID name)
    87 {
    89 {
    88 	assert(sclass < STAT_CLASS_MAX);
    90 	assert(sclass < STAT_CLASS_MAX);
    89 	station_classes[sclass].name = name;
    91 	_station_classes[sclass].name = name;
    90 }
    92 }
    91 
    93 
    92 /** Retrieve the name of a custom station class */
    94 /** Retrieve the name of a custom station class */
    93 StringID GetStationClassName(StationClassID sclass)
    95 StringID GetStationClassName(StationClassID sclass)
    94 {
    96 {
    95 	assert(sclass < STAT_CLASS_MAX);
    97 	assert(sclass < STAT_CLASS_MAX);
    96 	return station_classes[sclass].name;
    98 	return _station_classes[sclass].name;
    97 }
       
    98 
       
    99 /** Build a list of station class name StringIDs to use in a dropdown list
       
   100  * @return Pointer to a (static) array of StringIDs
       
   101  */
       
   102 StringID *BuildStationClassDropdown()
       
   103 {
       
   104 	/* Allow room for all station classes, plus a terminator entry */
       
   105 	static StringID names[STAT_CLASS_MAX + 1];
       
   106 	uint i;
       
   107 
       
   108 	/* Add each name */
       
   109 	for (i = 0; i < STAT_CLASS_MAX && station_classes[i].id != 0; i++) {
       
   110 		names[i] = station_classes[i].name;
       
   111 	}
       
   112 	/* Terminate the list */
       
   113 	names[i] = INVALID_STRING_ID;
       
   114 
       
   115 	return names;
       
   116 }
    99 }
   117 
   100 
   118 /**
   101 /**
   119  * Get the number of station classes in use.
   102  * Get the number of station classes in use.
   120  * @return Number of station classes.
   103  * @return Number of station classes.
   121  */
   104  */
   122 uint GetNumStationClasses()
   105 uint GetNumStationClasses()
   123 {
   106 {
   124 	uint i;
   107 	uint i;
   125 	for (i = 0; i < STAT_CLASS_MAX && station_classes[i].id != 0; i++);
   108 	for (i = 0; i < STAT_CLASS_MAX && _station_classes[i].id != 0; i++);
   126 	return i;
   109 	return i;
   127 }
   110 }
   128 
   111 
   129 /**
   112 /**
   130  * Return the number of stations for the given station class.
   113  * Return the number of stations for the given station class.
   132  * @return Number of stations in the class.
   115  * @return Number of stations in the class.
   133  */
   116  */
   134 uint GetNumCustomStations(StationClassID sclass)
   117 uint GetNumCustomStations(StationClassID sclass)
   135 {
   118 {
   136 	assert(sclass < STAT_CLASS_MAX);
   119 	assert(sclass < STAT_CLASS_MAX);
   137 	return station_classes[sclass].stations;
   120 	return _station_classes[sclass].stations;
   138 }
   121 }
   139 
   122 
   140 /**
   123 /**
   141  * Tie a station spec to its station class.
   124  * Tie a station spec to its station class.
   142  * @param statspec The station spec.
   125  * @param statspec The station spec.
   148 
   131 
   149 	/* If the station has already been allocated, don't reallocate it. */
   132 	/* If the station has already been allocated, don't reallocate it. */
   150 	if (statspec->allocated) return;
   133 	if (statspec->allocated) return;
   151 
   134 
   152 	assert(statspec->sclass < STAT_CLASS_MAX);
   135 	assert(statspec->sclass < STAT_CLASS_MAX);
   153 	station_class = &station_classes[statspec->sclass];
   136 	station_class = &_station_classes[statspec->sclass];
   154 
   137 
   155 	i = station_class->stations++;
   138 	i = station_class->stations++;
   156 	station_class->spec = ReallocT(station_class->spec, station_class->stations);
   139 	station_class->spec = ReallocT(station_class->spec, station_class->stations);
   157 
   140 
   158 	station_class->spec[i] = statspec;
   141 	station_class->spec[i] = statspec;
   166  * @return The station spec.
   149  * @return The station spec.
   167  */
   150  */
   168 const StationSpec *GetCustomStationSpec(StationClassID sclass, uint station)
   151 const StationSpec *GetCustomStationSpec(StationClassID sclass, uint station)
   169 {
   152 {
   170 	assert(sclass < STAT_CLASS_MAX);
   153 	assert(sclass < STAT_CLASS_MAX);
   171 	if (station < station_classes[sclass].stations)
   154 	if (station < _station_classes[sclass].stations)
   172 		return station_classes[sclass].spec[station];
   155 		return _station_classes[sclass].spec[station];
   173 
   156 
   174 	/* If the custom station isn't defined any more, then the GRF file
   157 	/* If the custom station isn't defined any more, then the GRF file
   175 	 * probably was not loaded. */
   158 	 * probably was not loaded. */
   176 	return NULL;
   159 	return NULL;
   177 }
   160 }
   180 const StationSpec *GetCustomStationSpecByGrf(uint32 grfid, byte localidx)
   163 const StationSpec *GetCustomStationSpecByGrf(uint32 grfid, byte localidx)
   181 {
   164 {
   182 	uint j;
   165 	uint j;
   183 
   166 
   184 	for (StationClassID i = STAT_CLASS_BEGIN; i < STAT_CLASS_MAX; i++) {
   167 	for (StationClassID i = STAT_CLASS_BEGIN; i < STAT_CLASS_MAX; i++) {
   185 		for (j = 0; j < station_classes[i].stations; j++) {
   168 		for (j = 0; j < _station_classes[i].stations; j++) {
   186 			const StationSpec *statspec = station_classes[i].spec[j];
   169 			const StationSpec *statspec = _station_classes[i].spec[j];
   187 			if (statspec == NULL) continue;
   170 			if (statspec == NULL) continue;
   188 			if (statspec->grffile->grfid == grfid && statspec->localidx == localidx) return statspec;
   171 			if (statspec->grffile->grfid == grfid && statspec->localidx == localidx) return statspec;
   189 		}
   172 		}
   190 	}
   173 	}
   191 
   174 
   441 		/* Variables 0x60 to 0x65 are handled separately below */
   424 		/* Variables 0x60 to 0x65 are handled separately below */
   442 		case 0x67: { // Land info of nearby tiles
   425 		case 0x67: { // Land info of nearby tiles
   443 			Axis axis = GetRailStationAxis(tile);
   426 			Axis axis = GetRailStationAxis(tile);
   444 
   427 
   445 			if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required
   428 			if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required
   446 			byte tile_type = GetTerrainType(tile) << 2 | (IsTileType(tile, MP_WATER) ? 1 : 0) << 1;
   429 
   447 
   430 			Slope tileh = GetTileSlope(tile, NULL);
   448 			uint z;
   431 			bool swap = (axis == AXIS_Y && HasBit(tileh, SLOPE_W) != HasBit(tileh, SLOPE_E));
   449 			Slope tileh = GetTileSlope(tile, &z);
   432 
   450 			bool swap = (axis == AXIS_Y && HasBit(tileh, 0) != HasBit(tileh, 2));
   433 			return GetNearbyTileInformation(tile) ^ (swap ? SLOPE_EW : 0);
   451 			return GetTileType(tile) << 24 | z << 16 | tile_type << 8 | (tileh ^ (swap ? 5 : 0));
       
   452 		}
   434 		}
   453 
   435 
   454 		case 0x68: { // Station info of nearby tiles
   436 		case 0x68: { // Station info of nearby tiles
   455 			TileIndex nearby_tile = GetNearbyTile(parameter, tile);
   437 			TileIndex nearby_tile = GetNearbyTile(parameter, tile);
   456 
   438