Convert weapons to world coords.

This commit is contained in:
Paul Chote
2013-12-24 23:10:05 +13:00
parent aca897fa76
commit ecdae4cbbe
13 changed files with 44 additions and 64 deletions

View File

@@ -18,8 +18,8 @@ namespace OpenRA.GameRules
{
public class WarheadInfo
{
[Desc("Distance (in pixels) from the explosion center at which damage is 1/2.")]
public readonly int Spread = 1;
[Desc("Distance from the explosion center at which damage is 1/2.")]
public readonly WRange Spread = new WRange(43);
[FieldLoader.LoadUsing("LoadVersus")]
[Desc("Damage vs each armortype. 0% = can't target.")]
public readonly Dictionary<string, float> Versus;
@@ -99,7 +99,7 @@ namespace OpenRA.GameRules
public class WeaponInfo
{
public readonly float Range = 0;
public readonly WRange Range = WRange.Zero;
public readonly string[] Report = null;
[Desc("Rate of Fire")]
public readonly int ROF = 1;
@@ -109,7 +109,7 @@ namespace OpenRA.GameRules
public readonly string[] ValidTargets = { "Ground", "Water" };
public readonly string[] InvalidTargets = { };
public readonly int BurstDelay = 5;
public readonly float MinRange = 0;
public readonly WRange MinRange = WRange.Zero;
[FieldLoader.LoadUsing("LoadProjectile")] public IProjectileInfo Projectile;
[FieldLoader.LoadUsing("LoadWarheads")] public List<WarheadInfo> Warheads;

View File

@@ -107,13 +107,10 @@ namespace OpenRA.Mods.RA
if (limitedAmmo != null && !limitedAmmo.HasAmmo())
return;
// TODO: Define weapon ranges as WRange
var range = new WRange((int)(1024*Weapon.Range));
var minRange = new WRange((int)(1024*Weapon.MinRange));
if (!target.IsInRange(self.CenterPosition, range))
if (!target.IsInRange(self.CenterPosition, Weapon.Range))
return;
if (minRange != WRange.Zero && target.IsInRange(self.CenterPosition, minRange))
if (Weapon.MinRange != WRange.Zero && target.IsInRange(self.CenterPosition, Weapon.MinRange))
return;
if (!Weapon.IsValidAgainst(target, self.World))

View File

@@ -144,7 +144,7 @@ namespace OpenRA.Mods.RA
public abstract Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove);
public bool HasAnyValidWeapons(Target t) { return Armaments.Any(a => a.Weapon.IsValidAgainst(t, self.World)); }
public WRange GetMaximumRange() { return new WRange((int)(1024 * Armaments.Max(a => a.Weapon.Range))); }
public WRange GetMaximumRange() { return Armaments.Max(a => a.Weapon.Range); }
public Armament ChooseArmamentForTarget(Target t) { return Armaments.FirstOrDefault(a => a.Weapon.IsValidAgainst(t, self.World)); }

View File

@@ -52,9 +52,7 @@ namespace OpenRA.Mods.RA
if (a == null)
return null;
// TODO: Define weapon ranges as WRange
var range = new WRange(Math.Max(0,(int)(1024*a.Weapon.Range)));
return new Activities.Attack(newTarget, range, allowMove);
return new Activities.Attack(newTarget, a.Weapon.Range, allowMove);
}
}
}

View File

@@ -42,9 +42,7 @@ namespace OpenRA.Mods.RA
if (a == null)
return;
// TODO: Define weapon ranges as WRange
var range = new WRange((int)(1024*a.Weapon.Range));
if (!target.IsInRange(self.CenterPosition, range))
if (!target.IsInRange(self.CenterPosition, a.Weapon.Range))
return;
self.CancelActivity();

View File

@@ -31,9 +31,7 @@ namespace OpenRA.Mods.RA
if (arm == null)
return;
// TODO: Define weapon ranges as WRange
var range = new WRange((int)(1024*arm.Weapon.Range));
if (!target.IsInRange(self.CenterPosition, range))
if (!target.IsInRange(self.CenterPosition, arm.Weapon.Range))
return;
var facing = self.TraitOrDefault<IFacing>();

View File

@@ -33,9 +33,7 @@ namespace OpenRA.Mods.RA
if (a == null)
return null;
// TODO: Define weapon ranges as WRange
var range = new WRange(Math.Max(0, (int)(1024 * a.Weapon.Range)));
return new Activities.Heal(newTarget, range, allowMove);
return new Activities.Heal(newTarget, a.Weapon.Range, allowMove);
}
}
}

View File

