src/engine.cpp
branchNewGRF_ports
changeset 10991 d8811e327d12
parent 10731 67db0d431d5e
equal deleted inserted replaced
10731:67db0d431d5e 10991:d8811e327d12
    26 #include "string_func.h"
    26 #include "string_func.h"
    27 #include "settings_type.h"
    27 #include "settings_type.h"
    28 #include "oldpool_func.h"
    28 #include "oldpool_func.h"
    29 #include "core/alloc_func.hpp"
    29 #include "core/alloc_func.hpp"
    30 #include "vehicle_func.h"
    30 #include "vehicle_func.h"
    31 #include "map"
    31 #include <map>
    32 
    32 
    33 #include "table/strings.h"
    33 #include "table/strings.h"
    34 #include "table/engines.h"
    34 #include "table/engines.h"
    35 
    35 
    36 DEFINE_OLD_POOL_GENERIC(Engine, Engine)
    36 DEFINE_OLD_POOL_GENERIC(Engine, Engine)
   113 {
   113 {
   114 	UnloadWagonOverrides(this);
   114 	UnloadWagonOverrides(this);
   115 	free(this->name);
   115 	free(this->name);
   116 }
   116 }
   117 
   117 
   118 /** Sort all items using qsort() and given 'CompareItems' function
       
   119  * @param el list to be sorted
       
   120  * @param compare function for evaluation of the quicksort
       
   121  */
       
   122 void EngList_Sort(EngineList *el, EngList_SortTypeFunction compare)
       
   123 {
       
   124 	size_t size = el->size();
       
   125 	/* out-of-bounds access at the next line for size == 0 (even with operator[] at some systems)
       
   126 	 * generally, do not sort if there are less than 2 items */
       
   127 	if (size < 2) return;
       
   128 	qsort(&((*el)[0]), size, sizeof(EngineID), compare); // MorphOS doesn't know vector::at(int) ...
       
   129 }
       
   130 
       
   131 /** Sort selected range of items (on indices @ <begin, begin+num_items-1>)
       
   132  * @param el list to be sorted
       
   133  * @param compare function for evaluation of the quicksort
       
   134  * @param begin start of sorting
       
   135  * @param num_items count of items to be sorted
       
   136  */
       
   137 void EngList_SortPartial(EngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items)
       
   138 {
       
   139 	assert(begin <= (uint)el->size());
       
   140 	assert(begin + num_items <= (uint)el->size());
       
   141 	if (num_items < 2) return;
       
   142 	qsort(&((*el)[begin]), num_items, sizeof(EngineID), compare);
       
   143 }
       
   144 
       
   145 
       
   146 /** Sets cached values in Player::num_vehicles and Group::num_vehicles
   118 /** Sets cached values in Player::num_vehicles and Group::num_vehicles
   147  */
   119  */
   148 void SetCachedEngineCounts()
   120 void SetCachedEngineCounts()
   149 {
   121 {
   150 	uint engines = GetEnginePoolSize();
   122 	uint engines = GetEnginePoolSize();
   210 {
   182 {
   211 	/* XXX: not done */
   183 	/* XXX: not done */
   212 	DEBUG(misc, 1, "LoadCustomEngineNames: not done");
   184 	DEBUG(misc, 1, "LoadCustomEngineNames: not done");
   213 }
   185 }
   214 
   186 
       
   187 /* Determine if an engine type is a wagon (and not a loco) */
       
   188 static bool IsWagon(EngineID index)
       
   189 {
       
   190 	const Engine *e = GetEngine(index);
       
   191 	return e->type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON;
       
   192 }
       
   193 
   215 static void CalcEngineReliability(Engine *e)
   194 static void CalcEngineReliability(Engine *e)
   216 {
   195 {
   217 	uint age = e->age;
   196 	uint age = e->age;
   218 
   197 
   219 	/* Check for early retirement */
   198 	/* Check for early retirement */
   220 	if (e->player_avail != 0 && !_settings.vehicle.never_expire_vehicles) {
   199 	if (e->player_avail != 0 && !_settings_game.vehicle.never_expire_vehicles) {
   221 		int retire_early = e->info.retire_early;
   200 		int retire_early = e->info.retire_early;
   222 		uint retire_early_max_age = max(0, e->duration_phase_1 + e->duration_phase_2 - retire_early * 12);
   201 		uint retire_early_max_age = max(0, e->duration_phase_1 + e->duration_phase_2 - retire_early * 12);
   223 		if (retire_early != 0 && age >= retire_early_max_age) {
   202 		if (retire_early != 0 && age >= retire_early_max_age) {
   224 			/* Early retirement is enabled and we're past the date... */
   203 			/* Early retirement is enabled and we're past the date... */
   225 			e->player_avail = 0;
   204 			e->player_avail = 0;
   228 	}
   207 	}
   229 
   208 
   230 	if (age < e->duration_phase_1) {
   209 	if (age < e->duration_phase_1) {
   231 		uint start = e->reliability_start;
   210 		uint start = e->reliability_start;
   232 		e->reliability = age * (e->reliability_max - start) / e->duration_phase_1 + start;
   211 		e->reliability = age * (e->reliability_max - start) / e->duration_phase_1 + start;
   233 	} else if ((age -= e->duration_phase_1) < e->duration_phase_2 || _settings.vehicle.never_expire_vehicles) {
   212 	} else if ((age -= e->duration_phase_1) < e->duration_phase_2 || _settings_game.vehicle.never_expire_vehicles) {
   234 		/* We are at the peak of this engines life. It will have max reliability.
   213 		/* We are at the peak of this engines life. It will have max reliability.
   235 		 * This is also true if the engines never expire. They will not go bad over time */
   214 		 * This is also true if the engines never expire. They will not go bad over time */
   236 		e->reliability = e->reliability_max;
   215 		e->reliability = e->reliability_max;
   237 	} else if ((age -= e->duration_phase_2) < e->duration_phase_3) {
   216 	} else if ((age -= e->duration_phase_2) < e->duration_phase_3) {
   238 		uint max = e->reliability_max;
   217 		uint max = e->reliability_max;
   282 		r = Random();
   261 		r = Random();
   283 		e->duration_phase_1 = GB(r, 0, 5) + 7;
   262 		e->duration_phase_1 = GB(r, 0, 5) + 7;
   284 		e->duration_phase_2 = GB(r, 5, 4) + ei->base_life * 12 - 96;
   263 		e->duration_phase_2 = GB(r, 5, 4) + ei->base_life * 12 - 96;
   285 		e->duration_phase_3 = GB(r, 9, 7) + 120;
   264 		e->duration_phase_3 = GB(r, 9, 7) + 120;
   286 
   265 
   287 		e->reliability_spd_dec = (ei->unk2&0x7F) << 2;
   266 		e->reliability_spd_dec = ei->decay_speed << 2;
   288 
   267 
   289 		/* my invented flag for something that is a wagon */
   268 		if (IsWagon(e->index)) {
   290 		if (ei->unk2 & 0x80) {
       
   291 			e->age = 0xFFFF;
   269 			e->age = 0xFFFF;
   292 		} else {
   270 		} else {
   293 			CalcEngineReliability(e);
   271 			CalcEngineReliability(e);
   294 		}
   272 		}
   295 
   273 
   296 		e->lifelength = ei->lifelength + _settings.vehicle.extend_vehicle_life;
   274 		e->lifelength = ei->lifelength + _settings_game.vehicle.extend_vehicle_life;
   297 
   275 
   298 		/* prevent certain engines from ever appearing. */
   276 		/* prevent certain engines from ever appearing. */
   299 		if (!HasBit(ei->climates, _settings.game_creation.landscape)) {
   277 		if (!HasBit(ei->climates, _settings_game.game_creation.landscape)) {
   300 			e->flags |= ENGINE_AVAILABLE;
   278 			e->flags |= ENGINE_AVAILABLE;
   301 			e->player_avail = 0;
   279 			e->player_avail = 0;
   302 		}
   280 		}
   303 	}
   281 	}
   304 }
   282 }
   401 	if (GetBestPlayer(e->preview_player_rank) != _current_player) return CMD_ERROR;
   379 	if (GetBestPlayer(e->preview_player_rank) != _current_player) return CMD_ERROR;
   402 
   380 
   403 	if (flags & DC_EXEC) AcceptEnginePreview(p1, _current_player);
   381 	if (flags & DC_EXEC) AcceptEnginePreview(p1, _current_player);
   404 
   382 
   405 	return CommandCost();
   383 	return CommandCost();
   406 }
       
   407 
       
   408 /* Determine if an engine type is a wagon (and not a loco) */
       
   409 static bool IsWagon(EngineID index)
       
   410 {
       
   411 	const Engine *e = GetEngine(index);
       
   412 	return e->type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON;
       
   413 }
   384 }
   414 
   385 
   415 StringID GetEngineCategoryName(EngineID engine);
   386 StringID GetEngineCategoryName(EngineID engine);
   416 
   387 
   417 static void NewVehicleAvailable(Engine *e)
   388 static void NewVehicleAvailable(Engine *e)