From 079cff0a7a3401b6406697cb7c6615da662e691c Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Sat, 26 Sep 2015 11:12:39 -0500 Subject: [PATCH 1/2] IRulesetLoaded Warhead support and better error messages. --- OpenRA.Game/FieldLoader.cs | 2 +- OpenRA.Game/FileFormats/ReplayMetadata.cs | 4 +++ OpenRA.Game/GameInformation.cs | 2 +- OpenRA.Game/GameRules/Ruleset.cs | 32 ++++++++++++++++++++++- OpenRA.Game/Network/Session.cs | 8 ++++-- OpenRA.Game/Traits/TraitsInterfaces.cs | 3 ++- 6 files changed, 45 insertions(+), 6 deletions(-) diff --git a/OpenRA.Game/FieldLoader.cs b/OpenRA.Game/FieldLoader.cs index 07d2387672..5957ab158c 100644 --- a/OpenRA.Game/FieldLoader.cs +++ b/OpenRA.Game/FieldLoader.cs @@ -46,7 +46,7 @@ namespace OpenRA public static Func InvalidValueAction = (s, t, f) => { - throw new InvalidOperationException("FieldLoader: Cannot parse `{0}` into `{1}.{2}` ".F(s, f, t)); + throw new YamlException("FieldLoader: Cannot parse `{0}` into `{1}.{2}` ".F(s, f, t)); }; public static Action UnknownFieldAction = (s, f) => diff --git a/OpenRA.Game/FileFormats/ReplayMetadata.cs b/OpenRA.Game/FileFormats/ReplayMetadata.cs index d8e0be7449..ca2a895e1d 100644 --- a/OpenRA.Game/FileFormats/ReplayMetadata.cs +++ b/OpenRA.Game/FileFormats/ReplayMetadata.cs @@ -102,6 +102,10 @@ namespace OpenRA.FileFormats { return new ReplayMetadata(fs, path); } + catch (YamlException ex) + { + Log.Write("debug", ex.ToString()); + } catch (InvalidOperationException ex) { Log.Write("debug", ex.ToString()); diff --git a/OpenRA.Game/GameInformation.cs b/OpenRA.Game/GameInformation.cs index 50ceef446b..67c496bc64 100644 --- a/OpenRA.Game/GameInformation.cs +++ b/OpenRA.Game/GameInformation.cs @@ -70,7 +70,7 @@ namespace OpenRA return info; } - catch (InvalidOperationException) + catch (YamlException) { Log.Write("debug", "GameInformation deserialized invalid MiniYaml:\n{0}".F(data)); throw; diff --git a/OpenRA.Game/GameRules/Ruleset.cs b/OpenRA.Game/GameRules/Ruleset.cs index 19dbf28449..2b27910440 100644 --- a/OpenRA.Game/GameRules/Ruleset.cs +++ b/OpenRA.Game/GameRules/Ruleset.cs @@ -44,8 +44,38 @@ namespace OpenRA Sequences = new ReadOnlyDictionary(sequences); foreach (var a in Actors.Values) + { foreach (var t in a.TraitInfos()) - t.RulesetLoaded(this, a); + { + try + { + t.RulesetLoaded(this, a); + } + catch (YamlException e) + { + throw new YamlException("Actor type {0}: {1}".F(a.Name, e.Message)); + } + } + } + + foreach (var weapon in Weapons) + { + foreach (var warhead in weapon.Value.Warheads) + { + var cacher = warhead as IRulesetLoaded; + if (cacher != null) + { + try + { + cacher.RulesetLoaded(this, weapon.Value); + } + catch (YamlException e) + { + throw new YamlException("Weapon type {0}: {1}".F(weapon.Key, e.Message)); + } + } + } + } } public IEnumerable> InstalledMusic { get { return Music.Where(m => m.Value.Exists); } } diff --git a/OpenRA.Game/Network/Session.cs b/OpenRA.Game/Network/Session.cs index d4a09185a0..e452f09a07 100644 --- a/OpenRA.Game/Network/Session.cs +++ b/OpenRA.Game/Network/Session.cs @@ -59,9 +59,13 @@ namespace OpenRA.Network return session; } - catch (InvalidOperationException e) + catch (YamlException) { - throw new InvalidOperationException("Session deserialized invalid MiniYaml:\n{0}".F(data), e); + throw new YamlException("Session deserialized invalid MiniYaml:\n{0}".F(data)); + } + catch (InvalidOperationException) + { + throw new YamlException("Session deserialized invalid MiniYaml:\n{0}".F(data)); } } diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 96d4a0a8c5..95cd22a7dc 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -369,5 +369,6 @@ namespace OpenRA.Traits bool RemoveActor(Actor self, Player owner); } - public interface IRulesetLoaded : ITraitInfo { void RulesetLoaded(Ruleset rules, ActorInfo ai); } + public interface IRulesetLoaded { void RulesetLoaded(Ruleset rules, TInfo info); } + public interface IRulesetLoaded : IRulesetLoaded, ITraitInfo { } } From dc54841bad0281a79dde39291db8a96feb7ff893 Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Sat, 26 Sep 2015 10:41:53 -0500 Subject: [PATCH 2/2] cache AttackGarrisoned fire ports using IRulesetLoaded --- .../Traits/Attack/AttackGarrisoned.cs | 67 ++++++++++--------- .../Traits/CombatDebugOverlay.cs | 2 +- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackGarrisoned.cs b/OpenRA.Mods.Common/Traits/Attack/AttackGarrisoned.cs index ce6d6c0f11..b01d899612 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackGarrisoned.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackGarrisoned.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits } [Desc("Cargo can fire their weapons out of fire ports.")] - public class AttackGarrisonedInfo : AttackFollowInfo, Requires + public class AttackGarrisonedInfo : AttackFollowInfo, IRulesetLoaded, Requires { [FieldLoader.Require] [Desc("Fire port offsets in local coordinates.")] @@ -39,16 +39,39 @@ namespace OpenRA.Mods.Common.Traits [Desc("Fire port yaw cone angle.")] public readonly WAngle[] PortCones = null; + public FirePort[] Ports { get; private set; } + [PaletteReference] public readonly string MuzzlePalette = "effect"; public override object Create(ActorInitializer init) { return new AttackGarrisoned(init.Self, this); } + public void RulesetLoaded(Ruleset rules, ActorInfo ai) + { + if (PortOffsets.Length == 0) + throw new YamlException("PortOffsets must have at least one entry."); + + if (PortYaws.Length != PortOffsets.Length) + throw new YamlException("PortYaws must define an angle for each port."); + + if (PortCones.Length != PortOffsets.Length) + throw new YamlException("PortCones must define an angle for each port."); + + Ports = new FirePort[PortOffsets.Length]; + + for (var i = 0; i < PortOffsets.Length; i++) + { + Ports[i] = new FirePort + { + Offset = PortOffsets[i], + Yaw = PortYaws[i], + Cone = PortCones[i], + }; + } + } } public class AttackGarrisoned : AttackFollow, INotifyPassengerEntered, INotifyPassengerExited, IRender { - public readonly FirePort[] Ports; - - AttackGarrisonedInfo info; + public readonly new AttackGarrisonedInfo Info; Lazy coords; List armaments; List muzzles; @@ -59,7 +82,7 @@ namespace OpenRA.Mods.Common.Traits public AttackGarrisoned(Actor self, AttackGarrisonedInfo info) : base(self, info) { - this.info = info; + this.Info = info; coords = Exts.Lazy(() => self.Trait()); armaments = new List(); muzzles = new List(); @@ -68,28 +91,6 @@ namespace OpenRA.Mods.Common.Traits paxRender = new Dictionary(); getArmaments = () => armaments; - - if (info.PortOffsets.Length == 0) - throw new InvalidOperationException("PortOffsets must have at least one entry."); - - if (info.PortYaws.Length != info.PortOffsets.Length) - throw new InvalidOperationException("PortYaws must define an angle for each port."); - - if (info.PortCones.Length != info.PortOffsets.Length) - throw new InvalidOperationException("PortCones must define an angle for each port."); - - var p = new List(); - for (var i = 0; i < info.PortOffsets.Length; i++) - { - p.Add(new FirePort - { - Offset = info.PortOffsets[i], - Yaw = info.PortYaws[i], - Cone = info.PortCones[i], - }); - } - - Ports = p.ToArray(); } public void PassengerEntered(Actor self, Actor passenger) @@ -99,7 +100,7 @@ namespace OpenRA.Mods.Common.Traits paxRender.Add(passenger, passenger.Trait()); armaments.AddRange( passenger.TraitsImplementing() - .Where(a => info.Armaments.Contains(a.Info.Name))); + .Where(a => Info.Armaments.Contains(a.Info.Name))); } public void PassengerExited(Actor self, Actor passenger) @@ -114,14 +115,14 @@ namespace OpenRA.Mods.Common.Traits { // Pick a random port that faces the target var bodyYaw = facing.Value != null ? WAngle.FromFacing(facing.Value.Facing) : WAngle.Zero; - var indices = Enumerable.Range(0, Ports.Length).Shuffle(self.World.SharedRandom); + var indices = Enumerable.Range(0, Info.Ports.Length).Shuffle(self.World.SharedRandom); foreach (var i in indices) { - var yaw = bodyYaw + Ports[i].Yaw; + var yaw = bodyYaw + Info.Ports[i].Yaw; var leftTurn = (yaw - targetYaw).Angle; var rightTurn = (targetYaw - yaw).Angle; - if (Math.Min(leftTurn, rightTurn) <= Ports[i].Cone.Angle) - return Ports[i]; + if (Math.Min(leftTurn, rightTurn) <= Info.Ports[i].Cone.Angle) + return Info.Ports[i]; } return null; @@ -178,7 +179,7 @@ namespace OpenRA.Mods.Common.Traits public IEnumerable Render(Actor self, WorldRenderer wr) { - var pal = wr.Palette(info.MuzzlePalette); + var pal = wr.Palette(Info.MuzzlePalette); // Display muzzle flashes foreach (var m in muzzles) diff --git a/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs b/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs index 5f9e256b9b..b42b07b96e 100644 --- a/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs +++ b/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs @@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.Traits if (garrison != null) { var bodyOrientation = coords.Value.QuantizeOrientation(self, self.Orientation); - foreach (var p in garrison.Ports) + foreach (var p in garrison.Info.Ports) { var pos = self.CenterPosition + coords.Value.LocalToWorld(p.Offset.Rotate(bodyOrientation)); var da = coords.Value.LocalToWorld(new WVec(224, 0, 0).Rotate(WRot.FromYaw(p.Yaw + p.Cone)).Rotate(bodyOrientation));