Add WAngle-compatible airstrike/paratrooper APIs.

This commit is contained in:
Paul Chote
2020-06-10 21:05:12 +01:00
committed by reaperrr
parent a98e460257
commit 27602a4a97
4 changed files with 68 additions and 30 deletions

View File

@@ -27,19 +27,27 @@ namespace OpenRA.Mods.Common.Scripting
ap = self.TraitsImplementing<AirstrikePower>().First();
}
[Desc("Activate the actor's Airstrike Power.")]
public void SendAirstrike(WPos target, bool randomize = true, int facing = 0)
[Desc("Activate the actor's Airstrike Power. Returns the aircraft that will attack.")]
public Actor[] TargetAirstrike(WPos target, WAngle? facing = null)
{
ap.SendAirstrike(Self, target, randomize, facing);
return ap.SendAirstrike(Self, target, facing);
}
[Desc("Activate the actor's Airstrike Power.")]
[Desc("Activate the actor's Airstrike Power. DEPRECATED! Will be removed.")]
public void SendAirstrike(WPos target, bool randomize = true, int facing = 0)
{
Game.Debug("SendAirstrike is deprecated. Use TargetAirstrike instead.");
ap.SendAirstrike(Self, target, randomize ? (WAngle?)null : WAngle.FromFacing(facing));
}
[Desc("Activate the actor's Airstrike Power. DEPRECATED! Will be removed.")]
public void SendAirstrikeFrom(CPos from, CPos to)
{
Game.Debug("SendAirstrikeFrom is deprecated. Use TargetAirstrike instead.");
var i = Self.World.Map.CenterOfCell(from);
var j = Self.World.Map.CenterOfCell(to);
ap.SendAirstrike(Self, j, false, (i - j).Yaw.Facing);
ap.SendAirstrike(Self, j, (i - j).Yaw);
}
}
}

View File

@@ -28,10 +28,18 @@ namespace OpenRA.Mods.Common.Scripting
}
[Desc("Activate the actor's Paratroopers Power. Returns the aircraft that will drop the reinforcements.")]
public Actor[] ActivateParatroopers(WPos target, int facing = -1)
public Actor[] TargetParatroopers(WPos target, WAngle? facing = null)
{
var actors = pp.SendParatroopers(Self, target, facing);
return actors.First;
}
[Desc("Activate the actor's Paratroopers Power. Returns the aircraft that will drop the reinforcements. DEPRECATED! Will be removed.")]
public Actor[] ActivateParatroopers(WPos target, int facing = -1)
{
Game.Debug("SendParatroopersFrom is deprecated. Use TargetParatroopers instead.");
var actors = pp.SendParatroopers(Self, target, facing == -1 ? (WAngle?)null : WAngle.FromFacing(facing));
return actors.First;
}
}
}

View File

