diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index d60af0d190..973ee5b574 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -31,7 +31,8 @@ namespace OpenRA.GameRules public Target GuidedTarget; } - public interface IProjectileInfo { IEffect Create(ProjectileArgs args); } + public interface IProjectile : IEffect { } + public interface IProjectileInfo { IProjectile Create(ProjectileArgs args); } public sealed class WeaponInfo { diff --git a/OpenRA.Game/Network/SyncReport.cs b/OpenRA.Game/Network/SyncReport.cs index 3cb7bd2b16..4dc3ce1ec8 100644 --- a/OpenRA.Game/Network/SyncReport.cs +++ b/OpenRA.Game/Network/SyncReport.cs @@ -77,20 +77,16 @@ namespace OpenRA.Network NamesValues = DumpSyncTrait(syncHash.Trait) }); - foreach (var e in orderManager.World.Effects) + foreach (var sync in orderManager.World.SyncedEffects) { - var sync = e as ISync; - if (sync != null) - { - var hash = Sync.Hash(sync); - if (hash != 0) - report.Effects.Add(new EffectReport() - { - Name = sync.GetType().Name, - Hash = hash, - NamesValues = DumpSyncTrait(sync) - }); - } + var hash = Sync.Hash(sync); + if (hash != 0) + report.Effects.Add(new EffectReport() + { + Name = sync.GetType().Name, + Hash = hash, + NamesValues = DumpSyncTrait(sync) + }); } } diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index c358be5dab..cc8b3393ae 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -14,6 +14,7 @@ using System.Collections.Generic; using System.Linq; using OpenRA.Effects; using OpenRA.FileFormats; +using OpenRA.GameRules; using OpenRA.Graphics; using OpenRA.Network; using OpenRA.Orders; @@ -30,6 +31,8 @@ namespace OpenRA internal readonly TraitDictionary TraitDict = new TraitDictionary(); readonly SortedDictionary actors = new SortedDictionary(); readonly List effects = new List(); + readonly List syncedEffects = new List(); + readonly Queue> frameEndActions = new Queue>(); public int Timestep; @@ -272,9 +275,27 @@ namespace OpenRA t.RemovedFromWorld(a); } - public void Add(IEffect b) { effects.Add(b); } - public void Remove(IEffect b) { effects.Remove(b); } - public void RemoveAll(Predicate predicate) { effects.RemoveAll(predicate); } + public void Add(IEffect e) + { + effects.Add(e); + var se = e as ISync; + if (se != null) + syncedEffects.Add(se); + } + + public void Remove(IEffect e) + { + effects.Remove(e); + var se = e as ISync; + if (se != null) + syncedEffects.Remove(se); + } + + public void RemoveAll(Predicate predicate) + { + effects.RemoveAll(predicate); + syncedEffects.RemoveAll(e => predicate((IEffect)e)); + } public void AddFrameEndTask(Action a) { frameEndActions.Enqueue(a); } @@ -334,6 +355,7 @@ namespace OpenRA public IEnumerable Actors { get { return actors.Values; } } public IEnumerable Effects { get { return effects; } } + public IEnumerable SyncedEffects { get { return syncedEffects; } } public Actor GetActorById(uint actorId) { @@ -356,24 +378,20 @@ namespace OpenRA var n = 0; var ret = 0; - // hash all the actors + // Hash all the actors. foreach (var a in Actors) ret += n++ * (int)(1 + a.ActorID) * Sync.HashActor(a); - // hash all the traits that tick + // Hash all the traits that tick. foreach (var actor in ActorsHavingTrait()) foreach (var syncHash in actor.SyncHashes) ret += n++ * (int)(1 + actor.ActorID) * syncHash.Hash; - // TODO: don't go over all effects - foreach (var e in Effects) - { - var sync = e as ISync; - if (sync != null) - ret += n++ * Sync.Hash(sync); - } + // Hash game state relevant effects such as projectiles. + foreach (var sync in SyncedEffects) + ret += n++ * Sync.Hash(sync); - // Hash the shared rng + // Hash the shared random number generator. ret += SharedRandom.Last; return ret; diff --git a/OpenRA.Mods.Cnc/Effects/IonCannon.cs b/OpenRA.Mods.Cnc/Effects/IonCannon.cs index c00aad2d79..e710ebf7f9 100644 --- a/OpenRA.Mods.Cnc/Effects/IonCannon.cs +++ b/OpenRA.Mods.Cnc/Effects/IonCannon.cs @@ -18,7 +18,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Cnc.Effects { - public class IonCannon : IEffect + public class IonCannon : IProjectile { readonly Target target; readonly Animation anim; diff --git a/OpenRA.Mods.Common/Effects/NukeLaunch.cs b/OpenRA.Mods.Common/Effects/NukeLaunch.cs index eec0589d93..f8f0ce1be3 100644 --- a/OpenRA.Mods.Common/Effects/NukeLaunch.cs +++ b/OpenRA.Mods.Common/Effects/NukeLaunch.cs @@ -19,7 +19,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Effects { - public class NukeLaunch : IEffect + public class NukeLaunch : IProjectile { readonly Player firedBy; readonly Animation anim; diff --git a/OpenRA.Mods.Common/Projectiles/AreaBeam.cs b/OpenRA.Mods.Common/Projectiles/AreaBeam.cs index 5e38dd48f8..1f72ab7c96 100644 --- a/OpenRA.Mods.Common/Projectiles/AreaBeam.cs +++ b/OpenRA.Mods.Common/Projectiles/AreaBeam.cs @@ -69,14 +69,14 @@ namespace OpenRA.Mods.Common.Projectiles [Desc("Beam color is the player's color.")] public readonly bool UsePlayerColor = false; - public IEffect Create(ProjectileArgs args) + public IProjectile Create(ProjectileArgs args) { var c = UsePlayerColor ? args.SourceActor.Owner.Color.RGB : Color; return new AreaBeam(this, args, c); } } - public class AreaBeam : IEffect, ISync + public class AreaBeam : IProjectile, ISync { readonly AreaBeamInfo info; readonly ProjectileArgs args; diff --git a/OpenRA.Mods.Common/Projectiles/Bullet.cs b/OpenRA.Mods.Common/Projectiles/Bullet.cs index ba1aebdc4a..3d4685a9b9 100644 --- a/OpenRA.Mods.Common/Projectiles/Bullet.cs +++ b/OpenRA.Mods.Common/Projectiles/Bullet.cs @@ -82,10 +82,10 @@ namespace OpenRA.Mods.Common.Projectiles public readonly int ContrailDelay = 1; public readonly WDist ContrailWidth = new WDist(64); - public IEffect Create(ProjectileArgs args) { return new Bullet(this, args); } + public IProjectile Create(ProjectileArgs args) { return new Bullet(this, args); } } - public class Bullet : IEffect, ISync + public class Bullet : IProjectile, ISync { readonly BulletInfo info; readonly ProjectileArgs args; diff --git a/OpenRA.Mods.Common/Projectiles/GravityBomb.cs b/OpenRA.Mods.Common/Projectiles/GravityBomb.cs index 1d1589d6fa..90204d18da 100644 --- a/OpenRA.Mods.Common/Projectiles/GravityBomb.cs +++ b/OpenRA.Mods.Common/Projectiles/GravityBomb.cs @@ -39,10 +39,10 @@ namespace OpenRA.Mods.Common.Projectiles [Desc("Value added to speed every tick.")] public readonly WDist Acceleration = new WDist(15); - public IEffect Create(ProjectileArgs args) { return new GravityBomb(this, args); } + public IProjectile Create(ProjectileArgs args) { return new GravityBomb(this, args); } } - public class GravityBomb : IEffect, ISync + public class GravityBomb : IProjectile, ISync { readonly GravityBombInfo info; readonly Animation anim; diff --git a/OpenRA.Mods.Common/Projectiles/LaserZap.cs b/OpenRA.Mods.Common/Projectiles/LaserZap.cs index c5928ffa17..2819396213 100644 --- a/OpenRA.Mods.Common/Projectiles/LaserZap.cs +++ b/OpenRA.Mods.Common/Projectiles/LaserZap.cs @@ -47,14 +47,14 @@ namespace OpenRA.Mods.Common.Projectiles [PaletteReference] public readonly string HitAnimPalette = "effect"; - public IEffect Create(ProjectileArgs args) + public IProjectile Create(ProjectileArgs args) { var c = UsePlayerColor ? args.SourceActor.Owner.Color.RGB : Color; return new LaserZap(args, this, c); } } - public class LaserZap : IEffect + public class LaserZap : IProjectile { readonly ProjectileArgs args; readonly LaserZapInfo info; diff --git a/OpenRA.Mods.Common/Projectiles/Missile.cs b/OpenRA.Mods.Common/Projectiles/Missile.cs index cfdd9b2c20..b3fd256085 100644 --- a/OpenRA.Mods.Common/Projectiles/Missile.cs +++ b/OpenRA.Mods.Common/Projectiles/Missile.cs @@ -141,11 +141,11 @@ namespace OpenRA.Mods.Common.Projectiles "not trigger fast enough, causing the missile to fly past the target.")] public readonly WDist CloseEnough = new WDist(298); - public IEffect Create(ProjectileArgs args) { return new Missile(this, args); } + public IProjectile Create(ProjectileArgs args) { return new Missile(this, args); } } // TODO: double check square roots!!! - public class Missile : IEffect, ISync + public class Missile : IProjectile, ISync { enum States { diff --git a/OpenRA.Mods.RA/Projectiles/TeslaZap.cs b/OpenRA.Mods.RA/Projectiles/TeslaZap.cs index 63995f222d..8b7302e809 100644 --- a/OpenRA.Mods.RA/Projectiles/TeslaZap.cs +++ b/OpenRA.Mods.RA/Projectiles/TeslaZap.cs @@ -32,10 +32,10 @@ namespace OpenRA.Mods.RA.Projectiles public readonly int Duration = 2; - public IEffect Create(ProjectileArgs args) { return new TeslaZap(this, args); } + public IProjectile Create(ProjectileArgs args) { return new TeslaZap(this, args); } } - public class TeslaZap : IEffect + public class TeslaZap : IProjectile { readonly ProjectileArgs args; readonly TeslaZapInfo info;