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/>.
9 * @file newgrf_townname.cpp
10 * Implementation of Action 0F "universal holder" structure and functions.
11 * This file implements a linked-lists of townname generators,
12 * holding everything that the newgrf action 0F will send over to OpenTTD.
16 #include "newgrf_townname.h"
17 #include "core/alloc_func.hpp"
18 #include "string_func.h"
19 #include "strings_internal.h"
21 #include "table/strings.h"
23 #include "safeguards.h"
25 static std::vector
<GRFTownName
> _grf_townnames
;
26 static std::vector
<StringID
> _grf_townname_names
;
28 GRFTownName
*GetGRFTownName(uint32_t grfid
)
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
;
35 GRFTownName
*AddGRFTownName(uint32_t grfid
)
37 GRFTownName
*t
= GetGRFTownName(grfid
);
39 t
= &_grf_townnames
.emplace_back();
45 void DelGRFTownName(uint32_t grfid
)
47 _grf_townnames
.erase(std::find_if(std::begin(_grf_townnames
), std::end(_grf_townnames
), [&grfid
](const GRFTownName
&t
){ return t
.grfid
== grfid
; }));
50 static void RandomPart(StringBuilder
&builder
, const GRFTownName
*t
, uint32_t seed
, byte id
)
53 for (const auto &partlist
: t
->partlists
[id
]) {
54 byte 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
);
70 void GRFTownNameGenerate(StringBuilder
&builder
, uint32_t grfid
, uint16_t gen
, uint32_t seed
)
72 const GRFTownName
*t
= GetGRFTownName(grfid
);
74 assert(gen
< t
->styles
.size());
75 RandomPart(builder
, t
, seed
, t
->styles
[gen
].id
);
80 /** Allocate memory for the NewGRF town names. */
81 void InitGRFTownGeneratorNames()
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
);
91 const std::vector
<StringID
> &GetGRFTownNameList()
93 return _grf_townname_names
;
96 StringID
GetGRFTownNameName(uint16_t gen
)
98 return gen
< _grf_townname_names
.size() ? _grf_townname_names
[gen
] : STR_UNDEFINED
;
101 void CleanUpGRFTownNames()
103 _grf_townnames
.clear();
106 uint32_t GetGRFTownNameId(uint16_t gen
)
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());
112 /* Fallback to no NewGRF */
116 uint16_t GetGRFTownNameType(uint16_t gen
)
118 for (const auto &t
: _grf_townnames
) {
119 if (gen
< t
.styles
.size()) return gen
;
120 gen
-= static_cast<uint16_t>(t
.styles
.size());
122 /* Fallback to english original */
123 return SPECSTR_TOWNNAME_ENGLISH
;