Documentation: Add NewGRF town feature additions

pull/507/head
Jonathan G Rennison 1 year ago
parent 2181b99bdd
commit a00eb94e2f

@ -30,6 +30,7 @@
<ul>
<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>
<li><a href="newgrf-town-nml.html">Towns (the parent scope for stations, objects, etc.) (FEAT_TOWN)</a></li>
</ul>
<h3 id="sections">Sections</h3>

@ -30,6 +30,7 @@
<ul>
<li><a href="newgrf-roadstops.html">Road stops</a></li>
<li><a href="newgrf-newlandscape.html">New landscape (custom graphics)</a></li>
<li><a href="newgrf-town.html">Towns (the parent scope for stations, objects, etc.)</a></li>
</ul>
<br />
@ -671,6 +672,11 @@
<p>Within an A2VM chunk, the NAME text (type T) field contains the name of the variable to map. The value of the language ID byte is ignored.</p>
<h4 id="A2VM-FEAT">Action 0 Feature ID: C "A2VM" -> B "FEAT"</h4>
<p>Within an A2VM chunk, the FEAT binary (type B) field contains the <a href="https://newgrf-specs.tt-wiki.net/wiki/VariationalAction2#Feature">Variational Action 2 feature ID</a>. This is 1 byte.</p>
<p>In the case where a parent/related scope is used to access a different feature (e.g. the town feature as the parent scope for objects),
the feature ID used here is that associated with the scope where the variable is used.<br />
To map a town variable, the feature ID should be the result of mapping the "town" feature name using the <a href="#feature-id-mapping">feature mapping mechanism</a>,
this is not necessarily the feature ID used directly in the variational action 2.</p>
</p>
<h4 id="A2VM-RSFT">Shift to replace: C "A2VM" -> B "RSFT"</h4>
<p>Within an A2VM chunk, the RSFT binary (type B) field contains the Variational Action 2 varadjust shift-num value to look for. This is 1 byte.<br />
The shift-num value must be &lt; 32 (0x20).<br />
@ -974,6 +980,7 @@
<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">new_landscape</font></td><td><a href="newgrf-newlandscape.html">Custom landscape graphics (currently rocky tiles only)</a></d></tr>
<tr><td><font face="monospace">town</font></td><td><a href="newgrf-town.html">Towns (the parent scope for stations, objects, etc.)</a></d></tr>
</table>
</body>
</html>

