diff --git a/.idea/.idea.Aetheria-Economy/.idea/contentModel.xml b/.idea/.idea.Aetheria-Economy/.idea/contentModel.xml index 021005cb9..b8ae16f57 100644 --- a/.idea/.idea.Aetheria-Economy/.idea/contentModel.xml +++ b/.idea/.idea.Aetheria-Economy/.idea/contentModel.xml @@ -1252,26 +1252,32 @@ - + + + + + + + @@ -1732,6 +1738,7 @@ + diff --git a/Assets/Scripts/Editor/DatabaseInspector.cs b/Assets/Scripts/Editor/DatabaseInspector.cs index 34870f887..6dd94becf 100644 --- a/Assets/Scripts/Editor/DatabaseInspector.cs +++ b/Assets/Scripts/Editor/DatabaseInspector.cs @@ -181,6 +181,7 @@ public class DatabaseInspector : EditorWindow else field.SetValue(obj, Inspect(field.Name.SplitCamelCase(), (string) value, inspectable is InspectableTextAttribute)); } + else if (type == typeof(Type) && inspectable is InspectableTypeAttribute typeAttribute) field.SetValue(obj, Inspect(field.Name.SplitCamelCase(), (Type) value, typeAttribute.Type)); else if (type == typeof(GameObject)) field.SetValue(obj, Inspect(field.Name.SplitCamelCase(), (GameObject) value)); else if (type == typeof(AnimationCurve)) field.SetValue(obj, Inspect(field.Name.SplitCamelCase(), (AnimationCurve) value)); else if (type == typeof(PerformanceStat)) field.SetValue(obj, Inspect(field.Name.SplitCamelCase(), (PerformanceStat) value, obj as CraftedItemData)); @@ -200,6 +201,11 @@ public class DatabaseInspector : EditorWindow field.SetValue(obj, stats); } } + else if (type == typeof(StatReference)) + { + var statRef = (StatReference) field.GetValue(obj); + Inspect(field.Name.SplitCamelCase(), ref statRef); + } else if (type == typeof(Dictionary)) { var dict = (Dictionary) field.GetValue(obj); @@ -567,6 +573,21 @@ public class DatabaseInspector : EditorWindow } } + public Type Inspect(string label, Type value, Type parentType) + { + var types = parentType.GetAllChildClasses(); + var enumOptions = new[] {"None"}.Concat(types.Select(t => t.Name)).ToArray(); + var index = Array.IndexOf(types, value) + 1; + + using (var h = new HorizontalScope()) + { + GUILayout.Label(label, GUILayout.Width(width)); + index = Popup(index, enumOptions); + } + + return index == 0 ? null : types[index - 1]; + } + public string InspectGameObject(string label, string value) { using (var h = new HorizontalScope()) @@ -826,13 +847,65 @@ public class DatabaseInspector : EditorWindow } } } + + public void Inspect(string label, ref StatReference effect) + { + using (new HorizontalScope()) + { + GUILayout.Label(label, GUILayout.Width(width)); + + using (new VerticalScope()) + { + var targetObjects = typeof(BehaviorData).GetAllChildClasses() + .Concat(typeof(EquippableItemData).GetAllChildClasses()).ToArray(); + var objectNames = targetObjects.Select(b => b.Name).ToArray(); + var selectedIndex = Array.IndexOf(objectNames, effect.Target); + if (selectedIndex == -1) + { + selectedIndex = 0; + GUI.changed = true; + } + using (new HorizontalScope()) + { + GUILayout.Label("Target", GUILayout.Width(width)); + var newSelection = Popup(selectedIndex, objectNames); + if (newSelection != selectedIndex) + GUI.changed = true; + effect.Target = objectNames[newSelection]; + } + + using (new HorizontalScope()) + { + GUILayout.Label("Stat", GUILayout.Width(width)); + var stats = targetObjects[selectedIndex].GetFields() + .Where(f => f.FieldType == typeof(PerformanceStat)).ToArray(); + if(stats.Length==0) + GUILayout.Label("No Stats!"); + else + { + var statNames = stats.Select(s => s.Name).ToArray(); + var selectedStatIndex = Array.IndexOf(statNames, effect.Stat); + if (selectedStatIndex == -1) + { + selectedStatIndex = 0; + GUI.changed = true; + } + var newSelection = Popup(selectedStatIndex, statNames); + if (newSelection != selectedStatIndex) + GUI.changed = true; + effect.Stat = statNames[newSelection]; + } + } + } + } + } public void Inspect(ref StatReference effect, EquippableItemData item) { using (new VerticalScope()) { var behaviorNames = new []{item.Name}.Concat(item.Behaviors.Select(b => b.GetType().Name)).ToArray(); - var selectedBehaviorIndex = Array.IndexOf(behaviorNames, effect.Behavior); + var selectedBehaviorIndex = Array.IndexOf(behaviorNames, effect.Target); if (selectedBehaviorIndex == -1) { selectedBehaviorIndex = 0; @@ -844,7 +917,7 @@ public class DatabaseInspector : EditorWindow var newSelection = Popup(selectedBehaviorIndex, behaviorNames); if (newSelection != selectedBehaviorIndex) GUI.changed = true; - effect.Behavior = behaviorNames[newSelection]; + effect.Target = behaviorNames[newSelection]; } using (new HorizontalScope()) diff --git a/Assets/Scripts/ServerShared/Behaviors/ActivatedItemUsage.cs b/Assets/Scripts/ServerShared/Behaviors/ActivatedItemUsage.cs deleted file mode 100644 index 383cdfb5f..000000000 --- a/Assets/Scripts/ServerShared/Behaviors/ActivatedItemUsage.cs +++ /dev/null @@ -1,54 +0,0 @@ -using MessagePack; -using Newtonsoft.Json; - -[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)] -public class ActivatedItemUsageData : BehaviorData -{ - - public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) - { - return new ActivatedItemUsage(context, this, entity, item); - } -} - -public class ActivatedItemUsage : IActivatedBehavior -{ - private ActivatedItemUsageData _data; - - private Entity Entity { get; } - private Gear Item { get; } - private GameContext Context { get; } - - public BehaviorData Data => _data; - - public ActivatedItemUsage(GameContext context, ActivatedItemUsageData data, Entity entity, Gear item) - { - _data = data; - Entity = entity; - Item = item; - Context = context; - } - - public void Initialize() - { - } - - public bool Activate() - { - throw new System.NotImplementedException(); - } - - public void Deactivate() - { - throw new System.NotImplementedException(); - } - - public bool Update(float delta) - { - return true; - } - - public void Remove() - { - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Afterburner.cs b/Assets/Scripts/ServerShared/Behaviors/Afterburner.cs index 5d777d89c..26ec0b6fa 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Afterburner.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Afterburner.cs @@ -4,88 +4,88 @@ using System.Linq; using MessagePack; using Newtonsoft.Json; -[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)] -public class AfterburnerData : BehaviorData -{ - [InspectableField, JsonProperty("thrust"), Key(1)] - public PerformanceStat ThrustModifier = new PerformanceStat(); - - [InspectableField, JsonProperty("speed"), Key(2)] - public PerformanceStat SpeedModifier = new PerformanceStat(); - - [InspectableField, JsonProperty("torque"), Key(3)] - public PerformanceStat TorqueModifier = new PerformanceStat(); - - public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) - { - return new Afterburner(context, this, entity, item); - } -} - -public class Afterburner : IActivatedBehavior -{ - private List> _modifiers = new List>(); - private AfterburnerData _data; - private Thruster _thruster; - private int _thrustAxis; - - public Entity Entity { get; } - public Gear Item { get; } - public GameContext Context { get; } - - public BehaviorData Data => _data; - - public Afterburner(GameContext context, AfterburnerData data, Entity entity, Gear item) - { - Context = context; - _data = data; - Entity = entity; - Item = item; - } - - public void Initialize() - { - _thruster = Entity.GetBehaviors().FirstOrDefault(); - _thrustAxis = Entity.GetAxis(); - } - - public bool Update(float delta) - { - return true; - } - - public bool Activate() - { - if (_thruster == null) return false; - - var thrustMod = ((ThrusterData) _thruster.Data).Thrust.GetScaleModifiers(Entity); - thrustMod.Add(this,Context.Evaluate(_data.ThrustModifier,Item, Entity)); - _modifiers.Add(thrustMod); - - Entity.AxisOverrides[_thrustAxis] = 1; - - return true; - - // var speedMod = (Ship.Hull.ItemData as HullData).TopSpeed.GetScaleModifiers(Ship); - // _modifiers.Add(speedMod); - // speedMod.Add(this,Context.Evaluate(_data.SpeedModifier,Item, Ship)); - // - // var torqueMod = (Ship.GetEquipped(HardpointType.Thruster).ItemData as ThrusterData).Torque.GetScaleModifiers(Ship); - // _modifiers.Add(torqueMod); - // torqueMod.Add(this,Context.Evaluate(_data.TorqueModifier,Item, Ship)); - } - - public void Deactivate() - { - Entity.AxisOverrides.Remove(_thrustAxis); - foreach (var mod in _modifiers) - { - mod.Remove(this); - } - _modifiers.Clear(); - } - - public void Remove() - { - } -} \ No newline at end of file +// [InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)] +// public class AfterburnerData : BehaviorData +// { +// [InspectableField, JsonProperty("thrust"), Key(1)] +// public PerformanceStat ThrustModifier = new PerformanceStat(); +// +// [InspectableField, JsonProperty("speed"), Key(2)] +// public PerformanceStat SpeedModifier = new PerformanceStat(); +// +// [InspectableField, JsonProperty("torque"), Key(3)] +// public PerformanceStat TorqueModifier = new PerformanceStat(); +// +// public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) +// { +// return new Afterburner(context, this, entity, item); +// } +// } +// +// public class Afterburner : IActivatedBehavior +// { +// private List> _modifiers = new List>(); +// private AfterburnerData _data; +// private Thruster _thruster; +// private int _thrustAxis; +// +// public Entity Entity { get; } +// public Gear Item { get; } +// public GameContext Context { get; } +// +// public BehaviorData Data => _data; +// +// public Afterburner(GameContext context, AfterburnerData data, Entity entity, Gear item) +// { +// Context = context; +// _data = data; +// Entity = entity; +// Item = item; +// } +// +// public void Initialize() +// { +// _thruster = Entity.GetBehaviors().FirstOrDefault(); +// _thrustAxis = Entity.GetAxis(); +// } +// +// public bool Update(float delta) +// { +// return true; +// } +// +// public bool Activate() +// { +// if (_thruster == null) return false; +// +// var thrustMod = ((ThrusterData) _thruster.Data).Thrust.GetScaleModifiers(Entity); +// thrustMod.Add(this,Context.Evaluate(_data.ThrustModifier,Item, Entity)); +// _modifiers.Add(thrustMod); +// +// Entity.AxisOverrides[_thrustAxis] = 1; +// +// return true; +// +// // var speedMod = (Ship.Hull.ItemData as HullData).TopSpeed.GetScaleModifiers(Ship); +// // _modifiers.Add(speedMod); +// // speedMod.Add(this,Context.Evaluate(_data.SpeedModifier,Item, Ship)); +// // +// // var torqueMod = (Ship.GetEquipped(HardpointType.Thruster).ItemData as ThrusterData).Torque.GetScaleModifiers(Ship); +// // _modifiers.Add(torqueMod); +// // torqueMod.Add(this,Context.Evaluate(_data.TorqueModifier,Item, Ship)); +// } +// +// public void Deactivate() +// { +// Entity.AxisOverrides.Remove(_thrustAxis); +// foreach (var mod in _modifiers) +// { +// mod.Remove(this); +// } +// _modifiers.Clear(); +// } +// +// public void Remove() +// { +// } +// } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Behaviors.cs b/Assets/Scripts/ServerShared/Behaviors/Behaviors.cs index c6f394435..193f86992 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Behaviors.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Behaviors.cs @@ -11,23 +11,36 @@ using static Unity.Mathematics.noise; public interface IBehavior { - void Initialize(); bool Update(float delta); - void Remove(); BehaviorData Data { get; } } -public interface IActivatedBehavior : IBehavior -{ - bool Activate(); - void Deactivate(); -} +// public interface IActivatedBehavior : IBehavior +// { +// bool Activate(); +// void Deactivate(); +// } public interface IAnalogBehavior : IBehavior { void SetAxis(float value); } +public interface IDisposableBehavior +{ + void Dispose(); +} + +public interface IInitializableBehavior +{ + void Initialize(); +} + +public interface IAlwaysUpdatedBehavior +{ + void AlwaysUpdate(float delta); +} + public interface IPersistentBehavior// where T : IBehavior { PersistentBehaviorData Store(); @@ -55,7 +68,7 @@ public abstract class PersistentBehaviorData Union(1, typeof(LauncherData)), Union(2, typeof(ReactorData)), Union(3, typeof(RadiatorData)), - Union(4, typeof(AfterburnerData)), + Union(4, typeof(StatModifierData)), Union(5, typeof(SensorData)), Union(6, typeof(ReflectorData)), Union(7, typeof(ShieldData)), @@ -66,6 +79,14 @@ public abstract class PersistentBehaviorData Union(12, typeof(FactoryData)), Union(13, typeof(PatrolControllerData)), Union(14, typeof(TowingControllerData)), + Union(15, typeof(CooldownData)), + Union(16, typeof(HeatData)), + Union(17, typeof(HitscanData)), + Union(18, typeof(ItemUsageData)), + Union(19, typeof(RadianceData)), + Union(20, typeof(SwitchData)), + Union(21, typeof(TriggerData)), + Union(22, typeof(VisibilityData)), JsonConverter(typeof(JsonKnownTypesConverter)), JsonObject(MemberSerialization.OptIn)] public abstract class BehaviorData { diff --git a/Assets/Scripts/ServerShared/Behaviors/Cooldown.cs b/Assets/Scripts/ServerShared/Behaviors/Cooldown.cs new file mode 100644 index 000000000..0dccf8617 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Cooldown.cs @@ -0,0 +1,55 @@ +using System; +using System.Linq; +using MessagePack; +using Newtonsoft.Json; + +[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)] +public class CooldownData : BehaviorData +{ + [InspectableField, JsonProperty("cooldown"), Key(1)] + public PerformanceStat Cooldown = new PerformanceStat(); + + public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) + { + return new Cooldown(context, this, entity, item); + } +} + +[UpdateOrder(-10)] +public class Cooldown : IBehavior, IAlwaysUpdatedBehavior +{ + private CooldownData _data; + + private Entity Entity { get; } + private Gear Item { get; } + private GameContext Context { get; } + + public BehaviorData Data => _data; + + private float _cooldown; // Normalized + + public Cooldown(GameContext context, CooldownData data, Entity entity, Gear item) + { + _data = data; + Entity = entity; + Item = item; + Context = context; + } + + public bool Update(float delta) + { + if (_cooldown < 0) + { + _cooldown = 1; + return true; + } + + return false; + + } + + public void AlwaysUpdate(float delta) + { + _cooldown -= delta / Context.Evaluate(_data.Cooldown, Item, Entity); + } +} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/ActivatedItemUsage.cs.meta b/Assets/Scripts/ServerShared/Behaviors/Cooldown.cs.meta similarity index 83% rename from Assets/Scripts/ServerShared/Behaviors/ActivatedItemUsage.cs.meta rename to Assets/Scripts/ServerShared/Behaviors/Cooldown.cs.meta index ef15ac809..fbf02e782 100644 --- a/Assets/Scripts/ServerShared/Behaviors/ActivatedItemUsage.cs.meta +++ b/Assets/Scripts/ServerShared/Behaviors/Cooldown.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9965ed11abd4e8c48b7b2bd8ab6e44e8 +guid: d1782458ac454624dbab2872ebbff979 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/ServerShared/Behaviors/FactoryBehavior.cs b/Assets/Scripts/ServerShared/Behaviors/FactoryBehavior.cs index b892c6028..f4e1830a9 100644 --- a/Assets/Scripts/ServerShared/Behaviors/FactoryBehavior.cs +++ b/Assets/Scripts/ServerShared/Behaviors/FactoryBehavior.cs @@ -22,7 +22,7 @@ public class FactoryData : BehaviorData } } -public class Factory : IBehavior, IPersistentBehavior// +public class Factory : IBehavior, IPersistentBehavior { public Entity Entity { get; } public Gear Item { get; } @@ -48,10 +48,6 @@ public class Factory : IBehavior, IPersistentBehavior// Item = item; } - public void Initialize() - { - } - public bool Update(float delta) { var blueprint = Context.Cache.Get(_blueprint); @@ -227,10 +223,6 @@ public class Factory : IBehavior, IPersistentBehavior// _assignedPopulation = factoryPersistence.AssignedPopulation; _productionQuality = factoryPersistence.ProductionQuality; } - - public void Remove() - { - } } [MessagePackObject, JsonObject(MemberSerialization.OptIn)] diff --git a/Assets/Scripts/ServerShared/Behaviors/Heat.cs b/Assets/Scripts/ServerShared/Behaviors/Heat.cs new file mode 100644 index 000000000..258274605 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Heat.cs @@ -0,0 +1,42 @@ +using System; +using System.Linq; +using MessagePack; +using Newtonsoft.Json; + +[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)] +public class HeatData : BehaviorData +{ + [InspectableField, JsonProperty("heat"), Key(1)] + public PerformanceStat Heat = new PerformanceStat(); + + public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) + { + return new Heat(context, this, entity, item); + } +} + +[UpdateOrder(10)] +public class Heat : IBehavior +{ + private HeatData _data; + + private Entity Entity { get; } + private Gear Item { get; } + private GameContext Context { get; } + + public BehaviorData Data => _data; + + public Heat(GameContext context, HeatData data, Entity entity, Gear item) + { + _data = data; + Entity = entity; + Item = item; + Context = context; + } + + public bool Update(float delta) + { + Entity.AddHeat(Context.Evaluate(_data.Heat, Item, Entity)); + return true; + } +} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Heat.cs.meta b/Assets/Scripts/ServerShared/Behaviors/Heat.cs.meta new file mode 100644 index 000000000..b4b497b56 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Heat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a60f2300e35155940adf1f353388dcdd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Behaviors/Hitscan.cs b/Assets/Scripts/ServerShared/Behaviors/Hitscan.cs index 4fd2490fe..966375ff6 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Hitscan.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Hitscan.cs @@ -10,7 +10,7 @@ public class HitscanData : WeaponData } } -public class Hitscan : IActivatedBehavior +public class Hitscan : IBehavior { private bool _firing; private float _cooldown; // normalized @@ -29,67 +29,10 @@ public class Hitscan : IActivatedBehavior Entity = entity; Item = item; } - - public bool Activate() - { -// Debug.Log("Activating ProjectileWeapon"); -// _firing = true; -// Observable.EveryUpdate().TakeWhile(_ => _firing).Subscribe(_ => -// { -// // Debug.Log($"Updating Observable {_cooldown}"); -// if (_cooldown < 0) -// { -// _cooldown = 1; -// Fire(0); -// if(_projectileWeapon.BurstCount>1) -// Observable.Interval(TimeSpan.FromSeconds(_projectileWeapon.BurstTime.Evaluate(Hardpoint) / (_projectileWeapon.BurstCount-1))).Take(_projectileWeapon.BurstCount-1) -// .Subscribe(l => Fire(l+1)); -// } -// }); - return true; - } - - private void Fire(long b) - { - // _firingVisibility += _projectileWeapon.Visibility.Evaluate(Hardpoint); - // Hardpoint.Temperature += _projectileWeapon.Heat.Evaluate(Hardpoint) / Hardpoint.HeatCapacity; - // var inst = GameObject.Instantiate(_projectileWeapon.BulletPrefab).transform; - // Physics.IgnoreCollision(Hardpoint.Ship.Ship.GetComponent(), inst.GetComponent()); - // var bullet = inst.GetComponent(); - // bullet.Target = Hardpoint.Ship.Ship.Target; - // bullet.Source = Hardpoint.Ship.Ship.Hitpoints; - // bullet.Lifetime = _projectileWeapon.Range.Evaluate(Hardpoint) / _projectileWeapon.Velocity.Evaluate(Hardpoint); - // bullet.Damage = _projectileWeapon.Damage.Evaluate(Hardpoint); - // inst.position = Hardpoint.Proxy.position; - // inst.rotation = Hardpoint.Proxy.rotation; - // inst.GetComponent().velocity = _projectileWeapon.Velocity.Evaluate(Hardpoint) * Vector3.RotateTowards(-inst.forward, Hardpoint.Ship.Ship.Direction, _projectileWeapon.Deflection * Mathf.Deg2Rad, 1); - // Hardpoint.Ship.Ship.AudioSource.PlayOneShot(_projectileWeapon.Sounds.RandomElement()); -// Debug.Log($"Firing bullet {b}"); - } - - public void Deactivate() - { - _firing = false; - } - - public void Initialize() - { - } public bool Update(float delta) { - _cooldown -= delta / Context.Evaluate(_data.Cooldown, Item, Entity); - - _firingVisibility *= Context.Evaluate(_data.VisibilityDecay, Item, Entity); - - if (_firingVisibility < 0.01f) - { - Entity.VisibilitySources.Remove(this); - } return true; } - public void Remove() - { - } } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/ItemUsage.cs b/Assets/Scripts/ServerShared/Behaviors/ItemUsage.cs index 7998124f5..988a24737 100644 --- a/Assets/Scripts/ServerShared/Behaviors/ItemUsage.cs +++ b/Assets/Scripts/ServerShared/Behaviors/ItemUsage.cs @@ -1,5 +1,6 @@  using System; +using System.Linq; using MessagePack; using Newtonsoft.Json; @@ -8,9 +9,6 @@ public class ItemUsageData : BehaviorData { [InspectableDatabaseLink(typeof(SimpleCommodityData)), JsonProperty("item"), Key(1)] public Guid Item; - - [InspectableField, JsonProperty("cooldown"), Key(2)] - public PerformanceStat Cooldown = new PerformanceStat(); public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) { @@ -18,6 +16,7 @@ public class ItemUsageData : BehaviorData } } +[UpdateOrder(-5)] public class ItemUsage : IBehavior { private ItemUsageData _data; @@ -36,16 +35,21 @@ public class ItemUsage : IBehavior Context = context; } - public void Initialize() - { - } - public bool Update(float delta) { - return true; - } + var cargoInstances = Entity.Cargo.Select(c => Context.Cache.Get(c)); + if (cargoInstances.FirstOrDefault(c => c.Data == _data.Item) is SimpleCommodity item) + { + if (item.Quantity > 1) + item.Quantity--; + else + { + Entity.Cargo.Remove(item.ID); + Context.Cache.Delete(item); + } - public void Remove() - { + return true; + } + return false; } } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Launcher.cs b/Assets/Scripts/ServerShared/Behaviors/Launcher.cs index ab94af384..84678aa12 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Launcher.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Launcher.cs @@ -7,34 +7,34 @@ using Unity.Mathematics; [InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)] public class LauncherData : WeaponData { - [InspectablePrefab, JsonProperty("missile"), Key(9)] + [InspectablePrefab, JsonProperty("missile"), Key(6)] public string MissilePrefab; - [InspectableAnimationCurve, JsonProperty("guidance"), Key(10)] + [InspectableAnimationCurve, JsonProperty("guidance"), Key(7)] public float4[] GuidanceCurve; - [InspectableAnimationCurve, JsonProperty("thrustCurve"), Key(11)] + [InspectableAnimationCurve, JsonProperty("thrustCurve"), Key(8)] public float4[] ThrustCurve; - [InspectableAnimationCurve, JsonProperty("liftCurve"), Key(12)] + [InspectableAnimationCurve, JsonProperty("liftCurve"), Key(9)] public float4[] LiftCurve; - [InspectableField, JsonProperty("thrust"), Key(13)] + [InspectableField, JsonProperty("thrust"), Key(10)] public PerformanceStat Thrust = new PerformanceStat(); - [InspectableField, JsonProperty("lockAngle"), Key(14)] + [InspectableField, JsonProperty("lockAngle"), Key(11)] public float LockAngle; - [InspectableField, JsonProperty("frequency"), Key(15)] + [InspectableField, JsonProperty("frequency"), Key(12)] public float DodgeFrequency; - [InspectableField, JsonProperty("launchSpeed"), Key(16)] + [InspectableField, JsonProperty("launchSpeed"), Key(13)] public PerformanceStat LaunchSpeed = new PerformanceStat(); - [InspectableField, JsonProperty("missileSpeed"), Key(17)] + [InspectableField, JsonProperty("missileSpeed"), Key(14)] public PerformanceStat MissileSpeed = new PerformanceStat(); - [InspectableField, JsonProperty("lockOnTime"), Key(18)] + [InspectableField, JsonProperty("lockOnTime"), Key(15)] public PerformanceStat LockOnTime = new PerformanceStat(); public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) @@ -43,7 +43,7 @@ public class LauncherData : WeaponData } } -public class Launcher : IActivatedBehavior +public class Launcher : IBehavior, IAlwaysUpdatedBehavior { private bool _locking; private float _lockingTimer; @@ -58,8 +58,6 @@ public class Launcher : IActivatedBehavior public BehaviorData Data => _data; - public int Group => _data.Group; - public Launcher(GameContext context, LauncherData m, Entity entity, Gear item) { Context = context; @@ -81,9 +79,24 @@ public class Launcher : IActivatedBehavior return true; } - private void Fire(long b) + public void Deactivate() + { + // if (_lockingTimer < 0) + // { + // Fire(0); + // if(_launcher.BurstCount>1) + // Observable.Interval(TimeSpan.FromSeconds(_launcher.BurstTime.Evaluate(Hardpoint) / (_launcher.BurstCount-1))).Take(_launcher.BurstCount-1) + // .Subscribe(l => Fire(l+1)); + // _lockingTimer = _cooldown = 1; + // _locking = _locked = false; + // _audio.Stop(); + // } + // _locking = false; + // _lockingTimer = 1; + } + + public bool Update(float delta) { - // _firingVisibility += _launcher.Visibility.Evaluate(Hardpoint); // Hardpoint.Temperature += _launcher.Heat.Evaluate(Hardpoint) / Hardpoint.HeatCapacity; // var inst = GameObject.Instantiate(_launcher.MissilePrefab).transform; @@ -107,31 +120,12 @@ public class Launcher : IActivatedBehavior // proj.Thrust = _launcher.Thrust.Evaluate(Hardpoint); // _audio.PlayOneShot(_launcher.Sounds.RandomElement()); // Debug.Log($"Firing bullet {b}"); - } - - public void Deactivate() - { - // if (_lockingTimer < 0) - // { - // Fire(0); - // if(_launcher.BurstCount>1) - // Observable.Interval(TimeSpan.FromSeconds(_launcher.BurstTime.Evaluate(Hardpoint) / (_launcher.BurstCount-1))).Take(_launcher.BurstCount-1) - // .Subscribe(l => Fire(l+1)); - // _lockingTimer = _cooldown = 1; - // _locking = _locked = false; - // _audio.Stop(); - // } - // _locking = false; - // _lockingTimer = 1; - } - - public void Initialize() - { - } - - public bool Update(float delta) - { return true; + } + + public void AlwaysUpdate(float delta) + { + // if (Ship.Target == null) // return; // @@ -167,8 +161,4 @@ public class Launcher : IActivatedBehavior // _firingVisibility = 0; // } } - - public void Remove() - { - } } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/PatrolController.cs b/Assets/Scripts/ServerShared/Behaviors/PatrolController.cs index 3e1a2003a..982d1680a 100644 --- a/Assets/Scripts/ServerShared/Behaviors/PatrolController.cs +++ b/Assets/Scripts/ServerShared/Behaviors/PatrolController.cs @@ -18,7 +18,8 @@ public class PatrolControllerData : ControllerData } } -public class PatrolController : IBehavior, IController +[UpdateOrder(-100)] +public class PatrolController : IBehavior, IController, IInitializableBehavior { public TaskType TaskType => TaskType.Tow; public bool Available => false; @@ -68,8 +69,4 @@ public class PatrolController : IBehavior, IController var entities = _context.ZonePlanets[_entity.Zone]; _targetOrbit = _context.Cache.Get(entities[_context.Random.NextInt(entities.Length)]).Orbit; } - - public void Remove() - { - } } diff --git a/Assets/Scripts/ServerShared/Behaviors/ProjectileWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/ProjectileWeapon.cs index 8393065bd..611de449e 100644 --- a/Assets/Scripts/ServerShared/Behaviors/ProjectileWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/ProjectileWeapon.cs @@ -4,16 +4,16 @@ using Newtonsoft.Json; [InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)] public class ProjectileWeaponData : WeaponData { - [InspectablePrefab, JsonProperty("bullet"), Key(9)] + [InspectablePrefab, JsonProperty("bullet"), Key(6)] public string BulletPrefab; - [InspectableField, JsonProperty("spread"), Key(10)] + [InspectableField, JsonProperty("spread"), Key(7)] public PerformanceStat Spread = new PerformanceStat(); - [InspectableField, JsonProperty("bulletInherit"), Key(11)] + [InspectableField, JsonProperty("bulletInherit"), Key(8)] public float Inherit; - [InspectableField, JsonProperty("bulletVelocity"), Key(12)] + [InspectableField, JsonProperty("bulletVelocity"), Key(9)] public PerformanceStat Velocity = new PerformanceStat(); public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) @@ -22,18 +22,12 @@ public class ProjectileWeaponData : WeaponData } } -public class ProjectileWeapon : IActivatedBehavior +public class ProjectileWeapon : IBehavior { private ProjectileWeaponData _data; private Entity Entity { get; } private Gear Item { get; } private GameContext Context { get; } - private float _firingVisibility; - private bool _firing; - private float _cooldown; // normalized - private float _burstCooldown; - private float _burstCooldownTime; - private int _burstRemaining; public BehaviorData Data => _data; @@ -44,31 +38,9 @@ public class ProjectileWeapon : IActivatedBehavior Entity = entity; Item = item; } - - public bool Activate() - { - _firing = true; - return true; -// Debug.Log("Activating ProjectileWeapon"); -// Observable.EveryUpdate().TakeWhile(_ => _firing).Subscribe(_ => -// { -// // Debug.Log($"Updating Observable {_cooldown}"); -// if (_cooldown < 0) -// { -// _cooldown = 1; -// Fire(0); -// if(_projectileWeapon.BurstCount>1) -// Observable.Interval(TimeSpan.FromSeconds(_projectileWeapon.BurstTime.Evaluate(Hardpoint) / (_projectileWeapon.BurstCount-1))).Take(_projectileWeapon.BurstCount-1) -// .Subscribe(l => Fire(l+1)); -// } -// }); - } - private void Fire() - { - _burstRemaining--; - _firingVisibility += Context.Evaluate(_data.Visibility, Item, Entity); - Entity.AddHeat(Context.Evaluate(_data.Heat, Item, Entity)); + // private void Fire() + // { // Hardpoint.Temperature += _projectileWeapon.Heat.Evaluate(Hardpoint) / Hardpoint.HeatCapacity; // var inst = GameObject.Instantiate(_projectileWeapon.BulletPrefab).transform; // Physics.IgnoreCollision(Hardpoint.Ship.Ship.GetComponent(), inst.GetComponent()); @@ -82,49 +54,10 @@ public class ProjectileWeapon : IActivatedBehavior // inst.GetComponent().velocity = _projectileWeapon.Velocity.Evaluate(Hardpoint) * Vector3.RotateTowards(-inst.forward, Hardpoint.Ship.Ship.Direction, _projectileWeapon.Deflection * Mathf.Deg2Rad, 1); // Hardpoint.Ship.Ship.AudioSource.PlayOneShot(_projectileWeapon.Sounds.RandomElement()); // Debug.Log($"Firing bullet {b}"); - } - - public void Deactivate() - { - _firing = false; - } - - public void Initialize() - { - } + // } public bool Update(float delta) { - _cooldown -= delta / Context.Evaluate(_data.Cooldown, Item, Entity); - if (_cooldown < 0) - { - _cooldown = 1; - _burstRemaining = _data.BurstCount; - _burstCooldownTime = Context.Evaluate(_data.BurstTime, Item, Entity) / _data.BurstCount; - _burstCooldown = -1; - Fire(); - } - - if (_burstRemaining > 0) - { - _burstCooldown -= delta / _burstCooldownTime; - if (_burstCooldown < 0) - { - _burstCooldown = 1; - Fire(); - } - } - - _firingVisibility *= Context.Evaluate(_data.VisibilityDecay, Item, Entity); - - if (_firingVisibility < 0.01f) - { - Entity.VisibilitySources.Remove(this); - } return true; } - - public void Remove() - { - } } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Radiance.cs b/Assets/Scripts/ServerShared/Behaviors/Radiance.cs new file mode 100644 index 000000000..f9e7d2470 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Radiance.cs @@ -0,0 +1,41 @@ +using System; +using System.Linq; +using MessagePack; +using Newtonsoft.Json; + +[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)] +public class RadianceData : BehaviorData +{ + [InspectableField, JsonProperty("radiance"), Key(1)] + public PerformanceStat Radiance = new PerformanceStat(); + + public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) + { + return new Radiance(context, this, entity, item); + } +} + +public class Radiance : IBehavior +{ + private RadianceData _data; + + private Entity Entity { get; } + private Gear Item { get; } + private GameContext Context { get; } + + public BehaviorData Data => _data; + + public Radiance(GameContext context, RadianceData data, Entity entity, Gear item) + { + _data = data; + Entity = entity; + Item = item; + Context = context; + } + + public bool Update(float delta) + { + // TODO: Light system! + return true; + } +} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Radiance.cs.meta b/Assets/Scripts/ServerShared/Behaviors/Radiance.cs.meta new file mode 100644 index 000000000..94acbd584 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Radiance.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1fbf8a3d31de89a4aa53d43e015536c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Behaviors/Radiator.cs b/Assets/Scripts/ServerShared/Behaviors/Radiator.cs index 2ad67a42e..78e0be173 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Radiator.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Radiator.cs @@ -33,10 +33,6 @@ public class Radiator : IBehavior Item = item; } - public void Initialize() - { - } - public bool Update(float delta) { var rad = pow(Entity.Temperature, Context.GlobalData.HeatRadiationPower) * Context.GlobalData.HeatRadiationMultiplier; @@ -44,8 +40,4 @@ public class Radiator : IBehavior Entity.VisibilitySources[this] = rad; return true; } - - public void Remove() - { - } } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Reactor.cs b/Assets/Scripts/ServerShared/Behaviors/Reactor.cs index ec0204758..66bf23bd4 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Reactor.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Reactor.cs @@ -43,10 +43,6 @@ public class Reactor : IBehavior Item = item; } - public void Initialize() - { - } - public bool Update(float delta) { var cap = Context.Evaluate(_data.Capacitance, Item, Entity); @@ -69,8 +65,4 @@ public class Reactor : IBehavior } return true; } - - public void Remove() - { - } } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Reflector.cs b/Assets/Scripts/ServerShared/Behaviors/Reflector.cs index 8229d601b..59f609982 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Reflector.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Reflector.cs @@ -36,16 +36,9 @@ public class Reflector : IBehavior Item = item; } - public void Initialize() - { - } - public bool Update(float delta) { + // TODO: Light system! return true; } - - public void Remove() - { - } } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Sensor.cs b/Assets/Scripts/ServerShared/Behaviors/Sensor.cs index e156d968d..53a1a1325 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Sensor.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Sensor.cs @@ -5,17 +5,8 @@ using Newtonsoft.Json; [InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)] public class SensorData : BehaviorData { - [InspectableField, JsonProperty("radiance"), Key(1)] - public PerformanceStat Radiance = new PerformanceStat(); - - [InspectableField, JsonProperty("masking"), Key(2)] - public PerformanceStat RadianceMasking = new PerformanceStat(); - [InspectableField, JsonProperty("sensitivity"), Key(3)] public PerformanceStat Sensitivity = new PerformanceStat(); - - [InspectableField, JsonProperty("range"), Key(4)] - public PerformanceStat Range = new PerformanceStat(); public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) { @@ -41,12 +32,9 @@ public class Sensor : IBehavior Context = context; } - public void Initialize() - { - } - public bool Update(float delta) { + // TODO: Handle Active Detection / Visibility From Reflected Radiance return true; // var ship = Hardpoint.Ship.Ship.transform; // var contacts = @@ -64,10 +52,5 @@ public class Sensor : IBehavior // } // // Hardpoint.Ship.VisibilitySources[this] = _data.Radiance.Evaluate(Hardpoint) / _data.RadianceMasking.Evaluate(Hardpoint); - // TODO: Handle Active Detection / Visibility From Reflected Radiance - } - - public void Remove() - { } } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Shield.cs b/Assets/Scripts/ServerShared/Behaviors/Shield.cs index 2f42461d5..40630a10f 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Shield.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Shield.cs @@ -38,16 +38,8 @@ public class Shield : IBehavior // TODO: Detect hits on Ship, keep a list of callbacks that modify the hit by reference } - public void Initialize() - { - } - public bool Update(float delta) { return true; } - - public void Remove() - { - } } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/StatModifier.cs b/Assets/Scripts/ServerShared/Behaviors/StatModifier.cs new file mode 100644 index 000000000..0c095ffa2 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/StatModifier.cs @@ -0,0 +1,95 @@ +using System; +using System.Linq; +using MessagePack; +using Newtonsoft.Json; + +[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)] +public class StatModifierData : BehaviorData +{ + [InspectableField, JsonProperty("stat"), Key(1)] + public StatReference Stat = new StatReference(); + + [InspectableField, JsonProperty("modifier"), Key(2)] + public PerformanceStat Modifier = new PerformanceStat(); + + [InspectableField, JsonProperty("type"), Key(3)] + public StatModifierType Type; + + [InspectableType(typeof(BehaviorData)), JsonProperty("requireBehavior"), Key(4)] + public Type RequireBehavior; + + public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) + { + return new StatModifier(context, this, entity, item); + } +} + +[UpdateOrder(-4)] +public class StatModifier : IBehavior, IInitializableBehavior, IDisposableBehavior +{ + private StatModifierData _data; + private Entity Entity { get; } + private Gear Item { get; } + private GameContext Context { get; } + + public BehaviorData Data => _data; + + private PerformanceStat[] _stats; + + public StatModifier(GameContext context, StatModifierData data, Entity entity, Gear item) + { + _data = data; + Entity = entity; + Item = item; + Context = context; + } + + public void Initialize() + { + var targetType = Context.StatObjects.FirstOrDefault(so => so.Name == _data.Stat.Target); + if (targetType != null) + { + var statField = targetType.GetFields() + .Where(f => f.FieldType == typeof(PerformanceStat)).FirstOrDefault(f => f.Name == _data.Stat.Stat); + if (statField != null) + { + if (typeof(EquippableItemData).IsAssignableFrom(targetType)) + _stats = Entity.EquippedItems + .Select(id => Context.Cache.Get(id)) + .Where(gear => _data.RequireBehavior == null || gear.ItemData.Behaviors.Any(behavior => behavior.GetType() == _data.RequireBehavior)) + .Where(gear => gear.ItemData.GetType() == targetType) + .Select(gear => statField.GetValue(gear.ItemData) as PerformanceStat) + .ToArray(); + else + _stats = Entity.EquippedItems + .Select(id => Context.Cache.Get(id)) + .Where(gear => _data.RequireBehavior == null || gear.ItemData.Behaviors.Any(behavior => behavior.GetType() == _data.RequireBehavior)) + .SelectMany(gear => gear.ItemData.Behaviors) + .Where(behaviorData => behaviorData.GetType() == targetType) + .Select(behaviorData => statField.GetValue(behaviorData) as PerformanceStat) + .ToArray(); + } + } + } + + public bool Update(float delta) + { + foreach (var stat in _stats) + (_data.Type == StatModifierType.Constant + ? stat.GetConstantModifiers(Entity) + : stat.GetScaleModifiers(Entity))[this] = Context.Evaluate(_data.Modifier, Item, Entity); + return true; + } + + public void Dispose() + { + foreach (var stat in _stats) + (_data.Type == StatModifierType.Constant ? stat.GetConstantModifiers(Entity) : stat.GetScaleModifiers(Entity)).Remove(this); + } +} + +public enum StatModifierType +{ + Constant, + Multiplier +} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/StatModifier.cs.meta b/Assets/Scripts/ServerShared/Behaviors/StatModifier.cs.meta new file mode 100644 index 000000000..b7e851aff --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/StatModifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 839f7ac20a89cef46b2103058238d26e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Behaviors/Switch.cs b/Assets/Scripts/ServerShared/Behaviors/Switch.cs new file mode 100644 index 000000000..897d765e0 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Switch.cs @@ -0,0 +1,40 @@ +using System; +using System.Linq; +using MessagePack; +using Newtonsoft.Json; + +[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)] +public class SwitchData : BehaviorData +{ + public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) + { + return new Switch(context, this, entity, item); + } +} + +[UpdateOrder(-25)] +public class Switch : IBehavior +{ + private SwitchData _data; + + private Entity Entity { get; } + private Gear Item { get; } + private GameContext Context { get; } + + public BehaviorData Data => _data; + + private bool Activated { get; set; } + + public Switch(GameContext context, SwitchData data, Entity entity, Gear item) + { + _data = data; + Entity = entity; + Item = item; + Context = context; + } + + public bool Update(float delta) + { + return Activated; + } +} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Switch.cs.meta b/Assets/Scripts/ServerShared/Behaviors/Switch.cs.meta new file mode 100644 index 000000000..a59cb2370 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Switch.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fabf8a72928044a4385e071218c6d7cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Behaviors/Thruster.cs b/Assets/Scripts/ServerShared/Behaviors/Thruster.cs index 4cd1d2458..8adf126c6 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Thruster.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Thruster.cs @@ -48,10 +48,6 @@ public class Thruster : IAnalogBehavior _input = saturate(value); } - public void Initialize() - { - } - public bool Update(float delta) { Thrust = Context.Evaluate(_data.Thrust, Item, Entity); @@ -60,8 +56,4 @@ public class Thruster : IAnalogBehavior Entity.VisibilitySources[this] = _input * Context.Evaluate(_data.Visibility, Item, Entity); return true; } - - public void Remove() - { - } } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/TowingController.cs b/Assets/Scripts/ServerShared/Behaviors/TowingController.cs index b11a42bb5..57485f947 100644 --- a/Assets/Scripts/ServerShared/Behaviors/TowingController.cs +++ b/Assets/Scripts/ServerShared/Behaviors/TowingController.cs @@ -16,7 +16,8 @@ public class TowingControllerData : ControllerData } } -public class TowingController : IBehavior, IPersistentBehavior, IController +[UpdateOrder(-100)] +public class TowingController : IBehavior, IPersistentBehavior, IController, IInitializableBehavior { public TaskType TaskType => TaskType.Tow; public bool Available => _towingTask != Guid.Empty; @@ -149,10 +150,6 @@ public class TowingController : IBehavior, IPersistentBehavior, IController { _locomotion.Objective = _context.WormholePosition(_entity.Zone, _path[0].ZoneID); } - - public void Remove() - { - } } public class TowingControllerPersistence : PersistentBehaviorData diff --git a/Assets/Scripts/ServerShared/Behaviors/Trigger.cs b/Assets/Scripts/ServerShared/Behaviors/Trigger.cs new file mode 100644 index 000000000..1613b0b77 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Trigger.cs @@ -0,0 +1,55 @@ +using System; +using System.Linq; +using MessagePack; +using Newtonsoft.Json; + +[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)] +public class TriggerData : BehaviorData +{ + public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) + { + return new Trigger(context, this, entity, item); + } +} + +[UpdateOrder(-20)] +public class Trigger : IBehavior +{ + private TriggerData _data; + + private Entity Entity { get; } + private Gear Item { get; } + private GameContext Context { get; } + + public BehaviorData Data => _data; + + public bool _pulled; + + public void Pull() + { + _pulled = true; + } + + public Trigger(GameContext context, TriggerData data, Entity entity, Gear item) + { + _data = data; + Entity = entity; + Item = item; + Context = context; + } + + public void Initialize() + { + } + + public bool Update(float delta) + { + if (_pulled) + { + _pulled = false; + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Trigger.cs.meta b/Assets/Scripts/ServerShared/Behaviors/Trigger.cs.meta new file mode 100644 index 000000000..1a4354a96 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Trigger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1dcb2be1f50095d458088f381e5e98a1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Behaviors/Visibility.cs b/Assets/Scripts/ServerShared/Behaviors/Visibility.cs new file mode 100644 index 000000000..dee3a90c1 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Visibility.cs @@ -0,0 +1,54 @@ +using System; +using System.Linq; +using MessagePack; +using Newtonsoft.Json; + +[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)] +public class VisibilityData : BehaviorData +{ + [InspectableField, JsonProperty("visibility"), Key(1)] + public PerformanceStat Visibility = new PerformanceStat(); + + [InspectableField, JsonProperty("visibilityDecay"), Key(2)] + public PerformanceStat VisibilityDecay = new PerformanceStat(); + + public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item) + { + return new Visibility(context, this, entity, item); + } +} + +public class Visibility : IBehavior, IAlwaysUpdatedBehavior +{ + private VisibilityData _data; + + private Entity Entity { get; } + private Gear Item { get; } + private GameContext Context { get; } + + public BehaviorData Data => _data; + + private float _cooldown; // Normalized + + public Visibility(GameContext context, VisibilityData data, Entity entity, Gear item) + { + _data = data; + Entity = entity; + Item = item; + Context = context; + } + + public bool Update(float delta) + { + Entity.VisibilitySources[this] = Context.Evaluate(_data.Visibility, Item, Entity); + return true; + } + + public void AlwaysUpdate(float delta) + { + // TODO: Time independent decay? + Entity.VisibilitySources[this] *= Context.Evaluate(_data.VisibilityDecay, Item, Entity); + + if (Entity.VisibilitySources[this] < 0.01f) Entity.VisibilitySources.Remove(this); + } +} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Visibility.cs.meta b/Assets/Scripts/ServerShared/Behaviors/Visibility.cs.meta new file mode 100644 index 000000000..4b0c06356 --- /dev/null +++ b/Assets/Scripts/ServerShared/Behaviors/Visibility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6cd797c5c65ecf9438830c92ff4ded64 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/ServerShared/Behaviors/Weapon.cs b/Assets/Scripts/ServerShared/Behaviors/Weapon.cs index 53ba24292..610219151 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Weapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Weapon.cs @@ -8,27 +8,15 @@ public abstract class WeaponData : BehaviorData [InspectableField, JsonProperty("damageType"), Key(1)] public DamageType DamageType; - [InspectableField, JsonProperty("damage"), Key(2)] + [InspectableField, JsonProperty("damage"), Key(2)] public PerformanceStat Damage = new PerformanceStat(); - [InspectableField, JsonProperty("range"), Key(3)] + [InspectableField, JsonProperty("range"), Key(3)] public PerformanceStat Range = new PerformanceStat(); - [InspectableField, JsonProperty("cooldown"), Key(4)] - public PerformanceStat Cooldown = new PerformanceStat(); - - [InspectableField, JsonProperty("heat"), Key(5)] - public PerformanceStat Heat = new PerformanceStat(); - - [InspectableField, JsonProperty("visibility"), Key(6)] - public PerformanceStat Visibility = new PerformanceStat(); - - [InspectableField, JsonProperty("visibilityDecay"), Key(7)] - public PerformanceStat VisibilityDecay = new PerformanceStat(); - - [InspectableField, JsonProperty("burstCount"), Key(8)] + [InspectableField, JsonProperty("burstCount"), Key(4)] public int BurstCount; - [InspectableField, JsonProperty("burstTime"), Key(9)] + [InspectableField, JsonProperty("burstTime"), Key(5)] public PerformanceStat BurstTime = new PerformanceStat(); } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/BlueprintData.cs b/Assets/Scripts/ServerShared/BlueprintData.cs index 30707fe48..ae73461e4 100644 --- a/Assets/Scripts/ServerShared/BlueprintData.cs +++ b/Assets/Scripts/ServerShared/BlueprintData.cs @@ -78,7 +78,7 @@ public class BlueprintStatEffect public class StatReference { [InspectableType(typeof(BehaviorData)), JsonProperty("behavior"), Key(1)] - public string Behavior; + public string Target; [InspectableField, JsonProperty("stat"), Key(2)] public string Stat; diff --git a/Assets/Scripts/ServerShared/Entity.cs b/Assets/Scripts/ServerShared/Entity.cs index 23ee022f5..e723448a6 100644 --- a/Assets/Scripts/ServerShared/Entity.cs +++ b/Assets/Scripts/ServerShared/Entity.cs @@ -31,7 +31,8 @@ public abstract class Entity : DatabaseEntry, IMessagePackSerializationCallbackR // [IgnoreMember] protected List Behaviors; [IgnoreMember] public Guid Zone; [IgnoreMember] public Dictionary> Behaviors; - [IgnoreMember] public Dictionary> Bindings; + [IgnoreMember] public Dictionary Switches; + [IgnoreMember] public Dictionary Triggers; [IgnoreMember] public Dictionary Axes; [IgnoreMember] public Dictionary AxisOverrides = new Dictionary(); [IgnoreMember] public readonly Dictionary VisibilitySources = new Dictionary(); @@ -83,12 +84,15 @@ public abstract class Entity : DatabaseEntry, IMessagePackSerializationCallbackR .Select((grouping, i) => new {index = i, group = grouping}) .ToDictionary(ig => ig.index, ig => ig.group.Select(x => x.behavior).ToList()); - Bindings = Behaviors - .Where(x => x.Value.Any(g => g is IActivatedBehavior)) - .Select((x, i) => new {index = i, behaviors = x.Value - .Where(g => g is IActivatedBehavior) - .Cast().ToList()}) - .ToDictionary(x => x.index, x => x.behaviors); + Switches = Behaviors + .Where(x => x.Value.Any(g => g is Switch)) + .Select((x, i) => new {index = i, s = x.Value.First(g => g is Switch) as Switch}) + .ToDictionary(x => x.index, x => x.s); + + Triggers = Behaviors + .Where(x => x.Value.Any(g => g is Trigger)) + .Select((x, i) => new {index = i, s = x.Value.First(g => g is Trigger) as Trigger}) + .ToDictionary(x => x.index, x => x.s); Axes = Behaviors .Where(x => x.Value.Any(g => g is IAnalogBehavior)) @@ -103,7 +107,9 @@ public abstract class Entity : DatabaseEntry, IMessagePackSerializationCallbackR // .ToDictionary(b => b as IAnalogBehavior, b => 0f); foreach (var behavior in Behaviors.Values - .SelectMany(behaviors=>behaviors)) behavior.Initialize(); + .SelectMany(behaviors=>behaviors) + .Where(behavior => behavior is IInitializableBehavior) + .Cast()) behavior.Initialize(); } public void RecalculateMass() diff --git a/Assets/Scripts/ServerShared/GameContext.cs b/Assets/Scripts/ServerShared/GameContext.cs index a27963475..89b29c8ef 100644 --- a/Assets/Scripts/ServerShared/GameContext.cs +++ b/Assets/Scripts/ServerShared/GameContext.cs @@ -31,10 +31,14 @@ public class GameContext private Dictionary _orbitPositions = new Dictionary(); private Dictionary _previousOrbitPositions = new Dictionary(); private Guid _forceLoadZone; - + private Type[] _statObjects; + public GlobalData GlobalData => _globalData ?? (_globalData = Cache.GetAll().FirstOrDefault()); public DatabaseCache Cache { get; } + public Type[] StatObjects => _statObjects ?? (_statObjects = typeof(BehaviorData).GetAllChildClasses() + .Concat(typeof(EquippableItemData).GetAllChildClasses()).ToArray()); + public Guid ForceLoadZone { get => _forceLoadZone; @@ -319,11 +323,11 @@ public class GameContext } // Get the first behavior of the type specified in the blueprint stat effect, return null if not found - var effectObject = effect.StatReference.Behavior == blueprintItem.Name ? (object) blueprintItem : - blueprintItem.Behaviors.FirstOrDefault(b => b.GetType().Name == effect.StatReference.Behavior); + var effectObject = effect.StatReference.Target == blueprintItem.Name ? (object) blueprintItem : + blueprintItem.Behaviors.FirstOrDefault(b => b.GetType().Name == effect.StatReference.Target); if (effectObject == null) { - _logger($"Attempted to get stat effect for Blueprint {blueprint.ID} but stat references missing behavior \"{effect.StatReference.Behavior}\"!"); + _logger($"Attempted to get stat effect for Blueprint {blueprint.ID} but stat references missing behavior \"{effect.StatReference.Target}\"!"); return AffectedStats[effect] = null; } @@ -332,7 +336,7 @@ public class GameContext var field = type.GetField(effect.StatReference.Stat); if (field == null) { - _logger($"Attempted to get stat effect for Blueprint {blueprint.ID} but object {effect.StatReference.Behavior} does not have a stat named \"{effect.StatReference.Stat}\"!"); + _logger($"Attempted to get stat effect for Blueprint {blueprint.ID} but object {effect.StatReference.Target} does not have a stat named \"{effect.StatReference.Stat}\"!"); return AffectedStats[effect] = null; } diff --git a/Assets/Scripts/ServerShared/RegisterResolver.cs b/Assets/Scripts/ServerShared/RegisterResolver.cs index 8e1d6a6d7..8a7d5ca5a 100644 --- a/Assets/Scripts/ServerShared/RegisterResolver.cs +++ b/Assets/Scripts/ServerShared/RegisterResolver.cs @@ -13,6 +13,7 @@ public static class RegisterResolver // Set extensions to default resolver. var resolver = CompositeResolver.Create( MathResolver.Instance, + TypeResolver.Instance, NativeGuidResolver.Instance, StandardResolver.Instance ); diff --git a/Assets/Scripts/ServerShared/TypeFormatterResolver.cs b/Assets/Scripts/ServerShared/TypeFormatterResolver.cs new file mode 100644 index 000000000..55edebfb8 --- /dev/null +++ b/Assets/Scripts/ServerShared/TypeFormatterResolver.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using MessagePack; +using MessagePack.Formatters; + +public class TypeFormatter : MessagePack.Formatters.IMessagePackFormatter +{ + public static readonly IMessagePackFormatter Instance = new TypeFormatter(); + + private TypeFormatter() + { + } + + public void Serialize(ref MessagePackWriter writer, Type value, MessagePackSerializerOptions options) + { + writer.Write(value.AssemblyQualifiedName); + } + + public Type Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + { + if (reader.IsNil) + { + throw new InvalidOperationException("typecode is null, struct not supported"); + } + + var assemblyQualifiedName = reader.ReadString(); + + return Type.GetType(assemblyQualifiedName); + } +} + +public class TypeResolver : IFormatterResolver +{ + public static readonly TypeResolver Instance = new TypeResolver(); + + private TypeResolver() + { + } + + public IMessagePackFormatter GetFormatter() + { + return FormatterCache.Formatter; + } + + private static object GetFormatterHelper(Type t) + { + if (t == typeof(Type)) + { + return TypeFormatter.Instance; + } + + return null; + } + + private static class FormatterCache + { + public static readonly IMessagePackFormatter Formatter; + + static FormatterCache() + { + Formatter = (IMessagePackFormatter)GetFormatterHelper(typeof(T)); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/TypeFormatterResolver.cs.meta b/Assets/Scripts/ServerShared/TypeFormatterResolver.cs.meta new file mode 100644 index 000000000..0a739e995 --- /dev/null +++ b/Assets/Scripts/ServerShared/TypeFormatterResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ede4e7a24e20d134fb02868d010af83d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Economy.Shared.Unity.csproj b/Economy.Shared.Unity.csproj index 19667b939..5405b14b3 100644 --- a/Economy.Shared.Unity.csproj +++ b/Economy.Shared.Unity.csproj @@ -69,26 +69,32 @@ - + + + + + + + @@ -494,6 +500,7 @@ +