Add a new INotifyCrushed interface

This commit is contained in:
abcdefg30
2016-01-22 10:56:04 +01:00
parent e343803810
commit 8b59ce4dc2
5 changed files with 70 additions and 48 deletions

View File

@@ -38,7 +38,8 @@ namespace OpenRA.Mods.Common.Traits
bool IOccupySpaceInfo.SharesCell { get { return false; } }
}
class Crate : ITick, IPositionable, ICrushable, ISync, INotifyParachuteLanded, INotifyAddedToWorld, INotifyRemovedFromWorld
class Crate : ITick, IPositionable, ICrushable, ISync,
INotifyParachuteLanded, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyCrushed
{
readonly Actor self;
readonly CrateInfo info;
@@ -56,36 +57,14 @@ namespace OpenRA.Mods.Common.Traits
SetPosition(self, init.Get<LocationInit, CPos>());
}
public void WarnCrush(Actor crusher) { }
void INotifyCrushed.WarnCrush(Actor self, Actor crusher, HashSet<string> crushClasses) { }
public void OnCrush(Actor crusher)
void INotifyCrushed.OnCrush(Actor self, Actor crusher, HashSet<string> crushClasses)
{
if (collected)
if (!CrushableBy(crushClasses, crusher.Owner))
return;
var crateActions = self.TraitsImplementing<CrateAction>();
self.Dispose();
collected = true;
if (crateActions.Any())
{
var shares = crateActions.Select(a => Pair.New(a, a.GetSelectionSharesOuter(crusher)));
var totalShares = shares.Sum(a => a.Second);
var n = self.World.SharedRandom.Next(totalShares);
foreach (var s in shares)
{
if (n < s.Second)
{
s.First.Activate(crusher);
return;
}
else
n -= s.Second;
}
}
OnCrushInner(crusher);
}
public void OnLanded()
@@ -110,11 +89,41 @@ namespace OpenRA.Mods.Common.Traits
// Destroy the crate if none of the units in the cell are valid collectors
if (collector != null)
OnCrush(collector);
OnCrushInner(collector);
else
self.Dispose();
}
void OnCrushInner(Actor crusher)
{
if (collected)
return;
var crateActions = self.TraitsImplementing<CrateAction>();
self.Dispose();
collected = true;
if (crateActions.Any())
{
var shares = crateActions.Select(a => Pair.New(a, a.GetSelectionSharesOuter(crusher)));
var totalShares = shares.Sum(a => a.Second);
var n = self.World.SharedRandom.Next(totalShares);
foreach (var s in shares)
{
if (n < s.Second)
{
s.First.Activate(crusher);
return;
}
n -= s.Second;
}
}
}
public void Tick(Actor self)
{
if (info.Lifetime != 0 && self.IsInWorld && ++ticks >= info.Lifetime * 25)