Add GRF feature: New Landscape
Custom graphics using actions 1/2/3. Currently only for rock tiles
This commit is contained in:
@@ -29,6 +29,7 @@
|
|||||||
<h3>Features with separate pages</h3>
|
<h3>Features with separate pages</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="newgrf-roadstops-nml.html">Road stops (FEAT_ROADSTOPS)</a></li>
|
<li><a href="newgrf-roadstops-nml.html">Road stops (FEAT_ROADSTOPS)</a></li>
|
||||||
|
<li><a href="newgrf-newlandscape-nml.html">New landscape (FEAT_NEWLANDSCAPE)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3><a href="https://newgrf-specs.tt-wiki.net/wiki/NML:Builtin_functions">Builtin functions</a></h3>
|
<h3><a href="https://newgrf-specs.tt-wiki.net/wiki/NML:Builtin_functions">Builtin functions</a></h3>
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
<h3 id="separate_features">Features with separate pages</h3>
|
<h3 id="separate_features">Features with separate pages</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="newgrf-roadstops.html">Road stops</a></li>
|
<li><a href="newgrf-roadstops.html">Road stops</a></li>
|
||||||
|
<li><a href="newgrf-newlandscape.html">New landscape (custom graphics)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
@@ -740,6 +741,7 @@
|
|||||||
<table>
|
<table>
|
||||||
<tr><th>Feature name</th><th>Description</th></tr>
|
<tr><th>Feature name</th><th>Description</th></tr>
|
||||||
<tr><td><font face="monospace">road_stops</font></td><td><a href="newgrf-roadstops.html">Custom road stops (bus stops, lorry stops and road waypoints)</a></d></tr>
|
<tr><td><font face="monospace">road_stops</font></td><td><a href="newgrf-roadstops.html">Custom road stops (bus stops, lorry stops and road waypoints)</a></d></tr>
|
||||||
|
<tr><td><font face="monospace">new_landscape</font></td><td><a href="newgrf-newlandscape.html">Custom landscape graphics (currently rocky tiles only)</a></d></tr>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
126
docs/newgrf-newlandscape-nml.html
Normal file
126
docs/newgrf-newlandscape-nml.html
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>JGR's Patchpack - NewGRF New Landscape Addition to NewGRF Specifications in NML</title>
|
||||||
|
<style type="text/css">
|
||||||
|
td li { white-space: nowrap; text-align: left; }
|
||||||
|
th { white-space: nowrap; text-align: center; }
|
||||||
|
td, th { border: 1px solid #CCCCCC; padding: 0px 5px; }
|
||||||
|
table { border-collapse: collapse; empty-cells: show; }
|
||||||
|
.code { white-space: pre; font-family: "Courier New", Courier, mono; }
|
||||||
|
.indent { margin-left: 2em; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>NewGRF New Landscape Addition to NewGRF Specifications in JGR's Patchpack in NML</h2>
|
||||||
|
<p>This document describes the non-standard addition of the NewGRF new landscape feature to the <a href="https://newgrf-specs.tt-wiki.net/wiki/NML:Main">Official OpenTTD NML Specifications</a>, as implemented in this patchpack, and the associated <a href="https://github.com/JGRennison/nml">NML fork</a></p>
|
||||||
|
<p>This feature allows NewGRF custom graphics using switches and spritesets for landscape tiles. Currently this includes: rock tiles.</p>
|
||||||
|
<p>This feature may not necessarily match implementations of additional landscape graphics features in other patches, branches, etc.<br />
|
||||||
|
This feature as implemented here MAY also be present in other patchpacks.</p>
|
||||||
|
|
||||||
|
<p>The feature identifier is <span class="code">FEAT_NEWLANDSCAPE</span>.<br />
|
||||||
|
There is no permanent storage associated with this feature.</p>
|
||||||
|
|
||||||
|
<p>See the <a href="newgrf-additions-nml.html">NewGRF additions (NML)</a> document for background information on additions to NML.</p>
|
||||||
|
|
||||||
|
<p>See the associated <a href="newgrf-newlandscape.html">non-NML document</a> for more details on the NewGRF new landscape feature.</p>
|
||||||
|
|
||||||
|
<p>This feature will be automatically skipped when loaded into a version of OpenTTD which does not support this feature.<br />
|
||||||
|
If this feature is the only significant thing in this GRF, then <span class="code">extended_feature_test("new_landscape")</span> SHOULD be called and some message, error or other form of
|
||||||
|
signalling to the user used to inform the user that this version of OpenTTD does not support the feature, if the return value is false.<br />
|
||||||
|
Otherwise the GRF could silently do nothing instead of the expected functionality, creating confusion for end users.</p>
|
||||||
|
|
||||||
|
<p><b>Sections:</b>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#newlandscape_ids">IDs</a></li>
|
||||||
|
<li><a href="#newlandscape_properties">Properties</a></li>
|
||||||
|
<li><a href="#newlandscape_variables">Variables</a></li>
|
||||||
|
<li><a href="#newlandscape_example">Syntax example</a></li>
|
||||||
|
</ul></p>
|
||||||
|
|
||||||
|
<h3 id="newlandscape_ids">New Landscape IDs</h3>
|
||||||
|
<p>
|
||||||
|
The ID field for an item must be set to one of the IDs in the table below (further IDs may be allocated for other purposes in future).
|
||||||
|
<table>
|
||||||
|
<tr><th>ID</th><th>Landscape type</th></tr>
|
||||||
|
<tr><td>NEW_LANDSCAPE_ID_ROCKS</td><td>Rocky tiles</td></tr>
|
||||||
|
</table>
|
||||||
|
</p>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 id="newlandscape_properties">New Landscape Properties</h3>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th>Property</th><th>Value range</th><th>Comment</th></tr>
|
||||||
|
<tr><td>enable_recolour</td><td>0 or 1</td>
|
||||||
|
<td>
|
||||||
|
Enable recolouring of graphics.<br />
|
||||||
|
When enabled, in addition to returning a sprite, register 0x100 may be set to the following using STORE_TEMP:
|
||||||
|
<table>
|
||||||
|
<tr><th>Bits</th><th>Meaning</th></tr>
|
||||||
|
<tr><td>0 - 23</td><td>Recolour sprite to use. Set to 0 for no recolouring.</td></tr>
|
||||||
|
<tr><td>24 - 31</td><td>Reserved, set to zero.</td></tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3 id="newlandscape_variables">New Landscape Variables</h3>
|
||||||
|
|
||||||
|
<p>A number of variables are shared between new landscape and stations. These are listed on the <a href="https://newgrf-specs.tt-wiki.net/wiki/NML:Stations#Base_station_variables">stations</a> page.</p>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th>Name</th><th>Value range</th><th>Comment</th></tr>
|
||||||
|
<tr><td>terrain_type</td><td>TILETYPE_XXX</td><td>XXX = NORMAL | DESERT | RAIN_FOREST | SNOW</td></tr>
|
||||||
|
<tr><td>tile_slope</td><td>SLOPE_XXX</td><td>See <a href="https://newgrf-specs.tt-wiki.net/wiki/NML:List_of_tile_slopes">tile slopes</a> for an overview of possible values</td></tr>
|
||||||
|
<tr><td>tile_height</td><td>0..255</td><td>Height of the lowest corner of the tile</td></tr>
|
||||||
|
<tr><td>tile_hash</td><td>0..4294967295</td><td>Hash value derived from the coordinates of the tile, suitable for pseudo-randomising graphics</td></tr>
|
||||||
|
<tr><td>landscape_type</td><td>NEW_LANDSCAPE_TYPE_XXX</td><td>Landscape type<br />XXX = ROCKS</td></tr>
|
||||||
|
</table>
|
||||||
|
<br />
|
||||||
|
Variables that require one or more parameters:
|
||||||
|
<table>
|
||||||
|
<tr><th>Name</th><th>Arguments</th><th>Value range</th><th>Comment</th></tr>
|
||||||
|
<tr><td>nearby_tile_slope</td><td>x, y offset (-8..7)</td><td>SLOPE_XXX</td><td>Slope of a nearby tile</td></tr>
|
||||||
|
<tr><td>nearby_tile_is_same_type</td><td>x, y offset (-8..7)</td><td>0 | 1</td><td>Is nearby tile the same landscape type as this one?</td></tr>
|
||||||
|
<tr><td>nearby_tile_is_water</td><td>x, y offset (-8..7)</td><td>0 | 1</td><td>Is nearby tile a water tile?</td></tr>
|
||||||
|
<tr><td>nearby_tile_terrain_type</td><td>x, y offset (-8..7)</td><td></td><td>See terrain_type</td></tr>
|
||||||
|
<tr><td>nearby_tile_water_class</td><td>x, y offset (-8..7)</td><td>WATER_CLASS_XXX</td><td>XXX = [NONE | SEA | CANAL | RIVER]<br />Note that tiles for which nearby_tile_is_water is 0 may still have a water class, e.g. industry tiles with water beneath them. </td></tr>
|
||||||
|
<tr><td>nearby_tile_height</td><td>x, y offset (-8..7)</td><td></td><td>The minimum height of the given tile in height level units</td></tr>
|
||||||
|
<tr><td>nearby_tile_class</td><td>x, y offset (-8..7)</td><td><a href="https://newgrf-specs.tt-wiki.net/wiki/NML:List_of_tile_classes">tile class</a></td><td></td></tr>
|
||||||
|
<tr><td>nearby_tile_info</td><td>x, y offset (-8..7)</td><td></td><td>Above nearby tile variables in one variable (all of variable 0x60)</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3 id="newlandscape_example">Syntax example</h3>
|
||||||
|
<p>
|
||||||
|
<pre class="code">
|
||||||
|
grf {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!extended_feature_test("new_landscape")) {
|
||||||
|
error(FATAL, string(STR_UNSUPPORTED_VERSION));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
spriteset spriteset_rocks {
|
||||||
|
/* 19 tile sprites in the standard order */
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (FEAT_NEWLANDSCAPE, SELF, switch_rocks, ...) {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
item (FEAT_NEWLANDSCAPE, item_rocks, NEW_LANDSCAPE_ID_ROCKS) {
|
||||||
|
property {
|
||||||
|
enable_recolour: 0;
|
||||||
|
}
|
||||||
|
graphics {
|
||||||
|
default: switch_rocks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
124
docs/newgrf-newlandscape.html
Normal file
124
docs/newgrf-newlandscape.html
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>JGR's Patchpack - NewGRF New Landscape Addition to NewGRF Specifications</title>
|
||||||
|
<style type="text/css">
|
||||||
|
td li { white-space: nowrap; text-align: left; }
|
||||||
|
th { white-space: nowrap; text-align: center; }
|
||||||
|
td, th { border: 1px solid #CCCCCC; padding: 0px 5px; }
|
||||||
|
table { border-collapse: collapse; empty-cells: show; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>NewGRF New Landscape Addition to NewGRF Specifications in JGR's Patchpack</h2>
|
||||||
|
<p>This document describes the non-standard addition of the NewGRF new landscape feature to the <a href="https://newgrf-specs.tt-wiki.net/wiki/Main_Page">Official OpenTTD NewGRF Specifications</a>, as implemented in this patchpack.</p>
|
||||||
|
<p>This feature allows NewGRF custom graphics using Action 1/2/3 for landscape tiles. Currently this includes: rock tiles.</p>
|
||||||
|
<p>This feature may not necessarily match implementations of additional landscape graphics features in other patches, branches, etc.<br />
|
||||||
|
This feature as implemented here MAY also be present in other patchpacks.</p>
|
||||||
|
<p>See the <a href="newgrf-additions.html">NewGRF additions</a> document for background information on additions to the NewGRF specifications.</p>
|
||||||
|
<p>The functionality listed below is also supported in a fork of NML, see the associated <a href="newgrf-newlandscape-nml.html">NML new landscape</a> and <a href="newgrf-additions-nml.html">NML additions</a> documents for more details.</p>
|
||||||
|
<p>NewGRFs which use this feature SHOULD use the <a href="newgrf-additions.html#feature-test">feature testing</a> mechanism to check whether the new landscape feature and/or feature ID mapping is supported.</p>
|
||||||
|
<p>NewGRFs which use this feature MUST use the <a href="newgrf-additions.html#feature-id-mapping">feature ID mapping</a> mechanism to map the non-standard NewGRF road stop feature to a local feature ID.</p>
|
||||||
|
<p>This feature is indicated by the feature name: <font face="monospace">new_landscape</font>, version 1.<br />
|
||||||
|
The feature name to use for feature ID mapping is <font face="monospace">new_landscape</font>.<br />
|
||||||
|
Features/properties/variables which require a higher version will indicate the required version. Unless indicated otherwise these will fall back to doing nothing on versions which do not support them.</p>
|
||||||
|
|
||||||
|
<p><h3 id="ids">IDs:</h3>
|
||||||
|
The ID field for Actions 0 and 3 must be set to one of the IDs in the table below (further IDs may be allocated for other purposes in future).
|
||||||
|
<table>
|
||||||
|
<tr><th>ID</th><th>Landscape type</th></tr>
|
||||||
|
<tr><td>0</td><td>Rocky tiles</td></tr>
|
||||||
|
</table>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><h3 id="actions">Actions:</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#a0roadstops">Action 0</a></li>
|
||||||
|
<li><a href="#a2roadstops">Action 2</a></li>
|
||||||
|
<li><a href="#varaction2roadstops">Variational Action 2</a></li>
|
||||||
|
<li><a href="#a3roadstops">Action 3</a></li>
|
||||||
|
</ul></p>
|
||||||
|
|
||||||
|
<h3 id="a0roadstops">Action 0 - New Landscape</h3>
|
||||||
|
|
||||||
|
<p>See the <a href="https://newgrf-specs.tt-wiki.net/wiki/Action0">Action 0 Specification</a> for background information.</p>
|
||||||
|
|
||||||
|
<b>Properties:</b>
|
||||||
|
<table>
|
||||||
|
<tr><th>Mappable name</th><th>Size in bytes</th><th>Description</th></tr>
|
||||||
|
<tr><td><a href="#newlandscape_enable_recolour">newlandscape_enable_recolour</a></td><td>1</td><td>Enable recolour</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4 id="newlandscape_enable_recolour">Enable recolouring for new landscape graphics (mappable property: newlandscape_enable_recolour)</h4>
|
||||||
|
<p>When enabled, in addition to returning a sprite, register 0x100 may be set to the following:
|
||||||
|
<table>
|
||||||
|
<tr><th>Bits</th><th>Meaning</th></tr>
|
||||||
|
<tr><td>0 - 23</td><td>Recolour sprite to use. Set to 0 for no recolouring.</td></tr>
|
||||||
|
<tr><td>24 - 31</td><td>Reserved, set to zero. </td></tr>
|
||||||
|
</table></p>
|
||||||
|
<p>The property length is 1 byte. 0 is disabled (default). 1 is enabled.</p>
|
||||||
|
|
||||||
|
<h3 id="a2roadstops">Action 2 - New Landscape</h3>
|
||||||
|
|
||||||
|
<p>See the <a href="https://newgrf-specs.tt-wiki.net/wiki/Action2">Action 2 Specification</a> for background information.</p>
|
||||||
|
|
||||||
|
<p>New landscape <b>does not</b> use the special sprite layout format.</p>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<h3 id="varaction2roadstops">Variational Action 2 - New Landscape</h3>
|
||||||
|
|
||||||
|
<p>See the <a href="https://newgrf-specs.tt-wiki.net/wiki/VariationalAction2">Variational Action 2 Specification</a> for background information.</p>
|
||||||
|
|
||||||
|
<b>Variables:</b>
|
||||||
|
<table>
|
||||||
|
<tr><th>Number</th><th>Mappable name</th><th>Description</th></tr>
|
||||||
|
<tr><td><a href="#newlandscape_terrain_type">40</a></td><td><a href="#newlandscape_terrain_type">newlandscape_terrain_type</a></td><td>Terrain type</td></tr>
|
||||||
|
<tr><td><a href="#newlandscape_tile_slope">41</a></td><td><a href="#newlandscape_tile_slope">newlandscape_tile_slope</a></td><td>Tile Slope</td></tr>
|
||||||
|
<tr><td><a href="#newlandscape_tile_height">42</a></td><td><a href="#newlandscape_tile_height">newlandscape_tile_height</a></td><td>Tile Height</td></tr>
|
||||||
|
<tr><td><a href="#newlandscape_tile_hash">43</a></td><td><a href="#newlandscape_tile_hash">newlandscape_tile_hash</a></td><td>Tile Hash</td></tr>
|
||||||
|
<tr><td><a href="#newlandscape_landscape_type">44</a></td><td><a href="#newlandscape_landscape_type">newlandscape_landscape_type</a></td><td>Landscape Type</td></tr>
|
||||||
|
<tr><td><a href="#newlandscape_land_info_nearby_tiles">60</a></td><td><a href="#newlandscape_land_info_nearby_tiles">newlandscape_land_info_nearby_tiles</a></td><td>Land info of nearby tiles</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4 id="newlandscape_terrain_type">Tile terrain type (40, or mappable variable: newlandscape_terrain_type)</h4>
|
||||||
|
<p>This has the same value as bits 0 - 7 of <a href="https://newgrf-specs.tt-wiki.net/wiki/VariationalAction2/Objects#Tile_information_.2841.29">object (feature F) variable 41</a>.
|
||||||
|
<table>
|
||||||
|
<tr><th>Value</th><th>Meaning</th></tr>
|
||||||
|
<tr><td>0</td><td>Normal</td></tr>
|
||||||
|
<tr><td>1</td><td>Desert</td></tr>
|
||||||
|
<tr><td>2</td><td>Rainforest</td></tr>
|
||||||
|
<tr><td>4</td><td>On or above snowline</td></tr>
|
||||||
|
</table>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4 id="newlandscape_tile_slope">Tile slope (41, or mappable variable: newlandscape_tile_slope)</h4>
|
||||||
|
<p>This has the same value as bits 0 - 7 of <a href="https://newgrf-specs.tt-wiki.net/wiki/VariationalAction2/Industry_Tiles#Land_info_of_nearby_tiles_.2860.29">industry tile (feature 9) variable 60</a> for this tile.</p>
|
||||||
|
|
||||||
|
<h4 id="newlandscape_tile_height">Tile height (42, or mappable variable: newlandscape_tile_height)</h4>
|
||||||
|
<p>The height of the lowest corner of the tile (in units of 1).</p>
|
||||||
|
|
||||||
|
<h4 id="newlandscape_tile_hash">Tile hash (43, or mappable variable: newlandscape_tile_hash)</h4>
|
||||||
|
<p>Hash value derived from the coordinates of the tile, suitable for pseudo-randomising graphics.</p>
|
||||||
|
|
||||||
|
<h4 id="roadstop_land_info_nearby_tiles">Land info of nearby tile (60, or mappable variable: newlandscape_land_info_nearby_tiles)</h4>
|
||||||
|
<p>This has the same value as <a href="https://newgrf-specs.tt-wiki.net/wiki/VariationalAction2/Industry_Tiles#Land_info_of_nearby_tiles_.2860.29">industry tile (feature 9) variable 60</a>.</p>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<h3 id="a3roadstops">Action 3 - New Landscape</h3>
|
||||||
|
|
||||||
|
<p>See the <a href="https://newgrf-specs.tt-wiki.net/wiki/Action3">Action 3 Specification</a> for background information.</p>
|
||||||
|
|
||||||
|
<p>Note that this is not a generic callback, the sprite group must be assigned to an ID in the <a href="#ids">IDs table</a>.
|
||||||
|
<table>
|
||||||
|
<tr><th>Action 3 ID</th><th>Expected number of sprites</th><th>Landscape type</th></tr>
|
||||||
|
<tr><td>0</td><td>19</td><td>Rocky tiles</td></tr>
|
||||||
|
</table>
|
||||||
|
Cargo type definitions are not used. Only the default set ID is used.
|
||||||
|
</p>
|
||||||
|
<p>This is indicated by the feature name: <font face="monospace">new_landscape</font>, version 1</p>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -272,6 +272,8 @@ add_files(
|
|||||||
newgrf_industrytiles.cpp
|
newgrf_industrytiles.cpp
|
||||||
newgrf_industrytiles.h
|
newgrf_industrytiles.h
|
||||||
newgrf_industrytiles_analysis.h
|
newgrf_industrytiles_analysis.h
|
||||||
|
newgrf_newlandscape.cpp
|
||||||
|
newgrf_newlandscape.h
|
||||||
newgrf_newsignals.cpp
|
newgrf_newsignals.cpp
|
||||||
newgrf_newsignals.h
|
newgrf_newsignals.h
|
||||||
newgrf_object.cpp
|
newgrf_object.cpp
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#include "water.h"
|
#include "water.h"
|
||||||
#include "core/random_func.hpp"
|
#include "core/random_func.hpp"
|
||||||
#include "newgrf_generic.h"
|
#include "newgrf_generic.h"
|
||||||
|
#include "newgrf_newlandscape.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/sprites.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);
|
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)
|
SpriteID GetSpriteIDForFields(const Slope slope, const uint field_type)
|
||||||
{
|
{
|
||||||
return _clear_land_sprites_farmland[field_type] + SlopeToSpriteOffset(slope);
|
return _clear_land_sprites_farmland[field_type] + SlopeToSpriteOffset(slope);
|
||||||
@@ -135,7 +159,9 @@ static void DrawTile_Clear(TileInfo *ti, DrawTileProcParams params)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CLEAR_ROCKS:
|
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;
|
break;
|
||||||
|
|
||||||
case CLEAR_FIELDS:
|
case CLEAR_FIELDS:
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include "newgrf_airport.h"
|
#include "newgrf_airport.h"
|
||||||
#include "newgrf_object.h"
|
#include "newgrf_object.h"
|
||||||
#include "newgrf_newsignals.h"
|
#include "newgrf_newsignals.h"
|
||||||
|
#include "newgrf_newlandscape.h"
|
||||||
#include "newgrf_extension.h"
|
#include "newgrf_extension.h"
|
||||||
#include "rev.h"
|
#include "rev.h"
|
||||||
#include "fios.h"
|
#include "fios.h"
|
||||||
@@ -5168,6 +5169,38 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, const
|
|||||||
return ret;
|
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)
|
static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, GrfSpecFeature feature, int property)
|
||||||
{
|
{
|
||||||
switch (cir) {
|
switch (cir) {
|
||||||
@@ -5248,6 +5281,7 @@ static const char *_feature_names[] = {
|
|||||||
"ROADTYPES",
|
"ROADTYPES",
|
||||||
"TRAMTYPES",
|
"TRAMTYPES",
|
||||||
"ROADSTOPS",
|
"ROADSTOPS",
|
||||||
|
"NEWLANDSCAPE",
|
||||||
};
|
};
|
||||||
static_assert(lengthof(_feature_names) == GSF_END);
|
static_assert(lengthof(_feature_names) == GSF_END);
|
||||||
|
|
||||||
@@ -5353,6 +5387,7 @@ static void FeatureChangeInfo(ByteReader *buf)
|
|||||||
/* GSF_ROADTYPES */ RoadTypeChangeInfo,
|
/* GSF_ROADTYPES */ RoadTypeChangeInfo,
|
||||||
/* GSF_TRAMTYPES */ TramTypeChangeInfo,
|
/* GSF_TRAMTYPES */ TramTypeChangeInfo,
|
||||||
/* GSF_ROADSTOPS */ RoadStopChangeInfo,
|
/* GSF_ROADSTOPS */ RoadStopChangeInfo,
|
||||||
|
/* GSF_NEWLANDSCAPE */ NewLandscapeChangeInfo,
|
||||||
};
|
};
|
||||||
static_assert(GSF_END == lengthof(handler));
|
static_assert(GSF_END == lengthof(handler));
|
||||||
static_assert(lengthof(handler) == lengthof(_cur.grffile->action0_property_remaps), "Action 0 feature list length mismatch");
|
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_ROADTYPES:
|
||||||
case GSF_TRAMTYPES:
|
case GSF_TRAMTYPES:
|
||||||
case GSF_SIGNALS:
|
case GSF_SIGNALS:
|
||||||
|
case GSF_NEWLANDSCAPE:
|
||||||
{
|
{
|
||||||
byte num_loaded = type;
|
byte num_loaded = type;
|
||||||
byte num_loading = buf->ReadByte();
|
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 */
|
/* Action 0x03 */
|
||||||
static void FeatureMapSpriteGroup(ByteReader *buf)
|
static void FeatureMapSpriteGroup(ByteReader *buf)
|
||||||
{
|
{
|
||||||
@@ -8969,6 +9038,10 @@ static void FeatureMapSpriteGroup(ByteReader *buf)
|
|||||||
RoadStopMapSpriteGroup(buf, idcount);
|
RoadStopMapSpriteGroup(buf, idcount);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case GSF_NEWLANDSCAPE:
|
||||||
|
NewLandscapeMapSpriteGroup(buf, idcount);
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %s, skipping", GetFeatureString(feature_ref));
|
grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %s, skipping", GetFeatureString(feature_ref));
|
||||||
return;
|
return;
|
||||||
@@ -12229,6 +12302,7 @@ static void ResetNewGRF()
|
|||||||
_grf_files.clear();
|
_grf_files.clear();
|
||||||
_cur.grffile = nullptr;
|
_cur.grffile = nullptr;
|
||||||
_new_signals_grfs.clear();
|
_new_signals_grfs.clear();
|
||||||
|
_new_landscape_rocks_grfs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clear all NewGRF errors */
|
/** Clear all NewGRF errors */
|
||||||
@@ -12415,6 +12489,9 @@ GRFFile::GRFFile(const GRFConfig *config)
|
|||||||
this->new_signal_ctrl_flags = 0;
|
this->new_signal_ctrl_flags = 0;
|
||||||
this->new_signal_extra_aspects = 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' */
|
/* Mark price_base_multipliers as 'not set' */
|
||||||
for (Price i = PR_BEGIN; i < PR_END; i++) {
|
for (Price i = PR_BEGIN; i < PR_END; i++) {
|
||||||
this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
|
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_TRAMTYPES,
|
||||||
|
|
||||||
GSF_ROADSTOPS,
|
GSF_ROADSTOPS,
|
||||||
|
GSF_NEWLANDSCAPE,
|
||||||
GSF_END,
|
GSF_END,
|
||||||
|
|
||||||
GSF_REAL_FEATURE_END = GSF_ROADSTOPS,
|
GSF_REAL_FEATURE_END = GSF_ROADSTOPS,
|
||||||
@@ -278,11 +279,22 @@ enum {
|
|||||||
NEW_SIGNALS_MAX_EXTRA_ASPECT = 6,
|
NEW_SIGNALS_MAX_EXTRA_ASPECT = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** New signal control flags. */
|
/** New signal action 3 IDs. */
|
||||||
enum NewSignalAction3ID {
|
enum NewSignalAction3ID {
|
||||||
NSA3ID_CUSTOM_SIGNALS = 0, ///< Action 3 ID for custom signal sprites
|
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. */
|
/** GRFFile control flags. */
|
||||||
enum GRFFileCtrlFlags {
|
enum GRFFileCtrlFlags {
|
||||||
GFCF_HAVE_FEATURE_ID_REMAP = 0, ///< This GRF has one or more feature ID mappings
|
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_ctrl_flags; ///< Ctrl flags for new signals
|
||||||
byte new_signal_extra_aspects; ///< Number of extra aspects 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
|
byte ctrl_flags; ///< General GRF control flags
|
||||||
|
|
||||||
btree::btree_map<uint16, uint> string_map; ///< Map of local GRF string ID to string ID
|
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_flood_resistant", 1),
|
||||||
GRFFeatureInfo("action0_object_viewport_map_tile_type", 1),
|
GRFFeatureInfo("action0_object_viewport_map_tile_type", 1),
|
||||||
GRFFeatureInfo("road_stops", 2),
|
GRFFeatureInfo("road_stops", 2),
|
||||||
|
GRFFeatureInfo("new_landscape", 1),
|
||||||
GRFFeatureInfo(),
|
GRFFeatureInfo(),
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Action14 remappable feature list */
|
/** Action14 remappable feature list */
|
||||||
extern const GRFFeatureMapDefinition _grf_remappable_features[] = {
|
extern const GRFFeatureMapDefinition _grf_remappable_features[] = {
|
||||||
GRFFeatureMapDefinition(GSF_ROADSTOPS, "road_stops"),
|
GRFFeatureMapDefinition(GSF_ROADSTOPS, "road_stops"),
|
||||||
|
GRFFeatureMapDefinition(GSF_NEWLANDSCAPE, "new_landscape"),
|
||||||
GRFFeatureMapDefinition(),
|
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_MIN_BRIDGE_HEIGHT, "roadstop_min_bridge_height"),
|
||||||
GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_DISALLOWED_BRIDGE_PILLARS, "roadstop_disallowed_bridge_pillars"),
|
GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_DISALLOWED_BRIDGE_PILLARS, "roadstop_disallowed_bridge_pillars"),
|
||||||
GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_COST_MULTIPLIERS, "roadstop_cost_multipliers"),
|
GRFPropertyMapDefinition(GSF_ROADSTOPS, A0RPI_ROADSTOP_COST_MULTIPLIERS, "roadstop_cost_multipliers"),
|
||||||
|
GRFPropertyMapDefinition(GSF_NEWLANDSCAPE, A0RPI_NEWLANDSCAPE_ENABLE_RECOLOUR, "newlandscape_enable_recolour"),
|
||||||
GRFPropertyMapDefinition(),
|
GRFPropertyMapDefinition(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -128,6 +131,12 @@ extern const GRFVariableMapDefinition _grf_action2_remappable_variables[] = {
|
|||||||
GRFVariableMapDefinition(GSF_ROADSTOPS, 0x6A, "roadstop_road_stop_grfid_nearby_tiles"),
|
GRFVariableMapDefinition(GSF_ROADSTOPS, 0x6A, "roadstop_road_stop_grfid_nearby_tiles"),
|
||||||
GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO, "railtype_signal_restriction_info"),
|
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_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(),
|
GRFVariableMapDefinition(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -54,6 +54,7 @@ enum Action0RemapPropertyIds {
|
|||||||
A0RPI_ROADSTOP_MIN_BRIDGE_HEIGHT,
|
A0RPI_ROADSTOP_MIN_BRIDGE_HEIGHT,
|
||||||
A0RPI_ROADSTOP_DISALLOWED_BRIDGE_PILLARS,
|
A0RPI_ROADSTOP_DISALLOWED_BRIDGE_PILLARS,
|
||||||
A0RPI_ROADSTOP_COST_MULTIPLIERS,
|
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_ROADTYPES
|
||||||
&_nif_roadtype, // GSF_TRAMTYPES
|
&_nif_roadtype, // GSF_TRAMTYPES
|
||||||
&_nif_roadstop, // GSF_ROADSTOPS
|
&_nif_roadstop, // GSF_ROADSTOPS
|
||||||
|
nullptr, // GSF_NEWLANDSCAPE
|
||||||
&_nif_town, // GSF_FAKE_TOWNS
|
&_nif_town, // GSF_FAKE_TOWNS
|
||||||
&_nif_station_struct, // GSF_FAKE_STATION_STRUCT
|
&_nif_station_struct, // GSF_FAKE_STATION_STRUCT
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user