OpenTTD Source  20241121-master-g67a0fccfad
newgrf_townname.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 
15 #include "stdafx.h"
16 #include "newgrf_townname.h"
17 #include "core/alloc_func.hpp"
18 #include "string_func.h"
19 #include "strings_internal.h"
20 
21 #include "table/strings.h"
22 
23 #include "safeguards.h"
24 
25 static std::vector<GRFTownName> _grf_townnames;
26 static std::vector<StringID> _grf_townname_names;
27 
28 GRFTownName *GetGRFTownName(uint32_t grfid)
29 {
30  auto found = std::find_if(std::begin(_grf_townnames), std::end(_grf_townnames), [&grfid](const GRFTownName &t) { return t.grfid == grfid; });
31  if (found != std::end(_grf_townnames)) return &*found;
32  return nullptr;
33 }
34 
35 GRFTownName *AddGRFTownName(uint32_t grfid)
36 {
37  GRFTownName *t = GetGRFTownName(grfid);
38  if (t == nullptr) {
39  t = &_grf_townnames.emplace_back();
40  t->grfid = grfid;
41  }
42  return t;
43 }
44 
45 void DelGRFTownName(uint32_t grfid)
46 {
47  _grf_townnames.erase(std::find_if(std::begin(_grf_townnames), std::end(_grf_townnames), [&grfid](const GRFTownName &t) { return t.grfid == grfid; }));
48 }
49 
50 static void RandomPart(StringBuilder &builder, const GRFTownName *t, uint32_t seed, uint8_t id)
51 {
52  assert(t != nullptr);
53  for (const auto &partlist : t->partlists[id]) {
54  uint8_t count = partlist.bitcount;
55  uint16_t maxprob = partlist.maxprob;
56  uint32_t r = (GB(seed, partlist.bitstart, count) * maxprob) >> count;
57  for (const auto &part : partlist.parts) {
58  maxprob -= GB(part.prob, 0, 7);
59  if (maxprob > r) continue;
60  if (HasBit(part.prob, 7)) {
61  RandomPart(builder, t, seed, part.id);
62  } else {
63  builder += part.text;
64  }
65  break;
66  }
67  }
68 }
69 
70 void GRFTownNameGenerate(StringBuilder &builder, uint32_t grfid, uint16_t gen, uint32_t seed)
71 {
72  const GRFTownName *t = GetGRFTownName(grfid);
73  if (t != nullptr) {
74  assert(gen < t->styles.size());
75  RandomPart(builder, t, seed, t->styles[gen].id);
76  }
77 }
78 
79 
82 {
83  _grf_townname_names.clear();
84  for (const auto &t : _grf_townnames) {
85  for (const auto &style : t.styles) {
86  _grf_townname_names.push_back(style.name);
87  }
88  }
89 }
90 
91 const std::vector<StringID> &GetGRFTownNameList()
92 {
93  return _grf_townname_names;
94 }
95 
96 StringID GetGRFTownNameName(uint16_t gen)
97 {
98  return gen < _grf_townname_names.size() ? _grf_townname_names[gen] : STR_UNDEFINED;
99 }
100 
101 void CleanUpGRFTownNames()
102 {
103  _grf_townnames.clear();
104 }
105 
106 uint32_t GetGRFTownNameId(uint16_t gen)
107 {
108  for (const auto &t : _grf_townnames) {
109  if (gen < t.styles.size()) return t.grfid;
110  gen -= static_cast<uint16_t>(t.styles.size());
111  }
112  /* Fallback to no NewGRF */
113  return 0;
114 }
115 
116 uint16_t GetGRFTownNameType(uint16_t gen)
117 {
118  for (const auto &t : _grf_townnames) {
119  if (gen < t.styles.size()) return gen;
120  gen -= static_cast<uint16_t>(t.styles.size());
121  }
122  /* Fallback to english original */
123  return SPECSTR_TOWNNAME_ENGLISH;
124 }
Functions related to the allocation of memory.
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr static debug_inline uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
Equivalent to the std::back_insert_iterator in function, with some convenience helpers for string con...
void InitGRFTownGeneratorNames()
Allocate memory for the NewGRF town names.
Header of Action 0F "universal holder" structure and functions.
A number of safeguards to prevent using unsafe methods.
Definition of base types and functions in a cross-platform compatible way.
Functions related to low-level strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
std::vector< NamePartList > partlists[MAX_LISTS]
Lists of town name parts.
std::vector< TownNameStyle > styles
Style names defined by the Town Name NewGRF.
uint32_t grfid
GRF ID of NewGRF.