From a7d8ad0004e00e1d917d636f4d69fd58f5edbfa3 Mon Sep 17 00:00:00 2001 From: celestar Date: Wed, 29 Mar 2006 16:30:26 +0000 Subject: [PATCH] (svn r4150) -Feature: Merged elrails into trunk. Thanks to Tron for lots of code and proofreading, thanks to peter1138 for another lot of code and ideas. --- BUGS | 7 + Makefile | 1 + ai/default/default.c | 45 +- bridge.h | 2 + bridge_map.h | 1 + data/elrailsw.grf | Bin 0 -> 7699 bytes docs/elrail.svg | 1091 +++++++++++++++++++++++++++++++++++++++ docs/elrail_tile.png | Bin 0 -> 64028 bytes docs/elrail_track.png | Bin 0 -> 62629 bytes docs/landscape.html | 2 +- elrail.c | 352 +++++++++++++ engine_gui.c | 7 +- gfxinit.c | 3 + lang/english.txt | 4 + misc.c | 3 - newgrf.c | 11 +- npf.c | 24 +- npf.h | 12 +- openttd.c | 69 +++ openttd.dsp | 4 + openttd.vcproj | 3 + pathfind.c | 13 +- pathfind.h | 2 +- player.h | 1 + rail.h | 22 +- rail_cmd.c | 15 +- rail_map.h | 9 +- railtypes.h | 65 ++- road_cmd.c | 1 + saveload.c | 2 +- station_cmd.c | 2 + table/elrail_data.h | 362 +++++++++++++ table/engines.h | 15 +- table/landscape_const.h | 29 -- table/sprites.h | 64 ++- train_cmd.c | 87 +++- train_gui.c | 4 +- tunnelbridge_cmd.c | 13 +- variables.h | 1 - vehicle.c | 4 + vehicle.h | 2 + vehicle_gui.c | 26 +- 42 files changed, 2258 insertions(+), 122 deletions(-) create mode 100644 BUGS create mode 100644 data/elrailsw.grf create mode 100644 docs/elrail.svg create mode 100644 docs/elrail_tile.png create mode 100644 docs/elrail_track.png create mode 100644 elrail.c create mode 100644 table/elrail_data.h diff --git a/BUGS b/BUGS new file mode 100644 index 0000000000..bcdcee6f2a --- /dev/null +++ b/BUGS @@ -0,0 +1,7 @@ +/* $Id */ + +KNOWN BUGS / PROBLEMS: + +Normal and elrail depots look the same. Use 'X' (transparent buildings) + to distinguish between them +Missing curors / icons for construction (currently using the conventional ones) diff --git a/Makefile b/Makefile index 5fb9a1eb73..4de699a2ac 100644 --- a/Makefile +++ b/Makefile @@ -630,6 +630,7 @@ SRCS += dock_gui.c SRCS += driver.c SRCS += dummy_land.c SRCS += economy.c +SRCS += elrail.c SRCS += engine.c SRCS += engine_gui.c SRCS += fileio.c diff --git a/ai/default/default.c b/ai/default/default.c index 2a638e3e90..8c4d2569e4 100644 --- a/ai/default/default.c +++ b/ai/default/default.c @@ -126,7 +126,7 @@ static void AiStateVehLoop(Player *p) p->ai.state_counter = 0; } -static EngineID AiChooseTrainToBuild(byte railtype, int32 money, byte flag, TileIndex tile) +static EngineID AiChooseTrainToBuild(RailType railtype, int32 money, byte flag, TileIndex tile) { EngineID best_veh_index = INVALID_ENGINE; byte best_veh_score = 0; @@ -137,7 +137,7 @@ static EngineID AiChooseTrainToBuild(byte railtype, int32 money, byte flag, Tile const RailVehicleInfo *rvi = RailVehInfo(i); const Engine* e = GetEngine(i); - if (e->railtype != railtype || + if (!IsCompatibleRail(e->railtype, railtype) || rvi->flags & RVI_WAGON || (rvi->flags & RVI_MULTIHEAD && flag & 1) || !HASBIT(e->player_avail, _current_player) || @@ -2321,6 +2321,41 @@ static StationID AiGetStationIdByDef(TileIndex tile, int id) return GetStationIndex(TILE_ADD(tile, ToTileIndexDiff(p->tileoffs))); } +static EngineID AiFindBestWagon(CargoID cargo, RailType railtype) +{ + EngineID best_veh_index = INVALID_ENGINE; + EngineID i; + uint16 best_capacity = 0; + uint16 best_speed = 0; + uint speed; + + for (i = 0; i < NUM_TRAIN_ENGINES; i++) { + const RailVehicleInfo *rvi = RailVehInfo(i); + const Engine* e = GetEngine(i); + + if (!IsCompatibleRail(e->railtype, railtype) || + !(rvi->flags & RVI_WAGON) || + !HASBIT(e->player_avail, _current_player)) { + continue; + } + + if (rvi->cargo_type != cargo) { + continue; + } + + /* max_speed of 0 indicates no speed limit */ + speed = rvi->max_speed == 0 ? 0xFFFF : rvi->max_speed; + + if (rvi->capacity >= best_capacity && speed >= best_speed) { + best_capacity = rvi->capacity; + best_speed = best_speed; + best_veh_index = i; + } + } + + return best_veh_index; +} + static void AiStateBuildRailVeh(Player *p) { const AiDefaultBlockData *ptr; @@ -2337,10 +2372,14 @@ static void AiStateBuildRailVeh(Player *p) tile = TILE_ADD(p->ai.src.use_tile, ToTileIndexDiff(ptr->tileoffs)); + cargo = p->ai.cargo_type; for (i = 0;;) { if (p->ai.wagon_list[i] == INVALID_VEHICLE) { - veh = _cargoc.ai_railwagon[p->ai.railtype_to_use][cargo]; + veh = AiFindBestWagon(cargo, p->ai.railtype_to_use); + /* veh will return INVALID_ENGINE if no suitable wagon is available. + * We shall treat this in the same way as having no money */ + if (veh == INVALID_ENGINE) goto handle_nocash; cost = DoCommandByTile(tile, veh, 0, DC_EXEC, CMD_BUILD_RAIL_VEHICLE); if (CmdFailed(cost)) goto handle_nocash; p->ai.wagon_list[i] = _new_wagon_id; diff --git a/bridge.h b/bridge.h index 79ea4fbde3..18fcf81de8 100644 --- a/bridge.h +++ b/bridge.h @@ -22,4 +22,6 @@ typedef struct Bridge { extern const Bridge orig_bridge[MAX_BRIDGES]; extern Bridge _bridge[MAX_BRIDGES]; +uint GetBridgeFoundation(uint tileh, Axis axis); + #endif /* BRIDGE_H */ diff --git a/bridge_map.h b/bridge_map.h index f799077b3c..014a3671c8 100644 --- a/bridge_map.h +++ b/bridge_map.h @@ -127,6 +127,7 @@ TileIndex GetSouthernBridgeEnd(TileIndex t); */ TileIndex GetOtherBridgeEnd(TileIndex); +uint GetBridgeHeight(TileIndex t); static inline void SetClearUnderBridge(TileIndex t) { diff --git a/data/elrailsw.grf b/data/elrailsw.grf new file mode 100644 index 0000000000000000000000000000000000000000..f722d1e3a7cb97e0bf00cc7d850df488954fbfc2 GIT binary patch literal 7699 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 + + + + + + + + image/svg+xml + + + + + + + + N + + Pylon Control Point (PCP) + + + + + + + + + + + + + + + + not allowed, not owned + not allowed, owned + allowed, owned + allowed, not owned + Pylon Position Point (PPP) + + + + + + + + + + + + + + + + + + + + + + + + + + + + not allowed, but preferred (end of line marker) + not allowed + preferred, allowed + allowed + Pylon Position Point (PPP) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + preferred, allowed andcan be ignored to createlong wires (which span2 tiles) + + diff --git a/docs/elrail_tile.png b/docs/elrail_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..82407de486ef0dbc451acf766faee098bd649685 GIT binary patch literal 64028 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
CEx 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 literal 0 HcmV?d00001 diff --git a/docs/elrail_track.png b/docs/elrail_track.png new file mode 100644 index 0000000000000000000000000000000000000000..af88bd3317920da5353412ba9516241feec4cae3 GIT binary patch literal 62629 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 z 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 G5}E*U1>X$- literal 0 HcmV?d00001 diff --git a/docs/landscape.html b/docs/landscape.html index 92fed219e4..b28a8932fc 100644 --- a/docs/landscape.html +++ b/docs/landscape.html @@ -129,7 +129,7 @@ m5 bit 7 clear: railway track B  fence on the N side (track in the S corner) C  on snow or desert -
  • m3 bits 0..3 = track type: 0 - conventional railway, 1 - monorail, 2 - maglev +
  • m3 bits 0..3 = track type: 0 - conventional railway, 1 - electrified railway, 2 - monorail, 3 - maglev m5 bits 7 and 6 set: railway depot / checkpoints
      diff --git a/elrail.c b/elrail.c new file mode 100644 index 0000000000..cfe69b2ab7 --- /dev/null +++ b/elrail.c @@ -0,0 +1,352 @@ +/* $Id$ */ +/** @file elrail.c + * This file deals with displaying wires and pylons for electric railway systems. +

      Basics

      + +

      Tile Types

      + +We have two different types of tiles in the drawing code: +Normal Railway Tiles (NRTs) which can have more than one track on it, and +Special Railways tiles (SRTs) which have only one track (like crossings, depots +stations, etc). + +

      Location Categories

      + +All tiles are categorized into three location groups (TLG): +Group 0: Tiles with both an even X coordinate and an even Y coordinate +Group 1: Tiles with an even X and an odd Y coordinate +Group 2: Tiles with an odd X and an even Y coordinate +Group 3: Tiles with both an odd X and Y coordnate. + +

      Pylon Points

      +

      Control Points

      +A Pylon Control Point (PCP) is a position where a wire (or rather two) +is mounted onto a pylon. +Each NRT does contain 4 PCPs which are mapped to a byte +variable and are represented by the DiagDirection enum: + +A wire that ends on the PCP has a dark ending, otherwise the end is bright.

      + +Now on each edge there are two PCPs: One from each adjacent tile. Both PCPs are merged +using an OR matrix (i. e. if one tile needs a PCP at the postion in question, both +tiles get it). + +

      Position Points

      +A Pylon Position Point (PPP) is a position where a pylon is located on the ground. +Each PCP owns 8 in (45 degree steps) PPPs that are located around it. PPPs are numbered +0 to 7 with 0 starting north and numbering in clockwise direction. Each track bit has PPPs +that are impossible (because the pylon would be situated on the track), preferred (because +the pylon would be rectangular to the track). PPPs are represented by the Direction enum. + + + + + */ + +#include "stdafx.h" +#include "openttd.h" +#include "tile.h" +#include "viewport.h" +#include "functions.h" /* We should REALLY get rid of this goddamn file, as it is butt-ugly */ +#include "variables.h" /* ... same here */ +#include "rail.h" +#include "debug.h" +#include "tunnel_map.h" +#include "road_map.h" +#include "bridge_map.h" +#include "bridge.h" +#include "rail_map.h" +#include "table/sprites.h" +#include "table/elrail_data.h" + +static inline TLG GetTLG(TileIndex t) +{ + return (HASBIT(TileX(t), 0) << 1) + HASBIT(TileY(t), 0); +} + +/** Finds which Rail Bits are present on a given tile. For bridge tiles, + * returns track bits under the bridge + */ +static TrackBits GetRailTrackBitsUniversal(TileIndex t, byte *override) +{ + switch (GetTileType(t)) { + case MP_RAILWAY: + if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0; + switch (GetRailTileType(t)) { + case RAIL_TYPE_NORMAL: case RAIL_TYPE_SIGNALS: + return GetTrackBits(t); + default: + return 0; + } + break; + case MP_TUNNELBRIDGE: + if (IsTunnel(t)) { + if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0; + if (override != NULL) *override = 1 << GetTunnelDirection(t); + return (_m[t].m5 & 1) ? TRACK_BIT_Y : TRACK_BIT_X; + } else { + if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0; + if ( + IsBridgeMiddle(t) && + IsTransportUnderBridge(t) && + GetTransportTypeUnderBridge(t) == TRANSPORT_RAIL) { + return GetRailBitsUnderBridge(t); + } else { + if (override != NULL && DistanceMax(t, GetOtherBridgeEnd(t)) > 1) *override = 1 << GetBridgeRampDirection(t); + + return GetBridgeAxis(t) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y; + } + } + case MP_STREET: + if ((_m[t].m4 & 0xF) != RAILTYPE_ELECTRIC) return 0; + return GetCrossingRailBits(t); + case MP_STATION: + if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0; + return _m[t].m5 & 1 ? TRACK_BIT_Y : TRACK_BIT_X; + default: + return 0; + } +} + +/** Draws wires and, if required, pylons on a given tile + * @param ti The Tileinfo to draw the tile for + * @todo Currently, each pylon is drawn twice (once for each neighbouring tiles use OwnedPPPonPCP for this) + */ +static void DrawCatenaryRailway(const TileInfo *ti) +{ + /* Pylons are placed on a tile edge, so we need to take into account + the track configuration of 2 adjacent tiles. trackconfig[0] stores the + current tile (home tile) while [1] holds the neighbour */ + TrackBits trackconfig[TS_END]; + bool isflat[TS_END]; + /* Note that ti->tileh has already been adjusted for Foundations */ + uint tileh[TS_END] = {ti->tileh, 0}; + + TLG tlg = GetTLG(ti->tile); + byte PCPstatus = 0; + byte OverridePCP = 0; + byte PPPpreferred[DIAGDIR_END] = {0xFF, 0xFF, 0xFF, 0xFF}; + byte PPPallowed[DIAGDIR_END] = {AllowedPPPonPCP[0], AllowedPPPonPCP[1], AllowedPPPonPCP[2], AllowedPPPonPCP[3]}; + byte PPPbuffer[DIAGDIR_END]; + DiagDirection i; + Track t; + + /* Find which rail bits are present, and select the override points. + We don't draw a pylon: + 1) INSIDE a tunnel (we wouldn't see it anyway) + 2) on the "far" end of a bridge head (the one that connects to bridge middle), + because that one is drawn on the bridge. Exception is for length 0 bridges + which have no middle tiles */ + trackconfig[TS_HOME] = GetRailTrackBitsUniversal(ti->tile, &OverridePCP); + /* If a track bit is present that is not in the main direction, the track is level */ + isflat[TS_HOME] = trackconfig[TS_HOME] & (TRACK_BIT_UPPER | TRACK_BIT_LOWER | TRACK_BIT_LEFT | TRACK_BIT_RIGHT); + + if (IsTunnelTile(ti->tile)) tileh[TS_HOME] = 0; + if (IsBridgeTile(ti->tile) && IsBridgeRamp(ti->tile)) { + if (tileh[TS_HOME] != 0) { + tileh[TS_HOME] = 0; + } else { + switch (GetBridgeRampDirection(ti->tile)) { + case DIAGDIR_NE: tileh[TS_HOME] = 12; break; + case DIAGDIR_SE: tileh[TS_HOME] = 6; break; + case DIAGDIR_SW: tileh[TS_HOME] = 3; break; + case DIAGDIR_NW: tileh[TS_HOME] = 9; break; + default: break; + } + } + } + + for (i = DIAGDIR_NE; i < DIAGDIR_END; i++) { + extern const TileIndexDiffC _tileoffs_by_dir[]; + TileIndex neighbour = ti->tile + TileOffsByDir(i); + uint foundation = 0; + int k; + + /* Here's one of the main headaches. GetTileSlope does not correct for possibly + existing foundataions, so we do have to do that manually later on.*/ + tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL); + trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL); + isflat[TS_NEIGHBOUR] = trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_UPPER | TRACK_BIT_LOWER | TRACK_BIT_LEFT | TRACK_BIT_RIGHT); + + /* We cycle through all the existing tracks at a PCP and see what + PPPs we want to have, or may not have at all */ + for (k = 0; k < TRACKS_AT_PCP; k++) { + /* Next to us, we have a bridge head, don't worry about that one, if it shows away from us */ + if ( + trackorigin[i][k] == TS_NEIGHBOUR && + IsBridgeTile(neighbour) && IsBridgeRamp(neighbour) && + GetBridgeRampDirection(neighbour) == ReverseDiagDir(i) + ) continue; + + if (HASBIT(trackconfig[trackorigin[i][k]], PPPtracks[i][k])) { + DiagDirection PCPpos = (trackorigin[i][k] == 0) ? i : ReverseDiagDir(i); + PCPstatus |= 1 << i; /* This PCP is in use */ + PPPpreferred[i] &= PreferredPPPofTrackBitAtPCP[PPPtracks[i][k]][PCPpos]; + PPPallowed[i] &= ~DisallowedPPPofTrackBitAtPCP[PPPtracks[i][k]][PCPpos]; + } + } + + /* Deactivate all PPPs if PCP is not used */ + PPPpreferred[i] *= HASBIT(PCPstatus, i); + PPPallowed[i] *= HASBIT(PCPstatus, i); + + /* Station on a non-flat tile means foundation. add one height level and adjust tileh */ + if (IsTileType(neighbour, MP_STATION) && tileh[TS_NEIGHBOUR] != 0) tileh[TS_NEIGHBOUR] = 0; + + /* Read the foundataions if they are present, and adjust the tileh */ + if (IsTileType(neighbour, MP_RAILWAY)) foundation = GetRailFoundation(tileh[TS_NEIGHBOUR], trackconfig[TS_NEIGHBOUR]); + if (IsBridgeTile(neighbour) && IsBridgeRamp(neighbour)) foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], GetBridgeAxis(neighbour)); + if (foundation != 0) { + if (foundation < 15) { + tileh[TS_NEIGHBOUR] = 0; + } else { + tileh[TS_NEIGHBOUR] = _inclined_tileh[foundation - 15]; + } + } + + /* Convert the real tileh into a pseudo-tileh for the track */ + if (IsTunnelTile(neighbour)) tileh[TS_NEIGHBOUR] = 0; + if (IsBridgeTile(neighbour) && IsBridgeRamp(neighbour)) { + if (tileh[TS_NEIGHBOUR] != 0) { + tileh[TS_NEIGHBOUR] = 0; + } else { + switch (GetBridgeRampDirection(neighbour)) { + case DIAGDIR_NE: tileh[TS_NEIGHBOUR] = 12; break; + case DIAGDIR_SE: tileh[TS_NEIGHBOUR] = 6; break; + case DIAGDIR_SW: tileh[TS_NEIGHBOUR] = 3; break; + case DIAGDIR_NW: tileh[TS_NEIGHBOUR] = 9; break; + default: break; + } + } + } + + /* If we have a straight (and level) track, we want a pylon only every 2 tiles + Delete the PCP if this is the case. */ + /* Level means that the slope is the same, or the track is flat */ + if (tileh[TS_HOME] == tileh[TS_NEIGHBOUR] || (isflat[TS_HOME] && isflat[TS_NEIGHBOUR])) { + for (k = 0; k < NUM_IGNORE_GROUPS; k++) + if (PPPpreferred[i] == IgnoredPCP[k][tlg][i]) PCPstatus &= ~(1 << i); + } + + /* Now decide where we draw our tiles. First try the preferred PPPs, but they may not exist. + In that case, we try the any of the allowed ones. if they don't exist either, don't draw + anything */ + if (PPPpreferred[i] != 0) { + /* Some of the preferred PPPs (the ones in direct extension of the track bit) + have been used as an "end of line" marker. As these are not ALLOWED, this operation + cancles them out */ + PPPbuffer[i] = PPPpreferred[i] & PPPallowed[i]; + /* We haven't any buffer yet, so try something else. Fixes 90° curves */ + if (PPPbuffer[i] == 0) PPPbuffer[i] = PPPallowed[i]; + } else { + PPPbuffer[i] = PPPallowed[i]; + } + + if (PPPbuffer[i] != 0 && HASBIT(PCPstatus, i) && !HASBIT(OverridePCP, i)) { + for (k = 0; k < DIR_END; k++) { + byte temp = PPPorder[i][GetTLG(ti->tile)][k]; + if (HASBIT(PPPbuffer[i], temp)) { + uint x = ti->x + x_pcp_offsets[i] + x_ppp_offsets[temp]; + uint y = ti->y + y_pcp_offsets[i] + y_ppp_offsets[temp]; + + /* Don't build the pylon if it would be outside the tile */ + if (!HASBIT(OwnedPPPonPCP[i], temp)) { + /* We have a neighour that will draw it, bail out */ + if (trackconfig[TS_NEIGHBOUR] != 0) break; + continue; /* No neighbour, go looking for a better position */ + } + + AddSortableSpriteToDraw(pylons_normal[temp], x, y, 1, 1, 10, + GetSlopeZ(ti->x + x_pcp_offsets[i], ti->y + y_pcp_offsets[i])); + break; /* We already have drawn a pylon, bail out */ + } + } + } + } + + /* Drawing of pylons is finished, now draw the wires */ + for (t = 0; t < TRACK_END; t++) { + if (HASBIT(trackconfig[TS_HOME], t)) { + + byte PCPconfig = HASBIT(PCPstatus, PCPpositions[t][0]) + + (HASBIT(PCPstatus, PCPpositions[t][1]) << 1); + + const SortableSpriteStruct *sss; + int tileh_selector = !(tileh[TS_HOME] % 3) * tileh[TS_HOME] / 3; /* tileh for the slopes, 0 otherwise */ + + if ( /* We are not drawing a wire under a low bridge */ + IsBridgeTile(ti->tile) && + IsBridgeMiddle(ti->tile) && + !(_display_opt & DO_TRANS_BUILDINGS) && + GetBridgeHeight(t) <= TilePixelHeight(t) + ) return; + + assert(PCPconfig != 0); /* We have a pylon on neither end of the wire, that doesn't work (since we have no sprites for that) */ + assert(!IsSteepTileh(tileh[TS_HOME])); + sss = &CatenarySpriteData[Wires[tileh_selector][t][PCPconfig]]; + + AddSortableSpriteToDraw( sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset, + sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x + min(sss->x_offset, 15), ti->y + min(sss->y_offset, 15)) + sss->z_offset); + } + } +} + +static void DrawCatenaryOnBridge(const TileInfo *ti) +{ + TileIndex start = GetOtherBridgeEnd(GetSouthernBridgeEnd(ti->tile)); + uint length = GetBridgeLength(GetSouthernBridgeEnd(ti->tile), GetOtherBridgeEnd(GetSouthernBridgeEnd(ti->tile))); + uint num = DistanceMax(ti->tile, start); + const SortableSpriteStruct *sss; + Axis axis = GetBridgeAxis(ti->tile); + TLG tlg = GetTLG(ti->tile); + + CatenarySprite offset = axis == AXIS_X ? 0 : WIRE_Y_FLAT_BOTH - WIRE_X_FLAT_BOTH; + + if ((length % 2) && num == length) { + sss = &CatenarySpriteData[WIRE_X_FLAT_BOTH + offset]; + } else { + sss = &CatenarySpriteData[WIRE_X_FLAT_SW + (num % 2) + offset]; + } + + if (num % 2) { + if (axis == AXIS_X) { + AddSortableSpriteToDraw( pylons_bridge[0 + HASBIT(tlg, 0)], ti->x, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, GetBridgeHeight(ti->tile) + 8); + } else { + AddSortableSpriteToDraw( pylons_bridge[2 + HASBIT(tlg, 1)], ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y, 1, 1, 10, GetBridgeHeight(ti->tile) + 8); + } + } + + if (DistanceMax(ti->tile, start) == length) { /* need a pylon here (the southern end) */ + if (axis == AXIS_X) { + AddSortableSpriteToDraw( pylons_bridge[0 + HASBIT(tlg, 0)], ti->x + 16, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, GetBridgeHeight(ti->tile) + 8); + } else { + AddSortableSpriteToDraw( pylons_bridge[2 + HASBIT(tlg, 1)], ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y + 16, 1, 1, 10, GetBridgeHeight(ti->tile) + 8); + } + } + + AddSortableSpriteToDraw( sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset, + sss->x_size, sss->y_size, sss->z_size, GetBridgeHeight(ti->tile) + sss->z_offset + 8); +} + +void DrawCatenary(const TileInfo *ti) +{ + switch (GetTileType(ti->tile)) { + case MP_RAILWAY: + if (GetRailTileType(ti->tile) == RAIL_TYPE_DEPOT_WAYPOINT && GetRailTileSubtype(ti->tile) == RAIL_SUBTYPE_DEPOT) { + const SortableSpriteStruct *sss = &CatenarySpriteData[WIRE_DEPOT_SW + ReverseDiagDir(GetRailDepotDirection(ti->tile))]; + AddSortableSpriteToDraw( sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset, + sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x, ti->y) + sss->z_offset); + return; + } + /* Fall through */ + case MP_TUNNELBRIDGE: + if (IsBridgeTile(ti->tile) && IsBridgeMiddle(ti->tile) && GetRailTypeOnBridge(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenaryOnBridge(ti); + /* Fall further */ + case MP_STREET: case MP_STATION: + DrawCatenaryRailway(ti); + break; + default: + break; + } +} + diff --git a/engine_gui.c b/engine_gui.c index 61147d644e..69df50f427 100644 --- a/engine_gui.c +++ b/engine_gui.c @@ -20,9 +20,10 @@ static StringID GetEngineCategoryName(EngineID engine) { if (engine < NUM_TRAIN_ENGINES) { switch (GetEngine(engine)->railtype) { - case RAILTYPE_RAIL: return STR_8102_RAILROAD_LOCOMOTIVE; - case RAILTYPE_MONO: return STR_8106_MONORAIL_LOCOMOTIVE; - case RAILTYPE_MAGLEV: return STR_8107_MAGLEV_LOCOMOTIVE; + case RAILTYPE_RAIL: return STR_8102_RAILROAD_LOCOMOTIVE; + case RAILTYPE_ELECTRIC: return STR_8102_RAILROAD_LOCOMOTIVE; + case RAILTYPE_MONO: return STR_8106_MONORAIL_LOCOMOTIVE; + case RAILTYPE_MAGLEV: return STR_8107_MAGLEV_LOCOMOTIVE; } } diff --git a/gfxinit.c b/gfxinit.c index 78c2367a3e..0d31c71236 100644 --- a/gfxinit.c +++ b/gfxinit.c @@ -358,6 +358,9 @@ static void LoadSpriteTables(void) load_index = SPR_AUTORAIL_BASE; load_index += LoadGrfFile("autorail.grf", load_index, i++); + assert(load_index == SPR_ELRAIL_BASE); + load_index += LoadGrfFile("elrailsw.grf", load_index, i++); + assert(load_index == SPR_2CCMAP_BASE); load_index += LoadGrfFile("2ccmap.grf", load_index, i++); diff --git a/lang/english.txt b/lang/english.txt index 7b7c1bf4a0..e2dee014b3 100644 --- a/lang/english.txt +++ b/lang/english.txt @@ -1443,6 +1443,7 @@ STR_1005_NO_SUITABLE_RAILROAD_TRACK :{WHITE}No suita STR_1007_ALREADY_BUILT :{WHITE}...already built STR_1008_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Must remove railway track first STR_100A_RAILROAD_CONSTRUCTION :{WHITE}Railway Construction +STR_TITLE_ELRAIL_CONSTRUCTION :{WHITE}Electrified Railway Construction STR_100B_MONORAIL_CONSTRUCTION :{WHITE}Monorail Construction STR_100C_MAGLEV_CONSTRUCTION :{WHITE}MagLev Construction STR_100D_SELECT_RAIL_BRIDGE :{WHITE}Select Rail Bridge @@ -1454,6 +1455,7 @@ STR_1012_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Can't re STR_1013_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Can't remove signals from here... STR_1014_TRAIN_DEPOT_ORIENTATION :{WHITE}Train Depot Orientation STR_1015_RAILROAD_CONSTRUCTION :Railway construction +STR_TOOLB_ELRAIL_CONSTRUCTION :Electrified Railway construction STR_1016_MONORAIL_CONSTRUCTION :Monorail construction STR_1017_MAGLEV_CONSTRUCTION :MagLev construction STR_1018_BUILD_RAILROAD_TRACK :{BLACK}Build railway track @@ -2410,6 +2412,7 @@ STR_8819_TRAIN_TOO_LONG :{WHITE}Train to STR_881A_TRAINS_CAN_ONLY_BE_ALTERED :{WHITE}Trains can only be altered when stopped inside a depot STR_881B_TRAINS :{WHITE}{COMPANY} - {COMMA} Train{P "" s} STR_881C_NEW_RAIL_VEHICLES :{WHITE}New Rail Vehicles +STR_NEW_ELRAIL_VEHICLES :{WHITE}New Electric Rail Vehicles STR_881D_NEW_MONORAIL_VEHICLES :{WHITE}New Monorail Vehicles STR_881E_NEW_MAGLEV_VEHICLES :{WHITE}New Maglev Vehicles STR_881F_BUILD_VEHICLE :{BLACK}Build Vehicle @@ -2810,6 +2813,7 @@ STR_SIGN_LIST_CAPTION :{WHITE}Sign Lis ############ Lists rail types STR_RAIL_VEHICLES :Rail Vehicles +STR_ELRAIL_VEHICLES :Electrified Rail Vehicles STR_MONORAIL_VEHICLES :Monorail Vehicles STR_MAGLEV_VEHICLES :Maglev Vehicles diff --git a/misc.c b/misc.c index 948ef5ebf0..82df58142b 100644 --- a/misc.c +++ b/misc.c @@ -401,8 +401,6 @@ typedef struct LandscapePredefVar { byte transit_days_table_1[NUM_CARGO]; byte transit_days_table_2[NUM_CARGO]; - byte railwagon_by_cargo[3][NUM_CARGO]; - byte road_veh_by_cargo_start[NUM_CARGO]; byte road_veh_by_cargo_count[NUM_CARGO]; } LandscapePredefVar; @@ -419,7 +417,6 @@ void InitializeLandscapeVariables(bool only_constants) lpd = &_landscape_predef_var[_opt.landscape]; - memcpy(_cargoc.ai_railwagon, lpd->railwagon_by_cargo, sizeof(lpd->railwagon_by_cargo)); memcpy(_cargoc.ai_roadveh_start, lpd->road_veh_by_cargo_start,sizeof(lpd->road_veh_by_cargo_start)); memcpy(_cargoc.ai_roadveh_count, lpd->road_veh_by_cargo_count,sizeof(lpd->road_veh_by_cargo_count)); diff --git a/newgrf.c b/newgrf.c index 4507579c3d..7506852437 100644 --- a/newgrf.c +++ b/newgrf.c @@ -355,6 +355,9 @@ static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf engclass = 0; } else if (traction <= 0x27) { engclass = 1; + } else if (traction <= 0x31) { + engclass = 2; + ei[i].railtype = RAILTYPE_ELECTRIC; } else if (traction <= 0x41) { engclass = 2; } else { @@ -2309,12 +2312,8 @@ static void InitializeGRFSpecial(void) | (1 << 0x18) /* newrvs */ | (1 << 0x19) /* newships */ | (1 << 0x1A) /* newplanes */ - | (_patches.signal_side ? (1 << 0x1B) : 0); /* signalsontrafficside */ - /* Uncomment following if you want to fool the GRF file. - * Some GRF files will refuse to load without this - * but you can still squeeze something from them even - * without the support - i.e. USSet. --pasky */ - //| (1 << 0x1C); /* electrifiedrailway */ + | (_patches.signal_side ? (1 << 0x1B) : 0) /* signalsontrafficside */ + | (1 << 0x1C); /* electrifiedrailway */ _ttdpatch_flags[2] = (_patches.build_on_slopes ? (1 << 0x0D) : 0) /* buildonslopes */ | (_patches.build_on_slopes ? (1 << 0x15) : 0) /* buildoncoasts */ diff --git a/npf.c b/npf.c index 4dc59f41a7..2c7bd06caf 100644 --- a/npf.c +++ b/npf.c @@ -587,7 +587,7 @@ static void NPFFollowTrack(AyStar* aystar, OpenListNode* current) /* check correct rail type (mono, maglev, etc) */ if (type == TRANSPORT_RAIL) { RailType dst_type = GetTileRailType(dst_tile, src_trackdir); - if (!IsCompatibleRail(aystar->user_data[NPF_RAILTYPE], dst_type)) + if (!HASBIT(aystar->user_data[NPF_RAILTYPES], dst_type)) return; } @@ -661,7 +661,7 @@ static void NPFFollowTrack(AyStar* aystar, OpenListNode* current) * multiple targets that are spread around, we should perform a breadth first * search by specifiying CalcZero as our heuristic. */ -static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, Owner owner, RailType railtype, uint reverse_penalty) +static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, Owner owner, RailTypeMask railtypes, uint reverse_penalty) { int r; NPFFoundTargetData result; @@ -703,7 +703,7 @@ static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start /* Initialize user_data */ _npf_aystar.user_data[NPF_TYPE] = type; _npf_aystar.user_data[NPF_OWNER] = owner; - _npf_aystar.user_data[NPF_RAILTYPE] = railtype; + _npf_aystar.user_data[NPF_RAILTYPES] = railtypes; /* GO! */ r = AyStarMain_Main(&_npf_aystar); @@ -721,7 +721,7 @@ static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start return result; } -NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype) +NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes) { AyStarNode start1; AyStarNode start2; @@ -735,15 +735,15 @@ NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir track start2.direction = trackdir2; start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR; - return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner, railtype, 0); + return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner, railtypes, 0); } -NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype) +NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes) { - return NPFRouteToStationOrTileTwoWay(tile, trackdir, INVALID_TILE, 0, target, type, owner, railtype); + return NPFRouteToStationOrTileTwoWay(tile, trackdir, INVALID_TILE, 0, target, type, owner, railtypes); } -NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailType railtype, uint reverse_penalty) +NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailTypeMask railtypes, uint reverse_penalty) { AyStarNode start1; AyStarNode start2; @@ -759,15 +759,15 @@ NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir t /* perform a breadth first search. Target is NULL, * since we are just looking for any depot...*/ - return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), NULL, NPFFindDepot, NPFCalcZero, type, owner, railtype, reverse_penalty); + return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), NULL, NPFFindDepot, NPFCalcZero, type, owner, railtypes, reverse_penalty); } -NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype) +NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes) { - return NPFRouteToDepotBreadthFirstTwoWay(tile, trackdir, INVALID_TILE, 0, type, owner, railtype, 0); + return NPFRouteToDepotBreadthFirstTwoWay(tile, trackdir, INVALID_TILE, 0, type, owner, railtypes, 0); } -NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype) +NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes) { /* Okay, what we're gonna do. First, we look at all depots, calculate * the manhatten distance to get to each depot. We then sort them by diff --git a/npf.h b/npf.h index 26b268521e..c550edaebf 100644 --- a/npf.h +++ b/npf.h @@ -38,7 +38,7 @@ typedef struct NPFFindStationOrTileData { /* Meant to be stored in AyStar.target enum { /* Indices into AyStar.userdata[] */ NPF_TYPE = 0, /* Contains a TransportTypes value */ NPF_OWNER, /* Contains an Owner value */ - NPF_RAILTYPE, /* Contains the RailType value of the engine when NPF_TYPE == TRANSPORT_RAIL. Unused otherwise. */ + NPF_RAILTYPES, /* Contains a bitmask the compatible RailTypes of the engine when NPF_TYPE == TRANSPORT_RAIL. Unused otherwise. */ }; enum { /* Indices into AyStarNode.userdata[] */ @@ -64,28 +64,28 @@ typedef struct NPFFoundTargetData { /* Meant to be stored in AyStar.userpath */ /* Will search from the given tile and direction, for a route to the given * station for the given transport type. See the declaration of * NPFFoundTargetData above for the meaning of the result. */ -NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype); +NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes); /* Will search as above, but with two start nodes, the second being the * reverse. Look at the NPF_FLAG_REVERSE flag in the result node to see which * direction was taken (NPFGetBit(result.node, NPF_FLAG_REVERSE)) */ -NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype); +NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes); /* Will search a route to the closest depot. */ /* Search using breadth first. Good for little track choice and inaccurate * heuristic, such as railway/road.*/ -NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype); +NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes); /* Same as above but with two start nodes, the second being the reverse. Call * NPFGetBit(result.node, NPF_FLAG_REVERSE) to see from which node the path * orginated. All pathfs from the second node will have the given * reverse_penalty applied (NPF_TILE_LENGTH is the equivalent of one full * tile). */ -NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailType railtype, uint reverse_penalty); +NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailTypeMask railtypes, uint reverse_penalty); /* Search by trying each depot in order of Manhattan Distance. Good for lots * of choices and accurate heuristics, such as water. */ -NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype); +NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes); void NPFFillWithOrderData(NPFFindStationOrTileData* fstd, Vehicle* v); diff --git a/openttd.c b/openttd.c index 15b20e1405..04143a0a9a 100644 --- a/openttd.c +++ b/openttd.c @@ -1238,6 +1238,75 @@ bool AfterLoadGame(void) } } + /* Elrails got added in rev 24 */ + if (CheckSavegameVersion(24)) { + Vehicle* v; + uint i; + TileIndex t; + bool make_elrail = false; + + for (i = 0; i < lengthof(_engines); i++) { + Engine* e = GetEngine(i); + if (e->type == VEH_Train && + (e->railtype != RAILTYPE_RAIL || RailVehInfo(i)->engclass == 2)) { + e->railtype++; + } + } + + FOR_ALL_VEHICLES(v) { + if (v->type == VEH_Train) { + RailType rt = GetEngine(v->engine_type)->railtype; + + v->u.rail.railtype = rt; + if (rt == RAILTYPE_ELECTRIC) make_elrail = true; + } + } + + /* .. so we convert the entire map from normal to elrail (so maintain "fairness") */ + for (t = 0; t < MapSize(); t++) { + switch (GetTileType(t)) { + case MP_RAILWAY: + if (GetRailType(t) > RAILTYPE_RAIL || make_elrail) AB(_m[t].m3, 0, 4, 1); + break; + + case MP_STREET: + if (IsLevelCrossing(t) && (GetRailTypeCrossing(t) > RAILTYPE_RAIL || make_elrail)) AB(_m[t].m4, 0, 4, 1); + break; + + case MP_STATION: + if (_m[t].m5 < 8 && (GB(_m[t].m3, 0, 4) > RAILTYPE_RAIL || make_elrail)) AB(_m[t].m3, 0, 4, 1); + break; + + case MP_TUNNELBRIDGE: + if (GB(_m[t].m5, 4, 4) == 0) { // tunnel? + if (GB(_m[t].m5, 2, 2) == 0) { // railway tunnel? + if (GB(_m[t].m3, 0, 4) > RAILTYPE_RAIL || make_elrail) AB(_m[t].m3, 0, 4, 1); + } + } else { + if (GB(_m[t].m5, 1, 2) == 0) { // railway bridge? + if (GB(_m[t].m5, 6, 1) == 0) { // bridge ending? + if (GB(_m[t].m3, 0, 4) > RAILTYPE_RAIL || make_elrail) AB(_m[t].m3, 0, 4, 1); + } else { + if (GB(_m[t].m3, 4, 4) > RAILTYPE_RAIL || make_elrail) AB(_m[t].m3, 4, 4, 1); + } + } + if ((_m[t].m5 & 0xF8) == 0xE0) { // bridge middle part with rails below? + if (GB(_m[t].m3, 0, 4) > RAILTYPE_RAIL || make_elrail) AB(_m[t].m3, 0, 4, 1); + } + } + break; + + default: + break; + } + } + + FOR_ALL_VEHICLES(v) { + if (v->type == VEH_Train && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v); + } + + } + /* In version 16.1 of the savegame a player can decide if trains, which get * replaced, shall keep their old length. In all prior versions, just default * to false */ diff --git a/openttd.dsp b/openttd.dsp index b8e28ed7f3..f4e2cea228 100644 --- a/openttd.dsp +++ b/openttd.dsp @@ -209,6 +209,10 @@ SOURCE=.\economy.c # End Source File # Begin Source File +SOURCE=.\elrail.c +# End Source File +# Begin Source File + SOURCE=.\engine.c # End Source File # Begin Source File diff --git a/openttd.vcproj b/openttd.vcproj index 1fa63899de..3afcd36d9e 100644 --- a/openttd.vcproj +++ b/openttd.vcproj @@ -214,6 +214,9 @@ + + diff --git a/pathfind.c b/pathfind.c index b70e51887f..b6c268938e 100644 --- a/pathfind.c +++ b/pathfind.c @@ -454,7 +454,8 @@ typedef struct { void *userdata; TileIndex dest; - byte tracktype; + TransportType tracktype; + RailTypeMask railtypes; uint maxlength; HashLink *new_link; @@ -791,6 +792,11 @@ start_at: * bits, not just reachable ones, to prevent infinite loops. */ if (bits == 0 || TracksOverlap(allbits)) break; + if (!HASBIT(tpf->railtypes, GetRailType(tile))) { + bits = 0; + break; + } + /* If we reach here, the tile has exactly one track, and this track is reachable => Rail segment continues */ @@ -926,14 +932,15 @@ start_at: // new pathfinder for trains. better and faster. -void NewTrainPathfind(TileIndex tile, TileIndex dest, DiagDirection direction, NTPEnumProc* enum_proc, void* data) +void NewTrainPathfind(TileIndex tile, TileIndex dest, RailTypeMask railtypes, DiagDirection direction, NTPEnumProc* enum_proc, void* data) { NewTrackPathFinder tpf; tpf.dest = dest; tpf.userdata = data; tpf.enum_proc = enum_proc; - tpf.tracktype = 0; + tpf.tracktype = TRANSPORT_RAIL; + tpf.railtypes = railtypes; tpf.maxlength = min(_patches.pf_maxlength * 3, 10000); tpf.nstack = 0; tpf.new_link = tpf.links; diff --git a/pathfind.h b/pathfind.h index 748ec5ab99..8796774dd2 100644 --- a/pathfind.h +++ b/pathfind.h @@ -68,6 +68,6 @@ typedef struct { } FindLengthOfTunnelResult; FindLengthOfTunnelResult FindLengthOfTunnel(TileIndex tile, DiagDirection direction); -void NewTrainPathfind(TileIndex tile, TileIndex dest, DiagDirection direction, NTPEnumProc* enum_proc, void* data); +void NewTrainPathfind(TileIndex tile, TileIndex dest, RailTypeMask railtypes, DiagDirection direction, NTPEnumProc* enum_proc, void* data); #endif /* PATHFIND_H */ diff --git a/player.h b/player.h index 3195e1c7ff..ebc42646dd 100644 --- a/player.h +++ b/player.h @@ -248,6 +248,7 @@ static inline RailType GetBestRailtype(const Player* p) { if (HasRailtypeAvail(p, RAILTYPE_MAGLEV)) return RAILTYPE_MAGLEV; if (HasRailtypeAvail(p, RAILTYPE_MONO)) return RAILTYPE_MONO; + if (HasRailtypeAvail(p, RAILTYPE_ELECTRIC)) return RAILTYPE_ELECTRIC; return RAILTYPE_RAIL; } diff --git a/rail.h b/rail.h index 83ed575b7f..e7c5f34137 100644 --- a/rail.h +++ b/rail.h @@ -9,7 +9,6 @@ #include "rail_map.h" #include "tile.h" - /** These are a combination of tracks and directions. Values are 0-5 in one direction (corresponding to the Track enum) and 8-13 in the other direction. */ typedef enum Trackdirs { @@ -110,8 +109,11 @@ typedef struct RailtypeInfo { /** sprite number difference between a piece of track on a snowy ground and the corresponding one on normal ground */ SpriteID snow_offset; - /** bitmask to the OTHER railtypes that can be used by an engine of THIS railtype */ - byte compatible_railtypes; + /** bitmask to the OTHER railtypes on which an engine of THIS railtype generates power */ + RailTypeMask powered_railtypes; + + /** bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel */ + RailTypeMask compatible_railtypes; /** * Offset between the current railtype and normal rail. This means that:

      @@ -478,6 +480,11 @@ static inline bool IsCompatibleRail(RailType enginetype, RailType tiletype) return HASBIT(GetRailTypeInfo(enginetype)->compatible_railtypes, tiletype); } +static inline bool HasPowerOnRail(RailType enginetype, RailType tiletype) +{ + return HASBIT(GetRailTypeInfo(enginetype)->powered_railtypes, tiletype); +} + /** * Checks if the given tracks overlap, ie form a crossing. Basically this * means when there is more than one track on the tile, exept when there are @@ -497,4 +504,13 @@ static inline bool TracksOverlap(TrackBits bits) void DrawTrainDepotSprite(int x, int y, int image, RailType railtype); void DrawDefaultWaypointSprite(int x, int y, RailType railtype); + +/** + * Draws overhead wires and pylons for electric railways. + * @param ti The TileInfo struct of the tile being drawn + * @see DrawCatenaryRailway + */ +void DrawCatenary(const TileInfo *ti); + +uint GetRailFoundation(uint tileh, uint bits); #endif /* RAIL_H */ diff --git a/rail_cmd.c b/rail_cmd.c index 039acf9bd5..75e0263f17 100644 --- a/rail_cmd.c +++ b/rail_cmd.c @@ -896,11 +896,13 @@ int32 CmdRemoveSignalTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2) return CmdSignalTrackHelper(x, y, flags, p1, SETBIT(p2, 0)); } -typedef int32 DoConvertRailProc(TileIndex tile, uint totype, bool exec); +typedef int32 DoConvertRailProc(TileIndex tile, RailType totype, bool exec); -static int32 DoConvertRail(TileIndex tile, uint totype, bool exec) +static int32 DoConvertRail(TileIndex tile, RailType totype, bool exec) { - if (!CheckTileOwnership(tile) || !EnsureNoVehicle(tile)) return CMD_ERROR; + if (!CheckTileOwnership(tile)) return CMD_ERROR; + + if (!EnsureNoVehicle(tile) && (!IsCompatibleRail(GetRailType(tile), totype) || IsPlainRailTile(tile))) return CMD_ERROR; // tile is already of requested type? if (GetRailType(tile) == totype) return CMD_ERROR; @@ -1297,6 +1299,9 @@ static void DrawTrackBits(TileInfo* ti, TrackBits track, bool earth, bool snow, if (track & TRACK_BIT_LEFT) DrawGroundSprite(rti->base_sprites.single_w); if (track & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e); } + + if (GB(_m[ti->tile].m3, 0, 4) == RAILTYPE_ELECTRIC) DrawCatenary(ti); + } static void DrawTile_Track(TileInfo *ti) @@ -1388,6 +1393,8 @@ static void DrawTile_Track(TileInfo *ti) DrawGroundSprite(image); + if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); + foreach_draw_tile_seq(seq, cust->seq) { DrawSpecialBuilding( seq->image + relocation, 0, ti, @@ -1420,6 +1427,8 @@ static void DrawTile_Track(TileInfo *ti) DrawGroundSprite(image); + if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); + for (; drss->image != 0; drss++) { DrawSpecialBuilding( drss->image, type < 4 ? rti->total_offset : 0, ti, diff --git a/rail_map.h b/rail_map.h index 5a3828282f..a74982cf11 100644 --- a/rail_map.h +++ b/rail_map.h @@ -32,13 +32,16 @@ typedef enum RailTileSubtypes { typedef enum RailTypes { - RAILTYPE_RAIL = 0, - RAILTYPE_MONO = 1, - RAILTYPE_MAGLEV = 2, + RAILTYPE_RAIL = 0, + RAILTYPE_ELECTRIC = 1, + RAILTYPE_MONO = 2, + RAILTYPE_MAGLEV = 3, RAILTYPE_END, INVALID_RAILTYPE = 0xFF } RailType; +typedef byte RailTypeMask; + static inline RailType GetRailType(TileIndex t) { return (RailType)GB(_m[t].m3, 0, 4); diff --git a/railtypes.h b/railtypes.h index 12180c352a..1b9b665c49 100644 --- a/railtypes.h +++ b/railtypes.h @@ -40,8 +40,11 @@ const RailtypeInfo _railtypes[] = { /* Offset of snow tiles */ SPR_RAIL_SNOW_OFFSET, + /* Powered railtypes */ + 1 << RAILTYPE_RAIL | 1 << RAILTYPE_ELECTRIC, + /* Compatible railtypes */ - (1 << RAILTYPE_RAIL), + 1 << RAILTYPE_RAIL | 1 << RAILTYPE_ELECTRIC, /* main offset */ 0, @@ -50,6 +53,56 @@ const RailtypeInfo _railtypes[] = { 0, }, + /** Electrified railway */ + { /* Main Sprites */ + { SPR_RAIL_TRACK_Y, SPR_RAIL_TRACK_N_S, SPR_RAIL_TRACK_BASE, SPR_RAIL_SINGLE_Y, SPR_RAIL_SINGLE_X, + SPR_RAIL_SINGLE_NORTH, SPR_RAIL_SINGLE_SOUTH, SPR_RAIL_SINGLE_EAST, SPR_RAIL_SINGLE_WEST, + SPR_CROSSING_OFF_X_RAIL, + SPR_TUNNEL_ENTRY_REAR_RAIL + }, + + /* GUI sprites */ + { + SPR_BUILD_NS_ELRAIL, + SPR_BUILD_X_ELRAIL, + SPR_BUILD_EW_ELRAIL, + SPR_BUILD_Y_ELRAIL, + SPR_OPENTTD_BASE + 0, + 0x50E, + SPR_BUILD_TUNNEL_ELRAIL, + SPR_IMG_CONVERT_RAIL + }, + + { + SPR_CURSOR_NS_ELRAIL, + SPR_CURSOR_SWNE_ELRAIL, + SPR_CURSOR_EW_ELRAIL, + SPR_CURSOR_NWSE_ELRAIL, + SPR_CURSOR_AUTORAIL, + SPR_CURSOR_RAIL_DEPOT, + SPR_CURSOR_TUNNEL_ELRAIL, + SPR_CURSOR_CONVERT_RAIL + }, + + /* strings */ + { STR_TITLE_ELRAIL_CONSTRUCTION }, + + /* Offset of snow tiles */ + SPR_RAIL_SNOW_OFFSET, + + /* Powered railtypes */ + 1 << RAILTYPE_ELECTRIC, + + /* Compatible railtypes */ + 1 << RAILTYPE_ELECTRIC | 1 << RAILTYPE_RAIL, + + /* main offset */ + 0, + + /* bridge offset */ + 0 + }, + /** Monorail */ { /* Main Sprites */ { SPR_MONO_TRACK_Y, SPR_MONO_TRACK_N_S, SPR_MONO_TRACK_BASE, SPR_MONO_SINGLE_Y, SPR_MONO_SINGLE_X, @@ -83,8 +136,11 @@ const RailtypeInfo _railtypes[] = { /* Offset of snow tiles */ SPR_MONO_SNOW_OFFSET, + /* Powered railtypes */ + 1 << RAILTYPE_MONO, + /* Compatible Railtypes */ - (1 << RAILTYPE_MONO), + 1 << RAILTYPE_MONO, /* main offset */ 82, @@ -126,8 +182,11 @@ const RailtypeInfo _railtypes[] = { /* Offset of snow tiles */ SPR_MGLV_SNOW_OFFSET, + /* Powered railtypes */ + 1 << RAILTYPE_MAGLEV, + /* Compatible Railtypes */ - (1 << RAILTYPE_MAGLEV), + 1 << RAILTYPE_MAGLEV, /* main offset */ 164, diff --git a/road_cmd.c b/road_cmd.c index 854c59cff9..20505c9591 100644 --- a/road_cmd.c +++ b/road_cmd.c @@ -787,6 +787,7 @@ static void DrawTile_Road(TileInfo *ti) } DrawGroundSprite(image); + if (GB(_m[ti->tile].m4, 0, 4) == RAILTYPE_ELECTRIC) DrawCatenary(ti); break; } diff --git a/saveload.c b/saveload.c index 3b304f445e..75f75c6d06 100644 --- a/saveload.c +++ b/saveload.c @@ -30,7 +30,7 @@ #include "variables.h" #include -const uint16 SAVEGAME_VERSION = 23; +const uint16 SAVEGAME_VERSION = 24; uint16 _sl_version; /// the major savegame version identifier byte _sl_minor_version; /// the minor savegame version, DO NOT USE! diff --git a/station_cmd.c b/station_cmd.c index 986e732411..1cbad1c0d1 100644 --- a/station_cmd.c +++ b/station_cmd.c @@ -1959,6 +1959,8 @@ static void DrawTile_Station(TileInfo *ti) // but this is something else. If AI builds station with 114 it looks all weird DrawGroundSprite(image); + if (GB(_m[ti->tile].m3, 0, 4) == RAILTYPE_ELECTRIC) DrawCatenary(ti); + foreach_draw_tile_seq(dtss, t->seq) { image = dtss->image + relocation; image += offset; diff --git a/table/elrail_data.h b/table/elrail_data.h new file mode 100644 index 0000000000..32a2834838 --- /dev/null +++ b/table/elrail_data.h @@ -0,0 +1,362 @@ +/* $Id */ +/** @file elrail_data.h Stores all the data for overhead wire and pylon drawing. @see elrail.c */ + +#ifndef ELRAIL_DATA_H +#define ELRAIL_DATA_H + +/** Tile Location group. This defines whether the X and or Y coordinate of a tile is even */ +typedef enum TLG { + XEVEN_YEVEN = 0, + XEVEN_YODD = 1, + XODD_YEVEN = 2, + XODD_YODD = 3, + TLG_END +} TLG; + +/** When determining the pylon configuration on the edge, two tiles are taken into account: + * the tile being drawn itself (the home tile, the one in ti->tile), and the neighbouring tile + */ +typedef enum { + TS_HOME = 0, + TS_NEIGHBOUR = 1, + + TS_END +} TileSource; + +enum { + TRACKS_AT_PCP = 6 +}; + +/** Which PPPs are possible at all on a given PCP */ +static byte AllowedPPPonPCP[DIAGDIR_END] = { + 1 << DIR_N | 1 << DIR_E | 1 << DIR_SE | 1 << DIR_S | 1 << DIR_W | 1 << DIR_NW, + 1 << DIR_N | 1 << DIR_NE | 1 << DIR_E | 1 << DIR_S | 1 << DIR_SW | 1 << DIR_W, + 1 << DIR_N | 1 << DIR_E | 1 << DIR_SE | 1 << DIR_S | 1 << DIR_W | 1 << DIR_NW, + 1 << DIR_N | 1 << DIR_NE | 1 << DIR_E | 1 << DIR_S | 1 << DIR_SW | 1 << DIR_W, +}; + +/** Which of the PPPs are inside the tile. For the two PPPs on the tile border the following system is used: + if you rotate the PCP so that it is in the north, the eastern PPP belongs to the tile. */ +static byte OwnedPPPonPCP[DIAGDIR_END] = { + 1 << DIR_SE | 1 << DIR_S | 1 << DIR_SW | 1 << DIR_W, + 1 << DIR_N | 1 << DIR_SW | 1 << DIR_W | 1 << DIR_NW, + 1 << DIR_N | 1 << DIR_NE | 1 << DIR_E | 1 << DIR_NW, + 1 << DIR_NE | 1 << DIR_E | 1 << DIR_SE | 1 << DIR_S +}; + +/** Preferred points of each trackbit. Those are the ones perpendicular to the track, plus the point in + extension of the track (to mark end-of-track).*/ +static byte PreferredPPPofTrackBitAtPCP[TRACK_END][DIAGDIR_END] = { + {1 << DIR_NE | 1 << DIR_SE | 1 << DIR_NW, 0xFF, 1 << DIR_SE | 1 << DIR_SW | 1 << DIR_NW, 0xFF }, /* X */ + {0xFF, 1 << DIR_NE | 1 << DIR_SE | 1 << DIR_SW, 0xFF, 1 << DIR_SW | 1 << DIR_NW | 1 << DIR_NE }, /* Y */ + {1 << DIR_E | 1 << DIR_N | 1 << DIR_S, 0xFF, 0xFF, 1 << DIR_W | 1 << DIR_N | 1 << DIR_S}, /* UPPER */ + {0xFF, 1 << DIR_E | 1 << DIR_N | 1 << DIR_S, 1 << DIR_W | 1 << DIR_N | 1 << DIR_S, 0xFF}, /* LOWER */ + {0xFF, 0xFF, 1 << DIR_S | 1 << DIR_E | 1 << DIR_W, 1 << DIR_N | 1 << DIR_E | 1 << DIR_W}, /* LEFT */ + {1 << DIR_N | 1 << DIR_E | 1 << DIR_W, 1 << DIR_S | 1 << DIR_E | 1 << DIR_W, 0xFF, 0xFF}, /* RIGHT */ +}; + +#define NUM_IGNORE_GROUPS 3 +/** In case we have a staight line, we place pylon only every two tiles, so there are certain tiles + which we ignore. A straight line is found if we have exactly two preferred points.*/ +static byte IgnoredPCP[NUM_IGNORE_GROUPS][TLG_END][DIAGDIR_END] = { + { + {1 << DIR_N | 1 << DIR_S , 1 << DIR_NE | 1 << DIR_SW, 1 << DIR_NW | 1 << DIR_SE, 1 << DIR_W | 1 << DIR_E}, + {0xFF , 1 << DIR_E | 1 << DIR_W, 1 << DIR_NW | 1 << DIR_SE, 1 << DIR_NE | 1 << DIR_SW}, + {1 << DIR_NW | 1 << DIR_SE, 1 << DIR_NE | 1 << DIR_SW, 1 << DIR_N | 1 << DIR_S , 0xFF}, + {1 << DIR_NW | 1 << DIR_SE, 0xFF , 0xFF, 1 << DIR_NE | 1 << DIR_SW} + }, + { + {1 << DIR_E | 1 << DIR_W, 1 << DIR_N | 1 << DIR_S, 0xFF, 1 << DIR_E | 1 << DIR_W}, + {0xFF, 0xFF, 1 << DIR_N | 1 << DIR_S, 1 << DIR_N | 1 << DIR_S}, + {0xFF, 1 << DIR_E | 1 << DIR_W, 1 << DIR_E | 1 << DIR_W, 1 << DIR_N | 1 << DIR_S}, + {1 << DIR_N | 1 << DIR_S, 1 << DIR_N | 1 << DIR_S, 0xFF, 1 << DIR_E | 1 << DIR_W} + }, + { + {0xFF, 0xFF, 0xFF, 0xFF}, + {0xFF, 0xFF, 1 << DIR_E | 1 << DIR_W, 0xFF}, + {0xFF, 0xFF, 0xFF, 0xFF}, + {1 << DIR_E | 1 << DIR_W, 0xFF, 0xFF, 0xFF} + } +}; + +/** Which pylons can definately NOT be built */ +static byte DisallowedPPPofTrackBitAtPCP[TRACK_END][DIAGDIR_END] = { + {1 << DIR_SW | 1 << DIR_NE, 0, 1 << DIR_SW | 1 << DIR_NE, 0 }, /* X */ + {0, 1 << DIR_NW | 1 << DIR_SE, 0, 1 << DIR_NW | 1 << DIR_SE}, /* Y */ + {1 << DIR_W | 1 << DIR_E, 0, 0, 1 << DIR_W | 1 << DIR_E }, /* UPPER */ + {0, 1 << DIR_W | 1 << DIR_E, 1 << DIR_W | 1 << DIR_E, 0 }, /* LOWER */ + {0, 0, 1 << DIR_S | 1 << DIR_N, 1 << DIR_N | 1 << DIR_S }, /* LEFT */ + {1 << DIR_S | 1 << DIR_N, 1 << DIR_S | 1 << DIR_N, 0, 0, }, /* RIGHT */ +}; + +typedef struct { + SpriteID image; + int8 x_offset; + int8 y_offset; + int8 x_size; + int8 y_size; + int8 z_size; + int8 z_offset; +} SortableSpriteStruct; + +enum { + /** Distance between wire and rail */ + ELRAIL_ELEVATION = 8, + /** Corrects an off-by-one error in some places (tileh 12 and 9) (TODO -- find source of error) */ + ELRAIL_ELEV_CORR = ELRAIL_ELEVATION + 1, + /** Wires that a draw one level higher than the north corner. */ + ELRAIL_ELEVRAISE = ELRAIL_ELEVATION + TILE_HEIGHT +}; + +static const SortableSpriteStruct CatenarySpriteData[] = { +/* X direction */ + /* Flat tiles: */ + /* Wires */ + { SPR_WIRE_X_SW, 0, 8, 16, 1, 1, ELRAIL_ELEVATION }, //! 0: Wire in X direction, pylon on the SW end only + { SPR_WIRE_X_NE, 0, 8, 16, 1, 1, ELRAIL_ELEVATION }, //! 1: Wire in X direction, pylon on the NE end + { SPR_WIRE_X_SHORT, 0, 8, 16, 1, 1, ELRAIL_ELEVATION }, //! 2: Wire in X direction, pylon on both ends + + /* "up" tiles */ + /* Wires */ + { SPR_WIRE_X_SW_UP, 0, 8, 16, 8, 1, ELRAIL_ELEVRAISE }, //! 3: Wire in X pitch up, pylon on the SW end only + { SPR_WIRE_X_NE_UP, 0, 8, 16, 8, 1, ELRAIL_ELEVRAISE }, //! 4: Wire in X pitch up, pylon on the NE end + { SPR_WIRE_X_SHORT_UP, 0, 8, 16, 8, 1, ELRAIL_ELEVRAISE }, //! 5: Wire in X pitch up, pylon on both ends + + /* "down" tiles */ + /* Wires */ + { SPR_WIRE_X_SW_DOWN, 0, 8, 16, 8, 1, ELRAIL_ELEV_CORR }, //! 6: Wire in X pitch down, pylon on the SW end + { SPR_WIRE_X_NE_DOWN, 0, 8, 16, 8, 1, ELRAIL_ELEV_CORR }, //! 7: Wire in X pitch down, pylon on the NE end + { SPR_WIRE_X_SHORT_DOWN, 0, 8, 16, 8, 1, ELRAIL_ELEV_CORR }, //! 8: Wire in X pitch down, pylon on both ends + + +/* Y direction */ + /* Flat tiles: */ + /* Wires */ + { SPR_WIRE_Y_SE, 8, 0, 1, 16, 1, ELRAIL_ELEVATION }, //! 9: Wire in Y direction, pylon on the SE end only + { SPR_WIRE_Y_NW, 8, 0, 1, 16, 1, ELRAIL_ELEVATION }, //!10: Wire in Y direction, pylon on the NW end + { SPR_WIRE_Y_SHORT, 8, 0, 1, 16, 1, ELRAIL_ELEVATION }, //!11: Wire in Y direction, pylon on both ends + + /* "up" tiles */ + /* Wires */ + { SPR_WIRE_Y_SE_UP, 8, 0, 8, 16, 1, ELRAIL_ELEVRAISE }, //!12: Wire in Y pitch up, pylon on the SE end only + { SPR_WIRE_Y_NW_UP, 8, 0, 8, 16, 1, ELRAIL_ELEVRAISE }, //!13: Wire in Y pitch up, pylon on the NW end + { SPR_WIRE_Y_SHORT_UP, 8, 0, 8, 16, 1, ELRAIL_ELEVRAISE }, //!14: Wire in Y pitch up, pylon on both ends + + /* "down" tiles */ + /* Wires */ + { SPR_WIRE_Y_SE_DOWN, 8, 0, 8, 16, 1, ELRAIL_ELEV_CORR }, //!15: Wire in Y pitch down, pylon on the SE end + { SPR_WIRE_Y_NW_DOWN, 8, 0, 8, 16, 1, ELRAIL_ELEV_CORR }, //!16: Wire in Y pitch down, pylon on the NW end + { SPR_WIRE_Y_SHORT_DOWN, 8, 0, 8, 16, 1, ELRAIL_ELEV_CORR }, //!17: Wire in Y pitch down, pylon on both ends + +/* NS Direction */ + { SPR_WIRE_NS_SHORT, 8, 0, 8, 8, 1, ELRAIL_ELEVATION }, //!18: LEFT trackbit wire, pylon on both ends + { SPR_WIRE_NS_SHORT, 0, 8, 8, 8, 1, ELRAIL_ELEVATION }, //!19: RIGHT trackbit wire, pylon on both ends + + { SPR_WIRE_NS_N, 8, 0, 8, 8, 1, ELRAIL_ELEVATION }, //!20: LEFT trackbit wire, pylon on N end + { SPR_WIRE_NS_N, 0, 8, 8, 8, 1, ELRAIL_ELEVATION }, //!21: RIGHT trackbit wire, pylon on N end + + { SPR_WIRE_NS_S, 8, 0, 8, 8, 1, ELRAIL_ELEVATION }, //!22: LEFT trackbit wire, pylon on S end + { SPR_WIRE_NS_S, 0, 8, 8, 8, 1, ELRAIL_ELEVATION }, //!23: RIGHT trackbit wire, pylon on S end + +/* EW Direction */ + { SPR_WIRE_EW_SHORT, 8, 0, 8, 8, 1, ELRAIL_ELEVATION }, //!24: UPPER trackbit wire, pylon on both ends + { SPR_WIRE_EW_SHORT, 16, 8, 8, 8, 1, ELRAIL_ELEVATION }, //!25: LOWER trackbit wire, pylon on both ends + + { SPR_WIRE_EW_W, 8, 0, 8, 8, 1, ELRAIL_ELEVATION }, //!28: UPPER trackbit wire, pylon on both ends + { SPR_WIRE_EW_W, 16, 8, 8, 8, 1, ELRAIL_ELEVATION }, //!29: LOWER trackbit wire, pylon on both ends + + { SPR_WIRE_EW_E, 8, 0, 8, 8, 1, ELRAIL_ELEVATION }, //!32: UPPER trackbit wire, pylon on both ends + { SPR_WIRE_EW_E, 16, 8, 8, 8, 1, ELRAIL_ELEVATION }, //!33: LOWER trackbit wire, pylon on both ends + +/* Depots */ + { SPR_WIRE_DEPOT_SW, 0, 8, 8, 1, 1, ELRAIL_ELEVATION }, //!36: Wire for SW depot exit + { SPR_WIRE_DEPOT_NW, 8, 0, 1, 8, 1, ELRAIL_ELEVATION }, //!37: Wire for NW depot exit + { SPR_WIRE_DEPOT_NE, 0, 8, 8, 1, 1, ELRAIL_ELEVATION }, //!38: Wire for NE depot exit + { SPR_WIRE_DEPOT_SE, 8, 0, 1, 8, 1, ELRAIL_ELEVATION }, //!39: Wire for SE depot exit +}; + +/** Refers to a certain element of the catenary. + * Identifiers for Wires: + *

      1. Direction of the wire
      2. + *
      3. Slope of the tile for diagonals, placement inside the track for horiz/vertical pieces
      4. + *
      5. Place where a pylon shoule be
      + * Identifiers for Pylons: + *
      1. Direction of the wire
      2. + *
      3. Slope of the tile
      4. + *
      5. Position of the Pylon relative to the track
      6. + *
      7. Position of the Pylon inside the tile
      + */ +typedef enum { + WIRE_X_FLAT_SW, + WIRE_X_FLAT_NE, + WIRE_X_FLAT_BOTH, + + WIRE_X_UP_SW, + WIRE_X_UP_NE, + WIRE_X_UP_BOTH, + + WIRE_X_DOWN_SW, + WIRE_X_DOWN_NE, + WIRE_X_DOWN_BOTH, + + WIRE_Y_FLAT_SE, + WIRE_Y_FLAT_NW, + WIRE_Y_FLAT_BOTH, + + WIRE_Y_UP_SE, + WIRE_Y_UP_NW, + WIRE_Y_UP_BOTH, + + WIRE_Y_DOWN_SE, + WIRE_Y_DOWN_NW, + WIRE_Y_DOWN_BOTH, + + WIRE_NS_W_BOTH, + WIRE_NS_E_BOTH, + + WIRE_NS_W_N, + WIRE_NS_E_N, + + WIRE_NS_W_S, + WIRE_NS_E_S, + + WIRE_EW_N_BOTH, + WIRE_EW_S_BOTH, + + WIRE_EW_N_W, + WIRE_EW_S_W, + + WIRE_EW_N_E, + WIRE_EW_S_E, + + WIRE_DEPOT_SW, + WIRE_DEPOT_NW, + WIRE_DEPOT_NE, + WIRE_DEPOT_SE, + + INVALID_CATENARY = 0xFF +} CatenarySprite; + +/* This array stores which track bits can meet at a tile edge */ +static const Track PPPtracks[DIAGDIR_END][TRACKS_AT_PCP] = { + {TRACK_X, TRACK_X, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT}, + {TRACK_Y, TRACK_Y, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT}, + {TRACK_X, TRACK_X, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT}, + {TRACK_Y, TRACK_Y, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT}, +}; + +/* takes each of the 8 track bits from the array above and + assigns it to the home tile or neighbour tile */ +static const TileSource trackorigin[DIAGDIR_END][TRACKS_AT_PCP] = { + {TS_HOME, TS_NEIGHBOUR, TS_HOME , TS_NEIGHBOUR, TS_NEIGHBOUR, TS_HOME }, + {TS_HOME, TS_NEIGHBOUR, TS_NEIGHBOUR, TS_HOME , TS_NEIGHBOUR, TS_HOME }, + {TS_HOME, TS_NEIGHBOUR, TS_NEIGHBOUR, TS_HOME , TS_HOME , TS_NEIGHBOUR}, + {TS_HOME, TS_NEIGHBOUR, TS_HOME , TS_NEIGHBOUR, TS_HOME , TS_NEIGHBOUR}, +}; + +/* Several PPPs maybe exist, here they are sorted in order of preference. */ +static const Direction PPPorder[DIAGDIR_END][TLG_END][DIR_END] = { /* X - Y */ + { /* PCP 0 */ + {DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_N, DIR_E, DIR_S, DIR_W}, /* evn - evn */ + {DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_S, DIR_W, DIR_N, DIR_E}, /* evn - odd */ + {DIR_SW, DIR_NW, DIR_NE, DIR_SE, DIR_S, DIR_W, DIR_N, DIR_E}, /* odd - evn */ + {DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_N, DIR_E, DIR_S, DIR_W}, /* odd - odd */ + }, {/* PCP 1 */ + {DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_S, DIR_E, DIR_N, DIR_W}, /* evn - evn */ + {DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_N, DIR_W, DIR_S, DIR_E}, /* evn - odd */ + {DIR_SW, DIR_NW, DIR_NE, DIR_SE, DIR_N, DIR_W, DIR_S, DIR_E}, /* odd - evn */ + {DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_S, DIR_E, DIR_N, DIR_W}, /* odd - odd */ + }, {/* PCP 2 */ + {DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_S, DIR_W, DIR_N, DIR_E}, /* evn - evn */ + {DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_N, DIR_E, DIR_S, DIR_W}, /* evn - odd */ + {DIR_SW, DIR_NW, DIR_NE, DIR_SE, DIR_N, DIR_E, DIR_S, DIR_W}, /* odd - evn */ + {DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_S, DIR_W, DIR_N, DIR_E}, /* odd - odd */ + }, {/* PCP 3 */ + {DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_N, DIR_W, DIR_S, DIR_E}, /* evn - evn */ + {DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_S, DIR_E, DIR_N, DIR_W}, /* evn - odd */ + {DIR_SW, DIR_NW, DIR_NE, DIR_SE, DIR_S, DIR_E, DIR_N, DIR_W}, /* odd - evn */ + {DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_N, DIR_W, DIR_S, DIR_E}, /* odd - odd */ + } +}; +/* Geometric placement of the PCP relative to the tile origin */ +static const char x_pcp_offsets[DIAGDIR_END] = {0, 8, 15, 8}; +static const char y_pcp_offsets[DIAGDIR_END] = {8, 15, 8, 0}; +/* Geometric placement of the PPP relative to the PCP*/ +static const char x_ppp_offsets[DIR_END] = {-3, -4, -3, 0, +3, +4, +3, 0}; +static const char y_ppp_offsets[DIR_END] = {-3, 0, +3, +4, +3, 0, -3, -4}; +/* The type of pylon to draw at each PPP */ +static const SpriteID pylons_normal[] = { + SPR_PYLON_EW_N, + SPR_PYLON_Y_NE, + SPR_PYLON_NS_E, + SPR_PYLON_X_SE, + SPR_PYLON_EW_S, + SPR_PYLON_Y_SW, + SPR_PYLON_NS_W, + SPR_PYLON_X_NW +}; + +static const SpriteID pylons_bridge[] = { + SPR_PYLON_X_NW, + SPR_PYLON_X_SE, + SPR_PYLON_Y_NE, + SPR_PYLON_Y_SW +}; + +/* Maps a track bit onto two PCP positions */ +static const byte PCPpositions[TRACK_END][2] = { + {0, 2}, /* X */ + {1, 3}, /* Y */ + {3, 0}, /* UPPER */ + {1, 2}, /* LOWER */ + {2, 3}, /* LEFT */ + {0, 1}, /* RIGHT */ +}; + +/* Selects a Wire (with white and grey ends) depending on whether: + a) none (should never happen) + b) the first + c) the second + d) both + PCP exists.*/ +static const CatenarySprite Wires[5][TRACK_END][4] = { + { /* Tileh == 0 */ + {INVALID_CATENARY, WIRE_X_FLAT_NE, WIRE_X_FLAT_SW, WIRE_X_FLAT_BOTH}, + {INVALID_CATENARY, WIRE_Y_FLAT_SE, WIRE_Y_FLAT_NW, WIRE_Y_FLAT_BOTH}, + {INVALID_CATENARY, WIRE_EW_N_W, WIRE_EW_N_E, WIRE_EW_N_BOTH}, + {INVALID_CATENARY, WIRE_EW_S_E, WIRE_EW_S_W, WIRE_EW_S_BOTH}, + {INVALID_CATENARY, WIRE_NS_W_S, WIRE_NS_W_N, WIRE_NS_W_BOTH}, + {INVALID_CATENARY, WIRE_NS_E_N, WIRE_NS_E_S, WIRE_NS_E_BOTH}, + }, { /* Tileh == 3 */ + {INVALID_CATENARY, WIRE_X_UP_NE, WIRE_X_UP_SW, WIRE_X_UP_BOTH}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + }, { /* Tileh == 6 */ + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, WIRE_Y_UP_SE, WIRE_Y_UP_NW, WIRE_Y_UP_BOTH}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + }, { /* Tileh == 9 */ + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, WIRE_Y_DOWN_SE, WIRE_Y_DOWN_NW, WIRE_Y_DOWN_BOTH}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + }, { /* Tileh == 12 */ + {INVALID_CATENARY, WIRE_X_DOWN_NE, WIRE_X_DOWN_SW, WIRE_X_DOWN_BOTH}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + {INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY}, + } +}; + +#endif /* ELRAIL_DATA_H */ + diff --git a/table/engines.h b/table/engines.h index b8fe401907..dc33ebafab 100644 --- a/table/engines.h +++ b/table/engines.h @@ -27,11 +27,13 @@ // Rail types // R = Conventional railway +// E = Electrified railway // M = Monorail // L = MagLev #define R 0 -#define M 1 -#define L 2 +#define E 1 +#define M 2 +#define L 3 // Climates // T = Temperate // A = Arctic @@ -65,10 +67,10 @@ const EngineInfo orig_engine_info[] = { MK( 20454, 20, 22, 30, R, A|S ), /* 20 Turner Turbo (Diesel) */ MK( 16071, 20, 22, 30, R, A|S ), /* 21 MJS 1000 (Diesel) */ MK( 20820, 20, 20, 25, R, T ), /* 22 SH '125' (Diesel) */ - MK( 16437, 20, 23, 30, R, T ), /* 23 SH '30' (Electric) */ - MK( 19359, 20, 23, 80, R, T ), /* 24 SH '40' (Electric) */ - MK( 23376, 20, 25, 30, R, T ), /* 25 'T.I.M.' (Electric) */ - MK( 26298, 20, 25, 50, R, T ), /* 26 'AsiaStar' (Electric) */ + MK( 16437, 20, 23, 30, E, T ), /* 23 SH '30' (Electric) */ + MK( 19359, 20, 23, 80, E, T ), /* 24 SH '40' (Electric) */ + MK( 23376, 20, 25, 30, E, T ), /* 25 'T.I.M.' (Electric) */ + MK( 26298, 20, 25, 50, E, T ), /* 26 'AsiaStar' (Electric) */ MW( 1827, 20, 20, 50, R, T|A|S|Y), /* 27 Passenger Carriage */ MW( 1827, 20, 20, 50, R, T|A|S|Y), /* 28 Mail Van */ MW( 1827, 20, 20, 50, R, T|A ), /* 29 Coal Truck */ @@ -306,6 +308,7 @@ const EngineInfo orig_engine_info[] = { #undef L #undef M #undef R +#undef E /** Writes the properties of a rail vehicle into the RailVehicleInfo struct. * @see RailVehicleInfo diff --git a/table/landscape_const.h b/table/landscape_const.h index d7c3179e77..8cf1083c0a 100644 --- a/table/landscape_const.h +++ b/table/landscape_const.h @@ -42,13 +42,6 @@ static const LandscapePredefVar _landscape_predef_var[4] = { 24, 255, 90, 255, 18, 28, 40, 255, 255, 255, 32, 30, }, - /* normal railveh by cargo */ - { - {27, 29, 28, 30, 31, 32, 33, 34, 35, 36, 37, 38}, - {57, 59, 58, 60, 61, 62, 63, 64, 65, 66, 67, 68}, - {89, 91, 90, 92, 93, 94, 95, 96, 97, 98, 99, 100} - }, - /* normal road veh by cargo start & count */ {116, 123, 126, 132, 135, 138, 141, 144, 147, 150, 153, 156}, {7, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3} @@ -95,14 +88,6 @@ static const LandscapePredefVar _landscape_predef_var[4] = { 24, 255, 90, 255, 18, 28, 40, 255, 255, 60, 40, 30 }, - /* hilly railveh by cargo */ - { - {27, 29, 28, 30, 31, 32, 33, 34, 35, 39, 37, 38}, - {57, 59, 58, 60, 61, 62, 63, 64, 65, 69, 67, 68}, - {89, 91, 90, 92, 93, 94, 95, 96, 97, 101, 99, 100} - }, - - /* hilly road veh by cargo start & count */ {116, 123, 126, 132, 135, 138, 141, 144, 147, 159, 153, 156}, {7, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3}, @@ -150,13 +135,6 @@ static const LandscapePredefVar _landscape_predef_var[4] = { 24, 20, 90, 255, 15, 28, 40, 255, 255, 80, 255, 30 }, - /* desert railveh by cargo */ - { - {27, 43, 28, 30, 42, 32, 33, 34, 40, 41, 37, 38}, - {57, 73, 58, 60, 72, 62, 63, 64, 70, 71, 67, 68}, - {89, 105, 90, 92, 104, 94, 95, 96, 102, 103, 99, 100} - }, - /* desert road veh by cargo start & count */ {116, 171, 126, 132, 168, 138, 141, 144, 162, 165, 153, 156}, {7, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3} @@ -203,13 +181,6 @@ static const LandscapePredefVar _landscape_predef_var[4] = { 24, 255, 90, 255, 30, 40, 60, 75, 25, 80, 255, 50 }, - /* candy railveh by cargo */ - { - {27, 44, 28, 50, 51, 49, 46, 48, 45, 47, 53, 52}, - {57, 74, 58, 80, 81, 79, 76, 78, 75, 77, 83, 82}, - {89, 106, 90, 112, 113, 111, 108, 110, 107, 109, 115, 114} - }, - /* candy road veh by cargo start & count */ {116, 174, 126, 186, 192, 189, 183, 177, 180, 201, 198, 195}, {7, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3} diff --git a/table/sprites.h b/table/sprites.h index 34fda3f647..f7e0817c29 100644 --- a/table/sprites.h +++ b/table/sprites.h @@ -51,7 +51,8 @@ enum Sprites { SPR_CANALS_BASE = 5382, SPR_SLOPES_BASE = SPR_CANALS_BASE + 70, SPR_AUTORAIL_BASE = SPR_SLOPES_BASE + 78, - SPR_2CCMAP_BASE = SPR_AUTORAIL_BASE + 55, + SPR_ELRAIL_BASE = SPR_AUTORAIL_BASE + 55, + SPR_2CCMAP_BASE = SPR_ELRAIL_BASE + 53, SPR_OPENTTD_BASE = SPR_2CCMAP_BASE + 256, SPR_BLOT = SPR_OPENTTD_BASE + 29, // colored circle (mainly used as vehicle profit marker and for sever compatibility) @@ -206,6 +207,54 @@ enum Sprites { OFFSET_TILEH_13 = 19, OFFSET_TILEH_14 = 16, + /* Elrail stuff */ + /* Wires. First identifier is the direction of the track, second is the required placement of the pylon. + "short" denotes a wire that requires a pylon on each end. Third identifier is the direction of the slope + (in positive coordinate direction) */ + SPR_WIRE_X_SHORT = SPR_ELRAIL_BASE + 3, + SPR_WIRE_Y_SHORT = SPR_ELRAIL_BASE + 4, + SPR_WIRE_EW_SHORT = SPR_ELRAIL_BASE + 5, + SPR_WIRE_NS_SHORT = SPR_ELRAIL_BASE + 6, + SPR_WIRE_X_SHORT_DOWN = SPR_ELRAIL_BASE + 7, + SPR_WIRE_Y_SHORT_UP = SPR_ELRAIL_BASE + 8, + SPR_WIRE_X_SHORT_UP = SPR_ELRAIL_BASE + 9, + SPR_WIRE_Y_SHORT_DOWN = SPR_ELRAIL_BASE + 10, + + SPR_WIRE_X_SW = SPR_ELRAIL_BASE + 11, + SPR_WIRE_Y_SE = SPR_ELRAIL_BASE + 12, + SPR_WIRE_EW_E = SPR_ELRAIL_BASE + 13, + SPR_WIRE_NS_S = SPR_ELRAIL_BASE + 14, + SPR_WIRE_X_SW_DOWN = SPR_ELRAIL_BASE + 15, + SPR_WIRE_Y_SE_UP = SPR_ELRAIL_BASE + 16, + SPR_WIRE_X_SW_UP = SPR_ELRAIL_BASE + 17, + SPR_WIRE_Y_SE_DOWN = SPR_ELRAIL_BASE + 18, + + SPR_WIRE_X_NE = SPR_ELRAIL_BASE + 19, + SPR_WIRE_Y_NW = SPR_ELRAIL_BASE + 20, + SPR_WIRE_EW_W = SPR_ELRAIL_BASE + 21, + SPR_WIRE_NS_N = SPR_ELRAIL_BASE + 22, + SPR_WIRE_X_NE_DOWN = SPR_ELRAIL_BASE + 23, + SPR_WIRE_Y_NW_UP = SPR_ELRAIL_BASE + 24, + SPR_WIRE_X_NE_UP = SPR_ELRAIL_BASE + 25, + SPR_WIRE_Y_NW_DOWN = SPR_ELRAIL_BASE + 26, + + /* Tunnel entries */ + SPR_WIRE_DEPOT_SW = SPR_ELRAIL_BASE + 27, + SPR_WIRE_DEPOT_NW = SPR_ELRAIL_BASE + 28, + SPR_WIRE_DEPOT_NE = SPR_ELRAIL_BASE + 29, + SPR_WIRE_DEPOT_SE = SPR_ELRAIL_BASE + 30, + + + /* Pylons, first identifier is the direction of the track, second the placement relative to the track */ + SPR_PYLON_Y_NE = SPR_ELRAIL_BASE + 31, + SPR_PYLON_Y_SW = SPR_ELRAIL_BASE + 32, + SPR_PYLON_X_NW = SPR_ELRAIL_BASE + 33, + SPR_PYLON_X_SE = SPR_ELRAIL_BASE + 34, + SPR_PYLON_EW_N = SPR_ELRAIL_BASE + 35, + SPR_PYLON_EW_S = SPR_ELRAIL_BASE + 36, + SPR_PYLON_NS_W = SPR_ELRAIL_BASE + 37, + SPR_PYLON_NS_E = SPR_ELRAIL_BASE + 38, + /* sprites for airports and airfields*/ /* Small airports are AIRFIELD, everything else is AIRPORT */ SPR_HELIPORT = 2633, @@ -955,6 +1004,13 @@ enum Sprites { SPR_BUBBLE_ABSORB_3 = 4761, SPR_BUBBLE_ABSORB_4 = 4762, + /* Electrified rail build menu */ + SPR_BUILD_NS_ELRAIL = SPR_ELRAIL_BASE + 39, + SPR_BUILD_X_ELRAIL = SPR_ELRAIL_BASE + 40, + SPR_BUILD_EW_ELRAIL = SPR_ELRAIL_BASE + 41, + SPR_BUILD_Y_ELRAIL = SPR_ELRAIL_BASE + 42, + SPR_BUILD_TUNNEL_ELRAIL = SPR_ELRAIL_BASE + 47, + /* road_gui.c */ SPR_IMG_ROAD_NW = 1309, SPR_IMG_ROAD_NE = 1310, @@ -1034,9 +1090,15 @@ typedef enum CursorSprites { SPR_CURSOR_EW_MAGLEV = 1273, SPR_CURSOR_NWSE_MAGLEV = 1274, + SPR_CURSOR_NS_ELRAIL = SPR_ELRAIL_BASE + 43, + SPR_CURSOR_SWNE_ELRAIL = SPR_ELRAIL_BASE + 44, + SPR_CURSOR_EW_ELRAIL = SPR_ELRAIL_BASE + 45, + SPR_CURSOR_NWSE_ELRAIL = SPR_ELRAIL_BASE + 46, + SPR_CURSOR_RAIL_STATION = 1300, SPR_CURSOR_TUNNEL_RAIL = 2434, + SPR_CURSOR_TUNNEL_ELRAIL = SPR_ELRAIL_BASE + 48, SPR_CURSOR_TUNNEL_MONO = 2435, SPR_CURSOR_TUNNEL_MAGLEV = 2436, diff --git a/train_cmd.c b/train_cmd.c index e5fd267724..4e433eef05 100644 --- a/train_cmd.c +++ b/train_cmd.c @@ -71,6 +71,46 @@ static void TrainCargoChanged(Vehicle* v) v->u.rail.cached_weight = weight; } +/** + * Recalculates the cached total power of a train. Should be called when the consist is changed + * @param v First vehicle of the consist. + */ +void TrainPowerChanged(Vehicle* v) +{ + const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type); + Vehicle* u; + uint32 power = 0; + + for (u = v; u != NULL; u = u->next) { + const RailVehicleInfo *rvi_u; + bool engine_has_power = true; + bool wagon_has_power = true; + + /* Power is not added for articulated parts */ + if (IsArticulatedPart(u)) continue; + + if (IsBridgeTile(u->tile) && IsBridgeMiddle(u->tile) && DiagDirToAxis(DirToDiagDir(u->direction)) == GetBridgeAxis(u->tile)) { + if (!HasPowerOnRail(u->u.rail.railtype, GetRailTypeOnBridge(u->tile))) engine_has_power = false; + if (!HasPowerOnRail(v->u.rail.railtype, GetRailTypeOnBridge(u->tile))) wagon_has_power = false; + } else { + if (!HasPowerOnRail(u->u.rail.railtype, GetRailType(u->tile))) engine_has_power = false; + if (!HasPowerOnRail(v->u.rail.railtype, GetRailType(u->tile))) wagon_has_power = false; + } + + rvi_u = RailVehInfo(u->engine_type); + + if (engine_has_power) power += rvi_u->power; + if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) { + power += rvi_v->pow_wag_power; + } + } + + if (v->u.rail.cached_power != power) { + v->u.rail.cached_power = power; + InvalidateWindow(WC_VEHICLE_DETAILS, v->index); + } +} + /** * Recalculates the cached stuff of a train. Should be called each time a vehicle is added * to/removed from the chain, and when the game is loaded. @@ -82,7 +122,6 @@ void TrainConsistChanged(Vehicle* v) const RailVehicleInfo *rvi_v; Vehicle *u; uint16 max_speed = 0xFFFF; - uint32 power = 0; EngineID first_engine; assert(v->type == VEH_Train); @@ -92,6 +131,7 @@ void TrainConsistChanged(Vehicle* v) rvi_v = RailVehInfo(v->engine_type); first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE; v->u.rail.cached_total_length = 0; + v->u.rail.compatible_railtypes = 0; for (u = v; u != NULL; u = u->next) { const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type); @@ -102,6 +142,7 @@ void TrainConsistChanged(Vehicle* v) // update the 'first engine' u->u.rail.first_engine = (v == u) ? INVALID_ENGINE : first_engine; + u->u.rail.railtype = GetEngine(u->engine_type)->railtype; if (rvi_u->visual_effect != 0) { u->u.rail.cached_vis_effect = rvi_u->visual_effect; @@ -119,9 +160,6 @@ void TrainConsistChanged(Vehicle* v) } if (!IsArticulatedPart(u)) { - // power is the sum of the powers of all engines and powered wagons in the consist - power += rvi_u->power; - // check if its a powered wagon CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON); if ((rvi_v->pow_wag_power != 0) && (rvi_u->flags & RVI_WAGON) && UsesWagonOverride(u)) { @@ -135,10 +173,15 @@ void TrainConsistChanged(Vehicle* v) if (u->u.rail.cached_vis_effect < 0x40) { /* wagon is powered */ SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status - power += rvi_v->pow_wag_power; } } + /* Do not count powered wagons for the compatible railtypes, as wagons always + have railtype normal */ + if (rvi_u->power > 0) { + v->u.rail.compatible_railtypes |= GetRailTypeInfo(u->u.rail.railtype)->powered_railtypes; + } + // max speed is the minimum of the speed limits of all vehicles in the consist if (!(rvi_u->flags & RVI_WAGON) || _patches.wagon_speed_limits) if (rvi_u->max_speed != 0 && !UsesWagonOverride(u)) @@ -159,7 +202,8 @@ void TrainConsistChanged(Vehicle* v) // store consist weight/max speed in cache v->u.rail.cached_max_speed = max_speed; - v->u.rail.cached_power = power; + + TrainPowerChanged(v); // recalculate cached weights too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added) TrainCargoChanged(v); @@ -333,6 +377,7 @@ static int GetTrainAcceleration(Vehicle *v, bool mode) if (speed > 0) { switch (v->u.rail.railtype) { case RAILTYPE_RAIL: + case RAILTYPE_ELECTRIC: case RAILTYPE_MONO: force = power / speed; //[N] force *= 22; @@ -1468,6 +1513,9 @@ static void ReverseTrainSwapVeh(Vehicle *v, int l, int r) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos); } + + /* Update train's power incase tiles were different rail type */ + TrainPowerChanged(v); } /* Check if the vehicle is a train and is on the tile we are testing */ @@ -1786,7 +1834,7 @@ static TrainFindDepotData FindClosestTrainDepot(Vehicle *v) Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last)); assert (trackdir != INVALID_TRACKDIR); - ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, NPF_INFINITE_PENALTY); + ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY); if (ftd.best_bird_dist == 0) { /* Found target */ tfdd.tile = ftd.node.tile; @@ -1805,7 +1853,7 @@ static TrainFindDepotData FindClosestTrainDepot(Vehicle *v) if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT); } - NewTrainPathfind(tile, 0, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd); + NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd); if (tfdd.best_length == (uint)-1){ tfdd.reverse = true; // search in backwards direction @@ -1813,7 +1861,7 @@ static TrainFindDepotData FindClosestTrainDepot(Vehicle *v) if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT); } - NewTrainPathfind(tile, 0, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd); + NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd); } } @@ -1899,7 +1947,7 @@ static void HandleLocomotiveSmokeCloud(const Vehicle* v) // no smoke? if ((RailVehInfo(engtype)->flags & RVI_WAGON && effect_type == 0) || disable_effect || - GetEngine(engtype)->railtype > RAILTYPE_RAIL || + GetEngine(engtype)->railtype > RAILTYPE_ELECTRIC || v->vehstatus & VS_HIDDEN || v->u.rail.track & 0xC0) { continue; @@ -1961,6 +2009,7 @@ static void TrainPlayLeaveStationSound(const Vehicle* v) switch (GetEngine(engtype)->railtype) { case RAILTYPE_RAIL: + case RAILTYPE_ELECTRIC: SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], v); break; @@ -2112,7 +2161,7 @@ static byte ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir, trackdir = GetVehicleTrackdir(v); assert(trackdir != 0xff); - ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype); + ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes); if (ftd.best_trackdir == 0xff) { /* We are already at our target. Just do something */ @@ -2136,7 +2185,7 @@ static byte ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir, fd.best_track = 0xFF; NewTrainPathfind(tile - TileOffsByDir(enterdir), v->dest_tile, - enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd); + v->u.rail.compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd); if (fd.best_track == 0xff) { // blaha @@ -2190,7 +2239,7 @@ static bool CheckReverseTrain(Vehicle *v) assert(trackdir != 0xff); assert(trackdir_rev != 0xff); - ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype); + ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes); if (ftd.best_bird_dist != 0) { /* We didn't find anything, just keep on going straight ahead */ reverse_best = false; @@ -2206,7 +2255,7 @@ static bool CheckReverseTrain(Vehicle *v) fd.best_bird_dist = (uint)-1; fd.best_track_dist = (uint)-1; - NewTrainPathfind(v->tile, v->dest_tile, reverse ^ i, (NTPEnumProc*)NtpCallbFindStation, &fd); + NewTrainPathfind(v->tile, v->dest_tile, v->u.rail.compatible_railtypes, reverse ^ i, (NTPEnumProc*)NtpCallbFindStation, &fd); if (best_track != -1) { if (best_bird_dist != 0) { @@ -2575,7 +2624,7 @@ static bool CheckCompatibleRail(const Vehicle *v, TileIndex tile) return IsTileOwner(tile, v->owner) && ( !IsFrontEngine(v) || - IsCompatibleRail(v->u.rail.railtype, GetRailType(tile)) + HASBIT(v->u.rail.compatible_railtypes, GetRailType(tile)) ); } @@ -2585,9 +2634,10 @@ typedef struct { byte z_down; // fraction to remove when moving down } RailtypeSlowdownParams; -static const RailtypeSlowdownParams _railtype_slowdown[3] = { +static const RailtypeSlowdownParams _railtype_slowdown[] = { // normal accel {256/4, 256/2, 256/4, 2}, // normal + {256/4, 256/2, 256/4, 2}, // electrified {256/4, 256/2, 256/4, 2}, // monorail {0, 256/2, 256/4, 2}, // maglev }; @@ -2873,6 +2923,11 @@ static void TrainController(Vehicle *v) if (!(r&0x4)) { v->tile = gp.new_tile; + + if (GetTileRailType(gp.new_tile, chosen_track) != GetTileRailType(gp.old_tile, v->u.rail.track)) { + TrainPowerChanged(GetFirstVehicleInChain(v)); + } + v->u.rail.track = chosen_track; assert(v->u.rail.track); } diff --git a/train_gui.c b/train_gui.c index 51565980b1..160e8fe7d5 100644 --- a/train_gui.c +++ b/train_gui.c @@ -177,7 +177,7 @@ static void engine_drawing_loop(int *x, int *y, int *pos, int *sel, const Engine *e = GetEngine(i); const RailVehicleInfo *rvi = RailVehInfo(i); - if (!IsCompatibleRail(e->railtype, railtype) || !(rvi->flags & RVI_WAGON) != is_engine || + if (!HasPowerOnRail(e->railtype, railtype) || !(rvi->flags & RVI_WAGON) != is_engine || !HASBIT(e->player_avail, _local_player)) continue; @@ -208,7 +208,7 @@ static void NewRailVehicleWndProc(Window *w, WindowEvent *e) for (i = 0; i < NUM_TRAIN_ENGINES; i++) { const Engine *e = GetEngine(i); - if (IsCompatibleRail(e->railtype, railtype) + if (HasPowerOnRail(e->railtype, railtype) && HASBIT(e->player_avail, _local_player)) count++; } diff --git a/tunnelbridge_cmd.c b/tunnelbridge_cmd.c index b7d8466dd1..7445db1673 100644 --- a/tunnelbridge_cmd.c +++ b/tunnelbridge_cmd.c @@ -799,9 +799,9 @@ int32 DoConvertTunnelBridgeRail(TileIndex tile, uint totype, bool exec) // fast routine for getting the height of a middle bridge tile. 'tile' MUST be a middle bridge tile. -static uint GetBridgeHeight(const TileInfo *ti) +uint GetBridgeHeight(TileIndex t) { - TileIndex tile = GetSouthernBridgeEnd(ti->tile); + TileIndex tile = GetSouthernBridgeEnd(t); /* Return the height there (the height of the NORTH CORNER) * If the end of the bridge is on a tileh 7 (all raised, except north corner), @@ -930,6 +930,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti) image += GetTunnelDirection(ti->tile) * 2; DrawGroundSprite(image); + if (GB(_m[ti->tile].m3, 0, 3) == RAILTYPE_ELECTRIC) DrawCatenary(ti); AddSortableSpriteToDraw(image+1, ti->x + 15, ti->y + 15, 1, 1, 8, (byte)ti->z); } else if (IsBridge(ti->tile)) { // XXX is this necessary? @@ -973,6 +974,8 @@ static void DrawTile_TunnelBridge(TileInfo *ti) DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh]); } + if (GB(_m[ti->tile].m3, 0, 3) == RAILTYPE_ELECTRIC) DrawCatenary(ti); + // draw ramp if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image); AddSortableSpriteToDraw(image, ti->x, ti->y, 16, 16, 7, ti->z); @@ -1029,7 +1032,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti) // get bridge sprites b = GetBridgeSpriteTable(GetBridgeType(ti->tile), GetBridgePiece(ti->tile)) + base_offset; - z = GetBridgeHeight(ti) + 5; + z = GetBridgeHeight(ti->tile) + 5; // draw rail or road component image = b[0]; @@ -1054,6 +1057,8 @@ static void DrawTile_TunnelBridge(TileInfo *ti) if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 1, 16, 0x28, z); } + if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC || GetRailTypeOnBridge(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); + if (ti->z + 5 == z) { // draw poles below for small bridges image = b[2]; @@ -1107,7 +1112,7 @@ static uint GetSlopeZ_TunnelBridge(const TileInfo* ti) if (_get_z_hint >= z + 8) return _get_z_hint; // actually on the bridge, but not yet in the shared area. - if (!IS_INT_INSIDE(x, 5, 10 + 1)) return GetBridgeHeight(ti) + 8; + if (!IS_INT_INSIDE(x, 5, 10 + 1)) return GetBridgeHeight(ti->tile) + 8; // in the shared area, assume that we're below the bridge, cause otherwise the hint would've caught it. // if rail or road below then it means it's possibly build on slope below the bridge. diff --git a/variables.h b/variables.h index c7c051ad34..b63a0cee7e 100644 --- a/variables.h +++ b/variables.h @@ -345,7 +345,6 @@ typedef struct { SpriteID sprites[NUM_CARGO]; byte transit_days_1[NUM_CARGO]; byte transit_days_2[NUM_CARGO]; - byte ai_railwagon[3][NUM_CARGO]; byte ai_roadveh_start[NUM_CARGO]; byte ai_roadveh_count[NUM_CARGO]; } CargoConst; diff --git a/vehicle.c b/vehicle.c index 6f85588237..0183d04c77 100644 --- a/vehicle.c +++ b/vehicle.c @@ -218,6 +218,10 @@ void AfterLoadVehicles(void) FOR_ALL_VEHICLES(v) { v->first = NULL; + if (v->type == VEH_Train) v->u.rail.first_engine = INVALID_ENGINE; + } + + FOR_ALL_VEHICLES(v) { if (v->type == VEH_Train && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v); } diff --git a/vehicle.h b/vehicle.h index d63e6b5f51..87d279449d 100644 --- a/vehicle.h +++ b/vehicle.h @@ -72,6 +72,7 @@ typedef struct VehicleRail { byte track; byte force_proceed; byte railtype; + RailTypeMask compatible_railtypes; byte flags; @@ -307,6 +308,7 @@ UnitID GetFreeUnitNumber(byte type); int LoadUnloadVehicle(Vehicle *v); void TrainConsistChanged(Vehicle *v); +void TrainPowerChanged(Vehicle *v); int32 GetTrainRunningCost(const Vehicle *v); int CheckTrainStoppedInDepot(const Vehicle *v); diff --git a/vehicle_gui.c b/vehicle_gui.c index 25b0f65772..31b8e9bf05 100644 --- a/vehicle_gui.c +++ b/vehicle_gui.c @@ -76,6 +76,7 @@ const StringID _vehicle_sort_listing[] = { static const StringID _rail_types_list[] = { STR_RAIL_VEHICLES, + STR_ELRAIL_VEHICLES, STR_MONORAIL_VEHICLES, STR_MAGLEV_VEHICLES, INVALID_STRING_ID @@ -450,7 +451,7 @@ static int CDECL VehicleValueSorter(const void *a, const void *b) * if used compined with show_cars set to false, it will work as intended. Replace window do it like that * this was a big hack even before show_outdated was added. Stupid newgrf :p */ static void train_engine_drawing_loop(int *x, int *y, int *pos, int *sel, EngineID *selected_id, RailType railtype, - uint8 lines_drawn, bool is_engine, bool show_cars, bool show_outdated) + uint8 lines_drawn, bool is_engine, bool show_cars, bool show_outdated, bool show_compatible) { EngineID j; byte colour; @@ -472,7 +473,9 @@ static void train_engine_drawing_loop(int *x, int *y, int *pos, int *sel, Engine colour = *sel == 0 ? 0xC : 0x10; if (!(ENGINE_AVAILABLE && show_outdated && RailVehInfo(i)->power && e->railtype == railtype)) { - if (e->railtype != railtype || !(rvi->flags & RVI_WAGON) != is_engine || + if ((!HasPowerOnRail(e->railtype, railtype) && show_compatible) + || (e->railtype != railtype && !show_compatible) + || !(rvi->flags & RVI_WAGON) != is_engine || !HASBIT(e->player_avail, _local_player)) continue; } /*else { @@ -522,16 +525,15 @@ static void SetupScrollStuffForReplaceWindow(Window *w) const Engine* e = GetEngine(eid); const EngineInfo* info = &_engine_info[eid]; + // left window contains compatible engines while right window only contains engines of the selected type if (ENGINE_AVAILABLE && ( (RailVehInfo(eid)->power != 0 && WP(w, replaceveh_d).wagon_btnstate) || - (RailVehInfo(eid)->power == 0 && !WP(w, replaceveh_d).wagon_btnstate) - ) && - e->railtype == railtype) { - if (_player_num_engines[eid] > 0 || EngineHasReplacementForPlayer(p, eid)) { + (RailVehInfo(eid)->power == 0 && !WP(w, replaceveh_d).wagon_btnstate))) { + if (HasPowerOnRail(e->railtype, railtype) && (_player_num_engines[eid] > 0 || EngineHasReplacementForPlayer(p, eid))) { if (sel[0] == count) selected_id[0] = eid; count++; } - if (HASBIT(e->player_avail, _local_player)) { + if (e->railtype == railtype && HASBIT(e->player_avail, _local_player)) { if (sel[1] == count2) selected_id[1] = eid; count2++; } @@ -647,12 +649,12 @@ static void DrawEngineArrayInReplaceWindow(Window *w, int x, int y, int x2, int * engines to get more types.. Stays here until we have our own format * then it is exit!!! */ if (WP(w,replaceveh_d).wagon_btnstate) { - train_engine_drawing_loop(&x, &y, &pos, &sel[0], &selected_id[0], railtype, w->vscroll.cap, true, false, true); // True engines - train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, true, false, false); // True engines - train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, false, false, false); // Feeble wagons + train_engine_drawing_loop(&x, &y, &pos, &sel[0], &selected_id[0], railtype, w->vscroll.cap, true, false, true, true); // True engines + train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, true, false, false, false); // True engines + train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, false, false, false, false); // Feeble wagons } else { - train_engine_drawing_loop(&x, &y, &pos, &sel[0], &selected_id[0], railtype, w->vscroll.cap, false, true, true); - train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, false, true, false); + train_engine_drawing_loop(&x, &y, &pos, &sel[0], &selected_id[0], railtype, w->vscroll.cap, false, true, true, true); + train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, false, true, false, true); } break; }