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"
20 #include "table/strings.h"
22 #include "safeguards.h"
24 static GRFTownName
*_grf_townnames
= nullptr;
25 static std::vector
<StringID
> _grf_townname_names
;
27 GRFTownName
*GetGRFTownName(uint32 grfid
)
29 GRFTownName
*t
= _grf_townnames
;
30 for (; t
!= nullptr; t
= t
->next
) {
31 if (t
->grfid
== grfid
) return t
;
36 GRFTownName
*AddGRFTownName(uint32 grfid
)
38 GRFTownName
*t
= GetGRFTownName(grfid
);
40 t
= CallocT
<GRFTownName
>(1);
42 t
->next
= _grf_townnames
;
48 void DelGRFTownName(uint32 grfid
)
50 GRFTownName
*t
= _grf_townnames
;
51 GRFTownName
*p
= nullptr;
52 for (;t
!= nullptr; p
= t
, t
= t
->next
) if (t
->grfid
== grfid
) break;
54 for (int i
= 0; i
< 128; i
++) {
55 for (int j
= 0; j
< t
->nbparts
[i
]; j
++) {
56 for (int k
= 0; k
< t
->partlist
[i
][j
].partcount
; k
++) {
57 if (!HasBit(t
->partlist
[i
][j
].parts
[k
].prob
, 7)) free(t
->partlist
[i
][j
].parts
[k
].data
.text
);
59 free(t
->partlist
[i
][j
].parts
);
66 _grf_townnames
= t
->next
;
72 static char *RandomPart(char *buf
, GRFTownName
*t
, uint32 seed
, byte id
, const char *last
)
75 for (int i
= 0; i
< t
->nbparts
[id
]; i
++) {
76 byte count
= t
->partlist
[id
][i
].bitcount
;
77 uint16 maxprob
= t
->partlist
[id
][i
].maxprob
;
78 uint32 r
= (GB(seed
, t
->partlist
[id
][i
].bitstart
, count
) * maxprob
) >> count
;
79 for (int j
= 0; j
< t
->partlist
[id
][i
].partcount
; j
++) {
80 byte prob
= t
->partlist
[id
][i
].parts
[j
].prob
;
81 maxprob
-= GB(prob
, 0, 7);
82 if (maxprob
> r
) continue;
83 if (HasBit(prob
, 7)) {
84 buf
= RandomPart(buf
, t
, seed
, t
->partlist
[id
][i
].parts
[j
].data
.id
, last
);
86 buf
= strecat(buf
, t
->partlist
[id
][i
].parts
[j
].data
.text
, last
);
94 char *GRFTownNameGenerate(char *buf
, uint32 grfid
, uint16 gen
, uint32 seed
, const char *last
)
96 strecpy(buf
, "", last
);
97 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) {
98 if (t
->grfid
== grfid
) {
99 assert(gen
< t
->nb_gen
);
100 buf
= RandomPart(buf
, t
, seed
, t
->id
[gen
], last
);
108 /** Allocate memory for the NewGRF town names. */
109 void InitGRFTownGeneratorNames()
111 _grf_townname_names
.clear();
112 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) {
113 for (int j
= 0; j
< t
->nb_gen
; j
++) _grf_townname_names
.push_back(t
->name
[j
]);
117 const std::vector
<StringID
>& GetGRFTownNameList()
119 return _grf_townname_names
;
122 StringID
GetGRFTownNameName(uint gen
)
124 return gen
< _grf_townname_names
.size() ? _grf_townname_names
[gen
] : STR_UNDEFINED
;
127 void CleanUpGRFTownNames()
129 while (_grf_townnames
!= nullptr) DelGRFTownName(_grf_townnames
->grfid
);
132 uint32
GetGRFTownNameId(int gen
)
134 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) {
135 if (gen
< t
->nb_gen
) return t
->grfid
;
138 /* Fallback to no NewGRF */
142 uint16
GetGRFTownNameType(int gen
)
144 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) {
145 if (gen
< t
->nb_gen
) return gen
;
148 /* Fallback to english original */
149 return SPECSTR_TOWNNAME_ENGLISH
;