From a32d8553e7166bd95d355c633307b9782402868a Mon Sep 17 00:00:00 2001 From: darkvater Date: Tue, 10 Aug 2004 14:42:52 +0000 Subject: [PATCH] (svn r5) -Fix: townname generation of TTDLX savegames. All work except for German Townnames (also fix one typo on English town-names) -CodeChange: *act_paper to *act_water in Town to more resemble its use -Fix: AI players now retain AI status. Since TTDLX savegame status is not fully documented, some holes exist (AI state is set to one without a vehicle, otherwise it crashes) --- economy.c | 2 +- namegen.c | 41 +++++++++++++++++++++++++++++----- oldloader.c | 64 ++++++++++++++++++++++++++++++++++++++--------------- town.h | 4 ++-- town_cmd.c | 12 +++++----- 5 files changed, 91 insertions(+), 32 deletions(-) diff --git a/economy.c b/economy.c index 94293e2b0e..3c5988d93c 100644 --- a/economy.c +++ b/economy.c @@ -1058,7 +1058,7 @@ static int32 DeliverGoods(int num_pieces, byte cargo_type, byte source, byte des { Town *t = s_to->town; if (cargo_type == CT_FOOD) t->new_act_food += num_pieces; - if (cargo_type == CT_STEEL) t->new_act_paper += num_pieces; + if (cargo_type == CT_STEEL) t->new_act_water += num_pieces; } // Give the goods to the industry. diff --git a/namegen.c b/namegen.c index f5b4486c55..9ae5c75169 100644 --- a/namegen.c +++ b/namegen.c @@ -534,7 +534,7 @@ static byte MakeGermanTownName(byte *buf, uint32 seed) if ((ext==12) || (ext==19)) { i=GETNUM(2,NUM_GERMAN_3-2); AppendPart(&buf, 2+i, german_3); - } + } i=GETNUM(3,NUM_GERMAN_1); @@ -543,7 +543,7 @@ static byte MakeGermanTownName(byte *buf, uint32 seed) if (i>NUM_GERMAN_1_HARDCODED-1) { AppendPart(&buf, GETNUM(5, NUM_GERMAN_2), german_2); - } + } if (ext==24) { i=GETNUM(9,NUM_GERMAN_4); @@ -551,11 +551,11 @@ static byte MakeGermanTownName(byte *buf, uint32 seed) if (i<=NUM_GERMAN_4_PRECHANGE-1) { AppendPart(&buf, 0, german_3); AppendPart(&buf, i, german_4); - } else { + } else { AppendPart(&buf, 1, german_3); AppendPart(&buf, i, german_4); - } } + } return 0; } @@ -802,7 +802,7 @@ static const char silly_1[] = MK("Scramble") MK("Silly") MK("Simple") - MK("Tricky") + MK("Trickle") MK("Slippery") MK("Slimey") MK("Slumber") @@ -1972,3 +1972,34 @@ TownNameGenerator * const _town_name_generators[] = { MakeHungarianTownName, MakeAustrianTownName }; + +#define FIXNUM(x, y, z) (((((x) << 16) / (y)) + 1) << z) + +uint32 GetOldTownName(uint32 townnameparts, byte old_town_name_type) +{ + uint32 a = 0; + switch (old_town_name_type) { + case 0: case 3: /* English, American */ + /* Already OK */ + return townnameparts; + case 1: /* French */ + /* For some reason 86 needs to be subtracted from townnameparts + * 0000 0000 0000 0000 0000 0000 1111 1111 */ + return FIXNUM(townnameparts - 86, NUM_FRENCH_1, 0); + case 2: /* German */ + #ifdef _DEBUG + printf("German Townnames are buggy... (%d)\n", townnameparts); + #endif + return townnameparts; + case 4: /* Latin-American */ + /* 0000 0000 0000 0000 0000 0000 1111 1111 */ + return FIXNUM(townnameparts, NUM_SPANISH_1, 0); + case 5: /* Silly */ + //AppendPart(&buf, GETNUM(16, NUM_SILLY_2),silly_2); + /* NUM_SILLY_1 - lower 16 bits + * NUM_SILLY_2 - upper 16 bits without leading 1 (first 8 bytes) + * 1000 0000 2222 2222 0000 0000 1111 1111 */ + return FIXNUM(townnameparts, NUM_SILLY_1, 0) | FIXNUM(((townnameparts >> 16)&0xFF), NUM_SILLY_2, 16); + } + return 0; +} diff --git a/oldloader.c b/oldloader.c index 4e1542d2ab..47484359da 100644 --- a/oldloader.c +++ b/oldloader.c @@ -49,10 +49,11 @@ typedef struct { uint16 max_pass, max_mail; uint16 act_pass, act_mail; byte pct_pass_transported, pct_mail_transported; - uint16 new_act_food, new_act_paper; - uint16 act_food, act_paper; + uint16 new_act_food, new_act_water; + uint16 act_food, act_water; byte road_build_months; byte fund_buildings_months; + // unused bytes at the end of the Town Struct uint32 unk56; uint32 unk5A; } GCC_PACK OldTown; @@ -579,15 +580,21 @@ static void LoadSavegameBytes(void *p, size_t count) } while (--count); } -static void FixTown(Town *t, OldTown *o, int num) +extern uint32 GetOldTownName(uint32 townnameparts, byte old_town_name_type); + +static void FixTown(Town *t, OldTown *o, int num, byte town_name_type) { do { t->xy = o->xy; t->population = o->population; t->townnametype = o->townnametype; t->townnameparts = o->townnameparts; - if (IS_INT_INSIDE(o->townnametype, 0x20C1, 0x20C2 + 1)) - t->townnametype = SPECSTR_TOWNNAME_ENGLISH; + // Random TownNames + if (IS_INT_INSIDE(o->townnametype, 0x20C1, 0x20C2 + 1)) { + t->townnametype = SPECSTR_TOWNNAME_ENGLISH + town_name_type; + if (o->xy) + t->townnameparts = GetOldTownName(o->townnameparts, town_name_type); + } t->grow_counter = o->grow_counter; t->flags12 = o->flags12; @@ -608,9 +615,9 @@ static void FixTown(Town *t, OldTown *o, int num) t->pct_pass_transported = o->pct_pass_transported; t->pct_mail_transported = o->pct_mail_transported; t->new_act_food = o->new_act_food; - t->new_act_paper = o->new_act_paper; + t->new_act_water = o->new_act_water; t->act_food = o->act_food; - t->act_paper = o->act_paper; + t->act_water = o->act_water; t->road_build_months = o->road_build_months; t->fund_buildings_months = o->fund_buildings_months; } while (t++,o++,--num); @@ -853,18 +860,28 @@ static void FixAiBuildRec(AiBuildRec *n, OldAiBuildRec *o) n->cargo = o->cargo; } -static void FixPlayer(Player *n, OldPlayer *o, int num) +static void FixPlayer(Player *n, OldPlayer *o, int num, byte town_name_type) { int i, j; int x = 0; - + do { n->name_1 = RemapOldStringID(o->name_1); n->name_2 = o->name_2; - if (o->name_1 == 0 && x == 0) - n->name_1 = STR_SV_UNNAMED; - else - n->is_active=true; + /* In every Old TTD(Patch) game Player1 (0) is human, and all others are AI + * (Except in .SV2 savegames, which were 2 player games, but we are not fixing + * that + */ + + if (x == 0) { + if (o->name_1 == 0) // if first player doesn't have a name, he is 'unnamed' + n->name_1 = STR_SV_UNNAMED; + } else { + n->is_ai = 1; + } + + if (o->name_1 != 0) + n->is_active = true; n->face = o->face; n->president_name_1 = o->pres_name_1; @@ -899,7 +916,12 @@ static void FixPlayer(Player *n, OldPlayer *o, int num) n->last_build_coordinate = o->last_build_coordinate; n->num_valid_stat_ent = o->num_valid_stat_ent; - n->ai.state = o->ai_state; + /* Not good, since AI doesn't have a vehicle assigned as + * in p->ai.cur_veh and thus will crash on certain actions. + * Best is to set state to AiStateVehLoop (2) + * n->ai.state = o->ai_state; + */ + n->ai.state = 2; n->ai.state_mode = o->ai_state_mode; n->ai.state_counter = o->ai_state_counter; n->ai.timeout_counter = o->ai_timeout_counter; @@ -1032,9 +1054,15 @@ bool LoadOldSaveGame(const char *file) lss.fin = fopen(file, "rb"); if (lss.fin == NULL) return false; - fseek(lss.fin, 49, SEEK_SET); + /* B - byte 8bit (1) + * W - word 16bit (2 bytes) + * L - 'long' word 32bit (4 bytes) + */ + fseek(lss.fin, 49, SEEK_SET); // 47B TITLE, W Checksum - Total 49 - // load the file into memory + /* Load the file into memory + * Game Data 0x77179 + L4 (256x256) + L5 (256x256) + */ m = (OldMain *)malloc(sizeof(OldMain)); LoadSavegameBytes(m, sizeof(OldMain)); @@ -1063,7 +1091,7 @@ bool LoadOldSaveGame(const char *file) memcpy(_order_array, m->order_list, sizeof(m->order_list)); _ptr_to_next_order = _order_array + REMAP_ORDER_IDX(m->ptr_to_next_order); - FixTown(_towns, m->town_list, lengthof(m->town_list)); + FixTown(_towns, m->town_list, lengthof(m->town_list), m->town_name_type); FixIndustry(_industries, m->industries, lengthof(m->industries)); FixStation(_stations, m->stations, lengthof(m->stations)); @@ -1071,7 +1099,7 @@ bool LoadOldSaveGame(const char *file) FixVehicle(_vehicles, m->vehicles, lengthof(m->vehicles)); FixSubsidy(_subsidies, m->subsidies, lengthof(m->subsidies)); - FixPlayer(_players, m->players, lengthof(m->players)); + FixPlayer(_players, m->players, lengthof(m->players), m->town_name_type); FixName(m->names, lengthof(m->names)); FixSign(_sign_list, m->signs, lengthof(m->signs)); FixEngine(_engines, m->engines, lengthof(m->engines)); diff --git a/town.h b/town.h index ccf37e28f8..1a59c247e9 100644 --- a/town.h +++ b/town.h @@ -47,9 +47,9 @@ struct Town { // Amount of food and paper that was transported. Actually a bit mask would be enough. uint16 act_food; - uint16 act_paper; + uint16 act_water; uint16 new_act_food; - uint16 new_act_paper; + uint16 new_act_water; // Time until we rebuild a house. byte time_until_rebuild; diff --git a/town_cmd.c b/town_cmd.c index c72ca70010..e889022e19 100644 --- a/town_cmd.c +++ b/town_cmd.c @@ -850,9 +850,9 @@ static void DoCreateTown(Town *t, TileIndex tile) t->pct_mail_transported = 0; t->fund_buildings_months = 0; t->new_act_food = 0; - t->new_act_paper = 0; + t->new_act_water = 0; t->act_food = 0; - t->act_paper = 0; + t->act_water = 0; for(i = 0; i != MAX_PLAYERS; i++) t->ratings[i] = 500; @@ -1590,7 +1590,7 @@ static void UpdateTownGrowRate(Town *t) if (GET_TILEHEIGHT(t->xy) >= _opt.snow_line && t->act_food == 0) return; } else if (_opt.landscape == LT_DESERT) { - if (GetMapExtraBits(t->xy) == 1 && (t->act_food==0 || t->act_paper==0)) + if (GetMapExtraBits(t->xy) == 1 && (t->act_food==0 || t->act_water==0)) return; } @@ -1609,7 +1609,7 @@ static void UpdateTownAmounts(Town *t) t->max_pass = t->new_max_pass; t->new_max_pass = 0; t->act_pass = t->new_act_pass; t->new_act_pass = 0; t->act_food = t->new_act_food; t->new_act_food = 0; - t->act_paper = t->new_act_paper; t->new_act_paper = 0; + t->act_water = t->new_act_water; t->new_act_water = 0; // Using +1 here to prevent overflow and division by zero t->pct_mail_transported = t->new_act_mail * 256 / (t->new_max_mail + 1); @@ -1811,9 +1811,9 @@ static const byte _town_desc[] = { SLE_VAR(Town,pct_mail_transported,SLE_UINT8), SLE_VAR(Town,act_food, SLE_UINT16), - SLE_VAR(Town,act_paper, SLE_UINT16), + SLE_VAR(Town,act_water, SLE_UINT16), SLE_VAR(Town,new_act_food,SLE_UINT16), - SLE_VAR(Town,new_act_paper,SLE_UINT16), + SLE_VAR(Town,new_act_water,SLE_UINT16), SLE_VAR(Town,time_until_rebuild, SLE_UINT8), SLE_VAR(Town,grow_counter, SLE_UINT8),