Improve Leap behavior:

* Configurable jump speed.
* Configurable jump angle.
* Configurable attack sound (uses weapon report).
* Don't accidentally eat tanks.
This commit is contained in:
Paul Chote
2013-07-08 22:10:05 +12:00
parent 4fbed810dc
commit 2cff2d8bbe
2 changed files with 39 additions and 22 deletions

View File

@@ -10,6 +10,7 @@
using System;
using System.Linq;
using OpenRA.GameRules;
using OpenRA.Mods.RA.Move;
using OpenRA.Mods.RA.Render;
using OpenRA.Traits;
@@ -19,47 +20,53 @@ namespace OpenRA.Mods.RA.Activities
class Leap : Activity
{
Mobile mobile;
WeaponInfo weapon;
PPos from;
PPos to;
WPos from;
WPos to;
int ticks;
int length;
WAngle angle;
int moveFraction;
const int length = 6;
public Leap(Actor self, Target target)
public Leap(Actor self, Actor target, WeaponInfo weapon, WRange speed, WAngle angle)
{
if (!target.IsActor)
throw new InvalidOperationException("Leap requires a target actor");
var targetMobile = target.Actor.TraitOrDefault<Mobile>();
var targetMobile = target.TraitOrDefault<Mobile>();
if (targetMobile == null)
throw new InvalidOperationException("Leap requires a target actor with the Mobile trait");
this.weapon = weapon;
this.angle = angle;
mobile = self.Trait<Mobile>();
mobile.SetLocation(mobile.fromCell, mobile.fromSubCell, targetMobile.fromCell, targetMobile.fromSubCell);
mobile.IsMoving = true;
from = self.CenterLocation;
to = Util.CenterOfCell(targetMobile.fromCell) + MobileInfo.SubCellOffsets[targetMobile.fromSubCell];
from = self.CenterPosition;
var offset = MobileInfo.SubCellOffsets[targetMobile.fromSubCell];
to = targetMobile.fromCell.CenterPosition + new WVec(offset.X * 1024 / Game.CellSize, offset.Y * 1024 / Game.CellSize, 0);
length = Math.Max((to - from).Length / speed.Range, 1);
self.Trait<RenderInfantry>().Attacking(self, target);
Sound.Play("dogg5p.aud", self.CenterLocation);
self.Trait<RenderInfantry>().Attacking(self, Target.FromActor(target));
if (weapon.Report != null && weapon.Report.Any())
Sound.Play(weapon.Report.Random(self.World.SharedRandom), self.CenterLocation);
}
public override Activity Tick(Actor self)
{
if (moveFraction == 0 && IsCanceled)
if (ticks == 0 && IsCanceled)
return NextActivity;
mobile.AdjustPxPosition(self, PPos.Lerp(from, to, moveFraction++, length - 1));
if (moveFraction >= length)
mobile.AdjustPxPosition(self, PPos.FromWPosHackZ(WPos.LerpQuadratic(from, to, angle, ++ticks, length)));
if (ticks >= length)
{
mobile.SetLocation(mobile.toCell, mobile.toSubCell, mobile.toCell, mobile.toSubCell);
mobile.FinishedMoving(self);
mobile.IsMoving = false;
// Kill whatever else is in our new cell
self.World.ActorMap.GetUnitsAt(mobile.toCell, mobile.toSubCell).Except(new []{self}).Do(a => a.Kill(self));
self.World.ActorMap.GetUnitsAt(mobile.toCell, mobile.toSubCell)
.Except(new []{self}).Where(t => weapon.IsValidAgainst(t))
.Do(t => t.Kill(self));
return NextActivity;
}

View File

@@ -10,6 +10,7 @@
using System;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Mods.RA.Activities;
using OpenRA.Traits;
@@ -17,17 +18,26 @@ namespace OpenRA.Mods.RA
{
class AttackLeapInfo : AttackFrontalInfo
{
[Desc("Leap speed (in units/tick).")]
public readonly WRange Speed = new WRange(426);
public readonly WAngle Angle = WAngle.FromDegrees(20);
public override object Create(ActorInitializer init) { return new AttackLeap(init.self, this); }
}
class AttackLeap : AttackFrontal, ISync
{
AttackLeapInfo info;
public AttackLeap(Actor self, AttackLeapInfo info)
: base(self, info) {}
: base(self, info)
{
this.info = info;
}
public override void DoAttack(Actor self, Target target)
{
if (!CanAttack(self, target))
if (!CanAttack(self, target) || !target.IsActor)
return;
var a = ChooseArmamentForTarget(target);
@@ -40,7 +50,7 @@ namespace OpenRA.Mods.RA
return;
self.CancelActivity();
self.QueueActivity(new Leap(self, target));
self.QueueActivity(new Leap(self, target.Actor, a.Weapon, info.Speed, info.Angle));
}
}
}