Entity Persistence Refactoring
Entities refactored to enable robust persistence Entities detect stale data references and reload behaviors
This commit is contained in:
parent
87acc75b96
commit
6aeb2ae280
29 changed files with 299 additions and 202 deletions
|
|
@ -7,25 +7,23 @@ using Random = Unity.Mathematics.Random;
|
|||
|
||||
public class AgentController
|
||||
{
|
||||
public Entity Entity { get; }
|
||||
public Guid Entity { get; }
|
||||
public EntityAgent EntityAgent { get; }
|
||||
public GameContext Context { get; }
|
||||
public Guid Zone { get; set; }
|
||||
|
||||
public Guid HomeZone;
|
||||
|
||||
private Locomotion _locomotion;
|
||||
private VelocityMatch _velocityMatch;
|
||||
private Random _random = new Random((uint) (DateTime.Now.Ticks%uint.MaxValue));
|
||||
private Guid _targetOrbit;
|
||||
|
||||
public AgentController(GameContext context, Guid zone, Entity entity)
|
||||
public AgentController(GameContext context, Guid zone, Guid entity)
|
||||
{
|
||||
Entity = entity;
|
||||
Zone = zone;
|
||||
Context = context;
|
||||
EntityAgent = new EntityAgent(context, zone, entity);
|
||||
_locomotion = new Locomotion(entity);
|
||||
EntityAgent = new EntityAgent(context, entity, zone, Guid.Empty);
|
||||
_locomotion = new Locomotion(context, entity);
|
||||
_velocityMatch = new VelocityMatch(context, entity);
|
||||
_velocityMatch.OnMatch += () =>
|
||||
{
|
||||
|
|
@ -44,6 +42,7 @@ public class AgentController
|
|||
// $"Agent Distance: {distance} " +
|
||||
// $"Turnaround Distance: {_stoppingDistance + _turnaroundDistance} " +
|
||||
// $"Objective: {_objective.Key.ID.ToString().Substring(0, 8)}");
|
||||
var entity = Context.Cache.Get<Entity>(Entity);
|
||||
|
||||
if (EntityAgent.CurrentBehavior == _locomotion)
|
||||
{
|
||||
|
|
@ -51,7 +50,7 @@ public class AgentController
|
|||
_velocityMatch.TargetOrbit = _targetOrbit;
|
||||
var matchDistanceTime = _velocityMatch.MatchDistanceTime;
|
||||
_locomotion.Objective = Context.GetOrbitPosition(_targetOrbit) + Context.GetOrbitVelocity(_targetOrbit) * matchDistanceTime.y;
|
||||
var distance = length(_locomotion.Objective - Entity.Position);
|
||||
var distance = length(_locomotion.Objective - entity.Position);
|
||||
if (distance < matchDistanceTime.x)
|
||||
EntityAgent.CurrentBehavior = _velocityMatch;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,19 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using JsonKnownTypes;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
|
||||
[MessagePackObject,
|
||||
Union(0, typeof(StationTowing)),
|
||||
JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<DatabaseEntry>))]
|
||||
public abstract class AgentTask
|
||||
{
|
||||
public abstract AgentJob JobType { get; }
|
||||
public int Priority;
|
||||
public Guid Zone;
|
||||
[IgnoreMember] public abstract AgentJob JobType { get; }
|
||||
[JsonProperty("id"), Key(0)] public int Priority;
|
||||
[JsonProperty("zone"), Key(1)] public Guid Zone;
|
||||
}
|
||||
|
||||
public enum AgentJob
|
||||
|
|
|
|||
|
|
@ -1,24 +1,29 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using JsonKnownTypes;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
[MessagePackObject,
|
||||
JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<Entity>))]
|
||||
public class EntityAgent
|
||||
{
|
||||
public AgentBehavior CurrentBehavior;
|
||||
[IgnoreMember] public AgentBehavior CurrentBehavior;
|
||||
[IgnoreMember] public Guid Entity;
|
||||
[IgnoreMember] public GameContext Context;
|
||||
[JsonProperty("homeZone"), Key(0)] public Guid HomeZone;
|
||||
[JsonProperty("homeColony"), Key(0)] public Guid HomeColony;
|
||||
|
||||
public Entity Entity { get; }
|
||||
public GameContext Context { get; }
|
||||
public Guid Zone { get; set; }
|
||||
|
||||
public EntityAgent(GameContext context, Guid zone, Entity entity)
|
||||
public EntityAgent(GameContext context, Guid entity, Guid homeZone, Guid homeColony)
|
||||
{
|
||||
Entity = entity;
|
||||
Zone = zone;
|
||||
HomeZone = homeZone;
|
||||
Context = context;
|
||||
}
|
||||
|
||||
public void Update(float delta)
|
||||
{
|
||||
CurrentBehavior.Update(delta);
|
||||
CurrentBehavior?.Update(delta);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unity.Mathematics;
|
||||
|
|
@ -7,28 +8,33 @@ using static Unity.Mathematics.math;
|
|||
public class Locomotion : AgentBehavior
|
||||
{
|
||||
public float2 Objective;
|
||||
private Entity _entity;
|
||||
private IAnalogBehavior _thrust;
|
||||
private IAnalogBehavior _turning;
|
||||
private const float Sensitivity = 1;
|
||||
private const float TangentSensitivity = 2;
|
||||
|
||||
private GameContext _context;
|
||||
private Guid _entity;
|
||||
private IAnalogBehavior _thrust;
|
||||
private IAnalogBehavior _turning;
|
||||
|
||||
public Locomotion(Entity entity)
|
||||
public Locomotion(GameContext context, Guid entity)
|
||||
{
|
||||
_context = context;
|
||||
_entity = entity;
|
||||
_thrust = entity.Axes.Keys.FirstOrDefault(x => x is Thruster);
|
||||
_turning = entity.Axes.Keys.FirstOrDefault(x => x is Turning);
|
||||
var entityObject = _context.Cache.Get<Entity>(_entity);
|
||||
_thrust = entityObject.Axes.Keys.FirstOrDefault(x => x is Thruster);
|
||||
_turning = entityObject.Axes.Keys.FirstOrDefault(x => x is Turning);
|
||||
}
|
||||
|
||||
public override void Update(float delta)
|
||||
{
|
||||
var entity = _context.Cache.Get<Entity>(_entity);
|
||||
if (_thrust != null && _turning != null)
|
||||
{
|
||||
float2 diff = Objective - _entity.Position;
|
||||
float2 tangential = _entity.Velocity - dot(normalize(diff), normalize(_entity.Velocity)) * _entity.Velocity;
|
||||
float angleDiff = _entity.Direction.AngleDiff(normalize(diff) - tangential * TangentSensitivity);
|
||||
_entity.Axes[_turning] = clamp(-angleDiff * Sensitivity, -1, 1);
|
||||
_entity.Axes[_thrust] = 1;
|
||||
float2 diff = Objective - entity.Position;
|
||||
float2 tangential = entity.Velocity - dot(normalize(diff), normalize(entity.Velocity)) * entity.Velocity;
|
||||
float angleDiff = entity.Direction.AngleDiff(normalize(diff) - tangential * TangentSensitivity);
|
||||
entity.Axes[_turning] = clamp(-angleDiff * Sensitivity, -1, 1);
|
||||
entity.Axes[_thrust] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using JsonKnownTypes;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
|
||||
[MessagePackObject,
|
||||
JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<DatabaseEntry>))]
|
||||
public class StationTowing : AgentTask
|
||||
{
|
||||
public override AgentJob JobType => AgentJob.Tow;
|
||||
[IgnoreMember] public override AgentJob JobType => AgentJob.Tow;
|
||||
|
||||
private Guid _entity;
|
||||
private Guid _targetOrbit;
|
||||
|
|
|
|||
|
|
@ -9,33 +9,35 @@ public class VelocityMatch : AgentBehavior
|
|||
{
|
||||
public event Action OnMatch;
|
||||
public Guid TargetOrbit;
|
||||
private Entity _entity;
|
||||
private Guid _entity;
|
||||
private IAnalogBehavior _thrust;
|
||||
private IAnalogBehavior _turning;
|
||||
private const float TurningSensitivity = 1;
|
||||
private const float ThrustSensitivity = 1;
|
||||
private const float TargetThreshold = .1f;
|
||||
|
||||
public GameContext Context { get; }
|
||||
|
||||
public VelocityMatch(GameContext context, Entity entity)
|
||||
private GameContext _context;
|
||||
|
||||
public VelocityMatch(GameContext context, Guid entity)
|
||||
{
|
||||
Context = context;
|
||||
_context = context;
|
||||
_entity = entity;
|
||||
_thrust = entity.Axes.Keys.FirstOrDefault(x => x is Thruster);
|
||||
_turning = entity.Axes.Keys.FirstOrDefault(x => x is Turning);
|
||||
var entityObject = _context.Cache.Get<Entity>(_entity);
|
||||
_thrust = entityObject.Axes.Keys.FirstOrDefault(x => x is Thruster);
|
||||
_turning = entityObject.Axes.Keys.FirstOrDefault(x => x is Turning);
|
||||
}
|
||||
|
||||
public override void Update(float delta)
|
||||
{
|
||||
var entity = _context.Cache.Get<Entity>(_entity);
|
||||
if (TargetOrbit != Guid.Empty && _thrust != null && _turning != null)
|
||||
{
|
||||
var deltaV = Context.GetOrbitVelocity(TargetOrbit) - _entity.Velocity;
|
||||
var deltaV = _context.GetOrbitVelocity(TargetOrbit) - entity.Velocity;
|
||||
if(length(deltaV) < TargetThreshold)
|
||||
OnMatch?.Invoke();
|
||||
var angleDiff = _entity.Direction.AngleDiff(deltaV);
|
||||
_entity.Axes[_turning] = clamp(-angleDiff * TurningSensitivity, -1, 1);
|
||||
_entity.Axes[_thrust] = saturate(length(pow(saturate(dot(normalize(_entity.Direction),normalize(deltaV))), 8)*length(deltaV))*ThrustSensitivity);
|
||||
var angleDiff = entity.Direction.AngleDiff(deltaV);
|
||||
entity.Axes[_turning] = clamp(-angleDiff * TurningSensitivity, -1, 1);
|
||||
entity.Axes[_thrust] = saturate(length(pow(saturate(dot(normalize(entity.Direction),normalize(deltaV))), 8)*length(deltaV))*ThrustSensitivity);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -43,14 +45,15 @@ public class VelocityMatch : AgentBehavior
|
|||
{
|
||||
get
|
||||
{
|
||||
var velocity = length(_entity.Velocity);
|
||||
var deltaV = Context.GetOrbitVelocity(TargetOrbit) - _entity.Velocity;
|
||||
var entity = _context.Cache.Get<Entity>(_entity);
|
||||
var velocity = length(entity.Velocity);
|
||||
var deltaV = _context.GetOrbitVelocity(TargetOrbit) - entity.Velocity;
|
||||
|
||||
var stoppingTime = length(deltaV) / (_entity.Context.Evaluate((_thrust.Data as ThrusterData).Thrust, _thrust.Item, _entity) / _entity.Mass);
|
||||
var stoppingTime = length(deltaV) / (_context.Evaluate((_thrust.Data as ThrusterData).Thrust, _thrust.Item, entity) / entity.Mass);
|
||||
var stoppingDistance = stoppingTime * (velocity / 2);
|
||||
|
||||
var angleDiff = _entity.Direction.AngleDiff(deltaV);
|
||||
var turnaroundTime = angleDiff / (_entity.Context.Evaluate((_turning.Data as TurningData).Torque, _turning.Item, _entity) / _entity.Mass);
|
||||
var angleDiff = entity.Direction.AngleDiff(deltaV);
|
||||
var turnaroundTime = angleDiff / (_context.Evaluate((_turning.Data as TurningData).Torque, _turning.Item, entity) / entity.Mass);
|
||||
var turnaroundDistance = turnaroundTime * velocity;
|
||||
|
||||
return float2(stoppingDistance + turnaroundDistance, stoppingTime + turnaroundTime);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using MessagePack;
|
|||
using Newtonsoft.Json;
|
||||
|
||||
[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class AfterburnerData : IBehaviorData
|
||||
public class AfterburnerData : BehaviorData
|
||||
{
|
||||
[InspectableField, JsonProperty("thrust"), Key(0)]
|
||||
public PerformanceStat ThrustModifier = new PerformanceStat();
|
||||
|
|
@ -16,7 +16,7 @@ public class AfterburnerData : IBehaviorData
|
|||
[InspectableField, JsonProperty("torque"), Key(2)]
|
||||
public PerformanceStat TorqueModifier = new PerformanceStat();
|
||||
|
||||
public IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
{
|
||||
return new Afterburner(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@ public class Afterburner : IActivatedBehavior
|
|||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
|
||||
public IBehaviorData Data => _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public Afterburner(GameContext context, AfterburnerData data, Entity entity, Gear item)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public interface IBehavior
|
|||
Entity Entity { get; }
|
||||
Gear Item { get; }
|
||||
GameContext Context { get; }
|
||||
IBehaviorData Data { get; }
|
||||
BehaviorData Data { get; }
|
||||
}
|
||||
|
||||
public interface IActivatedBehavior : IBehavior
|
||||
|
|
@ -35,9 +35,14 @@ public interface IPersistentBehavior//<T> where T : IBehavior
|
|||
PersistentBehaviorData Store();
|
||||
void Restore(PersistentBehaviorData data);
|
||||
}
|
||||
[Union(0, typeof(FactoryPersistence)),
|
||||
|
||||
[MessagePackObject,
|
||||
Union(0, typeof(FactoryPersistence)),
|
||||
JsonObject(MemberSerialization.OptIn),
|
||||
JsonConverter(typeof(JsonKnownTypesConverter<PersistentBehaviorData>))]
|
||||
public class PersistentBehaviorData { }
|
||||
public abstract class PersistentBehaviorData
|
||||
{
|
||||
}
|
||||
|
||||
[InspectableField,
|
||||
Union(0, typeof(ProjectileWeaponData)),
|
||||
|
|
@ -53,8 +58,11 @@ public class PersistentBehaviorData { }
|
|||
Union(10, typeof(VelocityConversionData)),
|
||||
Union(11, typeof(VelocityLimitData)),
|
||||
Union(12, typeof(FactoryData)),
|
||||
JsonConverter(typeof(JsonKnownTypesConverter<IBehaviorData>)), JsonObject(MemberSerialization.OptIn)]
|
||||
public interface IBehaviorData
|
||||
JsonConverter(typeof(JsonKnownTypesConverter<BehaviorData>)), JsonObject(MemberSerialization.OptIn)]
|
||||
public abstract class BehaviorData
|
||||
{
|
||||
IBehavior CreateInstance(GameContext context, Entity entity, Gear item);
|
||||
// [InspectableField, JsonProperty("index"), Key(0)]
|
||||
// public int Index;
|
||||
|
||||
public abstract IBehavior CreateInstance(GameContext context, Entity entity, Gear item);
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ using static Unity.Mathematics.math;
|
|||
using Random = Unity.Mathematics.Random;
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class FactoryData : IBehaviorData
|
||||
public class FactoryData : BehaviorData
|
||||
{
|
||||
[InspectableField, JsonProperty("toolingTime"), Key(0)]
|
||||
public PerformanceStat ToolingTime = new PerformanceStat();
|
||||
|
|
@ -16,7 +16,7 @@ public class FactoryData : IBehaviorData
|
|||
[InspectableField, JsonProperty("automation"), Key(1)]
|
||||
public int AutomationPoints;
|
||||
|
||||
public IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
{
|
||||
return new Factory(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ public class Factory : IBehavior, IPersistentBehavior//<Factory>
|
|||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
|
||||
public IBehaviorData Data => _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private FactoryData _data;
|
||||
|
||||
|
|
@ -109,28 +109,28 @@ public class Factory : IBehavior, IPersistentBehavior//<Factory>
|
|||
};
|
||||
}
|
||||
Context.Cache.Add(newItem);
|
||||
Entity.Cargo.Add(newItem);
|
||||
Entity.Cargo.Add(newItem.ID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var simpleCommodityData = blueprintItemData as SimpleCommodityData;
|
||||
var simpleCommodityInstance = Entity.Cargo.FirstOrDefault(i => i.Data == simpleCommodityData.ID) as SimpleCommodity;
|
||||
if (simpleCommodityInstance == null)
|
||||
var simpleCommodityInstance = Entity.Cargo.FirstOrDefault(i => i == simpleCommodityData.ID);
|
||||
if (simpleCommodityInstance == Guid.Empty)
|
||||
{
|
||||
simpleCommodityInstance = new SimpleCommodity
|
||||
var newSimpleCommodity = new SimpleCommodity
|
||||
{
|
||||
Context = Context,
|
||||
Data = simpleCommodityData.ID,
|
||||
ID = Guid.NewGuid(),
|
||||
Quantity = blueprint.Quantity
|
||||
};
|
||||
Context.Cache.Add(simpleCommodityInstance);
|
||||
Entity.Cargo.Add(simpleCommodityInstance);
|
||||
Context.Cache.Add(newSimpleCommodity);
|
||||
Entity.Cargo.Add(newSimpleCommodity.ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
simpleCommodityInstance.Quantity += blueprint.Quantity;
|
||||
Context.Cache.Get<SimpleCommodity>(simpleCommodityInstance).Quantity += blueprint.Quantity;
|
||||
}
|
||||
}
|
||||
Entity.RecalculateMass();
|
||||
|
|
@ -138,15 +138,15 @@ public class Factory : IBehavior, IPersistentBehavior//<Factory>
|
|||
var simpleIngredients = new List<SimpleCommodity>();
|
||||
var compoundIngredients = new List<CompoundCommodity>();
|
||||
var hasAllIngredients = true;
|
||||
var cargoInstances = Entity.Cargo.Select(c => Context.Cache.Get<ItemInstance>(c));
|
||||
foreach (var kvp in blueprint.Ingredients)
|
||||
{
|
||||
var itemData = Context.Cache.Get(kvp.Key);
|
||||
if (itemData is SimpleCommodityData)
|
||||
{
|
||||
var matchingItem = Entity.Cargo.FirstOrDefault(ii =>
|
||||
var matchingItem = cargoInstances.FirstOrDefault(ii =>
|
||||
{
|
||||
var simpleCommodity = ii as SimpleCommodity;
|
||||
if (simpleCommodity == null) return false;
|
||||
if (!(ii is SimpleCommodity simpleCommodity)) return false;
|
||||
return simpleCommodity.Data == itemData.ID && simpleCommodity.Quantity >= kvp.Value;
|
||||
}) as SimpleCommodity;
|
||||
hasAllIngredients = hasAllIngredients && matchingItem != null;
|
||||
|
|
@ -156,10 +156,10 @@ public class Factory : IBehavior, IPersistentBehavior//<Factory>
|
|||
else
|
||||
{
|
||||
var matchingItems =
|
||||
Entity.Cargo.Where(ii => (ii as CompoundCommodity)?.Data == itemData.ID).Cast<CompoundCommodity>().ToArray();
|
||||
cargoInstances.Where(ii => (ii as CompoundCommodity)?.Data == itemData.ID).Cast<CompoundCommodity>().ToArray();
|
||||
hasAllIngredients = hasAllIngredients && matchingItems.Length >= kvp.Value;
|
||||
if(matchingItems.Length >= kvp.Value)
|
||||
compoundIngredients.AddRange(matchingItems);
|
||||
compoundIngredients.AddRange(matchingItems.Take(kvp.Value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ public class Factory : IBehavior, IPersistentBehavior//<Factory>
|
|||
_reservedStock.AddRange(compoundIngredients);
|
||||
foreach (var compoundCommodity in compoundIngredients)
|
||||
{
|
||||
Entity.Cargo.Remove(compoundCommodity);
|
||||
Entity.Cargo.Remove(compoundCommodity.ID);
|
||||
}
|
||||
foreach (var simpleCommodity in simpleIngredients)
|
||||
{
|
||||
|
|
@ -177,7 +177,7 @@ public class Factory : IBehavior, IPersistentBehavior//<Factory>
|
|||
if (simpleCommodity.Quantity == blueprintQuantity)
|
||||
{
|
||||
_reservedStock.Add(simpleCommodity);
|
||||
Entity.Cargo.Remove(simpleCommodity);
|
||||
Entity.Cargo.Remove(simpleCommodity.ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -230,11 +230,11 @@ public class Factory : IBehavior, IPersistentBehavior//<Factory>
|
|||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class FactoryPersistence : PersistentBehaviorData
|
||||
{
|
||||
public Guid Blueprint;
|
||||
public float RemainingManHours;
|
||||
public bool Retooling;
|
||||
public bool Producing;
|
||||
public Guid[] ReservedStock;
|
||||
public int AssignedPopulation;
|
||||
public float ProductionQuality;
|
||||
[JsonProperty("blueprint"), Key(0)] public Guid Blueprint;
|
||||
[JsonProperty("remainingManHours"), Key(1)] public float RemainingManHours;
|
||||
[JsonProperty("retooling"), Key(2)] public bool Retooling;
|
||||
[JsonProperty("producing"), Key(3)] public bool Producing;
|
||||
[JsonProperty("reservedStock"), Key(4)] public Guid[] ReservedStock;
|
||||
[JsonProperty("assignedPopulation"), Key(5)] public int AssignedPopulation;
|
||||
[JsonProperty("productionQuality"), Key(6)] public float ProductionQuality;
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ using Newtonsoft.Json;
|
|||
using Unity.Mathematics;
|
||||
|
||||
[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class LauncherData : IBehaviorData
|
||||
public class LauncherData : BehaviorData
|
||||
{
|
||||
[InspectablePrefab, JsonProperty("missile"), Key(9)]
|
||||
public string MissilePrefab;
|
||||
|
|
@ -37,7 +37,7 @@ public class LauncherData : IBehaviorData
|
|||
[InspectableField, JsonProperty("lockOnTime"), Key(18)]
|
||||
public PerformanceStat LockOnTime = new PerformanceStat();
|
||||
|
||||
public IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
{
|
||||
return new Launcher(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -162,5 +162,5 @@ public class Launcher : IActivatedBehavior
|
|||
// }
|
||||
}
|
||||
|
||||
public IBehaviorData Data => _launcher;
|
||||
public BehaviorData Data => _launcher;
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ using MessagePack;
|
|||
using Newtonsoft.Json;
|
||||
|
||||
[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class ProjectileWeaponData : WeaponData, IBehaviorData
|
||||
public class ProjectileWeaponData : WeaponData
|
||||
{
|
||||
[InspectablePrefab, JsonProperty("bullet"), Key(9)]
|
||||
public string BulletPrefab;
|
||||
|
|
@ -16,7 +16,7 @@ public class ProjectileWeaponData : WeaponData, IBehaviorData
|
|||
[InspectableField, JsonProperty("bulletVelocity"), Key(12)]
|
||||
public PerformanceStat Velocity = new PerformanceStat();
|
||||
|
||||
public IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
{
|
||||
return new ProjectileWeapon(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -97,5 +97,5 @@ public class ProjectileWeapon : IActivatedBehavior
|
|||
}
|
||||
}
|
||||
|
||||
public IBehaviorData Data => _projectileWeapon;
|
||||
public BehaviorData Data => _projectileWeapon;
|
||||
}
|
||||
|
|
@ -4,12 +4,12 @@ using Unity.Mathematics;
|
|||
using static Unity.Mathematics.math;
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class RadiatorData : IBehaviorData
|
||||
public class RadiatorData : BehaviorData
|
||||
{
|
||||
[InspectableField, JsonProperty("emissivity"), Key(0)]
|
||||
public PerformanceStat Emissivity = new PerformanceStat();
|
||||
|
||||
public IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
{
|
||||
return new Radiator(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ public class Radiator : IBehavior
|
|||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
|
||||
public IBehaviorData Data => _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private RadiatorData _data;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ using MessagePack;
|
|||
using Newtonsoft.Json;
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class ReactorData : IBehaviorData
|
||||
public class ReactorData : BehaviorData
|
||||
{
|
||||
[InspectableField, JsonProperty("charge"), Key(0)]
|
||||
public PerformanceStat Charge = new PerformanceStat();
|
||||
|
|
@ -19,7 +19,7 @@ public class ReactorData : IBehaviorData
|
|||
[InspectableField, JsonProperty("underload"), Key(4)]
|
||||
public PerformanceStat UnderloadRecovery = new PerformanceStat();
|
||||
|
||||
public IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
{
|
||||
return new Reactor(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ public class Reactor : IBehavior
|
|||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
|
||||
public IBehaviorData Data => _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public Reactor(GameContext context, ReactorData data, Entity entity, Gear item)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using Unity.Mathematics;
|
|||
using static Unity.Mathematics.math;
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class ReflectorData : IBehaviorData
|
||||
public class ReflectorData : BehaviorData
|
||||
{
|
||||
[InspectableField, JsonProperty("crossSection"), Key(0)]
|
||||
public PerformanceStat CrossSection = new PerformanceStat();
|
||||
|
|
@ -12,7 +12,7 @@ public class ReflectorData : IBehaviorData
|
|||
// [InspectableAnimationCurve, JsonProperty("visibility"), Key(1)]
|
||||
// public float4[] VisibilityCurve;
|
||||
|
||||
public IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
{
|
||||
return new Reflector(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ public class Reflector : IBehavior
|
|||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
|
||||
public IBehaviorData Data => _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private ReflectorData _data;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ using MessagePack;
|
|||
using Newtonsoft.Json;
|
||||
|
||||
[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class SensorData : IBehaviorData
|
||||
public class SensorData : BehaviorData
|
||||
{
|
||||
[InspectableField, JsonProperty("radiance"), Key(0)]
|
||||
public PerformanceStat Radiance = new PerformanceStat();
|
||||
|
|
@ -17,7 +17,7 @@ public class SensorData : IBehaviorData
|
|||
[InspectableField, JsonProperty("range"), Key(3)]
|
||||
public PerformanceStat Range = new PerformanceStat();
|
||||
|
||||
public IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
{
|
||||
return new Sensor(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ public class Sensor : IBehavior
|
|||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
|
||||
public IBehaviorData Data => _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public Sensor(GameContext context, SensorData data, Entity entity, Gear item)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using Unity.Mathematics;
|
|||
using static Unity.Mathematics.math;
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class ShieldData : IBehaviorData
|
||||
public class ShieldData : BehaviorData
|
||||
{
|
||||
[InspectableField, JsonProperty("efficiency"), Key(0)]
|
||||
public PerformanceStat Efficiency = new PerformanceStat();
|
||||
|
|
@ -12,7 +12,7 @@ public class ShieldData : IBehaviorData
|
|||
[InspectableField, JsonProperty("shielding"), Key(1)]
|
||||
public PerformanceStat Shielding = new PerformanceStat();
|
||||
|
||||
public IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
{
|
||||
return new Shield(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ public class Shield : IBehavior
|
|||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
|
||||
public IBehaviorData Data => _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private ShieldData _data;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using Unity.Mathematics;
|
|||
using static Unity.Mathematics.math;
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn), EntityTypeRestriction(HullType.Ship)]
|
||||
public class ThrusterData : IBehaviorData
|
||||
public class ThrusterData : BehaviorData
|
||||
{
|
||||
[InspectableField, JsonProperty("thrust"), Key(0)]
|
||||
public PerformanceStat Thrust = new PerformanceStat();
|
||||
|
|
@ -15,7 +15,7 @@ public class ThrusterData : IBehaviorData
|
|||
[InspectableField, JsonProperty("heat"), Key(2)]
|
||||
public PerformanceStat Heat = new PerformanceStat();
|
||||
|
||||
public IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
{
|
||||
return new Thruster(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ public class Thruster : IAnalogBehavior
|
|||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
|
||||
public IBehaviorData Data => _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private ThrusterData _data;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using Unity.Mathematics;
|
|||
using static Unity.Mathematics.math;
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class TurningData : IBehaviorData
|
||||
public class TurningData : BehaviorData
|
||||
{
|
||||
[InspectableField, JsonProperty("torque"), Key(0)]
|
||||
public PerformanceStat Torque = new PerformanceStat();
|
||||
|
|
@ -15,7 +15,7 @@ public class TurningData : IBehaviorData
|
|||
[InspectableField, JsonProperty("heat"), Key(2)]
|
||||
public PerformanceStat Heat = new PerformanceStat();
|
||||
|
||||
public IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
{
|
||||
return new Turning(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ public class Turning : IAnalogBehavior
|
|||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
|
||||
public IBehaviorData Data => _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private TurningData _data;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ using Unity.Mathematics;
|
|||
using static Unity.Mathematics.math;
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class VelocityConversionData : IBehaviorData
|
||||
public class VelocityConversionData : BehaviorData
|
||||
{
|
||||
[InspectableField, JsonProperty("traction"), Key(0)]
|
||||
public PerformanceStat Traction = new PerformanceStat();
|
||||
|
||||
public IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
{
|
||||
return new VelocityConversion(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ public class VelocityConversion : IBehavior
|
|||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
|
||||
public IBehaviorData Data => _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private VelocityConversionData _data;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ using Unity.Mathematics;
|
|||
using static Unity.Mathematics.math;
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class VelocityLimitData : IBehaviorData
|
||||
public class VelocityLimitData : BehaviorData
|
||||
{
|
||||
[InspectableField, JsonProperty("topSpeed"), Key(0)]
|
||||
public PerformanceStat TopSpeed = new PerformanceStat();
|
||||
|
||||
public IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
{
|
||||
return new VelocityLimit(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ public class VelocityLimit : IBehavior
|
|||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
|
||||
public IBehaviorData Data => _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private VelocityLimitData _data;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ using Newtonsoft.Json;
|
|||
|
||||
[Union(0, typeof(ProjectileWeaponData)),
|
||||
Union(1, typeof(LauncherData))]
|
||||
public abstract class WeaponData
|
||||
public abstract class WeaponData : BehaviorData
|
||||
{
|
||||
[InspectableField, JsonProperty("damageType"), Key(0)]
|
||||
public DamageType DamageType;
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ public class BlueprintStatEffect
|
|||
[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class StatReference
|
||||
{
|
||||
[InspectableType(typeof(IBehaviorData)), JsonProperty("behavior"), Key(1)]
|
||||
[InspectableType(typeof(BehaviorData)), JsonProperty("behavior"), Key(1)]
|
||||
public string Behavior;
|
||||
|
||||
[InspectableField, JsonProperty("stat"), Key(2)]
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ public class Player : DatabaseEntry, INamedEntry
|
|||
public class Corporation : DatabaseEntry, INamedEntry
|
||||
{
|
||||
[JsonProperty("name"), Key(1)] public string Name;
|
||||
[JsonProperty("tasks"), Key(2)] public List<AgentTask> Tasks = new List<AgentTask>();
|
||||
|
||||
[IgnoreMember] public string EntryName
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,32 +15,35 @@ using static Unity.Mathematics.math;
|
|||
JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<Entity>))]
|
||||
public abstract class Entity : DatabaseEntry, IMessagePackSerializationCallbackReceiver
|
||||
{
|
||||
[JsonProperty("temperature"), Key(1)] public float Temperature;
|
||||
[JsonProperty("energy"), Key(2)] public float Energy;
|
||||
[JsonProperty("position"), Key(3)] public float2 Position;
|
||||
[JsonProperty("direction"), Key(4)] public float2 Direction = float2(0,1);
|
||||
[JsonProperty("velocity"), Key(5)] public float2 Velocity;
|
||||
[JsonProperty("cargo"), Key(6)] public readonly List<Guid> Cargo; // Type: ItemInstance
|
||||
[JsonProperty("equipment"), Key(7)] public readonly List<Guid> EquippedItems; // Type: Gear
|
||||
[JsonProperty("parent"), Key(8)] public Guid Parent; // Type: Entity
|
||||
[JsonProperty("children"), Key(9)] public List<Guid> Children = new List<Guid>(); // Type: Entity
|
||||
[JsonProperty("hull"), Key(10)] public Guid Hull; // Type: Gear
|
||||
[JsonProperty("persistedBehaviorData"), Key(11)] public Dictionary<Guid, PersistentBehaviorData[]> PersistedBehaviors;
|
||||
[JsonProperty("agent"), Key(12)] public EntityAgent Agent;
|
||||
|
||||
// [IgnoreMember] protected List<IBehavior> Behaviors;
|
||||
[IgnoreMember] public Guid Zone;
|
||||
[IgnoreMember] public Dictionary<Gear, List<IBehavior>> ItemBehaviors;
|
||||
[IgnoreMember] public Dictionary<Gear, List<IActivatedBehavior>> Bindings;
|
||||
[IgnoreMember] public Dictionary<IAnalogBehavior, float> Axes;
|
||||
[IgnoreMember] public Dictionary<IAnalogBehavior, float> AxisOverrides = new Dictionary<IAnalogBehavior, float>();
|
||||
[IgnoreMember] public readonly Dictionary<object, float> VisibilitySources = new Dictionary<object, float>();
|
||||
public float Temperature;
|
||||
public float Energy;
|
||||
public float2 Position;
|
||||
public float2 Direction = float2(0,1);
|
||||
public float2 Velocity;
|
||||
[IgnoreMember] public Dictionary<Guid, List<IActivatedBehavior>> Bindings;
|
||||
[IgnoreMember] public Dictionary<IAnalogBehavior, float> Axes;
|
||||
public readonly List<ItemInstance> Cargo;
|
||||
public readonly List<Gear> EquippedItems;
|
||||
public Entity Parent;
|
||||
public List<Entity> Children = new List<Entity>();
|
||||
public Guid Zone;
|
||||
|
||||
[IgnoreMember] protected List<IBehavior> Behaviors;
|
||||
|
||||
public Gear Hull { get; }
|
||||
private Dictionary<Gear, EquippableItemData> GearData;
|
||||
|
||||
[IgnoreMember] public float Mass { get; private set; }
|
||||
[IgnoreMember] public float SpecificHeat { get; private set; }
|
||||
[IgnoreMember] public float Visibility => VisibilitySources.Values.Sum();
|
||||
|
||||
public PersistentBehaviorData[] PersistedBehaviors;
|
||||
|
||||
public Entity(GameContext context, Gear hull, IEnumerable<Gear> items, IEnumerable<ItemInstance> cargo)
|
||||
public Entity(GameContext context, Guid hull, IEnumerable<Guid> items, IEnumerable<Guid> cargo)
|
||||
{
|
||||
ID = Guid.NewGuid();
|
||||
Context = context;
|
||||
|
|
@ -51,24 +54,35 @@ public abstract class Entity : DatabaseEntry, IMessagePackSerializationCallbackR
|
|||
|
||||
RecalculateMass();
|
||||
|
||||
var activeItems = Hull == null ? EquippedItems : EquippedItems.Append(Hull);
|
||||
AddItemBehaviors();
|
||||
}
|
||||
|
||||
public void AddItemBehaviors()
|
||||
{
|
||||
var gear = EquippedItems.Append(Hull);
|
||||
var gearData = gear.ToDictionary(id => id, id => Context.Cache.Get<Gear>(id));
|
||||
GearData = gearData.Values.ToDictionary(g => g, g => g.ItemData);
|
||||
|
||||
Behaviors = activeItems
|
||||
.Where(i=>i.ItemData.Behaviors?.Any()??false)
|
||||
.SelectMany(i => i.ItemData.Behaviors
|
||||
.Select(bd => bd.CreateInstance(Context, this, i)))
|
||||
var allbehaviors = gear
|
||||
.Where(i=>gearData[i].ItemData.Behaviors?.Any()??false)
|
||||
.SelectMany(i => gearData[i].ItemData.Behaviors
|
||||
.Select(bd => bd.CreateInstance(Context, this, gearData[i])))
|
||||
.OrderBy(b => b.GetType().GetCustomAttribute<UpdateOrderAttribute>()?.Order ?? 0).ToList();
|
||||
|
||||
Bindings = Behaviors
|
||||
ItemBehaviors = allbehaviors
|
||||
.GroupBy(b => b.Item.ID, (guid, behaviors) => new {guid, behaviors})
|
||||
.ToDictionary(g => gearData[g.guid], g => g.behaviors.ToList());
|
||||
|
||||
Bindings = allbehaviors
|
||||
.Where(b => b is IActivatedBehavior)
|
||||
.GroupBy(b => b.Item.ID, (guid, behaviors) => new {guid, behaviors})
|
||||
.ToDictionary(g => g.guid, g => g.behaviors.Cast<IActivatedBehavior>().ToList());
|
||||
.ToDictionary(g => gearData[g.guid], g => g.behaviors.Cast<IActivatedBehavior>().ToList());
|
||||
|
||||
Axes = Behaviors
|
||||
Axes = allbehaviors
|
||||
.Where(b => b is IAnalogBehavior)
|
||||
.ToDictionary(b => b as IAnalogBehavior, b => 0f);
|
||||
|
||||
foreach (var behavior in Behaviors)
|
||||
foreach (var behavior in allbehaviors)
|
||||
{
|
||||
behavior.Initialize();
|
||||
}
|
||||
|
|
@ -76,28 +90,30 @@ public abstract class Entity : DatabaseEntry, IMessagePackSerializationCallbackR
|
|||
|
||||
public void RecalculateMass()
|
||||
{
|
||||
Mass = Hull?.Mass ?? 0 +
|
||||
EquippedItems.Sum(i => i.Mass) +
|
||||
Cargo.Sum(ii => ii.Mass) +
|
||||
Children.Sum(c=>c.Mass);
|
||||
Mass = Context.Cache.Get<Gear>(Hull).Mass +
|
||||
EquippedItems.Select(i => Context.Cache.Get<Gear>(i)).Sum(i => i.Mass) +
|
||||
Cargo.Select(i => Context.Cache.Get<ItemInstance>(i)).Sum(ii => ii.Mass) +
|
||||
Children.Select(i => Context.Cache.Get<Entity>(i)).Sum(c=>c.Mass);
|
||||
|
||||
SpecificHeat = (Hull?.HeatCapacity ?? 0) +
|
||||
EquippedItems.Sum(i => i.HeatCapacity) +
|
||||
Cargo.Sum(ii => ii.HeatCapacity);
|
||||
SpecificHeat = Context.Cache.Get<Gear>(Hull).HeatCapacity +
|
||||
EquippedItems.Select(i => Context.Cache.Get<Gear>(i)).Sum(i => i.HeatCapacity) +
|
||||
Cargo.Select(i => Context.Cache.Get<ItemInstance>(i)).Sum(ii => ii.HeatCapacity);
|
||||
}
|
||||
|
||||
public IEnumerable<T> GetBehaviors<T>() where T : class, IBehavior
|
||||
{
|
||||
foreach (var behavior in Behaviors)
|
||||
if (behavior is T b)
|
||||
yield return b;
|
||||
foreach (var behaviors in ItemBehaviors.Values)
|
||||
foreach (var behavior in behaviors)
|
||||
if (behavior is T b)
|
||||
yield return b;
|
||||
}
|
||||
|
||||
public IEnumerable<T> GetBehaviorData<T>() where T : class, IBehaviorData
|
||||
public IEnumerable<T> GetBehaviorData<T>() where T : BehaviorData
|
||||
{
|
||||
foreach (var behavior in Behaviors)
|
||||
if (behavior.Data is T b)
|
||||
yield return b;
|
||||
foreach (var behaviors in ItemBehaviors.Values)
|
||||
foreach (var behavior in behaviors)
|
||||
if (behavior.Data is T b)
|
||||
yield return b;
|
||||
}
|
||||
|
||||
public void AddHeat(float heat)
|
||||
|
|
@ -109,60 +125,103 @@ public abstract class Entity : DatabaseEntry, IMessagePackSerializationCallbackR
|
|||
{
|
||||
foreach(var analogBehavior in Axes.Keys)
|
||||
analogBehavior.SetAxis(AxisOverrides.ContainsKey(analogBehavior) ? AxisOverrides[analogBehavior] : Axes[analogBehavior]);
|
||||
|
||||
foreach(var behavior in Behaviors)
|
||||
|
||||
foreach (var behavior in ItemBehaviors.SelectMany(item => item.Value))
|
||||
behavior.Update(delta);
|
||||
|
||||
foreach (var item in EquippedItems.Where(item => item.ItemData.Performance(Temperature) < .01f))
|
||||
foreach (var staleItem in GearData
|
||||
.Where(kvp=>kvp.Key.ItemData!=kvp.Value)
|
||||
.Select(kvp=>kvp.Key))
|
||||
{
|
||||
// Item is stale, there's an updated one in the database cache
|
||||
//var actualItem = Context.Cache.Get<Gear>(staleItem.ID);
|
||||
var staleBehaviors = ItemBehaviors[staleItem];
|
||||
ItemBehaviors.Remove(staleItem);
|
||||
|
||||
// We'll be reloading the item along with its behaviors, some data must be persisted
|
||||
var persistentData = staleBehaviors
|
||||
.Where(b => b is IPersistentBehavior)
|
||||
.Cast<IPersistentBehavior>()
|
||||
.Select(b => b.Store());
|
||||
|
||||
// Regenerate the behavior list for the updated item
|
||||
ItemBehaviors[staleItem] = staleItem.ItemData.Behaviors
|
||||
.Select(bd => bd.CreateInstance(Context, this, staleItem))
|
||||
.OrderBy(b => b.GetType().GetCustomAttribute<UpdateOrderAttribute>()?.Order ?? 0).ToList();
|
||||
|
||||
// Restore state for persisted behaviors
|
||||
foreach(var persistentBehaviorData in ItemBehaviors[staleItem]
|
||||
.Where(b => b is IPersistentBehavior)
|
||||
.Cast<IPersistentBehavior>()
|
||||
.Zip(persistentData, (behavior, data) => new {behavior, data}))
|
||||
persistentBehaviorData.behavior.Restore(persistentBehaviorData.data);
|
||||
|
||||
// Regenerate activated behavior bindings
|
||||
if (Bindings.ContainsKey(staleItem))
|
||||
{
|
||||
Bindings.Remove(staleItem);
|
||||
Bindings[staleItem] = ItemBehaviors[staleItem]
|
||||
.Where(b => b is IActivatedBehavior)
|
||||
.Cast<IActivatedBehavior>().ToList();
|
||||
}
|
||||
|
||||
// Remove axis bindings and overrides for analog behaviors
|
||||
foreach (var axis in staleBehaviors.Where(b => b is IAnalogBehavior).Cast<IAnalogBehavior>())
|
||||
{
|
||||
Axes.Remove(axis);
|
||||
if (AxisOverrides.ContainsKey(axis))
|
||||
AxisOverrides.Remove(axis);
|
||||
}
|
||||
|
||||
// Regenerate axis bindings for analog behaviors
|
||||
foreach (var axis in ItemBehaviors[staleItem].Where(b => b is IAnalogBehavior).Cast<IAnalogBehavior>())
|
||||
Axes[axis] = 0;
|
||||
}
|
||||
|
||||
foreach (var item in EquippedItems
|
||||
.Select(item => Context.Cache.Get<Gear>(item))
|
||||
.Where(item => item.ItemData.Performance(Temperature) < .01f))
|
||||
item.Durability -= delta;
|
||||
|
||||
if (Parent != null)
|
||||
if (Parent != Guid.Empty)
|
||||
{
|
||||
Position = Parent.Position;
|
||||
Velocity = Parent.Velocity;
|
||||
var parent = Context.Cache.Get<Entity>(Parent);
|
||||
Position = parent.Position;
|
||||
Velocity = parent.Velocity;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
PersistedBehaviors = Behaviors
|
||||
.Where(b => b is IPersistentBehavior)
|
||||
.Cast<IPersistentBehavior>()
|
||||
.Select(b => b.Store()).ToArray();
|
||||
// Filter item behavior collections by those with any persistent behaviors
|
||||
// For each item create an object containing the item ID and a list of persistent behaviors
|
||||
// Then turn that into a dictionary mapping from item ID to an array of every behaviors persistent data
|
||||
PersistedBehaviors = ItemBehaviors
|
||||
.Where(x => x.Value.Any(b=>b is IPersistentBehavior))
|
||||
.Select(x => new {gear=x.Key, behaviors = x.Value
|
||||
.Where(b=>b is IPersistentBehavior)
|
||||
.Cast<IPersistentBehavior>()})
|
||||
.ToDictionary(x=> x.gear.ID, x=>x.behaviors.Select(b => b.Store()).ToArray());
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
RecalculateMass();
|
||||
|
||||
var activeItems = Hull == null ? EquippedItems : EquippedItems.Append(Hull);
|
||||
|
||||
Behaviors = activeItems
|
||||
.Where(i=>i.ItemData.Behaviors?.Any()??false)
|
||||
.SelectMany(i => i.ItemData.Behaviors
|
||||
.Select(bd => bd.CreateInstance(Context, this, i)))
|
||||
.OrderBy(b => b.GetType().GetCustomAttribute<UpdateOrderAttribute>()?.Order ?? 0).ToList();
|
||||
AddItemBehaviors();
|
||||
|
||||
var index = 0;
|
||||
foreach (var persistentBehavior in Behaviors
|
||||
.Where(b => b is IPersistentBehavior)
|
||||
.Cast<IPersistentBehavior>())
|
||||
{
|
||||
persistentBehavior.Restore(PersistedBehaviors[index++]);
|
||||
}
|
||||
|
||||
Bindings = Behaviors
|
||||
.Where(b => b is IActivatedBehavior)
|
||||
.GroupBy(b => b.Item.ID, (guid, behaviors) => new {guid, behaviors})
|
||||
.ToDictionary(g => g.guid, g => g.behaviors.Cast<IActivatedBehavior>().ToList());
|
||||
|
||||
Axes = Behaviors
|
||||
.Where(b => b is IAnalogBehavior)
|
||||
.ToDictionary(b => b as IAnalogBehavior, b => 0f);
|
||||
|
||||
foreach (var behavior in Behaviors)
|
||||
{
|
||||
behavior.Initialize();
|
||||
}
|
||||
// Iterate only over the behaviors of items which contain persistent data
|
||||
// Filter the behaviors for each item to get the persistent ones, then cast them and combine with the persisted data array for that item
|
||||
foreach (var persistentBehaviorData in ItemBehaviors
|
||||
.Where(itemBehaviors => PersistedBehaviors.ContainsKey(itemBehaviors.Key.ID)).
|
||||
SelectMany(itemBehaviors => itemBehaviors.Value
|
||||
.Where(b=> b is IPersistentBehavior)
|
||||
.Cast<IPersistentBehavior>()
|
||||
.Zip(PersistedBehaviors[itemBehaviors.Key.ID], (behavior, data) => new{behavior, data})))
|
||||
persistentBehaviorData.behavior.Restore(persistentBehaviorData.data);
|
||||
|
||||
Agent.Context = Context;
|
||||
Agent.Entity = ID;
|
||||
}
|
||||
}
|
||||
|
|
@ -105,7 +105,7 @@ public abstract class EquippableItemData : CraftedItemData
|
|||
public PerformanceStat HeatExponent = new PerformanceStat();
|
||||
|
||||
[InspectableField, JsonProperty("behaviors"), Key(13)]
|
||||
public List<IBehaviorData> Behaviors = new List<IBehaviorData>();
|
||||
public List<BehaviorData> Behaviors = new List<BehaviorData>();
|
||||
|
||||
[IgnoreMember]
|
||||
public abstract HardpointType HardpointType { get; }
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ public class OrbitalEntity : Entity
|
|||
{
|
||||
private Guid _orbitData;
|
||||
|
||||
public OrbitalEntity(GameContext context, Gear hull, IEnumerable<Gear> items, IEnumerable<ItemInstance> cargo, Guid orbit) : base(context, hull, items, cargo)
|
||||
public OrbitalEntity(GameContext context, Guid hull, IEnumerable<Guid> items, IEnumerable<Guid> cargo, Guid orbit) : base(context, hull, items, cargo)
|
||||
{
|
||||
_orbitData = orbit;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public class Ship : Entity
|
|||
// [IgnoreMember] public Dictionary<Targetable, float> Contacts = new Dictionary<Targetable, float>();
|
||||
// [IgnoreMember] public Targetable Target;
|
||||
|
||||
public Ship(GameContext context, Gear hull, IEnumerable<Gear> items, IEnumerable<ItemInstance> cargo) : base(context, hull, items, cargo)
|
||||
public Ship(GameContext context, Guid hull, IEnumerable<Guid> items, IEnumerable<Guid> cargo) : base(context, hull, items, cargo)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue