OpenTTD: src/saveload/company_sl.cpp Source File

OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

company_sl.cpp
Go to the documentation of this file.
1 /* $Id: company_sl.cpp 27893 2017-08-13 18:38:42Z frosch $ */
2
3 /*
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/>.
8 */
9
12 #include "../stdafx.h"
13 #include "../company_func.h"
14 #include "../company_manager_face.h"
15 #include "../fios.h"
16 #include "../tunnelbridge_map.h"
17 #include "../tunnelbridge.h"
18 #include "../station_base.h"
19 #include "../strings_func.h"
20
21 #include "saveload.h"
22
23 #include "table/strings.h"
24
25 #include "../safeguards.h"
26
45 CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face)
46 {
47 CompanyManagerFace cmf = 0;
48 GenderEthnicity ge = GE_WM;
49
50 if (HasBit(face, 31)) SetBit(ge, GENDER_FEMALE);
51 if (HasBit(face, 27) && (HasBit(face, 26) == HasBit(face, 19))) SetBit(ge, ETHNICITY_BLACK);
52
53 SetCompanyManagerFaceBits(cmf, CMFV_GEN_ETHN, ge, ge);
54 SetCompanyManagerFaceBits(cmf, CMFV_HAS_GLASSES, ge, GB(face, 28, 3) <= 1);
55 SetCompanyManagerFaceBits(cmf, CMFV_EYE_COLOUR, ge, HasBit(ge, ETHNICITY_BLACK) ? 0 : ClampU(GB(face, 20, 3), 5, 7) - 5);
56 SetCompanyManagerFaceBits(cmf, CMFV_CHIN, ge, ScaleCompanyManagerFaceValue(CMFV_CHIN, ge, GB(face, 4, 2)));
57 SetCompanyManagerFaceBits(cmf, CMFV_EYEBROWS, ge, ScaleCompanyManagerFaceValue(CMFV_EYEBROWS, ge, GB(face, 6, 4)));
58 SetCompanyManagerFaceBits(cmf, CMFV_HAIR, ge, ScaleCompanyManagerFaceValue(CMFV_HAIR, ge, GB(face, 16, 4)));
59 SetCompanyManagerFaceBits(cmf, CMFV_JACKET, ge, ScaleCompanyManagerFaceValue(CMFV_JACKET, ge, GB(face, 20, 2)));
60 SetCompanyManagerFaceBits(cmf, CMFV_COLLAR, ge, ScaleCompanyManagerFaceValue(CMFV_COLLAR, ge, GB(face, 22, 2)));
61 SetCompanyManagerFaceBits(cmf, CMFV_GLASSES, ge, GB(face, 28, 1));
62
63 uint lips = GB(face, 10, 4);
64 if (!HasBit(ge, GENDER_FEMALE) && lips < 4) {
65 SetCompanyManagerFaceBits(cmf, CMFV_HAS_MOUSTACHE, ge, true);
66 SetCompanyManagerFaceBits(cmf, CMFV_MOUSTACHE, ge, max(lips, 1U) - 1);
67 } else {
68 if (!HasBit(ge, GENDER_FEMALE)) {
69 lips = lips * 15 / 16;
70 lips -= 3;
71 if (HasBit(ge, ETHNICITY_BLACK) && lips > 8) lips = 0;
72 } else {
73 lips = ScaleCompanyManagerFaceValue(CMFV_LIPS, ge, lips);
74 }
75 SetCompanyManagerFaceBits(cmf, CMFV_LIPS, ge, lips);
76
77 uint nose = GB(face, 13, 3);
78 if (ge == GE_WF) {
79 nose = (nose * 3 >> 3) * 3 >> 2; // There is 'hole' in the nose sprites for females
80 } else {
81 nose = ScaleCompanyManagerFaceValue(CMFV_NOSE, ge, nose);
82 }
83 SetCompanyManagerFaceBits(cmf, CMFV_NOSE, ge, nose);
84 }
85
86 uint tie_earring = GB(face, 24, 4);
87 if (!HasBit(ge, GENDER_FEMALE) || tie_earring < 3) { // Not all females have an earring
88 if (HasBit(ge, GENDER_FEMALE)) SetCompanyManagerFaceBits(cmf, CMFV_HAS_TIE_EARRING, ge, true);
89 SetCompanyManagerFaceBits(cmf, CMFV_TIE_EARRING, ge, HasBit(ge, GENDER_FEMALE) ? tie_earring : ScaleCompanyManagerFaceValue(CMFV_TIE_EARRING, ge, tie_earring / 2));
90 }
91
92 return cmf;
93 }
94
96 void AfterLoadCompanyStats()
97 {
98 /* Reset infrastructure statistics to zero. */
99 Company *c;
100 FOR_ALL_COMPANIES(c) MemSetT(&c->infrastructure, 0);
101
102 /* Collect airport count. */
103 Station *st;
104 FOR_ALL_STATIONS(st) {
105 if ((st->facilities & FACIL_AIRPORT) && Company::IsValidID(st->owner)) {
106 Company::Get(st->owner)->infrastructure.airport++;
107 }
108 }
109
110 for (TileIndex tile = 0; tile < MapSize(); tile++) {
111 switch (GetTileType(tile)) {
112 case MP_RAILWAY:
113 c = Company::GetIfValid(GetTileOwner(tile));
114 if (c != NULL) {
115 uint pieces = 1;
116 if (IsPlainRail(tile)) {
117 TrackBits bits = GetTrackBits(tile);
118 pieces = CountBits(bits);
119 if (TracksOverlap(bits)) pieces *= pieces;
120 }
121 c->infrastructure.rail[GetRailType(tile)] += pieces;
122
123 if (HasSignals(tile)) c->infrastructure.signal += CountBits(GetPresentSignals(tile));
124 }
125 break;
126
127 case MP_ROAD: {
128 if (IsLevelCrossing(tile)) {
129 c = Company::GetIfValid(GetTileOwner(tile));
130 if (c != NULL) c->infrastructure.rail[GetRailType(tile)] += LEVELCROSSING_TRACKBIT_FACTOR;
131 }
132
133 /* Iterate all present road types as each can have a different owner. */
134 RoadType rt;
135 FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) {
136 c = Company::GetIfValid(IsRoadDepot(tile) ? GetTileOwner(tile) : GetRoadOwner(tile, rt));
137 /* A level crossings and depots have two road bits. */
138 if (c != NULL) c->infrastructure.road[rt] += IsNormalRoad(tile) ? CountBits(GetRoadBits(tile, rt)) : 2;
139 }
140 break;
141 }
142
143 case MP_STATION:
144 c = Company::GetIfValid(GetTileOwner(tile));
145 if (c != NULL && GetStationType(tile) != STATION_AIRPORT && !IsBuoy(tile)) c->infrastructure.station++;
146
147 switch (GetStationType(tile)) {
148 case STATION_RAIL:
149 case STATION_WAYPOINT:
150 if (c != NULL && !IsStationTileBlocked(tile)) c->infrastructure.rail[GetRailType(tile)]++;
151 break;
152
153 case STATION_BUS:
154 case STATION_TRUCK: {
155 /* Iterate all present road types as each can have a different owner. */
156 RoadType rt;
157 FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) {
158 c = Company::GetIfValid(GetRoadOwner(tile, rt));
159 if (c != NULL) c->infrastructure.road[rt] += 2; // A road stop has two road bits.
160 }
161 break;
162 }
163
164 case STATION_DOCK:
165 case STATION_BUOY:
166 if (GetWaterClass(tile) == WATER_CLASS_CANAL) {
167 if (c != NULL) c->infrastructure.water++;
168 }
169 break;
170
171 default:
172 break;
173 }
174 break;
175
176 case MP_WATER:
177 if (IsShipDepot(tile) || IsLock(tile)) {
178 c = Company::GetIfValid(GetTileOwner(tile));
179 if (c != NULL) {
180 if (IsShipDepot(tile)) c->infrastructure.water += LOCK_DEPOT_TILE_FACTOR;
181 if (IsLock(tile) && GetLockPart(tile) == LOCK_PART_MIDDLE) {
182 /* The middle tile specifies the owner of the lock. */
183 c->infrastructure.water += 3 * LOCK_DEPOT_TILE_FACTOR; // the middle tile specifies the owner of the
184 break; // do not count the middle tile as canal
185 }
186 }
187 }
188 FALLTHROUGH;
189
190 case MP_OBJECT:
191 if (GetWaterClass(tile) == WATER_CLASS_CANAL) {
192 c = Company::GetIfValid(GetTileOwner(tile));
193 if (c != NULL) c->infrastructure.water++;
194 }
195 break;
196
197 case MP_TUNNELBRIDGE: {
198 /* Only count the tunnel/bridge if we're on the northern end tile. */
199 TileIndex other_end = GetOtherTunnelBridgeEnd(tile);
200 if (tile < other_end) {
201 /* Count each tunnel/bridge TUNNELBRIDGE_TRACKBIT_FACTOR times to simulate
202 * the higher structural maintenance needs, and don't forget the end tiles. */
203 uint len = (GetTunnelBridgeLength(tile, other_end) + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR;
204
205 switch (GetTunnelBridgeTransportType(tile)) {
206 case TRANSPORT_RAIL:
207 c = Company::GetIfValid(GetTileOwner(tile));
208 if (c != NULL) c->infrastructure.rail[GetRailType(tile)] += len;
209 break;
210
211 case TRANSPORT_ROAD: {
212 /* Iterate all present road types as each can have a different owner. */
213 RoadType rt;
214 FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) {
215 c = Company::GetIfValid(GetRoadOwner(tile, rt));
216 if (c != NULL) c->infrastructure.road[rt] += len * 2; // A full diagonal road has two road bits.
217 }
218 break;
219 }
220
221 case TRANSPORT_WATER:
222 c = Company::GetIfValid(GetTileOwner(tile));
223 if (c != NULL) c->infrastructure.water += len;
224 break;
225
226 default:
227 break;
228 }
229 }
230 break;
231 }
232
233 default:
234 break;
235 }
236 }
237 }
238
239
240
241 /* Save/load of companies */
242 static const SaveLoad _company_desc[] = {
243 SLE_VAR(CompanyProperties, name_2, SLE_UINT32),
244 SLE_VAR(CompanyProperties, name_1, SLE_STRINGID),
245 SLE_CONDSTR(CompanyProperties, name, SLE_STR | SLF_ALLOW_CONTROL, 0, 84, SL_MAX_VERSION),
246
247 SLE_VAR(CompanyProperties, president_name_1, SLE_STRINGID),
248 SLE_VAR(CompanyProperties, president_name_2, SLE_UINT32),
249 SLE_CONDSTR(CompanyProperties, president_name, SLE_STR | SLF_ALLOW_CONTROL, 0, 84, SL_MAX_VERSION),
250
251 SLE_VAR(CompanyProperties, face, SLE_UINT32),
252
253 /* money was changed to a 64 bit field in savegame version 1. */
254 SLE_CONDVAR(CompanyProperties, money, SLE_VAR_I64 | SLE_FILE_I32, 0, 0),
255 SLE_CONDVAR(CompanyProperties, money, SLE_INT64, 1, SL_MAX_VERSION),
256
257 SLE_CONDVAR(CompanyProperties, current_loan, SLE_VAR_I64 | SLE_FILE_I32, 0, 64),
258 SLE_CONDVAR(CompanyProperties, current_loan, SLE_INT64, 65, SL_MAX_VERSION),
259
260 SLE_VAR(CompanyProperties, colour, SLE_UINT8),
261 SLE_VAR(CompanyProperties, money_fraction, SLE_UINT8),
262 SLE_CONDVAR(CompanyProperties, avail_railtypes, SLE_VAR_I32 | SLE_FILE_I8, 0, 57),
263 SLE_VAR(CompanyProperties, block_preview, SLE_UINT8),
264
265 SLE_CONDNULL(2, 0, 93),
266 SLE_CONDNULL(4, 94, 169),
267 SLE_CONDVAR(CompanyProperties, location_of_HQ, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
268 SLE_CONDVAR(CompanyProperties, location_of_HQ, SLE_UINT32, 6, SL_MAX_VERSION),
269 SLE_CONDVAR(CompanyProperties, last_build_coordinate, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
270 SLE_CONDVAR(CompanyProperties, last_build_coordinate, SLE_UINT32, 6, SL_MAX_VERSION),
271 SLE_CONDVAR(CompanyProperties, inaugurated_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
272 SLE_CONDVAR(CompanyProperties, inaugurated_year, SLE_INT32, 31, SL_MAX_VERSION),
273
274 SLE_ARR(CompanyProperties, share_owners, SLE_UINT8, 4),
275
276 SLE_VAR(CompanyProperties, num_valid_stat_ent, SLE_UINT8),
277
278 SLE_VAR(CompanyProperties, months_of_bankruptcy, SLE_UINT8),
279 SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
280 SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_UINT16, 104, SL_MAX_VERSION),
281 SLE_VAR(CompanyProperties, bankrupt_timeout, SLE_INT16),
282 SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_VAR_I64 | SLE_FILE_I32, 0, 64),
283 SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_INT64, 65, SL_MAX_VERSION),
284
285 /* yearly expenses was changed to 64-bit in savegame version 2. */
286 SLE_CONDARR(CompanyProperties, yearly_expenses, SLE_FILE_I32 | SLE_VAR_I64, 3 * 13, 0, 1),
287 SLE_CONDARR(CompanyProperties, yearly_expenses, SLE_INT64, 3 * 13, 2, SL_MAX_VERSION),
288
289 SLE_CONDVAR(CompanyProperties, is_ai, SLE_BOOL, 2, SL_MAX_VERSION),
290 SLE_CONDNULL(1, 107, 111),
291 SLE_CONDNULL(1, 4, 99),
292
293 SLE_CONDVAR(CompanyProperties, terraform_limit, SLE_UINT32, 156, SL_MAX_VERSION),
294 SLE_CONDVAR(CompanyProperties, clear_limit, SLE_UINT32, 156, SL_MAX_VERSION),
295 SLE_CONDVAR(CompanyProperties, tree_limit, SLE_UINT32, 175, SL_MAX_VERSION),
296
297 SLE_END()
298 };
299
300 static const SaveLoad _company_settings_desc[] = {
301 /* Engine renewal settings */
302 SLE_CONDNULL(512, 16, 18),
303 SLE_CONDREF(Company, engine_renew_list, REF_ENGINE_RENEWS, 19, SL_MAX_VERSION),
304 SLE_CONDVAR(Company, settings.engine_renew, SLE_BOOL, 16, SL_MAX_VERSION),
305 SLE_CONDVAR(Company, settings.engine_renew_months, SLE_INT16, 16, SL_MAX_VERSION),
306 SLE_CONDVAR(Company, settings.engine_renew_money, SLE_UINT32, 16, SL_MAX_VERSION),
307 SLE_CONDVAR(Company, settings.renew_keep_length, SLE_BOOL, 2, SL_MAX_VERSION),
308
309 /* Default vehicle settings */
310 SLE_CONDVAR(Company, settings.vehicle.servint_ispercent, SLE_BOOL, 120, SL_MAX_VERSION),
311 SLE_CONDVAR(Company, settings.vehicle.servint_trains, SLE_UINT16, 120, SL_MAX_VERSION),
312 SLE_CONDVAR(Company, settings.vehicle.servint_roadveh, SLE_UINT16, 120, SL_MAX_VERSION),
313 SLE_CONDVAR(Company, settings.vehicle.servint_aircraft, SLE_UINT16, 120, SL_MAX_VERSION),
314 SLE_CONDVAR(Company, settings.vehicle.servint_ships, SLE_UINT16, 120, SL_MAX_VERSION),
315
316 SLE_CONDNULL(63, 2, 143), // old reserved space
317
318 SLE_END()
319 };
320
321 static const SaveLoad _company_settings_skip_desc[] = {
322 /* Engine renewal settings */
323 SLE_CONDNULL(512, 16, 18),
324 SLE_CONDNULL(2, 19, 68), // engine_renew_list
325 SLE_CONDNULL(4, 69, SL_MAX_VERSION), // engine_renew_list
326 SLE_CONDNULL(1, 16, SL_MAX_VERSION), // settings.engine_renew
327 SLE_CONDNULL(2, 16, SL_MAX_VERSION), // settings.engine_renew_months
328 SLE_CONDNULL(4, 16, SL_MAX_VERSION), // settings.engine_renew_money
329 SLE_CONDNULL(1, 2, SL_MAX_VERSION), // settings.renew_keep_length
330
331 /* Default vehicle settings */
332 SLE_CONDNULL(1, 120, SL_MAX_VERSION), // settings.vehicle.servint_ispercent
333 SLE_CONDNULL(2, 120, SL_MAX_VERSION), // settings.vehicle.servint_trains
334 SLE_CONDNULL(2, 120, SL_MAX_VERSION), // settings.vehicle.servint_roadveh
335 SLE_CONDNULL(2, 120, SL_MAX_VERSION), // settings.vehicle.servint_aircraft
336 SLE_CONDNULL(2, 120, SL_MAX_VERSION), // settings.vehicle.servint_ships
337
338 SLE_CONDNULL(63, 2, 143), // old reserved space
339
340 SLE_END()
341 };
342
343 static const SaveLoad _company_economy_desc[] = {
344 /* these were changed to 64-bit in savegame format 2 */
345 SLE_CONDVAR(CompanyEconomyEntry, income, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
346 SLE_CONDVAR(CompanyEconomyEntry, income, SLE_INT64, 2, SL_MAX_VERSION),
347 SLE_CONDVAR(CompanyEconomyEntry, expenses, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
348 SLE_CONDVAR(CompanyEconomyEntry, expenses, SLE_INT64, 2, SL_MAX_VERSION),
349 SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
350 SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_INT64, 2, SL_MAX_VERSION),
351
352 SLE_CONDVAR(CompanyEconomyEntry, delivered_cargo[NUM_CARGO - 1], SLE_INT32, 0, 169),
353 SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, NUM_CARGO, 170, SL_MAX_VERSION),
354 SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32),
355
356 SLE_END()
357 };
358
359 /* We do need to read this single value, as the bigger it gets, the more data is stored */
360 struct CompanyOldAI {
361 uint8 num_build_rec;
362 };
363
364 static const SaveLoad _company_ai_desc[] = {
365 SLE_CONDNULL(2, 0, 106),
366 SLE_CONDNULL(2, 0, 12),
367 SLE_CONDNULL(4, 13, 106),
368 SLE_CONDNULL(8, 0, 106),
369 SLE_CONDVAR(CompanyOldAI, num_build_rec, SLE_UINT8, 0, 106),
370 SLE_CONDNULL(3, 0, 106),
371
372 SLE_CONDNULL(2, 0, 5),
373 SLE_CONDNULL(4, 6, 106),
374 SLE_CONDNULL(2, 0, 5),
375 SLE_CONDNULL(4, 6, 106),
376 SLE_CONDNULL(2, 0, 106),
377
378 SLE_CONDNULL(2, 0, 5),
379 SLE_CONDNULL(4, 6, 106),
380 SLE_CONDNULL(2, 0, 5),
381 SLE_CONDNULL(4, 6, 106),
382 SLE_CONDNULL(2, 0, 106),
383
384 SLE_CONDNULL(2, 0, 68),
385 SLE_CONDNULL(4, 69, 106),
386
387 SLE_CONDNULL(18, 0, 106),
388 SLE_CONDNULL(20, 0, 106),
389 SLE_CONDNULL(32, 0, 106),
390
391 SLE_CONDNULL(64, 2, 106),
392 SLE_END()
393 };
394
395 static const SaveLoad _company_ai_build_rec_desc[] = {
396 SLE_CONDNULL(2, 0, 5),
397 SLE_CONDNULL(4, 6, 106),
398 SLE_CONDNULL(2, 0, 5),
399 SLE_CONDNULL(4, 6, 106),
400 SLE_CONDNULL(8, 0, 106),
401 SLE_END()
402 };
403
404 static const SaveLoad _company_livery_desc[] = {
405 SLE_CONDVAR(Livery, in_use, SLE_BOOL, 34, SL_MAX_VERSION),
406 SLE_CONDVAR(Livery, colour1, SLE_UINT8, 34, SL_MAX_VERSION),
407 SLE_CONDVAR(Livery, colour2, SLE_UINT8, 34, SL_MAX_VERSION),
408 SLE_END()
409 };
410
411 static void SaveLoad_PLYR_common(Company *c, CompanyProperties *cprops)
412 {
413 int i;
414
415 SlObject(cprops, _company_desc);
416 if (c != NULL) {
417 SlObject(c, _company_settings_desc);
418 } else {
419 char nothing;
420 SlObject(&nothing, _company_settings_skip_desc);
421 }
422
423 /* Keep backwards compatible for savegames, so load the old AI block */
424 if (IsSavegameVersionBefore(107) && cprops->is_ai) {
425 CompanyOldAI old_ai;
426 char nothing;
427
428 SlObject(&old_ai, _company_ai_desc);
429 for (i = 0; i != old_ai.num_build_rec; i++) {
430 SlObject(&nothing, _company_ai_build_rec_desc);
431 }
432 }
433
434 /* Write economy */
435 SlObject(&cprops->cur_economy, _company_economy_desc);
436
437 /* Write old economy entries. */
438 if (cprops->num_valid_stat_ent > lengthof(cprops->old_economy)) SlErrorCorrupt("Too many old economy entries");
439 for (i = 0; i < cprops->num_valid_stat_ent; i++) {
440 SlObject(&cprops->old_economy[i], _company_economy_desc);
441 }
442
443 /* Write each livery entry. */
444 int num_liveries = IsSavegameVersionBefore(63) ? LS_END - 4 : (IsSavegameVersionBefore(85) ? LS_END - 2: LS_END);
445 if (c != NULL) {
446 for (i = 0; i < num_liveries; i++) {
447 SlObject(&c->livery[i], _company_livery_desc);
448 }
449
450 if (num_liveries < LS_END) {
451 /* We want to insert some liveries somewhere in between. This means some have to be moved. */
452 memmove(&c->livery[LS_FREIGHT_WAGON], &c->livery[LS_PASSENGER_WAGON_MONORAIL], (LS_END - LS_FREIGHT_WAGON) * sizeof(c->livery[0]));
453 c->livery[LS_PASSENGER_WAGON_MONORAIL] = c->livery[LS_MONORAIL];
454 c->livery[LS_PASSENGER_WAGON_MAGLEV] = c->livery[LS_MAGLEV];
455 }
456
457 if (num_liveries == LS_END - 4) {
458 /* Copy bus/truck liveries over to trams */
459 c->livery[LS_PASSENGER_TRAM] = c->livery[LS_BUS];
460 c->livery[LS_FREIGHT_TRAM] = c->livery[LS_TRUCK];
461 }
462 } else {
463 /* Skip liveries */
464 Livery dummy_livery;
465 for (i = 0; i < num_liveries; i++) {
466 SlObject(&dummy_livery, _company_livery_desc);
467 }
468 }
469 }
470
471 static void SaveLoad_PLYR(Company *c)
472 {
473 SaveLoad_PLYR_common(c, c);
474 }
475
476 static void Save_PLYR()
477 {
478 Company *c;
479 FOR_ALL_COMPANIES(c) {
480 SlSetArrayIndex(c->index);
481 SlAutolength((AutolengthProc*)SaveLoad_PLYR, c);
482 }
483 }
484
485 static void Load_PLYR()
486 {
487 int index;
488 while ((index = SlIterateArray()) != -1) {
489 Company *c = new (index) Company();
490 SaveLoad_PLYR(c);
491 _company_colours[index] = (Colours)c->colour;
492 }
493 }
494
495 static void Check_PLYR()
496 {
497 int index;
498 while ((index = SlIterateArray()) != -1) {
499 CompanyProperties *cprops = new CompanyProperties();
500 memset(cprops, 0, sizeof(*cprops));
501 SaveLoad_PLYR_common(NULL, cprops);
502
503 /* We do not load old custom names */
504 if (IsSavegameVersionBefore(84)) {
505 if (GetStringTab(cprops->name_1) == TEXT_TAB_OLD_CUSTOM) {
506 cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
507 }
508
509 if (GetStringTab(cprops->president_name_1) == TEXT_TAB_OLD_CUSTOM) {
510 cprops->president_name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
511 }
512 }
513
514 if (cprops->name == NULL && !IsInsideMM(cprops->name_1, SPECSTR_COMPANY_NAME_START, SPECSTR_COMPANY_NAME_LAST + 1) &&
515 cprops->name_1 != STR_GAME_SAVELOAD_NOT_AVAILABLE && cprops->name_1 != STR_SV_UNNAMED &&
516 cprops->name_1 != SPECSTR_ANDCO_NAME && cprops->name_1 != SPECSTR_PRESIDENT_NAME &&
517 cprops->name_1 != SPECSTR_SILLY_NAME) {
518 cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
519 }
520
521 if (!_load_check_data.companies.Insert(index, cprops)) delete cprops;
522 }
523 }
524
525 static void Ptrs_PLYR()
526 {
527 Company *c;
528 FOR_ALL_COMPANIES(c) {
529 SlObject(c, _company_settings_desc);
530 }
531 }
532
533
534 extern const ChunkHandler _company_chunk_handlers[] = {
535 { 'PLYR', Save_PLYR, Load_PLYR, Ptrs_PLYR, Check_PLYR, CH_ARRAY | CH_LAST},
536 };