Give husks the ability to crush
This commit is contained in:
committed by
Matthias Mailänder
parent
7638822e49
commit
a691f2ebac
@@ -9,8 +9,10 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
@@ -18,13 +20,17 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("Spawns remains of a husk actor with the correct facing.")]
|
||||
public class HuskInfo : TraitInfo, IPositionableInfo, IFacingInfo, IActorPreviewInitInfo
|
||||
public class HuskInfo : TraitInfo, IPositionableInfo, IFacingInfo, IActorPreviewInitInfo, IRulesetLoaded
|
||||
{
|
||||
public readonly HashSet<string> AllowedTerrain = new();
|
||||
|
||||
[Desc("Facing to use for actor previews (map editor, color picker, etc)")]
|
||||
public readonly WAngle PreviewFacing = new(384);
|
||||
|
||||
[LocomotorReference]
|
||||
[Desc("Used to define crushes. Locomotor must be defined on the World actor.")]
|
||||
public readonly string Locomotor = null;
|
||||
|
||||
IEnumerable<ActorInit> IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type)
|
||||
{
|
||||
yield return new FacingInit(PreviewFacing);
|
||||
@@ -47,6 +53,15 @@ namespace OpenRA.Mods.Common.Traits
|
||||
// all places relevant for husks check IPositionable.CanEnterCell instead, so we can safely set this to true.
|
||||
return true;
|
||||
}
|
||||
|
||||
public LocomotorInfo LocomotorInfo { get; private set; }
|
||||
public void RulesetLoaded(Ruleset rules, ActorInfo ai)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Locomotor))
|
||||
return;
|
||||
|
||||
LocomotorInfo = rules.Actors[SystemActors.World].TraitInfos<LocomotorInfo>().FirstOrDefault(li => li.Name == Locomotor);
|
||||
}
|
||||
}
|
||||
|
||||
public class Husk : IPositionable, IFacing, ISync, INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld,
|
||||
@@ -95,10 +110,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
void INotifyCreated.Created(Actor self)
|
||||
{
|
||||
var distance = (finalPosition - CenterPosition).Length;
|
||||
if (dragSpeed > 0 && distance > 0)
|
||||
self.QueueActivity(new Drag(self, CenterPosition, finalPosition, distance / dragSpeed));
|
||||
|
||||
self.QueueActivity(new DragAndCrush(self, info.LocomotorInfo, dragSpeed, finalPosition));
|
||||
notifyCenterPositionChanged = self.TraitsImplementing<INotifyCenterPositionChanged>().ToArray();
|
||||
}
|
||||
|
||||
@@ -181,4 +193,39 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public HuskSpeedInit(int value)
|
||||
: base(value) { }
|
||||
}
|
||||
|
||||
public class DragAndCrush : Activity
|
||||
{
|
||||
readonly LocomotorInfo info;
|
||||
|
||||
public DragAndCrush(Actor self, LocomotorInfo info, int dragSpeed, WPos finalPosition)
|
||||
{
|
||||
this.info = info;
|
||||
|
||||
var distance = (finalPosition - self.CenterPosition).Length;
|
||||
if (dragSpeed > 0 && distance > 0)
|
||||
self.QueueActivity(new Drag(self, self.CenterPosition, finalPosition, distance / dragSpeed));
|
||||
}
|
||||
|
||||
protected override void OnFirstRun(Actor self)
|
||||
{
|
||||
if (self.IsAtGroundLevel())
|
||||
CrushAction(self, self.CenterPosition, (notifyCrushed) => notifyCrushed.OnCrush);
|
||||
}
|
||||
|
||||
void CrushAction(Actor self, WPos position, Func<INotifyCrushed, Action<Actor, Actor, BitSet<CrushClass>>> action)
|
||||
{
|
||||
if (info == null || !info.Crushes.Any())
|
||||
return;
|
||||
|
||||
var crushables = self.World.ActorMap.GetActorsAt(self.World.Map.CellContaining(position)).Where(a => a != self)
|
||||
.SelectMany(a => a.TraitsImplementing<ICrushable>().Select(t => new TraitPair<ICrushable>(a, t)));
|
||||
|
||||
// Only crush actors that are on the ground level.
|
||||
foreach (var crushable in crushables)
|
||||
if (crushable.Trait.CrushableBy(crushable.Actor, self, info.Crushes) && crushable.Actor.IsAtGroundLevel())
|
||||
foreach (var notifyCrushed in crushable.Actor.TraitsImplementing<INotifyCrushed>())
|
||||
action(notifyCrushed)(crushable.Actor, self, info.Crushes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1069,6 +1069,7 @@
|
||||
Inherits: ^CommonHuskDefaults
|
||||
Husk:
|
||||
AllowedTerrain: Clear, Rough, Road, Tiberium, BlueTiberium, Beach
|
||||
Locomotor: tracked
|
||||
Targetable:
|
||||
RequiresForceFire: true
|
||||
TargetTypes: Ground, Husk
|
||||
@@ -1097,6 +1098,8 @@
|
||||
|
||||
^LightHusk:
|
||||
Inherits: ^Husk
|
||||
Husk:
|
||||
Locomotor: wheeled
|
||||
Health:
|
||||
HP: 4000
|
||||
|
||||
|
||||
@@ -299,6 +299,7 @@
|
||||
Inherits: ^Husk
|
||||
Husk:
|
||||
AllowedTerrain: Sand, Rock, Transition, Concrete, Spice, SpiceSand, SpiceBlobs, Dune
|
||||
Locomotor: tank
|
||||
Targetable:
|
||||
TargetTypes: Ground, Vehicle
|
||||
RequiresForceFire: true
|
||||
|
||||
@@ -32,6 +32,8 @@ missile_tank.husk:
|
||||
|
||||
sonic_tank.husk:
|
||||
Inherits: ^VehicleHusk
|
||||
Husk:
|
||||
Locomotor: vehicle
|
||||
Tooltip:
|
||||
Name: Sonic Tank (Destroyed)
|
||||
TransformOnCapture:
|
||||
@@ -39,6 +41,8 @@ sonic_tank.husk:
|
||||
|
||||
devastator.husk:
|
||||
Inherits: ^VehicleHusk
|
||||
Husk:
|
||||
Locomotor: devastator
|
||||
Health:
|
||||
HP: 1250
|
||||
Tooltip:
|
||||
|
||||
@@ -1048,6 +1048,7 @@
|
||||
Inherits@2: ^ClassicFacingSpriteActor
|
||||
Husk:
|
||||
AllowedTerrain: Clear, Rough, Road, Ore, Gems, Beach
|
||||
Locomotor: tracked
|
||||
WithIdleOverlay@Burns:
|
||||
Image: fire
|
||||
Sequence: 1
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
4TNK.Husk:
|
||||
Inherits: ^Husk
|
||||
Husk:
|
||||
Locomotor: heavytracked
|
||||
Tooltip:
|
||||
Name: Husk (Mammoth Tank)
|
||||
ThrowsParticle@turret:
|
||||
@@ -72,6 +74,8 @@ MCV.Husk:
|
||||
|
||||
MGG.Husk:
|
||||
Inherits: ^Husk
|
||||
Husk:
|
||||
Locomotor: wheeled
|
||||
Tooltip:
|
||||
Name: Husk (Mobile Gap Generator)
|
||||
ThrowsParticle@spinner:
|
||||
|
||||
Reference in New Issue
Block a user