mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r19056) -Add: [NewGRF] Action 3/2/1 (i.e. new graphics) support for rail types. (To be documented...)
This commit is contained in:
parent
01474412fc
commit
898e879bd9
|
@ -206,6 +206,7 @@ newgrf_house.h
|
||||||
newgrf_industries.h
|
newgrf_industries.h
|
||||||
newgrf_industrytiles.h
|
newgrf_industrytiles.h
|
||||||
newgrf_properties.h
|
newgrf_properties.h
|
||||||
|
newgrf_railtype.h
|
||||||
newgrf_sound.h
|
newgrf_sound.h
|
||||||
newgrf_spritegroup.h
|
newgrf_spritegroup.h
|
||||||
newgrf_station.h
|
newgrf_station.h
|
||||||
|
@ -745,6 +746,7 @@ newgrf_generic.cpp
|
||||||
newgrf_house.cpp
|
newgrf_house.cpp
|
||||||
newgrf_industries.cpp
|
newgrf_industries.cpp
|
||||||
newgrf_industrytiles.cpp
|
newgrf_industrytiles.cpp
|
||||||
|
newgrf_railtype.cpp
|
||||||
newgrf_sound.cpp
|
newgrf_sound.cpp
|
||||||
newgrf_spritegroup.cpp
|
newgrf_spritegroup.cpp
|
||||||
newgrf_station.cpp
|
newgrf_station.cpp
|
||||||
|
|
|
@ -64,6 +64,8 @@
|
||||||
#include "elrail_func.h"
|
#include "elrail_func.h"
|
||||||
#include "engine_base.h"
|
#include "engine_base.h"
|
||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
|
#include "rail.h"
|
||||||
|
#include "newgrf_railtype.h"
|
||||||
|
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
#include "table/elrail_data.h"
|
#include "table/elrail_data.h"
|
||||||
|
@ -165,7 +167,9 @@ static TrackBits MaskWireBits(TileIndex t, TrackBits tracks)
|
||||||
*/
|
*/
|
||||||
static inline SpriteID GetWireBase(TileIndex tile)
|
static inline SpriteID GetWireBase(TileIndex tile)
|
||||||
{
|
{
|
||||||
return SPR_WIRE_BASE;
|
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile));
|
||||||
|
SpriteID wires = GetCustomRailSprite(rti, tile, RTSG_WIRES);
|
||||||
|
return wires == 0 ? SPR_WIRE_BASE : wires;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -173,7 +177,9 @@ static inline SpriteID GetWireBase(TileIndex tile)
|
||||||
*/
|
*/
|
||||||
static inline SpriteID GetPylonBase(TileIndex tile)
|
static inline SpriteID GetPylonBase(TileIndex tile)
|
||||||
{
|
{
|
||||||
return SPR_PYLON_BASE;
|
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile));
|
||||||
|
SpriteID pylons = GetCustomRailSprite(rti, tile, RTSG_PYLONS);
|
||||||
|
return pylons == 0 ? SPR_PYLON_BASE : pylons;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Corrects the tileh for certain tile types. Returns an effective tileh for the track on the tile.
|
/** Corrects the tileh for certain tile types. Returns an effective tileh for the track on the tile.
|
||||||
|
|
|
@ -3037,6 +3037,7 @@ static void NewSpriteGroup(ByteReader *buf)
|
||||||
case GSF_STATION:
|
case GSF_STATION:
|
||||||
case GSF_CANAL:
|
case GSF_CANAL:
|
||||||
case GSF_CARGOS:
|
case GSF_CARGOS:
|
||||||
|
case GSF_RAILTYPES:
|
||||||
{
|
{
|
||||||
byte sprites = _cur_grffile->spriteset_numents;
|
byte sprites = _cur_grffile->spriteset_numents;
|
||||||
byte num_loaded = type;
|
byte num_loaded = type;
|
||||||
|
@ -3519,6 +3520,35 @@ static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
|
||||||
|
{
|
||||||
|
uint8 *railtypes = AllocaM(uint8, idcount);
|
||||||
|
for (uint i = 0; i < idcount; i++) {
|
||||||
|
railtypes[i] = _cur_grffile->railtype_map[buf->ReadByte()];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 cidcount = buf->ReadByte();
|
||||||
|
for (uint c = 0; c < cidcount; c++) {
|
||||||
|
uint8 ctype = buf->ReadByte();
|
||||||
|
uint16 groupid = buf->ReadWord();
|
||||||
|
if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
|
||||||
|
|
||||||
|
if (ctype >= RTSG_END) continue;
|
||||||
|
|
||||||
|
extern RailtypeInfo _railtypes[RAILTYPE_END];
|
||||||
|
for (uint i = 0; i < idcount; i++) {
|
||||||
|
if (railtypes[i] != INVALID_RAILTYPE) {
|
||||||
|
RailtypeInfo *rti = &_railtypes[railtypes[i]];
|
||||||
|
|
||||||
|
rti->group[ctype] = _cur_grffile->spritegroups[groupid];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Railtypes do not use the default group. */
|
||||||
|
buf->ReadWord();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Action 0x03 */
|
/* Action 0x03 */
|
||||||
static void FeatureMapSpriteGroup(ByteReader *buf)
|
static void FeatureMapSpriteGroup(ByteReader *buf)
|
||||||
|
@ -3594,6 +3624,10 @@ static void FeatureMapSpriteGroup(ByteReader *buf)
|
||||||
CargoMapSpriteGroup(buf, idcount);
|
CargoMapSpriteGroup(buf, idcount);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case GSF_RAILTYPES:
|
||||||
|
RailTypeMapSpriteGroup(buf, idcount);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
|
grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
|
||||||
return;
|
return;
|
||||||
|
@ -6446,6 +6480,9 @@ static void AfterLoadGRFs()
|
||||||
/* Load old shore sprites in new position, if they were replaced by ActionA */
|
/* Load old shore sprites in new position, if they were replaced by ActionA */
|
||||||
ActivateOldShore();
|
ActivateOldShore();
|
||||||
|
|
||||||
|
/* Set up custom rail types */
|
||||||
|
InitRailTypes();
|
||||||
|
|
||||||
Engine *e;
|
Engine *e;
|
||||||
FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
|
||||||
if (_gted[e->index].rv_max_speed != 0) {
|
if (_gted[e->index].rv_max_speed != 0) {
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/** @file newgrf_railtype.cpp NewGRF handling of rail types. */
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "openttd.h"
|
||||||
|
#include "variables.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "strings_type.h"
|
||||||
|
#include "rail.h"
|
||||||
|
#include "road_map.h"
|
||||||
|
#include "newgrf.h"
|
||||||
|
#include "newgrf_callbacks.h"
|
||||||
|
#include "newgrf_commons.h"
|
||||||
|
#include "newgrf_railtype.h"
|
||||||
|
#include "newgrf_spritegroup.h"
|
||||||
|
|
||||||
|
static uint32 RailTypeGetRandomBits(const ResolverObject *object)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 RailTypeGetTriggers(const ResolverObject *object)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RailTypeSetTriggers(const ResolverObject *object, int triggers)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 RailTypeGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
|
||||||
|
{
|
||||||
|
TileIndex tile = object->u.routes.tile;
|
||||||
|
|
||||||
|
if (tile == INVALID_TILE) {
|
||||||
|
switch (variable) {
|
||||||
|
case 0x40: return 0;
|
||||||
|
case 0x41: return 0;
|
||||||
|
case 0x42: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (variable) {
|
||||||
|
case 0x40: return GetTerrainType(tile);
|
||||||
|
case 0x41: return 0;
|
||||||
|
case 0x42: return IsLevelCrossingTile(tile) && IsCrossingBarred(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG(grf, 1, "Unhandled rail type tile property 0x%X", variable);
|
||||||
|
|
||||||
|
*available = false;
|
||||||
|
return UINT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const SpriteGroup *RailTypeResolveReal(const ResolverObject *object, const RealSpriteGroup *group)
|
||||||
|
{
|
||||||
|
if (group->num_loading > 0) return group->loading[0];
|
||||||
|
if (group->num_loaded > 0) return group->loaded[0];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void NewRailTypeResolver(ResolverObject *res, TileIndex tile)
|
||||||
|
{
|
||||||
|
res->GetRandomBits = &RailTypeGetRandomBits;
|
||||||
|
res->GetTriggers = &RailTypeGetTriggers;
|
||||||
|
res->SetTriggers = &RailTypeSetTriggers;
|
||||||
|
res->GetVariable = &RailTypeGetVariable;
|
||||||
|
res->ResolveReal = &RailTypeResolveReal;
|
||||||
|
|
||||||
|
res->u.routes.tile = tile;
|
||||||
|
|
||||||
|
res->callback = CBID_NO_CALLBACK;
|
||||||
|
res->callback_param1 = 0;
|
||||||
|
res->callback_param2 = 0;
|
||||||
|
res->last_value = 0;
|
||||||
|
res->trigger = 0;
|
||||||
|
res->reseed = 0;
|
||||||
|
res->count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg)
|
||||||
|
{
|
||||||
|
assert(rtsg < RTSG_END);
|
||||||
|
|
||||||
|
if (rti->group[rtsg] == NULL) return 0;
|
||||||
|
|
||||||
|
const SpriteGroup *group;
|
||||||
|
ResolverObject object;
|
||||||
|
|
||||||
|
NewRailTypeResolver(&object, tile);
|
||||||
|
|
||||||
|
group = SpriteGroup::Resolve(rti->group[rtsg], &object);
|
||||||
|
if (group == NULL || group->GetNumResults() == 0) return 0;
|
||||||
|
|
||||||
|
return group->GetResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile)
|
||||||
|
{
|
||||||
|
/* No rail type table present, return rail type as-is */
|
||||||
|
if (grffile->railtype_max == 0) return railtype;
|
||||||
|
|
||||||
|
/* Look for a matching rail type label in the table */
|
||||||
|
RailTypeLabel label = GetRailTypeInfo(railtype)->label;
|
||||||
|
for (uint i = 0; i < grffile->railtype_max; i++) {
|
||||||
|
if (label == grffile->railtype_list[i]) return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If not found, return as invalid */
|
||||||
|
return 0xFF;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#ifndef NEWGRF_RAILTYPE_H
|
||||||
|
#define NEWGRF_RAILTYPE_H
|
||||||
|
|
||||||
|
#include "rail.h"
|
||||||
|
|
||||||
|
SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg);
|
||||||
|
|
||||||
|
uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile);
|
||||||
|
|
||||||
|
#endif /* NEWGRF_RAILTYPE_H */
|
|
@ -339,6 +339,9 @@ struct ResolverObject {
|
||||||
uint8 count;
|
uint8 count;
|
||||||
uint8 station_size;
|
uint8 station_size;
|
||||||
} generic;
|
} generic;
|
||||||
|
struct {
|
||||||
|
TileIndex tile;
|
||||||
|
} routes;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
uint32 (*GetRandomBits)(const struct ResolverObject*);
|
uint32 (*GetRandomBits)(const struct ResolverObject*);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "newgrf_station.h"
|
#include "newgrf_station.h"
|
||||||
#include "newgrf_spritegroup.h"
|
#include "newgrf_spritegroup.h"
|
||||||
#include "newgrf_sound.h"
|
#include "newgrf_sound.h"
|
||||||
|
#include "newgrf_railtype.h"
|
||||||
#include "town.h"
|
#include "town.h"
|
||||||
#include "newgrf_town.h"
|
#include "newgrf_town.h"
|
||||||
#include "date_func.h"
|
#include "date_func.h"
|
||||||
|
@ -442,7 +443,7 @@ static uint32 StationGetVariable(const ResolverObject *object, byte variable, by
|
||||||
if (!HasBit(_svc.valid, 1)) { _svc.v41 = GetPlatformInfoHelper(tile, true, false, false); SetBit(_svc.valid, 1); }
|
if (!HasBit(_svc.valid, 1)) { _svc.v41 = GetPlatformInfoHelper(tile, true, false, false); SetBit(_svc.valid, 1); }
|
||||||
return _svc.v41;
|
return _svc.v41;
|
||||||
|
|
||||||
case 0x42: return GetTerrainType(tile) | (GetRailType(tile) << 8);
|
case 0x42: return GetTerrainType(tile) | (GetReverseRailTypeTranslation(GetRailType(tile), object->u.station.statspec->grffile) << 8);
|
||||||
case 0x43: return st->owner; // Station owner
|
case 0x43: return st->owner; // Station owner
|
||||||
case 0x44: return HasStationReservation(tile) ? 7 : 4; // PBS status
|
case 0x44: return HasStationReservation(tile) ? 7 : 4; // PBS status
|
||||||
case 0x45:
|
case 0x45:
|
||||||
|
|
63
src/rail.h
63
src/rail.h
|
@ -30,6 +30,54 @@ enum RailTypeFlags {
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_AS_BIT_SET(RailTypeFlags);
|
DECLARE_ENUM_AS_BIT_SET(RailTypeFlags);
|
||||||
|
|
||||||
|
struct SpriteGroup;
|
||||||
|
|
||||||
|
enum RailTypeSpriteGroup {
|
||||||
|
RTSG_CURSORS, ///< Cursor and toolbar icon images
|
||||||
|
RTSG_OVERLAY, ///< Images for overlaying track
|
||||||
|
RTSG_GROUND, ///< Main group of ground images
|
||||||
|
RTSG_TUNNEL, ///< Main group of ground images for snow or desert
|
||||||
|
RTSG_WIRES, ///< Catenary wires
|
||||||
|
RTSG_PYLONS, ///< Catenary pylons
|
||||||
|
RTSG_BRIDGE, ///< Bridge surface images
|
||||||
|
RTSG_CROSSING, ///< Level crossing overlay images
|
||||||
|
RTSG_DEPOT, ///< Depot images
|
||||||
|
RTSG_FENCES, ///< Fence images
|
||||||
|
RTSG_END,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offsets for sprites within an overlay/underlay set.
|
||||||
|
* These are the same for overlay and underlay sprites.
|
||||||
|
*/
|
||||||
|
enum RailTrackOffset {
|
||||||
|
RTO_X, ///< Piece of rail in X direction
|
||||||
|
RTO_Y, ///< Piece of rail in Y direction
|
||||||
|
RTO_N, ///< Piece of rail in northern corner
|
||||||
|
RTO_S, ///< Piece of rail in southern corner
|
||||||
|
RTO_E, ///< Piece of rail in eastern corner
|
||||||
|
RTO_W, ///< Piece of rail in western corner
|
||||||
|
RTO_SLOPE_NE, ///< Piece of rail on slope with north-east raised
|
||||||
|
RTO_SLOPE_SE, ///< Piece of rail on slope with south-east raised
|
||||||
|
RTO_SLOPE_SW, ///< Piece of rail on slope with south-west raised
|
||||||
|
RTO_SLOPE_NW, ///< Piece of rail on slope with north-west raised
|
||||||
|
RTO_CROSSING_XY, ///< Crossing of X and Y rail, with ballast
|
||||||
|
RTO_JUNCTION_SW, ///< Ballast for junction 'pointing' SW
|
||||||
|
RTO_JUNCTION_NE, ///< Ballast for junction 'pointing' NE
|
||||||
|
RTO_JUNCTION_SE, ///< Ballast for junction 'pointing' SE
|
||||||
|
RTO_JUNCTION_NW, ///< Ballast for junction 'pointing' NW
|
||||||
|
RTO_JUNCTION_NSEW,///< Ballast for full junction
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offsets for spries within a bridge surface overlay set.
|
||||||
|
*/
|
||||||
|
enum RailTrackBridgeOffset {
|
||||||
|
RTBO_X, ///< Piece of rail in X direction
|
||||||
|
RTBO_Y, ///< Piece of rail in Y direction
|
||||||
|
RTBO_SLOPE, ///< Sloped rail pieces, in order NE, SE, SW, NW
|
||||||
|
};
|
||||||
|
|
||||||
/** Offsets from base sprite for fence sprites. These are in the order of
|
/** Offsets from base sprite for fence sprites. These are in the order of
|
||||||
* the sprites in the original data files.
|
* the sprites in the original data files.
|
||||||
*/
|
*/
|
||||||
|
@ -154,6 +202,16 @@ struct RailtypeInfo {
|
||||||
* Unique 32 bit rail type identifier
|
* Unique 32 bit rail type identifier
|
||||||
*/
|
*/
|
||||||
RailTypeLabel label;
|
RailTypeLabel label;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sprite groups for resolving sprites
|
||||||
|
*/
|
||||||
|
const SpriteGroup *group[RTSG_END];
|
||||||
|
|
||||||
|
inline bool UsesOverlay() const
|
||||||
|
{
|
||||||
|
return this->group[RTSG_GROUND] != NULL;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -286,6 +344,11 @@ RailType GetRailTypeByLabel(RailTypeLabel label);
|
||||||
*/
|
*/
|
||||||
void ResetRailTypes();
|
void ResetRailTypes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve sprites of custom rail types
|
||||||
|
*/
|
||||||
|
void InitRailTypes();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a new rail type label
|
* Allocate a new rail type label
|
||||||
*/
|
*/
|
||||||
|
|
256
src/rail_cmd.cpp
256
src/rail_cmd.cpp
|
@ -19,6 +19,8 @@
|
||||||
#include "pathfinder/yapf/yapf_cache.h"
|
#include "pathfinder/yapf/yapf_cache.h"
|
||||||
#include "newgrf_engine.h"
|
#include "newgrf_engine.h"
|
||||||
#include "landscape_type.h"
|
#include "landscape_type.h"
|
||||||
|
#include "newgrf_railtype.h"
|
||||||
|
#include "newgrf_commons.h"
|
||||||
#include "train.h"
|
#include "train.h"
|
||||||
#include "variables.h"
|
#include "variables.h"
|
||||||
#include "autoslope.h"
|
#include "autoslope.h"
|
||||||
|
@ -52,6 +54,37 @@ void ResetRailTypes()
|
||||||
memcpy(_railtypes, _original_railtypes, sizeof(_original_railtypes));
|
memcpy(_railtypes, _original_railtypes, sizeof(_original_railtypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResolveRailTypeGUISprites(RailtypeInfo *rti)
|
||||||
|
{
|
||||||
|
SpriteID cursors_base = GetCustomRailSprite(rti, INVALID_TILE, RTSG_CURSORS);
|
||||||
|
if (cursors_base != 0) {
|
||||||
|
rti->gui_sprites.build_ns_rail = cursors_base + 0;
|
||||||
|
rti->gui_sprites.build_x_rail = cursors_base + 1;
|
||||||
|
rti->gui_sprites.build_ew_rail = cursors_base + 2;
|
||||||
|
rti->gui_sprites.build_y_rail = cursors_base + 3;
|
||||||
|
rti->gui_sprites.auto_rail = cursors_base + 4;
|
||||||
|
rti->gui_sprites.build_depot = cursors_base + 5;
|
||||||
|
rti->gui_sprites.build_tunnel = cursors_base + 6;
|
||||||
|
rti->gui_sprites.convert_rail = cursors_base + 7;
|
||||||
|
rti->cursor.rail_ns = cursors_base + 8;
|
||||||
|
rti->cursor.rail_swne = cursors_base + 9;
|
||||||
|
rti->cursor.rail_ew = cursors_base + 10;
|
||||||
|
rti->cursor.rail_nwse = cursors_base + 11;
|
||||||
|
rti->cursor.autorail = cursors_base + 12;
|
||||||
|
rti->cursor.depot = cursors_base + 13;
|
||||||
|
rti->cursor.tunnel = cursors_base + 14;
|
||||||
|
rti->cursor.convert = cursors_base + 15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitRailTypes()
|
||||||
|
{
|
||||||
|
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
||||||
|
RailtypeInfo *rti = &_railtypes[rt];
|
||||||
|
ResolveRailTypeGUISprites(rti);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RailType AllocateRailType(RailTypeLabel label)
|
RailType AllocateRailType(RailTypeLabel label)
|
||||||
{
|
{
|
||||||
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
||||||
|
@ -1709,10 +1742,11 @@ static void DrawTrackFence_WE_2(const TileInfo *ti, SpriteID base_image)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DrawTrackDetails(const TileInfo *ti)
|
static void DrawTrackDetails(const TileInfo *ti, const RailtypeInfo *rti)
|
||||||
{
|
{
|
||||||
/* Base sprite for track fences. */
|
/* Base sprite for track fences. */
|
||||||
SpriteID base_image = SPR_TRACK_FENCE_FLAT_X;
|
SpriteID base_image = GetCustomRailSprite(rti, ti->tile, RTSG_FENCES);
|
||||||
|
if (base_image == 0) base_image = SPR_TRACK_FENCE_FLAT_X;
|
||||||
|
|
||||||
switch (GetRailGroundType(ti->tile)) {
|
switch (GetRailGroundType(ti->tile)) {
|
||||||
case RAIL_GROUND_FENCE_NW: DrawTrackFence_NW(ti, base_image); break;
|
case RAIL_GROUND_FENCE_NW: DrawTrackFence_NW(ti, base_image); break;
|
||||||
|
@ -1747,6 +1781,162 @@ static void DrawTrackDetails(const TileInfo *ti)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SubSprite for drawing the track halftile of 'three-corners-raised'-sloped rail sprites. */
|
||||||
|
static const int INF = 1000; // big number compared to tilesprite size
|
||||||
|
static const SubSprite _halftile_sub_sprite[4] = {
|
||||||
|
{ -INF , -INF , 32 - 33, INF }, // CORNER_W, clip 33 pixels from right
|
||||||
|
{ -INF , 0 + 7, INF , INF }, // CORNER_S, clip 7 pixels from top
|
||||||
|
{ -31 + 33, -INF , INF , INF }, // CORNER_E, clip 33 pixels from left
|
||||||
|
{ -INF , -INF , INF , 30 - 23 } // CORNER_N, clip 23 pixels from bottom
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void DrawTrackSprite(SpriteID sprite, PaletteID pal, const TileInfo *ti, Slope s)
|
||||||
|
{
|
||||||
|
DrawGroundSprite(sprite, pal, NULL, 0, (ti->tileh & s) ? -8 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawTrackBitsOverlay(TileInfo *ti, TrackBits track, const RailtypeInfo *rti)
|
||||||
|
{
|
||||||
|
RailGroundType rgt = GetRailGroundType(ti->tile);
|
||||||
|
Foundation f = GetRailFoundation(ti->tileh, track);
|
||||||
|
Corner halftile_corner = CORNER_INVALID;
|
||||||
|
|
||||||
|
if (IsNonContinuousFoundation(f)) {
|
||||||
|
/* Save halftile corner */
|
||||||
|
halftile_corner = (f == FOUNDATION_STEEP_BOTH ? GetHighestSlopeCorner(ti->tileh) : GetHalftileFoundationCorner(f));
|
||||||
|
/* Draw lower part first */
|
||||||
|
track &= ~CornerToTrackBits(halftile_corner);
|
||||||
|
f = (f == FOUNDATION_STEEP_BOTH ? FOUNDATION_STEEP_LOWER : FOUNDATION_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawFoundation(ti, f);
|
||||||
|
/* DrawFoundation modifies ti */
|
||||||
|
|
||||||
|
/* Draw ground */
|
||||||
|
if (track == TRACK_BIT_NONE && rgt == RAIL_GROUND_WATER) {
|
||||||
|
if (IsSteepSlope(ti->tileh)) {
|
||||||
|
DrawShoreTile(ti->tileh);
|
||||||
|
} else {
|
||||||
|
DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SpriteID image;
|
||||||
|
|
||||||
|
switch (rgt) {
|
||||||
|
case RAIL_GROUND_BARREN: image = SPR_FLAT_BARE_LAND; break;
|
||||||
|
case RAIL_GROUND_ICE_DESERT: image = SPR_FLAT_SNOW_DESERT_TILE; break;
|
||||||
|
default: image = SPR_FLAT_GRASS_TILE; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
image += _tileh_to_sprite[ti->tileh];
|
||||||
|
|
||||||
|
DrawGroundSprite(image, PAL_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
|
||||||
|
SpriteID ground = GetCustomRailSprite(rti, ti->tile, RTSG_GROUND);
|
||||||
|
TrackBits pbs = _settings_client.gui.show_track_reservation ? GetRailReservationTrackBits(ti->tile) : TRACK_BIT_NONE;
|
||||||
|
|
||||||
|
if (track == TRACK_BIT_NONE) {
|
||||||
|
/* Half-tile foundation, no track here? */
|
||||||
|
} else if (ti->tileh == SLOPE_NW && track == TRACK_BIT_Y) {
|
||||||
|
DrawGroundSprite(ground + RTO_SLOPE_NW, PAL_NONE);
|
||||||
|
if (pbs != TRACK_BIT_NONE) DrawGroundSprite(overlay + 9, PALETTE_CRASH);
|
||||||
|
} else if (ti->tileh == SLOPE_NE && track == TRACK_BIT_X) {
|
||||||
|
DrawGroundSprite(ground + RTO_SLOPE_NE, PAL_NONE);
|
||||||
|
if (pbs != TRACK_BIT_NONE) DrawGroundSprite(overlay + 6, PALETTE_CRASH);
|
||||||
|
} else if (ti->tileh == SLOPE_SE && track == TRACK_BIT_Y) {
|
||||||
|
DrawGroundSprite(ground + RTO_SLOPE_SE, PAL_NONE);
|
||||||
|
if (pbs != TRACK_BIT_NONE) DrawGroundSprite(overlay + 7, PALETTE_CRASH);
|
||||||
|
} else if (ti->tileh == SLOPE_SW && track == TRACK_BIT_X) {
|
||||||
|
DrawGroundSprite(ground + RTO_SLOPE_SW, PAL_NONE);
|
||||||
|
if (pbs != TRACK_BIT_NONE) DrawGroundSprite(overlay + 8, PALETTE_CRASH);
|
||||||
|
} else {
|
||||||
|
switch (track) {
|
||||||
|
/* Draw single ground sprite when not overlapping. No track overlay
|
||||||
|
* is necessary for these sprites. */
|
||||||
|
case TRACK_BIT_X: DrawGroundSprite(ground + RTO_X, PAL_NONE); break;
|
||||||
|
case TRACK_BIT_Y: DrawGroundSprite(ground + RTO_Y, PAL_NONE); break;
|
||||||
|
case TRACK_BIT_UPPER: DrawTrackSprite(ground + RTO_N, PAL_NONE, ti, SLOPE_N); break;
|
||||||
|
case TRACK_BIT_LOWER: DrawTrackSprite(ground + RTO_S, PAL_NONE, ti, SLOPE_S); break;
|
||||||
|
case TRACK_BIT_RIGHT: DrawTrackSprite(ground + RTO_E, PAL_NONE, ti, SLOPE_E); break;
|
||||||
|
case TRACK_BIT_LEFT: DrawTrackSprite(ground + RTO_W, PAL_NONE, ti, SLOPE_W); break;
|
||||||
|
case TRACK_BIT_CROSS: DrawGroundSprite(ground + RTO_CROSSING_XY, PAL_NONE); break;
|
||||||
|
case TRACK_BIT_HORZ: DrawTrackSprite(ground + RTO_N, PAL_NONE, ti, SLOPE_N);
|
||||||
|
DrawTrackSprite(ground + RTO_S, PAL_NONE, ti, SLOPE_S); break;
|
||||||
|
case TRACK_BIT_VERT: DrawTrackSprite(ground + RTO_E, PAL_NONE, ti, SLOPE_E);
|
||||||
|
DrawTrackSprite(ground + RTO_W, PAL_NONE, ti, SLOPE_W); break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* We're drawing a junction tile */
|
||||||
|
if ((track & TRACK_BIT_3WAY_NE) == 0) {
|
||||||
|
DrawGroundSprite(ground + RTO_JUNCTION_SW, PAL_NONE);
|
||||||
|
} else if ((track & TRACK_BIT_3WAY_SW) == 0) {
|
||||||
|
DrawGroundSprite(ground + RTO_JUNCTION_NE, PAL_NONE);
|
||||||
|
} else if ((track & TRACK_BIT_3WAY_NW) == 0) {
|
||||||
|
DrawGroundSprite(ground + RTO_JUNCTION_SE, PAL_NONE);
|
||||||
|
} else if ((track & TRACK_BIT_3WAY_SE) == 0) {
|
||||||
|
DrawGroundSprite(ground + RTO_JUNCTION_NW, PAL_NONE);
|
||||||
|
} else {
|
||||||
|
DrawGroundSprite(ground + RTO_JUNCTION_NSEW, PAL_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mask out PBS bits as we shall draw them afterwards anyway. */
|
||||||
|
track &= ~pbs;
|
||||||
|
|
||||||
|
/* Draw regular track bits */
|
||||||
|
if (track & TRACK_BIT_X) DrawGroundSprite(overlay + RTO_X, PAL_NONE);
|
||||||
|
if (track & TRACK_BIT_Y) DrawGroundSprite(overlay + RTO_Y, PAL_NONE);
|
||||||
|
if (track & TRACK_BIT_UPPER) DrawGroundSprite(overlay + RTO_N, PAL_NONE);
|
||||||
|
if (track & TRACK_BIT_LOWER) DrawGroundSprite(overlay + RTO_S, PAL_NONE);
|
||||||
|
if (track & TRACK_BIT_RIGHT) DrawGroundSprite(overlay + RTO_E, PAL_NONE);
|
||||||
|
if (track & TRACK_BIT_LEFT) DrawGroundSprite(overlay + RTO_W, PAL_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw reserved track bits */
|
||||||
|
if (pbs & TRACK_BIT_X) DrawGroundSprite(overlay + RTO_X, PALETTE_CRASH);
|
||||||
|
if (pbs & TRACK_BIT_Y) DrawGroundSprite(overlay + RTO_Y, PALETTE_CRASH);
|
||||||
|
if (pbs & TRACK_BIT_UPPER) DrawTrackSprite(overlay + RTO_N, PALETTE_CRASH, ti, SLOPE_N);
|
||||||
|
if (pbs & TRACK_BIT_LOWER) DrawTrackSprite(overlay + RTO_S, PALETTE_CRASH, ti, SLOPE_S);
|
||||||
|
if (pbs & TRACK_BIT_RIGHT) DrawTrackSprite(overlay + RTO_E, PALETTE_CRASH, ti, SLOPE_E);
|
||||||
|
if (pbs & TRACK_BIT_LEFT) DrawTrackSprite(overlay + RTO_W, PALETTE_CRASH, ti, SLOPE_W);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsValidCorner(halftile_corner)) {
|
||||||
|
DrawFoundation(ti, HalftileFoundation(halftile_corner));
|
||||||
|
|
||||||
|
/* Draw higher halftile-overlay: Use the sloped sprites with three corners raised. They probably best fit the lightning. */
|
||||||
|
Slope fake_slope = SlopeWithThreeCornersRaised(OppositeCorner(halftile_corner));
|
||||||
|
|
||||||
|
SpriteID image;
|
||||||
|
switch (rgt) {
|
||||||
|
case RAIL_GROUND_BARREN: image = SPR_FLAT_BARE_LAND; break;
|
||||||
|
case RAIL_GROUND_ICE_DESERT:
|
||||||
|
case RAIL_GROUND_HALF_SNOW: image = SPR_FLAT_SNOW_DESERT_TILE; break;
|
||||||
|
default: image = SPR_FLAT_GRASS_TILE; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
image += _tileh_to_sprite[fake_slope];
|
||||||
|
|
||||||
|
DrawGroundSprite(image, PAL_NONE, &(_halftile_sub_sprite[halftile_corner]));
|
||||||
|
|
||||||
|
track = CornerToTrackBits(halftile_corner);
|
||||||
|
|
||||||
|
int offset;
|
||||||
|
switch (track) {
|
||||||
|
default: NOT_REACHED();
|
||||||
|
case TRACK_BIT_UPPER: offset = RTO_N; break;
|
||||||
|
case TRACK_BIT_LOWER: offset = RTO_S; break;
|
||||||
|
case TRACK_BIT_RIGHT: offset = RTO_E; break;
|
||||||
|
case TRACK_BIT_LEFT: offset = RTO_W; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawTrackSprite(ground + offset, PAL_NONE, ti, fake_slope);
|
||||||
|
if (HasReservedTracks(ti->tile, track)) {
|
||||||
|
DrawTrackSprite(overlay + offset, PALETTE_CRASH, ti, fake_slope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw ground sprite and track bits
|
* Draw ground sprite and track bits
|
||||||
|
@ -1755,16 +1945,13 @@ static void DrawTrackDetails(const TileInfo *ti)
|
||||||
*/
|
*/
|
||||||
static void DrawTrackBits(TileInfo *ti, TrackBits track)
|
static void DrawTrackBits(TileInfo *ti, TrackBits track)
|
||||||
{
|
{
|
||||||
/* SubSprite for drawing the track halftile of 'three-corners-raised'-sloped rail sprites. */
|
|
||||||
static const int INF = 1000; // big number compared to tilesprite size
|
|
||||||
static const SubSprite _halftile_sub_sprite[4] = {
|
|
||||||
{ -INF , -INF , 32 - 33, INF }, // CORNER_W, clip 33 pixels from right
|
|
||||||
{ -INF , 0 + 7, INF , INF }, // CORNER_S, clip 7 pixels from top
|
|
||||||
{ -31 + 33, -INF , INF , INF }, // CORNER_E, clip 33 pixels from left
|
|
||||||
{ -INF , -INF , INF , 30 - 23 } // CORNER_N, clip 23 pixels from bottom
|
|
||||||
};
|
|
||||||
|
|
||||||
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
||||||
|
|
||||||
|
if (rti->UsesOverlay()) {
|
||||||
|
DrawTrackBitsOverlay(ti, track, rti);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
RailGroundType rgt = GetRailGroundType(ti->tile);
|
RailGroundType rgt = GetRailGroundType(ti->tile);
|
||||||
Foundation f = GetRailFoundation(ti->tileh, track);
|
Foundation f = GetRailFoundation(ti->tileh, track);
|
||||||
Corner halftile_corner = CORNER_INVALID;
|
Corner halftile_corner = CORNER_INVALID;
|
||||||
|
@ -1960,7 +2147,7 @@ static void DrawTile_Track(TileInfo *ti)
|
||||||
|
|
||||||
DrawTrackBits(ti, rails);
|
DrawTrackBits(ti, rails);
|
||||||
|
|
||||||
if (HasBit(_display_opt, DO_FULL_DETAIL)) DrawTrackDetails(ti);
|
if (HasBit(_display_opt, DO_FULL_DETAIL)) DrawTrackDetails(ti, rti);
|
||||||
|
|
||||||
if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti);
|
if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti);
|
||||||
|
|
||||||
|
@ -1969,6 +2156,7 @@ static void DrawTile_Track(TileInfo *ti)
|
||||||
/* draw depot */
|
/* draw depot */
|
||||||
const DrawTileSprites *dts;
|
const DrawTileSprites *dts;
|
||||||
PaletteID pal = PAL_NONE;
|
PaletteID pal = PAL_NONE;
|
||||||
|
SpriteID relocation;
|
||||||
|
|
||||||
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
|
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
|
||||||
|
|
||||||
|
@ -1979,8 +2167,12 @@ static void DrawTile_Track(TileInfo *ti)
|
||||||
dts = &_depot_gfx_table[GetRailDepotDirection(ti->tile)];
|
dts = &_depot_gfx_table[GetRailDepotDirection(ti->tile)];
|
||||||
}
|
}
|
||||||
|
|
||||||
image = dts->ground.sprite;
|
if (rti->UsesOverlay()) {
|
||||||
if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset;
|
image = SPR_FLAT_GRASS_TILE;
|
||||||
|
} else {
|
||||||
|
image = dts->ground.sprite;
|
||||||
|
if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset;
|
||||||
|
}
|
||||||
|
|
||||||
/* adjust ground tile for desert
|
/* adjust ground tile for desert
|
||||||
* don't adjust for snow, because snow in depots looks weird */
|
* don't adjust for snow, because snow in depots looks weird */
|
||||||
|
@ -1994,19 +2186,43 @@ static void DrawTile_Track(TileInfo *ti)
|
||||||
|
|
||||||
DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, _drawtile_track_palette));
|
DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, _drawtile_track_palette));
|
||||||
|
|
||||||
/* PBS debugging, draw reserved tracks darker */
|
if (rti->UsesOverlay()) {
|
||||||
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile)) {
|
SpriteID ground = GetCustomRailSprite(rti, ti->tile, RTSG_GROUND);
|
||||||
|
|
||||||
switch (GetRailDepotDirection(ti->tile)) {
|
switch (GetRailDepotDirection(ti->tile)) {
|
||||||
case DIAGDIR_SW: DrawGroundSprite(rti->base_sprites.single_x, PALETTE_CRASH); break;
|
case DIAGDIR_SW: DrawGroundSprite(ground + RTO_X, PAL_NONE); break;
|
||||||
case DIAGDIR_SE: DrawGroundSprite(rti->base_sprites.single_y, PALETTE_CRASH); break;
|
case DIAGDIR_SE: DrawGroundSprite(ground + RTO_Y, PAL_NONE); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile)) {
|
||||||
|
SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
|
||||||
|
|
||||||
|
switch (GetRailDepotDirection(ti->tile)) {
|
||||||
|
case DIAGDIR_SW: DrawGroundSprite(overlay + RTO_X, PALETTE_CRASH); break;
|
||||||
|
case DIAGDIR_SE: DrawGroundSprite(overlay + RTO_Y, PALETTE_CRASH); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
relocation = GetCustomRailSprite(rti, ti->tile, RTSG_DEPOT);
|
||||||
|
relocation -= SPR_RAIL_DEPOT_SE_1;
|
||||||
|
} else {
|
||||||
|
/* PBS debugging, draw reserved tracks darker */
|
||||||
|
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile)) {
|
||||||
|
switch (GetRailDepotDirection(ti->tile)) {
|
||||||
|
case DIAGDIR_SW: DrawGroundSprite(rti->base_sprites.single_y, PALETTE_CRASH); break;
|
||||||
|
case DIAGDIR_SE: DrawGroundSprite(rti->base_sprites.single_x, PALETTE_CRASH); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
relocation = rti->total_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti);
|
if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti);
|
||||||
|
|
||||||
/* No NewGRF depots, so no relocation */
|
DrawRailTileSeq(ti, dts, TO_BUILDINGS, relocation, 0, _drawtile_track_palette);
|
||||||
DrawRailTileSeq(ti, dts, TO_BUILDINGS, rti->total_offset, 0, _drawtile_track_palette);
|
|
||||||
}
|
}
|
||||||
DrawBridgeMiddle(ti);
|
DrawBridgeMiddle(ti);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "town.h"
|
#include "town.h"
|
||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
#include "core/random_func.hpp"
|
#include "core/random_func.hpp"
|
||||||
|
#include "newgrf_railtype.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
|
||||||
|
@ -1164,7 +1165,36 @@ static void DrawTile_Road(TileInfo *ti)
|
||||||
case ROAD_TILE_CROSSING: {
|
case ROAD_TILE_CROSSING: {
|
||||||
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
|
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
|
||||||
|
|
||||||
SpriteID image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.crossing;
|
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
||||||
|
|
||||||
|
if (rti->UsesOverlay()) {
|
||||||
|
Axis axis = GetCrossingRailAxis(ti->tile);
|
||||||
|
SpriteID road = SPR_ROAD_Y + axis;
|
||||||
|
PaletteID pal = PAL_NONE;
|
||||||
|
|
||||||
|
Roadside roadside = GetRoadside(ti->tile);
|
||||||
|
|
||||||
|
if (AlwaysDrawUnpavedRoads(ti->tile, roadside)) {
|
||||||
|
road += 19;
|
||||||
|
} else {
|
||||||
|
switch (roadside) {
|
||||||
|
case ROADSIDE_BARREN: pal = PALETTE_TO_BARE_LAND; break;
|
||||||
|
case ROADSIDE_GRASS: break;
|
||||||
|
default: road -= 19; break; // Paved
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawGroundSprite(road, pal);
|
||||||
|
|
||||||
|
SpriteID rail = GetCustomRailSprite(rti, ti->tile, RTSG_CROSSING) + axis;
|
||||||
|
DrawGroundSprite(rail, PAL_NONE);
|
||||||
|
DrawRailTileSeq(ti, &_crossing_layout, TO_CATENARY, rail, 0, PAL_NONE);
|
||||||
|
|
||||||
|
if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpriteID image = rti->base_sprites.crossing;
|
||||||
PaletteID pal = PAL_NONE;
|
PaletteID pal = PAL_NONE;
|
||||||
|
|
||||||
if (GetCrossingRoadAxis(ti->tile) == AXIS_X) image++;
|
if (GetCrossingRoadAxis(ti->tile) == AXIS_X) image++;
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "elrail_func.h"
|
#include "elrail_func.h"
|
||||||
#include "station_base.h"
|
#include "station_base.h"
|
||||||
#include "roadstop_base.h"
|
#include "roadstop_base.h"
|
||||||
|
#include "newgrf_railtype.h"
|
||||||
#include "waypoint_base.h"
|
#include "waypoint_base.h"
|
||||||
#include "waypoint_func.h"
|
#include "waypoint_func.h"
|
||||||
#include "pbs.h"
|
#include "pbs.h"
|
||||||
|
@ -2303,12 +2304,13 @@ static void DrawTile_Station(TileInfo *ti)
|
||||||
RoadTypes roadtypes;
|
RoadTypes roadtypes;
|
||||||
int32 total_offset;
|
int32 total_offset;
|
||||||
int32 custom_ground_offset;
|
int32 custom_ground_offset;
|
||||||
|
const RailtypeInfo *rti = NULL;
|
||||||
uint32 relocation = 0;
|
uint32 relocation = 0;
|
||||||
const BaseStation *st = NULL;
|
const BaseStation *st = NULL;
|
||||||
const StationSpec *statspec = NULL;
|
const StationSpec *statspec = NULL;
|
||||||
|
|
||||||
if (HasStationRail(ti->tile)) {
|
if (HasStationRail(ti->tile)) {
|
||||||
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
rti = GetRailTypeInfo(GetRailType(ti->tile));
|
||||||
roadtypes = ROADTYPES_NONE;
|
roadtypes = ROADTYPES_NONE;
|
||||||
total_offset = rti->total_offset;
|
total_offset = rti->total_offset;
|
||||||
custom_ground_offset = rti->custom_ground_offset;
|
custom_ground_offset = rti->custom_ground_offset;
|
||||||
|
@ -2446,18 +2448,29 @@ static void DrawTile_Station(TileInfo *ti)
|
||||||
} else {
|
} else {
|
||||||
SpriteID image = t->ground.sprite;
|
SpriteID image = t->ground.sprite;
|
||||||
PaletteID pal = t->ground.pal;
|
PaletteID pal = t->ground.pal;
|
||||||
if (HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE)) {
|
if (rti != NULL && rti->UsesOverlay() && (image == SPR_RAIL_TRACK_X || image == SPR_RAIL_TRACK_Y)) {
|
||||||
image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
|
SpriteID ground = GetCustomRailSprite(rti, ti->tile, RTSG_GROUND);
|
||||||
image += custom_ground_offset;
|
DrawGroundSprite(SPR_FLAT_GRASS_TILE, PAL_NONE);
|
||||||
} else {
|
DrawGroundSprite(ground + (image == SPR_RAIL_TRACK_X ? RTO_X : RTO_Y), PAL_NONE);
|
||||||
image += total_offset;
|
|
||||||
}
|
|
||||||
DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, palette));
|
|
||||||
|
|
||||||
/* PBS debugging, draw reserved tracks darker */
|
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasStationReservation(ti->tile)) {
|
||||||
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasStationRail(ti->tile) && HasStationReservation(ti->tile)) {
|
SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
|
||||||
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
DrawGroundSprite(overlay + (image == SPR_RAIL_TRACK_X ? RTO_X : RTO_Y), PALETTE_CRASH);
|
||||||
DrawGroundSprite(GetRailStationAxis(ti->tile) == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH);
|
}
|
||||||
|
} else {
|
||||||
|
if (HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE)) {
|
||||||
|
image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
|
||||||
|
image += custom_ground_offset;
|
||||||
|
} else {
|
||||||
|
image += total_offset;
|
||||||
|
}
|
||||||
|
DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, palette));
|
||||||
|
|
||||||
|
/* PBS debugging, draw reserved tracks darker */
|
||||||
|
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasStationRail(ti->tile) && HasStationReservation(ti->tile)) {
|
||||||
|
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
||||||
|
DrawGroundSprite(GetRailStationAxis(ti->tile) == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2482,14 +2495,21 @@ void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, Ro
|
||||||
int32 total_offset = 0;
|
int32 total_offset = 0;
|
||||||
PaletteID pal = COMPANY_SPRITE_COLOUR(_local_company);
|
PaletteID pal = COMPANY_SPRITE_COLOUR(_local_company);
|
||||||
const DrawTileSprites *t = &_station_display_datas[st][image];
|
const DrawTileSprites *t = &_station_display_datas[st][image];
|
||||||
|
const RailtypeInfo *rti = NULL;
|
||||||
|
|
||||||
if (railtype != INVALID_RAILTYPE) {
|
if (railtype != INVALID_RAILTYPE) {
|
||||||
const RailtypeInfo *rti = GetRailTypeInfo(railtype);
|
rti = GetRailTypeInfo(railtype);
|
||||||
total_offset = rti->total_offset;
|
total_offset = rti->total_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpriteID img = t->ground.sprite;
|
SpriteID img = t->ground.sprite;
|
||||||
DrawSprite(img + total_offset, HasBit(img, PALETTE_MODIFIER_COLOUR) ? pal : PAL_NONE, x, y);
|
if ((img == SPR_RAIL_TRACK_X || img == SPR_RAIL_TRACK_Y) && rti->UsesOverlay()) {
|
||||||
|
SpriteID ground = GetCustomRailSprite(rti, INVALID_TILE, RTSG_GROUND);
|
||||||
|
DrawSprite(SPR_FLAT_GRASS_TILE, PAL_NONE, x, y);
|
||||||
|
DrawSprite(ground + (img == SPR_RAIL_TRACK_X ? RTO_X : RTO_Y), PAL_NONE, x, y);
|
||||||
|
} else {
|
||||||
|
DrawSprite(img + total_offset, HasBit(img, PALETTE_MODIFIER_COLOUR) ? pal : PAL_NONE, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
if (roadtype == ROADTYPE_TRAM) {
|
if (roadtype == ROADTYPE_TRAM) {
|
||||||
DrawSprite(SPR_TRAMWAY_TRAM + (t->ground.sprite == SPR_ROAD_PAVED_STRAIGHT_X ? 1 : 0), PAL_NONE, x, y);
|
DrawSprite(SPR_TRAMWAY_TRAM + (t->ground.sprite == SPR_ROAD_PAVED_STRAIGHT_X ? 1 : 0), PAL_NONE, x, y);
|
||||||
|
|
|
@ -89,6 +89,8 @@ static const RailtypeInfo _original_railtypes[] = {
|
||||||
|
|
||||||
/* rail type label */
|
/* rail type label */
|
||||||
'RAIL',
|
'RAIL',
|
||||||
|
|
||||||
|
{ NULL },
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Electrified railway */
|
/** Electrified railway */
|
||||||
|
@ -167,6 +169,8 @@ static const RailtypeInfo _original_railtypes[] = {
|
||||||
|
|
||||||
/* rail type label */
|
/* rail type label */
|
||||||
'ELRL',
|
'ELRL',
|
||||||
|
|
||||||
|
{ NULL },
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Monorail */
|
/** Monorail */
|
||||||
|
@ -241,6 +245,8 @@ static const RailtypeInfo _original_railtypes[] = {
|
||||||
|
|
||||||
/* rail type label */
|
/* rail type label */
|
||||||
'MONO',
|
'MONO',
|
||||||
|
|
||||||
|
{ NULL },
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Maglev */
|
/** Maglev */
|
||||||
|
@ -315,6 +321,8 @@ static const RailtypeInfo _original_railtypes[] = {
|
||||||
|
|
||||||
/* rail type label */
|
/* rail type label */
|
||||||
'MGLV',
|
'MGLV',
|
||||||
|
|
||||||
|
{ NULL },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,20 @@ static const DrawTileSprites _tram_depot[] = {
|
||||||
{ {0xA4A, PAL_NONE}, _tram_depot_NW }
|
{ {0xA4A, PAL_NONE}, _tram_depot_NW }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Sprite layout for level crossings. The SpriteIDs are actually offsets
|
||||||
|
* from the base SpriteID returned from the NewGRF sprite resolver. */
|
||||||
|
static const DrawTileSeqStruct _crossing_layout_ALL[] = {
|
||||||
|
TILE_SEQ_LINE(2, PAL_NONE, 0, 0, 3, 3)
|
||||||
|
TILE_SEQ_LINE(4, PAL_NONE, 0, 13, 3, 3)
|
||||||
|
TILE_SEQ_LINE(6, PAL_NONE, 13, 0, 3, 3)
|
||||||
|
TILE_SEQ_LINE(8, PAL_NONE, 13, 13, 3, 3)
|
||||||
|
TILE_SEQ_END()
|
||||||
|
};
|
||||||
|
|
||||||
|
static const DrawTileSprites _crossing_layout = {
|
||||||
|
{0, PAL_NONE}, _crossing_layout_ALL
|
||||||
|
};
|
||||||
|
|
||||||
#undef TILE_SEQ_LINE
|
#undef TILE_SEQ_LINE
|
||||||
#undef TILE_SEQ_END
|
#undef TILE_SEQ_END
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "pbs.h"
|
#include "pbs.h"
|
||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
#include "engine_base.h"
|
#include "engine_base.h"
|
||||||
|
#include "newgrf_railtype.h"
|
||||||
|
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
@ -930,14 +931,22 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||||
AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_CATENARY), BB_data[8], BB_data[9], BB_Z_SEPARATOR);
|
AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_CATENARY), BB_data[8], BB_data[9], BB_Z_SEPARATOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (HasCatenaryDrawn(GetRailType(ti->tile))) {
|
} else {
|
||||||
/* Maybe draw pylons on the entry side */
|
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
||||||
DrawCatenary(ti);
|
if (rti->UsesOverlay()) {
|
||||||
|
SpriteID surface = GetCustomRailSprite(rti, ti->tile, RTSG_TUNNEL);
|
||||||
|
if (surface != 0) DrawGroundSprite(surface + tunnelbridge_direction, PAL_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
catenary = true;
|
if (HasCatenaryDrawn(GetRailType(ti->tile))) {
|
||||||
StartSpriteCombine();
|
/* Maybe draw pylons on the entry side */
|
||||||
/* Draw wire above the ramp */
|
DrawCatenary(ti);
|
||||||
DrawCatenaryOnTunnel(ti);
|
|
||||||
|
catenary = true;
|
||||||
|
StartSpriteCombine();
|
||||||
|
/* Draw wire above the ramp */
|
||||||
|
DrawCatenaryOnTunnel(ti);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AddSortableSpriteToDraw(image + 1, PAL_NONE, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, BB_data[0], BB_data[1], TILE_HEIGHT, ti->z, false, BB_data[2], BB_data[3], BB_Z_SEPARATOR);
|
AddSortableSpriteToDraw(image + 1, PAL_NONE, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, BB_data[0], BB_data[1], TILE_HEIGHT, ti->z, false, BB_data[2], BB_data[3], BB_Z_SEPARATOR);
|
||||||
|
@ -995,15 +1004,6 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||||
/* Bridge heads are drawn solid no matter how invisibility/transparency is set */
|
/* Bridge heads are drawn solid no matter how invisibility/transparency is set */
|
||||||
AddSortableSpriteToDraw(psid->sprite, psid->pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z);
|
AddSortableSpriteToDraw(psid->sprite, psid->pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z);
|
||||||
|
|
||||||
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && transport_type == TRANSPORT_RAIL && HasTunnelBridgeReservation(ti->tile)) {
|
|
||||||
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
|
||||||
if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
|
|
||||||
AddSortableSpriteToDraw(DiagDirToAxis(tunnelbridge_direction) == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + 8);
|
|
||||||
} else {
|
|
||||||
AddSortableSpriteToDraw(rti->base_sprites.single_sloped + tunnelbridge_direction, PALETTE_CRASH, ti->x, ti->y, 16, 16, 8, ti->z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transport_type == TRANSPORT_ROAD) {
|
if (transport_type == TRANSPORT_ROAD) {
|
||||||
RoadTypes rts = GetRoadTypes(ti->tile);
|
RoadTypes rts = GetRoadTypes(ti->tile);
|
||||||
|
|
||||||
|
@ -1021,6 +1021,26 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||||
}
|
}
|
||||||
EndSpriteCombine();
|
EndSpriteCombine();
|
||||||
} else if (transport_type == TRANSPORT_RAIL) {
|
} else if (transport_type == TRANSPORT_RAIL) {
|
||||||
|
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
||||||
|
if (rti->UsesOverlay()) {
|
||||||
|
SpriteID surface = GetCustomRailSprite(rti, ti->tile, RTSG_BRIDGE);
|
||||||
|
if (surface != 0) {
|
||||||
|
if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
|
||||||
|
AddSortableSpriteToDraw(surface + ((DiagDirToAxis(tunnelbridge_direction) == AXIS_X) ? RTBO_X : RTBO_Y), PAL_NONE, ti->x, ti->y, 16, 16, 0, ti->z + 8);
|
||||||
|
} else {
|
||||||
|
AddSortableSpriteToDraw(surface + RTBO_SLOPE + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, 16, 16, 8, ti->z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Don't fallback to non-overlay sprite -- the spec states that
|
||||||
|
* if an overlay is present then the bridge surface must be
|
||||||
|
* present. */
|
||||||
|
} else if (_game_mode != GM_MENU &&_settings_client.gui.show_track_reservation && HasTunnelBridgeReservation(ti->tile)) {
|
||||||
|
if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
|
||||||
|
AddSortableSpriteToDraw(DiagDirToAxis(tunnelbridge_direction) == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + 8);
|
||||||
|
} else {
|
||||||
|
AddSortableSpriteToDraw(rti->base_sprites.single_sloped + tunnelbridge_direction, PALETTE_CRASH, ti->x, ti->y, 16, 16, 8, ti->z);
|
||||||
|
}
|
||||||
|
}
|
||||||
EndSpriteCombine();
|
EndSpriteCombine();
|
||||||
if (HasCatenaryDrawn(GetRailType(ti->tile))) {
|
if (HasCatenaryDrawn(GetRailType(ti->tile))) {
|
||||||
DrawCatenary(ti);
|
DrawCatenary(ti);
|
||||||
|
@ -1128,7 +1148,7 @@ void DrawBridgeMiddle(const TileInfo *ti)
|
||||||
AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, x, y, 16, 16, 1, bridge_z - TILE_HEIGHT + BB_Z_SEPARATOR);
|
AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, x, y, 16, 16, 1, bridge_z - TILE_HEIGHT + BB_Z_SEPARATOR);
|
||||||
|
|
||||||
/* Draw Trambits as SpriteCombine */
|
/* Draw Trambits as SpriteCombine */
|
||||||
if (transport_type == TRANSPORT_ROAD) StartSpriteCombine();
|
if (transport_type == TRANSPORT_ROAD || transport_type == TRANSPORT_RAIL) StartSpriteCombine();
|
||||||
|
|
||||||
/* Draw floor and far part of bridge*/
|
/* Draw floor and far part of bridge*/
|
||||||
if (!IsInvisibilitySet(TO_BRIDGES)) {
|
if (!IsInvisibilitySet(TO_BRIDGES)) {
|
||||||
|
@ -1152,6 +1172,15 @@ void DrawBridgeMiddle(const TileInfo *ti)
|
||||||
StartSpriteCombine();
|
StartSpriteCombine();
|
||||||
}
|
}
|
||||||
} else if (transport_type == TRANSPORT_RAIL) {
|
} else if (transport_type == TRANSPORT_RAIL) {
|
||||||
|
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(rampsouth));
|
||||||
|
if (rti->UsesOverlay()) {
|
||||||
|
SpriteID surface = GetCustomRailSprite(rti, ti->tile, RTSG_BRIDGE);
|
||||||
|
if (surface != 0) {
|
||||||
|
AddSortableSpriteToDraw(surface + axis, PAL_NONE, x, y, 16, 16, 0, bridge_z, IsTransparencySet(TO_BRIDGES));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EndSpriteCombine();
|
||||||
|
|
||||||
if (HasCatenaryDrawn(GetRailType(rampsouth))) {
|
if (HasCatenaryDrawn(GetRailType(rampsouth))) {
|
||||||
DrawCatenaryOnBridge(ti);
|
DrawCatenaryOnBridge(ti);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue