Merge branch 'master' of git://github.com/chrisforbes/OpenRA
This commit is contained in:
@@ -46,5 +46,10 @@ namespace OpenRa
|
|||||||
if( i.Value is T )
|
if( i.Value is T )
|
||||||
yield return (T)i.Value;
|
yield return (T)i.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerator<object> GetEnumerator()
|
||||||
|
{
|
||||||
|
return WithInterface<object>().GetEnumerator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,16 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
class Actor
|
class Actor
|
||||||
{
|
{
|
||||||
|
[Sync]
|
||||||
public readonly TypeDictionary traits = new TypeDictionary();
|
public readonly TypeDictionary traits = new TypeDictionary();
|
||||||
public readonly UnitInfo Info;
|
public readonly UnitInfo Info;
|
||||||
|
|
||||||
public readonly uint ActorID;
|
public readonly uint ActorID;
|
||||||
|
[Sync]
|
||||||
public int2 Location;
|
public int2 Location;
|
||||||
|
[Sync]
|
||||||
public Player Owner;
|
public Player Owner;
|
||||||
|
[Sync]
|
||||||
public int Health;
|
public int Health;
|
||||||
IActivity currentActivity;
|
IActivity currentActivity;
|
||||||
|
|
||||||
|
|||||||
@@ -147,14 +147,24 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
public Cursor ChooseCursor()
|
public Cursor ChooseCursor()
|
||||||
{
|
{
|
||||||
var mi = new MouseInput
|
int sync = Game.world.SyncHash();
|
||||||
{
|
|
||||||
Location = (Game.CellSize * MousePosition - Game.viewport.Location).ToInt2(),
|
|
||||||
Button = MouseButton.Right,
|
|
||||||
Modifiers = GetModifierKeys(),
|
|
||||||
};
|
|
||||||
|
|
||||||
return orderGenerator.GetCursor(MousePosition.ToInt2(), mi);
|
try
|
||||||
|
{
|
||||||
|
var mi = new MouseInput
|
||||||
|
{
|
||||||
|
Location = ( Game.CellSize * MousePosition - Game.viewport.Location ).ToInt2(),
|
||||||
|
Button = MouseButton.Right,
|
||||||
|
Modifiers = GetModifierKeys(),
|
||||||
|
};
|
||||||
|
|
||||||
|
return orderGenerator.GetCursor( MousePosition.ToInt2(), mi );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if( sync != Game.world.SyncHash() )
|
||||||
|
throw new InvalidOperationException( "Desync in Controller.ChooseCursor" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Cache<int, List<Actor>> controlGroups = new Cache<int, List<Actor>>(_ => new List<Actor>());
|
Cache<int, List<Actor>> controlGroups = new Cache<int, List<Actor>>(_ => new List<Actor>());
|
||||||
|
|||||||
0
OpenRa.Game/Effects/Bullet.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Bullet.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Corpse.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Corpse.cs
Normal file → Executable file
0
OpenRa.Game/Effects/DelayedAction.cs
Normal file → Executable file
0
OpenRa.Game/Effects/DelayedAction.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Explosion.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Explosion.cs
Normal file → Executable file
0
OpenRa.Game/Effects/FlashTarget.cs
Normal file → Executable file
0
OpenRa.Game/Effects/FlashTarget.cs
Normal file → Executable file
0
OpenRa.Game/Effects/GpsSatellite.cs
Normal file → Executable file
0
OpenRa.Game/Effects/GpsSatellite.cs
Normal file → Executable file
0
OpenRa.Game/Effects/IEffect.cs
Normal file → Executable file
0
OpenRa.Game/Effects/IEffect.cs
Normal file → Executable file
0
OpenRa.Game/Effects/InvulnEffect.cs
Normal file → Executable file
0
OpenRa.Game/Effects/InvulnEffect.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Missile.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Missile.cs
Normal file → Executable file
0
OpenRa.Game/Effects/MoveFlash.cs
Normal file → Executable file
0
OpenRa.Game/Effects/MoveFlash.cs
Normal file → Executable file
0
OpenRa.Game/Effects/PowerDownIndicator.cs
Normal file → Executable file
0
OpenRa.Game/Effects/PowerDownIndicator.cs
Normal file → Executable file
0
OpenRa.Game/Effects/RepairIndicator.cs
Normal file → Executable file
0
OpenRa.Game/Effects/RepairIndicator.cs
Normal file → Executable file
0
OpenRa.Game/Effects/SatelliteLaunch.cs
Normal file → Executable file
0
OpenRa.Game/Effects/SatelliteLaunch.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Smoke.cs
Normal file → Executable file
0
OpenRa.Game/Effects/Smoke.cs
Normal file → Executable file
@@ -95,6 +95,8 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
void DispatchMouseInput(MouseInputEvent ev, MouseEventArgs e)
|
void DispatchMouseInput(MouseInputEvent ev, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
|
int sync = Game.world.SyncHash();
|
||||||
|
|
||||||
Game.viewport.DispatchMouseInput(
|
Game.viewport.DispatchMouseInput(
|
||||||
new MouseInput
|
new MouseInput
|
||||||
{
|
{
|
||||||
@@ -103,6 +105,9 @@ namespace OpenRa.Game
|
|||||||
Location = new int2(e.Location),
|
Location = new int2(e.Location),
|
||||||
Modifiers = (Modifiers)(int)ModifierKeys,
|
Modifiers = (Modifiers)(int)ModifierKeys,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if( sync != Game.world.SyncHash() )
|
||||||
|
throw new InvalidOperationException( "Desync in DispatchMouseInput" );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnMouseDown(MouseEventArgs e)
|
protected override void OnMouseDown(MouseEventArgs e)
|
||||||
@@ -136,6 +141,8 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
base.OnKeyDown(e);
|
base.OnKeyDown(e);
|
||||||
|
|
||||||
|
int sync = Game.world.SyncHash();
|
||||||
|
|
||||||
/* hack hack hack */
|
/* hack hack hack */
|
||||||
if (e.KeyCode == Keys.F8 && !Game.orderManager.GameStarted)
|
if (e.KeyCode == Keys.F8 && !Game.orderManager.GameStarted)
|
||||||
{
|
{
|
||||||
@@ -156,16 +163,24 @@ namespace OpenRa.Game
|
|||||||
if (!Game.chat.isChatting)
|
if (!Game.chat.isChatting)
|
||||||
if (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9)
|
if (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9)
|
||||||
Game.controller.DoControlGroup( (int)e.KeyCode - (int)Keys.D0, (Modifiers)(int)e.Modifiers );
|
Game.controller.DoControlGroup( (int)e.KeyCode - (int)Keys.D0, (Modifiers)(int)e.Modifiers );
|
||||||
|
|
||||||
|
if( sync != Game.world.SyncHash() )
|
||||||
|
throw new InvalidOperationException( "Desync in OnKeyDown" );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnKeyPress(KeyPressEventArgs e)
|
protected override void OnKeyPress(KeyPressEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnKeyPress(e);
|
base.OnKeyPress(e);
|
||||||
|
|
||||||
|
int sync = Game.world.SyncHash();
|
||||||
|
|
||||||
if (e.KeyChar == '\r')
|
if (e.KeyChar == '\r')
|
||||||
Game.chat.Toggle();
|
Game.chat.Toggle();
|
||||||
else if (Game.chat.isChatting)
|
else if (Game.chat.isChatting)
|
||||||
Game.chat.TypeChar(e.KeyChar);
|
Game.chat.TypeChar(e.KeyChar);
|
||||||
|
|
||||||
|
if( sync != Game.world.SyncHash() )
|
||||||
|
throw new InvalidOperationException( "Desync in OnKeyPress" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -129,6 +129,7 @@
|
|||||||
<Compile Include="SupportPowers\NullPower.cs" />
|
<Compile Include="SupportPowers\NullPower.cs" />
|
||||||
<Compile Include="Support\Stopwatch.cs" />
|
<Compile Include="Support\Stopwatch.cs" />
|
||||||
<Compile Include="Support\PerfHistory.cs" />
|
<Compile Include="Support\PerfHistory.cs" />
|
||||||
|
<Compile Include="Sync.cs" />
|
||||||
<Compile Include="Traits\AcceptsOre.cs" />
|
<Compile Include="Traits\AcceptsOre.cs" />
|
||||||
<Compile Include="Traits\Activities\Attack.cs" />
|
<Compile Include="Traits\Activities\Attack.cs" />
|
||||||
<Compile Include="Traits\Activities\CaptureBuilding.cs" />
|
<Compile Include="Traits\Activities\CaptureBuilding.cs" />
|
||||||
|
|||||||
107
OpenRa.Game/Sync.cs
Executable file
107
OpenRa.Game/Sync.cs
Executable file
@@ -0,0 +1,107 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using IjwFramework.Collections;
|
||||||
|
|
||||||
|
namespace OpenRa.Game
|
||||||
|
{
|
||||||
|
class SyncAttribute : Attribute { }
|
||||||
|
|
||||||
|
static class Sync
|
||||||
|
{
|
||||||
|
static Cache<Type, Func<object, int>> hashFuncCache = new Cache<Type, Func<object, int>>( t => GenerateHashFunc( t ) );
|
||||||
|
|
||||||
|
public static int CalculateSyncHash( object obj )
|
||||||
|
{
|
||||||
|
return hashFuncCache[ obj.GetType() ]( obj );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Func<object,int> GenerateHashFunc( Type t )
|
||||||
|
{
|
||||||
|
var d = new DynamicMethod( "hash_{0}".F( t.Name ), typeof( int ), new Type[] { typeof( object ) }, t );
|
||||||
|
var il = d.GetILGenerator();
|
||||||
|
var this_ = il.DeclareLocal( t ).LocalIndex;
|
||||||
|
il.Emit( OpCodes.Ldarg_0 );
|
||||||
|
il.Emit( OpCodes.Castclass, t );
|
||||||
|
il.Emit( OpCodes.Stloc, this_ );
|
||||||
|
il.Emit( OpCodes.Ldc_I4_0 );
|
||||||
|
|
||||||
|
const BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
|
||||||
|
foreach( var field in t.GetFields( bf ).Where( x => x.GetCustomAttributes( typeof( SyncAttribute ), true ).Length != 0 ) )
|
||||||
|
{
|
||||||
|
il.Emit( OpCodes.Ldloc, this_ );
|
||||||
|
il.Emit( OpCodes.Ldfld, field );
|
||||||
|
|
||||||
|
if( field.FieldType == typeof( int ) )
|
||||||
|
{
|
||||||
|
il.Emit( OpCodes.Xor );
|
||||||
|
}
|
||||||
|
else if( field.FieldType == typeof( bool ) )
|
||||||
|
{
|
||||||
|
var l = il.DefineLabel();
|
||||||
|
il.Emit( OpCodes.Ldc_I4, 0xaaa );
|
||||||
|
il.Emit( OpCodes.Brtrue, l );
|
||||||
|
il.Emit( OpCodes.Pop );
|
||||||
|
il.Emit( OpCodes.Ldc_I4, 0x555 );
|
||||||
|
il.MarkLabel( l );
|
||||||
|
il.Emit( OpCodes.Xor );
|
||||||
|
}
|
||||||
|
else if( field.FieldType == typeof( int2 ) )
|
||||||
|
{
|
||||||
|
il.EmitCall( OpCodes.Call, ( (Func<int2, int>)hash_int2 ).Method, null );
|
||||||
|
il.Emit( OpCodes.Xor );
|
||||||
|
}
|
||||||
|
else if( field.FieldType == typeof( TypeDictionary ) )
|
||||||
|
{
|
||||||
|
il.EmitCall( OpCodes.Call, ( (Func<TypeDictionary, int>)hash_tdict ).Method, null );
|
||||||
|
il.Emit( OpCodes.Xor );
|
||||||
|
}
|
||||||
|
else if( field.FieldType == typeof( Actor ) )
|
||||||
|
{
|
||||||
|
il.EmitCall( OpCodes.Call, ( (Func<Actor, int>)hash_actor ).Method, null );
|
||||||
|
il.Emit( OpCodes.Xor );
|
||||||
|
}
|
||||||
|
else if( field.FieldType == typeof( Player ) )
|
||||||
|
{
|
||||||
|
il.EmitCall( OpCodes.Call, ( (Func<Player, int>)hash_player ).Method, null );
|
||||||
|
il.Emit( OpCodes.Xor );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new NotImplementedException( "SyncAttribute on unhashable field" );
|
||||||
|
}
|
||||||
|
|
||||||
|
il.Emit( OpCodes.Ret );
|
||||||
|
return (Func<object,int>)d.CreateDelegate( typeof( Func<object,int> ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int hash_int2( int2 i2 )
|
||||||
|
{
|
||||||
|
return ( ( i2.X * 5 ) ^ ( i2.Y * 3 ) ) / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int hash_tdict( TypeDictionary d )
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
foreach( var o in d )
|
||||||
|
ret += CalculateSyncHash( o );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int hash_actor( Actor a )
|
||||||
|
{
|
||||||
|
if( a != null )
|
||||||
|
return (int)( a.ActorID << 16 );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int hash_player( Player p )
|
||||||
|
{
|
||||||
|
if( p != null )
|
||||||
|
return p.Index * 0x567;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,10 +8,12 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
class AttackBase : IIssueOrder, IResolveOrder, ITick
|
class AttackBase : IIssueOrder, IResolveOrder, ITick
|
||||||
{
|
{
|
||||||
public Actor target;
|
[Sync] public Actor target;
|
||||||
|
|
||||||
// time (in frames) until each weapon can fire again.
|
// time (in frames) until each weapon can fire again.
|
||||||
|
[Sync]
|
||||||
protected int primaryFireDelay = 0;
|
protected int primaryFireDelay = 0;
|
||||||
|
[Sync]
|
||||||
protected int secondaryFireDelay = 0;
|
protected int secondaryFireDelay = 0;
|
||||||
|
|
||||||
int primaryBurst;
|
int primaryBurst;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace OpenRa.Game.Traits
|
|||||||
public AttackFrontal(Actor self, int facingTolerance)
|
public AttackFrontal(Actor self, int facingTolerance)
|
||||||
: base(self) { FacingTolerance = facingTolerance; }
|
: base(self) { FacingTolerance = facingTolerance; }
|
||||||
|
|
||||||
int FacingTolerance;
|
readonly int FacingTolerance;
|
||||||
|
|
||||||
public override void Tick(Actor self)
|
public override void Tick(Actor self)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
readonly Actor self;
|
readonly Actor self;
|
||||||
public readonly BuildingInfo unitInfo;
|
public readonly BuildingInfo unitInfo;
|
||||||
|
[Sync]
|
||||||
bool isRepairing = false;
|
bool isRepairing = false;
|
||||||
|
[Sync]
|
||||||
bool manuallyDisabled = false;
|
bool manuallyDisabled = false;
|
||||||
public bool ManuallyDisabled { get { return manuallyDisabled; } }
|
public bool ManuallyDisabled { get { return manuallyDisabled; } }
|
||||||
public bool Disabled { get { return (manuallyDisabled || (unitInfo.Powered && self.Owner.GetPowerState() != PowerState.Normal)); } }
|
public bool Disabled { get { return (manuallyDisabled || (unitInfo.Powered && self.Owner.GetPowerState() != PowerState.Normal)); } }
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ namespace OpenRa.Game.Traits
|
|||||||
class ChronoshiftDeploy : IIssueOrder, IResolveOrder, ISpeedModifier, ITick, IPips
|
class ChronoshiftDeploy : IIssueOrder, IResolveOrder, ISpeedModifier, ITick, IPips
|
||||||
{
|
{
|
||||||
// Recharge logic
|
// Recharge logic
|
||||||
|
[Sync]
|
||||||
int chargeTick = 0; // How long until we can chronoshift again?
|
int chargeTick = 0; // How long until we can chronoshift again?
|
||||||
int chargeLength = (int)(Rules.Aftermath.ChronoTankDuration * 60 * 25); // How long between shifts?
|
readonly int chargeLength = (int)(Rules.Aftermath.ChronoTankDuration * 60 * 25); // How long between shifts?
|
||||||
|
|
||||||
public ChronoshiftDeploy(Actor self) { }
|
public ChronoshiftDeploy(Actor self) { }
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ namespace OpenRa.Game.Traits
|
|||||||
class Chronoshiftable : IResolveOrder, ISpeedModifier, ITick
|
class Chronoshiftable : IResolveOrder, ISpeedModifier, ITick
|
||||||
{
|
{
|
||||||
// Return-to-sender logic
|
// Return-to-sender logic
|
||||||
|
[Sync]
|
||||||
int2 chronoshiftOrigin;
|
int2 chronoshiftOrigin;
|
||||||
|
[Sync]
|
||||||
int chronoshiftReturnTicks = 0;
|
int chronoshiftReturnTicks = 0;
|
||||||
|
|
||||||
public Chronoshiftable(Actor self) { }
|
public Chronoshiftable(Actor self) { }
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
class Cloak : IRenderModifier, INotifyAttack, ITick
|
class Cloak : IRenderModifier, INotifyAttack, ITick
|
||||||
{
|
{
|
||||||
|
[Sync]
|
||||||
int remainingUncloakTime = 2; /* setup for initial cloak */
|
int remainingUncloakTime = 2; /* setup for initial cloak */
|
||||||
|
|
||||||
public Cloak(Actor self) {}
|
public Cloak(Actor self) {}
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
class Harvester : IIssueOrder, IResolveOrder, IPips
|
class Harvester : IIssueOrder, IResolveOrder, IPips
|
||||||
{
|
{
|
||||||
|
[Sync]
|
||||||
public int oreCarried = 0; /* sum of these must not exceed capacity */
|
public int oreCarried = 0; /* sum of these must not exceed capacity */
|
||||||
|
[Sync]
|
||||||
public int gemsCarried = 0;
|
public int gemsCarried = 0;
|
||||||
|
|
||||||
public bool IsFull { get { return oreCarried + gemsCarried == Rules.General.BailCount; } }
|
public bool IsFull { get { return oreCarried + gemsCarried == Rules.General.BailCount; } }
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
class IronCurtainable : IResolveOrder, IDamageModifier, ITick
|
class IronCurtainable : IResolveOrder, IDamageModifier, ITick
|
||||||
{
|
{
|
||||||
|
[Sync]
|
||||||
int RemainingTicks = 0;
|
int RemainingTicks = 0;
|
||||||
|
|
||||||
public IronCurtainable(Actor self) { }
|
public IronCurtainable(Actor self) { }
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
class LimitedAmmo : INotifyAttack, IPips
|
class LimitedAmmo : INotifyAttack, IPips
|
||||||
{
|
{
|
||||||
|
[Sync]
|
||||||
int ammo;
|
int ammo;
|
||||||
Actor self;
|
Actor self;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
readonly Actor self;
|
readonly Actor self;
|
||||||
|
|
||||||
|
[Sync]
|
||||||
int2 __fromCell;
|
int2 __fromCell;
|
||||||
public int2 fromCell
|
public int2 fromCell
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ namespace OpenRa.Game.Traits
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Key: Production category.
|
// Key: Production category.
|
||||||
|
// TODO: sync this
|
||||||
readonly Cache<string, List<ProductionItem>> production
|
readonly Cache<string, List<ProductionItem>> production
|
||||||
= new Cache<string, List<ProductionItem>>( _ => new List<ProductionItem>() );
|
= new Cache<string, List<ProductionItem>>( _ => new List<ProductionItem>() );
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
class RallyPoint : IRender, IIssueOrder, IResolveOrder, ITick
|
class RallyPoint : IRender, IIssueOrder, IResolveOrder, ITick
|
||||||
{
|
{
|
||||||
|
[Sync]
|
||||||
public int2 rallyPoint;
|
public int2 rallyPoint;
|
||||||
public Animation anim;
|
public Animation anim;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ namespace OpenRa.Game.Traits
|
|||||||
class RenderWarFactory : IRender, INotifyBuildComplete, INotifyDamage, ITick, INotifyProduction
|
class RenderWarFactory : IRender, INotifyBuildComplete, INotifyDamage, ITick, INotifyProduction
|
||||||
{
|
{
|
||||||
public Animation roof;
|
public Animation roof;
|
||||||
|
[Sync]
|
||||||
bool doneBuilding;
|
bool doneBuilding;
|
||||||
|
[Sync]
|
||||||
bool isOpen;
|
bool isOpen;
|
||||||
public readonly Actor self;
|
public readonly Actor self;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
class Submarine : IRenderModifier, INotifyAttack, ITick, INotifyDamage
|
class Submarine : IRenderModifier, INotifyAttack, ITick, INotifyDamage
|
||||||
{
|
{
|
||||||
|
[Sync]
|
||||||
int remainingSurfaceTime = 2; /* setup for initial dive */
|
int remainingSurfaceTime = 2; /* setup for initial dive */
|
||||||
|
|
||||||
public Submarine(Actor self) { }
|
public Submarine(Actor self) { }
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace OpenRa.Game.Traits
|
|||||||
const float proneDamage = .5f;
|
const float proneDamage = .5f;
|
||||||
const float proneSpeed = .5f;
|
const float proneSpeed = .5f;
|
||||||
|
|
||||||
|
[Sync]
|
||||||
int remainingProneTime = 0;
|
int remainingProneTime = 0;
|
||||||
|
|
||||||
public bool IsProne { get { return remainingProneTime > 0; } }
|
public bool IsProne { get { return remainingProneTime > 0; } }
|
||||||
|
|||||||
@@ -13,15 +13,15 @@ namespace OpenRa.Game.Traits
|
|||||||
|
|
||||||
interface ITick { void Tick(Actor self); }
|
interface ITick { void Tick(Actor self); }
|
||||||
interface IRender { IEnumerable<Renderable> Render(Actor self); }
|
interface IRender { IEnumerable<Renderable> Render(Actor self); }
|
||||||
|
interface IIssueOrder { Order IssueOrder( Actor self, int2 xy, MouseInput mi, Actor underCursor ); }
|
||||||
|
interface IResolveOrder { void ResolveOrder( Actor self, Order order ); }
|
||||||
|
|
||||||
interface INotifySold { void Sold(Actor self); }
|
interface INotifySold { void Sold(Actor self); }
|
||||||
interface INotifyDamage { void Damaged(Actor self, AttackInfo e); }
|
interface INotifyDamage { void Damaged(Actor self, AttackInfo e); }
|
||||||
interface INotifyBuildComplete { void BuildingComplete (Actor self); }
|
interface INotifyBuildComplete { void BuildingComplete (Actor self); }
|
||||||
interface INotifyProduction { void UnitProduced(Actor self, Actor other); }
|
interface INotifyProduction { void UnitProduced(Actor self, Actor other); }
|
||||||
interface IAcceptThief { void OnSteal(Actor self, Actor thief); }
|
interface IAcceptThief { void OnSteal(Actor self, Actor thief); }
|
||||||
|
|
||||||
interface IIssueOrder { Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor); }
|
|
||||||
interface IResolveOrder { void ResolveOrder(Actor self, Order order); }
|
|
||||||
|
|
||||||
interface IProducer
|
interface IProducer
|
||||||
{
|
{
|
||||||
bool Produce( Actor self, UnitInfo producee );
|
bool Produce( Actor self, UnitInfo producee );
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
class Turreted : ITick
|
class Turreted : ITick
|
||||||
{
|
{
|
||||||
|
[Sync]
|
||||||
public int turretFacing = 0;
|
public int turretFacing = 0;
|
||||||
public int? desiredFacing;
|
public int? desiredFacing;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
class Unit : INotifyDamage
|
class Unit : INotifyDamage
|
||||||
{
|
{
|
||||||
|
[Sync]
|
||||||
public int Facing;
|
public int Facing;
|
||||||
|
[Sync]
|
||||||
public int Altitude;
|
public int Altitude;
|
||||||
|
|
||||||
public Unit( Actor self ) { }
|
public Unit( Actor self ) { }
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using OpenRa.Game.Effects;
|
using OpenRa.Game.Effects;
|
||||||
|
using OpenRa.Game.Support;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
@@ -52,5 +53,17 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
return nextAID++;
|
return nextAID++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int SyncHash()
|
||||||
|
{
|
||||||
|
using (new PerfSample("synchash"))
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
foreach (var a in Actors)
|
||||||
|
ret += (int)a.ActorID * Sync.CalculateSyncHash(a);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user