File diff r1976:fcef181ed14a → r1977:1f8b99c96041
waypoint.c
Show inline comments
 
@@ -84,97 +84,97 @@ void UpdateWaypointSign(Waypoint *wp)
 
void RedrawWaypointSign(Waypoint *wp)
 
{
 
	MarkAllViewportsDirty(
 
		wp->sign.left - 6,
 
		wp->sign.top,
 
		wp->sign.left + (wp->sign.width_1 << 2) + 12,
 
		wp->sign.top + 48);
 
}
 

	
 
/* Update all signs */
 
void UpdateAllWaypointSigns(void)
 
{
 
	Waypoint *wp;
 

	
 
	FOR_ALL_WAYPOINTS(wp) {
 
		if (wp->xy)
 
			UpdateWaypointSign(wp);
 
	}
 
}
 

	
 
/* Set the default name for a waypoint */
 
void MakeDefaultWaypointName(Waypoint *wp)
 
{
 
	Waypoint *local_wp;
 
	bool used_waypoint[MAX_WAYPOINTS_PER_TOWN];
 
	int i;
 

	
 
	wp->town_index = ClosestTownFromTile(wp->xy, (uint)-1)->index;
 

	
 
	memset(used_waypoint, 0, sizeof(used_waypoint));
 

	
 
	/* Find an unused waypoint number belonging to this town */
 
	FOR_ALL_WAYPOINTS(local_wp) {
 
		if (wp == local_wp)
 
			continue;
 

	
 
		if (local_wp->xy && local_wp->string == STR_NULL && local_wp->town_index == wp->town_index)
 
			used_waypoint[local_wp->town_cn] = true;
 
	}
 

	
 
	/* Find an empty spot */
 
	for (i = 0; used_waypoint[i] && i < MAX_WAYPOINTS_PER_TOWN; i++) {}
 

	
 
	wp->string = STR_NULL;
 
	wp->town_cn = i;
 
}
 

	
 
/* Find a deleted waypoint close to a tile. */
 
static Waypoint *FindDeletedWaypointCloseTo(uint tile)
 
static Waypoint *FindDeletedWaypointCloseTo(TileIndex tile)
 
{
 
	Waypoint *wp, *best = NULL;
 
	uint thres = 8, cur_dist;
 

	
 
	FOR_ALL_WAYPOINTS(wp) {
 
		if (wp->deleted && wp->xy) {
 
			cur_dist = DistanceManhattan(tile, wp->xy);
 
			if (cur_dist < thres) {
 
				thres = cur_dist;
 
				best = wp;
 
			}
 
		}
 
	}
 

	
 
	return best;
 
}
 

	
 
/** Convert existing rail to waypoint. Eg build a waypoint station over
 
 * piece of rail
 
 * @param x,y coordinates where waypoint will be built
 
 * @param p1 graphics for waypoint type, bit 8 signifies custom waypoint gfx (& 0x100)
 
 * @param p2 unused
 
 */
 
int32 CmdBuildTrainWaypoint(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	TileIndex tile = TILE_FROM_XY(x, y);
 
	Waypoint *wp;
 
	uint tileh;
 
	uint dir;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	/* if custom gfx are used, make sure it is within bounds */
 
	if (p1 > 0x100 + (uint)GetCustomStationsCount(STAT_CLASS_WAYP)) return CMD_ERROR;
 

	
 
	if (!IsTileType(tile, MP_RAILWAY) || ((dir = 0, _map5[tile] != 1) && (dir = 1, _map5[tile] != 2)))
 
		return_cmd_error(STR_1005_NO_SUITABLE_RAILROAD_TRACK);
 

	
 
	if (!CheckTileOwnership(tile))
 
		return CMD_ERROR;
 

	
 
	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 

	
 
	tileh = GetTileSlope(tile, NULL);
 
	if (tileh != 0) {
 
		if (!_patches.build_on_slopes || tileh & 0x10 || !(tileh & (0x3 << dir)) || !(tileh & ~(0x3 << dir)))
 
			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 
	}
 
@@ -198,189 +198,189 @@ int32 CmdBuildTrainWaypoint(int x, int y
 
			_map3_hi[tile] = p1 & 0xff;
 
		}
 

	
 
		wp->deleted = 0;
 
		wp->xy = tile;
 
		wp->build_date = _date;
 

	
 
		if (wp->town_index == STR_NULL)
 
			MakeDefaultWaypointName(wp);
 

	
 
		UpdateWaypointSign(wp);
 
		RedrawWaypointSign(wp);
 
	}
 

	
 
	return _price.build_train_depot;
 
}
 

	
 
/* Internal handler to delete a waypoint */
 
static void DoDeleteWaypoint(Waypoint *wp)
 
{
 
	Order order;
 

	
 
	wp->xy = 0;
 

	
 
	order.type = OT_GOTO_WAYPOINT;
 
	order.station = wp->index;
 
	DeleteDestinationFromVehicleOrder(order);
 

	
 
	if (wp->string != STR_NULL)
 
		DeleteName(wp->string);
 

	
 
	RedrawWaypointSign(wp);
 
}
 

	
 
/* Daily loop for waypoints */
 
void WaypointsDailyLoop(void)
 
