Changeset - r4:44fa2d88cb6a
[Not reviewed]
master
0 5 0
darkvater - 20 years ago 2004-08-10 14:42:52
darkvater@openttd.org
(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)
5 files changed with 91 insertions and 32 deletions:
0 comments (0 inline, 0 general)
economy.c
Show inline comments
 
@@ -1049,25 +1049,25 @@ static int32 DeliverGoods(int num_pieces
 

	
 
	// Get station pointers.
 
	s_from = DEREF_STATION(source);
 
	s_to = DEREF_STATION(dest);
 

	
 
	// Check if a subsidy applies.
 
	subsidised = CheckSubsidised(s_from, s_to, cargo_type);
 

	
 
	// Increase town's counter for some special goods types
 
	{
 
		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.
 
	DeliverGoodsToIndustry(s_to->xy, cargo_type, num_pieces);
 
	
 
	// Determine profit
 
	{
 
		int t = GetTileDist(s_from->xy, s_to->xy);
 
		int r = num_pieces;
 
		profit = 0;
 
		do {
 
			int u = min(r, 255);
namegen.c
Show inline comments
 
@@ -525,46 +525,46 @@ static const char german_4[] =
 
;
 

	
 
static byte MakeGermanTownName(byte *buf, uint32 seed)
 
{
 
	int i;
 
	int ext;
 
	
 
	ext=GETNUM(7, 28); /* Extension - Prefix / Suffix */
 

	
 
	if ((ext==12) || (ext==19)) {
 
		i=GETNUM(2,NUM_GERMAN_3-2);
 
		AppendPart(&buf, 2+i, german_3);
 
		}
 
	}
 

	
 

	
 
	i=GETNUM(3,NUM_GERMAN_1);
 

	
 
	AppendPart(&buf, i, german_1);
 

	
 
	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);
 

	
 
		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;
 
}
 

	
 
#define NUM_SPANISH_1 86
 
static const char spanish_1[] = 
 
	MK("Caracas")
 
	MK("Maracay")
 
	MK("Maracaibo")
 
	MK("Velencia")
 
	MK("El Dorado")
 
	MK("Morrocoy")
 
@@ -793,25 +793,25 @@ static const char silly_1[] =
 
	MK("Rattle")
 
	MK("Rickety")
 
	MK("Waffle")
 
	MK("Sagging")
 
	MK("Sausage")
 
	MK("Egg")
 

	
 
	MK("Sleepy")
 
	MK("Scatter")
 
	MK("Scramble")
 
	MK("Silly")
 
	MK("Simple")
 
	MK("Tricky")
 
	MK("Trickle")
 
	MK("Slippery")
 
	MK("Slimey")
 
	MK("Slumber")
 
	MK("Soggy")
 

	
 
	MK("Sliggles")
 
	MK("Splutter")
 
	MK("Sulky")
 
	MK("Swindle")
 
	MK("Swivel")
 
	MK("Tasty")
 
	MK("Tangle")
 
@@ -1963,12 +1963,43 @@ TownNameGenerator * const _town_name_gen
 
	MakeGermanTownName,
 
	MakeAmericanTownName,
 
	MakeSpanishTownName,
 
	MakeSillyTownName,
 
	MakeSwedishTownName,
 
	MakeDutchTownName,
 
	MakeFinnishTownName,
 
	MakePolishTownName,
 
	MakeSlovakishTownName,
 
	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;
 
}
oldloader.c
Show inline comments
 
@@ -40,28 +40,29 @@ typedef struct {
 
	uint16 radius[5];
 
	uint16 ratings[8];
 
	uint32 have_ratings;
 
	uint32 statues;
 
	uint16 num_houses;
 
	byte time_until_rebuild;
 
	byte growth_rate;
 
	uint16 new_max_pass, new_max_mail;
 
	uint16 new_act_pass, new_act_mail;
 
	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;
 
assert_compile(sizeof(OldTown) == 0x5E);
 

	
 
typedef struct {
 
	uint16 xy;
 
	uint32 town;
 
} GCC_PACK OldDepot;
 
assert_compile(sizeof(OldDepot) == 0x6);
 

	
 
typedef struct {
 
@@ -570,56 +571,62 @@ static byte DecodeSavegameByte()
 
	}	
 
}
 

	
 
static void LoadSavegameBytes(void *p, size_t count)
 
{
 
	byte *ptr = (byte*)p;
 
	assert(count > 0);
 
	do {
 
		*ptr++ = DecodeSavegameByte();
 
	} 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;
 
		memcpy(t->ratings,o->ratings,sizeof(t->ratings));
 
		t->have_ratings = o->have_ratings;
 
		t->statues = o->statues;
 
		t->num_houses = o->num_houses;
 
		t->time_until_rebuild = o->time_until_rebuild;
 
		t->growth_rate = o->growth_rate;
 
		t->new_max_pass = o->new_max_pass;
 
		t->new_max_mail = o->new_max_mail;
 
		t->new_act_pass = o->new_act_pass;
 
		t->new_act_mail = o->new_act_mail;
 
		t->max_pass = o->max_pass;
 
		t->max_mail = o->max_mail;
 
		t->act_pass = o->act_pass;
 
		t->act_mail = o->act_mail;
 
		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);
 
}
 

	
 
