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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user