Merge pull request #8226 from pchote/actor-disposal

Dispose traits when destroying an actor.
This commit is contained in:
Oliver Brakmann
2015-06-02 19:33:22 +02:00
54 changed files with 138 additions and 81 deletions

View File

@@ -382,7 +382,7 @@ namespace OpenRA.Mods.Common.AI
case BuildingType.Defense:
// Build near the closest enemy structure
var closestEnemy = World.Actors.Where(a => !a.Destroyed && a.HasTrait<Building>() && Player.Stances[a.Owner] == Stance.Enemy)
var closestEnemy = World.Actors.Where(a => !a.Disposed && a.HasTrait<Building>() && Player.Stances[a.Owner] == Stance.Enemy)
.ClosestTo(World.Map.CenterOfCell(defenseCenter));
var targetCell = closestEnemy != null ? closestEnemy.Location : baseCenter;
@@ -944,7 +944,7 @@ namespace OpenRA.Mods.Common.AI
}
}
if (e.Attacker.Destroyed)
if (e.Attacker.Disposed)
return;
if (!e.Attacker.HasTrait<ITargetable>())

View File

@@ -94,7 +94,7 @@ namespace OpenRA.Mods.Common.AI
else
{
var enemies = owner.World.FindActorsInCircle(leader.CenterPosition, WRange.FromCells(12))
.Where(a1 => !a1.Destroyed && !a1.IsDead);
.Where(a1 => !a1.Disposed && !a1.IsDead);
var enemynearby = enemies.Where(a1 => a1.HasTrait<ITargetable>() && leader.Owner.Stances[a1.Owner] == Stance.Enemy);
var target = enemynearby.ClosestTo(leader.CenterPosition);
if (target != null)

View File

@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Activities
weapon.Impact(Target.FromPos(self.CenterPosition), self, Enumerable.Empty<int>());
}
self.Destroy();
self.Dispose();
return null;
}

View File

@@ -71,7 +71,7 @@ namespace OpenRA.Mods.Common.Activities
actor.InflictDamage(self, damage, null);
}
self.Destroy();
self.Dispose();
});
}
}

View File

@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Activities
return;
target.Owner.PlayerActor.Trait<PlayerResources>().GiveCash(payload);
self.Destroy();
self.Dispose();
if (self.Owner.IsAlliedWith(self.World.RenderPlayer))
self.World.AddFrameEndTask(w => w.Add(new FloatingText(target.CenterPosition, target.Owner.Color.RGB, FloatingText.FormatCashTick(payload), 30)));

View File

@@ -77,7 +77,7 @@ namespace OpenRA.Mods.Common.Activities
capturable.EndCapture();
if (capturesInfo != null && capturesInfo.ConsumeActor)
self.Destroy();
self.Dispose();
});
}
}

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
if (IsCanceled) return NextActivity;
self.Destroy();
self.Dispose();
return null;
}
}

View File

@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Activities
if (hut.BridgeDamageState == DamageState.Undamaged || hut.Repairing || hut.Bridge.GetHut(0) == null || hut.Bridge.GetHut(1) == null)
return;
hut.Repair(self);
self.Destroy();
self.Dispose();
}
}
}

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Mods.Common.Activities
if (health.DamageState == DamageState.Undamaged)
return;
target.InflictDamage(self, -health.MaxHP, null);
self.Destroy();
self.Dispose();
}
}
}

View File

@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Activities
if (refund > 0 && self.Owner.IsAlliedWith(self.World.RenderPlayer))
self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition, self.Owner.Color.RGB, FloatingText.FormatCashTick(refund), 30)));
self.Destroy();
self.Dispose();
return this;
}

View File

@@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Activities
var selected = w.Selection.Contains(self);
var controlgroup = w.Selection.GetControlGroupForActor(self);
self.Destroy();
self.Dispose();
foreach (var s in Sounds)
Sound.PlayToPlayer(self.Owner, s, self.CenterPosition);

View File