static void FixIndustry(Industry *i, OldIndustry *o, int num)
 
{
 
	do {
 
		i->xy = o->xy;
 
		i->town = REMAP_TOWN_PTR(o->town);
 
		i->width = o->width;
 
		i->height = o->height;
 
@@ -844,36 +851,46 @@ static void FixAiBuildRec(AiBuildRec *n,
 
	n->spec_tile = o->spec_tile;
 
	n->use_tile = o->use_tile;
 
	n->rand_rng = o->rand_rng;
 
	n->cur_building_rule = o->cur_rule;
 
	n->unk6 = o->unk6;
 
	n->unk7 = o->unk7;
 
	n->buildcmd_a = o->buildcmd_a;
 
	n->buildcmd_b = o->buildcmd_b;
 
	n->direction = o->direction;
 
	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;
 
		n->president_name_2 = o->pres_name_2;
 
		
 
		n->money64 = n->player_money = o->money;
 
		n->current_loan = o->loan;
 
		
 
		// Correct money for scenario loading. 
 
		// It's always 893288 pounds (and no loan), if not corrected
 
		if(o->money==0xda168)
 
			n->money64 = n->player_money = n->current_loan =100000;
 
@@ -890,25 +907,30 @@ static void FixPlayer(Player *n, OldPlay
 
		n->cargo_types = o->cargo_types;
 
		
 
		for(i=0; i!=3; i++)
 
			for(j=0; j!=13; j++)
 
				n->yearly_expenses[i][j] = o->expenses[i].cost[j];
 

	
 
		FixEconomy(&n->cur_economy, &o->economy[0]);
 
		for(i=0; i!=24; i++) FixEconomy(&n->old_economy[i], &o->economy[i+1]);
 
		n->inaugurated_year = o->inaugurated_date - 1920;
 
		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;
 
		n->ai.banned_tile_count = o->ai_banned_tile_count;
 
		n->ai.railtype_to_use = o->ai_railtype_to_use;
 
		
 
		FixAiBuildRec(&n->ai.src, &o->ai_src);
 
		FixAiBuildRec(&n->ai.dst, &o->ai_dst);
 
		FixAiBuildRec(&n->ai.mid1, &o->ai_mid1);
 
		FixAiBuildRec(&n->ai.mid2, &o->ai_mid2);
 
		
 
		n->ai.cargo_type = o->ai_cargo_type;
 
@@ -1023,27 +1045,33 @@ void FixGameDifficulty(GameDifficulty *n
 
bool LoadOldSaveGame(const char *file)
 
{
 
	LoadSavegameState lss;
 
	OldMain *m;
 
	int i;
 

	
 
	_cur_state = &lss;
 
	memset(&lss, 0, sizeof(lss));
 

	
 
	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));
 

	
 
	// copy sections of it to our datastructures.
 
	memcpy(_map_owner, m->map_owner, sizeof(_map_owner));
 
	memcpy(_map2, m->map2, sizeof(_map2));
 
	memcpy(_map_type_and_height, m->map_type_and_height, sizeof(_map_type_and_height));
 
	memcpy(_map5, m->map5, sizeof(_map5));
 
	for(i=0; i!=256*256; i++) {
 
		_map3_lo[i] = m->map3[i] & 0xFF;
 
		_map3_hi[i] = m->map3[i] >> 8;
 
	}
 
@@ -1054,33 +1082,33 @@ bool LoadOldSaveGame(const char *file)
 
		if (IS_TILETYPE(i, MP_RAILWAY) && (_map5[i] & 0xC0) == 0x40) {
 
			// this byte is always zero in real ttd.
 
			if (_map3_hi[i]) { 
 
				// convert ttdpatch presignal format to openttd presignal format.
 
				_map3_hi[i] = (_map3_hi[i] >> 1) & 7;
 
			}
 
		}
 
	}
 

	
 
	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));
 

	
 
	FixDepot(_depots, m->depots, lengthof(m->depots));
 
	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));
 

	
 
	_opt.diff_level = m->difficulty_level;
 
	_opt.currency = m->currency;
 
	_opt.kilometers = m->use_kilometers;
 
	_opt.town_name = m->town_name_type;
 
	_opt.landscape = m->landscape_type;
 
	_opt.snow_line = m->snow_line_height;
 
	_opt.autosave = 0;
 
	_opt.road_side = m->road_side;
