Take ownership into account when determining crushability. Fixes the important half of #951 (tanks crushing your own walls).
This commit is contained in:
@@ -142,7 +142,7 @@ namespace OpenRA.Traits
|
||||
public interface ICrushable
|
||||
{
|
||||
void OnCrush(Actor crusher);
|
||||
IEnumerable<string> CrushClasses { get; }
|
||||
bool CrushableBy(string[] crushClasses, Player owner);
|
||||
}
|
||||
|
||||
public struct Renderable
|
||||
|
||||
@@ -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<string> 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);
|
||||
|
||||
@@ -122,6 +122,9 @@ namespace OpenRA.Mods.RA
|
||||
self.World.ActorMap.Add(self, this);
|
||||
}
|
||||
|
||||
public IEnumerable<string> CrushClasses { get { yield return "crate"; } }
|
||||
public bool CrushableBy(string[] crushClasses, Player owner)
|
||||
{
|
||||
return crushClasses.Contains("crate");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<string> 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<Pair<int2, SubCell>> OccupiedCells() { yield return Pair.New(TopLeft, SubCell.FullCell); }
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace OpenRA.Mods.RA.Move
|
||||
return false;
|
||||
|
||||
if (blockingActors.Any(a => !(a.HasTrait<ICrushable>() &&
|
||||
a.TraitsImplementing<ICrushable>().Any(b => b.CrushClasses.Intersect(Crushes).Any()))))
|
||||
a.TraitsImplementing<ICrushable>().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<ICrushable>() &&
|
||||
c.TraitsImplementing<ICrushable>().Any(d => d.CrushClasses.Intersect(Info.Crushes).Any()))))
|
||||
|
||||
if (blockingActors.Any(c => !(c.HasTrait<ICrushable>() &&
|
||||
c.TraitsImplementing<ICrushable>().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<ICrushable>());
|
||||
foreach (var a in crushable)
|
||||
{
|
||||
var crushActions = a.TraitsImplementing<ICrushable>().Where(b => b.CrushClasses.Intersect(Info.Crushes).Any());
|
||||
var crushActions = a.TraitsImplementing<ICrushable>().Where(b => b.CrushableBy(Info.Crushes, self.Owner));
|
||||
foreach (var b in crushActions)
|
||||
b.OnCrush(self);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user