Cache WeaponInfo look-ups

This commit is contained in:
atlimit8
2015-10-03 22:29:40 -05:00
parent f2f2fd8871
commit 49d7604bd9
12 changed files with 82 additions and 53 deletions

View File

@@ -35,12 +35,10 @@ namespace OpenRA.Mods.Common.Activities
{
if (self.CenterPosition.Z <= 0)
{
if (info.Explosion != null)
if (info.ExplosionWeapon != null)
{
var weapon = self.World.Map.Rules.Weapons[info.Explosion.ToLowerInvariant()];
// Use .FromPos since this actor is killed. Cannot use Target.FromActor
weapon.Impact(Target.FromPos(self.CenterPosition), self, Enumerable.Empty<int>());
info.ExplosionWeapon.Impact(Target.FromPos(self.CenterPosition), self, Enumerable.Empty<int>());
}
self.Dispose();

View File

@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.Effects
{
readonly Player firedBy;
readonly Animation anim;
readonly string weapon;
readonly WeaponInfo weapon;
readonly string flashType;
readonly WPos ascendSource;
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.Effects
WPos pos;
int ticks;
public NukeLaunch(Player firedBy, string weapon, WPos launchPos, WPos targetPos, WDist velocity, int delay, bool skipAscent, string flashType)
public NukeLaunch(Player firedBy, string name, WeaponInfo weapon, WPos launchPos, WPos targetPos, WDist velocity, int delay, bool skipAscent, string flashType)
{
this.firedBy = firedBy;
this.weapon = weapon;
@@ -49,13 +49,12 @@ namespace OpenRA.Mods.Common.Effects
descendSource = targetPos + offset;
descendTarget = targetPos;
anim = new Animation(firedBy.World, weapon);
anim = new Animation(firedBy.World, name);
anim.PlayRepeating("up");
pos = launchPos;
var weaponRules = firedBy.World.Map.Rules.Weapons[weapon.ToLowerInvariant()];
if (weaponRules.Report != null && weaponRules.Report.Any())
Game.Sound.Play(weaponRules.Report.Random(firedBy.World.SharedRandom), pos);
if (weapon.Report != null && weapon.Report.Any())
Game.Sound.Play(weapon.Report.Random(firedBy.World.SharedRandom), pos);
if (skipAscent)
ticks = turn;
@@ -82,7 +81,6 @@ namespace OpenRA.Mods.Common.Effects
void Explode(World world)
{
world.AddFrameEndTask(w => w.Remove(this));
var weapon = world.Map.Rules.Weapons[this.weapon.ToLowerInvariant()];
weapon.Impact(Target.FromPos(pos), firedBy.PlayerActor, Enumerable.Empty<int>());
world.WorldActor.Trait<ScreenShaker>().AddEffect(20, pos, 5);

View File

@@ -16,7 +16,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Causes aircraft husks that are spawned in the air to crash to the ground.")]
public class FallsToEarthInfo : ITraitInfo
public class FallsToEarthInfo : ITraitInfo, IRulesetLoaded
{
[WeaponReference]
public readonly string Explosion = "UnitExplode";
@@ -25,7 +25,13 @@ namespace OpenRA.Mods.Common.Traits
public readonly bool Moves = false;
public readonly WDist Velocity = new WDist(43);
public WeaponInfo ExplosionWeapon { get; private set; }
public object Create(ActorInitializer init) { return new FallsToEarth(init.Self, this); }
public void RulesetLoaded(Ruleset rules, ActorInfo ai)
{
ExplosionWeapon = string.IsNullOrEmpty(Explosion) ? null : rules.Weapons[Explosion.ToLowerInvariant()];
}
}
public class FallsToEarth

View File

@@ -12,13 +12,14 @@ using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Effects;
using OpenRA.GameRules;
using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
class BridgeInfo : ITraitInfo, Requires<HealthInfo>, Requires<BuildingInfo>
class BridgeInfo : ITraitInfo, IRulesetLoaded, Requires<HealthInfo>, Requires<BuildingInfo>
{
public readonly bool Long = false;
@@ -41,8 +42,12 @@ namespace OpenRA.Mods.Common.Traits
[Desc("The name of the weapon to use when demolishing the bridge")]
[WeaponReference] public readonly string DemolishWeapon = "Demolish";
public WeaponInfo DemolishWeaponInfo { get; private set; }
public object Create(ActorInitializer init) { return new Bridge(init.Self, this); }
public void RulesetLoaded(Ruleset rules, ActorInfo ai) { DemolishWeaponInfo = rules.Weapons[DemolishWeapon.ToLowerInvariant()]; }
public IEnumerable<Pair<ushort, int>> Templates
{
get
@@ -333,10 +338,8 @@ namespace OpenRA.Mods.Common.Traits
var initialDamage = health.DamageState;
self.World.AddFrameEndTask(w =>
{
var weapon = saboteur.World.Map.Rules.Weapons[info.DemolishWeapon.ToLowerInvariant()];
// Use .FromPos since this actor is killed. Cannot use Target.FromActor
weapon.Impact(Target.FromPos(self.CenterPosition), saboteur, Enumerable.Empty<int>());
info.DemolishWeaponInfo.Impact(Target.FromPos(self.CenterPosition), saboteur, Enumerable.Empty<int>());
self.World.WorldActor.Trait<ScreenShaker>().AddEffect(15, self.CenterPosition, 6);
self.Kill(saboteur);

View File

@@ -11,13 +11,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.GameRules;
using OpenRA.Mods.Common.Warheads;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("This actor explodes when killed.")]
public class ExplodesInfo : ITraitInfo
public class ExplodesInfo : ITraitInfo, IRulesetLoaded
{
[WeaponReference, FieldLoader.Require, Desc("Weapon to use for explosion if ammo/payload is loaded.")]
public readonly string Weapon = "UnitExplode";
@@ -34,7 +35,15 @@ namespace OpenRA.Mods.Common.Traits
[Desc("DeathType(s) to apply upon explosion.")]
public readonly HashSet<string> DeathType = new HashSet<string>();
public WeaponInfo WeaponInfo { get; private set; }
public WeaponInfo EmptyWeaponInfo { get; private set; }
public object Create(ActorInitializer init) { return new Explodes(this); }
public void RulesetLoaded(Ruleset rules, ActorInfo ai)
{
WeaponInfo = string.IsNullOrEmpty(Weapon) ? null : rules.Weapons[Weapon.ToLowerInvariant()];
EmptyWeaponInfo = string.IsNullOrEmpty(EmptyWeapon) ? null : rules.Weapons[EmptyWeapon.ToLowerInvariant()];
}
}
public class Explodes : INotifyKilled
@@ -55,15 +64,10 @@ namespace OpenRA.Mods.Common.Traits
if (info.DeathType.Count > 0 && warhead != null && !warhead.DamageTypes.Overlaps(info.DeathType))
return;
var weaponName = ChooseWeaponForExplosion(self);
if (string.IsNullOrEmpty(weaponName))
var weapon = ChooseWeaponForExplosion(self);
if (weapon == null)
return;
if (!e.Attacker.World.Map.Rules.Weapons.ContainsKey(weaponName.ToLowerInvariant()))
throw new InvalidOperationException("Actor " + self.Info.Name
+ ": Could not find weapon '" + weaponName.ToLowerInvariant() + "', check for typos.");
var weapon = e.Attacker.World.Map.Rules.Weapons[weaponName.ToLowerInvariant()];
if (weapon.Report != null && weapon.Report.Any())
Game.Sound.Play(weapon.Report.Random(e.Attacker.World.SharedRandom), self.CenterPosition);
@@ -71,11 +75,11 @@ namespace OpenRA.Mods.Common.Traits
weapon.Impact(Target.FromPos(self.CenterPosition), e.Attacker, Enumerable.Empty<int>());
}
string ChooseWeaponForExplosion(Actor self)
WeaponInfo ChooseWeaponForExplosion(Actor self)
{
var shouldExplode = self.TraitsImplementing<IExplodeModifier>().All(a => a.ShouldExplode(self));
var useFullExplosion = self.World.SharedRandom.Next(100) <= info.LoadedChance;
return (shouldExplode && useFullExplosion) ? info.Weapon : info.EmptyWeapon;
return (shouldExplode && useFullExplosion) ? info.WeaponInfo : info.EmptyWeaponInfo;
}
}
}

View File

@@ -10,6 +10,7 @@
using System;
using OpenRA.Effects;
using OpenRA.GameRules;
using OpenRA.Mods.Common.Activities;
using OpenRA.Mods.Common.Effects;
using OpenRA.Primitives;
@@ -17,7 +18,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
class NukePowerInfo : SupportPowerInfo, Requires<BodyOrientationInfo>
class NukePowerInfo : SupportPowerInfo, IRulesetLoaded, Requires<BodyOrientationInfo>
{
[WeaponReference]
public readonly string MissileWeapon = "";
@@ -51,7 +52,10 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Sequence the launching actor should play when activating this power.")]
public readonly string ActivationSequence = "active";
public WeaponInfo WeaponInfo { get; private set; }
public override object Create(ActorInitializer init) { return new NukePower(init.Self, this); }
public void RulesetLoaded(Ruleset rules, ActorInfo ai) { WeaponInfo = rules.Weapons[MissileWeapon.ToLowerInvariant()]; }
}
class NukePower : SupportPower
@@ -82,7 +86,7 @@ namespace OpenRA.Mods.Common.Traits
}
var targetPosition = self.World.Map.CenterOfCell(order.TargetLocation);
var missile = new NukeLaunch(self.Owner, info.MissileWeapon,
var missile = new NukeLaunch(self.Owner, info.MissileWeapon, info.WeaponInfo,
self.CenterPosition + body.LocalToWorld(info.SpawnOffset),
targetPosition,
info.FlightVelocity, info.FlightDelay, info.SkipAscent,

View File

@@ -15,13 +15,20 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Throws particles when the actor is destroyed that do damage on impact.")]
public class ThrowsShrapnelInfo : ITraitInfo
public class ThrowsShrapnelInfo : ITraitInfo, IRulesetLoaded
{
[WeaponReference, FieldLoader.Require]
public string[] Weapons = { };
public int[] Pieces = { 3, 10 };
public WDist[] Range = { WDist.FromCells(2), WDist.FromCells(5) };
public WeaponInfo[] WeaponInfos { get; private set; }
public object Create(ActorInitializer actor) { return new ThrowsShrapnel(this); }
public void RulesetLoaded(Ruleset rules, ActorInfo ai)
{
WeaponInfos = Weapons.Select(w => rules.Weapons[w.ToLowerInvariant()]).ToArray();
}
}
class ThrowsShrapnel : INotifyKilled
@@ -35,9 +42,8 @@ namespace OpenRA.Mods.Common.Traits
public void Killed(Actor self, AttackInfo attack)
{
foreach (var name in info.Weapons)
foreach (var wep in info.WeaponInfos)
{
var wep = self.World.Map.Rules.Weapons[name.ToLowerInvariant()];
var pieces = self.World.SharedRandom.Next(info.Pieces[0], info.Pieces[1]);
var range = self.World.SharedRandom.Next(info.Range[0].Length, info.Range[1].Length);