town.h
Show inline comments
 
@@ -38,27 +38,27 @@ struct Town {
 
	uint16 new_max_mail;
 
	uint16 act_pass;
 
	uint16 act_mail;
 
	uint16 new_act_pass;
 
	uint16 new_act_mail;
 

	
 
	// Amount of passengers that were transported.
 
	byte pct_pass_transported;
 
	byte pct_mail_transported;
 

	
 
	// 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;
 

	
 
	// When to grow town next time.
 
	byte grow_counter;
 
	byte growth_rate;	
 

	
 
	// Fund buildings program in action?
 
	byte fund_buildings_months;
 
	
 
	// Fund road reconstruction in action?
town_cmd.c
Show inline comments
 
@@ -841,27 +841,27 @@ static void DoCreateTown(Town *t, TileIn
 
	t->new_max_mail = 0;
 
	t->new_act_pass = 0;
 
	t->new_act_mail = 0;
 
	t->max_pass = 0;
 
	t->max_mail = 0;
 
	t->act_pass = 0;
 
	t->act_mail = 0;
 

	
 
	t->pct_pass_transported = 0;
 
	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;
 

	
 
	t->have_ratings = 0;
 
	t->statues = 0;
 

	
 
	CreateTownName(t);
 
		
 
	UpdateTownVirtCoord(t);
 
	_town_sort_dirty = true;
 

	
 
@@ -1581,44 +1581,44 @@ static void UpdateTownGrowRate(Town *t)
 
			return;
 
	} else {
 
		static const byte _grow_count_values[5] = {
 
			210, 150, 110, 80, 50
 
		};
 
		m = _grow_count_values[min(n, 5) - 1];
 
	}
 

	
 
	if (_opt.landscape == LT_HILLY) {
 
		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;
 
	}
 

	
 
	t->growth_rate = m;
 
	if (m <= t->grow_counter)
 
		t->grow_counter = m;
 

	
 
	t->flags12 |= 1;
 
}
 

	
 
static void UpdateTownAmounts(Town *t)
 
{
 
	// Using +1 here to prevent overflow and division by zero
 
	t->pct_pass_transported = t->new_act_pass * 256 / (t->new_max_pass + 1);
 

	
 
	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);
 
	t->max_mail = t->new_max_mail; t->new_max_mail = 0;
 
	t->act_mail = t->new_act_mail; t->new_act_mail = 0;
 

	
 
	InvalidateWindow(WC_TOWN_VIEW, t->index);
 
}
 

	
 
static void UpdateTownUnwanted(Town *t)
 
{
 
	Player *p;
 
@@ -1802,27 +1802,27 @@ static const byte _town_desc[] = {
 
	SLE_VAR(Town,max_mail,		SLE_UINT16),
 
	SLE_VAR(Town,new_max_pass,SLE_UINT16),
 
	SLE_VAR(Town,new_max_mail,SLE_UINT16),
 
	SLE_VAR(Town,act_pass,		SLE_UINT16),
 
	SLE_VAR(Town,act_mail,		SLE_UINT16),
 
	SLE_VAR(Town,new_act_pass,SLE_UINT16),
 
	SLE_VAR(Town,new_act_mail,SLE_UINT16),
 

	
 
	SLE_VAR(Town,pct_pass_transported,SLE_UINT8),
 
	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),
 
	SLE_VAR(Town,growth_rate,						SLE_UINT8),
 
	SLE_VAR(Town,fund_buildings_months,	SLE_UINT8),
 
	SLE_VAR(Town,road_build_months,			SLE_UINT8),
 

	
 
	// reserve extra space in savegame here. (currently 32 bytes)
 
	SLE_CONDARR(NullStruct,null,SLE_FILE_U64 | SLE_VAR_NULL, 4, 2, 255),
 

	
 
	SLE_END()
 
};
0 comments (0 inline, 0 general)