Merge pull request #10243 from pchote/fix-neutrino-bullets
Fix collision detection for Missiles and Bullets.
This commit is contained in:
@@ -54,7 +54,7 @@ namespace OpenRA.Mods.Common.Effects
|
|||||||
public readonly bool Blockable = false;
|
public readonly bool Blockable = false;
|
||||||
|
|
||||||
[Desc("Extra search radius beyond beam width. Required to ensure affecting actors with large health radius.")]
|
[Desc("Extra search radius beyond beam width. Required to ensure affecting actors with large health radius.")]
|
||||||
public readonly WDist TargetExtraSearchRadius = new WDist(2048);
|
public readonly WDist TargetExtraSearchRadius = new WDist(1536);
|
||||||
|
|
||||||
[Desc("Should the beam be visuall rendered? False = Beam is invisible.")]
|
[Desc("Should the beam be visuall rendered? False = Beam is invisible.")]
|
||||||
public readonly bool RenderBeam = true;
|
public readonly bool RenderBeam = true;
|
||||||
|
|||||||
@@ -50,6 +50,12 @@ namespace OpenRA.Mods.Common.Effects
|
|||||||
[Desc("Is this blocked by actors with BlocksProjectiles trait.")]
|
[Desc("Is this blocked by actors with BlocksProjectiles trait.")]
|
||||||
public readonly bool Blockable = true;
|
public readonly bool Blockable = true;
|
||||||
|
|
||||||
|
[Desc("Width of projectile (used for finding blocking actors).")]
|
||||||
|
public readonly WDist Width = new WDist(1);
|
||||||
|
|
||||||
|
[Desc("Extra search radius beyond path for blocking actors.")]
|
||||||
|
public readonly WDist TargetExtraSearchRadius = new WDist(1536);
|
||||||
|
|
||||||
[Desc("Arc in WAngles, two values indicate variable arc.")]
|
[Desc("Arc in WAngles, two values indicate variable arc.")]
|
||||||
public readonly WAngle[] Angle = { WAngle.Zero };
|
public readonly WAngle[] Angle = { WAngle.Zero };
|
||||||
|
|
||||||
@@ -156,8 +162,19 @@ namespace OpenRA.Mods.Common.Effects
|
|||||||
if (anim != null)
|
if (anim != null)
|
||||||
anim.Tick();
|
anim.Tick();
|
||||||
|
|
||||||
|
var lastPos = pos;
|
||||||
pos = WPos.LerpQuadratic(args.Source, target, angle, ticks, length);
|
pos = WPos.LerpQuadratic(args.Source, target, angle, ticks, length);
|
||||||
|
|
||||||
|
// Check for walls or other blocking obstacles
|
||||||
|
var shouldExplode = false;
|
||||||
|
WPos blockedPos;
|
||||||
|
if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, lastPos, pos, info.Width,
|
||||||
|
info.TargetExtraSearchRadius, out blockedPos))
|
||||||
|
{
|
||||||
|
pos = blockedPos;
|
||||||
|
shouldExplode = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(info.Trail) && --smokeTicks < 0)
|
if (!string.IsNullOrEmpty(info.Trail) && --smokeTicks < 0)
|
||||||
{
|
{
|
||||||
var delayedPos = WPos.LerpQuadratic(args.Source, target, angle, ticks - info.TrailDelay, length);
|
var delayedPos = WPos.LerpQuadratic(args.Source, target, angle, ticks - info.TrailDelay, length);
|
||||||
@@ -168,8 +185,8 @@ namespace OpenRA.Mods.Common.Effects
|
|||||||
if (info.ContrailLength > 0)
|
if (info.ContrailLength > 0)
|
||||||
contrail.Update(pos);
|
contrail.Update(pos);
|
||||||
|
|
||||||
var shouldExplode = ticks++ >= length // Flight length reached/exceeded
|
// Flight length reached / exceeded
|
||||||
|| (info.Blockable && BlocksProjectiles.AnyBlockingActorAt(world, pos)); // Hit a wall or other blocking obstacle
|
shouldExplode |= ticks++ >= length;
|
||||||
|
|
||||||
if (shouldExplode)
|
if (shouldExplode)
|
||||||
Explode(world);
|
Explode(world);
|
||||||
|
|||||||
@@ -58,6 +58,12 @@ namespace OpenRA.Mods.Common.Effects
|
|||||||
[Desc("Is the missile blocked by actors with BlocksProjectiles: trait.")]
|
[Desc("Is the missile blocked by actors with BlocksProjectiles: trait.")]
|
||||||
public readonly bool Blockable = true;
|
public readonly bool Blockable = true;
|
||||||
|
|
||||||
|
[Desc("Width of projectile (used for finding blocking actors).")]
|
||||||
|
public readonly WDist Width = new WDist(1);
|
||||||
|
|
||||||
|
[Desc("Extra search radius beyond path for blocking actors.")]
|
||||||
|
public readonly WDist TargetExtraSearchRadius = new WDist(1536);
|
||||||
|
|
||||||
[Desc("Maximum offset at the maximum range")]
|
[Desc("Maximum offset at the maximum range")]
|
||||||
public readonly WDist Inaccuracy = WDist.Zero;
|
public readonly WDist Inaccuracy = WDist.Zero;
|
||||||
|
|
||||||
@@ -773,8 +779,19 @@ namespace OpenRA.Mods.Common.Effects
|
|||||||
renderFacing = WAngle.ArcTan(move.Z - move.Y, move.X).Angle / 4 - 64;
|
renderFacing = WAngle.ArcTan(move.Z - move.Y, move.X).Angle / 4 - 64;
|
||||||
|
|
||||||
// Move the missile
|
// Move the missile
|
||||||
|
var lastPos = pos;
|
||||||
pos += move;
|
pos += move;
|
||||||
|
|
||||||
|
// Check for walls or other blocking obstacles
|
||||||
|
var shouldExplode = false;
|
||||||
|
WPos blockedPos;
|
||||||
|
if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, lastPos, pos, info.Width,
|
||||||
|
info.TargetExtraSearchRadius, out blockedPos))
|
||||||
|
{
|
||||||
|
pos = blockedPos;
|
||||||
|
shouldExplode = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Create the smoke trail effect
|
// Create the smoke trail effect
|
||||||
if (!string.IsNullOrEmpty(info.TrailImage) && --ticksToNextSmoke < 0 && (state != States.Freefall || info.TrailWhenDeactivated))
|
if (!string.IsNullOrEmpty(info.TrailImage) && --ticksToNextSmoke < 0 && (state != States.Freefall || info.TrailWhenDeactivated))
|
||||||
{
|
{
|
||||||
@@ -786,14 +803,10 @@ namespace OpenRA.Mods.Common.Effects
|
|||||||
contrail.Update(pos);
|
contrail.Update(pos);
|
||||||
|
|
||||||
var cell = world.Map.CellContaining(pos);
|
var cell = world.Map.CellContaining(pos);
|
||||||
|
|
||||||
// NOTE: High speeds might cause the missile to miss the target or fly through obstacles
|
|
||||||
// In that case, big moves should probably be decomposed into multiple smaller ones with hit checks
|
|
||||||
var height = world.Map.DistanceAboveTerrain(pos);
|
var height = world.Map.DistanceAboveTerrain(pos);
|
||||||
var shouldExplode = (height.Length < 0) // Hit the ground
|
shouldExplode |= height.Length < 0 // Hit the ground
|
||||||
|| (relTarDist < info.CloseEnough.Length) // Within range
|
|| relTarDist < info.CloseEnough.Length // Within range
|
||||||
|| (info.ExplodeWhenEmpty && info.RangeLimit != 0 && ticks > info.RangeLimit) // Ran out of fuel
|
|| (info.ExplodeWhenEmpty && info.RangeLimit != 0 && ticks > info.RangeLimit) // Ran out of fuel
|
||||||
|| (info.Blockable && BlocksProjectiles.AnyBlockingActorAt(world, pos)) // Hit a wall or other blocking obstacle
|
|
||||||
|| !world.Map.Contains(cell) // This also avoids an IndexOutOfRangeException in GetTerrainInfo below.
|
|| !world.Map.Contains(cell) // This also avoids an IndexOutOfRangeException in GetTerrainInfo below.
|
||||||
|| (!string.IsNullOrEmpty(info.BoundToTerrainType) && world.Map.GetTerrainInfo(cell).Type != info.BoundToTerrainType) // Hit incompatible terrain
|
|| (!string.IsNullOrEmpty(info.BoundToTerrainType) && world.Map.GetTerrainInfo(cell).Type != info.BoundToTerrainType) // Hit incompatible terrain
|
||||||
|| (height.Length < info.AirburstAltitude.Length && relTarHorDist < info.CloseEnough.Length); // Airburst
|
|| (height.Length < info.AirburstAltitude.Length && relTarHorDist < info.CloseEnough.Length); // Airburst
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using OpenRA.GameRules;
|
||||||
|
using OpenRA.Mods.Common.Effects;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Mods.Common.Warheads;
|
using OpenRA.Mods.Common.Warheads;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
@@ -48,6 +50,21 @@ namespace OpenRA.Mods.Common.Lint
|
|||||||
emitError("Actor type `{0}` has a health radius exceeding the victim scan radius of a warhead on `{1}`!"
|
emitError("Actor type `{0}` has a health radius exceeding the victim scan radius of a warhead on `{1}`!"
|
||||||
.F(actorInfo.Key, weaponInfo.Key));
|
.F(actorInfo.Key, weaponInfo.Key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var bullet = weaponInfo.Value.Projectile as BulletInfo;
|
||||||
|
var missile = weaponInfo.Value.Projectile as MissileInfo;
|
||||||
|
var areabeam = weaponInfo.Value.Projectile as AreaBeamInfo;
|
||||||
|
|
||||||
|
if (bullet == null && missile == null && areabeam == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var targetExtraSearchRadius = bullet != null ? bullet.TargetExtraSearchRadius :
|
||||||
|
missile != null ? missile.TargetExtraSearchRadius :
|
||||||
|
areabeam != null ? areabeam.TargetExtraSearchRadius : WDist.Zero;
|
||||||
|
|
||||||
|
if (healthTraits.Where(x => x.Shape.OuterRadius.Length > targetExtraSearchRadius.Length).Any())
|
||||||
|
emitError("Actor type `{0}` has a health radius exceeding the victim scan radius of the projectile on `{1}`!"
|
||||||
|
.F(actorInfo.Key, weaponInfo.Key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -276,8 +276,6 @@ ARCO.Husk:
|
|||||||
|
|
||||||
BARB:
|
BARB:
|
||||||
Inherits: ^Wall
|
Inherits: ^Wall
|
||||||
Health:
|
|
||||||
HP: 100
|
|
||||||
Armor:
|
Armor:
|
||||||
Type: Light
|
Type: Light
|
||||||
Tooltip:
|
Tooltip:
|
||||||
@@ -292,8 +290,6 @@ BARB:
|
|||||||
|
|
||||||
WOOD:
|
WOOD:
|
||||||
Inherits: ^Wall
|
Inherits: ^Wall
|
||||||
Health:
|
|
||||||
HP: 100
|
|
||||||
Armor:
|
Armor:
|
||||||
Type: Wood
|
Type: Wood
|
||||||
Tooltip:
|
Tooltip:
|
||||||
|
|||||||
@@ -579,6 +579,11 @@
|
|||||||
Guardable:
|
Guardable:
|
||||||
FrozenUnderFog:
|
FrozenUnderFog:
|
||||||
ScriptTriggers:
|
ScriptTriggers:
|
||||||
|
Health:
|
||||||
|
HP: 100
|
||||||
|
Shape: Rectangle
|
||||||
|
TopLeft: -512, -512
|
||||||
|
BottomRight: 512, 512
|
||||||
|
|
||||||
^Tree:
|
^Tree:
|
||||||
Inherits@1: ^SpriteActor
|
Inherits@1: ^SpriteActor
|
||||||
|
|||||||
@@ -855,8 +855,6 @@ SBAG:
|
|||||||
BuildPaletteOrder: 20
|
BuildPaletteOrder: 20
|
||||||
Prerequisites: fact
|
Prerequisites: fact
|
||||||
Queue: Defence.GDI
|
Queue: Defence.GDI
|
||||||
Health:
|
|
||||||
HP: 100
|
|
||||||
Armor:
|
Armor:
|
||||||
Type: Light
|
Type: Light
|
||||||
LineBuild:
|
LineBuild:
|
||||||
@@ -880,8 +878,6 @@ CYCL:
|
|||||||
BuildPaletteOrder: 20
|
BuildPaletteOrder: 20
|
||||||
Prerequisites: fact
|
Prerequisites: fact
|
||||||
Queue: Defence.Nod
|
Queue: Defence.Nod
|
||||||
Health:
|
|
||||||
HP: 100
|
|
||||||
Armor:
|
Armor:
|
||||||
Type: Light
|
Type: Light
|
||||||
LineBuild:
|
LineBuild:
|
||||||
|
|||||||
@@ -613,6 +613,9 @@ wall:
|
|||||||
TerrainTypes: Rock, Concrete
|
TerrainTypes: Rock, Concrete
|
||||||
Health:
|
Health:
|
||||||
HP: 2000
|
HP: 2000
|
||||||
|
Shape: Rectangle
|
||||||
|
TopLeft: -512, -512
|
||||||
|
BottomRight: 512, 512
|
||||||
Armor:
|
Armor:
|
||||||
Type: none
|
Type: none
|
||||||
RevealsShroud:
|
RevealsShroud:
|
||||||
|
|||||||
@@ -501,6 +501,11 @@
|
|||||||
Guardable:
|
Guardable:
|
||||||
FrozenUnderFog:
|
FrozenUnderFog:
|
||||||
GpsRemoveFrozenActor:
|
GpsRemoveFrozenActor:
|
||||||
|
Health:
|
||||||
|
HP: 100
|
||||||
|
Shape: Rectangle
|
||||||
|
TopLeft: -512, -512
|
||||||
|
BottomRight: 512, 512
|
||||||
|
|
||||||
^TechBuilding:
|
^TechBuilding:
|
||||||
Inherits: ^BasicBuilding
|
Inherits: ^BasicBuilding
|
||||||
|
|||||||
@@ -1664,8 +1664,6 @@ CYCL:
|
|||||||
Inherits: ^Wall
|
Inherits: ^Wall
|
||||||
Tooltip:
|
Tooltip:
|
||||||
Name: Chain-Link Barrier
|
Name: Chain-Link Barrier
|
||||||
Health:
|
|
||||||
HP: 100
|
|
||||||
Armor:
|
Armor:
|
||||||
Type: Wood
|
Type: Wood
|
||||||
LineBuild:
|
LineBuild:
|
||||||
@@ -1679,8 +1677,6 @@ BARB:
|
|||||||
Inherits: ^Wall
|
Inherits: ^Wall
|
||||||
Tooltip:
|
Tooltip:
|
||||||
Name: Barbed-Wire Fence
|
Name: Barbed-Wire Fence
|
||||||
Health:
|
|
||||||
HP: 100
|
|
||||||
Armor:
|
Armor:
|
||||||
Type: Wood
|
Type: Wood
|
||||||
LineBuild:
|
LineBuild:
|
||||||
@@ -1694,8 +1690,6 @@ WOOD:
|
|||||||
Inherits: ^Wall
|
Inherits: ^Wall
|
||||||
Tooltip:
|
Tooltip:
|
||||||
Name: Wooden Fence
|
Name: Wooden Fence
|
||||||
Health:
|
|
||||||
HP: 100
|
|
||||||
Armor:
|
Armor:
|
||||||
Type: Wood
|
Type: Wood
|
||||||
LineBuild:
|
LineBuild:
|
||||||
|
|||||||
@@ -216,6 +216,9 @@
|
|||||||
InitialDelay: 0
|
InitialDelay: 0
|
||||||
CloakDelay: 90
|
CloakDelay: 90
|
||||||
IsPlayerPalette: true
|
IsPlayerPalette: true
|
||||||
|
Health:
|
||||||
|
Shape: Circle
|
||||||
|
Radius: 363
|
||||||
|
|
||||||
^BuildingPlug:
|
^BuildingPlug:
|
||||||
AlwaysVisible:
|
AlwaysVisible:
|
||||||
|
|||||||
Reference in New Issue
Block a user