Take ownership into account when determining crushability. Fixes the important half of #951 (tanks crushing your own walls).

This commit is contained in:
Paul Chote
2011-07-10 17:16:22 +12:00
parent 64b88819a9
commit 98ae8c7630
5 changed files with 26 additions and 11 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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");
}
}
}

View File

@@ -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); }

View File

@@ -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);
}