diff --git a/OpenRA.Mods.Common/Traits/EjectOnDeath.cs b/OpenRA.Mods.Common/Traits/EjectOnDeath.cs index 1ca8286e02..648eab6524 100644 --- a/OpenRA.Mods.Common/Traits/EjectOnDeath.cs +++ b/OpenRA.Mods.Common/Traits/EjectOnDeath.cs @@ -50,9 +50,7 @@ namespace OpenRA.Mods.Common.Traits if (IsTraitDisabled || self.Owner.WinState == WinState.Lost || !self.World.Map.Contains(self.Location)) return; - var r = self.World.SharedRandom.Next(1, 100); - - if (r <= 100 - Info.SuccessRate) + if (self.World.SharedRandom.Next(100) >= Info.SuccessRate) return; var cp = self.CenterPosition; @@ -60,48 +58,47 @@ namespace OpenRA.Mods.Common.Traits if ((inAir && !Info.EjectInAir) || (!inAir && !Info.EjectOnGround)) return; - var pilot = self.World.CreateActor(false, Info.PilotActor.ToLowerInvariant(), - new TypeDictionary { new OwnerInit(self.Owner), new LocationInit(self.Location) }); - - var pilotPositionable = pilot.TraitOrDefault(); - var pilotCell = self.Location; - var pilotSubCell = pilotPositionable.GetAvailableSubCell(pilotCell); - if (pilotSubCell == SubCell.Invalid) + if (!Info.AllowUnsuitableCell) { - if (!Info.AllowUnsuitableCell) - { - pilot.Dispose(); + var pilotInfo = self.World.Map.Rules.Actors[Info.PilotActor.ToLowerInvariant()]; + var pilotPositionable = pilotInfo.TraitInfo(); + if (!pilotPositionable.CanEnterCell(self.World, null, self.Location)) return; - } - - pilotSubCell = SubCell.Any; } + var td = new TypeDictionary + { + new OwnerInit(self.Owner), + new LocationInit(self.Location), + }; + + // If airborne, offset the spawn location so the pilot doesn't drop on another infantry's head + var spawnPos = cp; if (inAir) { - self.World.AddFrameEndTask(w => + var subCell = self.World.ActorMap.FreeSubCell(self.Location); + if (subCell != SubCell.Invalid) { - pilotPositionable.SetPosition(pilot, pilotCell, pilotSubCell); - var dropPosition = pilot.CenterPosition + new WVec(0, 0, self.CenterPosition.Z - pilot.CenterPosition.Z); - pilotPositionable.SetVisualPosition(pilot, dropPosition); - - w.Add(pilot); - }); - - Game.Sound.Play(SoundType.World, Info.ChuteSound, cp); + td.Add(new SubCellInit(subCell)); + spawnPos = self.World.Map.CenterOfSubCell(self.Location, subCell) + new WVec(0, 0, spawnPos.Z); + } } - else + + td.Add(new CenterPositionInit(spawnPos)); + + var pilot = self.World.CreateActor(true, Info.PilotActor.ToLowerInvariant(), td); + + if (!inAir) { self.World.AddFrameEndTask(w => { - w.Add(pilot); - pilotPositionable.SetPosition(pilot, pilotCell, pilotSubCell); - var pilotMobile = pilot.TraitOrDefault(); if (pilotMobile != null) pilotMobile.Nudge(pilot); }); } + else + Game.Sound.Play(SoundType.World, Info.ChuteSound, cp); } } }