diff --git a/OpenRA.Mods.Common/Effects/CrateEffect.cs b/OpenRA.Mods.Common/Effects/CrateEffect.cs deleted file mode 100644 index 55b9f9b9af..0000000000 --- a/OpenRA.Mods.Common/Effects/CrateEffect.cs +++ /dev/null @@ -1,48 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2018 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, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using System.Collections.Generic; -using OpenRA.Effects; -using OpenRA.Graphics; - -namespace OpenRA.Mods.Common.Effects -{ - public class CrateEffect : IEffect, ISpatiallyPartitionable - { - readonly string palette; - readonly Actor a; - readonly Animation anim; - - public CrateEffect(Actor a, string seq, string palette) - { - this.a = a; - this.palette = palette; - - anim = new Animation(a.World, "crate-effects"); - anim.PlayThen(seq, () => a.World.AddFrameEndTask(w => { w.Remove(this); w.ScreenMap.Remove(this); })); - a.World.ScreenMap.Add(this, a.CenterPosition, anim.Image); - } - - public void Tick(World world) - { - anim.Tick(); - world.ScreenMap.Update(this, a.CenterPosition, anim.Image); - } - - public IEnumerable Render(WorldRenderer wr) - { - if (!a.IsInWorld || a.World.FogObscures(a.CenterPosition)) - return SpriteRenderable.None; - - return anim.Render(a.CenterPosition, wr.Palette(palette)); - } - } -} diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 10c321241b..2de00b2bd7 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -139,7 +139,6 @@ - @@ -942,6 +941,7 @@ + diff --git a/OpenRA.Mods.Common/Traits/Crates/CrateAction.cs b/OpenRA.Mods.Common/Traits/Crates/CrateAction.cs index 6b5e2fbdbd..ad70e7bcdd 100644 --- a/OpenRA.Mods.Common/Traits/Crates/CrateAction.cs +++ b/OpenRA.Mods.Common/Traits/Crates/CrateAction.cs @@ -20,8 +20,11 @@ namespace OpenRA.Mods.Common.Traits [Desc("Chance of getting this crate, assuming the collector is compatible.")] public readonly int SelectionShares = 10; - [Desc("An animation defined in sequence yaml(s) to draw.")] - public readonly string Effect = null; + [Desc("Image containing the crate effect animation sequence.")] + public readonly string Image = "crate-effects"; + + [Desc("Animation sequence played when collected. Leave empty for no effect.")] + [SequenceReference("Image")] public readonly string Sequence = null; [Desc("Palette to draw the animation in.")] [PaletteReference] public readonly string Palette = "effect"; @@ -84,8 +87,8 @@ namespace OpenRA.Mods.Common.Traits Game.Sound.PlayNotification(self.World.Map.Rules, collector.Owner, "Speech", Info.Notification, collector.Owner.Faction.InternalName); - if (Info.Effect != null) - collector.World.AddFrameEndTask(w => w.Add(new CrateEffect(collector, Info.Effect, Info.Palette))); + if (Info.Image != null && Info.Sequence != null) + collector.World.AddFrameEndTask(w => w.Add(new SpriteEffect(collector, w, Info.Image, Info.Sequence, Info.Palette))); } } } diff --git a/OpenRA.Mods.Common/Traits/GainsExperience.cs b/OpenRA.Mods.Common/Traits/GainsExperience.cs index 0f5fa29aa3..7c82c4d5ef 100644 --- a/OpenRA.Mods.Common/Traits/GainsExperience.cs +++ b/OpenRA.Mods.Common/Traits/GainsExperience.cs @@ -29,6 +29,12 @@ namespace OpenRA.Mods.Common.Traits [GrantedConditionReference] public IEnumerable LinterConditions { get { return Conditions.Values; } } + [Desc("Image for the level up sprite.")] + public readonly string LevelUpImage = null; + + [Desc("Sequence for the level up sprite. Needs to be present on Image.")] + [SequenceReference("Image")] public readonly string LevelUpSequence = "levelup"; + [Desc("Palette for the level up sprite.")] [PaletteReference] public readonly string LevelUpPalette = "effect"; @@ -107,7 +113,8 @@ namespace OpenRA.Mods.Common.Traits if (!silent) { Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", info.LevelUpNotification, self.Owner.Faction.InternalName); - self.World.AddFrameEndTask(w => w.Add(new CrateEffect(self, "levelup", info.LevelUpPalette))); + if (info.LevelUpImage != null && info.LevelUpSequence != null) + self.World.AddFrameEndTask(w => w.Add(new SpriteEffect(self, w, info.LevelUpImage, info.LevelUpSequence, info.LevelUpPalette))); } } } diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/20180923/DefineLevelupImageDefault.cs b/OpenRA.Mods.Common/UpdateRules/Rules/20180923/DefineLevelupImageDefault.cs new file mode 100644 index 0000000000..64b8698e79 --- /dev/null +++ b/OpenRA.Mods.Common/UpdateRules/Rules/20180923/DefineLevelupImageDefault.cs @@ -0,0 +1,61 @@ +#region Copyright & License Information +/* + * Copyright 2007-2018 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, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System.Collections.Generic; + +namespace OpenRA.Mods.Common.UpdateRules.Rules +{ + public class DefineLevelUpImageDefault : UpdateRule + { + public override string Name { get { return "Unhardcoded LevelUpImage and LevelUpSequence on GainsExperience"; } } + public override string Description + { + get + { + return "GainsExperience was hardcoded to play a 'levelup' crate effect from 'crate-effects' image."; + } + } + + static readonly string[] CrateActionTraits = + { + "DuplicateUnitCrateAction", + "ExplodeCrateAction", + "GiveCashCrateAction", + "GiveMcvCrateAction", + "GiveUnitCrateAction", + "GrantExternalConditionCrateAction", + "HealUnitsCrateAction", + "HideMapCrateAction", + "LevelUpCrateAction", + "RevealMapCrateAction", + "SupportPowerCrateAction" + }; + + public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNode actorNode) + { + var levelUpImageNode = new MiniYamlNode("LevelUpImage", "crate-effects"); + foreach (var ge in actorNode.ChildrenMatching("GainsExperience")) + ge.AddNode(levelUpImageNode); + + foreach (var t in CrateActionTraits) + { + foreach (var ca in actorNode.ChildrenMatching(t)) + { + var effect = ca.LastChildMatching("Effect"); + if (effect != null) + effect.RenameKey("Sequence"); + } + } + + yield break; + } + } +} diff --git a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs index 88bd2b0fb9..a297ae9fff 100644 --- a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs +++ b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs @@ -108,6 +108,7 @@ namespace OpenRA.Mods.Common.UpdateRules new ExtractHackyAIModules(), new RemoveNegativeDamageFullHealthCheck(), new RemoveResourceExplodeModifier(), + new DefineLevelUpImageDefault(), }) }; diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index 91acf9c2ad..66abf41a90 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -49,6 +49,7 @@ 400: rank-veteran 800: rank-veteran 1600: rank-veteran + LevelUpImage: crate-effects GrantCondition@RANK-ELITE: RequiresCondition: rank-veteran >= 4 Condition: rank-elite diff --git a/mods/cnc/rules/misc.yaml b/mods/cnc/rules/misc.yaml index 3f58da9748..f679692106 100644 --- a/mods/cnc/rules/misc.yaml +++ b/mods/cnc/rules/misc.yaml @@ -12,13 +12,13 @@ CRATE: UseCashTick: yes RevealMapCrateAction: SelectionShares: 1 - Effect: reveal-map + Sequence: reveal-map ExplodeCrateAction@fire: Weapon: Napalm.Crate SelectionShares: 5 GrantExternalConditionCrateAction@cloak: SelectionShares: 5 - Effect: cloak + Sequence: cloak Condition: cloak-crate-collected GiveMcvCrateAction: SelectionShares: 0 diff --git a/mods/d2k/rules/defaults.yaml b/mods/d2k/rules/defaults.yaml index 450f151c2f..31e0d6ce0d 100644 --- a/mods/d2k/rules/defaults.yaml +++ b/mods/d2k/rules/defaults.yaml @@ -21,6 +21,7 @@ 400: rank-veteran 800: rank-veteran 1600: rank-veteran + LevelUpImage: crate-effects GrantCondition@RANK-ELITE: RequiresCondition: rank-veteran >= 4 Condition: rank-elite diff --git a/mods/d2k/rules/misc.yaml b/mods/d2k/rules/misc.yaml index 6d2d94e305..ff7ae7f01b 100644 --- a/mods/d2k/rules/misc.yaml +++ b/mods/d2k/rules/misc.yaml @@ -22,12 +22,12 @@ crate: SelectionShares: 5 HideMapCrateAction: SelectionShares: 5 - Effect: hide-map + Sequence: hide-map LevelUpCrateAction: SelectionShares: 40 RevealMapCrateAction: SelectionShares: 2 - Effect: reveal-map + Sequence: reveal-map GiveUnitCrateAction@LightInfantry: SelectionShares: 15 Units: light_inf, light_inf, light_inf, light_inf, light_inf diff --git a/mods/ra/maps/fort-lonestar/rules.yaml b/mods/ra/maps/fort-lonestar/rules.yaml index 7be7e6031e..66c1e3df60 100644 --- a/mods/ra/maps/fort-lonestar/rules.yaml +++ b/mods/ra/maps/fort-lonestar/rules.yaml @@ -63,11 +63,11 @@ FORTCRATE: SupportPowerCrateAction@parabombs: SelectionShares: 30 Proxy: powerproxy.parabombs - Effect: parabombs + Sequence: parabombs HealUnitsCrateAction: SelectionShares: 30 Sound: heal2.aud - Effect: heal + Sequence: heal GiveCashCrateAction: Amount: 400 UseCashTick: true @@ -77,7 +77,7 @@ FORTCRATE: SelectionShares: 10 GrantExternalConditionCrateAction@ironcurtain: SelectionShares: 10 - Effect: invuln + Sequence: invuln Sound: ironcur9.aud Condition: invulnerability Duration: 1200 diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index 57e86c8672..f1b24352ad 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -48,6 +48,7 @@ 400: rank-veteran 800: rank-veteran 1600: rank-veteran + LevelUpImage: crate-effects GrantCondition@RANK-ELITE: RequiresCondition: rank-veteran >= 4 Condition: rank-elite diff --git a/mods/ra/rules/misc.yaml b/mods/ra/rules/misc.yaml index 642da14b5f..f44eca27f2 100644 --- a/mods/ra/rules/misc.yaml +++ b/mods/ra/rules/misc.yaml @@ -31,14 +31,14 @@ CRATE: SelectionShares: 5 HideMapCrateAction: SelectionShares: 5 - Effect: hide-map + Sequence: hide-map HealUnitsCrateAction: Sound: heal2.aud SelectionShares: 2 - Effect: heal + Sequence: heal RevealMapCrateAction: SelectionShares: 1 - Effect: reveal-map + Sequence: reveal-map DuplicateUnitCrateAction: SelectionShares: 10 MaxAmount: 5 @@ -104,7 +104,7 @@ CRATE: TimeDelay: 4500 GrantExternalConditionCrateAction@invuln: SelectionShares: 5 - Effect: invuln + Sequence: invuln Sound: ironcur9.aud Condition: invulnerability Duration: 600 @@ -127,7 +127,7 @@ HEALCRATE: HealUnitsCrateAction: Sound: heal2.aud SelectionShares: 1 - Effect: heal + Sequence: heal WCRATE: Inherits: ^Crate diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index c34749586d..36f755f124 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -21,6 +21,7 @@ Conditions: 500: rank 1000: rank + LevelUpImage: crate-effects GrantCondition@RANK-VETERAN: RequiresCondition: rank == 1 Condition: rank-veteran diff --git a/mods/ts/rules/misc.yaml b/mods/ts/rules/misc.yaml index c183a8cf76..66b0fbc5ab 100644 --- a/mods/ts/rules/misc.yaml +++ b/mods/ts/rules/misc.yaml @@ -69,37 +69,37 @@ CRATE: GiveCashCrateAction: Amount: 1000 SelectionShares: 50 - Effect: dollar + Sequence: dollar UseCashTick: true LevelUpCrateAction: SelectionShares: 40 - Effect: levelup + Sequence: levelup HideMapCrateAction: SelectionShares: 5 - Effect: hide-map + Sequence: hide-map HealUnitsCrateAction: SelectionShares: 2 - Effect: heal + Sequence: heal RevealMapCrateAction: SelectionShares: 1 - Effect: reveal-map + Sequence: reveal-map GiveMcvCrateAction: SelectionShares: 0 NoBaseSelectionShares: 100 Units: mcv GrantExternalConditionCrateAction@cloak: SelectionShares: 5 - Effect: stealth + Sequence: stealth Condition: crate-cloak Sound: cloak5.aud GrantExternalConditionCrateAction@firepower: SelectionShares: 5 - Effect: firepower + Sequence: firepower Condition: crate-firepower Notification: UnitFirepowerUpgraded GrantExternalConditionCrateAction@armor: SelectionShares: 5 - Effect: armor + Sequence: armor Condition: crate-damage Notification: UnitArmourUpgraded GrantExternalConditionCrateAction@speed: