OpenTTD Source 20250331-master-g3c15e0c889
newgrf_actf.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
6 */
7
10#include "../stdafx.h"
11#include "../debug.h"
12#include "../newgrf_townname.h"
13#include "newgrf_bytereader.h"
14#include "newgrf_internal.h"
15
16#include "table/strings.h"
17
18#include "../safeguards.h"
19
21static void FeatureTownName(ByteReader &buf)
22{
23 /* <0F> <id> <style-name> <num-parts> <parts>
24 *
25 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
26 * V style-name Name of the style (only for final definition)
27 * B num-parts Number of parts in this definition
28 * V parts The parts */
29
30 uint32_t grfid = _cur.grffile->grfid;
31
32 GRFTownName *townname = AddGRFTownName(grfid);
33
34 uint8_t id = buf.ReadByte();
35 GrfMsg(6, "FeatureTownName: definition 0x{:02X}", id & 0x7F);
36
37 if (HasBit(id, 7)) {
38 /* Final definition */
39 ClrBit(id, 7);
40 bool new_scheme = _cur.grffile->grf_version >= 7;
41
42 uint8_t lang = buf.ReadByte();
43 StringID style = STR_UNDEFINED;
44
45 do {
46 ClrBit(lang, 7);
47
48 std::string_view name = buf.ReadString();
49
50 std::string lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
51 GrfMsg(6, "FeatureTownName: lang 0x{:X} -> '{}'", lang, lang_name);
52
53 style = AddGRFString(grfid, GRFStringID{id}, lang, new_scheme, false, name, STR_UNDEFINED);
54
55 lang = buf.ReadByte();
56 } while (lang != 0);
57 townname->styles.emplace_back(style, id);
58 }
59
60 uint8_t parts = buf.ReadByte();
61 GrfMsg(6, "FeatureTownName: {} parts", parts);
62
63 townname->partlists[id].reserve(parts);
64 for (uint partnum = 0; partnum < parts; partnum++) {
65 NamePartList &partlist = townname->partlists[id].emplace_back();
66 uint8_t texts = buf.ReadByte();
67 partlist.bitstart = buf.ReadByte();
68 partlist.bitcount = buf.ReadByte();
69 partlist.maxprob = 0;
70 GrfMsg(6, "FeatureTownName: part {} contains {} texts and will use GB(seed, {}, {})", partnum, texts, partlist.bitstart, partlist.bitcount);
71
72 partlist.parts.reserve(texts);
73 for (uint textnum = 0; textnum < texts; textnum++) {
74 NamePart &part = partlist.parts.emplace_back();
75 part.prob = buf.ReadByte();
76
77 if (HasBit(part.prob, 7)) {
78 uint8_t ref_id = buf.ReadByte();
79 if (ref_id >= GRFTownName::MAX_LISTS || townname->partlists[ref_id].empty()) {
80 GrfMsg(0, "FeatureTownName: definition 0x{:02X} doesn't exist, deactivating", ref_id);
81 DelGRFTownName(grfid);
82 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
83 return;
84 }
85 part.id = ref_id;
86 GrfMsg(6, "FeatureTownName: part {}, text {}, uses intermediate definition 0x{:02X} (with probability {})", partnum, textnum, ref_id, part.prob & 0x7F);
87 } else {
88 std::string_view text = buf.ReadString();
89 part.text = TranslateTTDPatchCodes(grfid, 0, false, text);
90 GrfMsg(6, "FeatureTownName: part {}, text {}, '{}' (with probability {})", partnum, textnum, part.text, part.prob);
91 }
92 partlist.maxprob += GB(part.prob, 0, 7);
93 }
94 GrfMsg(6, "FeatureTownName: part {}, total probability {}", partnum, partlist.maxprob);
95 }
96}
97
98template <> void GrfActionHandler<0x0F>::FileScan(ByteReader &) { }
99template <> void GrfActionHandler<0x0F>::SafetyScan(ByteReader &buf) { GRFUnsafe(buf); }
100template <> void GrfActionHandler<0x0F>::LabelScan(ByteReader &) { }
101template <> void GrfActionHandler<0x0F>::Init(ByteReader &buf) { FeatureTownName(buf); }
102template <> void GrfActionHandler<0x0F>::Reserve(ByteReader &) { }
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
Class to read from a NewGRF file.
std::string_view ReadString()
Read a string.
uint8_t ReadByte()
Read a single byte (8 bits).
void GRFUnsafe(ByteReader &)
Set the current NewGRF as unsafe for static use.
Definition newgrf.cpp:365
GRFError * DisableGrf(StringID message, GRFConfig *config)
Disable a GRF.
Definition newgrf.cpp:131
static void FeatureTownName(ByteReader &buf)
Action 0x0F - Define Town names.
NewGRF buffer reader definition.
NewGRF internal processing state.
std::string TranslateTTDPatchCodes(uint32_t grfid, uint8_t language_id, bool allow_newlines, std::string_view str, StringControlCode byte80)
Translate TTDPatch string codes into something OpenTTD can handle (better).
StringID AddGRFString(uint32_t grfid, GRFStringID stringid, uint8_t langid_to_add, bool new_scheme, bool allow_newlines, std::string_view text_to_add, StringID def_string)
Add the new read string into our structure.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
std::vector< NamePartList > partlists[MAX_LISTS]
Lists of town name parts.
static const uint MAX_LISTS
Maximum number of town name lists that can be defined per GRF.
std::vector< TownNameStyle > styles
Style names defined by the Town Name NewGRF.
GRF action handler.
GRFFile * grffile
Currently processed GRF file.
uint8_t bitcount
Number of bits of random seed to use.
uint16_t maxprob
Total probability of all parts.
std::vector< NamePart > parts
List of parts to choose from.
uint8_t bitstart
Start of random seed bits to use.
uint8_t prob
The relative probability of the following name to appear in the bottom 7 bits.
uint8_t id
If probability bit 7 is set.
std::string text
If probability bit 7 is clear.