예제 #1
0
/* static */ bool AIRail::BuildRailWaypoint(TileIndex tile)
{
	EnforcePrecondition(false, ::IsValidTile(tile));
	EnforcePrecondition(false, IsRailTile(tile));
	EnforcePrecondition(false, GetRailTracks(tile) == RAILTRACK_NE_SW || GetRailTracks(tile) == RAILTRACK_NW_SE);
	EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));

	return AIObject::DoCommand(tile, GetCurrentRailType() | (GetRailTracks(tile) == RAILTRACK_NE_SW ? AXIS_X : AXIS_Y) << 4 | 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16, CMD_BUILD_RAIL_WAYPOINT);
}
예제 #2
0
/* static */ bool ScriptRail::BuildSignal(TileIndex tile, TileIndex front, SignalType signal)
{
	EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
	EnforcePrecondition(false, ScriptMap::DistanceManhattan(tile, front) == 1)
	EnforcePrecondition(false, ::IsPlainRailTile(tile));
	EnforcePrecondition(false, ::IsValidSignalType(signal));

	Track track = INVALID_TRACK;
	uint signal_cycles;

	int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile));
	for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) {
		const Track &t = _possible_trackdirs[data_index][i].track;
		if (!(::TrackToTrackBits(t) & GetRailTracks(tile))) continue;
		track = t;
		signal_cycles = _possible_trackdirs[data_index][i].signal_cycles;
		break;
	}
	EnforcePrecondition(false, track != INVALID_TRACK);

	uint p1 = track;
	if (signal < SIGNALTYPE_TWOWAY) {
		if (signal != SIGNALTYPE_PBS && signal != SIGNALTYPE_PBS_ONEWAY) signal_cycles++;
		p1 |= (signal_cycles << 15);
	}
	p1 |= ((signal >= SIGNALTYPE_TWOWAY ? signal ^ SIGNALTYPE_TWOWAY : signal) << 5);

	return ScriptObject::DoCommand(tile, p1, 0, CMD_BUILD_SIGNALS);
}
예제 #3
0
/* static */ bool AIRail::RemoveRailTrack(TileIndex tile, RailTrack rail_track)
{
	EnforcePrecondition(false, ::IsValidTile(tile));
	EnforcePrecondition(false, ::IsPlainRailTile(tile) || ::IsLevelCrossingTile(tile));
	EnforcePrecondition(false, GetRailTracks(tile) & rail_track);
	EnforcePrecondition(false, KillFirstBit((uint)rail_track) == 0);

	return AIObject::DoCommand(tile, tile, GetCurrentRailType() | (FindFirstTrack((::TrackBits)rail_track) << 4), CMD_REMOVE_RAILROAD_TRACK);
}
예제 #4
0
/* static */ bool AIRail::RemoveSignal(TileIndex tile, TileIndex front)
{
	EnforcePrecondition(false, AIMap::DistanceManhattan(tile, front) == 1)
	EnforcePrecondition(false, GetSignalType(tile, front) != SIGNALTYPE_NONE);

	Track track = INVALID_TRACK;
	int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile));
	for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) {
		const Track &t = _possible_trackdirs[data_index][i].track;
		if (!(::TrackToTrackBits(t) & GetRailTracks(tile))) continue;
		track = t;
		break;
	}
	EnforcePrecondition(false, track != INVALID_TRACK);

	return AIObject::DoCommand(tile, track, 0, CMD_REMOVE_SIGNALS);
}
예제 #5
0
/* static */ ScriptRail::SignalType ScriptRail::GetSignalType(TileIndex tile, TileIndex front)
{
	if (ScriptMap::DistanceManhattan(tile, front) != 1) return SIGNALTYPE_NONE;
	if (!::IsTileType(tile, MP_RAILWAY) || !::HasSignals(tile)) return SIGNALTYPE_NONE;

	int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile));

	for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) {
		const Track &track = _possible_trackdirs[data_index][i].track;
		if (!(::TrackToTrackBits(track) & GetRailTracks(tile))) continue;
		if (!HasSignalOnTrack(tile, track)) continue;
		if (!HasSignalOnTrackdir(tile, _possible_trackdirs[data_index][i].trackdir)) continue;
		SignalType st = (SignalType)::GetSignalType(tile, track);
		if (HasSignalOnTrackdir(tile, ::ReverseTrackdir(_possible_trackdirs[data_index][i].trackdir))) st = (SignalType)(st | SIGNALTYPE_TWOWAY);
		return st;
	}

	return SIGNALTYPE_NONE;
}
예제 #6
0
/* static */ bool ScriptRail::AreTilesConnected(TileIndex from, TileIndex tile, TileIndex to)
{
	if (!IsRailTile(tile)) return false;
	if (from == to || ScriptMap::DistanceManhattan(from, tile) != 1 || ScriptMap::DistanceManhattan(tile, to) != 1) return false;

	if (to < from) ::Swap(from, to);

	if (tile - from == 1) {
		if (to - tile == 1) return (GetRailTracks(tile) & RAILTRACK_NE_SW) != 0;
		if (to - tile == ::MapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NE_SE) != 0;
	} else if (tile - from == ::MapSizeX()) {
		if (tile - to == 1) return (GetRailTracks(tile) & RAILTRACK_NW_NE) != 0;
		if (to - tile == 1) return (GetRailTracks(tile) & RAILTRACK_NW_SW) != 0;
		if (to - tile == ::MapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NW_SE) != 0;
	} else {
		return (GetRailTracks(tile) & RAILTRACK_SW_SE) != 0;
	}

	NOT_REACHED();
}