smart queries for World.Actors
This commit is contained in:
54
OpenRa.FileFormats/Collections/Set.cs
Executable file
54
OpenRa.FileFormats/Collections/Set.cs
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using IjwFramework.Types;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace OpenRa.Collections
|
||||||
|
{
|
||||||
|
public class Set<T> : IEnumerable<T>
|
||||||
|
{
|
||||||
|
Dictionary<T, bool> data = new Dictionary<T, bool>();
|
||||||
|
|
||||||
|
public void Add( T obj )
|
||||||
|
{
|
||||||
|
data.Add( obj, false );
|
||||||
|
if( OnAdd != null )
|
||||||
|
OnAdd( obj );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove( T obj )
|
||||||
|
{
|
||||||
|
data.Remove( obj );
|
||||||
|
if( OnRemove != null )
|
||||||
|
OnRemove( obj );
|
||||||
|
}
|
||||||
|
|
||||||
|
public event Action<T> OnAdd;
|
||||||
|
public event Action<T> OnRemove;
|
||||||
|
|
||||||
|
public IEnumerator<T> GetEnumerator()
|
||||||
|
{
|
||||||
|
return data.Keys.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CachedView<T,U> : Set<U>
|
||||||
|
{
|
||||||
|
public CachedView( Set<T> set, Func<T,bool> include, Func<T,U> store )
|
||||||
|
{
|
||||||
|
foreach( var t in set )
|
||||||
|
if( include( t ) )
|
||||||
|
Add( store( t ) );
|
||||||
|
|
||||||
|
set.OnAdd += obj => { if( include( obj ) ) Add( store( obj ) ); };
|
||||||
|
set.OnRemove += obj => { if( include( obj ) ) Remove( store( obj ) ); };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -51,6 +51,7 @@
|
|||||||
<Compile Include="AudLoader.cs" />
|
<Compile Include="AudLoader.cs" />
|
||||||
<Compile Include="Blowfish.cs" />
|
<Compile Include="Blowfish.cs" />
|
||||||
<Compile Include="BlowfishKeyProvider.cs" />
|
<Compile Include="BlowfishKeyProvider.cs" />
|
||||||
|
<Compile Include="Collections\Set.cs" />
|
||||||
<Compile Include="DisposableAction.cs" />
|
<Compile Include="DisposableAction.cs" />
|
||||||
<Compile Include="Dune2ShpReader.cs" />
|
<Compile Include="Dune2ShpReader.cs" />
|
||||||
<Compile Include="Exts.cs" />
|
<Compile Include="Exts.cs" />
|
||||||
|
|||||||
@@ -196,5 +196,16 @@ namespace OpenRa
|
|||||||
{
|
{
|
||||||
return currentActivity;
|
return currentActivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return (int)ActorID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals( object obj )
|
||||||
|
{
|
||||||
|
var o = obj as Actor;
|
||||||
|
return ( o != null && o.ActorID == ActorID );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -503,9 +503,9 @@ namespace OpenRa
|
|||||||
|
|
||||||
void DrawRadar( World world )
|
void DrawRadar( World world )
|
||||||
{
|
{
|
||||||
var hasNewRadar = world.Actors.Any(a => a.Owner == world.LocalPlayer
|
var hasNewRadar = world.Queries.OwnedBy[world.LocalPlayer]
|
||||||
&& a.traits.Contains<ProvidesRadar>()
|
.WithTrait<ProvidesRadar>()
|
||||||
&& a.traits.Get<ProvidesRadar>().IsActive);
|
.Any(a => a.Trait.IsActive);
|
||||||
|
|
||||||
if (hasNewRadar != hasRadar)
|
if (hasNewRadar != hasRadar)
|
||||||
{
|
{
|
||||||
@@ -661,7 +661,7 @@ namespace OpenRa
|
|||||||
Rectangle repairRect = new Rectangle(buttonOrigin.X, buttonOrigin.Y, repairButton.Image.bounds.Width, repairButton.Image.bounds.Height);
|
Rectangle repairRect = new Rectangle(buttonOrigin.X, buttonOrigin.Y, repairButton.Image.bounds.Width, repairButton.Image.bounds.Height);
|
||||||
var repairDrawPos = new float2(repairRect.Location);
|
var repairDrawPos = new float2(repairRect.Location);
|
||||||
|
|
||||||
var hasFact = world.Actors.Any(a => a.Owner == world.LocalPlayer && a.traits.Contains<ConstructionYard>());
|
var hasFact = world.Queries.OwnedBy[world.LocalPlayer].WithTrait<ConstructionYard>().Any();
|
||||||
|
|
||||||
if (Game.Settings.RepairRequiresConyard && !hasFact)
|
if (Game.Settings.RepairRequiresConyard && !hasFact)
|
||||||
repairButton.ReplaceAnim("disabled");
|
repairButton.ReplaceAnim("disabled");
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace OpenRa.GameRules
|
|||||||
public Cache<string, List<Actor>> GatherBuildings( Player player )
|
public Cache<string, List<Actor>> GatherBuildings( Player player )
|
||||||
{
|
{
|
||||||
var ret = new Cache<string, List<Actor>>( x => new List<Actor>() );
|
var ret = new Cache<string, List<Actor>>( x => new List<Actor>() );
|
||||||
foreach( var b in player.World.Actors.Where( x => x.Owner == player && x.Info.Traits.Contains<BuildingInfo>() ) )
|
foreach( var b in player.World.Queries.OwnedBy[player].Where( x=>x.Info.Traits.Contains<BuildingInfo>() ) )
|
||||||
{
|
{
|
||||||
ret[ b.Info.Name ].Add( b );
|
ret[ b.Info.Name ].Add( b );
|
||||||
var buildable = b.Info.Traits.GetOrDefault<BuildableInfo>();
|
var buildable = b.Info.Traits.GetOrDefault<BuildableInfo>();
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ namespace OpenRa.Graphics
|
|||||||
|
|
||||||
mapOnlySheet.Texture.SetData(oreLayer);
|
mapOnlySheet.Texture.SetData(oreLayer);
|
||||||
|
|
||||||
if (!world.Actors.Any(a => a.Owner == world.LocalPlayer && a.traits.Contains<ProvidesRadar>()))
|
if (!world.Queries.OwnedBy[world.LocalPlayer].WithTrait<ProvidesRadar>().Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var bitmap = new Bitmap(oreLayer);
|
var bitmap = new Bitmap(oreLayer);
|
||||||
@@ -114,9 +114,9 @@ namespace OpenRa.Graphics
|
|||||||
(b.Owner != null ? playerColors[(int)b.Owner.Palette] : colors[4]).ToArgb();
|
(b.Owner != null ? playerColors[(int)b.Owner.Palette] : colors[4]).ToArgb();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var a in world.Actors.Where(a => a.traits.Contains<Unit>()))
|
foreach (var a in world.Queries.WithTrait<Unit>())
|
||||||
*(c + (a.Location.Y * bitmapData.Stride >> 2) + a.Location.X) =
|
*(c + (a.Actor.Location.Y * bitmapData.Stride >> 2) + a.Actor.Location.X) =
|
||||||
playerColors[(int)a.Owner.Palette].ToArgb();
|
playerColors[(int)a.Actor.Owner.Palette].ToArgb();
|
||||||
|
|
||||||
unchecked
|
unchecked
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ namespace OpenRa.Graphics
|
|||||||
|
|
||||||
public void GoToStartLocation( Player player )
|
public void GoToStartLocation( Player player )
|
||||||
{
|
{
|
||||||
Center(player.World.Actors.Where(a => a.Owner == player && a.traits.Contains<Selectable>()));
|
Center( player.World.Queries.OwnedBy[ player ].WithTrait<Selectable>().Select( a => a.Actor ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,8 +38,9 @@ namespace OpenRa.Orders
|
|||||||
if (!Game.Settings.RepairRequiresConyard)
|
if (!Game.Settings.RepairRequiresConyard)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var hasFact = world.Actors
|
var hasFact = world.Queries.OwnedBy[world.LocalPlayer]
|
||||||
.Any(a => a.Owner == world.LocalPlayer && a.traits.Contains<ConstructionYard>());
|
.WithTrait<ConstructionYard>()
|
||||||
|
.Any();
|
||||||
|
|
||||||
if (!hasFact)
|
if (!hasFact)
|
||||||
Game.controller.CancelInputMode();
|
Game.controller.CancelInputMode();
|
||||||
|
|||||||
@@ -49,12 +49,12 @@ namespace OpenRa
|
|||||||
PowerProvided = 0;
|
PowerProvided = 0;
|
||||||
PowerDrained = 0;
|
PowerDrained = 0;
|
||||||
|
|
||||||
var myBuildings = World.Actors
|
var myBuildings = World.Queries.OwnedBy[this]
|
||||||
.Where(a => a.Owner == this && a.traits.Contains<Building>());
|
.WithTrait<Building>();
|
||||||
|
|
||||||
foreach (var a in myBuildings)
|
foreach (var a in myBuildings)
|
||||||
{
|
{
|
||||||
var p = a.traits.Get<Building>().GetPowerUsage();
|
var p = a.Trait.GetPowerUsage();
|
||||||
if (p > 0)
|
if (p > 0)
|
||||||
PowerProvided += p;
|
PowerProvided += p;
|
||||||
else
|
else
|
||||||
@@ -80,8 +80,8 @@ namespace OpenRa
|
|||||||
|
|
||||||
void UpdateOreCapacity()
|
void UpdateOreCapacity()
|
||||||
{
|
{
|
||||||
OreCapacity = World.Actors
|
OreCapacity = World.Queries.OwnedBy[this]
|
||||||
.Where(a => a.Owner == this && a.traits.Contains<StoresOre>())
|
.Where(a => a.traits.Contains<StoresOre>())
|
||||||
.Select(a => a.Info.Traits.Get<StoresOreInfo>())
|
.Select(a => a.Info.Traits.Get<StoresOreInfo>())
|
||||||
.Sum(b => b.Capacity);
|
.Sum(b => b.Capacity);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ namespace OpenRa
|
|||||||
{
|
{
|
||||||
// Clear active flags
|
// Clear active flags
|
||||||
gapActive = new bool[128, 128];
|
gapActive = new bool[128, 128];
|
||||||
foreach (var a in world.Actors.Where(a => a.traits.Contains<GeneratesGap>() && owner != a.Owner))
|
foreach (var a in world.Queries.WithTrait<GeneratesGap>().Where(a => owner != a.Actor.Owner))
|
||||||
{
|
{
|
||||||
foreach (var t in a.traits.Get<GeneratesGap>().GetShroudedTiles())
|
foreach (var t in a.Trait.GetShroudedTiles())
|
||||||
gapActive[t.X, t.Y] = true;
|
gapActive[t.X, t.Y] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,9 @@ namespace OpenRa.Traits.Activities
|
|||||||
umt = mobile.GetMovementType(),
|
umt = mobile.GetMovementType(),
|
||||||
checkForBlocked = false,
|
checkForBlocked = false,
|
||||||
};
|
};
|
||||||
var refineries = self.World.Actors.Where( x => x.traits.Contains<AcceptsOre>()
|
var refineries = self.World.Queries.OwnedBy[self.Owner]
|
||||||
&& x.Owner == self.Owner ).ToList();
|
.Where( x => x.traits.Contains<AcceptsOre>())
|
||||||
|
.ToList();
|
||||||
if( refinery != null )
|
if( refinery != null )
|
||||||
search.AddInitialCell( self.World, refinery.Location + refineryDeliverOffset );
|
search.AddInitialCell( self.World, refinery.Location + refineryDeliverOffset );
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -9,9 +9,8 @@ namespace OpenRa.Traits.Activities
|
|||||||
|
|
||||||
static Actor ChooseHelipad(Actor self)
|
static Actor ChooseHelipad(Actor self)
|
||||||
{
|
{
|
||||||
return self.World.Actors.FirstOrDefault(
|
return self.World.Queries.OwnedBy[self.Owner].FirstOrDefault(
|
||||||
a => a.Info.Name == "hpad" &&
|
a => a.Info.Name == "hpad" &&
|
||||||
a.Owner == self.Owner &&
|
|
||||||
!Reservable.IsReserved(a));
|
!Reservable.IsReserved(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,8 @@ namespace OpenRa.Traits.Activities
|
|||||||
|
|
||||||
Actor ChooseAirfield(Actor self)
|
Actor ChooseAirfield(Actor self)
|
||||||
{
|
{
|
||||||
var airfield = self.World.Actors
|
var airfield = self.World.Queries.OwnedBy[self.Owner]
|
||||||
.Where(a => a.Info.Name == "afld"
|
.Where(a => a.Info.Name == "afld"
|
||||||
&& a.Owner == self.Owner
|
|
||||||
&& !Reservable.IsReserved(a))
|
&& !Reservable.IsReserved(a))
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,10 @@ namespace OpenRa.Traits
|
|||||||
if (!movement.CanEnterCell(order.TargetLocation))
|
if (!movement.CanEnterCell(order.TargetLocation))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var chronosphere = self.World.Actors.Where(a => a.Owner == self.Owner
|
var chronosphere = self.World.Queries
|
||||||
&& a.traits.Contains<Chronosphere>()).FirstOrDefault();
|
.OwnedBy[self.Owner]
|
||||||
|
.WithTrait<Chronosphere>()
|
||||||
|
.Select(x=>x.Actor).FirstOrDefault();
|
||||||
|
|
||||||
bool success = order.TargetActor.traits.Get<Chronoshiftable>().Activate(order.TargetActor,
|
bool success = order.TargetActor.traits.Get<Chronoshiftable>().Activate(order.TargetActor,
|
||||||
order.TargetLocation,
|
order.TargetLocation,
|
||||||
@@ -60,8 +62,8 @@ namespace OpenRa.Traits
|
|||||||
Sound.Play("chrono2.aud");
|
Sound.Play("chrono2.aud");
|
||||||
|
|
||||||
// Trigger screen desaturate effect
|
// Trigger screen desaturate effect
|
||||||
foreach (var a in self.World.Actors.Where(a => a.traits.Contains<ChronoshiftPaletteEffect>()))
|
foreach (var a in self.World.Queries.WithTrait<ChronoshiftPaletteEffect>())
|
||||||
a.traits.Get<ChronoshiftPaletteEffect>().DoChronoshift();
|
a.Trait.DoChronoshift();
|
||||||
|
|
||||||
if (chronosphere != null)
|
if (chronosphere != null)
|
||||||
chronosphere.traits.Get<RenderBuilding>().PlayCustomAnim(chronosphere, "active");
|
chronosphere.traits.Get<RenderBuilding>().PlayCustomAnim(chronosphere, "active");
|
||||||
@@ -98,8 +100,9 @@ namespace OpenRa.Traits
|
|||||||
|
|
||||||
public void Tick( World world )
|
public void Tick( World world )
|
||||||
{
|
{
|
||||||
var hasChronosphere = world.Actors
|
var hasChronosphere = world.Queries.OwnedBy[world.LocalPlayer]
|
||||||
.Any(a => a.Owner == world.LocalPlayer && a.traits.Contains<Chronosphere>());
|
.WithTrait<Chronosphere>()
|
||||||
|
.Any();
|
||||||
|
|
||||||
if (!hasChronosphere)
|
if (!hasChronosphere)
|
||||||
Game.controller.CancelInputMode();
|
Game.controller.CancelInputMode();
|
||||||
@@ -135,8 +138,9 @@ namespace OpenRa.Traits
|
|||||||
|
|
||||||
public void Tick(World world)
|
public void Tick(World world)
|
||||||
{
|
{
|
||||||
var hasChronosphere = world.Actors
|
var hasChronosphere = world.Queries.OwnedBy[world.LocalPlayer]
|
||||||
.Any(a => a.Owner == world.LocalPlayer && a.traits.Contains<Chronosphere>());
|
.WithTrait<Chronosphere>()
|
||||||
|
.Any();
|
||||||
|
|
||||||
if (!hasChronosphere)
|
if (!hasChronosphere)
|
||||||
Game.controller.CancelInputMode();
|
Game.controller.CancelInputMode();
|
||||||
|
|||||||
@@ -26,8 +26,9 @@ namespace OpenRa.Traits
|
|||||||
{
|
{
|
||||||
if (order.OrderString == "NuclearMissile")
|
if (order.OrderString == "NuclearMissile")
|
||||||
{
|
{
|
||||||
var silo = self.World.Actors.Where(a => a.Owner == self.Owner
|
var silo = self.World.Queries.OwnedBy[self.Owner]
|
||||||
&& a.traits.Contains<NukeSilo>()).FirstOrDefault();
|
.Where(a => a.traits.Contains<NukeSilo>())
|
||||||
|
.FirstOrDefault();
|
||||||
if (silo != null)
|
if (silo != null)
|
||||||
silo.traits.Get<RenderBuilding>().PlayCustomAnim(silo, "active");
|
silo.traits.Get<RenderBuilding>().PlayCustomAnim(silo, "active");
|
||||||
|
|
||||||
@@ -70,8 +71,9 @@ namespace OpenRa.Traits
|
|||||||
|
|
||||||
public void Tick(World world)
|
public void Tick(World world)
|
||||||
{
|
{
|
||||||
var hasStructure = world.Actors
|
var hasStructure = world.Queries.OwnedBy[world.LocalPlayer]
|
||||||
.Any(a => a.Owner == world.LocalPlayer && a.traits.Contains<NukeSilo>());
|
.WithTrait<NukeSilo>()
|
||||||
|
.Any();
|
||||||
|
|
||||||
if (!hasStructure)
|
if (!hasStructure)
|
||||||
Game.controller.CancelInputMode();
|
Game.controller.CancelInputMode();
|
||||||
|
|||||||
@@ -86,12 +86,12 @@ namespace OpenRa.Traits
|
|||||||
// Cancel existing primaries
|
// Cancel existing primaries
|
||||||
foreach (var p in self.Info.Traits.Get<ProductionInfo>().Produces)
|
foreach (var p in self.Info.Traits.Get<ProductionInfo>().Produces)
|
||||||
{
|
{
|
||||||
foreach (var b in self.World.Actors.Where(x => x.traits.Contains<Production>()
|
foreach (var b in self.World.Queries.OwnedBy[self.Owner]
|
||||||
&& x.Owner == self.Owner
|
.WithTrait<Production>()
|
||||||
&& x.traits.Get<Production>().IsPrimary == true
|
.Where(x => x.Trait.IsPrimary
|
||||||
&& (x.Info.Traits.Get<ProductionInfo>().Produces.Contains(p))))
|
&& (x.Actor.Info.Traits.Get<ProductionInfo>().Produces.Contains(p))))
|
||||||
{
|
{
|
||||||
b.traits.Get<Production>().SetPrimaryProducer(b, false);
|
b.Trait.SetPrimaryProducer(b.Actor, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isPrimary = true;
|
isPrimary = true;
|
||||||
|
|||||||
@@ -131,18 +131,17 @@ namespace OpenRa.Traits
|
|||||||
Actor producer = null;
|
Actor producer = null;
|
||||||
|
|
||||||
// Prioritise primary structure in build order
|
// Prioritise primary structure in build order
|
||||||
var primaryProducers = self.World.Actors
|
var primaryProducers = self.World.Queries.OwnedBy[self.Owner]
|
||||||
.Where(x => x.traits.Contains<Production>()
|
.WithTrait<Production>()
|
||||||
&& producerTypes.Contains(x.Info)
|
.Where(x => producerTypes.Contains(x.Actor.Info)
|
||||||
&& x.Owner == self.Owner
|
&& x.Trait.IsPrimary);
|
||||||
&& x.traits.Get<Production>().IsPrimary == true);
|
|
||||||
|
|
||||||
foreach (var p in primaryProducers)
|
foreach (var p in primaryProducers)
|
||||||
{
|
{
|
||||||
// Ignore buildings that are disabled
|
// Ignore buildings that are disabled
|
||||||
if (p.traits.Contains<Building>() && p.traits.Get<Building>().Disabled)
|
if (p.Actor.traits.Contains<Building>() && p.Actor.traits.Get<Building>().Disabled)
|
||||||
continue;
|
continue;
|
||||||
producer = p;
|
producer = p.Actor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,8 +151,8 @@ namespace OpenRa.Traits
|
|||||||
// Pick the first available producer
|
// Pick the first available producer
|
||||||
if (producer == null)
|
if (producer == null)
|
||||||
{
|
{
|
||||||
producer = self.World.Actors
|
producer = self.World.Queries.OwnedBy[self.Owner]
|
||||||
.Where( x => producerTypes.Contains( x.Info ) && x.Owner == self.Owner )
|
.Where( x => producerTypes.Contains( x.Info ) )
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,8 @@ namespace OpenRa.Traits
|
|||||||
var b = self.traits.Get<Building>();
|
var b = self.traits.Get<Building>();
|
||||||
if (b != null && b.Disabled) return false;
|
if (b != null && b.Disabled) return false;
|
||||||
|
|
||||||
var isJammed = self.World.Actors.Any(a => a.traits.Contains<JamsRadar>()
|
var isJammed = self.World.Queries.WithTrait<JamsRadar>().Any(a => self.Owner != a.Actor.Owner
|
||||||
&& self.Owner != a.Owner
|
&& (self.Location - a.Actor.Location).Length < a.Actor.Info.Traits.Get<JamsRadarInfo>().Range);
|
||||||
&& (self.Location - a.Location).Length < a.Info.Traits.Get<JamsRadarInfo>().Range);
|
|
||||||
|
|
||||||
return !isJammed;
|
return !isJammed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,8 +30,9 @@ namespace OpenRa.Traits
|
|||||||
// Does this belong here? NO, but it's your mess.
|
// Does this belong here? NO, but it's your mess.
|
||||||
|
|
||||||
// Get the crushable actors
|
// Get the crushable actors
|
||||||
foreach (var a in self.World.Actors.Where(b => b.traits.Contains<ICrushable>()))
|
foreach (var aa in self.World.Queries.WithTrait<ICrushable>())
|
||||||
{
|
{
|
||||||
|
var a = aa.Actor;
|
||||||
// Are there any units in the same cell that can crush this?
|
// Are there any units in the same cell that can crush this?
|
||||||
foreach( var ios in a.traits.WithInterface<IOccupySpace>() )
|
foreach( var ios in a.traits.WithInterface<IOccupySpace>() )
|
||||||
foreach( var cell in ios.OccupiedCells() )
|
foreach( var cell in ios.OccupiedCells() )
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ using OpenRa.Support;
|
|||||||
using OpenRa.FileFormats;
|
using OpenRa.FileFormats;
|
||||||
using OpenRa.Graphics;
|
using OpenRa.Graphics;
|
||||||
using OpenRa.Traits;
|
using OpenRa.Traits;
|
||||||
|
using OpenRa.Collections;
|
||||||
|
|
||||||
namespace OpenRa
|
namespace OpenRa
|
||||||
{
|
{
|
||||||
public class World
|
public class World
|
||||||
{
|
{
|
||||||
List<Actor> actors = new List<Actor>();
|
Set<Actor> actors = new Set<Actor>();
|
||||||
List<IEffect> effects = new List<IEffect>();
|
List<IEffect> effects = new List<IEffect>();
|
||||||
List<Action<World>> frameEndActions = new List<Action<World>>();
|
List<Action<World>> frameEndActions = new List<Action<World>>();
|
||||||
|
|
||||||
@@ -77,6 +78,9 @@ namespace OpenRa
|
|||||||
WorldRenderer = new WorldRenderer(this, Game.renderer);
|
WorldRenderer = new WorldRenderer(this, Game.renderer);
|
||||||
Minimap = new Minimap(this, Game.renderer);
|
Minimap = new Minimap(this, Game.renderer);
|
||||||
Timer.Time( "renderer, minimap: {0}" );
|
Timer.Time( "renderer, minimap: {0}" );
|
||||||
|
|
||||||
|
Queries = new AllQueries( this );
|
||||||
|
Timer.Time( "queries: {0}" );
|
||||||
Timer.Time( "----end World.ctor" );
|
Timer.Time( "----end World.ctor" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,5 +157,65 @@ namespace OpenRa
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AllQueries
|
||||||
|
{
|
||||||
|
readonly World world;
|
||||||
|
|
||||||
|
public readonly Dictionary<Player, OwnedByCachedView> OwnedBy = new Dictionary<Player, OwnedByCachedView>();
|
||||||
|
readonly TypeDictionary hasTrait = new TypeDictionary();
|
||||||
|
|
||||||
|
public AllQueries( World world )
|
||||||
|
{
|
||||||
|
this.world = world;
|
||||||
|
foreach( var p in world.players.Values )
|
||||||
|
{
|
||||||
|
var player = p;
|
||||||
|
OwnedBy.Add( player, new OwnedByCachedView( world, world.actors, x => x.Owner == player ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CachedView<Actor, TraitPair<T>> WithTrait<T>()
|
||||||
|
{
|
||||||
|
return WithTraitInner<T>( world, hasTrait );
|
||||||
|
}
|
||||||
|
|
||||||
|
static CachedView<Actor, TraitPair<T>> WithTraitInner<T>( World world, TypeDictionary hasTrait )
|
||||||
|
{
|
||||||
|
var ret = hasTrait.GetOrDefault<CachedView<Actor, TraitPair<T>>>();
|
||||||
|
if( ret != null )
|
||||||
|
return ret;
|
||||||
|
ret = new CachedView<Actor, TraitPair<T>>(
|
||||||
|
world.actors,
|
||||||
|
x => x.traits.Contains<T>(),
|
||||||
|
x => new TraitPair<T> { Actor = x, Trait = x.traits.Get<T>() } );
|
||||||
|
hasTrait.Add( ret );
|
||||||
|
return ret; }
|
||||||
|
|
||||||
|
public struct TraitPair<T>
|
||||||
|
{
|
||||||
|
public Actor Actor;
|
||||||
|
public T Trait;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OwnedByCachedView : CachedView<Actor, Actor>
|
||||||
|
{
|
||||||
|
readonly World world;
|
||||||
|
readonly TypeDictionary hasTrait = new TypeDictionary();
|
||||||
|
|
||||||
|
public OwnedByCachedView( World world, Set<Actor> set, Func<Actor, bool> include )
|
||||||
|
: base( set, include, a => a )
|
||||||
|
{
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CachedView<Actor, TraitPair<T>> WithTrait<T>()
|
||||||
|
{
|
||||||
|
return WithTraitInner<T>( world, hasTrait );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly AllQueries Queries;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ namespace OpenRa.Mods.Aftermath
|
|||||||
Sound.Play("chrotnk1.aud");
|
Sound.Play("chrotnk1.aud");
|
||||||
chargeTick = chargeLength;
|
chargeTick = chargeLength;
|
||||||
|
|
||||||
foreach (var a in self.World.Actors.Where(a => a.traits.Contains<ChronoshiftPaletteEffect>()))
|
foreach (var a in self.World.Queries.WithTrait<ChronoshiftPaletteEffect>())
|
||||||
a.traits.Get<ChronoshiftPaletteEffect>().DoChronoshift();
|
a.Trait.DoChronoshift();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ namespace OpenRa.Mods.RA
|
|||||||
|
|
||||||
protected override void OnFinishCharging()
|
protected override void OnFinishCharging()
|
||||||
{
|
{
|
||||||
var launchSite = Owner.World.Actors
|
var launchSite = Owner.World.Queries.OwnedBy[Owner]
|
||||||
.FirstOrDefault(a => a.Owner == Owner && a.traits.Contains<GpsLaunchSite>());
|
.FirstOrDefault(a => a.traits.Contains<GpsLaunchSite>());
|
||||||
|
|
||||||
if (launchSite == null)
|
if (launchSite == null)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -29,8 +29,9 @@ namespace OpenRa.Mods.RA
|
|||||||
if (self.Owner == self.World.LocalPlayer)
|
if (self.Owner == self.World.LocalPlayer)
|
||||||
Game.controller.CancelInputMode();
|
Game.controller.CancelInputMode();
|
||||||
|
|
||||||
var curtain = self.World.Actors.Where(a => a.Owner != null
|
var curtain = self.World.Queries.WithTrait<IronCurtain>()
|
||||||
&& a.traits.Contains<IronCurtain>()).FirstOrDefault();
|
.Where(a => a.Actor.Owner != null)
|
||||||
|
.FirstOrDefault().Actor;
|
||||||
if (curtain != null)
|
if (curtain != null)
|
||||||
curtain.traits.Get<RenderBuilding>().PlayCustomAnim(curtain, "active");
|
curtain.traits.Get<RenderBuilding>().PlayCustomAnim(curtain, "active");
|
||||||
|
|
||||||
@@ -73,8 +74,9 @@ namespace OpenRa.Mods.RA
|
|||||||
|
|
||||||
public void Tick(World world)
|
public void Tick(World world)
|
||||||
{
|
{
|
||||||
var hasStructure = world.Actors
|
var hasStructure = world.Queries.OwnedBy[world.LocalPlayer]
|
||||||
.Any(a => a.Owner == world.LocalPlayer && a.traits.Contains<IronCurtain>());
|
.WithTrait<IronCurtain>()
|
||||||
|
.Any();
|
||||||
|
|
||||||
if (!hasStructure)
|
if (!hasStructure)
|
||||||
Game.controller.CancelInputMode();
|
Game.controller.CancelInputMode();
|
||||||
|
|||||||
Reference in New Issue
Block a user