1 /* $Id: newgrf_townname.cpp 20283 2010-08-01 19:22:34Z frosch $ */
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
11 * @file newgrf_townname.cpp
12 * Implementation of Action 0F "universal holder" structure and functions.
13 * This file implements a linked-lists of townname generators,
14 * holding everything that the newgrf action 0F will send over to OpenTTD.
18 #include "newgrf_townname.h"
19 #include "core/alloc_func.hpp"
20 #include "string_func.h"
22 #include "safeguards.h"
24 static GRFTownName
*_grf_townnames
= nullptr;
26 GRFTownName
*GetGRFTownName(uint32 grfid
)
28 GRFTownName
*t
= _grf_townnames
;
29 for (; t
!= nullptr; t
= t
->next
) {
30 if (t
->grfid
== grfid
) return t
;
35 GRFTownName
*AddGRFTownName(uint32 grfid
)
37 GRFTownName
*t
= GetGRFTownName(grfid
);
39 t
= CallocT
<GRFTownName
>(1);
41 t
->next
= _grf_townnames
;
47 void DelGRFTownName(uint32 grfid
)
49 GRFTownName
*t
= _grf_townnames
;
50 GRFTownName
*p
= nullptr;
51 for (;t
!= nullptr; p
= t
, t
= t
->next
) if (t
->grfid
== grfid
) break;
53 for (int i
= 0; i
< 128; i
++) {
54 for (int j
= 0; j
< t
->nbparts
[i
]; j
++) {
55 for (int k
= 0; k
< t
->partlist
[i
][j
].partcount
; k
++) {
56 if (!HasBit(t
->partlist
[i
][j
].parts
[k
].prob
, 7)) free(t
->partlist
[i
][j
].parts
[k
].data
.text
);
58 free(t
->partlist
[i
][j
].parts
);
65 _grf_townnames
= t
->next
;
71 static char *RandomPart(char *buf
, GRFTownName
*t
, uint32 seed
, byte id
, const char *last
)
74 for (int i
= 0; i
< t
->nbparts
[id
]; i
++) {
75 byte count
= t
->partlist
[id
][i
].bitcount
;
76 uint16 maxprob
= t
->partlist
[id
][i
].maxprob
;
77 uint32 r
= (GB(seed
, t
->partlist
[id
][i
].bitstart
, count
) * maxprob
) >> count
;
78 for (int j
= 0; j
< t
->partlist
[id
][i
].partcount
; j
++) {
79 byte prob
= t
->partlist
[id
][i
].parts
[j
].prob
;
80 maxprob
-= GB(prob
, 0, 7);
81 if (maxprob
> r
) continue;
82 if (HasBit(prob
, 7)) {
83 buf
= RandomPart(buf
, t
, seed
, t
->partlist
[id
][i
].parts
[j
].data
.id
, last
);
85 buf
= strecat(buf
, t
->partlist
[id
][i
].parts
[j
].data
.text
, last
);
93 char *GRFTownNameGenerate(char *buf
, uint32 grfid
, uint16 gen
, uint32 seed
, const char *last
)
95 strecpy(buf
, "", last
);
96 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) {
97 if (t
->grfid
== grfid
) {
98 assert(gen
< t
->nb_gen
);
99 buf
= RandomPart(buf
, t
, seed
, t
->id
[gen
], last
);
106 StringID
*GetGRFTownNameList()
108 int nb_names
= 0, n
= 0;
109 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) nb_names
+= t
->nb_gen
;
110 StringID
*list
= MallocT
<StringID
>(nb_names
+ 1);
111 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) {
112 for (int j
= 0; j
< t
->nb_gen
; j
++) list
[n
++] = t
->name
[j
];
114 list
[n
] = INVALID_STRING_ID
;
118 void CleanUpGRFTownNames()
120 while (_grf_townnames
!= nullptr) DelGRFTownName(_grf_townnames
->grfid
);
123 uint32
GetGRFTownNameId(int gen
)
125 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) {
126 if (gen
< t
->nb_gen
) return t
->grfid
;
129 /* Fallback to no NewGRF */
133 uint16
GetGRFTownNameType(int gen
)
135 for (GRFTownName
*t
= _grf_townnames
; t
!= nullptr; t
= t
->next
) {
136 if (gen
< t
->nb_gen
) return gen
;
139 /* Fallback to english original */
140 return SPECSTR_TOWNNAME_ENGLISH
;