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 "safeguards.h"
22 static GRFTownName
*_grf_townnames
= nullptr;
24 GRFTownName
*GetGRFTownName(uint32 grfid
)
26 GRFTownName
*t
= _grf_townnames
;
27 for (; t
!= nullptr; t
= t
->next
) {
28 if (t
->grfid
== grfid
) return t
;
33 GRFTownName
*AddGRFTownName(uint32 grfid
)
35 GRFTownName
*t
= GetGRFTownName(grfid
);
37 t
= CallocT
<GRFTownName
>(1);
39 t
->next
= _grf_townnames
;
45 void DelGRFTownName(uint32 grfid
)
47 GRFTownName
*t
= _grf_townnames
;
48 GRFTownName
*p
= nullptr;
49 for (;t
!= nullptr; p
= t
, t
= t
->next
) if (t
->grfid
== grfid
) break;
51 for (int i
= 0; i
< 128; i
++) {
52 for (int j
= 0; j
< t
->nbparts
[i
]; j
++) {
53 for (int k
= 0; k
< t
->partlist
[i
][j
].partcount
; k
++) {
54 if (!HasBit(t
->partlist
[i
][j
].parts
[k
].prob
, 7)) free(t
->partlist
[i
][j
].parts
[k
].data
.text
);
56 free(t
->partlist
[i
][j
].parts
);
63 _grf_townnames
= t
->next
;
69 static char *RandomPart(char *buf
, GRFTownName
*t
, uint32 seed
, byte id
, const char *last
)
72 for (int i
= 0; i
< t
->nbparts
[id
]; i
++) {
73 byte count
= t
->partlist
[id
][i
].bitcount
;
74 uint16 maxprob
= t
->partlist
[id
][i
].maxprob
;
75 uint32 r
= (GB(seed
, t
->partlist
[id
][i
].bitstart
, count
) * maxprob
) >> count
;
76 for (int j
= 0; j
< t
->partlist
[id
][i
].partcount
; j
++) {
77 byte prob
= t
->partlist
[id
][i
].parts
[j
].prob
;
78 maxprob
-= GB(prob
, 0, 7);
79 if (maxprob
> r
) continue;
80 if (HasBit(prob
, 7)) {
81 buf
= RandomPart(buf
, t
, seed
, t
->partlist
[id
][i
].parts
[j
].data
.id
, last
);
83 buf
= strecat(buf
, t
->partlist
[id
][i
].parts
[j
].data
.text
, last
);
91 char *GRFTownNameGenerate(char *buf
, uint32 grfid
, uint16 gen
, uint32 seed
, const char *last
)
93 strecpy(buf
, "", last
);
94 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) {
95 if (t
->grfid
== grfid
) {
96 assert(gen
< t
->nb_gen
);
97 buf
= RandomPart(buf
, t
, seed
, t
->id
[gen
], last
);
104 StringID
*GetGRFTownNameList()
106 int nb_names
= 0, n
= 0;
107 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) nb_names
+= t
->nb_gen
;
108 StringID
*list
= MallocT
<StringID
>(nb_names
+ 1);
109 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) {
110 for (int j
= 0; j
< t
->nb_gen
; j
++) list
[n
++] = t
->name
[j
];
112 list
[n
] = INVALID_STRING_ID
;
116 void CleanUpGRFTownNames()
118 while (_grf_townnames
!= nullptr) DelGRFTownName(_grf_townnames
->grfid
);
121 uint32
GetGRFTownNameId(int gen
)
123 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) {
124 if (gen
< t
->nb_gen
) return t
->grfid
;
127 /* Fallback to no NewGRF */
131 uint16
GetGRFTownNameType(int gen
)
133 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) {
134 if (gen
< t
->nb_gen
) return gen
;
137 /* Fallback to english original */
138 return SPECSTR_TOWNNAME_ENGLISH
;