diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 678df47f0d..b8ab0f7b3d 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -142,7 +142,7 @@ namespace OpenRA.Traits public interface ICrushable { void OnCrush(Actor crusher); - IEnumerable CrushClasses { get; } + bool CrushableBy(string[] crushClasses, Player owner); } public struct Renderable diff --git a/OpenRA.Mods.RA/Buildings/Wall.cs b/OpenRA.Mods.RA/Buildings/Wall.cs index da22175d29..e5e486de0a 100755 --- a/OpenRA.Mods.RA/Buildings/Wall.cs +++ b/OpenRA.Mods.RA/Buildings/Wall.cs @@ -9,6 +9,7 @@ #endregion using System.Collections.Generic; +using System.Linq; using OpenRA.Traits; namespace OpenRA.Mods.RA.Buildings @@ -31,7 +32,14 @@ namespace OpenRA.Mods.RA.Buildings this.info = info; } - public IEnumerable CrushClasses { get { return info.CrushClasses; } } + public bool CrushableBy(string[] crushClasses, Player crushOwner) + { + if (crushOwner.Stances[self.Owner] == Stance.Ally) + return false; + + return info.CrushClasses.Intersect(crushClasses).Any(); + } + public void OnCrush(Actor crusher) { self.Kill(crusher); diff --git a/OpenRA.Mods.RA/Crate.cs b/OpenRA.Mods.RA/Crate.cs index 03ede79c5f..7f38113604 100644 --- a/OpenRA.Mods.RA/Crate.cs +++ b/OpenRA.Mods.RA/Crate.cs @@ -122,6 +122,9 @@ namespace OpenRA.Mods.RA self.World.ActorMap.Add(self, this); } - public IEnumerable CrushClasses { get { yield return "crate"; } } + public bool CrushableBy(string[] crushClasses, Player owner) + { + return crushClasses.Contains("crate"); + } } } diff --git a/OpenRA.Mods.RA/Mine.cs b/OpenRA.Mods.RA/Mine.cs index ef90aa15b6..1738c1ef35 100644 --- a/OpenRA.Mods.RA/Mine.cs +++ b/OpenRA.Mods.RA/Mine.cs @@ -9,6 +9,7 @@ #endregion using System.Collections.Generic; +using System.Linq; using OpenRA.Mods.RA.Activities; using OpenRA.Traits; using OpenRA.FileFormats; @@ -48,10 +49,13 @@ namespace OpenRA.Mods.RA Combat.DoExplosion(self, info.Weapon, crusher.CenterLocation, 0); self.QueueActivity(new RemoveSelf()); } - + // TODO: Re-implement friendly-mine avoidance - public IEnumerable CrushClasses { get { return info.CrushClasses; } } - + public bool CrushableBy(string[] crushClasses, Player owner) + { + return info.CrushClasses.Intersect(crushClasses).Any(); + } + public int2 TopLeft { get { return location; } } public IEnumerable> OccupiedCells() { yield return Pair.New(TopLeft, SubCell.FullCell); } diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index d27c9e2cc0..a3eac5aff1 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -91,7 +91,7 @@ namespace OpenRA.Mods.RA.Move return false; if (blockingActors.Any(a => !(a.HasTrait() && - a.TraitsImplementing().Any(b => b.CrushClasses.Intersect(Crushes).Any())))) + a.TraitsImplementing().Any(b => b.CrushableBy(Crushes, owner))))) return false; } @@ -310,9 +310,9 @@ namespace OpenRA.Mods.RA.Move // Non-sharable unit can enter a cell with shareable units only if it can crush all of them if (Info.Crushes == null) return false; - - if (blockingActors.Any(c => !(c.HasTrait() && - c.TraitsImplementing().Any(d => d.CrushClasses.Intersect(Info.Crushes).Any())))) + + if (blockingActors.Any(c => !(c.HasTrait() && + c.TraitsImplementing().Any(d => d.CrushableBy(Info.Crushes, self.Owner))))) return false; } return true; @@ -334,7 +334,7 @@ namespace OpenRA.Mods.RA.Move var crushable = self.World.ActorMap.GetUnitsAt(toCell).Where(a => a != self && a.HasTrait()); foreach (var a in crushable) { - var crushActions = a.TraitsImplementing().Where(b => b.CrushClasses.Intersect(Info.Crushes).Any()); + var crushActions = a.TraitsImplementing().Where(b => b.CrushableBy(Info.Crushes, self.Owner)); foreach (var b in crushActions) b.OnCrush(self); }