@@ -76,7 +76,7 @@ namespace OpenRA.Mods.Common.Activities
cargo.Unload(self);
self.World.AddFrameEndTask(w =>
{
if (actor.Destroyed)
if (actor.Disposed)
return;
var move = actor.Trait<IMove>();

View File

@@ -106,7 +106,7 @@ namespace OpenRA.Mods.Common.Commands
foreach (var actor in world.Selection.Actors)
{
if (actor.IsDead || actor.Destroyed)
if (actor.IsDead || actor.Disposed)
continue;
var leveluporder = new Order("DevLevelUp", actor, false);

View File

@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Effects
public IEnumerable<IRenderable> Render(WorldRenderer wr)
{
if (a.Destroyed || wr.World.FogObscures(a))
if (a.Disposed || wr.World.FogObscures(a))
return SpriteRenderable.None;
return anim.Render(a.CenterPosition, wr.Palette(canPowerDown.Info.IndicatorPalette));

View File

@@ -45,7 +45,7 @@ namespace OpenRA.Mods.Common.Effects
public IEnumerable<IRenderable> Render(WorldRenderer wr)
{
if (building.Destroyed || wr.World.FogObscures(building) || rb.Repairers.Count == 0)
if (building.Disposed || wr.World.FogObscures(building) || rb.Repairers.Count == 0)
return SpriteRenderable.None;
PaletteReference palette;

View File

@@ -112,7 +112,7 @@ namespace OpenRA.Mods.Common.Scripting
if (!sma.Actors.TryGetValue(actorName, out ret))
return null;
if (ret.Destroyed)
if (ret.Disposed)
return null;
return ret;

View File

@@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Traits
bool IOccupySpaceInfo.SharesCell { get { return false; } }
}
public class Aircraft : IFacing, IPositionable, ISync, INotifyKilled, IIssueOrder, IOrderVoice, INotifyAddedToWorld, INotifyRemovedFromWorld
public class Aircraft : IFacing, IPositionable, ISync, IIssueOrder, IOrderVoice, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyActorDisposing
{
static readonly Pair<CPos, SubCell>[] NoCells = { };
@@ -157,7 +157,7 @@ namespace OpenRA.Mods.Common.Traits
}
}
public void Killed(Actor self, AttackInfo e)
public void Disposing(Actor self)
{
UnReserve();
}

View File

@@ -75,10 +75,10 @@ namespace OpenRA.Mods.Common.Traits
return;
var attacker = e.Attacker;
if (attacker.Destroyed || Stance < UnitStance.ReturnFire)
if (attacker.Disposed || Stance < UnitStance.ReturnFire)
return;
if (!attacker.IsInWorld && !attacker.Destroyed)
if (!attacker.IsInWorld && !attacker.Disposed)
{
// If the aggressor is in a transport, then attack the transport instead
var passenger = attacker.TraitOrDefault<Passenger>();

View File

@@ -8,6 +8,7 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Activities;
@@ -42,7 +43,7 @@ namespace OpenRA.Mods.Common.Traits
public virtual object Create(ActorInitializer init) { return new Refinery(init.Self, this); }
}
public class Refinery : ITick, IAcceptResources, INotifyKilled, INotifySold, INotifyCapture, INotifyOwnerChanged, IExplodeModifier, ISync
public class Refinery : ITick, IAcceptResources, INotifySold, INotifyCapture, INotifyOwnerChanged, IExplodeModifier, ISync, INotifyActorDisposing
{
readonly Actor self;
readonly RefineryInfo info;
@@ -118,7 +119,7 @@ namespace OpenRA.Mods.Common.Traits
}
}
public void Killed(Actor self, AttackInfo e)
public void Disposing(Actor self)
{
CancelDock(self);
foreach (var harv in GetLinkedHarvesters())

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Reserve landing places for aircraft.")]
class ReservableInfo : TraitInfo<Reservable> { }
public class Reservable : ITick, INotifyKilled, INotifyOwnerChanged, INotifySold
public class Reservable : ITick, INotifyOwnerChanged, INotifySold, INotifyActorDisposing
{
Actor reservedFor;
Aircraft reservedForAircraft;
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.Traits
return res != null && res.reservedFor != null;
}
public void Killed(Actor self, AttackInfo e)
public void Disposing(Actor self)
{
if (reservedForAircraft != null)
reservedForAircraft.UnReserve();

View File

@@ -54,7 +54,8 @@ namespace OpenRA.Mods.Common.Traits
public object Create(ActorInitializer init) { return new Cargo(init, this); }
}
public class Cargo : IPips, IIssueOrder, IResolveOrder, IOrderVoice, INotifyCreated, INotifyKilled, INotifyOwnerChanged, INotifyAddedToWorld, ITick, INotifySold, IDisableMove
public class Cargo : IPips, IIssueOrder, IResolveOrder, IOrderVoice, INotifyCreated, INotifyKilled,
INotifyOwnerChanged, INotifyAddedToWorld, ITick, INotifySold, IDisableMove, INotifyActorDisposing
{
public readonly CargoInfo Info;
readonly Actor self;
@@ -305,6 +306,14 @@ namespace OpenRA.Mods.Common.Traits
cargo.Clear();
}
public void Disposing(Actor self)
{
foreach (var c in cargo)
c.Dispose();
cargo.Clear();
}
public void Selling(Actor self) { }
public void Sold(Actor self)
{

View File

@@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.Traits
var crateActions = self.TraitsImplementing<CrateAction>();
self.Destroy();
self.Dispose();
collected = true;
if (crateActions.Any())
@@ -112,13 +112,13 @@ namespace OpenRA.Mods.Common.Traits
if (collector != null)
OnCrush(collector);
else
self.Destroy();
self.Dispose();
}
public void Tick(Actor self)
{
if (info.Lifetime != 0 && ++ticks >= info.Lifetime * 25)
self.Destroy();
self.Dispose();
}
public CPos TopLeft { get { return Location; } }

View File

@@ -78,7 +78,7 @@ namespace OpenRA.Mods.Common.Traits
}
}
else
pilot.Destroy();
pilot.Dispose();
}
static bool IsSuitableCell(Actor self, Actor actorToDrop)