@ -0,0 +1,121 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>JGR's Patchpack - NewGRF Town Feature Additions 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 Town Feature Additions to NewGRF Specifications in JGR's Patchpack in NML</h2>
<p>This document describes the non-standard additions to the <a href="https://newgrf-specs.tt-wiki.net/wiki/NML:Towns">town feature in the 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 directly referencing the town feature.<br />
Ordinarily this is only accessible as the parent scope for the features: stations, bridges, houses, industries, objects, road stops.</p>
<p>This feature may not necessarily match implementations 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_TOWN</span>.</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-town.html">non-NML document</a> for more details on the additions to the NewGRF town 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, the <span class="code">extended_feature_test(...)</span> function SHOULD be called with the specific feature(s) used 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="#town_variables">Variables</a></li>
<li><a href="#town_generic_callbacks">Generic Callbacks</a></li>
<li><a href="#town_example">Syntax example</a></li>
</ul></p>
<h3 id="town_variables">Additional Town Variables</h3>
<p>See <a href="https://newgrf-specs.tt-wiki.net/wiki/NML:Towns">NML town variables</a> for context.</p>
<table>
<tr><th>Name</th><th>Value range</th><th>Comment</th><th>Requires feature</th></tr>
<tr><td>num_houses_uncapped</td><td>0..4294967295</td><td>Number of town houses (not clamped to 0xFFFF)</td><td><font face="monospace">town_uncapped_variables</font>, version 1</td></tr>
<tr><td>population_uncapped</td><td>0..4294967295</td><td>Town population (not clamped to 0xFFFF)</td><td><font face="monospace">town_uncapped_variables</font>, version 1</td></tr>
<tr><td>town_zone_0_radius_square_uncapped</td><td>0..4294967295</td><td>Town zone 0 radius squared (not clamped to 0xFFFF)</td><td><font face="monospace">town_uncapped_variables</font>, version 1</td></tr>
<tr><td>town_zone_1_radius_square_uncapped</td><td>0..4294967295</td><td>Town zone 1 radius squared (not clamped to 0xFFFF)</td><td><font face="monospace">town_uncapped_variables</font>, version 1</td></tr>
<tr><td>town_zone_2_radius_square_uncapped</td><td>0..4294967295</td><td>Town zone 2 radius squared (not clamped to 0xFFFF)</td><td><font face="monospace">town_uncapped_variables</font>, version 1</td></tr>
<tr><td>town_zone_3_radius_square_uncapped</td><td>0..4294967295</td><td>Town zone 3 radius squared (not clamped to 0xFFFF)</td><td><font face="monospace">town_uncapped_variables</font>, version 1</td></tr>
<tr><td>town_zone_4_radius_square_uncapped</td><td>0..4294967295</td><td>Town zone 4 radius squared (not clamped to 0xFFFF)</td><td><font face="monospace">town_uncapped_variables</font>, version 1</td></tr>
</table>
<h3 id="town_generic_callbacks">Town Generic Callbacks</h3>
<p>Currently only the <font face="monospace">town_zone</font> callback is defined.<br />
This requires the feature: <font face="monospace">town_zone_callback</font>, version 1.
</p>
<pre class="code">
item (FEAT_TOWN, ..., GENERIC_CALLBACK) {
graphics {
town_zone: ...;
}
}
</pre>
<p>This callback is called whenever the zone radii of a town need to be recalculated.<br />
This can occur when:<br />
<ul>
<li>The number of houses in the town changes</li>
<li>When the game is loaded</li>
<li>When settings, NewGRFs or other relavant game configuration is changed</li>
</ul>
</p>
<p>The callback is not called if the town zone radii calculations have been manually overriden by settings.</p>
<p>The return value of the callback is the version of the result format returned by the callback.<br />
Currently only version 0 is defined.<br />
The callback must store the values of the town zone radii into registers: 0x100 to 0x104, for zones 0 to 4 respectively, using <font face="monospace">STORE_TEMP</font>.
</p>
<p>A callback failure result should be returned to use the default town zone radii calculation (or to allow another GRF to handle the callback).</p>
<p><b>The <font face="monospace">num_houses_uncapped</font> variable should be used instead of <font face="monospace">num_houses</font>, otherwise the results may be incorrect for large towns.</b><br />
Implementers of this callback may assume that the <font face="monospace">town_uncapped_variables</font> feature is present.</p>
<h3 id="town_example">Syntax example</h3>
<p>
<pre class="code">
grf {
...
}
if (!extended_feature_test("town_zone_callback")) {
error(FATAL, string(STR_UNSUPPORTED_VERSION));
}
switch (FEAT_TOWN, SELF, town_zone_cb,
[
STORE_TEMP(num_houses_uncapped * (is_city ? 32 : 16), 0x100),
STORE_TEMP((num_houses_uncapped >> 3) * 9, 0x101),
STORE_TEMP(0, 0x102),
STORE_TEMP((num_houses_uncapped >> 3) * 5, 0x103),
STORE_TEMP((num_houses_uncapped >> 3) * 3, 0x104)
]) {
return 0;
}
item (FEAT_TOWN, town_cb, GENERIC_CALLBACK) {
graphics {
town_zone: town_zone_cb;
}
}
</pre>
</p>
</body>
</html>

