src/newgrf_engine.cpp
branchNewGRF_ports
changeset 6872 1c4a4a609f85
parent 6871 5a9dc001e1ad
child 6878 7d1ff2f621c7
equal deleted inserted replaced
6871:5a9dc001e1ad 6872:1c4a4a609f85
     4 
     4 
     5 #include "stdafx.h"
     5 #include "stdafx.h"
     6 #include "openttd.h"
     6 #include "openttd.h"
     7 #include "variables.h"
     7 #include "variables.h"
     8 #include "debug.h"
     8 #include "debug.h"
     9 #include "functions.h"
       
    10 #include "engine.h"
     9 #include "engine.h"
    11 #include "train.h"
    10 #include "train.h"
    12 #include "player.h"
    11 #include "player_func.h"
       
    12 #include "player_base.h"
    13 #include "station.h"
    13 #include "station.h"
    14 #include "airport.h"
    14 #include "airport.h"
    15 #include "newgrf.h"
    15 #include "newgrf.h"
    16 #include "newgrf_callbacks.h"
    16 #include "newgrf_callbacks.h"
    17 #include "newgrf_engine.h"
    17 #include "newgrf_engine.h"
    18 #include "newgrf_station.h"
    18 #include "newgrf_station.h"
    19 #include "newgrf_spritegroup.h"
    19 #include "newgrf_spritegroup.h"
    20 #include "newgrf_cargo.h"
    20 #include "newgrf_cargo.h"
    21 #include "date.h"
       
    22 #include "helpers.hpp"
       
    23 #include "cargotype.h"
    21 #include "cargotype.h"
       
    22 #include "date_func.h"
       
    23 #include "vehicle_func.h"
       
    24 #include "core/random_func.hpp"
       
    25 #include "direction_func.h"
    24 
    26 
    25 
    27 
    26 int _traininfo_vehicle_pitch = 0;
    28 int _traininfo_vehicle_pitch = 0;
    27 int _traininfo_vehicle_width = 29;
    29 int _traininfo_vehicle_width = 29;
    28 
    30 
    29 struct WagonOverride {
    31 struct WagonOverride {
    30 	byte *train_id;
    32 	EngineID *train_id;
    31 	int trains;
    33 	uint trains;
    32 	CargoID cargo;
    34 	CargoID cargo;
    33 	const SpriteGroup *group;
    35 	const SpriteGroup *group;
    34 };
    36 };
    35 
    37 
    36 struct WagonOverrides {
    38 struct WagonOverrides {
    37 	int overrides_count;
    39 	uint overrides_count;
    38 	WagonOverride *overrides;
    40 	WagonOverride *overrides;
    39 };
    41 };
    40 
    42 
    41 static WagonOverrides _engine_wagon_overrides[TOTAL_NUM_ENGINES];
    43 static WagonOverrides _engine_wagon_overrides[TOTAL_NUM_ENGINES];
    42 
    44 
    43 void SetWagonOverrideSprites(EngineID engine, CargoID cargo, const SpriteGroup *group, byte *train_id, int trains)
    45 void SetWagonOverrideSprites(EngineID engine, CargoID cargo, const SpriteGroup *group, EngineID *train_id, uint trains)
    44 {
    46 {
    45 	WagonOverrides *wos;
    47 	WagonOverrides *wos;
    46 	WagonOverride *wo;
    48 	WagonOverride *wo;
    47 
    49 
    48 	assert(engine < TOTAL_NUM_ENGINES);
    50 	assert(engine < TOTAL_NUM_ENGINES);
    57 	 * to prevent leaks. But first we need to refcount the SpriteGroup.
    59 	 * to prevent leaks. But first we need to refcount the SpriteGroup.
    58 	 * --pasky */
    60 	 * --pasky */
    59 	wo->group = group;
    61 	wo->group = group;
    60 	wo->cargo = cargo;
    62 	wo->cargo = cargo;
    61 	wo->trains = trains;
    63 	wo->trains = trains;
    62 	wo->train_id = MallocT<byte>(trains);
    64 	wo->train_id = MallocT<EngineID>(trains);
    63 	memcpy(wo->train_id, train_id, trains);
    65 	memcpy(wo->train_id, train_id, trains * sizeof *train_id);
    64 }
    66 }
    65 
    67 
    66 const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, byte overriding_engine)
    68 const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, EngineID overriding_engine)
    67 {
    69 {
    68 	const WagonOverrides *wos = &_engine_wagon_overrides[engine];
    70 	const WagonOverrides *wos = &_engine_wagon_overrides[engine];
    69 
    71 
    70 	/* XXX: This could turn out to be a timesink on profiles. We could
    72 	/* XXX: This could turn out to be a timesink on profiles. We could
    71 	 * always just dedicate 65535 bytes for an [engine][train] trampoline
    73 	 * always just dedicate 65535 bytes for an [engine][train] trampoline
    72 	 * for O(1). Or O(logMlogN) and searching binary tree or smt. like
    74 	 * for O(1). Or O(logMlogN) and searching binary tree or smt. like
    73 	 * that. --pasky */
    75 	 * that. --pasky */
    74 
    76 
    75 	for (int i = 0; i < wos->overrides_count; i++) {
    77 	for (uint i = 0; i < wos->overrides_count; i++) {
    76 		const WagonOverride *wo = &wos->overrides[i];
    78 		const WagonOverride *wo = &wos->overrides[i];
    77 
    79 
    78 		if (wo->cargo != cargo && wo->cargo != CT_DEFAULT) continue;
    80 		if (wo->cargo != cargo && wo->cargo != CT_DEFAULT) continue;
    79 
    81 
    80 		for (int j = 0; j < wo->trains; j++) {
    82 		for (uint j = 0; j < wo->trains; j++) {
    81 			if (wo->train_id[j] == overriding_engine) return wo->group;
    83 			if (wo->train_id[j] == overriding_engine) return wo->group;
    82 		}
    84 		}
    83 	}
    85 	}
    84 	return NULL;
    86 	return NULL;
    85 }
    87 }
    87 /**
    89 /**
    88  * Unload all wagon override sprite groups.
    90  * Unload all wagon override sprite groups.
    89  */
    91  */
    90 void UnloadWagonOverrides()
    92 void UnloadWagonOverrides()
    91 {
    93 {
    92 	WagonOverrides *wos;
    94 	for (EngineID engine = 0; engine < TOTAL_NUM_ENGINES; engine++) {
    93 	WagonOverride *wo;
    95 		WagonOverrides *wos = &_engine_wagon_overrides[engine];
    94 	EngineID engine;
    96 		for (uint i = 0; i < wos->overrides_count; i++) {
    95 	int i;
    97 			WagonOverride *wo = &wos->overrides[i];
    96 
       
    97 	for (engine = 0; engine < TOTAL_NUM_ENGINES; engine++) {
       
    98 		wos = &_engine_wagon_overrides[engine];
       
    99 		for (i = 0; i < wos->overrides_count; i++) {
       
   100 			wo = &wos->overrides[i];
       
   101 			wo->group = NULL;
       
   102 			free(wo->train_id);
    98 			free(wo->train_id);
   103 		}
    99 		}
   104 		free(wos->overrides);
   100 		free(wos->overrides);
   105 		wos->overrides_count = 0;
   101 		wos->overrides_count = 0;
   106 		wos->overrides = NULL;
   102 		wos->overrides = NULL;
   128 void UnloadCustomEngineSprites()
   124 void UnloadCustomEngineSprites()
   129 {
   125 {
   130 	memset(_engine_custom_sprites, 0, sizeof(_engine_custom_sprites));
   126 	memset(_engine_custom_sprites, 0, sizeof(_engine_custom_sprites));
   131 	memset(_engine_grf, 0, sizeof(_engine_grf));
   127 	memset(_engine_grf, 0, sizeof(_engine_grf));
   132 }
   128 }
   133 
       
   134 static const SpriteGroup *heli_rotor_custom_sprites[NUM_AIRCRAFT_ENGINES];
       
   135 
       
   136 /** Load a rotor override sprite group for an aircraft */
       
   137 void SetRotorOverrideSprites(EngineID engine, const SpriteGroup *group)
       
   138 {
       
   139 	assert(engine >= AIRCRAFT_ENGINES_INDEX);
       
   140 	assert(engine < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES);
       
   141 
       
   142 	if (heli_rotor_custom_sprites[engine - AIRCRAFT_ENGINES_INDEX] != NULL) {
       
   143 		grfmsg(6, "SetRotorOverrideSprites: engine %d already has group -- replacing.", engine);
       
   144 	}
       
   145 	heli_rotor_custom_sprites[engine - AIRCRAFT_ENGINES_INDEX] = group;
       
   146 }
       
   147 
       
   148 /** Unload all rotor override sprite groups */
       
   149 void UnloadRotorOverrideSprites()
       
   150 {
       
   151 	EngineID engine;
       
   152 
       
   153 	/* Starting at AIRCRAFT_ENGINES_INDEX may seem pointless, but it means
       
   154 	 * the context of EngineID is correct */
       
   155 	for (engine = AIRCRAFT_ENGINES_INDEX; engine < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES; engine++) {
       
   156 		heli_rotor_custom_sprites[engine - AIRCRAFT_ENGINES_INDEX] = NULL;
       
   157 	}
       
   158 }
       
   159 
       
   160 
   129 
   161 /**
   130 /**
   162  * Tie a GRFFile entry to an engine, to allow us to retrieve GRF parameters
   131  * Tie a GRFFile entry to an engine, to allow us to retrieve GRF parameters
   163  * etc during a game.
   132  * etc during a game.
   164  * @param engine Engine ID to tie the GRFFile to.
   133  * @param engine Engine ID to tie the GRFFile to.
   720 		case 0x5A: return v->Next() == NULL ? INVALID_VEHICLE : v->Next()->index;
   689 		case 0x5A: return v->Next() == NULL ? INVALID_VEHICLE : v->Next()->index;
   721 		case 0x5C: return ClampToI32(v->value);
   690 		case 0x5C: return ClampToI32(v->value);
   722 		case 0x5D: return GB(ClampToI32(v->value),  8, 24);
   691 		case 0x5D: return GB(ClampToI32(v->value),  8, 24);
   723 		case 0x5E: return GB(ClampToI32(v->value), 16, 16);
   692 		case 0x5E: return GB(ClampToI32(v->value), 16, 16);
   724 		case 0x5F: return GB(ClampToI32(v->value), 24,  8);
   693 		case 0x5F: return GB(ClampToI32(v->value), 24,  8);
   725 		case 0x60: return v->string_id;
       
   726 		case 0x61: return GB(v->string_id, 8, 8);
       
   727 		case 0x72: return v->cargo_subtype;
   694 		case 0x72: return v->cargo_subtype;
   728 		case 0x7A: return v->random_bits;
   695 		case 0x7A: return v->random_bits;
   729 		case 0x7B: return v->waiting_triggers;
   696 		case 0x7B: return v->waiting_triggers;
   730 	}
   697 	}
   731 
   698 
   786 
   753 
   787 	bool in_motion = v->First()->current_order.type != OT_LOADING;
   754 	bool in_motion = v->First()->current_order.type != OT_LOADING;
   788 
   755 
   789 	totalsets = in_motion ? group->g.real.num_loaded : group->g.real.num_loading;
   756 	totalsets = in_motion ? group->g.real.num_loaded : group->g.real.num_loading;
   790 
   757 
   791 	if (v->cargo.Count() == v->cargo_cap || totalsets == 1) {
   758 	if (v->cargo.Count() >= v->cargo_cap || totalsets == 1) {
   792 		set = totalsets - 1;
   759 		set = totalsets - 1;
   793 	} else if (v->cargo.Empty() || totalsets == 2) {
   760 	} else if (v->cargo.Empty() || totalsets == 2) {
   794 		set = 0;
   761 		set = 0;
   795 	} else {
   762 	} else {
   796 		set = v->cargo.Count() * (totalsets - 2) / max((uint16)1, v->cargo_cap) + 1;
   763 		set = v->cargo.Count() * (totalsets - 2) / max((uint16)1, v->cargo_cap) + 1;
   886 
   853 
   887 	NewVehicleResolver(&object, engine, v);
   854 	NewVehicleResolver(&object, engine, v);
   888 
   855 
   889 	object.info_view = info_view;
   856 	object.info_view = info_view;
   890 
   857 
   891 	group = heli_rotor_custom_sprites[engine - AIRCRAFT_ENGINES_INDEX];
   858 	group = GetWagonOverrideSpriteSet(engine, CT_DEFAULT, engine);
   892 	group = Resolve(group, &object);
   859 	group = Resolve(group, &object);
   893 
   860 
   894 	if (group == NULL || group->type != SGT_RESULT) return 0;
   861 	if (group == NULL || group->type != SGT_RESULT) return 0;
   895 
   862 
   896 	if (v == NULL) return group->g.result.sprite;
   863 	if (v == NULL) return group->g.result.sprite;
  1054 	}
  1021 	}
  1055 
  1022 
  1056 	DoTriggerVehicle(v, trigger, 0, true);
  1023 	DoTriggerVehicle(v, trigger, 0, true);
  1057 }
  1024 }
  1058 
  1025 
  1059 StringID _engine_custom_names[TOTAL_NUM_ENGINES];
       
  1060 
       
  1061 void SetCustomEngineName(EngineID engine, StringID name)
       
  1062 {
       
  1063 	assert(engine < lengthof(_engine_custom_names));
       
  1064 	_engine_custom_names[engine] = name;
       
  1065 }
       
  1066 
       
  1067 void UnloadCustomEngineNames()
       
  1068 {
       
  1069 	EngineID i;
       
  1070 	for (i = 0; i < TOTAL_NUM_ENGINES; i++) {
       
  1071 		_engine_custom_names[i] = 0;
       
  1072 	}
       
  1073 }
       
  1074 
       
  1075 StringID GetCustomEngineName(EngineID engine)
       
  1076 {
       
  1077 	return _engine_custom_names[engine] == 0 ? _engine_name_strings[engine] : _engine_custom_names[engine];
       
  1078 }
       
  1079 
       
  1080 /* Functions for changing the order of vehicle purchase lists
  1026 /* Functions for changing the order of vehicle purchase lists
  1081  * This is currently only implemented for rail vehicles. */
  1027  * This is currently only implemented for rail vehicles. */
  1082 static EngineID _engine_list_order[NUM_TRAIN_ENGINES];
  1028 static EngineID _engine_list_order[NUM_TRAIN_ENGINES];
  1083 static byte _engine_list_position[NUM_TRAIN_ENGINES];
  1029 static byte _engine_list_position[NUM_TRAIN_ENGINES];
  1084 
  1030