Destroy a paradropped crate if it lands on something that can’t collect it. Fixes #5953, #6427.

This commit is contained in:
Paul Chote
2014-09-12 18:23:04 +12:00
parent 6e5d1da468
commit 8ec8f82178

View File

@@ -11,6 +11,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.RA.Buildings; using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Move;
using OpenRA.Mods.RA.Render; using OpenRA.Mods.RA.Render;
using OpenRA.Primitives; using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
@@ -53,10 +54,12 @@ namespace OpenRA.Mods.RA
public void OnCrush(Actor crusher) public void OnCrush(Actor crusher)
{ {
if (collected) return; if (collected)
return;
var shares = self.TraitsImplementing<CrateAction>()
.Select(a => Pair.New(a, a.GetSelectionSharesOuter(crusher)));
var shares = self.TraitsImplementing<CrateAction>().Select(
a => Pair.New(a, a.GetSelectionSharesOuter(crusher)));
var totalShares = shares.Sum(a => a.Second); var totalShares = shares.Sum(a => a.Second);
var n = self.World.SharedRandom.Next(totalShares); var n = self.World.SharedRandom.Next(totalShares);
@@ -64,6 +67,7 @@ namespace OpenRA.Mods.RA
collected = true; collected = true;
foreach (var s in shares) foreach (var s in shares)
{
if (n < s.Second) if (n < s.Second)
{ {
s.First.Activate(crusher); s.First.Activate(crusher);
@@ -72,14 +76,33 @@ namespace OpenRA.Mods.RA
else else
n -= s.Second; n -= s.Second;
} }
}
public void OnLanded() public void OnLanded()
{ {
// Check whether the crate landed on anything
var landedOn = self.World.ActorMap.GetUnitsAt(self.Location) var landedOn = self.World.ActorMap.GetUnitsAt(self.Location)
.FirstOrDefault(a => a != self); .Where(a => a != self);
if (landedOn != null) if (!landedOn.Any())
OnCrush(landedOn); return;
var collector = landedOn.FirstOrDefault(a =>
{
// Mobile is (currently) the only trait that supports crushing
var mi = a.Info.Traits.GetOrDefault<MobileInfo>();
if (mi == null)
return false;
// Make sure that the actor can collect this crate type
return CrushableBy(mi.Crushes, a.Owner);
});
// Destroy the crate if none of the units in the cell are valid collectors
if (collector != null)
OnCrush(collector);
else
self.Destroy();
} }
public void Tick(Actor self) public void Tick(Actor self)