Changeset - r457:8379810cd1c9
[Not reviewed]
master
0 1 0
tron - 20 years ago 2004-11-17 21:11:16
tron@openttd.org
(svn r667) Fix bug in rendering stations from savegames
Also don't pitch custom station sprites by railtype
(pasky)
1 file changed with 3 insertions and 3 deletions:
0 comments (0 inline, 0 general)
station_cmd.c
Show inline comments
 
@@ -1752,391 +1752,391 @@ int32 CmdBuildDock(int x, int y, uint32 
 
	TileInfo ti;
 
	int direction;
 
	int32 cost;
 
	uint tile, tile_cur;
 
	Station *st;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	FindLandscapeHeight(&ti, x, y);
 

	
 
	if ((direction=0,ti.tileh) != 3 &&
 
			(direction++,ti.tileh) != 9 &&
 
			(direction++,ti.tileh) != 12 &&
 
			(direction++,ti.tileh) != 6)
 
		return_cmd_error(STR_304B_SITE_UNSUITABLE);
 

	
 
	if (!EnsureNoVehicle(ti.tile))
 
		return CMD_ERROR;
 

	
 
	cost = DoCommandByTile(ti.tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (cost == CMD_ERROR)
 
		return CMD_ERROR;
 

	
 
	tile_cur = (tile=ti.tile) + _tileoffs_by_dir[direction];
 

	
 
	if (!EnsureNoVehicle(tile_cur))
 
		return CMD_ERROR;
 

	
 
	FindLandscapeHeightByTile(&ti, tile_cur);
 
	if (ti.tileh != 0 || ti.type != MP_WATER)
 
		return_cmd_error(STR_304B_SITE_UNSUITABLE);
 

	
 
	cost = DoCommandByTile(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (cost == CMD_ERROR)
 
		return CMD_ERROR;
 

	
 
	tile_cur = tile_cur + _tileoffs_by_dir[direction];
 
	FindLandscapeHeightByTile(&ti, tile_cur);
 
	if (ti.tileh != 0 || ti.type != MP_WATER)
 
		return_cmd_error(STR_304B_SITE_UNSUITABLE);
 

	
 
	/* middle */
 
	st = GetStationAround(tile + _dock_tileoffs_chkaround[direction],
 
		_dock_w_chk[direction], _dock_h_chk[direction], -1);
 
	if (st == CHECK_STATIONS_ERR)
 
		return CMD_ERROR;
 

	
 
	/* Find a station close to us */
 
	if (st == NULL) {
 
		st = GetClosestStationFromTile(tile, 8, _current_player);
 
		if (st!=NULL && st->facilities) st = NULL;
 
	}
 

	
 
	if (st != NULL) {
 
		if (st->owner != OWNER_NONE && st->owner != _current_player)
 
			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
 

	
 
		if (!CheckStationSpreadOut(st, tile, 1, 1))
 
			return CMD_ERROR;
 

	
 
		if (st->dock_tile != 0)
 
			return_cmd_error(STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK);
 
	} else {
 
		Town *t;
 

	
 
		st = AllocateStation();
 
		if (st == NULL)
 
			return CMD_ERROR;
 

	
 
		st->town = t = ClosestTownFromTile(tile, (uint)-1);
 

	
 
		if (_current_player < MAX_PLAYERS && flags&DC_EXEC)
 
			SETBIT(t->have_ratings, _current_player);
 

	
 
		st->sign.width_1 = 0;
 

	
 
		if (!GenerateStationName(st, tile, 3))
 
			return CMD_ERROR;
 

	
 
		if (flags & DC_EXEC)
 
			StationInitialize(st, tile);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		st->dock_tile = tile;
 
		if (!st->facilities) st->xy = tile;
 
		st->facilities |= FACIL_DOCK;
 
		st->owner = _current_player;
 

	
 
		st->build_date = _date;
 

	
 
		ModifyTile(tile,
 
			MP_SETTYPE(MP_STATION) | MP_MAPOWNER_CURRENT |
 
			MP_MAP2 | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR |
 
			MP_MAP5,
 
			st->index,
 
			direction + 0x4C);
 

	
 
		ModifyTile(tile + _tileoffs_by_dir[direction],
 
			MP_SETTYPE(MP_STATION) | MP_MAPOWNER_CURRENT |
 
			MP_MAP2 | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR |
 
			MP_MAP5,
 
			st->index,
 
			(direction&1) + 0x50);
 

	
 
		UpdateStationVirtCoordDirty(st);
 
		UpdateStationAcceptance(st, false);
 
		InvalidateWindow(WC_STATION_LIST, st->owner);
 
	}
 
	return _price.build_dock;
 
}
 

	
 
static int32 RemoveDock(Station *st, uint32 flags)
 
{
 
	uint tile1, tile2;
 

	
 
	if (!CheckOwnership(st->owner))
 
		return CMD_ERROR;
 

	
 
	tile1 = st->dock_tile;
 
	tile2 = tile1 + _tileoffs_by_dir[_map5[tile1] - 0x4C];
 

	
 
	if (!EnsureNoVehicle(tile1))
 
		return CMD_ERROR;
 

	
 
	if (!EnsureNoVehicle(tile2))
 
		return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		DoClearSquare(tile1);
 

	
 
		// convert the water tile to water.
 
		ModifyTile(tile2, MP_SETTYPE(MP_WATER) | MP_MAPOWNER | MP_MAP5 | MP_MAP2_CLEAR | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR, OWNER_WATER, 0);
 

	
 
		st->dock_tile = 0;
 
		st->facilities &= ~FACIL_DOCK;
 

	
 
		UpdateStationVirtCoordDirty(st);
 
		DeleteStationIfEmpty(st);
 
	}
 

	
 
	return _price.remove_dock;
 
}
 

	
 
#include "table/station_land.h"
 

	
 

	
 
extern uint16 _custom_sprites_base;
 

	
 
static void DrawTile_Station(TileInfo *ti)
 
{
 
	uint32 image_or_modificator;
 
	uint32 image;
 
	const DrawTileSeqStruct *dtss;
 
	const DrawTileSprites *t = NULL;
 
	byte railtype = _map3_lo[ti->tile] & 0xF;
 
	uint32 relocation = 0;
 

	
 
	{
 
		uint owner = _map_owner[ti->tile];
 
		image_or_modificator = 0x315 << 16; /* NOTE: possible bug in ttd here? */
 
		if (owner < MAX_PLAYERS)
 
			image_or_modificator = PLAYER_SPRITE_COLOR(owner);
 
	}
 

	
 
	// don't show foundation for docks (docks are between 76 (0x4C) and 81 (0x51))
 
	if (ti->tileh != 0 && (ti->map5 < 0x4C || ti->map5 > 0x51))
 
		DrawFoundation(ti, ti->tileh);
 

	
 
	if (_map3_lo[ti->tile] & 0x10) {
 
		// look for customization
 
		struct StationSpec *statspec = GetCustomStation(STAT_CLASS_DFLT, _map3_hi[ti->tile]);
 

	
 
		//debug("Cust-o-mized %p", statspec);
 

	
 
		if (statspec != NULL) {
 
			Station *st = DEREF_STATION(_map2[ti->tile]);
 

	
 
			relocation = GetCustomStationRelocation(statspec, st, 0);
 
			//debug("Relocation %d", relocation);
 
			t = &statspec->renderdata[ti->map5];
 
		}
 
	}
 

	
 
	if (t == NULL) t = &_station_display_datas[ti->map5];
 

	
 
	image = t->ground_sprite;
 
	if (image & 0x8000)
 
		image |= image_or_modificator;
 

	
 
	// station_land array has been increased from 82 elements to 114
 
	// but this is something else. If AI builds station with 114 it looks all weird
 
	image += railtype * ((image < _custom_sprites_base) ? TRACKTYPE_SPRITE_PITCH : 1);
 
	image += railtype * ((image & 0x3FFF) < _custom_sprites_base ? TRACKTYPE_SPRITE_PITCH : 1);
 
	DrawGroundSprite(image);
 

	
 
	foreach_draw_tile_seq(dtss, t->seq) {
 
		image =	dtss->image + relocation;
 
		// XXX: Do we want to do this for custom stations? --pasky
 
		image += railtype * ((image < _custom_sprites_base) ? TRACKTYPE_SPRITE_PITCH : 1);
 
		// For custom sprites, there's no railtype-based pitching.
 
		image += railtype * ((image & 0x3FFF) < _custom_sprites_base ? TRACKTYPE_SPRITE_PITCH : 0);
 
		if (_display_opt & DO_TRANS_BUILDINGS) {
 
			if (image&0x8000) image |= image_or_modificator;	
 
		} else {
 
			image = (image & 0x3FFF) | 0x03224000;
 
		}
 

	
 
		if ((byte)dtss->delta_z != 0x80) {
 
			AddSortableSpriteToDraw(image, ti->x + dtss->delta_x, ti->y + dtss->delta_y, dtss->width, dtss->height, dtss->unk, ti->z + dtss->delta_z);
 
		} else {
 
			AddChildSpriteScreen(image, dtss->delta_x, dtss->delta_y);
 
		}
 
	}
 
}
 

	
 
void StationPickerDrawSprite(int x, int y, int railtype, int image)
 
{
 
	uint32 ormod, img;
 
	const DrawTileSeqStruct *dtss;
 
	const DrawTileSprites *t;
 

	
 
	/* baseimage */
 
	railtype *= TRACKTYPE_SPRITE_PITCH;
 

	
 
	ormod = PLAYER_SPRITE_COLOR(_local_player);
 

	
 
	t = &_station_display_datas[image];
 

	
 
	img = t->ground_sprite;
 
	if (img & 0x8000)
 
		img |= ormod;
 
	DrawSprite(img + railtype, x, y);
 

	
 
	foreach_draw_tile_seq(dtss, t->seq) {
 
		Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
 
		DrawSprite((dtss->image | ormod) + railtype, x + pt.x, y + pt.y);
 
	}
 
}
 

	
 
static uint GetSlopeZ_Station(TileInfo *ti)
 
{
 
	uint z = ti->z;
 
	if (ti->tileh != 0)
 
		z += 8;
 
	return z;
 
}
 

	
 
static uint GetSlopeTileh_Station(TileInfo *ti)
 
{
 
	return 0;
 
}
 

	
 
static void GetAcceptedCargo_Station(uint tile, AcceptedCargo *ac)
 
{
 
	/* not used */
 
}
 

	
 
static void GetTileDesc_Station(uint tile, TileDesc *td)
 
{
 
	byte m5;
 
	StringID str;
 

	
 
	td->owner = _map_owner[tile];
 
	td->build_date = DEREF_STATION(_map2[tile])->build_date;
 

	
 
	m5 = _map5[tile];
 
	(str=STR_305E_RAILROAD_STATION, m5 < 8) ||
 
	(str=STR_305F_AIRCRAFT_HANGAR, m5==32 || m5==45) || // hangars
 
	(str=STR_3060_AIRPORT, m5 < 0x43 || (m5 >= 83 && m5 <= 114)) ||
 
	(str=STR_3061_TRUCK_LOADING_AREA, m5 < 0x47) ||
 
	(str=STR_3062_BUS_STATION, m5 < 0x4B) ||
 
	(str=STR_4807_OIL_RIG, m5 == 0x4B) ||
 
	(str=STR_3063_SHIP_DOCK, m5 != 0x52) ||
 
	(str=STR_3069_BUOY, true);
 
	td->str = str;
 
}
 

	
 

	
 
static const byte _tile_track_status_rail[8] = { 1,2,1,2,1,2,1,2 };
 

	
 
static uint32 GetTileTrackStatus_Station(uint tile, TransportType mode) {
 
	uint i = _map5[tile];
 
	uint j = 0;
 

	
 
	if (mode == TRANSPORT_RAIL) {
 
		if (i < 8)
 
			j = _tile_track_status_rail[i];
 
		j += (j << 8);
 
	} else if (mode == TRANSPORT_ROAD) {
 
		Station *st = DEREF_STATION(_map2[tile]);
 
		if ( (IS_BYTE_INSIDE(i, 0x43, 0x47) && (_patches.roadveh_queue || st->truck_stop_status&3)) ||
 
		(IS_BYTE_INSIDE(i, 0x47, 0x4B) && (_patches.roadveh_queue || st->bus_stop_status&3)) ) {
 
			/* This is a bus/truck stop, and there is free space
 
			 * (or we allow queueing) */
 

	
 
			/* We reverse the dir because it points out of the
 
			 * exit, and we want to get in. Maybe we should return
 
			 * both dirs here? */
 
			byte dir = _reverse_dir[(i-0x43)&3];
 
			j = 1 << _dir_to_straight_trackdir[dir];
 
		}
 
	} else if (mode == TRANSPORT_WATER) {
 
		// buoy is coded as a station, it is always on open water
 
		// (0x3F, all tracks available)
 
		if (i == 0x52) j = 0x3F;
 
		j += (j << 8);
 
	}
 
	return j;
 
}
 

	
 
static void TileLoop_Station(uint tile)
 
{
 
  //FIXME -- GetTileTrackStatus_Station -> animated stationtiles
 
  // hardcoded.....not good
 
  // 0x27 - large big airport (39)
 
  // 0x66 - radar metropolitan airport (102)
 
  // 0x5A - radar international airport (90)
 
  // 0x3A - flag small airport (58)
 
	if (_map5[tile] == 39 || _map5[tile] == 58 || _map5[tile] == 90 || _map5[tile] == 102)
 
		AddAnimatedTile(tile);
 

	
 
	// treat a bouy tile as water.
 
	else if (_map5[tile] == 0x52)
 
		TileLoop_Water(tile);
 

	
 
	// treat a oilrig (the station part) as water
 
	else if (_map5[tile] == 0x4B)
 
		TileLoop_Water(tile);
 

	
 
}
 

	
 

	
 
static void AnimateTile_Station(uint tile)
 
{
 
	byte m5 = _map5[tile];
 
	//FIXME -- AnimateTile_Station -> not nice code, lots of things double
 
  // again hardcoded...was a quick hack
 

	
 
  // turning radar / windsack on airport
 
	if (m5 >= 39 && m5 <= 50) { // turning radar (39 - 50)
 
		if (_tick_counter & 3)
 
			return;
 

	
 
		if (++m5 == 50+1)
 
			m5 = 39;
 

	
 
		_map5[tile] = m5;
 
		MarkTileDirtyByTile(tile);
 
  //added - begin
 
	} else if (m5 >= 90 && m5 <= 113) { // turning radar with ground under it (different fences) (90 - 101 | 102 - 113)
 
		if (_tick_counter & 3)
 
			return;
 

	
 
		m5++;
 

	
 
		if (m5 == 101+1) {m5 = 90;}  // radar with fences in south
 
		else if (m5 == 113+1) {m5 = 102;} // radar with fences in north
 

	
 
		_map5[tile] = m5;
 
		MarkTileDirtyByTile(tile);
 
	//added - end
 
	} else if (m5 >= 0x3A && m5 <= 0x3D) {  // windsack (58 - 61)
 
		if (_tick_counter & 1)
 
			return;
 

	
 
		if (++m5 == 0x3D+1)
 
			m5 = 0x3A;
 

	
 
		_map5[tile] = m5;
 
		MarkTileDirtyByTile(tile);
 
	}
 
}
 

	
 
static void ClickTile_Station(uint tile)
 
{
 
  // 0x20 - hangar large airport (32)
 
  // 0x41 - hangar small airport (65)
 
	if (_map5[tile] == 32 || _map5[tile] == 65) {
 
		ShowAircraftDepotWindow(tile);
 
	} else {
 
		ShowStationViewWindow(_map2[tile]);
 
	}
 
}
 

	
 
static INLINE bool IsTrainStationTile(uint tile) {
 
	return IS_TILETYPE(tile, MP_STATION) && IS_BYTE_INSIDE(_map5[tile], 0, 8);
 
}
 

	
 
static const byte _enter_station_speedtable[12] = {
 
	215, 195, 175, 155, 135, 115, 95, 75, 55, 35, 15, 0
 
};
 

	
 
static uint32 VehicleEnter_Station(Vehicle *v, uint tile, int x, int y)
0 comments (0 inline, 0 general)