diff --git a/BUGS b/BUGS new file mode 100644 --- /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 --- 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 --- 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(byt 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(Til 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 * 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 --- 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 --- a/bridge_map.h +++ b/bridge_map.h @@ -127,6 +127,7 @@ TileIndex GetSouthernBridgeEnd(TileIndex */ 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 zc$}444|o*SwZC^}cC(q8O_rb#3nnuWm(iq>st830G%73zlr&2BGtr`=WjE9Zsrt}L zO9SGa*$uluS`+ly6ww!LtIHqzf=0U_J~wFFP0%+3ik$%JO+@_DH&3kP?K^ii!SJ=U z-<$8-d~?p6x#ylgzjMx=2qIG~{8x&O`a zuqNfR-cC7N$|(v_+NW@;N^05{ahgUNNg27nUFRH!w735|CyL~^?XPf>MBZpW&dDy}4ArAu=bUjV>!VPG9oxBA%pzjnpLn`zM*OI>I3)`4|0iqm+~zSLv@CH^8r1|G-EdyTiEC*kx=tvhd{8&>0Qm zLS~c~o$E(|8Av9PE4<8;pg%;u>t*f(zpW%c@-n}H=aS?XUgk@1>mKqlcoQV|kax3t zSRDSUOTYogxjK%6j=wRwYl@(0EHSzl3Cus_rtXN~E_ZMDgMzDKOZP7YSM4)haps7F z-G|xYadJ%O^f7sd{%szBFI7?vzs1(g%$v)}4`~H?khB47m$i>Alp!YUM0VS8|NF7h-%d8|7|RT-;aTQ z)c6%vjYo`wLx+u{#s{|g56}Q6DUkmR3SiVQ6d<%SNf~y5fF0nK!Cw~!9p$inKth?m zu%iJC*Q0PtIv&P~`-Y+)0Qy`&$nq#h005@gHB8ko8Zy^{8UTZ9dj;vXD?k-M0cZ#4 zzXB4z)_Vz4db$2BAimdk7gKw${vZ&K!`liVq8FqUpogrAFJYmucriFY{8+j>ETSyD za4GB>1q>$W%CP6~=>b8u>`P)0sR!*)j$Lr$$Ko>KLd}I>yyYV zy_Q3cUhk6YfP9QJ>ODMUu>J?&oYcP{vy2PC9OF_*|B&%rAnyTBHX3bMF?JZcf!hak zjqx!?qo8q)M+LU`VQ4U0&q70V7&JT#1P(lZjQ&Po_A_L_bLItNk@x8&9_;;R;9yzO zHHC$(tm}G#6&V*Atl*G)Qxkcnf+53I@J#oMg1bCm!(Du0vg}-N20I!|fju zL(V94DES8CO0b7t(KY}KtZB?5O<+YMG2k!j8s+3wx1GF)wUMR)cQtw~1ahQjIBw4X zfB=N_-@BOk3jm^&Ly~a`BaNj%-VNy3!b7+pIgw{-7&=@ftZ_KQ@NgAO zO!WvZP5~Wx?7r7t_Eo)u;RAk)AWc<<4mWejR`~7A)B@wb=)2&{;kMy+h#7 zX8=HY`d))v>DLDsYz&TEV<`Pouw-0iT<3D`1kMJs+}Qs7PRJLd$9N4;bJRFVuOSHg z0_RxmI-@fH1);MH2Byv`NXgC_kfh0?&ZU64&gI~fWOM$-b4{{k)-Ov~6@*}v*tIO1 zLp&RWZsOS-w30&hE7NgN+5>&#vC9aN1 zJR1tGa@B`G{he$#pb|m|3GYLn=RO@)$vK+k<100h1|V>V`luJPzhme`tCSXIeHqPC zGCu62ec2^gP5VdyN7KIUKs&-EK3L+Tk%f>5+ZU0e+1>)kRIw7Vl_B-AKD*cs*u}6; z09FZDWogDgyA}!LH-*rrIgg{ctMTxD#>Z^Q`Y^IZ+ea_LA}zHp?b5Q--Q9%ns1@?N z`8@Yg4z}Pf0O_3)-TlzIOz`6zIFBg<3DFiZKJU45BNl#g){CFI1;x{hTZLVH1}<)bCcU6x{%q| zNVa0v_^=>z1yN^xYBmjErE4~ptou^4v1rexYdOuy&Zc+asC`$a7(3ZwPIaB1N47FzP&T3WqLJ&?KaxD)db>7u|?fp!?A#v>kP$Ui3B^ zM4zD+n15OdC8?!AmN^dl8KSC$xA1B zAf9292Iv$nDOdp^8jfgo37x?CxJ-#)64{|a`$Db|rGtX`kZjWHX&L85*&r7$pdtGP ztB&&^E65RFcBxMjITSWq`OHQ1MvtjE1w!UlZ%dKp`1njIEfQ3R^Vs9S^dU52+&A;a z)u381ZUI`1z6WuOp?^cW!Mr2r9n>N^N{cAUZD{!517n^jLsPRw$b9J0wvhD&6j8t? zTtcC#i01k+RQ9*I?SZAM<0y2FRaES>p=g+pa1^d^6cEf2(ml%)b<7O`d%jgeXV}-` zXhw3|U5!;^{fKW7qqLJ79gQpgX*3FkqXEr__e4#TE2Lve{jyxZhczcEie^i(Bo*?e zs8y;ORlF@@M6n3bOK6G548v~em7brDb&^mY=vYCEgrnB^oDbQB^kTswqM135E5KBw z3j|Y_%(TYI*ji}K7ff?wQMO9(38I#r&plXdReJn_qnYUteMl%V!yFyUJye)!q<&r{ zh4f+TCw7t0;y1%4=F5UGD|~vkUi%R$E-ota``sa&ai|RAQIJl;e#%?kj11jR)RGH5 zMSegC6G+RPrjTGN2;+6I>k;e+>6cRsHK>zX;!wBO5mp}^3mA*QP8 zKr|&)p#uFG3EDv{(TjQ0bm%OP!vIMqlOVKRB|JF6E2@zQt2|ynT_hrrg@ZG*L94lN z)hcbZ;;5>aY`0f-1-YiCOpq5sIeBq9h*xKV0}l)=rG=f>_f;2&tT>ozD#)X-(z$xDT2LYpG4m3Rb_dC1 zuc}5@t&%d$T|sPGi*fj{*jtU|-fAwYJax*xr+0f_2FscD_MrV}M~0Uo%3!}`ZJ)t~ zm5%M4xTd)$>`tR8| zst@hGMgOy*8r4R1z%+|TrHdpQw-`S#9@uto`#d9N5<5DK2s|#rDFeWt=k3 z#N=)F;-XZDOm{&a|wWHK+-9~+3lnBkZADV*ew z%kc^EiLp&s?hcXp@mu4o;wxwfOFL5q06D+EsHngG*peeRU@x|6!~>|9GLJDQ47B zG?;U`tp4d_{?LikBN<~h_ z)3%=4jt-@;YW-pF4o;Ctd~hYU=%4h{&)&@Wi;pGu4jtYhD2^hLI3Ffc?LQfFo_&HV zE*`qrs1`Jp@dumq6^TI_GOCBF`N}-U$R={QxF@^4no~p)H%KD4hZuPxwk(m`n=-0t z2=2QQxxUjz&yk+Dmf}czJoa%S$4SK}HyS-39D|WR9-p4bv3|~IUUjAdXI&!qVJR;9 zU|TE%twd!)876e{H(Nv8)TwOQ)<7cn+Om_M0V4`tX$>cGySqO8RyuxSGLG*4kJipa zF7|O|!3!Z0YNd%>GIaD!qk7Y#_ijt%exBL1c2k^$61gX*pUPOClt|9YT*RxQ$~Ysb z-zk$)I+@P*a{NVA=!3I!DAW{lWH8SLNfnt&syeSo&*q91av|JS@_sc;7LX0yd%S+A zYf6};NGdbHYMn^FPEy@NoGjUu_D!UZ*n{7~Ql^r8T`we+mtEkVA<{=}k%zps$JpoFrMNhIsWqjuvis}Z z6Cr7f2A}B6!n{1hYmfj{hjkbkY}k5L@1Dc&lhv6pjKH=415p(@FTFufBc@C85d36- zDt3yKikNt3RiRuYy1meW3hslkT9H!hyNGIs`C?HWIE5xGh;Ac>VSe9-=?(S`!s>{*nl7^%d8o#gOwa2sO{X#% zUQG#JZCy#LY}pQ^ORcvDefDANsD0d$u>;CZr>pjr^R+aIQRTblhTCuWYOspdIjiDd+7atV6BrwuK2-CU;WBu1R2h_q3l^&u#g@zuw>fqqghm%ih3H(?>eBNve*4C*Kz5Sb z@JO=z7hkqKmS@&v*7htCq6=B6aH1xZiqup%)ZI=(9hKOhO+u*%M^%+B=)9htSAIj1 zogpk|<3iKw2+1tyY-2}IOHb|n-QY}Xu4ifl(losw{U@x_BkgUv(jJ1-Og77z5fBwM zYp$;8E83IkY_d(znRMO@RM@7j| zI(mj)H|FT4kIf)$gFS*HshY9m*dGmI%mK53#XC}^vBb#6cJ3mZHO>)@C9%@j>3;Io z?VB|iPImykEY`KVt3#uqZA%WViFL(3-u>y}9vnFyg(25C@z%?+kK@ySJ!5Z=OP-M9 z(;r=ji{k70dibd-a8AltjjwxjItlIT;TXd{8PCMmwT|gu0t4dIsax0RO6w+M7XR&NFMVl${Ub#=Nf3?lsRn*Glb> zHJ{AeboHS%Pke#ZP1P10Ggb2Drj|{cq1%{dGK9t6iR|OnND$$G3ne5QN-cP5+2CsK z%PIo!ou7@T7JRfkH7{`{ao`t+((!a#Pc@mB$R++r77S|7XCTzc#J)t9w87eY)*Rdn zk1`1}_0F&8(2>OdCSFOr(V^kuUsoHqBwkMR>&@bqz4F+IKo2f%pP#=sy!*F3{Vpu> zdg3i(37O9{CEhW%k*)0Y#DH;v98LUZ;?2Z~*k$mnH(@2-kFCkeCx-NBUOw@mekSqq z!~H98;aE1eVpJJKm!TObgu*C_)}qbm3G_V5qW92W(HML&o`&b*dfbRNdfX~G&VXuJ zSJ%)`S7(}W&TN=gKdrv8(JuCG!e(9lg|w)!PSJ>3XC@I1aMNz40g-5mr6_ggW<;wC zE}Yg_=Y&PNxX>bX<`z^}e>1HW6~#0q365Ni_IbX>`uh6D1}AL)kbRS{YcRK>`bN5f ztJAU@3r$(BuQS_F105$c)J4_oqXMauWqTZ7*U(5SImfh0eU?(!ST9L!bd#r{p`j6m zC@&22W|+|NT>VzM2RG2Ayk#|I$79CY!oiDmDomJ>%sAdm@^m(xXhpXA$f6o&6r!&!V_?bQCx2 z{8aQ8osHyik1RtZ+rbCL5X%=JmVF$p!1eT%U6=F4MGaJSquF&I`>)$o^}0H>VU@HT2Ms z!M--}a2$DI7rp+=Ihv{gjK|67v)rjs4TO}E$>b_>9k~H2eKYwf`wU5*AuqE3e~=;a zdH$W;|LYwO%83}C?|B0io~NK=xi50lHFPP!_6jr;T?c352DBXg0Nsn$qd58*dJO#v z?LjZ1{pcWChg!-cas7nXUlaMSN#a4fh~rA_5>KXA?PPsn_LMV*dQU%C783JlX<*)w(0- + + + + + + + + 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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 diff --git a/docs/landscape.html b/docs/landscape.html --- 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 - 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 --- /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 --- a/engine_gui.c +++ b/engine_gui.c @@ -20,9 +20,10 @@ static StringID GetEngineCategoryName(En { 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 --- 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 --- a/lang/english.txt +++ b/lang/english.txt @@ -1443,6 +1443,7 @@ STR_1005_NO_SUITABLE_RAILROAD_TRACK 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 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 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 ############ 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 --- 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 o 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 --- a/newgrf.c +++ b/newgrf.c @@ -355,6 +355,9 @@ static bool RailVehicleChangeInfo(uint e 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 --- a/npf.c +++ b/npf.c @@ -587,7 +587,7 @@ static void NPFFollowTrack(AyStar* aysta /* 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* aysta * 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 NPFRouteIntern /* 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 NPFRouteIntern 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 NPFRouteToStationOrTi 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 NPFRouteToDepotBreadt /* 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 --- a/npf.h +++ b/npf.h @@ -38,7 +38,7 @@ typedef struct NPFFindStationOrTileData 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 { /* M /* 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 --- 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 --- 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 --- a/openttd.vcproj +++ b/openttd.vcproj @@ -215,6 +215,9 @@ RelativePath=".\economy.c"> + + 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 --- 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 --- a/player.h +++ b/player.h @@ -248,6 +248,7 @@ static inline RailType GetBestRailtype(c { 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 --- 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(Rail 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(TrackBi 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 --- a/rail_cmd.c +++ b/rail_cmd.c @@ -896,11 +896,13 @@ int32 CmdRemoveSignalTrack(int x, int y, 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, 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 --- 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 --- 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 --- 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 --- 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 --- a/station_cmd.c +++ b/station_cmd.c @@ -1959,6 +1959,8 @@ static void DrawTile_Station(TileInfo *t // 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 --- /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 --- 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 --- a/table/landscape_const.h +++ b/table/landscape_const.h @@ -42,13 +42,6 @@ static const LandscapePredefVar _landsca 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 _landsca 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 _landsca 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 _landsca 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 --- 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 --- a/train_cmd.c +++ b/train_cmd.c @@ -72,6 +72,46 @@ static void TrainCargoChanged(Vehicle* v } /** + * 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. * Note: this needs to be called too for 'wagon chains' (in the depot, without an engine) @@ -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 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 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 FindClosestTra 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 FindClosestTra 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 FindClosestTra 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(c // 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(c 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, 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, 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 Ve 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 --- a/train_gui.c +++ b/train_gui.c @@ -177,7 +177,7 @@ static void engine_drawing_loop(int *x, 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 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 --- a/tunnelbridge_cmd.c +++ b/tunnelbridge_cmd.c @@ -799,9 +799,9 @@ int32 DoConvertTunnelBridgeRail(TileInde // 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(TileIn 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(TileIn 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(TileIn // 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(TileIn 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 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 --- 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 --- 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 --- 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 --- 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(cons * 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(in 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 SetupScrollStuffForReplaceWi 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 DrawEngineArrayInReplaceWind * 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; }
  • m3 bits 0..3 = track type: 0 - conventional railway, 1 - monorail, 2 - maglev +