From 6af377030cbb50d44da567a43226eb66a95b3020 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 2 Jan 2016 12:42:57 +0000 Subject: [PATCH 1/4] Add sequence parameter to SpriteEffect. --- OpenRA.Game/Effects/SpriteEffect.cs | 4 ++-- OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs | 2 +- OpenRA.Mods.Common/Traits/Render/LeavesTrails.cs | 2 +- OpenRA.Mods.Common/Traits/SupportPowers/SpawnActorPower.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/OpenRA.Game/Effects/SpriteEffect.cs b/OpenRA.Game/Effects/SpriteEffect.cs index c415dfab19..46929ebd6a 100644 --- a/OpenRA.Game/Effects/SpriteEffect.cs +++ b/OpenRA.Game/Effects/SpriteEffect.cs @@ -20,13 +20,13 @@ namespace OpenRA.Effects readonly WPos pos; readonly bool scaleSizeWithZoom; - public SpriteEffect(WPos pos, World world, string image, string palette, bool scaleSizeWithZoom = false) + public SpriteEffect(WPos pos, World world, string image, string sequence, string palette, bool scaleSizeWithZoom = false) { this.pos = pos; this.palette = palette; this.scaleSizeWithZoom = scaleSizeWithZoom; anim = new Animation(world, image); - anim.PlayThen("idle", () => world.AddFrameEndTask(w => w.Remove(this))); + anim.PlayThen(sequence, () => world.AddFrameEndTask(w => w.Remove(this))); } public void Tick(World world) diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index 232b4cdbe4..6bcf07d067 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -214,7 +214,7 @@ namespace OpenRA.Widgets else if (o.TargetLocation != CPos.Zero) { var pos = world.Map.CenterOfCell(cell); - world.AddFrameEndTask(w => w.Add(new SpriteEffect(pos, world, "moveflsh", "moveflash", true))); + world.AddFrameEndTask(w => w.Add(new SpriteEffect(pos, world, "moveflsh", "idle", "moveflash", true))); flashed = true; } } diff --git a/OpenRA.Mods.Common/Traits/Render/LeavesTrails.cs b/OpenRA.Mods.Common/Traits/Render/LeavesTrails.cs index 6ca9e85c01..30bb428a59 100644 --- a/OpenRA.Mods.Common/Traits/Render/LeavesTrails.cs +++ b/OpenRA.Mods.Common/Traits/Render/LeavesTrails.cs @@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.Traits self.World.Map.CenterOfCell(cachedCell); if (info.TerrainTypes.Contains(type) && !string.IsNullOrEmpty(info.Image)) - self.World.AddFrameEndTask(w => w.Add(new SpriteEffect(pos, self.World, info.Image, info.Palette))); + self.World.AddFrameEndTask(w => w.Add(new SpriteEffect(pos, self.World, info.Image, "idle", info.Palette))); cachedPosition = self.CenterPosition; ticks = 0; diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/SpawnActorPower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/SpawnActorPower.cs index f0f4f21f46..d704651789 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/SpawnActorPower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/SpawnActorPower.cs @@ -52,7 +52,7 @@ namespace OpenRA.Mods.Common.Traits Game.Sound.Play(info.DeploySound, location); if (!string.IsNullOrEmpty(info.EffectSequence) && !string.IsNullOrEmpty(info.EffectPalette)) - w.Add(new SpriteEffect(location, w, info.EffectSequence, info.EffectPalette)); + w.Add(new SpriteEffect(location, w, info.EffectSequence, "idle", info.EffectPalette)); var actor = w.CreateActor(info.Actor, new TypeDictionary { From adaa1fa70e9b3cec82e6a406cc1e79d29c16b933 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 2 Jan 2016 19:25:26 +0000 Subject: [PATCH 2/4] Add multiple sequence and upgrade support to LeavesTrails. --- .../Traits/Render/LeavesTrails.cs | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/Render/LeavesTrails.cs b/OpenRA.Mods.Common/Traits/Render/LeavesTrails.cs index 30bb428a59..6287644c71 100644 --- a/OpenRA.Mods.Common/Traits/Render/LeavesTrails.cs +++ b/OpenRA.Mods.Common/Traits/Render/LeavesTrails.cs @@ -18,9 +18,13 @@ namespace OpenRA.Mods.Common.Traits public enum TrailType { Cell, CenterPosition } [Desc("Renders a sprite effect when leaving a cell.")] - public class LeavesTrailsInfo : ITraitInfo + public class LeavesTrailsInfo : UpgradableTraitInfo { public readonly string Image = null; + + [SequenceReference("Image")] + public readonly string[] Sequences = { "idle" }; + [PaletteReference] public readonly string Palette = "effect"; [Desc("Only do so when the terrain types match with the previous cell.")] @@ -42,43 +46,47 @@ namespace OpenRA.Mods.Common.Traits [Desc("Delay between trail updates when moving.")] public readonly int MovingInterval = 0; - public object Create(ActorInitializer init) { return new LeavesTrails(this, init.Self); } + public override object Create(ActorInitializer init) { return new LeavesTrails(init.Self, this); } } - public class LeavesTrails : ITick + public class LeavesTrails : UpgradableTrait, ITick { - readonly LeavesTrailsInfo info; - - public LeavesTrails(LeavesTrailsInfo info, Actor self) - { - this.info = info; - } + public LeavesTrails(Actor self, LeavesTrailsInfo info) + : base(info) { } WPos cachedPosition; int ticks; public void Tick(Actor self) { - var isMoving = self.CenterPosition != cachedPosition; - if ((isMoving && !info.TrailWhileMoving) || (!isMoving && !info.TrailWhileStationary)) + if (IsTraitDisabled) return; - var interval = isMoving ? info.MovingInterval : - info.StationaryInterval; + var isMoving = self.CenterPosition != cachedPosition; + if ((isMoving && !Info.TrailWhileMoving) || (!isMoving && !Info.TrailWhileStationary)) + return; + + var interval = isMoving ? Info.MovingInterval : Info.StationaryInterval; if (++ticks >= interval) { var cachedCell = self.World.Map.CellContaining(cachedPosition); var type = self.World.Map.GetTerrainInfo(cachedCell).Type; - var pos = info.Type == TrailType.CenterPosition ? cachedPosition : + var pos = Info.Type == TrailType.CenterPosition ? cachedPosition : self.World.Map.CenterOfCell(cachedCell); - if (info.TerrainTypes.Contains(type) && !string.IsNullOrEmpty(info.Image)) - self.World.AddFrameEndTask(w => w.Add(new SpriteEffect(pos, self.World, info.Image, "idle", info.Palette))); + if (Info.TerrainTypes.Contains(type) && !string.IsNullOrEmpty(Info.Image)) + self.World.AddFrameEndTask(w => w.Add(new SpriteEffect(pos, self.World, Info.Image, + Info.Sequences.Random(Game.CosmeticRandom), Info.Palette))); cachedPosition = self.CenterPosition; ticks = 0; } } + + protected override void UpgradeEnabled(Actor self) + { + cachedPosition = self.CenterPosition; + } } } From 8ce274ed791f19e81745509afd31d0143dbbe5b1 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 2 Jan 2016 19:25:55 +0000 Subject: [PATCH 3/4] Overhaul and rename WithActiveAnimation -> WithIdleAnimation. --- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 2 +- .../Traits/Render/WithActiveAnimation.cs | 70 ------------------ .../Traits/Render/WithIdleAnimation.cs | 71 +++++++++++++++++++ .../UtilityCommands/UpgradeRules.cs | 12 ++++ mods/cnc/rules/trees.yaml | 6 +- mods/ts/rules/defaults.yaml | 2 +- 6 files changed, 88 insertions(+), 75 deletions(-) delete mode 100644 OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs create mode 100644 OpenRA.Mods.Common/Traits/Render/WithIdleAnimation.cs diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index b7545db6da..f4d9622074 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -421,7 +421,6 @@ - @@ -718,6 +717,7 @@ + diff --git a/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs b/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs deleted file mode 100644 index 22d17f6eda..0000000000 --- a/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs +++ /dev/null @@ -1,70 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2015 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ -#endregion - -using System.Collections.Generic; -using System.Linq; -using OpenRA.Graphics; -using OpenRA.Traits; - -namespace OpenRA.Mods.Common.Traits -{ - [Desc("Replaces the idle animation of a building.")] - public class WithActiveAnimationInfo : ITraitInfo, Requires - { - [Desc("Sequence name to use")] - [SequenceReference] public readonly string Sequence = "active"; - - public readonly int Interval = 750; - - public readonly bool PauseOnLowPower = false; - - public object Create(ActorInitializer init) { return new WithActiveAnimation(init.Self, this); } - } - - public class WithActiveAnimation : ITick, INotifyBuildComplete, INotifySold - { - readonly WithActiveAnimationInfo info; - readonly WithSpriteBody wsb; - - public WithActiveAnimation(Actor self, WithActiveAnimationInfo info) - { - wsb = self.Trait(); - this.info = info; - } - - int ticks; - public void Tick(Actor self) - { - if (!buildComplete) - return; - - if (--ticks <= 0) - { - if (!(info.PauseOnLowPower && self.IsDisabled())) - wsb.PlayCustomAnimation(self, info.Sequence, () => wsb.CancelCustomAnimation(self)); - ticks = info.Interval; - } - } - - bool buildComplete = false; - - public void BuildingComplete(Actor self) - { - buildComplete = true; - } - - public void Selling(Actor self) - { - buildComplete = false; - } - - public void Sold(Actor self) { } - } -} diff --git a/OpenRA.Mods.Common/Traits/Render/WithIdleAnimation.cs b/OpenRA.Mods.Common/Traits/Render/WithIdleAnimation.cs new file mode 100644 index 0000000000..bf6ec6cf4c --- /dev/null +++ b/OpenRA.Mods.Common/Traits/Render/WithIdleAnimation.cs @@ -0,0 +1,71 @@ +#region Copyright & License Information +/* + * Copyright 2007-2015 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System.Collections.Generic; +using System.Linq; +using OpenRA.Graphics; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Traits +{ + [Desc("Periodically plays an idle animation, replacing the default body animation.")] + public class WithIdleAnimationInfo : UpgradableTraitInfo, Requires + { + [SequenceReference, Desc("Sequence names to use.")] + public readonly string[] Sequences = { "active" }; + + public readonly int Interval = 750; + + [Desc("Pause when the actor is disabled. Deprecated. Use upgrades instead.")] + public readonly bool PauseOnLowPower = false; + + public override object Create(ActorInitializer init) { return new WithIdleAnimation(init.Self, this); } + } + + public class WithIdleAnimation : UpgradableTrait, ITick, INotifyBuildComplete, INotifySold + { + readonly WithSpriteBody wsb; + bool buildComplete; + int ticks; + + public WithIdleAnimation(Actor self, WithIdleAnimationInfo info) + : base(info) + { + wsb = self.Trait(); + buildComplete = !self.Info.HasTraitInfo(); // always render instantly for units + ticks = info.Interval; + } + + public void Tick(Actor self) + { + if (!buildComplete || IsTraitDisabled) + return; + + if (--ticks <= 0) + { + if (!(Info.PauseOnLowPower && self.IsDisabled())) + wsb.PlayCustomAnimation(self, Info.Sequences.Random(Game.CosmeticRandom), () => wsb.CancelCustomAnimation(self)); + ticks = Info.Interval; + } + } + + public void BuildingComplete(Actor self) + { + buildComplete = true; + } + + public void Selling(Actor self) + { + buildComplete = false; + } + + public void Sold(Actor self) { } + } +} diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index f2e612b9dd..c681f7f856 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -2818,6 +2818,18 @@ namespace OpenRA.Mods.Common.UtilityCommands } } + if (engineVersion < 20160103) + { + // Overhauled WithActiveAnimation -> WithIdleAnimation + if (node.Key == "WithActiveAnimation") + { + node.Key = "WithIdleAnimation"; + foreach (var n in node.Value.Nodes) + if (n.Key == "Sequence") + n.Key = "Sequences"; + } + } + UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); } } diff --git a/mods/cnc/rules/trees.yaml b/mods/cnc/rules/trees.yaml index 2bff4b0382..eaefa4a9a7 100644 --- a/mods/cnc/rules/trees.yaml +++ b/mods/cnc/rules/trees.yaml @@ -3,7 +3,7 @@ SPLIT2: SeedsResource: ResourceType: Tiberium Interval: 55 - WithActiveAnimation: + WithIdleAnimation: SPLIT3: Inherits: ^TibTree @@ -12,7 +12,7 @@ SPLIT3: SeedsResource: ResourceType: Tiberium Interval: 55 - WithActiveAnimation: + WithIdleAnimation: SPLITBLUE: Inherits: ^TibTree @@ -21,7 +21,7 @@ SPLITBLUE: SeedsResource: ResourceType: BlueTiberium Interval: 110 - WithActiveAnimation: + WithIdleAnimation: Tooltip: Name: Blossom Tree (blue) RadarColorFromTerrain: diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index c6b22f5ea0..f1b8070d92 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -571,7 +571,7 @@ SeedsResource: ResourceType: Tiberium Interval: 55 - WithActiveAnimation: + WithIdleAnimation: ^Tree: Inherits@1: ^SpriteActor From 47c97735eddd889f603ce49a6d4f326285f63ad6 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 2 Jan 2016 19:26:15 +0000 Subject: [PATCH 4/4] Overhaul sand worm rendering and attacking. --- OpenRA.Mods.D2k/Activities/SwallowActor.cs | 191 +++++++++++---------- OpenRA.Mods.D2k/Traits/AttackSwallow.cs | 8 +- OpenRA.Mods.D2k/Traits/Sandworm.cs | 22 +-- mods/d2k/bits/sandtrail.shp | Bin 0 -> 1513 bytes mods/d2k/rules/arrakis.yaml | 26 ++- mods/d2k/sequences/infantry.yaml | 35 +++- mods/d2k/sequences/misc.yaml | 11 ++ 7 files changed, 171 insertions(+), 122 deletions(-) create mode 100644 mods/d2k/bits/sandtrail.shp diff --git a/OpenRA.Mods.D2k/Activities/SwallowActor.cs b/OpenRA.Mods.D2k/Activities/SwallowActor.cs index e99b5903f0..969b36393b 100644 --- a/OpenRA.Mods.D2k/Activities/SwallowActor.cs +++ b/OpenRA.Mods.D2k/Activities/SwallowActor.cs @@ -19,22 +19,22 @@ using OpenRA.Traits; namespace OpenRA.Mods.D2k.Activities { - enum AttackState { Burrowed, EmergingAboveGround, ReturningUnderground } + enum AttackState { Uninitialized, Burrowed, Attacking } class SwallowActor : Activity { const int NearEnough = 1; - readonly CPos location; readonly Target target; readonly Sandworm sandworm; + readonly UpgradeManager manager; readonly WeaponInfo weapon; - readonly WithSpriteBody withSpriteBody; readonly RadarPings radarPings; readonly AttackSwallow swallow; readonly IPositionable positionable; int countdown; + CPos burrowLocation; AttackState stance; public SwallowActor(Actor self, Target target, WeaponInfo weapon) @@ -44,128 +44,133 @@ namespace OpenRA.Mods.D2k.Activities sandworm = self.Trait(); positionable = self.Trait(); swallow = self.Trait(); - withSpriteBody = self.Trait(); + manager = self.Trait(); radarPings = self.World.WorldActor.TraitOrDefault(); - countdown = swallow.Info.AttackTime; - - withSpriteBody.DefaultAnimation.ReplaceAnim(sandworm.Info.BurrowedSequence); - stance = AttackState.Burrowed; - location = target.Actor.Location; } - bool WormAttack(Actor worm) + bool AttackTargets(Actor self, IEnumerable targets) { var targetLocation = target.Actor.Location; - - // The target has moved too far away - if ((location - targetLocation).Length > NearEnough) - return false; - - var lunch = worm.World.ActorMap.GetActorsAt(targetLocation) - .Where(t => !t.Equals(worm) && weapon.IsValidAgainst(t, worm)); - - if (!lunch.Any()) - return false; - - stance = AttackState.EmergingAboveGround; - sandworm.IsAttacking = true; - - foreach (var actor in lunch) + foreach (var t in targets) { - var actor1 = actor; // loop variable in closure hazard + var target = t; // loop variable in closure hazard - actor.World.AddFrameEndTask(_ => + self.World.AddFrameEndTask(_ => + { + // Don't use Kill() because we don't want any of its side-effects (husks, etc) + target.Dispose(); + + // Harvester insurance + if (target.Info.HasTraitInfo()) { - actor1.Dispose(); - - // Harvester insurance - if (!actor1.Info.HasTraitInfo()) - return; - - var insurance = actor1.Owner.PlayerActor.TraitOrDefault(); - + var insurance = target.Owner.PlayerActor.TraitOrDefault(); if (insurance != null) - actor1.World.AddFrameEndTask(__ => insurance.TryActivate()); - }); + self.World.AddFrameEndTask(__ => insurance.TryActivate()); + } + }); } - positionable.SetPosition(worm, targetLocation); + positionable.SetPosition(self, targetLocation); - var attackPosition = worm.CenterPosition; - var affectedPlayers = lunch.Select(x => x.Owner).Distinct().ToList(); - - PlayAttack(worm, attackPosition, affectedPlayers); - foreach (var notify in worm.TraitsImplementing()) - notify.Attacking(worm, target, null, null); - - return true; - } - - // List because IEnumerable gets evaluated too late. - void PlayAttack(Actor self, WPos attackPosition, List affectedPlayers) - { - withSpriteBody.PlayCustomAnimation(self, sandworm.Info.MouthSequence); + var attackPosition = self.CenterPosition; + var affectedPlayers = targets.Select(x => x.Owner).Distinct().ToList(); Game.Sound.Play(swallow.Info.WormAttackSound, self.CenterPosition); Game.RunAfterDelay(1000, () => { - if (Game.IsCurrentWorld(self.World)) - foreach (var affectedPlayer in affectedPlayers) - NotifyPlayer(affectedPlayer, attackPosition); + if (!Game.IsCurrentWorld(self.World)) + return; + + foreach (var player in affectedPlayers) + { + Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", swallow.Info.WormAttackNotification, player.Faction.InternalName); + + if (player == player.World.RenderPlayer) + radarPings.Add(() => true, attackPosition, Color.Red, 50); + } }); - } - void NotifyPlayer(Player player, WPos location) - { - Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", swallow.Info.WormAttackNotification, player.Faction.InternalName); + foreach (var notify in self.TraitsImplementing()) + notify.Attacking(self, target, null, null); - if (player == player.World.RenderPlayer) - radarPings.Add(() => true, location, Color.Red, 50); + return true; } public override Activity Tick(Actor self) { - if (countdown > 0) + switch (stance) { - countdown--; - return this; - } + case AttackState.Uninitialized: + GrantUpgrades(self); + stance = AttackState.Burrowed; + countdown = swallow.Info.AttackDelay; + burrowLocation = self.Location; + break; + case AttackState.Burrowed: + if (--countdown > 0) + return this; - // Wait for the worm to get back underground - if (stance == AttackState.ReturningUnderground) - { - sandworm.IsAttacking = false; + var targetLocation = target.Actor.Location; - // There is a chance that the worm would just go away after attacking - if (self.World.SharedRandom.Next() % 100 <= sandworm.Info.ChanceToDisappear) - { - self.CancelActivity(); - self.World.AddFrameEndTask(w => self.Kill(self)); - } - else - withSpriteBody.DefaultAnimation.ReplaceAnim(sandworm.Info.IdleSequence); + // The target has moved too far away + if ((burrowLocation - targetLocation).Length > NearEnough) + { + RevokeUpgrades(self); + return NextActivity; + } - return NextActivity; - } + // The target reached solid ground + if (!positionable.CanEnterCell(targetLocation, null, false)) + { + RevokeUpgrades(self); + return NextActivity; + } - // Wait for the worm to get in position - if (stance == AttackState.Burrowed) - { - // This is so that the worm cancels an attack against a target that has reached solid rock - if (!positionable.CanEnterCell(target.Actor.Location, null, false)) + var targets = self.World.ActorMap.GetActorsAt(targetLocation) + .Where(t => !t.Equals(self) && weapon.IsValidAgainst(t, self)); + + if (!targets.Any()) + { + RevokeUpgrades(self); + return NextActivity; + } + + stance = AttackState.Attacking; + countdown = swallow.Info.ReturnDelay; + sandworm.IsAttacking = true; + AttackTargets(self, targets); + + break; + case AttackState.Attacking: + if (--countdown > 0) + return this; + + sandworm.IsAttacking = false; + + // There is a chance that the worm would just go away after attacking + if (self.World.SharedRandom.Next(100) <= sandworm.Info.ChanceToDisappear) + { + self.CancelActivity(); + self.World.AddFrameEndTask(w => self.Dispose()); + } + + RevokeUpgrades(self); return NextActivity; - - if (!WormAttack(self)) - { - withSpriteBody.DefaultAnimation.ReplaceAnim(sandworm.Info.IdleSequence); - return NextActivity; - } - - countdown = swallow.Info.ReturnTime; - stance = AttackState.ReturningUnderground; } return this; } + + void GrantUpgrades(Actor self) + { + foreach (var up in swallow.Info.AttackingUpgrades) + manager.GrantUpgrade(self, up, this); + } + + void RevokeUpgrades(Actor self) + { + foreach (var up in swallow.Info.AttackingUpgrades) + manager.RevokeUpgrade(self, up, this); + } } } diff --git a/OpenRA.Mods.D2k/Traits/AttackSwallow.cs b/OpenRA.Mods.D2k/Traits/AttackSwallow.cs index 090996630d..4aad528d11 100644 --- a/OpenRA.Mods.D2k/Traits/AttackSwallow.cs +++ b/OpenRA.Mods.D2k/Traits/AttackSwallow.cs @@ -20,10 +20,14 @@ namespace OpenRA.Mods.D2k.Traits class AttackSwallowInfo : AttackFrontalInfo { [Desc("The number of ticks it takes to return underground.")] - public readonly int ReturnTime = 60; + public readonly int ReturnDelay = 60; [Desc("The number of ticks it takes to get in place under the target to attack.")] - public readonly int AttackTime = 30; + public readonly int AttackDelay = 30; + + [UpgradeGrantedReference] + [Desc("The upgrades to grant while attacking.")] + public readonly string[] AttackingUpgrades = { "attacking" }; public readonly string WormAttackSound = "Worm.wav"; diff --git a/OpenRA.Mods.D2k/Traits/Sandworm.cs b/OpenRA.Mods.D2k/Traits/Sandworm.cs index 2ee042dc1f..91ad133b6d 100644 --- a/OpenRA.Mods.D2k/Traits/Sandworm.cs +++ b/OpenRA.Mods.D2k/Traits/Sandworm.cs @@ -10,12 +10,13 @@ using System; using System.Linq; +using OpenRA.Graphics; using OpenRA.Mods.Common.Traits; using OpenRA.Traits; namespace OpenRA.Mods.D2k.Traits { - class SandwormInfo : WandersInfo, Requires, Requires, Requires + class SandwormInfo : WandersInfo, Requires, Requires { [Desc("Time between rescanning for targets (in ticks).")] public readonly int TargetRescanInterval = 125; @@ -29,15 +30,6 @@ namespace OpenRA.Mods.D2k.Traits [Desc("The chance this actor has of disappearing after it attacks (in %).")] public readonly int ChanceToDisappear = 100; - [Desc("Name of the sequence that is used when the actor is idle or moving (not attacking).")] - [SequenceReference] public readonly string IdleSequence = "idle"; - - [Desc("Name of the sequence that is used when the actor is attacking.")] - [SequenceReference] public readonly string MouthSequence = "mouth"; - - [Desc("Name of the sequence that is used when the actor is burrowed.")] - [SequenceReference] public readonly string BurrowedSequence = "burrowed"; - public override object Create(ActorInitializer init) { return new Sandworm(init.Self, this); } } @@ -47,7 +39,6 @@ namespace OpenRA.Mods.D2k.Traits readonly WormManager manager; readonly Mobile mobile; - readonly WithSpriteBody withSpriteBody; readonly AttackBase attackTrait; public bool IsMovingTowardTarget { get; private set; } @@ -61,19 +52,10 @@ namespace OpenRA.Mods.D2k.Traits { Info = info; mobile = self.Trait(); - withSpriteBody = self.Trait(); attackTrait = self.Trait(); manager = self.World.WorldActor.Trait(); } - public override void OnBecomingIdle(Actor self) - { - if (withSpriteBody.DefaultAnimation.CurrentSequence.Name != Info.IdleSequence) - withSpriteBody.DefaultAnimation.PlayRepeating(Info.IdleSequence); - - base.OnBecomingIdle(self); - } - public override void DoAction(Actor self, CPos targetCell) { IsMovingTowardTarget = false; diff --git a/mods/d2k/bits/sandtrail.shp b/mods/d2k/bits/sandtrail.shp new file mode 100644 index 0000000000000000000000000000000000000000..8601595dc27aeceec36ec7b038a2090537d232a8 GIT binary patch literal 1513 zcmYk6$!b+Av6?`?fM#ryJv z_0J@tho^o^X|vRG!d$0ppEbTWUNT-V9x*N$=SO(Y_GP28E88LCb7N%4^`-3-#_5!{ zN=ms>h@zjo^;KO}fpT0F<~n2haY~;{DwXWizT%zRMp!^dUj6q@g~dXaK0E`D|%YrLOhqe+Tg&4y2QZo%1`B z4YsA;9g(N&UoYIZ@(dM(3xm1QA zSv+ROK+ssc!+l2x2tP_AFURms$Bjg>mE)W?wPCi>zvD&woDl9U!k#x(5i~VQ?nMu~ zeS#Zy0cn`|;7mCf%LmmUI&q-xg>-?1T9i%G?2?L`3M1|@YDU`boS$~=3!?@|p*g?O z7KKR8vHCfj3{`0QAmyq9;UH(S(aUgsAqOo)gVuN&eDBX^ufF<3Ab3L#TF~Vm1pO%y N<+}5=WPX3uz<*&FxxD}Y literal 0 HcmV?d00001 diff --git a/mods/d2k/rules/arrakis.yaml b/mods/d2k/rules/arrakis.yaml index 557edd6a10..d6c222012f 100644 --- a/mods/d2k/rules/arrakis.yaml +++ b/mods/d2k/rules/arrakis.yaml @@ -69,8 +69,20 @@ sandworm: Spice: 100 Targetable: TargetTypes: Ground - WithFacingSpriteBody: - WithAttackOverlay: + WithSpriteBody: + WithIdleAnimation: + Interval: 160 + Sequences: lightninga, lightningb, lightningc, lightningd, lightninge, lightningf + UpgradeTypes: attacking + UpgradeMaxEnabledLevel: 0 + AmbientSound: + SoundFile: WRMSIGN1.WAV + Interval: 160 + UpgradeTypes: attacking + UpgradeMaxEnabledLevel: 0 + WithAttackOverlay@mouth: + Sequence: mouth + WithAttackOverlay@sand: Sequence: sand HiddenUnderFog: AppearsOnRadar: @@ -88,6 +100,16 @@ sandworm: PingRadar: True RevealsShroud: Range: 5c0 + LeavesTrails: + Image: sandtrail + Sequences: traila, trailb, trailc + Palette: effect + Type: CenterPosition + TerrainTypes: Sand, Dune, SpiceSand, Spice + MovingInterval: 3 + UpgradeTypes: attacking + UpgradeMaxEnabledLevel: 0 + UpgradeManager: sietch: Inherits: ^Building diff --git a/mods/d2k/sequences/infantry.yaml b/mods/d2k/sequences/infantry.yaml index 1f114d484d..22bd0b67ce 100644 --- a/mods/d2k/sequences/infantry.yaml +++ b/mods/d2k/sequences/infantry.yaml @@ -481,10 +481,35 @@ sandworm: Length: 20 Tick: 100 idle: DATA.R8 - Start: 3586 - Length: 35 - Tick: 180 - BlendMode: Additive - burrowed: DATA.R8 Start: 39 + lightninga: DATA.R8 + Start: 3591 + Length: 5 + Tick: 80 + BlendMode: Additive + lightningb: DATA.R8 + Start: 3596 + Length: 5 + Tick: 80 + BlendMode: Additive + lightningc: DATA.R8 + Start: 3601 + Length: 5 + Tick: 80 + BlendMode: Additive + lightningd: DATA.R8 + Start: 3606 + Length: 5 + Tick: 80 + BlendMode: Additive + lightninge: DATA.R8 + Start: 3611 + Length: 5 + Tick: 80 + BlendMode: Additive + lightningf: DATA.R8 + Start: 3616 + Length: 5 + Tick: 80 + BlendMode: Additive icon: wormicon.shp \ No newline at end of file diff --git a/mods/d2k/sequences/misc.yaml b/mods/d2k/sequences/misc.yaml index d9a1b9e1e4..84a8854d1e 100644 --- a/mods/d2k/sequences/misc.yaml +++ b/mods/d2k/sequences/misc.yaml @@ -109,6 +109,17 @@ laserfire: BlendMode: Additive ZOffset: 511 +sandtrail: + Defaults: + Length: 8 + Tick: 200 + ZOffset: -512 + traila: sandtrail.shp + trailb: sandtrail.shp + Frames: 2, 6, 4, 5, 0, 1, 3, 7 + trailc: sandtrail.shp + Frames: 7, 4, 6, 5, 2, 0, 3, 1 + pips: groups: DATA.R8 Start: 17