@@ -96,7 +96,7 @@ namespace OpenRA.Mods.RA
if (weapon != null)
{
var range = WRange.FromCells(Math.Max(0, (int)weapon.Weapon.Range - RangeTolerance));
var range = WRange.FromCells(Math.Max(0, weapon.Weapon.Range.Range / 1024 - RangeTolerance));
attack.Target = target;
if (allowMove && self.HasTrait<Mobile>() && !self.Info.Traits.Get<MobileInfo>().OnRails)

View File

@@ -49,8 +49,7 @@ namespace OpenRA.Mods.RA
// Bombs drop anywhere in range
foreach (var a in Armaments.Where(a => a.Info.Name == info.Bombs))
{
var range = new WRange((int)(1024 * a.Weapon.Range));
if (!target.IsInRange(self.CenterPosition, range))
if (!target.IsInRange(self.CenterPosition, a.Weapon.Range))
continue;
a.CheckFire(self, this, facing, bombTarget);
@@ -63,11 +62,10 @@ namespace OpenRA.Mods.RA
foreach (var a in Armaments.Where(a => a.Info.Name == info.Guns))
{
var range = new WRange((int)(1024 * a.Weapon.Range));
if (!target.IsInRange(self.CenterPosition, range))
if (!target.IsInRange(self.CenterPosition, a.Weapon.Range))
continue;
var t = Target.FromPos(cp - new WVec(0, range.Range / 2, cp.Z).Rotate(WRot.FromFacing(facing.Facing)));
var t = Target.FromPos(cp - new WVec(0, a.Weapon.Range.Range / 2, cp.Z).Rotate(WRot.FromFacing(facing.Facing)));
a.CheckFire(self, this, facing, t);
}
}

View File

@@ -101,9 +101,8 @@ namespace OpenRA.Mods.RA
{
case DamageModel.Normal:
{
var maxSpread = warhead.Spread * (float)Math.Log(Math.Abs(warhead.Damage), 2);
var range = new WRange((int)maxSpread * 1024 / Game.CellSize);
var hitActors = world.FindActorsInCircle(pos, range);
var maxSpread = new WRange((int)(warhead.Spread.Range * (float)Math.Log(Math.Abs(warhead.Damage), 2)));
var hitActors = world.FindActorsInCircle(pos, maxSpread);
foreach (var victim in hitActors)
{
@@ -192,8 +191,8 @@ namespace OpenRA.Mods.RA
var rawDamage = (float)warhead.Damage;
if (withFalloff)
{
var distance = Math.Max(0, (target.CenterPosition - pos).Length - healthInfo.Radius.Range) * Game.CellSize / 1024;
var falloff = (float)GetDamageFalloff(distance / warhead.Spread);
var distance = Math.Max(0, (target.CenterPosition - pos).Length - healthInfo.Radius.Range);
var falloff = (float)GetDamageFalloff(distance * 1f / warhead.Spread.Range);
rawDamage = (float)(falloff * rawDamage);
}
return (float)(rawDamage * modifier * (float)warhead.EffectivenessAgainst(target.Info));

View File

@@ -22,15 +22,16 @@ namespace OpenRA.Mods.RA.Effects
{
public class BulletInfo : IProjectileInfo
{
public readonly int Speed = 1;
[Desc("Projectile speed in WRange / tick")]
public readonly WRange Speed = new WRange(17);
public readonly string Trail = null;
[Desc("Pixels at maximum range")]
public readonly float Inaccuracy = 0;
[Desc("Maximum offset at the maximum range")]
public readonly WRange Inaccuracy = WRange.Zero;
public readonly string Image = null;
[Desc("Check for whether an actor with Wall: trait blocks fire")]
public readonly bool High = false;
public readonly bool Shadow = false;
public readonly float Angle = 0;
public readonly WAngle Angle = WAngle.Zero;
public readonly int TrailInterval = 2;
public readonly int TrailDelay = 1;
public readonly int ContrailLength = 0;
@@ -49,7 +50,6 @@ namespace OpenRA.Mods.RA.Effects
ContrailRenderable trail;
Animation anim;
[Sync] WAngle angle;
[Sync] WPos pos, target;
[Sync] int length;
[Sync] int facing;
@@ -63,22 +63,15 @@ namespace OpenRA.Mods.RA.Effects
this.args = args;
this.pos = args.Source;
// Convert ProjectileArg definitions to world coordinates
// TODO: Change the yaml definitions so we don't need this
var range = new WRange((int)(1024 * args.Weapon.Range)); // Range in world units
var inaccuracy = new WRange((int)(info.Inaccuracy * 1024 / Game.CellSize)); // Offset in world units at max range
var speed = (int)(info.Speed * 4 * 1024 / (10 * Game.CellSize)); // Speed in world units per tick
angle = WAngle.ArcTan((int)(info.Angle * 4 * 1024), 1024); // Angle in world angle
target = args.PassiveTarget;
if (info.Inaccuracy > 0)
if (info.Inaccuracy.Range > 0)
{
var maxOffset = inaccuracy.Range * (target - pos).Length / range.Range;
var maxOffset = info.Inaccuracy.Range * (target - pos).Length / args.Weapon.Range.Range;
target += WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxOffset / 1024;
}
facing = Traits.Util.GetFacing(target - pos, 0);
length = Math.Max((target - pos).Length / speed, 1);
length = Math.Max((target - pos).Length / info.Speed.Range, 1);
if (info.Image != null)
{
@@ -98,7 +91,7 @@ namespace OpenRA.Mods.RA.Effects
int GetEffectiveFacing()
{
var at = (float)ticks / (length - 1);
var attitude = angle.Tan() * (1 - 2 * at) / (4 * 1024);
var attitude = info.Angle.Tan() * (1 - 2 * at) / (4 * 1024);
var u = (facing % 128) / 128f;
var scale = 512 * u * (1 - u);
@@ -113,11 +106,11 @@ namespace OpenRA.Mods.RA.Effects
if (anim != null)
anim.Tick();
pos = WPos.LerpQuadratic(args.Source, target, angle, ticks, length);
pos = WPos.LerpQuadratic(args.Source, target, info.Angle, ticks, length);
if (info.Trail != null && --smokeTicks < 0)
{
var delayedPos = WPos.LerpQuadratic(args.Source, target, angle, ticks - info.TrailDelay, length);
var delayedPos = WPos.LerpQuadratic(args.Source, target, info.Angle, ticks - info.TrailDelay, length);
world.AddFrameEndTask(w => w.Add(new Smoke(w, delayedPos, info.Trail)));
smokeTicks = info.TrailInterval;
}

View File

@@ -21,13 +21,15 @@ namespace OpenRA.Mods.RA.Effects
{
class MissileInfo : IProjectileInfo
{
public readonly int Speed = 1;
[Desc("Projectile speed in WRange / tick")]
public readonly WRange Speed = new WRange(8);
public readonly WAngle MaximumPitch = WAngle.FromDegrees(30);
public readonly int Arm = 0;
[Desc("Check for whether an actor with Wall: trait blocks fire")]
public readonly bool High = false;
public readonly string Trail = null;
public readonly float Inaccuracy = 0;
[Desc("Maximum offset at the maximum range")]
public readonly WRange Inaccuracy = WRange.Zero;
public readonly string Image = null;
[Desc("Rate of Turning")]
public readonly int ROT = 5;
@@ -46,12 +48,15 @@ namespace OpenRA.Mods.RA.Effects
class Missile : IEffect, ISync
{
// HACK: the missile movement code isn't smart enough to explode
// when the projectile passes the actor. This defines an arbitrary
// proximity radius that they will explode within, which makes
// missiles difficult to consistently balance.
static readonly WRange MissileCloseEnough = new WRange(298);
readonly MissileInfo info;
readonly ProjectileArgs args;
readonly Animation anim;
readonly int speed;
int ticksToNextSmoke;
ContrailRenderable trail;
@@ -76,13 +81,8 @@ namespace OpenRA.Mods.RA.Effects
targetPosition = args.PassiveTarget;
// Convert ProjectileArg definitions to world coordinates
// TODO: Change the yaml definitions so we don't need this
var inaccuracy = (int)(info.Inaccuracy * 1024 / Game.CellSize);
speed = info.Speed * 1024 / (5 * Game.CellSize);
if (info.Inaccuracy > 0)
offset = WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * inaccuracy / 1024;
if (info.Inaccuracy.Range > 0)
offset = WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * info.Inaccuracy.Range / 1024;
if (info.Image != null)
{
@@ -131,7 +131,7 @@ namespace OpenRA.Mods.RA.Effects
desiredFacing = facing;
facing = Traits.Util.TickFacing(facing, desiredFacing, info.ROT);
var move = new WVec(0, -1024, 0).Rotate(WRot.FromFacing(facing)) * speed / 1024;
var move = new WVec(0, -1024, 0).Rotate(WRot.FromFacing(facing)) * info.Speed.Range / 1024;
if (targetPosition.Z > 0 && info.TurboBoost)
move = (move * 3) / 2;

View File

@@ -27,11 +27,12 @@ namespace OpenRA.Mods.RA
public void Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition)
{
var range = ai.Traits.WithInterface<ArmamentInfo>()
.Select(a => Rules.Weapons[a.Weapon.ToLowerInvariant()].Range).Max();
.Select(a => Rules.Weapons[a.Weapon.ToLowerInvariant()].Range)
.Max();
wr.DrawRangeCircleWithContrast(
centerPosition,
new WRange((int)(1024 * range)),
range,
Color.FromArgb(128, Color.Yellow),
Color.FromArgb(96, Color.Black)
);