@@ -78,16 +78,19 @@ namespace OpenRA.Mods.Common.Traits
public override void Activate(Actor self, Order order, SupportPowerManager manager)
{
base.Activate(self, order, manager);
SendAirstrike(self, order.Target.CenterPosition, !info.UseDirectionalTarget || order.ExtraData == uint.MaxValue, (int)order.ExtraData);
var facing = info.UseDirectionalTarget && order.ExtraData != uint.MaxValue ? (WAngle?)WAngle.FromFacing((int)order.ExtraData) : null;
SendAirstrike(self, order.Target.CenterPosition, facing);
}
public void SendAirstrike(Actor self, WPos target, bool randomize = true, int attackFacing = 0)
public Actor[] SendAirstrike(Actor self, WPos target, WAngle? facing = null)
{
if (randomize)
attackFacing = 256 * self.World.SharedRandom.Next(info.QuantizedFacings) / info.QuantizedFacings;
var aircraft = new List<Actor>();
if (!facing.HasValue)
facing = WAngle.FromFacing(256 * self.World.SharedRandom.Next(info.QuantizedFacings) / info.QuantizedFacings);
var altitude = self.World.Map.Rules.Actors[info.UnitType].TraitInfo<AircraftInfo>().CruiseAltitude.Length;
var attackRotation = WRot.FromFacing(attackFacing);
var attackRotation = WRot.FromYaw(facing.Value);
var delta = new WVec(0, -1024, 0).Rotate(attackRotation);
target = target + new WVec(0, 0, altitude);
var startEdge = target - (self.World.Map.DistanceToEdge(target, -delta) + info.Cordon).Length * delta / 1024;
@@ -140,10 +143,38 @@ namespace OpenRA.Mods.Common.Traits
}
};
// Create the actors immediately so they can be returned
for (var i = -info.SquadSize / 2; i <= info.SquadSize / 2; i++)
{
// Even-sized squads skip the lead plane
if (i == 0 && (info.SquadSize & 1) == 0)
continue;
// Includes the 90 degree rotation between body and world coordinates
var so = info.SquadOffset;
var spawnOffset = new WVec(i * so.Y, -Math.Abs(i) * so.X, 0).Rotate(attackRotation);
var targetOffset = new WVec(i * so.Y, 0, 0).Rotate(attackRotation);
var a = self.World.CreateActor(false, info.UnitType, new TypeDictionary
{
new CenterPositionInit(startEdge + spawnOffset),
new OwnerInit(self.Owner),
new FacingInit(facing.Value.Facing),
});
aircraft.Add(a);
var attack = a.Trait<AttackBomber>();
attack.SetTarget(self.World, target + targetOffset);
attack.OnEnteredAttackRange += onEnterRange;
attack.OnExitedAttackRange += onExitRange;
attack.OnRemovedFromWorld += onRemovedFromWorld;
}
self.World.AddFrameEndTask(w =>
{
PlayLaunchSounds();
var j = 0;
Actor distanceTestActor = null;
for (var i = -info.SquadSize / 2; i <= info.SquadSize / 2; i++)
{
@@ -154,20 +185,9 @@ namespace OpenRA.Mods.Common.Traits
// Includes the 90 degree rotation between body and world coordinates
var so = info.SquadOffset;
var spawnOffset = new WVec(i * so.Y, -Math.Abs(i) * so.X, 0).Rotate(attackRotation);
var targetOffset = new WVec(i * so.Y, 0, 0).Rotate(attackRotation);
var a = w.CreateActor(info.UnitType, new TypeDictionary
{
new CenterPositionInit(startEdge + spawnOffset),
new OwnerInit(self.Owner),
new FacingInit(attackFacing),
});
var attack = a.Trait<AttackBomber>();
attack.SetTarget(w, target + targetOffset);
attack.OnEnteredAttackRange += onEnterRange;
attack.OnExitedAttackRange += onExitRange;
attack.OnRemovedFromWorld += onRemovedFromWorld;
var a = aircraft[j++];
w.Add(a);
a.QueueActivity(new Fly(a, Target.FromPos(target + spawnOffset)));
a.QueueActivity(new Fly(a, Target.FromPos(finishEdge + spawnOffset)));
@@ -198,6 +218,8 @@ namespace OpenRA.Mods.Common.Traits
w.Add(beacon);
}
});
return aircraft.ToArray();
}
void RemoveCamera(Actor camera)

View File

@@ -93,19 +93,19 @@ namespace OpenRA.Mods.Common.Traits
{
base.Activate(self, order, manager);
var facing = info.UseDirectionalTarget && order.ExtraData != uint.MaxValue ? (int)order.ExtraData : -1;
var facing = info.UseDirectionalTarget && order.ExtraData != uint.MaxValue ? (WAngle?)WAngle.FromFacing((int)order.ExtraData) : null;
SendParatroopers(self, order.Target.CenterPosition, facing);
}
public Pair<Actor[], Actor[]> SendParatroopers(Actor self, WPos target, int facing = -1)
public Pair<Actor[], Actor[]> SendParatroopers(Actor self, WPos target, WAngle? facing = null)
{
var aircraft = new List<Actor>();
var units = new List<Actor>();
var info = Info as ParatroopersPowerInfo;
if (facing < 0)
facing = 256 * self.World.SharedRandom.Next(info.QuantizedFacings) / info.QuantizedFacings;
if (!facing.HasValue)
facing = WAngle.FromFacing(256 * self.World.SharedRandom.Next(info.QuantizedFacings) / info.QuantizedFacings);
var utLower = info.UnitType.ToLowerInvariant();
ActorInfo unitType;
@@ -113,7 +113,7 @@ namespace OpenRA.Mods.Common.Traits
throw new YamlException("Actors ruleset does not include the entry '{0}'".F(utLower));
var altitude = unitType.TraitInfo<AircraftInfo>().CruiseAltitude.Length;
var dropRotation = WRot.FromFacing(facing);
var dropRotation = WRot.FromYaw(facing.Value);
var delta = new WVec(0, -1024, 0).Rotate(dropRotation);
target = target + new WVec(0, 0, altitude);
var startEdge = target - (self.World.Map.DistanceToEdge(target, -delta) + info.Cordon).Length * delta / 1024;
@@ -185,7 +185,7 @@ namespace OpenRA.Mods.Common.Traits
{
new CenterPositionInit(startEdge + spawnOffset),
new OwnerInit(self.Owner),
new FacingInit(facing),
new FacingInit(facing.Value.Facing),
}));
}