diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 63863d7847..d0447ab2f6 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -137,6 +137,7 @@ namespace OpenRA.Traits public interface IPositionable : IOccupySpace { bool CanEnterCell(CPos location); + bool CanEnterCell(CPos location, Actor ignoreActor, bool checkTransientActors); void SetPosition(Actor self, CPos cell); void SetPosition(Actor self, WPos pos); void SetVisualPosition(Actor self, WPos pos); diff --git a/OpenRA.Mods.RA/Air/Aircraft.cs b/OpenRA.Mods.RA/Air/Aircraft.cs index a88af7990a..73bffe7911 100755 --- a/OpenRA.Mods.RA/Air/Aircraft.cs +++ b/OpenRA.Mods.RA/Air/Aircraft.cs @@ -140,6 +140,7 @@ namespace OpenRA.Mods.RA.Air } public bool CanEnterCell(CPos location) { return true; } + public bool CanEnterCell(CPos cell, Actor ignoreActor, bool checkTransientActors) { return CanEnterCell(cell, null, true); } public int MovementSpeed { diff --git a/OpenRA.Mods.RA/Crate.cs b/OpenRA.Mods.RA/Crate.cs index 2fdeb44bce..e628356864 100644 --- a/OpenRA.Mods.RA/Crate.cs +++ b/OpenRA.Mods.RA/Crate.cs @@ -88,19 +88,26 @@ namespace OpenRA.Mods.RA public void SetPosition(Actor self, WPos pos) { SetPosition(self, pos.ToCPos()); } public void SetVisualPosition(Actor self, WPos pos) { SetPosition(self, pos.ToCPos()); } - public bool CanEnterCell(CPos cell) + public bool CanEnterCell(CPos cell, Actor ignoreActor, bool checkTransientActors) { if (!self.World.Map.IsInMap(cell.X, cell.Y)) return false; + var type = self.World.GetTerrainType(cell); if (!info.TerrainTypes.Contains(type)) return false; if (self.World.WorldActor.Trait().GetBuildingAt(cell) != null) return false; - if (self.World.ActorMap.GetUnitsAt(cell).Any()) return false; - return true; + if (!checkTransientActors) + return true; + + return !self.World.ActorMap.GetUnitsAt(cell) + .Where(x => x != ignoreActor) + .Any(); } + public bool CanEnterCell(CPos cell) { return CanEnterCell(cell, null, true); } + public void SetPosition(Actor self, CPos cell) { self.World.ActorMap.RemoveInfluence(self, this); diff --git a/OpenRA.Mods.RA/EjectOnDeath.cs b/OpenRA.Mods.RA/EjectOnDeath.cs index 328acf06b2..466597e774 100644 --- a/OpenRA.Mods.RA/EjectOnDeath.cs +++ b/OpenRA.Mods.RA/EjectOnDeath.cs @@ -8,7 +8,6 @@ */ #endregion -using System.Linq; using OpenRA.FileFormats; using OpenRA.Mods.RA.Effects; using OpenRA.Traits; @@ -29,15 +28,16 @@ namespace OpenRA.Mods.RA { public void Killed(Actor self, AttackInfo e) { - var cp = self.CenterPosition; - var info = self.Info.Traits.Get(); + if (self.Owner.WinState == WinState.Lost) + return; + var r = self.World.SharedRandom.Next(1, 100); + var info = self.Info.Traits.Get(); - if (r <= 100 - info.SuccessRate || self.Owner.WinState == WinState.Lost) + if (r <= 100 - info.SuccessRate) return; - if ((!info.EjectInAir && cp.Z > 0) || (!info.EjectOnGround && cp.Z == 0)) - return; + var cp = self.CenterPosition; var pilot = self.World.CreateActor(false, info.PilotActor.ToLowerInvariant(), new TypeDictionary { new OwnerInit(self.Owner), new LocationInit(self.Location) }); @@ -45,12 +45,12 @@ namespace OpenRA.Mods.RA if (IsSuitableCell(self, pilot, self.Location)) { - if (cp.Z > 0 && info.EjectInAir) + if (cp.Z > 0) { self.World.AddFrameEndTask(w => w.Add(new Parachute(pilot, cp))); Sound.Play(info.ChuteSound, cp); } - else if (cp.Z == 0 && info.EjectOnGround) + else self.World.AddFrameEndTask(w => w.Add(pilot)); } else diff --git a/OpenRA.Mods.RA/Husk.cs b/OpenRA.Mods.RA/Husk.cs index 7efd9e19e4..1edae2eb39 100644 --- a/OpenRA.Mods.RA/Husk.cs +++ b/OpenRA.Mods.RA/Husk.cs @@ -52,7 +52,7 @@ namespace OpenRA.Mods.RA } public IEnumerable> OccupiedCells() { yield return Pair.New(TopLeft, SubCell.FullCell); } - public bool CanEnterCell(CPos cell) + public bool CanEnterCell(CPos cell, Actor ignoreActor, bool checkTransientActors) { if (!self.World.Map.IsInMap(cell.X, cell.Y)) return false; @@ -60,9 +60,16 @@ namespace OpenRA.Mods.RA if (!info.AllowedTerrain.Contains(self.World.GetTerrainType(cell))) return false; - return !self.World.ActorMap.AnyUnitsAt(cell); + if (!checkTransientActors) + return true; + + return !self.World.ActorMap.GetUnitsAt(cell) + .Where(x => x != ignoreActor) + .Any(); } + public bool CanEnterCell(CPos cell) { return CanEnterCell(cell, null, true); } + public void SetPosition(Actor self, CPos cell) { SetPosition(self, cell.CenterPosition); } public void SetVisualPosition(Actor self, WPos pos) { diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index 99776134c4..c8eb7e9935 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -195,7 +195,7 @@ EjectOnDeath: PilotActor: E1 SuccessRate: 50 - EjectOnDeath: no + EjectOnGround: no EjectInAir: yes GivesBounty: GpsDot: