summaryrefslogtreecommitdiff
path: root/engine.c
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2007-01-02 19:19:48 +0000
committerrubidium <rubidium@openttd.org>2007-01-02 19:19:48 +0000
commit66bbf336c6af7353ef0aeed58002c46543b30635 (patch)
treead4a63860df2626b22f77e7dac712e958bea54cb /engine.c
parentccc0a3f4dbf58c005b22341ac8874252924690cd (diff)
downloadopenttd-66bbf336c6af7353ef0aeed58002c46543b30635.tar.xz
(svn r7759) -Merge: makefile rewrite. This merge features:
- A proper ./configure, so everything needs to be configured only once, not for every make. - Usage of makedepend when available. This greatly reduces the time needed for generating the dependencies. - A generator for all project files. There is a single file with sources, which is used to generate Makefiles and the project files for MSVC. - Proper support for OSX universal binaries. - Object files for non-MSVC compiles are also placed in separate directories, making is faster to switch between debug and release compiles and it does not touch the directory with the source files. - Functionality to make a bundle of all needed files for for example a nightly or distribution of a binary with all needed GRFs and language files. Note: as this merge moves almost all files, it is recommended to make a backup of your working copy before updating your working copy.
Diffstat (limited to 'engine.c')
-rw-r--r--engine.c650
1 files changed, 0 insertions, 650 deletions
diff --git a/engine.c b/engine.c
deleted file mode 100644
index 0a4b21c3d..000000000
--- a/engine.c
+++ /dev/null
@@ -1,650 +0,0 @@
-/* $Id$ */
-
-#include "stdafx.h"
-#include "openttd.h"
-#include "debug.h"
-#include "functions.h"
-#include "table/strings.h"
-#include "engine.h"
-#include "gfx.h"
-#include "player.h"
-#include "command.h"
-#include "vehicle.h"
-#include "news.h"
-#include "saveload.h"
-#include "variables.h"
-#include "train.h"
-#include "newgrf_cargo.h"
-#include "date.h"
-#include "table/engines.h"
-
-EngineInfo _engine_info[TOTAL_NUM_ENGINES];
-RailVehicleInfo _rail_vehicle_info[NUM_TRAIN_ENGINES];
-ShipVehicleInfo _ship_vehicle_info[NUM_SHIP_ENGINES];
-AircraftVehicleInfo _aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES];
-RoadVehicleInfo _road_vehicle_info[NUM_ROAD_ENGINES];
-
-enum {
- ENGINE_AVAILABLE = 1,
- ENGINE_INTRODUCING = 2,
- ENGINE_PREVIEWING = 4,
-};
-
-enum {
- YEAR_ENGINE_AGING_STOPS = 2050,
-};
-
-
-void ShowEnginePreviewWindow(EngineID engine);
-
-void DeleteCustomEngineNames(void)
-{
- uint i;
- StringID old;
-
- for (i = 0; i != TOTAL_NUM_ENGINES; i++) {
- old = _engine_name_strings[i];
- _engine_name_strings[i] = i + STR_8000_KIRBY_PAUL_TANK_STEAM;
- DeleteName(old);
- }
-
- _vehicle_design_names &= ~1;
-}
-
-void LoadCustomEngineNames(void)
-{
- /* XXX: not done */
- DEBUG(misc, 1, "LoadCustomEngineNames: not done");
-}
-
-static void SetupEngineNames(void)
-{
- StringID *name;
-
- for (name = _engine_name_strings; name != endof(_engine_name_strings); name++)
- *name = STR_SV_EMPTY;
-
- DeleteCustomEngineNames();
- LoadCustomEngineNames();
-}
-
-static void AdjustAvailAircraft(void)
-{
- byte avail = 0;
- if (_cur_year >= 1955) avail |= 2; // big airport
- if (_cur_year < 1960 || _patches.always_small_airport) avail |= 1; // small airport
- if (_cur_year >= 1963) avail |= 4; // enable heliport
-
- if (avail != _avail_aircraft) {
- _avail_aircraft = avail;
- InvalidateWindow(WC_BUILD_STATION, 0);
- }
-}
-
-static void CalcEngineReliability(Engine *e)
-{
- uint age = e->age;
-
- if (age < e->duration_phase_1) {
- uint start = e->reliability_start;
- e->reliability = age * (e->reliability_max - start) / e->duration_phase_1 + start;
- } else if ((age -= e->duration_phase_1) < e->duration_phase_2 || _patches.never_expire_vehicles) {
- /* We are at the peak of this engines life. It will have max reliability.
- * This is also true if the engines never expire. They will not go bad over time */
- e->reliability = e->reliability_max;
- } else if ((age -= e->duration_phase_2) < e->duration_phase_3) {
- uint max = e->reliability_max;
- e->reliability = (int)age * (int)(e->reliability_final - max) / e->duration_phase_3 + max;
- } else {
- /* time's up for this engine.
- * We will now completely retire this design */
- e->player_avail = 0;
- e->reliability = e->reliability_final;
- InvalidateWindowClassesData(WC_BUILD_VEHICLE); // Kick this engine out of the lists
- }
- InvalidateWindowClasses(WC_BUILD_VEHICLE); // Update to show the new reliability
-}
-
-void AddTypeToEngines(void)
-{
- Engine* e = _engines;
-
- do e->type = VEH_Train; while (++e < &_engines[ROAD_ENGINES_INDEX]);
- do e->type = VEH_Road; while (++e < &_engines[SHIP_ENGINES_INDEX]);
- do e->type = VEH_Ship; while (++e < &_engines[AIRCRAFT_ENGINES_INDEX]);
- do e->type = VEH_Aircraft; while (++e < &_engines[TOTAL_NUM_ENGINES]);
- do e->type = VEH_Special; while (++e < endof(_engines));
-}
-
-void StartupEngines(void)
-{
- Engine *e;
- const EngineInfo *ei;
- /* Aging of vehicles stops, so account for that when starting late */
- const Date aging_date = min(_date, ConvertYMDToDate(YEAR_ENGINE_AGING_STOPS, 0, 1));
-
- SetupEngineNames();
-
- for (e = _engines, ei = _engine_info; e != endof(_engines); e++, ei++) {
- uint32 r;
-
- e->age = 0;
- e->railtype = ei->railtype;
- e->flags = 0;
- e->player_avail = 0;
-
- // The magic value of 729 days below comes from the NewGRF spec. If the
- // base intro date is before 1922 then the random number of days is not
- // added.
- r = Random();
- e->intro_date = ei->base_intro <= ConvertYMDToDate(1922, 0, 1) ? ei->base_intro : (Date)GB(r, 0, 9) + ei->base_intro;
- if (e->intro_date <= _date) {
- e->age = (aging_date - e->intro_date) >> 5;
- e->player_avail = (byte)-1;
- e->flags |= ENGINE_AVAILABLE;
- }
-
- e->reliability_start = GB(r, 16, 14) + 0x7AE0;
- r = Random();
- e->reliability_max = GB(r, 0, 14) + 0xBFFF;
- e->reliability_final = GB(r, 16, 14) + 0x3FFF;
-
- r = Random();
- e->duration_phase_1 = GB(r, 0, 5) + 7;
- e->duration_phase_2 = GB(r, 5, 4) + ei->base_life * 12 - 96;
- e->duration_phase_3 = GB(r, 9, 7) + 120;
-
- e->reliability_spd_dec = (ei->unk2&0x7F) << 2;
-
- /* my invented flag for something that is a wagon */
- if (ei->unk2 & 0x80) {
- e->age = 0xFFFF;
- } else {
- CalcEngineReliability(e);
- }
-
- e->lifelength = ei->lifelength + _patches.extend_vehicle_life;
-
- // prevent certain engines from ever appearing.
- if (!HASBIT(ei->climates, _opt.landscape)) {
- e->flags |= ENGINE_AVAILABLE;
- e->player_avail = 0;
- }
-
- /* This sets up type for the engine
- * It is needed if you want to ask the engine what type it is
- * It should hopefully be the same as when you ask a vehicle what it is
- * but using this, you can ask what type an engine number is
- * even if it is not a vehicle (yet)*/
- }
-
- AdjustAvailAircraft();
-}
-
-static void AcceptEnginePreview(Engine *e, PlayerID player)
-{
- Player *p = GetPlayer(player);
-
- assert(e->railtype < RAILTYPE_END);
- SETBIT(e->player_avail, player);
- SETBIT(p->avail_railtypes, e->railtype);
-
- e->preview_player = 0xFF;
- if (player == _local_player) {
- InvalidateWindowClassesData(WC_BUILD_VEHICLE);
- InvalidateWindowClasses(WC_REPLACE_VEHICLE);
- }
-}
-
-static PlayerID GetBestPlayer(PlayerID pp)
-{
- const Player *p;
- int32 best_hist;
- PlayerID best_player;
- uint mask = 0;
-
- do {
- best_hist = -1;
- best_player = PLAYER_SPECTATOR;
- FOR_ALL_PLAYERS(p) {
- if (p->is_active && p->block_preview == 0 && !HASBIT(mask, p->index) &&
- p->old_economy[0].performance_history > best_hist) {
- best_hist = p->old_economy[0].performance_history;
- best_player = p->index;
- }
- }
-
- if (best_player == PLAYER_SPECTATOR) return PLAYER_SPECTATOR;
-
- SETBIT(mask, best_player);
- } while (--pp != 0);
-
- return best_player;
-}
-
-void EnginesDailyLoop(void)
-{
- EngineID i;
-
- if (_cur_year >= YEAR_ENGINE_AGING_STOPS) return;
-
- for (i = 0; i != lengthof(_engines); i++) {
- Engine *e = &_engines[i];
-
- if (e->flags & ENGINE_INTRODUCING) {
- if (e->flags & ENGINE_PREVIEWING) {
- if (e->preview_player != 0xFF && !--e->preview_wait) {
- e->flags &= ~ENGINE_PREVIEWING;
- DeleteWindowById(WC_ENGINE_PREVIEW, i);
- e->preview_player++;
- }
- } else if (e->preview_player != 0xFF) {
- PlayerID best_player = GetBestPlayer(e->preview_player);
-
- if (best_player == PLAYER_SPECTATOR) {
- e->preview_player = 0xFF;
- continue;
- }
-
- if (!IsHumanPlayer(best_player)) {
- /* XXX - TTDBUG: TTD has a bug here ???? */
- AcceptEnginePreview(e, best_player);
- } else {
- e->flags |= ENGINE_PREVIEWING;
- e->preview_wait = 20;
- if (IsInteractivePlayer(best_player)) ShowEnginePreviewWindow(i);
- }
- }
- }
- }
-}
-
-/** Accept an engine prototype. XXX - it is possible that the top-player
- * changes while you are waiting to accept the offer? Then it becomes invalid
- * @param tile unused
- * @param p1 engine-prototype offered
- * @param p2 unused
- */
-int32 CmdWantEnginePreview(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
-{
- Engine *e;
-
- if (!IsEngineIndex(p1)) return CMD_ERROR;
- e = GetEngine(p1);
- if (GetBestPlayer(e->preview_player) != _current_player) return CMD_ERROR;
-
- if (flags & DC_EXEC) AcceptEnginePreview(e, _current_player);
-
- return 0;
-}
-
-// Determine if an engine type is a wagon (and not a loco)
-static bool IsWagon(EngineID index)
-{
- return index < NUM_TRAIN_ENGINES && RailVehInfo(index)->flags & RVI_WAGON;
-}
-
-static void NewVehicleAvailable(Engine *e)
-{
- Vehicle *v;
- Player *p;
- EngineID index = e - _engines;
-
- // In case the player didn't build the vehicle during the intro period,
- // prevent that player from getting future intro periods for a while.
- if (e->flags & ENGINE_INTRODUCING) {
- FOR_ALL_PLAYERS(p) {
- uint block_preview = p->block_preview;
-
- if (!HASBIT(e->player_avail, p->index)) continue;
-
- /* We assume the user did NOT build it.. prove me wrong ;) */
- p->block_preview = 20;
-
- FOR_ALL_VEHICLES(v) {
- if (v->type == VEH_Train || v->type == VEH_Road || v->type == VEH_Ship ||
- (v->type == VEH_Aircraft && v->subtype <= 2)) {
- if (v->owner == p->index && v->engine_type == index) {
- /* The user did prove me wrong, so restore old value */
- p->block_preview = block_preview;
- break;
- }
- }
- }
- }
- }
-
- e->flags = (e->flags & ~ENGINE_INTRODUCING) | ENGINE_AVAILABLE;
- InvalidateWindowClassesData(WC_BUILD_VEHICLE);
- InvalidateWindowClasses(WC_REPLACE_VEHICLE);
-
- // Now available for all players
- e->player_avail = (byte)-1;
-
- // Do not introduce new rail wagons
- if (IsWagon(index)) return;
-
- // make maglev / monorail available
- FOR_ALL_PLAYERS(p) {
- if (p->is_active) {
- assert(e->railtype < RAILTYPE_END);
- SETBIT(p->avail_railtypes, e->railtype);
- }
- }
-
- if (index < NUM_TRAIN_ENGINES) {
- AddNewsItem(index, NEWS_FLAGS(NM_CALLBACK, 0, NT_NEW_VEHICLES, DNC_TRAINAVAIL), 0, 0);
- } else if (index < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES) {
- AddNewsItem(index, NEWS_FLAGS(NM_CALLBACK, 0, NT_NEW_VEHICLES, DNC_ROADAVAIL), 0, 0);
- } else if (index < NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES) {
- AddNewsItem(index, NEWS_FLAGS(NM_CALLBACK, 0, NT_NEW_VEHICLES, DNC_SHIPAVAIL), 0, 0);
- } else {
- AddNewsItem(index, NEWS_FLAGS(NM_CALLBACK, 0, NT_NEW_VEHICLES, DNC_AIRCRAFTAVAIL), 0, 0);
- }
-}
-
-void EnginesMonthlyLoop(void)
-{
- Engine *e;
-
- if (_cur_year < YEAR_ENGINE_AGING_STOPS) {
- for (e = _engines; e != endof(_engines); e++) {
- // Age the vehicle
- if (e->flags & ENGINE_AVAILABLE && e->age != 0xFFFF) {
- e->age++;
- CalcEngineReliability(e);
- }
-
- if (!(e->flags & ENGINE_AVAILABLE) && _date >= (e->intro_date + 365)) {
- // Introduce it to all players
- NewVehicleAvailable(e);
- } else if (!(e->flags & (ENGINE_AVAILABLE|ENGINE_INTRODUCING)) && _date >= e->intro_date) {
- // Introduction date has passed.. show introducing dialog to one player.
- e->flags |= ENGINE_INTRODUCING;
-
- // Do not introduce new rail wagons
- if (!IsWagon(e - _engines))
- e->preview_player = 1; // Give to the player with the highest rating.
- }
- }
- }
- AdjustAvailAircraft();
-}
-
-/** Rename an engine.
- * @param tile unused
- * @param p1 engine ID to rename
- * @param p2 unused
- */
-int32 CmdRenameEngine(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
-{
- StringID str;
-
- if (!IsEngineIndex(p1) || _cmd_text[0] == '\0') return CMD_ERROR;
-
- str = AllocateNameUnique(_cmd_text, 0);
- if (str == 0) return CMD_ERROR;
-
- if (flags & DC_EXEC) {
- StringID old_str = _engine_name_strings[p1];
- _engine_name_strings[p1] = str;
- DeleteName(old_str);
- _vehicle_design_names |= 3;
- MarkWholeScreenDirty();
- } else {
- DeleteName(str);
- }
-
- return 0;
-}
-
-
-/*
- * returns true if an engine is valid, of the specified type, and buildable by
- * the given player, false otherwise
- *
- * engine = index of the engine to check
- * type = the type the engine should be of (VEH_xxx)
- * player = index of the player
- */
-bool IsEngineBuildable(EngineID engine, byte type, PlayerID player)
-{
- const Engine *e;
-
- // check if it's an engine that is in the engine array
- if (!IsEngineIndex(engine)) return false;
-
- e = GetEngine(engine);
-
- // check if it's an engine of specified type
- if (e->type != type) return false;
-
- // check if it's available
- if (!HASBIT(e->player_avail, player)) return false;
-
- return true;
-}
-
-/************************************************************************
- * Engine Replacement stuff
- ************************************************************************/
-
-static void EngineRenewPoolNewBlock(uint start_item);
-
-DEFINE_OLD_POOL(EngineRenew, EngineRenew, EngineRenewPoolNewBlock, NULL)
-
-static void EngineRenewPoolNewBlock(uint start_item)
-{
- EngineRenew *er;
-
- /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
- * TODO - This is just a temporary stage, this will be removed. */
- for (er = GetEngineRenew(start_item); er != NULL; er = (er->index + 1U < GetEngineRenewPoolSize()) ? GetEngineRenew(er->index + 1U) : NULL) {
- er->index = start_item++;
- er->from = INVALID_ENGINE;
- }
-}
-
-
-static EngineRenew *AllocateEngineRenew(void)
-{
- EngineRenew *er;
-
- /* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
- * TODO - This is just a temporary stage, this will be removed. */
- for (er = GetEngineRenew(0); er != NULL; er = (er->index + 1U < GetEngineRenewPoolSize()) ? GetEngineRenew(er->index + 1U) : NULL) {
- if (IsValidEngineRenew(er)) continue;
-
- er->to = INVALID_ENGINE;
- er->next = NULL;
- return er;
- }
-
- /* Check if we can add a block to the pool */
- if (AddBlockToPool(&_EngineRenew_pool)) return AllocateEngineRenew();
-
- return NULL;
-}
-
-/**
- * Retrieves the EngineRenew that specifies the replacement of the given
- * engine type from the given renewlist */
-static EngineRenew *GetEngineReplacement(EngineRenewList erl, EngineID engine)
-{
- EngineRenew *er = (EngineRenew *)erl;
-
- while (er) {
- if (er->from == engine) return er;
- er = er->next;
- }
- return NULL;
-}
-
-void RemoveAllEngineReplacement(EngineRenewList *erl)
-{
- EngineRenew *er = (EngineRenew *)(*erl);
- EngineRenew *next;
-
- while (er) {
- next = er->next;
- DeleteEngineRenew(er);
- er = next;
- }
- *erl = NULL; // Empty list
-}
-
-EngineID EngineReplacement(EngineRenewList erl, EngineID engine)
-{
- const EngineRenew *er = GetEngineReplacement(erl, engine);
- return er == NULL ? INVALID_ENGINE : er->to;
-}
-
-int32 AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, EngineID new_engine, uint32 flags)
-{
- EngineRenew *er;
-
- /* Check if the old vehicle is already in the list */
- er = GetEngineReplacement(*erl, old_engine);
- if (er != NULL) {
- if (flags & DC_EXEC) er->to = new_engine;
- return 0;
- }
-
- er = AllocateEngineRenew();
- if (er == NULL) return CMD_ERROR;
-
- if (flags & DC_EXEC) {
- er->from = old_engine;
- er->to = new_engine;
-
- /* Insert before the first element */
- er->next = (EngineRenew *)(*erl);
- *erl = (EngineRenewList)er;
- }
-
- return 0;
-}
-
-int32 RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, uint32 flags)
-{
- EngineRenew *er = (EngineRenew *)(*erl);
- EngineRenew *prev = NULL;
-
- while (er)
- {
- if (er->from == engine) {
- if (flags & DC_EXEC) {
- if (prev == NULL) { // First element
- /* The second becomes the new first element */
- *erl = (EngineRenewList)er->next;
- } else {
- /* Cut this element out */
- prev->next = er->next;
- }
- DeleteEngineRenew(er);
- }
- return 0;
- }
- prev = er;
- er = er->next;
- }
-
- return CMD_ERROR;
-}
-
-static const SaveLoad _engine_renew_desc[] = {
- SLE_VAR(EngineRenew, from, SLE_UINT16),
- SLE_VAR(EngineRenew, to, SLE_UINT16),
-
- SLE_REF(EngineRenew, next, REF_ENGINE_RENEWS),
-
- SLE_END()
-};
-
-static void Save_ERNW(void)
-{
- EngineRenew *er;
-
- FOR_ALL_ENGINE_RENEWS(er) {
- SlSetArrayIndex(er->index);
- SlObject(er, _engine_renew_desc);
- }
-}
-
-static void Load_ERNW(void)
-{
- int index;
-
- while ((index = SlIterateArray()) != -1) {
- EngineRenew *er;
-
- if (!AddBlockIfNeeded(&_EngineRenew_pool, index))
- error("EngineRenews: failed loading savegame: too many EngineRenews");
-
- er = GetEngineRenew(index);
- SlObject(er, _engine_renew_desc);
- }
-}
-
-static const SaveLoad _engine_desc[] = {
- SLE_CONDVAR(Engine, intro_date, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
- SLE_CONDVAR(Engine, intro_date, SLE_INT32, 31, SL_MAX_VERSION),
- SLE_CONDVAR(Engine, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
- SLE_CONDVAR(Engine, age, SLE_INT32, 31, SL_MAX_VERSION),
- SLE_VAR(Engine, reliability, SLE_UINT16),
- SLE_VAR(Engine, reliability_spd_dec, SLE_UINT16),
- SLE_VAR(Engine, reliability_start, SLE_UINT16),
- SLE_VAR(Engine, reliability_max, SLE_UINT16),
- SLE_VAR(Engine, reliability_final, SLE_UINT16),
- SLE_VAR(Engine, duration_phase_1, SLE_UINT16),
- SLE_VAR(Engine, duration_phase_2, SLE_UINT16),
- SLE_VAR(Engine, duration_phase_3, SLE_UINT16),
-
- SLE_VAR(Engine, lifelength, SLE_UINT8),
- SLE_VAR(Engine, flags, SLE_UINT8),
- SLE_VAR(Engine, preview_player, SLE_UINT8),
- SLE_VAR(Engine, preview_wait, SLE_UINT8),
- SLE_VAR(Engine, railtype, SLE_UINT8),
- SLE_VAR(Engine, player_avail, SLE_UINT8),
-
- // reserve extra space in savegame here. (currently 16 bytes)
- SLE_CONDNULL(16, 2, SL_MAX_VERSION),
-
- SLE_END()
-};
-
-static void Save_ENGN(void)
-{
- uint i;
-
- for (i = 0; i != lengthof(_engines); i++) {
- SlSetArrayIndex(i);
- SlObject(&_engines[i], _engine_desc);
- }
-}
-
-static void Load_ENGN(void)
-{
- int index;
- while ((index = SlIterateArray()) != -1) {
- SlObject(GetEngine(index), _engine_desc);
- }
-}
-
-static void LoadSave_ENGS(void)
-{
- SlArray(_engine_name_strings, lengthof(_engine_name_strings), SLE_STRINGID);
-}
-
-const ChunkHandler _engine_chunk_handlers[] = {
- { 'ENGN', Save_ENGN, Load_ENGN, CH_ARRAY },
- { 'ENGS', LoadSave_ENGS, LoadSave_ENGS, CH_RIFF },
- { 'ERNW', Save_ERNW, Load_ERNW, CH_ARRAY | CH_LAST},
-};
-
-void InitializeEngines(void)
-{
- /* Clean the engine renew pool and create 1 block in it */
- CleanPool(&_EngineRenew_pool);
- AddBlockToPool(&_EngineRenew_pool);
-}