{
 
	Waypoint *wp;
 

	
 
	/* Check if we need to delete a waypoint */
 
	FOR_ALL_WAYPOINTS(wp) {
 
		if (wp->deleted && !--wp->deleted) {
 
			DoDeleteWaypoint(wp);
 
		}
 
	}
 
}
 

	
 
/* Remove a waypoint */
 
int32 RemoveTrainWaypoint(uint tile, uint32 flags, bool justremove)
 
int32 RemoveTrainWaypoint(TileIndex tile, uint32 flags, bool justremove)
 
{
 
	Waypoint *wp;
 

	
 
	/* Make sure it's a waypoint */
 
	if (!IsTileType(tile, MP_RAILWAY) || !IsRailWaypoint(_map5[tile]))
 
		return CMD_ERROR;
 

	
 
	if (!CheckTileOwnership(tile) && !(_current_player == OWNER_WATER))
 
		return CMD_ERROR;
 

	
 
	if (!EnsureNoVehicle(tile))
 
		return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		int direction = _map5[tile] & RAIL_WAYPOINT_TRACK_MASK;
 

	
 
		wp = GetWaypointByTile(tile);
 

	
 
		wp->deleted = 30; // let it live for this many days before we do the actual deletion.
 
		RedrawWaypointSign(wp);
 

	
 
		if (justremove) {
 
			ModifyTile(tile, MP_MAP5, 1<<direction);
 
			_map3_lo[tile] &= ~16;
 
			_map3_hi[tile] = 0;
 
		} else {
 
			DoClearSquare(tile);
 
			SetSignalsOnBothDir(tile, direction);
 
		}
 
	}
 

	
 
	return _price.remove_train_depot;
 
}
 

	
 
/** Delete a waypoint
 
 * @param x,y coordinates where waypoint is to be deleted
 
 * @param p1 unused
 
 * @param p2 unused
 
 */
 
int32 CmdRemoveTrainWaypoint(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	TileIndex tile = TILE_FROM_XY(x,y);
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
	return RemoveTrainWaypoint(tile, flags, true);
 
}
 

	
 
/** Rename a waypoint.
 
 * @param x,y unused
 
 * @param p1 id of waypoint
 
 * @param p2 unused
 
 */
 
int32 CmdRenameWaypoint(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Waypoint *wp;
 
	StringID str;
 

	
 
	if (!IsWaypointIndex(p1)) return CMD_ERROR;
 

	
 
	if (_cmd_text[0] != '\0') {
 
		str = AllocateNameUnique(_cmd_text, 0);
 
		if (str == 0)
 
			return CMD_ERROR;
 

	
 
		if (flags & DC_EXEC) {
 
			wp = GetWaypoint(p1);
 
			if (wp->string != STR_NULL)
 
				DeleteName(wp->string);
 

	
 
			wp->string = str;
 
			wp->town_cn = 0;
 

	
 
			UpdateWaypointSign(wp);
 
			MarkWholeScreenDirty();
 
		} else {
 
			DeleteName(str);
 
		}
 
	}	else {
 
		if (flags & DC_EXEC) {
 
			wp = GetWaypoint(p1);
 
			if (wp->string != STR_NULL)
 
				DeleteName(wp->string);
 

	
 
			MakeDefaultWaypointName(wp);
 
			UpdateWaypointSign(wp);
 
			MarkWholeScreenDirty();
 
		}
 
	}
 
	return 0;
 
}
 

	
 
/* This hacks together some dummy one-shot Station structure for a waypoint. */
 
Station *ComposeWaypointStation(uint tile)
 
Station *ComposeWaypointStation(TileIndex tile)
 
{
 
	Waypoint *wp = GetWaypointByTile(tile);
 
	static Station stat;
 

	
 
	stat.train_tile = stat.xy = wp->xy;
 
	stat.town = GetTown(wp->town_index);
 
	stat.string_id = wp->string == STR_NULL ? /* FIXME? */ 0 : wp->string;
 
	stat.build_date = wp->build_date;
 
	stat.class_id = 6;
 
	stat.stat_id = wp->stat_id;
 

	
 
	return &stat;
 
}
 

	
 
extern uint16 _custom_sprites_base;
 

	
 
/* Draw a waypoint */
 
void DrawWaypointSprite(int x, int y, int stat_id, int railtype)
 
{
 
	StationSpec *stat;
 
	uint32 relocation;
 
	DrawTileSprites *cust;
 
	DrawTileSeqStruct const *seq;
 
	uint32 ormod, img;
 

	
 
	ormod = SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player));
 

	
 
	x += 33;
 
	y += 17;
 

	
 
	/* draw default waypoint graphics of ID 0 */
 
	if (stat_id == 0) {
 
		const DrawTrackSeqStruct *dtss = _track_depot_layout_table[4];
 

	
 
		img = dtss++->image;
 
		if (img & 0x8000) img = (img & 0x7FFF) + railtype*TRACKTYPE_SPRITE_PITCH;
 
		DrawSprite(img, x, y);
 

	
 
		for (; dtss->image != 0; dtss++) {
 
			Point pt = RemapCoords(dtss->subcoord_x, dtss->subcoord_y, 0);
 
			img = dtss->image;
 
			if (img & 0x8000) img |= ormod;
 
			DrawSprite(img, x + pt.x, y + pt.y);
 
		}
 
		return;
 
	}
 

	
 
	stat = GetCustomStation(STAT_CLASS_WAYP, stat_id - 1);