Serialize order Target directly instead of TargetActor/TargetCell.
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using OpenRA.Network;
|
using OpenRA.Network;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
@@ -19,8 +20,7 @@ namespace OpenRA
|
|||||||
[Flags]
|
[Flags]
|
||||||
enum OrderFields : byte
|
enum OrderFields : byte
|
||||||
{
|
{
|
||||||
TargetActor = 0x01,
|
Target = 0x01,
|
||||||
TargetLocation = 0x02,
|
|
||||||
TargetString = 0x04,
|
TargetString = 0x04,
|
||||||
Queued = 0x08,
|
Queued = 0x08,
|
||||||
ExtraLocation = 0x10,
|
ExtraLocation = 0x10,
|
||||||
@@ -40,8 +40,7 @@ namespace OpenRA
|
|||||||
public readonly string OrderString;
|
public readonly string OrderString;
|
||||||
public readonly Actor Subject;
|
public readonly Actor Subject;
|
||||||
public readonly bool Queued;
|
public readonly bool Queued;
|
||||||
public Actor TargetActor { get; private set; }
|
public readonly Target Target;
|
||||||
public CPos TargetLocation { get; private set; }
|
|
||||||
public string TargetString;
|
public string TargetString;
|
||||||
public CPos ExtraLocation;
|
public CPos ExtraLocation;
|
||||||
public uint ExtraData;
|
public uint ExtraData;
|
||||||
@@ -49,34 +48,35 @@ namespace OpenRA
|
|||||||
public bool SuppressVisualFeedback;
|
public bool SuppressVisualFeedback;
|
||||||
public Actor VisualFeedbackTarget;
|
public Actor VisualFeedbackTarget;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DEPRECATED: Use Target instead.
|
||||||
|
/// </summary>
|
||||||
|
public Actor TargetActor { get { return Target.SerializableActor; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DEPRECATED: Use Target instead.
|
||||||
|
/// </summary>
|
||||||
|
public CPos TargetLocation
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Target.SerializableCell.HasValue ? Target.SerializableCell.Value : CPos.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Player Player { get { return Subject != null ? Subject.Owner : null; } }
|
public Player Player { get { return Subject != null ? Subject.Owner : null; } }
|
||||||
|
|
||||||
Order(string orderString, Actor subject,
|
Order(string orderString, Actor subject, Target target, string targetString, bool queued, CPos extraLocation, uint extraData)
|
||||||
Actor targetActor, CPos targetLocation, string targetString, bool queued, CPos extraLocation, uint extraData)
|
|
||||||
{
|
{
|
||||||
OrderString = orderString;
|
OrderString = orderString;
|
||||||
Subject = subject;
|
Subject = subject;
|
||||||
TargetActor = targetActor;
|
Target = target;
|
||||||
TargetLocation = targetLocation;
|
|
||||||
TargetString = targetString;
|
TargetString = targetString;
|
||||||
Queued = queued;
|
Queued = queued;
|
||||||
ExtraLocation = extraLocation;
|
ExtraLocation = extraLocation;
|
||||||
ExtraData = extraData;
|
|
||||||
}
|
|
||||||
|
|
||||||
Order(string orderString, Actor subject, Target target, bool queued, CPos extraLocation, uint extraData)
|
// TODO: remove FrozenActor ID after the various ResolveOrders that rely on it are updated
|
||||||
{
|
ExtraData = target.Type == TargetType.FrozenActor ? target.FrozenActor.ID : extraData;
|
||||||
var targetType = target.SerializableType;
|
|
||||||
|
|
||||||
OrderString = orderString;
|
|
||||||
Subject = subject;
|
|
||||||
TargetActor = targetType == TargetType.Actor ? target.SerializableActor : null;
|
|
||||||
TargetLocation = targetType == TargetType.Terrain ? target.SerializableCell.HasValue ?
|
|
||||||
target.SerializableCell.Value : subject.World.Map.CellContaining(target.CenterPosition) : CPos.Zero;
|
|
||||||
TargetString = null;
|
|
||||||
Queued = queued;
|
|
||||||
ExtraLocation = extraLocation;
|
|
||||||
ExtraData = targetType == TargetType.FrozenActor ? target.FrozenActor.ID : extraData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Order Deserialize(World world, BinaryReader r)
|
public static Order Deserialize(World world, BinaryReader r)
|
||||||
@@ -90,21 +90,62 @@ namespace OpenRA
|
|||||||
var subjectId = r.ReadUInt32();
|
var subjectId = r.ReadUInt32();
|
||||||
var flags = (OrderFields)r.ReadByte();
|
var flags = (OrderFields)r.ReadByte();
|
||||||
|
|
||||||
var targetActorId = flags.HasField(OrderFields.TargetActor) ? r.ReadUInt32() : uint.MaxValue;
|
Actor subject = null;
|
||||||
var targetLocation = (CPos)(flags.HasField(OrderFields.TargetLocation) ? r.ReadInt2() : int2.Zero);
|
if (world != null)
|
||||||
|
TryGetActorFromUInt(world, subjectId, out subject);
|
||||||
|
|
||||||
|
var target = Target.Invalid;
|
||||||
|
if (flags.HasField(OrderFields.Target))
|
||||||
|
{
|
||||||
|
switch ((TargetType)r.ReadByte())
|
||||||
|
{
|
||||||
|
case TargetType.Actor:
|
||||||
|
{
|
||||||
|
Actor targetActor;
|
||||||
|
if (world != null && TryGetActorFromUInt(world, r.ReadUInt32(), out targetActor))
|
||||||
|
target = Target.FromActor(targetActor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TargetType.FrozenActor:
|
||||||
|
{
|
||||||
|
Actor playerActor;
|
||||||
|
if (world == null || !TryGetActorFromUInt(world, r.ReadUInt32(), out playerActor))
|
||||||
|
break;
|
||||||
|
|
||||||
|
var frozenLayer = playerActor.TraitOrDefault<FrozenActorLayer>();
|
||||||
|
if (frozenLayer == null)
|
||||||
|
break;
|
||||||
|
|
||||||
|
var frozen = frozenLayer.FromID(r.ReadUInt32());
|
||||||
|
if (frozen != null)
|
||||||
|
target = Target.FromFrozenActor(frozen);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TargetType.Terrain:
|
||||||
|
{
|
||||||
|
if (world != null)
|
||||||
|
target = Target.FromCell(world, (CPos)r.ReadInt2());
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var targetString = flags.HasField(OrderFields.TargetString) ? r.ReadString() : null;
|
var targetString = flags.HasField(OrderFields.TargetString) ? r.ReadString() : null;
|
||||||
var queued = flags.HasField(OrderFields.Queued);
|
var queued = flags.HasField(OrderFields.Queued);
|
||||||
var extraLocation = (CPos)(flags.HasField(OrderFields.ExtraLocation) ? r.ReadInt2() : int2.Zero);
|
var extraLocation = (CPos)(flags.HasField(OrderFields.ExtraLocation) ? r.ReadInt2() : int2.Zero);
|
||||||
var extraData = flags.HasField(OrderFields.ExtraData) ? r.ReadUInt32() : 0;
|
var extraData = flags.HasField(OrderFields.ExtraData) ? r.ReadUInt32() : 0;
|
||||||
|
|
||||||
if (world == null)
|
if (world == null)
|
||||||
return new Order(order, null, null, targetLocation, targetString, queued, extraLocation, extraData);
|
return new Order(order, null, target, targetString, queued, extraLocation, extraData);
|
||||||
|
|
||||||
Actor subject, targetActor;
|
if (subject == null)
|
||||||
if (!TryGetActorFromUInt(world, subjectId, out subject) || !TryGetActorFromUInt(world, targetActorId, out targetActor))
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return new Order(order, subject, targetActor, targetLocation, targetString, queued, extraLocation, extraData);
|
return new Order(order, subject, target, targetString, queued, extraLocation, extraData);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xfe:
|
case 0xfe:
|
||||||
@@ -185,16 +226,16 @@ namespace OpenRA
|
|||||||
|
|
||||||
// For scripting special powers
|
// For scripting special powers
|
||||||
public Order()
|
public Order()
|
||||||
: this(null, null, null, CPos.Zero, null, false, CPos.Zero, 0) { }
|
: this(null, null, Target.Invalid, null, false, CPos.Zero, 0) { }
|
||||||
|
|
||||||
public Order(string orderString, Actor subject, bool queued)
|
public Order(string orderString, Actor subject, bool queued)
|
||||||
: this(orderString, subject, null, CPos.Zero, null, queued, CPos.Zero, 0) { }
|
: this(orderString, subject, Target.Invalid, null, queued, CPos.Zero, 0) { }
|
||||||
|
|
||||||
public Order(string orderString, Actor subject, Target target, bool queued)
|
public Order(string orderString, Actor subject, Target target, bool queued)
|
||||||
: this(orderString, subject, target, queued, CPos.Zero, 0) { }
|
: this(orderString, subject, target, null, queued, CPos.Zero, 0) { }
|
||||||
|
|
||||||
public Order(string orderstring, Order order)
|
public Order(string orderstring, Order order)
|
||||||
: this(orderstring, order.Subject, order.TargetActor, order.TargetLocation,
|
: this(orderstring, order.Subject, order.Target,
|
||||||
order.TargetString, order.Queued, order.ExtraLocation, order.ExtraData) { }
|
order.TargetString, order.Queued, order.ExtraLocation, order.ExtraData) { }
|
||||||
|
|
||||||
public byte[] Serialize()
|
public byte[] Serialize()
|
||||||
@@ -218,7 +259,6 @@ namespace OpenRA
|
|||||||
* varies: rest of order.
|
* varies: rest of order.
|
||||||
*/
|
*/
|
||||||
default:
|
default:
|
||||||
// TODO: specific serializers for specific orders.
|
|
||||||
{
|
{
|
||||||
var ret = new MemoryStream();
|
var ret = new MemoryStream();
|
||||||
var w = new BinaryWriter(ret);
|
var w = new BinaryWriter(ret);
|
||||||
@@ -227,8 +267,7 @@ namespace OpenRA
|
|||||||
w.Write(UIntFromActor(Subject));
|
w.Write(UIntFromActor(Subject));
|
||||||
|
|
||||||
OrderFields fields = 0;
|
OrderFields fields = 0;
|
||||||
if (TargetActor != null) fields |= OrderFields.TargetActor;
|
if (Target.SerializableType != TargetType.Invalid) fields |= OrderFields.Target;
|
||||||
if (TargetLocation != CPos.Zero) fields |= OrderFields.TargetLocation;
|
|
||||||
if (TargetString != null) fields |= OrderFields.TargetString;
|
if (TargetString != null) fields |= OrderFields.TargetString;
|
||||||
if (Queued) fields |= OrderFields.Queued;
|
if (Queued) fields |= OrderFields.Queued;
|
||||||
if (ExtraLocation != CPos.Zero) fields |= OrderFields.ExtraLocation;
|
if (ExtraLocation != CPos.Zero) fields |= OrderFields.ExtraLocation;
|
||||||
@@ -236,14 +275,30 @@ namespace OpenRA
|
|||||||
|
|
||||||
w.Write((byte)fields);
|
w.Write((byte)fields);
|
||||||
|
|
||||||
if (TargetActor != null)
|
if (Target.SerializableType != TargetType.Invalid)
|
||||||
w.Write(UIntFromActor(TargetActor));
|
w.Write((byte)Target.Type);
|
||||||
if (TargetLocation != CPos.Zero)
|
|
||||||
w.Write(TargetLocation);
|
switch (Target.SerializableType)
|
||||||
|
{
|
||||||
|
case TargetType.Actor:
|
||||||
|
w.Write(UIntFromActor(Target.SerializableActor));
|
||||||
|
break;
|
||||||
|
case TargetType.FrozenActor:
|
||||||
|
w.Write(Target.FrozenActor.Owner.PlayerActor.ActorID);
|
||||||
|
w.Write(Target.FrozenActor.ID);
|
||||||
|
break;
|
||||||
|
case TargetType.Terrain:
|
||||||
|
// SerializableCell is guaranteed to be non-null if Type == TargetType.Terrain
|
||||||
|
w.Write(Target.SerializableCell.Value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (TargetString != null)
|
if (TargetString != null)
|
||||||
w.Write(TargetString);
|
w.Write(TargetString);
|
||||||
|
|
||||||
if (ExtraLocation != CPos.Zero)
|
if (ExtraLocation != CPos.Zero)
|
||||||
w.Write(ExtraLocation);
|
w.Write(ExtraLocation);
|
||||||
|
|
||||||
if (ExtraData != 0)
|
if (ExtraData != 0)
|
||||||
w.Write(ExtraData);
|
w.Write(ExtraData);
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace OpenRA.Traits
|
namespace OpenRA.Traits
|
||||||
{
|
{
|
||||||
public enum TargetType { Invalid, Actor, Terrain, FrozenActor }
|
public enum TargetType : byte { Invalid, Actor, Terrain, FrozenActor }
|
||||||
public struct Target
|
public struct Target
|
||||||
{
|
{
|
||||||
public static readonly Target[] None = { };
|
public static readonly Target[] None = { };
|
||||||
@@ -34,6 +34,10 @@ namespace OpenRA.Traits
|
|||||||
return new Target { pos = w.Map.CenterOfSubCell(c, subCell), cell = c, type = TargetType.Terrain };
|
return new Target { pos = w.Map.CenterOfSubCell(c, subCell), cell = c, type = TargetType.Terrain };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DEPRECATED: Use Order.Target instead.
|
||||||
|
/// This method is kept to maintain compatibility with legacy code that may not understand TargetType.FrozenActor.
|
||||||
|
/// </summary>
|
||||||
public static Target FromOrder(World w, Order o)
|
public static Target FromOrder(World w, Order o)
|
||||||
{
|
{
|
||||||
return o.TargetActor != null
|
return o.TargetActor != null
|
||||||
|
|||||||
Reference in New Issue
Block a user