Allow driving under crates and crushable units

This commit is contained in:
Gustas
2022-09-29 19:27:06 +03:00
committed by abcdefg30
parent 5abbdc37cb
commit 7f677f1842
4 changed files with 30 additions and 62 deletions

View File

@@ -830,41 +830,28 @@ namespace OpenRA.Mods.Common.Traits
public void FinishedMoving(Actor self)
{
// Only make actor crush if it is on the ground
// Only crush actors on having landed
if (!self.IsAtGroundLevel())
return;
var actors = self.World.ActorMap.GetActorsAt(TopLeft).Where(a => a != self).ToList();
if (!AnyCrushables(actors))
return;
var notifiers = actors.SelectMany(a => a.TraitsImplementing<INotifyCrushed>().Select(t => new TraitPair<INotifyCrushed>(a, t)));
foreach (var notifyCrushed in notifiers)
notifyCrushed.Trait.OnCrush(notifyCrushed.Actor, self, Info.Crushes);
}
bool AnyCrushables(List<Actor> actors)
{
var crushables = actors.SelectMany(a => a.TraitsImplementing<ICrushable>().Select(t => new TraitPair<ICrushable>(a, t))).ToList();
if (crushables.Count == 0)
return false;
foreach (var crushes in crushables)
if (crushes.Trait.CrushableBy(crushes.Actor, self, Info.Crushes))
return true;
return false;
CrushAction(self, (notifyCrushed) => notifyCrushed.OnCrush);
}
public void EnteringCell(Actor self)
{
var actors = self.World.ActorMap.GetActorsAt(TopLeft).Where(a => a != self).ToList();
if (!AnyCrushables(actors))
return;
CrushAction(self, (notifyCrushed) => notifyCrushed.WarnCrush);
}
var notifiers = actors.SelectMany(a => a.TraitsImplementing<INotifyCrushed>().Select(t => new TraitPair<INotifyCrushed>(a, t)));
foreach (var notifyCrushed in notifiers)
notifyCrushed.Trait.WarnCrush(notifyCrushed.Actor, self, Info.Crushes);
void CrushAction(Actor self, Func<INotifyCrushed, Action<Actor, Actor, BitSet<CrushClass>>> action)
{
var crushables = self.World.ActorMap.GetActorsAt(TopLeft).Where(a => a != self)
.SelectMany(a => a.TraitsImplementing<ICrushable>().Select(t => new TraitPair<ICrushable>(a, t)));
// Only crush actors that are on the ground level
foreach (var crushable in crushables)
if (crushable.Trait.CrushableBy(crushable.Actor, self, Info.Crushes) && crushable.Actor.IsAtGroundLevel())
foreach (var notifyCrushed in crushable.Actor.TraitsImplementing<INotifyCrushed>())
action(notifyCrushed)(crushable.Actor, self, Info.Crushes);
}
public void AddInfluence(IEnumerable<CPos> landingCells)