#region Copyright & License Information /* * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, * see COPYING. */ #endregion using System; using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("Reserve landing places for aircraft.")] class ReservableInfo : TraitInfo { } public class Reservable : ITick, INotifyKilled, INotifyOwnerChanged, INotifySold { Actor reservedFor; Aircraft reservedForAircraft; public void Tick(Actor self) { if (reservedFor == null) return; /* nothing to do */ if (!Target.FromActor(reservedFor).IsValidFor(self)) reservedFor = null; /* not likely to arrive now. */ } public IDisposable Reserve(Actor self, Actor forActor, Aircraft forAircraft) { reservedFor = forActor; reservedForAircraft = forAircraft; // NOTE: we really dont care about the GC eating DisposableActions that apply to a world *other* than // the one we're playing in. return new DisposableAction( () => { reservedFor = null; reservedForAircraft = null; }, () => Game.RunAfterTick(() => { if (Game.IsCurrentWorld(self.World)) throw new InvalidOperationException( "Attempted to finalize an undisposed DisposableAction. {0} ({1}) reserved {2} ({3})".F( forActor.Info.Name, forActor.ActorID, self.Info.Name, self.ActorID)); })); } public static bool IsReserved(Actor a) { var res = a.TraitOrDefault(); return res != null && res.reservedFor != null; } public void Killed(Actor self, AttackInfo e) { if (reservedForAircraft != null) reservedForAircraft.UnReserve(); } public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) { if (reservedForAircraft != null) reservedForAircraft.UnReserve(); } public void Selling(Actor self) { Sold(self); } public void Sold(Actor self) { if (reservedForAircraft != null) reservedForAircraft.UnReserve(); } } }