View File

@@ -44,7 +44,7 @@ namespace OpenRA.Mods.Common.Traits
{
var info = self.Info.Traits.Get<GivesBountyInfo>();
if (e.Attacker == null || e.Attacker.Destroyed) return;
if (e.Attacker == null || e.Attacker.Disposed) return;
if (!info.Stances.Contains(e.Attacker.Owner.Stances[self.Owner])) return;

View File

@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits
public void Killed(Actor self, AttackInfo e)
{
// Prevent TK from giving exp
if (e.Attacker == null || e.Attacker.Destroyed || (!info.FriendlyFire && e.Attacker.Owner.Stances[self.Owner] == Stance.Ally))
if (e.Attacker == null || e.Attacker.Disposed || (!info.FriendlyFire && e.Attacker.Owner.Stances[self.Owner] == Stance.Ally))
return;
var valued = self.Info.Traits.GetOrDefault<ValuedInfo>();

View File

@@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.Traits
public void SetProcLines(Actor proc)
{
if (proc == null) return;
if (proc.Destroyed) return;
if (proc.Disposed) return;
var linkedHarvs = proc.World.ActorsWithTrait<Harvester>()
.Where(a => a.Trait.LinkedProc == proc)
@@ -156,7 +156,7 @@ namespace OpenRA.Mods.Common.Traits
{
// Check that we're not in a critical location and being useless (refinery drop-off):
var lastproc = LastLinkedProc ?? LinkedProc;
if (lastproc != null && !lastproc.Destroyed)
if (lastproc != null && !lastproc.Disposed)
{
var deliveryLoc = lastproc.Location + lastproc.Trait<IAcceptResources>().DeliveryOffset;
if (self.Location == deliveryLoc)

View File

@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits
return;
if (Info.RemoveInstead || !self.HasTrait<Health>())
self.Destroy();
self.Dispose();
else
self.Kill(self);
}

View File

@@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Traits
public void Tick(Actor self)
{
if (self.Destroyed)
if (self.Disposed)
return;
VisibilityHash = 0;

View File

@@ -86,7 +86,7 @@ namespace OpenRA.Mods.Common.Traits
{
self.World.AddFrameEndTask(w =>
{
if (self.Destroyed || captor.Destroyed) return;
if (self.Disposed || captor.Disposed) return;
var previousOwner = self.Owner;
@@ -112,7 +112,7 @@ namespace OpenRA.Mods.Common.Traits
IEnumerable<Actor> UnitsInRange()
{
return Self.World.FindActorsInCircle(Self.CenterPosition, WRange.FromCells(Info.Range))
.Where(a => a.IsInWorld && a != Self && !a.Destroyed && !a.Owner.NonCombatant);
.Where(a => a.IsInWorld && a != Self && !a.Disposed && !a.Owner.NonCombatant);
}
bool IsClear(Actor self, Player currentOwner, Player originalOwner)

View File

@@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.Traits
{
self.World.AddFrameEndTask(w =>
{
if (!self.Destroyed)
if (!self.Disposed)
w.Add(new Corpse(w, self.CenterPosition, rs.GetImage(self), sequence, palette));
});
}

View File

@@ -8,6 +8,7 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Traits;
@@ -24,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits
public object Create(ActorInitializer init) { return new StoresResources(init.Self, this); }
}
class StoresResources : IPips, INotifyOwnerChanged, INotifyCapture, INotifyKilled, IExplodeModifier, IStoreResources, ISync
class StoresResources : IPips, INotifyOwnerChanged, INotifyCapture, IExplodeModifier, IStoreResources, ISync, INotifyActorDisposing
{
readonly StoresResourcesInfo info;
@@ -51,9 +52,14 @@ namespace OpenRA.Mods.Common.Traits
newOwner.PlayerActor.Trait<PlayerResources>().GiveResources(resources);
}
public void Killed(Actor self, AttackInfo e)
bool disposed;
public void Disposing(Actor self)
{
if (disposed)
return;
player.TakeResources(Stored); // lose the stored resources
disposed = true;
}
public IEnumerable<PipType> GetPips(Actor self)

View File

@@ -87,7 +87,7 @@ namespace OpenRA.Mods.Common.Traits
void ActorEntered(Actor a)
{
if (a.Destroyed)
if (a.Disposed)
return;
if (a == self && !info.AffectsParent)
@@ -122,7 +122,7 @@ namespace OpenRA.Mods.Common.Traits
void ActorExited(Actor a)
{
if (a == self || a.Destroyed)
if (a == self || a.Disposed)
return;
var stance = self.Owner.Stances[a.Owner];

View File

@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits
{
if (claimByActor.Remove(claim.Claimer) & claimByCell.Remove(claim.Cell))
{
if (claim.Claimer.Destroyed) return;
if (claim.Claimer.Disposed) return;
if (!claim.Claimer.IsInWorld) return;
if (claim.Claimer.IsDead) return;

View File

@@ -106,7 +106,7 @@ namespace OpenRA.Mods.Common.Widgets
void PerformKeyboardOrderOnSelection(Func<Actor, Order> f)
{
var orders = world.Selection.Actors
.Where(a => a.Owner == world.LocalPlayer && !a.Destroyed)
.Where(a => a.Owner == world.LocalPlayer && !a.Disposed)
.Select(f)
.ToArray();
@@ -142,7 +142,7 @@ namespace OpenRA.Mods.Common.Widgets
bool PerformStanceCycle()
{
var actor = world.Selection.Actors
.Where(a => a.Owner == world.LocalPlayer && !a.Destroyed)
.Where(a => a.Owner == world.LocalPlayer && !a.Disposed)
.Select(a => Pair.New(a, a.TraitOrDefault<AutoTarget>()))
.FirstOrDefault(a => a.Second != null);
@@ -176,7 +176,7 @@ namespace OpenRA.Mods.Common.Widgets
bool PerformGuard()
{
var actors = world.Selection.Actors
.Where(a => !a.Destroyed && a.Owner == world.LocalPlayer && a.HasTrait<Guard>());
.Where(a => !a.Disposed && a.Owner == world.LocalPlayer && a.HasTrait<Guard>());
if (actors.Any())
world.OrderGenerator = new GuardOrderGenerator(actors);