@ -0,0 +1,113 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>JGR's Patchpack - NewGRF Town Feature Additions 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 Town Feature Additions to NewGRF Specifications in JGR's Patchpack</h2>
<p>This document describes the non-standard additions to the <a href="https://newgrf-specs.tt-wiki.net/wiki/VariationalAction2/Towns">town feature in the Official OpenTTD NewGRF Specifications</a>, as implemented in this patchpack.</p>
<p>The town feature is ordinarily only accessible via the parent scope from the features: stations, bridges, houses, industries, objects, road stops.</p>
<p>Mapping a feature ID to the town feature allows referencing it directly, this is useful for:<br />
<ul>
<li>Mapping variables into the town feature using the <a href="newgrf-additions.html#variable-mapping">variable mapping mechanism</a>.</li>
<li>Generic town callbacks (town zone radii).</li>
</ul>
</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 town feature to a local feature ID.</p>
<p>This feature is indicated by the feature name: <font face="monospace">town_feature</font>, version 1.<br />
The feature name to use for feature ID mapping is <font face="monospace">town</font>.<br />
<p>This feature may not necessarily match implementations 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-town-nml.html">NML town feature</a> and <a href="newgrf-additions-nml.html">NML additions</a> documents for more details.</p>
<p><h3 id="actions">Actions:</h3>
<ul>
<li><a href="#varaction2town">Variational Action 2</a></li>
<li><a href="#a3town">Action 3</a></li>
</ul></p>
<h3 id="varaction2town">Variational Action 2 - Town</h3>
Note: non-variational action 2 sprites should ONLY be used to implement the return callback failure pattern.
<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>Mappable name</th><th>Description</th></tr>
<tr><td><a href="#town_house_count">town_house_count</a></td><td>Number of town houses</td></tr>
<tr><td><a href="#town_population">town_population</a></td><td>Town population</td></tr>
<tr><td><a href="#town_zone_N_radius_square">town_zone_0_radius_square</a></td><td>Town zone 0 radius squared</td></tr>
<tr><td><a href="#town_zone_N_radius_square">town_zone_1_radius_square</a></td><td>Town zone 1 radius squared</td></tr>
<tr><td><a href="#town_zone_N_radius_square">town_zone_2_radius_square</a></td><td>Town zone 2 radius squared</td></tr>
<tr><td><a href="#town_zone_N_radius_square">town_zone_3_radius_square</a></td><td>Town zone 3 radius squared</td></tr>
<tr><td><a href="#town_zone_N_radius_square">town_zone_4_radius_square</a></td><td>Town zone 4 radius squared</td></tr>
</table>
<h4 id="town_house_count">Number of town house (mappable variable: town_house_count)</h4>
<p>This is the same as <a href="https://newgrf-specs.tt-wiki.net/wiki/VariationalAction2/Towns">town variable B6</a>, except 32 bits and not clamped to a maximum value of 0xFFFF.</p>
<p>This requires <font face="monospace">town_uncapped_variables</font>, version 1.</p>
<h4 id="town_population">Town population (mappable variable: town_population)</h4>
<p>This is the same as <a href="https://newgrf-specs.tt-wiki.net/wiki/VariationalAction2/Towns">town variable 82</a>, except 32 bits and not clamped to a maximum value of 0xFFFF.</p>
<p>This requires <font face="monospace">town_uncapped_variables</font>, version 1.</p>
<h4 id="town_zone_N_radius_square">Town zone [0 .. 4] radius squared (mappable variable: town_zone_0_radius_square, town_zone_1_radius_square, town_zone_2_radius_square, town_zone_3_radius_square, town_zone_4_radius_square)</h4>
<p>This is the same as <a href="https://newgrf-specs.tt-wiki.net/wiki/VariationalAction2/Towns">town variables 94, 96, 98, 9A, 9C</a>, except 32 bits and not clamped to a maximum value of 0xFFFF.</p>
<p>This requires <font face="monospace">town_uncapped_variables</font>, version 1.</p>
<br />
<h3 id="a3town">Action 3 - Town</h3>
<p>See the <a href="https://newgrf-specs.tt-wiki.net/wiki/Action3">Action 3 Specification</a> for background information.</p>
<p>Only generic callbacks are supported, the "number of IDs" field in the action 3 must be set to 0.</p>
<p>The variational action 2 sprite group referenced must be a callback handler which properly branches on the value of callback variable 0C.</p>
<p>The following callbacks are defined:</p>
<table>
<tr><th>Callback ID</th><th>Purpose</th><th>Enabled if</th></tr>
<tr><td><a href="#town_zone_cb">0xEC008001</a></td><td>Custom town zone radii</td><td>The <font face="monospace">town_zone_callback</font> feature is tested for</td></tr>
</table>
<h4 id="town_zone_cb">Town zone radii callback 0xEC008001:</h4>
<p>The <font face="monospace">town_zone_callback</font> feature must be tested for to enable this generic callback.</p>
<p>This callback is called whenever the zone radii of a town need to be recalculated.<br />
This can occur when:<br />
<ul>
<li>The number of houses in the town changes</li>
<li>When the game is loaded</li>
<li>When settings, NewGRFs or other relavant game configuration is changed</li>
</ul>
</p>
<p>The callback is not called if the town zone radii calculations have been manually overriden by settings.</p>
<p>The return value of the callback is the version of the result format returned by the callback.<br />
Currently only version 0 is defined.<br />
The callback must store the values of the town zone radii into registers: 0x100 to 0x104, for zones 0 to 4 respectively.
</p>
<p>A callback failure result should be returned to use the default town zone radii calculation (or to allow another GRF to handle the callback).</p>
<p><b>The <a href="#town_house_count">town_house_count</a> variable should be used instead of variable B6, otherwise the results may be incorrect for large towns.</b><br />
Implementers of this callback may assume that the <font face="monospace">town_uncapped_variables</font> feature is present.</p>
</body>
</html>
Loading…
Cancel
Save