Add GRF feature: New Landscape
Custom graphics using actions 1/2/3. Currently only for rock tiles
This commit is contained in:
@@ -272,6 +272,8 @@ add_files(
|
||||
newgrf_industrytiles.cpp
|
||||
newgrf_industrytiles.h
|
||||
newgrf_industrytiles_analysis.h
|
||||
newgrf_newlandscape.cpp
|
||||
newgrf_newlandscape.h
|
||||
newgrf_newsignals.cpp
|
||||
newgrf_newsignals.h
|
||||
newgrf_object.cpp
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "water.h"
|
||||
#include "core/random_func.hpp"
|
||||
#include "newgrf_generic.h"
|
||||
#include "newgrf_newlandscape.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
#include "table/sprites.h"
|
||||
@@ -73,6 +74,29 @@ SpriteID GetSpriteIDForRocks(const Slope slope, const uint tile_hash)
|
||||
return ((HasGrfMiscBit(GMB_SECOND_ROCKY_TILE_SET) && (tile_hash & 1)) ? SPR_FLAT_ROCKY_LAND_2 : SPR_FLAT_ROCKY_LAND_1) + SlopeToSpriteOffset(slope);
|
||||
}
|
||||
|
||||
inline SpriteID GetSpriteIDForRocksUsingOffset(const uint slope_to_sprite_offset, const uint x, const uint y)
|
||||
{
|
||||
return ((HasGrfMiscBit(GMB_SECOND_ROCKY_TILE_SET) && (TileHash(x, y) & 1)) ? SPR_FLAT_ROCKY_LAND_2 : SPR_FLAT_ROCKY_LAND_1) + slope_to_sprite_offset;
|
||||
}
|
||||
|
||||
void DrawCustomSpriteIDForRocks(const TileInfo *ti)
|
||||
{
|
||||
uint8 slope_to_sprite_offset = SlopeToSpriteOffset(ti->tileh);
|
||||
|
||||
for (const GRFFile *grf : _new_landscape_rocks_grfs) {
|
||||
NewLandscapeResolverObject object(grf, ti, NEW_LANDSCAPE_ROCKS);
|
||||
|
||||
const SpriteGroup *group = object.Resolve();
|
||||
if (group != nullptr && group->GetNumResults() > slope_to_sprite_offset) {
|
||||
PaletteID pal = HasBit(grf->new_landscape_ctrl_flags, NLCF_ROCKS_RECOLOUR_ENABLED) ? GB(GetRegister(0x100), 0, 24) : PAL_NONE;
|
||||
DrawGroundSprite(group->GetResult() + slope_to_sprite_offset, pal);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DrawGroundSprite(GetSpriteIDForRocksUsingOffset(slope_to_sprite_offset, ti->x, ti->y), PAL_NONE);
|
||||
}
|
||||
|
||||
SpriteID GetSpriteIDForFields(const Slope slope, const uint field_type)
|
||||
{
|
||||
return _clear_land_sprites_farmland[field_type] + SlopeToSpriteOffset(slope);
|
||||
@@ -135,7 +159,9 @@ static void DrawTile_Clear(TileInfo *ti, DrawTileProcParams params)
|
||||
break;
|
||||
|
||||
case CLEAR_ROCKS:
|
||||
if (!params.no_ground_tiles) DrawGroundSprite(GetSpriteIDForRocks(ti->tileh, TileHash(ti->x, ti->y)), PAL_NONE);
|
||||
if (!params.no_ground_tiles) {
|
||||
DrawCustomSpriteIDForRocks(ti);
|
||||
}
|
||||
break;
|
||||
|
||||
case CLEAR_FIELDS:
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "newgrf_airport.h"
|
||||
#include "newgrf_object.h"
|
||||
#include "newgrf_newsignals.h"
|
||||
#include "newgrf_newlandscape.h"
|
||||
#include "newgrf_extension.h"
|
||||
#include "rev.h"
|
||||
#include "fios.h"
|
||||
@@ -5168,6 +5169,38 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, const
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define properties for new landscape
|
||||
* @param id Landscape type.
|
||||
* @param numinfo Number of subsequent IDs to change the property for.
|
||||
* @param prop The property to change.
|
||||
* @param buf The property value.
|
||||
* @return ChangeInfoResult.
|
||||
*/
|
||||
static ChangeInfoResult NewLandscapeChangeInfo(uint id, int numinfo, int prop, const GRFFilePropertyRemapEntry *mapping_entry, ByteReader *buf)
|
||||
{
|
||||
/* Properties which are handled per item */
|
||||
ChangeInfoResult ret = CIR_SUCCESS;
|
||||
for (int i = 0; i < numinfo; i++) {
|
||||
switch (prop) {
|
||||
case A0RPI_NEWLANDSCAPE_ENABLE_RECOLOUR: {
|
||||
if (MappedPropertyLengthMismatch(buf, 1, mapping_entry)) break;
|
||||
bool enabled = (buf->ReadByte() != 0 ? 1 : 0);
|
||||
if (id == NLA3ID_CUSTOM_ROCKS) {
|
||||
SB(_cur.grffile->new_landscape_ctrl_flags, NLCF_ROCKS_RECOLOUR_ENABLED, 1, enabled);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = HandleAction0PropertyDefault(buf, prop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, GrfSpecFeature feature, int property)
|
||||
{
|
||||
switch (cir) {
|
||||
@@ -5248,6 +5281,7 @@ static const char *_feature_names[] = {
|
||||
"ROADTYPES",
|
||||
"TRAMTYPES",
|
||||
"ROADSTOPS",
|
||||
"NEWLANDSCAPE",
|
||||
};
|
||||
static_assert(lengthof(_feature_names) == GSF_END);
|
||||
|
||||
@@ -5353,6 +5387,7 @@ static void FeatureChangeInfo(ByteReader *buf)
|
||||
/* GSF_ROADTYPES */ RoadTypeChangeInfo,
|
||||
/* GSF_TRAMTYPES */ TramTypeChangeInfo,
|
||||
/* GSF_ROADSTOPS */ RoadStopChangeInfo,
|
||||
/* GSF_NEWLANDSCAPE */ NewLandscapeChangeInfo,
|
||||
};
|
||||
static_assert(GSF_END == lengthof(handler));
|
||||
static_assert(lengthof(handler) == lengthof(_cur.grffile->action0_property_remaps), "Action 0 feature list length mismatch");
|
||||
@@ -8060,6 +8095,7 @@ static void NewSpriteGroup(ByteReader *buf)
|
||||
case GSF_ROADTYPES:
|
||||
case GSF_TRAMTYPES:
|
||||
case GSF_SIGNALS:
|
||||
case GSF_NEWLANDSCAPE:
|
||||
{
|
||||
byte num_loaded = type;
|
||||
byte num_loading = buf->ReadByte();
|
||||
@@ -8861,6 +8897,39 @@ static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount)
|
||||
}
|
||||
}
|
||||
|
||||
static void NewLandscapeMapSpriteGroup(ByteReader *buf, uint8 idcount)
|
||||
{
|
||||
uint8 *ids = AllocaM(uint8, idcount);
|
||||
for (uint i = 0; i < idcount; i++) {
|
||||
ids[i] = buf->ReadByte();
|
||||
}
|
||||
|
||||
/* Skip the cargo type section, we only care about the default group */
|
||||
uint8 cidcount = buf->ReadByte();
|
||||
buf->Skip(cidcount * 3);
|
||||
|
||||
uint16 groupid = buf->ReadWord();
|
||||
if (!IsValidGroupID(groupid, "NewLandscapeMapSpriteGroup")) return;
|
||||
|
||||
for (uint i = 0; i < idcount; i++) {
|
||||
uint8 id = ids[i];
|
||||
|
||||
switch (id) {
|
||||
case NLA3ID_CUSTOM_ROCKS:
|
||||
_cur.grffile->new_rocks_group = GetGroupByID(groupid);
|
||||
if (!HasBit(_cur.grffile->new_landscape_ctrl_flags, NLCF_ROCKS_SET)) {
|
||||
SetBit(_cur.grffile->new_landscape_ctrl_flags, NLCF_ROCKS_SET);
|
||||
_new_landscape_rocks_grfs.push_back(_cur.grffile);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
grfmsg(1, "NewLandscapeMapSpriteGroup: ID not implemented: %d", id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Action 0x03 */
|
||||
static void FeatureMapSpriteGroup(ByteReader *buf)
|
||||
{
|
||||
@@ -8969,6 +9038,10 @@ static void FeatureMapSpriteGroup(ByteReader *buf)
|
||||
RoadStopMapSpriteGroup(buf, idcount);
|
||||
return;
|
||||
|
||||
case GSF_NEWLANDSCAPE:
|
||||
NewLandscapeMapSpriteGroup(buf, idcount);
|
||||
return;
|
||||
|
||||
default:
|
||||
grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %s, skipping", GetFeatureString(feature_ref));
|
||||
return;
|
||||
@@ -12229,6 +12302,7 @@ static void ResetNewGRF()
|
||||
_grf_files.clear();
|
||||
_cur.grffile = nullptr;
|
||||
_new_signals_grfs.clear();
|
||||
_new_landscape_rocks_grfs.clear();
|
||||
}
|
||||
|
||||
/** Clear all NewGRF errors */
|
||||
@@ -12415,6 +12489,9 @@ GRFFile::GRFFile(const GRFConfig *config)
|
||||
this->new_signal_ctrl_flags = 0;
|
||||
this->new_signal_extra_aspects = 0;
|
||||
|
||||
this->new_rocks_group = nullptr;
|
||||
this->new_landscape_ctrl_flags = 0;
|
||||
|
||||
/* Mark price_base_multipliers as 'not set' */
|
||||
for (Price i = PR_BEGIN; i < PR_END; i++) {
|
||||
this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
|
||||
|
||||
17
src/newgrf.h
17
src/newgrf.h
@@ -89,6 +89,7 @@ enum GrfSpecFeature : uint8 {
|
||||
GSF_TRAMTYPES,
|
||||
|
||||
GSF_ROADSTOPS,
|
||||
GSF_NEWLANDSCAPE,
|
||||
GSF_END,
|
||||
|
||||
GSF_REAL_FEATURE_END = GSF_ROADSTOPS,
|
||||
@@ -278,11 +279,22 @@ enum {
|
||||
NEW_SIGNALS_MAX_EXTRA_ASPECT = 6,
|
||||
};
|
||||
|
||||
/** New signal control flags. */
|
||||
/** New signal action 3 IDs. */
|
||||
enum NewSignalAction3ID {
|
||||
NSA3ID_CUSTOM_SIGNALS = 0, ///< Action 3 ID for custom signal sprites
|
||||
};
|
||||
|
||||
/** New landscape control flags. */
|
||||
enum NewLandscapeCtrlFlags {
|
||||
NLCF_ROCKS_SET = 0, ///< Custom landscape rocks sprites group set.
|
||||
NLCF_ROCKS_RECOLOUR_ENABLED = 1, ///< Recolour sprites enabled for rocks
|
||||
};
|
||||
|
||||
/** New landscape action 3 IDs. */
|
||||
enum NewLandscapeAction3ID {
|
||||
NLA3ID_CUSTOM_ROCKS = 0, ///< Action 3 ID for custom landscape sprites
|
||||
};
|
||||
|
||||
/** GRFFile control flags. */
|
||||
enum GRFFileCtrlFlags {
|
||||
GFCF_HAVE_FEATURE_ID_REMAP = 0, ///< This GRF has one or more feature ID mappings
|
||||
@@ -346,6 +358,9 @@ struct GRFFile : ZeroedMemoryAllocator {
|
||||
byte new_signal_ctrl_flags; ///< Ctrl flags for new signals
|
||||
byte new_signal_extra_aspects; ///< Number of extra aspects for new signals
|
||||
|
||||
const SpriteGroup *new_rocks_group; ///< New landscape rocks group
|
||||
byte new_landscape_ctrl_flags; ///< Ctrl flags for new landscape
|
||||
|
||||
byte ctrl_flags; ///< General GRF control flags
|
||||
|
||||
btree::btree_map<uint16, uint> string_map; ///< Map of local GRF string ID to string ID
|
||||
|
||||
@@ -52,12 +52,14 @@ extern const GRFFeatureInfo _grf_feature_list[] = {
|
||||
GRFFeatureInfo("action0_object_flood_resistant", 1),
|
||||
GRFFeatureInfo("action0_object_viewport_map_tile_type", 1),
|
||||
GRFFeatureInfo("road_stops", 2),
|
||||
GRFFeatureInfo("new_landscape", 1),
|
||||
GRFFeatureInfo(),
|
||||
};
|
||||
|
||||
/** Action14 remappable feature list */
|
||||
extern const GRFFeatureMapDefinition _grf_remappable_features[] = {
|
||||
GRFFeatureMapDefinition(GSF_ROADSTOPS, "road_stops"),
|
||||
GRFFeatureMapDefinition(GSF_NEWLANDSCAPE, "new_landscape"),
|
||||
GRFFeatureMapDefinition(),
|
||||
};
|
||||
|
||||
@@ -105,6 +107,7 @@ extern const GRFPropertyMapDefinition _grf_action0_remappable_properties[] = {
|
||||
GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_MIN_BRIDGE_HEIGHT, "roadstop_min_bridge_height"),
|
||||
GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_DISALLOWED_BRIDGE_PILLARS, "roadstop_disallowed_bridge_pillars"),
|
||||
GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_COST_MULTIPLIERS, "roadstop_cost_multipliers"),
|
||||
GRFPropertyMapDefinition(GSF_NEWLANDSCAPE, A0RPI_NEWLANDSCAPE_ENABLE_RECOLOUR, "newlandscape_enable_recolour"),
|
||||
GRFPropertyMapDefinition(),
|
||||
};
|
||||
|
||||
@@ -128,6 +131,12 @@ extern const GRFVariableMapDefinition _grf_action2_remappable_variables[] = {
|
||||
GRFVariableMapDefinition(GSF_ROADSTOPS, 0x6A, "roadstop_road_stop_grfid_nearby_tiles"),
|
||||
GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO, "railtype_signal_restriction_info"),
|
||||
GRFVariableMapDefinition(GSF_SIGNALS, A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO, "signals_signal_restriction_info"),
|
||||
GRFVariableMapDefinition(GSF_NEWLANDSCAPE, 0x40, "newlandscape_terrain_type"),
|
||||
GRFVariableMapDefinition(GSF_NEWLANDSCAPE, 0x41, "newlandscape_tile_slope"),
|
||||
GRFVariableMapDefinition(GSF_NEWLANDSCAPE, 0x42, "newlandscape_tile_height"),
|
||||
GRFVariableMapDefinition(GSF_NEWLANDSCAPE, 0x43, "newlandscape_tile_hash"),
|
||||
GRFVariableMapDefinition(GSF_NEWLANDSCAPE, 0x44, "newlandscape_landscape_type"),
|
||||
GRFVariableMapDefinition(GSF_NEWLANDSCAPE, 0x60, "newlandscape_land_info_nearby_tiles"),
|
||||
GRFVariableMapDefinition(),
|
||||
};
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ enum Action0RemapPropertyIds {
|
||||
A0RPI_ROADSTOP_MIN_BRIDGE_HEIGHT,
|
||||
A0RPI_ROADSTOP_DISALLOWED_BRIDGE_PILLARS,
|
||||
A0RPI_ROADSTOP_COST_MULTIPLIERS,
|
||||
A0RPI_NEWLANDSCAPE_ENABLE_RECOLOUR,
|
||||
};
|
||||
|
||||
|
||||
|
||||
102
src/newgrf_newlandscape.cpp
Normal file
102
src/newgrf_newlandscape.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file newgrf_newlandscape.cpp NewGRF handling of new landscape. */
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "debug.h"
|
||||
#include "newgrf_newlandscape.h"
|
||||
#include "newgrf_extension.h"
|
||||
#include "map_func.h"
|
||||
#include "clear_map.h"
|
||||
#include "core/hash_func.hpp"
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
std::vector<const GRFFile *> _new_landscape_rocks_grfs;
|
||||
|
||||
/* virtual */ uint32 NewLandscapeScopeResolver::GetVariable(uint16 variable, uint32 parameter, GetVariableExtra *extra) const
|
||||
{
|
||||
if (unlikely(this->ti->tile == INVALID_TILE)) {
|
||||
switch (variable) {
|
||||
case 0x40: return 0;
|
||||
case 0x41: return 0;
|
||||
case 0x42: return 0;
|
||||
case 0x43: return 0;
|
||||
case 0x44: return this->landscape_type;
|
||||
case 0x60: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (variable) {
|
||||
case 0x40:
|
||||
return GetTerrainType(this->ti->tile, TCX_NORMAL);
|
||||
|
||||
case 0x41:
|
||||
return this->ti->tileh;
|
||||
|
||||
case 0x42:
|
||||
return this->ti->z / TILE_HEIGHT;
|
||||
|
||||
case 0x43:
|
||||
/* Knuth hash */
|
||||
return SimpleHash32(this->ti->tile);
|
||||
|
||||
case 0x44:
|
||||
return this->landscape_type;
|
||||
|
||||
case 0x60: {
|
||||
TileIndex tile = this->ti->tile;
|
||||
if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required
|
||||
uint32 result = 0;
|
||||
if (extra->mask & ~0x100) result |= GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8, extra->mask);
|
||||
if (extra->mask & 0x100) {
|
||||
switch (this->landscape_type) {
|
||||
case NEW_LANDSCAPE_ROCKS:
|
||||
if (IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_ROCKS)) result |= 0x100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(grf, 1, "Unhandled new landscape tile variable 0x%X", variable);
|
||||
|
||||
extra->available = false;
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
/* virtual */ const SpriteGroup *NewLandscapeResolverObject::ResolveReal(const RealSpriteGroup *group) const
|
||||
{
|
||||
if (!group->loading.empty()) return group->loading[0];
|
||||
if (!group->loaded.empty()) return group->loaded[0];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrfSpecFeature NewLandscapeResolverObject::GetFeature() const
|
||||
{
|
||||
return GSF_NEWLANDSCAPE;
|
||||
}
|
||||
|
||||
NewLandscapeResolverObject::NewLandscapeResolverObject(const GRFFile *grffile, const TileInfo *ti, NewLandscapeType landscape_type, uint32 param1, uint32 param2)
|
||||
: ResolverObject(grffile, CBID_NO_CALLBACK, param1, param2), newlandscape_scope(*this, ti, landscape_type)
|
||||
{
|
||||
if (grffile != nullptr) {
|
||||
switch (landscape_type) {
|
||||
case NEW_LANDSCAPE_ROCKS:
|
||||
this->root_spritegroup = grffile->new_rocks_group;
|
||||
break;
|
||||
|
||||
default:
|
||||
this->root_spritegroup = nullptr;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
this->root_spritegroup = nullptr;
|
||||
}
|
||||
}
|
||||
55
src/newgrf_newlandscape.h
Normal file
55
src/newgrf_newlandscape.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file newgrf_newlandscape.h NewGRF handling of new landscape. */
|
||||
|
||||
#ifndef NEWGRF_NEWLANDSCAPE_H
|
||||
#define NEWGRF_NEWLANDSCAPE_H
|
||||
|
||||
#include "newgrf_commons.h"
|
||||
#include "newgrf_spritegroup.h"
|
||||
|
||||
extern std::vector<const GRFFile *> _new_landscape_rocks_grfs;
|
||||
|
||||
enum NewLandscapeType : uint8 {
|
||||
NEW_LANDSCAPE_ROCKS,
|
||||
};
|
||||
|
||||
struct TileInfo;
|
||||
|
||||
/** Resolver for the new landscape scope. */
|
||||
struct NewLandscapeScopeResolver : public ScopeResolver {
|
||||
const TileInfo *ti;
|
||||
NewLandscapeType landscape_type;
|
||||
|
||||
NewLandscapeScopeResolver(ResolverObject &ro, const TileInfo *ti, NewLandscapeType landscape_type)
|
||||
: ScopeResolver(ro), ti(ti), landscape_type(landscape_type)
|
||||
{
|
||||
}
|
||||
|
||||
uint32 GetVariable(uint16 variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||
};
|
||||
|
||||
struct NewLandscapeResolverObject : public ResolverObject {
|
||||
NewLandscapeScopeResolver newlandscape_scope;
|
||||
|
||||
NewLandscapeResolverObject(const GRFFile *grffile, const TileInfo *ti, NewLandscapeType landscape_type, uint32 param1 = 0, uint32 param2 = 0);
|
||||
|
||||
ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override
|
||||
{
|
||||
switch (scope) {
|
||||
case VSG_SCOPE_SELF: return &this->newlandscape_scope;
|
||||
default: return ResolverObject::GetScope(scope, relative);
|
||||
}
|
||||
}
|
||||
|
||||
const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override;
|
||||
|
||||
GrfSpecFeature GetFeature() const override;
|
||||
};
|
||||
|
||||
#endif /* NEWGRF_NEWLANDSCAPE_H */
|
||||
@@ -1534,6 +1534,7 @@ static const NIFeature * const _nifeatures[] = {
|
||||
&_nif_roadtype, // GSF_ROADTYPES
|
||||
&_nif_roadtype, // GSF_TRAMTYPES
|
||||
&_nif_roadstop, // GSF_ROADSTOPS
|
||||
nullptr, // GSF_NEWLANDSCAPE
|
||||
&_nif_town, // GSF_FAKE_TOWNS
|
||||
&_nif_station_struct, // GSF_FAKE_STATION_STRUCT
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user