Merge pull request #9447 from atlimit8/CacheFireportsForAttackGarrisoned
Cache AttackGarrisoned fire ports using IRulesetLoaded
This commit is contained in:
@@ -46,7 +46,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
public static Func<string, Type, string, object> InvalidValueAction = (s, t, f) =>
|
public static Func<string, Type, string, object> 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<string, Type> UnknownFieldAction = (s, f) =>
|
public static Action<string, Type> UnknownFieldAction = (s, f) =>
|
||||||
|
|||||||
@@ -102,6 +102,10 @@ namespace OpenRA.FileFormats
|
|||||||
{
|
{
|
||||||
return new ReplayMetadata(fs, path);
|
return new ReplayMetadata(fs, path);
|
||||||
}
|
}
|
||||||
|
catch (YamlException ex)
|
||||||
|
{
|
||||||
|
Log.Write("debug", ex.ToString());
|
||||||
|
}
|
||||||
catch (InvalidOperationException ex)
|
catch (InvalidOperationException ex)
|
||||||
{
|
{
|
||||||
Log.Write("debug", ex.ToString());
|
Log.Write("debug", ex.ToString());
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
catch (InvalidOperationException)
|
catch (YamlException)
|
||||||
{
|
{
|
||||||
Log.Write("debug", "GameInformation deserialized invalid MiniYaml:\n{0}".F(data));
|
Log.Write("debug", "GameInformation deserialized invalid MiniYaml:\n{0}".F(data));
|
||||||
throw;
|
throw;
|
||||||
|
|||||||
@@ -44,9 +44,39 @@ namespace OpenRA
|
|||||||
Sequences = new ReadOnlyDictionary<string, SequenceProvider>(sequences);
|
Sequences = new ReadOnlyDictionary<string, SequenceProvider>(sequences);
|
||||||
|
|
||||||
foreach (var a in Actors.Values)
|
foreach (var a in Actors.Values)
|
||||||
|
{
|
||||||
foreach (var t in a.TraitInfos<IRulesetLoaded>())
|
foreach (var t in a.TraitInfos<IRulesetLoaded>())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
t.RulesetLoaded(this, a);
|
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<WeaponInfo>;
|
||||||
|
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<KeyValuePair<string, MusicInfo>> InstalledMusic { get { return Music.Where(m => m.Value.Exists); } }
|
public IEnumerable<KeyValuePair<string, MusicInfo>> InstalledMusic { get { return Music.Where(m => m.Value.Exists); } }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,9 +59,13 @@ namespace OpenRA.Network
|
|||||||
|
|
||||||
return session;
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -369,5 +369,6 @@ namespace OpenRA.Traits
|
|||||||
bool RemoveActor(Actor self, Player owner);
|
bool RemoveActor(Actor self, Player owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IRulesetLoaded : ITraitInfo { void RulesetLoaded(Ruleset rules, ActorInfo ai); }
|
public interface IRulesetLoaded<TInfo> { void RulesetLoaded(Ruleset rules, TInfo info); }
|
||||||
|
public interface IRulesetLoaded : IRulesetLoaded<ActorInfo>, ITraitInfo { }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Desc("Cargo can fire their weapons out of fire ports.")]
|
[Desc("Cargo can fire their weapons out of fire ports.")]
|
||||||
public class AttackGarrisonedInfo : AttackFollowInfo, Requires<CargoInfo>
|
public class AttackGarrisonedInfo : AttackFollowInfo, IRulesetLoaded, Requires<CargoInfo>
|
||||||
{
|
{
|
||||||
[FieldLoader.Require]
|
[FieldLoader.Require]
|
||||||
[Desc("Fire port offsets in local coordinates.")]
|
[Desc("Fire port offsets in local coordinates.")]
|
||||||
@@ -39,16 +39,39 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
[Desc("Fire port yaw cone angle.")]
|
[Desc("Fire port yaw cone angle.")]
|
||||||
public readonly WAngle[] PortCones = null;
|
public readonly WAngle[] PortCones = null;
|
||||||
|
|
||||||
|
public FirePort[] Ports { get; private set; }
|
||||||
|
|
||||||
[PaletteReference] public readonly string MuzzlePalette = "effect";
|
[PaletteReference] public readonly string MuzzlePalette = "effect";
|
||||||
|
|
||||||
public override object Create(ActorInitializer init) { return new AttackGarrisoned(init.Self, this); }
|
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 class AttackGarrisoned : AttackFollow, INotifyPassengerEntered, INotifyPassengerExited, IRender
|
||||||
{
|
{
|
||||||
public readonly FirePort[] Ports;
|
public readonly new AttackGarrisonedInfo Info;
|
||||||
|
|
||||||
AttackGarrisonedInfo info;
|
|
||||||
Lazy<BodyOrientation> coords;
|
Lazy<BodyOrientation> coords;
|
||||||
List<Armament> armaments;
|
List<Armament> armaments;
|
||||||
List<AnimationWithOffset> muzzles;
|
List<AnimationWithOffset> muzzles;
|
||||||
@@ -59,7 +82,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public AttackGarrisoned(Actor self, AttackGarrisonedInfo info)
|
public AttackGarrisoned(Actor self, AttackGarrisonedInfo info)
|
||||||
: base(self, info)
|
: base(self, info)
|
||||||
{
|
{
|
||||||
this.info = info;
|
this.Info = info;
|
||||||
coords = Exts.Lazy(() => self.Trait<BodyOrientation>());
|
coords = Exts.Lazy(() => self.Trait<BodyOrientation>());
|
||||||
armaments = new List<Armament>();
|
armaments = new List<Armament>();
|
||||||
muzzles = new List<AnimationWithOffset>();
|
muzzles = new List<AnimationWithOffset>();
|
||||||
@@ -68,28 +91,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
paxRender = new Dictionary<Actor, RenderSprites>();
|
paxRender = new Dictionary<Actor, RenderSprites>();
|
||||||
|
|
||||||
getArmaments = () => armaments;
|
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<FirePort>();
|
|
||||||
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)
|
public void PassengerEntered(Actor self, Actor passenger)
|
||||||
@@ -99,7 +100,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
paxRender.Add(passenger, passenger.Trait<RenderSprites>());
|
paxRender.Add(passenger, passenger.Trait<RenderSprites>());
|
||||||
armaments.AddRange(
|
armaments.AddRange(
|
||||||
passenger.TraitsImplementing<Armament>()
|
passenger.TraitsImplementing<Armament>()
|
||||||
.Where(a => info.Armaments.Contains(a.Info.Name)));
|
.Where(a => Info.Armaments.Contains(a.Info.Name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PassengerExited(Actor self, Actor passenger)
|
public void PassengerExited(Actor self, Actor passenger)
|
||||||
@@ -114,14 +115,14 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
// Pick a random port that faces the target
|
// Pick a random port that faces the target
|
||||||
var bodyYaw = facing.Value != null ? WAngle.FromFacing(facing.Value.Facing) : WAngle.Zero;
|
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)
|
foreach (var i in indices)
|
||||||
{
|
{
|
||||||
var yaw = bodyYaw + Ports[i].Yaw;
|
var yaw = bodyYaw + Info.Ports[i].Yaw;
|
||||||
var leftTurn = (yaw - targetYaw).Angle;
|
var leftTurn = (yaw - targetYaw).Angle;
|
||||||
var rightTurn = (targetYaw - yaw).Angle;
|
var rightTurn = (targetYaw - yaw).Angle;
|
||||||
if (Math.Min(leftTurn, rightTurn) <= Ports[i].Cone.Angle)
|
if (Math.Min(leftTurn, rightTurn) <= Info.Ports[i].Cone.Angle)
|
||||||
return Ports[i];
|
return Info.Ports[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -178,7 +179,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public IEnumerable<IRenderable> Render(Actor self, WorldRenderer wr)
|
public IEnumerable<IRenderable> Render(Actor self, WorldRenderer wr)
|
||||||
{
|
{
|
||||||
var pal = wr.Palette(info.MuzzlePalette);
|
var pal = wr.Palette(Info.MuzzlePalette);
|
||||||
|
|
||||||
// Display muzzle flashes
|
// Display muzzle flashes
|
||||||
foreach (var m in muzzles)
|
foreach (var m in muzzles)
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (garrison != null)
|
if (garrison != null)
|
||||||
{
|
{
|
||||||
var bodyOrientation = coords.Value.QuantizeOrientation(self, self.Orientation);
|
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 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));
|
var da = coords.Value.LocalToWorld(new WVec(224, 0, 0).Rotate(WRot.FromYaw(p.Yaw + p.Cone)).Rotate(bodyOrientation));
|
||||||
|
|||||||
Reference in New Issue
Block a user