mirror of https://github.com/OpenTTD/OpenTTD.git
(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)
This commit is contained in:
parent
cc8080f2dc
commit
a32d8553e7
|
@ -1058,7 +1058,7 @@ static int32 DeliverGoods(int num_pieces, byte cargo_type, byte source, byte des
|
||||||
{
|
{
|
||||||
Town *t = s_to->town;
|
Town *t = s_to->town;
|
||||||
if (cargo_type == CT_FOOD) t->new_act_food += num_pieces;
|
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.
|
// Give the goods to the industry.
|
||||||
|
|
33
namegen.c
33
namegen.c
|
@ -802,7 +802,7 @@ static const char silly_1[] =
|
||||||
MK("Scramble")
|
MK("Scramble")
|
||||||
MK("Silly")
|
MK("Silly")
|
||||||
MK("Simple")
|
MK("Simple")
|
||||||
MK("Tricky")
|
MK("Trickle")
|
||||||
MK("Slippery")
|
MK("Slippery")
|
||||||
MK("Slimey")
|
MK("Slimey")
|
||||||
MK("Slumber")
|
MK("Slumber")
|
||||||
|
@ -1972,3 +1972,34 @@ TownNameGenerator * const _town_name_generators[] = {
|
||||||
MakeHungarianTownName,
|
MakeHungarianTownName,
|
||||||
MakeAustrianTownName
|
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;
|
||||||
|
}
|
||||||
|
|
58
oldloader.c
58
oldloader.c
|
@ -49,10 +49,11 @@ typedef struct {
|
||||||
uint16 max_pass, max_mail;
|
uint16 max_pass, max_mail;
|
||||||
uint16 act_pass, act_mail;
|
uint16 act_pass, act_mail;
|
||||||
byte pct_pass_transported, pct_mail_transported;
|
byte pct_pass_transported, pct_mail_transported;
|
||||||
uint16 new_act_food, new_act_paper;
|
uint16 new_act_food, new_act_water;
|
||||||
uint16 act_food, act_paper;
|
uint16 act_food, act_water;
|
||||||
byte road_build_months;
|
byte road_build_months;
|
||||||
byte fund_buildings_months;
|
byte fund_buildings_months;
|
||||||
|
// unused bytes at the end of the Town Struct
|
||||||
uint32 unk56;
|
uint32 unk56;
|
||||||
uint32 unk5A;
|
uint32 unk5A;
|
||||||
} GCC_PACK OldTown;
|
} GCC_PACK OldTown;
|
||||||
|
@ -579,15 +580,21 @@ static void LoadSavegameBytes(void *p, size_t count)
|
||||||
} while (--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 {
|
do {
|
||||||
t->xy = o->xy;
|
t->xy = o->xy;
|
||||||
t->population = o->population;
|
t->population = o->population;
|
||||||
t->townnametype = o->townnametype;
|
t->townnametype = o->townnametype;
|
||||||
t->townnameparts = o->townnameparts;
|
t->townnameparts = o->townnameparts;
|
||||||
if (IS_INT_INSIDE(o->townnametype, 0x20C1, 0x20C2 + 1))
|
// Random TownNames
|
||||||
t->townnametype = SPECSTR_TOWNNAME_ENGLISH;
|
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->grow_counter = o->grow_counter;
|
||||||
t->flags12 = o->flags12;
|
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_pass_transported = o->pct_pass_transported;
|
||||||
t->pct_mail_transported = o->pct_mail_transported;
|
t->pct_mail_transported = o->pct_mail_transported;
|
||||||
t->new_act_food = o->new_act_food;
|
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_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->road_build_months = o->road_build_months;
|
||||||
t->fund_buildings_months = o->fund_buildings_months;
|
t->fund_buildings_months = o->fund_buildings_months;
|
||||||
} while (t++,o++,--num);
|
} while (t++,o++,--num);
|
||||||
|
@ -853,7 +860,7 @@ static void FixAiBuildRec(AiBuildRec *n, OldAiBuildRec *o)
|
||||||
n->cargo = o->cargo;
|
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 i, j;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
@ -861,9 +868,19 @@ static void FixPlayer(Player *n, OldPlayer *o, int num)
|
||||||
do {
|
do {
|
||||||
n->name_1 = RemapOldStringID(o->name_1);
|
n->name_1 = RemapOldStringID(o->name_1);
|
||||||
n->name_2 = o->name_2;
|
n->name_2 = o->name_2;
|
||||||
if (o->name_1 == 0 && x == 0)
|
/* 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;
|
n->name_1 = STR_SV_UNNAMED;
|
||||||
else
|
} else {
|
||||||
|
n->is_ai = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o->name_1 != 0)
|
||||||
n->is_active = true;
|
n->is_active = true;
|
||||||
|
|
||||||
n->face = o->face;
|
n->face = o->face;
|
||||||
|
@ -899,7 +916,12 @@ static void FixPlayer(Player *n, OldPlayer *o, int num)
|
||||||
n->last_build_coordinate = o->last_build_coordinate;
|
n->last_build_coordinate = o->last_build_coordinate;
|
||||||
n->num_valid_stat_ent = o->num_valid_stat_ent;
|
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_mode = o->ai_state_mode;
|
||||||
n->ai.state_counter = o->ai_state_counter;
|
n->ai.state_counter = o->ai_state_counter;
|
||||||
n->ai.timeout_counter = o->ai_timeout_counter;
|
n->ai.timeout_counter = o->ai_timeout_counter;
|
||||||
|
@ -1032,9 +1054,15 @@ bool LoadOldSaveGame(const char *file)
|
||||||
lss.fin = fopen(file, "rb");
|
lss.fin = fopen(file, "rb");
|
||||||
if (lss.fin == NULL) return false;
|
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));
|
m = (OldMain *)malloc(sizeof(OldMain));
|
||||||
LoadSavegameBytes(m, 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));
|
memcpy(_order_array, m->order_list, sizeof(m->order_list));
|
||||||
_ptr_to_next_order = _order_array + REMAP_ORDER_IDX(m->ptr_to_next_order);
|
_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));
|
FixIndustry(_industries, m->industries, lengthof(m->industries));
|
||||||
FixStation(_stations, m->stations, lengthof(m->stations));
|
FixStation(_stations, m->stations, lengthof(m->stations));
|
||||||
|
|
||||||
|
@ -1071,7 +1099,7 @@ bool LoadOldSaveGame(const char *file)
|
||||||
FixVehicle(_vehicles, m->vehicles, lengthof(m->vehicles));
|
FixVehicle(_vehicles, m->vehicles, lengthof(m->vehicles));
|
||||||
FixSubsidy(_subsidies, m->subsidies, lengthof(m->subsidies));
|
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));
|
FixName(m->names, lengthof(m->names));
|
||||||
FixSign(_sign_list, m->signs, lengthof(m->signs));
|
FixSign(_sign_list, m->signs, lengthof(m->signs));
|
||||||
FixEngine(_engines, m->engines, lengthof(m->engines));
|
FixEngine(_engines, m->engines, lengthof(m->engines));
|
||||||
|
|
4
town.h
4
town.h
|
@ -47,9 +47,9 @@ struct Town {
|
||||||
|
|
||||||
// Amount of food and paper that was transported. Actually a bit mask would be enough.
|
// Amount of food and paper that was transported. Actually a bit mask would be enough.
|
||||||
uint16 act_food;
|
uint16 act_food;
|
||||||
uint16 act_paper;
|
uint16 act_water;
|
||||||
uint16 new_act_food;
|
uint16 new_act_food;
|
||||||
uint16 new_act_paper;
|
uint16 new_act_water;
|
||||||
|
|
||||||
// Time until we rebuild a house.
|
// Time until we rebuild a house.
|
||||||
byte time_until_rebuild;
|
byte time_until_rebuild;
|
||||||
|
|
12
town_cmd.c
12
town_cmd.c
|
@ -850,9 +850,9 @@ static void DoCreateTown(Town *t, TileIndex tile)
|
||||||
t->pct_mail_transported = 0;
|
t->pct_mail_transported = 0;
|
||||||
t->fund_buildings_months = 0;
|
t->fund_buildings_months = 0;
|
||||||
t->new_act_food = 0;
|
t->new_act_food = 0;
|
||||||
t->new_act_paper = 0;
|
t->new_act_water = 0;
|
||||||
t->act_food = 0;
|
t->act_food = 0;
|
||||||
t->act_paper = 0;
|
t->act_water = 0;
|
||||||
|
|
||||||
for(i = 0; i != MAX_PLAYERS; i++)
|
for(i = 0; i != MAX_PLAYERS; i++)
|
||||||
t->ratings[i] = 500;
|
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)
|
if (GET_TILEHEIGHT(t->xy) >= _opt.snow_line && t->act_food == 0)
|
||||||
return;
|
return;
|
||||||
} else if (_opt.landscape == LT_DESERT) {
|
} 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1609,7 +1609,7 @@ static void UpdateTownAmounts(Town *t)
|
||||||
t->max_pass = t->new_max_pass; t->new_max_pass = 0;
|
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_pass = t->new_act_pass; t->new_act_pass = 0;
|
||||||
t->act_food = t->new_act_food; t->new_act_food = 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
|
// Using +1 here to prevent overflow and division by zero
|
||||||
t->pct_mail_transported = t->new_act_mail * 256 / (t->new_max_mail + 1);
|
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,pct_mail_transported,SLE_UINT8),
|
||||||
|
|
||||||
SLE_VAR(Town,act_food, SLE_UINT16),
|
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_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,time_until_rebuild, SLE_UINT8),
|
||||||
SLE_VAR(Town,grow_counter, SLE_UINT8),
|
SLE_VAR(Town,grow_counter, SLE_UINT8),
|
||||||
|
|
Loading…
Reference in New Issue