ModernUO/Projects/UOContent/Engines/Factions/Mobiles/Guards/Orders.cs
Kamron Batman 4ddb3de026
fix(core): Fixes several serialization issues (#355)
- [X] Fixes an issue where a buffer smaller than 8 bytes would not double with enough space in some cases.
- [X] Fixes an issue with dupe copying the savebuffer reference (ugh).
- [X] Streamlines the IGenericWriter API to use better generics.
- [X] Streamlines the IGenericReader API to use better generics.
- [X] Forces `tidying` of a List/HashSet to be done externally since Writers/Readers should not have side effects.
- [X] Fixes an issue where Tidying a list didn't TrimExcess, causing memory leaks.
- [X] Reverted the meaning of `World.Running` to specifically refer to any world state post world loading.
  - NOTE: Do not use this if you want to block on world saves. Instead use checks against `WorldState.Saving` states.
- [X] Fixes an issue with serializing negative DateTime deltas.
- [X] Fixes a potential issue with serializing non-UTC DateTime.

Bumps release version
2020-12-23 07:11:41 -08:00

149 lines
3.5 KiB
C#

using System.Collections.Generic;
namespace Server.Factions.AI
{
public enum ReactionType
{
Ignore,
Warn,
Attack
}
public enum MovementType
{
Stand,
Patrol,
Follow
}
public class Reaction
{
public Reaction(Faction faction, ReactionType type)
{
Faction = faction;
Type = type;
}
public Reaction(IGenericReader reader)
{
var version = reader.ReadEncodedInt();
switch (version)
{
case 0:
{
Faction = Faction.ReadReference(reader);
Type = (ReactionType)reader.ReadEncodedInt();
break;
}
}
}
public Faction Faction { get; }
public ReactionType Type { get; set; }
public void Serialize(IGenericWriter writer)
{
writer.WriteEncodedInt(0); // version
Faction.WriteReference(writer, Faction);
writer.WriteEncodedInt((int)Type);
}
}
public class Orders
{
private readonly List<Reaction> m_Reactions;
public Orders(BaseFactionGuard guard)
{
Guard = guard;
m_Reactions = new List<Reaction>();
Movement = MovementType.Patrol;
}
public Orders(BaseFactionGuard guard, IGenericReader reader)
{
Guard = guard;
var version = reader.ReadEncodedInt();
switch (version)
{
case 1:
{
Follow = reader.ReadEntity<Mobile>();
goto case 0;
}
case 0:
{
var count = reader.ReadEncodedInt();
m_Reactions = new List<Reaction>(count);
for (var i = 0; i < count; ++i)
{
m_Reactions.Add(new Reaction(reader));
}
Movement = (MovementType)reader.ReadEncodedInt();
break;
}
}
}
public BaseFactionGuard Guard { get; }
public MovementType Movement { get; set; }
public Mobile Follow { get; set; }
public Reaction GetReaction(Faction faction)
{
Reaction reaction;
for (var i = 0; i < m_Reactions.Count; ++i)
{
reaction = m_Reactions[i];
if (reaction.Faction == faction)
{
return reaction;
}
}
reaction = new Reaction(
faction,
faction == null || faction == Guard.Faction ? ReactionType.Ignore : ReactionType.Attack
);
m_Reactions.Add(reaction);
return reaction;
}
public void SetReaction(Faction faction, ReactionType type)
{
var reaction = GetReaction(faction);
reaction.Type = type;
}
public void Serialize(IGenericWriter writer)
{
writer.WriteEncodedInt(1); // version
writer.Write(Follow);
writer.WriteEncodedInt(m_Reactions.Count);
for (var i = 0; i < m_Reactions.Count; ++i)
{
m_Reactions[i].Serialize(writer);
}
writer.WriteEncodedInt((int)Movement);
}
}
}