From 4f29bf24d0e217011d4ad6cc165c3219df64f643 Mon Sep 17 00:00:00 2001 From: hyperion51 Date: Mon, 4 May 2020 00:07:36 +0100 Subject: [PATCH] Refactored Ghost Entities Game Context was creating an empty OrbitalEntity for every planet; this was an ugly hack so I refactored it, as well as refactoring some object references to GUIDs as they should be --- Assets/Scenes/Main.unity | 2 +- .../ServerShared/Agents/AgentController.cs | 22 +-- .../ServerShared/Agents/EntityAgent.cs | 7 +- .../Scripts/ServerShared/Agents/Locomotion.cs | 7 +- .../ServerShared/Agents/VelocityMatch.cs | 13 +- Assets/Scripts/ServerShared/Entity.cs | 17 ++- Assets/Scripts/ServerShared/GameContext.cs | 99 +++++++++---- Assets/Scripts/ServerShared/GlobalData.cs | 17 ++- Assets/Scripts/ServerShared/OrbitalEntity.cs | 32 +--- Assets/Scripts/ServerShared/ZoneData.cs | 29 ++-- Assets/Scripts/ServerShared/ZoneGenerator.cs | 2 +- Assets/Scripts/StrategyGameManager.cs | 140 ++++++++---------- Assets/Scripts/UI/ClickCatcher.cs | 5 +- 13 files changed, 200 insertions(+), 192 deletions(-) diff --git a/Assets/Scenes/Main.unity b/Assets/Scenes/Main.unity index e406f4792..d37d964cb 100644 --- a/Assets/Scenes/Main.unity +++ b/Assets/Scenes/Main.unity @@ -41507,7 +41507,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 20fa7724865c6b04097615292a325dfe, type: 3} m_Name: m_EditorClassIdentifier: - ClickTime: 0.5 + DragDistance: 25 --- !u!1 &1777186238 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/ServerShared/Agents/AgentController.cs b/Assets/Scripts/ServerShared/Agents/AgentController.cs index 50efb2a6d..6c3c5864e 100644 --- a/Assets/Scripts/ServerShared/Agents/AgentController.cs +++ b/Assets/Scripts/ServerShared/Agents/AgentController.cs @@ -10,21 +10,23 @@ public class AgentController public Entity Entity { get; } public EntityAgent EntityAgent { get; } public GameContext Context { get; } - public ZoneData Zone { get; set; } + 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 KeyValuePair _objective; + private Guid _targetOrbit; - public AgentController(GameContext context, ZoneData zone, Entity entity) + public AgentController(GameContext context, Guid zone, Entity entity) { Entity = entity; Zone = zone; Context = context; EntityAgent = new EntityAgent(context, zone, entity); _locomotion = new Locomotion(entity); - _velocityMatch = new VelocityMatch(entity); + _velocityMatch = new VelocityMatch(context, entity); _velocityMatch.OnMatch += () => { EntityAgent.CurrentBehavior = _locomotion; @@ -37,7 +39,6 @@ public class AgentController public void Update(float delta) { EntityAgent.Update(delta); - var distance = length(_locomotion.Objective.Position - Entity.Position); // Context.Log( // $"Agent Mode: {EntityAgent.CurrentBehavior.GetType()} " + // $"Agent Distance: {distance} " + @@ -46,9 +47,11 @@ public class AgentController if (EntityAgent.CurrentBehavior == _locomotion) { - _velocityMatch.Objective = _locomotion.Objective; + var orbitData = Context.Cache.Get(_targetOrbit); + _velocityMatch.TargetOrbit = _targetOrbit; var matchDistanceTime = _velocityMatch.MatchDistanceTime; - _locomotion.LeadTime = matchDistanceTime.y; + _locomotion.Objective = Context.GetOrbitPosition(_targetOrbit) + Context.GetOrbitVelocity(_targetOrbit) * matchDistanceTime.y; + var distance = length(_locomotion.Objective - Entity.Position); if (distance < matchDistanceTime.x) EntityAgent.CurrentBehavior = _velocityMatch; } @@ -56,8 +59,7 @@ public class AgentController private void RandomTarget() { - var entities = Context.ZoneContents[Zone].Where(kvp=>!(kvp.Key is ShipData)).ToArray(); - _objective = entities[_random.NextInt(entities.Length)]; - _locomotion.Objective = _objective.Value; + var entities = Context.ZonePlanets[Zone]; + _targetOrbit = Context.Cache.Get(entities[_random.NextInt(entities.Length)]).Orbit; } } diff --git a/Assets/Scripts/ServerShared/Agents/EntityAgent.cs b/Assets/Scripts/ServerShared/Agents/EntityAgent.cs index 9a2cd32b9..5baf4d05c 100644 --- a/Assets/Scripts/ServerShared/Agents/EntityAgent.cs +++ b/Assets/Scripts/ServerShared/Agents/EntityAgent.cs @@ -1,4 +1,5 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; public class EntityAgent @@ -7,9 +8,9 @@ public class EntityAgent public Entity Entity { get; } public GameContext Context { get; } - public ZoneData Zone { get; set; } + public Guid Zone { get; set; } - public EntityAgent(GameContext context, ZoneData zone, Entity entity) + public EntityAgent(GameContext context, Guid zone, Entity entity) { Entity = entity; Zone = zone; diff --git a/Assets/Scripts/ServerShared/Agents/Locomotion.cs b/Assets/Scripts/ServerShared/Agents/Locomotion.cs index 71e792d81..6a2d72ab4 100644 --- a/Assets/Scripts/ServerShared/Agents/Locomotion.cs +++ b/Assets/Scripts/ServerShared/Agents/Locomotion.cs @@ -6,8 +6,7 @@ using static Unity.Mathematics.math; public class Locomotion : AgentBehavior { - public Entity Objective; - public float LeadTime; + public float2 Objective; private Entity _entity; private IAnalogBehavior _thrust; private IAnalogBehavior _turning; @@ -23,9 +22,9 @@ public class Locomotion : AgentBehavior public override void Update(float delta) { - if (Objective != null && _thrust != null && _turning != null) + if (_thrust != null && _turning != null) { - float2 diff = Objective.Position + Objective.Velocity * LeadTime - _entity.Position; + 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); diff --git a/Assets/Scripts/ServerShared/Agents/VelocityMatch.cs b/Assets/Scripts/ServerShared/Agents/VelocityMatch.cs index 8581aa6f1..25ac1c631 100644 --- a/Assets/Scripts/ServerShared/Agents/VelocityMatch.cs +++ b/Assets/Scripts/ServerShared/Agents/VelocityMatch.cs @@ -8,16 +8,19 @@ using static Unity.Mathematics.math; public class VelocityMatch : AgentBehavior { public event Action OnMatch; - public Entity Objective; + public Guid TargetOrbit; private Entity _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(Entity entity) + public VelocityMatch(GameContext context, Entity entity) { + Context = context; _entity = entity; _thrust = entity.Axes.Keys.FirstOrDefault(x => x is Thruster); _turning = entity.Axes.Keys.FirstOrDefault(x => x is Turning); @@ -25,9 +28,9 @@ public class VelocityMatch : AgentBehavior public override void Update(float delta) { - if (Objective != null && _thrust != null && _turning != null) + if (TargetOrbit != Guid.Empty && _thrust != null && _turning != null) { - var deltaV = Objective.Velocity - _entity.Velocity; + var deltaV = Context.GetOrbitVelocity(TargetOrbit) - _entity.Velocity; if(length(deltaV) < TargetThreshold) OnMatch?.Invoke(); var angleDiff = _entity.Direction.AngleDiff(deltaV); @@ -41,7 +44,7 @@ public class VelocityMatch : AgentBehavior get { var velocity = length(_entity.Velocity); - var deltaV = Objective.Velocity - _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 stoppingDistance = stoppingTime * (velocity / 2); diff --git a/Assets/Scripts/ServerShared/Entity.cs b/Assets/Scripts/ServerShared/Entity.cs index 9bed240bb..115808135 100644 --- a/Assets/Scripts/ServerShared/Entity.cs +++ b/Assets/Scripts/ServerShared/Entity.cs @@ -10,8 +10,10 @@ using Unity.Mathematics; using static Unity.Mathematics.math; [MessagePackObject, + Union(0, typeof(Ship)), + Union(1, typeof(OrbitalEntity)), JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter))] -public class Entity : DatabaseEntry, IMessagePackSerializationCallbackReceiver +public abstract class Entity : DatabaseEntry, IMessagePackSerializationCallbackReceiver { [IgnoreMember] public Dictionary AxisOverrides = new Dictionary(); [IgnoreMember] public readonly Dictionary VisibilitySources = new Dictionary(); @@ -24,6 +26,9 @@ public class Entity : DatabaseEntry, IMessagePackSerializationCallbackReceiver [IgnoreMember] public Dictionary Axes; public readonly List Cargo; public readonly List EquippedItems; + public Entity Parent; + public List Children = new List(); + public Guid Zone; [IgnoreMember] protected List Behaviors; @@ -37,6 +42,7 @@ public class Entity : DatabaseEntry, IMessagePackSerializationCallbackReceiver public Entity(GameContext context, Gear hull, IEnumerable items, IEnumerable cargo) { + ID = Guid.NewGuid(); Context = context; EquippedItems = items.ToList(); @@ -72,7 +78,8 @@ public class Entity : DatabaseEntry, IMessagePackSerializationCallbackReceiver { Mass = Hull?.Mass ?? 0 + EquippedItems.Sum(i => i.Mass) + - Cargo.Sum(ii => ii.Mass); + Cargo.Sum(ii => ii.Mass) + + Children.Sum(c=>c.Mass); SpecificHeat = (Hull?.HeatCapacity ?? 0) + EquippedItems.Sum(i => i.HeatCapacity) + @@ -108,6 +115,12 @@ public class Entity : DatabaseEntry, IMessagePackSerializationCallbackReceiver foreach (var item in EquippedItems.Where(item => item.ItemData.Performance(Temperature) < .01f)) item.Durability -= delta; + + if (Parent != null) + { + Position = Parent.Position; + Velocity = Parent.Velocity; + } } public void OnBeforeSerialize() diff --git a/Assets/Scripts/ServerShared/GameContext.cs b/Assets/Scripts/ServerShared/GameContext.cs index ddc5b79e0..24200f8e5 100644 --- a/Assets/Scripts/ServerShared/GameContext.cs +++ b/Assets/Scripts/ServerShared/GameContext.cs @@ -2,14 +2,17 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using Unity.Mathematics; using static Unity.Mathematics.math; +using float2 = Unity.Mathematics.float2; using Random = Unity.Mathematics.Random; public class GameContext { public Random Random = new Random((uint) (DateTime.Now.Ticks%uint.MaxValue)); public List Agents = new List(); - public Dictionary> ZoneContents = new Dictionary>(); + public Dictionary ZonePlanets = new Dictionary(); + public Dictionary> ZoneEntities = new Dictionary>(); public Dictionary MapLayers = new Dictionary(); private Action _logger; @@ -20,6 +23,10 @@ public class GameContext private double _time; private float _deltaTime; private GlobalData _globalData; + private HashSet _orbits = new HashSet(); + private Dictionary _orbitVelocities = new Dictionary(); + private Dictionary _orbitPositions = new Dictionary(); + private Dictionary _previousOrbitPositions = new Dictionary(); public GlobalData GlobalData => _globalData ?? (_globalData = Cache.GetAll().FirstOrDefault()); public DatabaseCache Cache { get; } @@ -34,6 +41,13 @@ public class GameContext } } + public float2 WormholePosition(Guid zone, Guid other) + { + var zoneData = Cache.Get(zone); + var direction = Cache.Get(other).Position - zoneData.Position; + return normalize(direction) * zoneData.Radius * .95f; + } + // private readonly Dictionary Tier = new Dictionary(); public GameContext(DatabaseCache cache, Action logger) @@ -53,56 +67,81 @@ public class GameContext _logger(s); } - public IEnumerable ZoneEntities(ZoneData zone) + public IEnumerable GetEntities(Guid zone) { - return ZoneContents[zone].Values; + return ZoneEntities[zone].Values; } - public Dictionary InitializeZone(Guid zoneID) + public void InitializeZone(Guid zoneID) { - var contents = new Dictionary(); - var zoneData = Cache.Get(zoneID); - // TODO: Associate planets with stored entities for planetary colonies - var planetsData = zoneData.Planets.Select(id => Cache.Get(id)).ToArray(); - var planetEntities = planetsData.ToDictionary(p => p, - p => new OrbitalEntity(this, null, Enumerable.Empty(), Enumerable.Empty(), p.Belt ? Cache.Get(p.Orbit).Parent : p.Orbit)); - foreach(var kvp in planetEntities) - contents.Add(kvp.Key, kvp.Value); + foreach (var orbit in zoneData.Orbits) _orbits.Add(orbit); - var stationsData = zoneData.Stations.Select(id => Cache.Get(id)); - var stationEntities = stationsData.ToDictionary(s => s, - s => new OrbitalEntity(this, null, Enumerable.Empty(), Enumerable.Empty(), s.Parent)); - foreach(var kvp in stationEntities) - contents.Add(kvp.Key, kvp.Value); + // TODO: Associate planets with stored entities for planetary colonies + ZonePlanets[zoneID] = zoneData.Planets; - ZoneContents.Add(zoneData, contents); - - return contents; + // TODO: Load stored entities } public void Update() { + _previousOrbitPositions = _orbitPositions; + _orbitPositions = new Dictionary(_orbits.Count); + + foreach(var orbit in _orbits) + { + _orbitPositions[orbit] = GetOrbitPosition(orbit); + _orbitVelocities[orbit] = _previousOrbitPositions.ContainsKey(orbit) + ? _orbitPositions[orbit] - _previousOrbitPositions[orbit] + : float2.zero; + } + foreach (var agent in Agents) { agent.Update(_deltaTime); } - OrbitalEntity.ClearOrbits(); - foreach (var kvp in ZoneContents) + + foreach (var kvp in ZoneEntities) { - var zone = kvp.Key; - var entities = kvp.Value.Values; - foreach (var entity in entities) - { - entity.Update(_deltaTime); - } + foreach (var entity in kvp.Value.Values) entity.Update(_deltaTime); } } - public void UnloadZone(ZoneData zone) + public void UnloadZone(Guid zone) { - ZoneContents.Remove(zone); + var zoneData = Cache.Get(zone); + foreach (var orbit in zoneData.Orbits) _orbits.Remove(orbit); + ZoneEntities.Remove(zone); + } + + // Determine orbital position recursively, caching parent positions to avoid repeated calculations + public float2 GetOrbitPosition(Guid orbit) + { + // Root orbit is fixed at center + if(orbit==Guid.Empty) + return float2.zero; + + if (!_orbitPositions.ContainsKey(orbit)) + { + var orbitData = Cache.Get(orbit); + _orbitPositions[orbit] = GetOrbitPosition(orbitData.Parent) + (orbitData.Period < .01f ? float2.zero : + OrbitData.Evaluate((float) (Time / -orbitData.Period * GlobalData.OrbitSpeedMultiplier + orbitData.Phase)) * + orbitData.Distance); + } + + var position = _orbitPositions[orbit]; + if (float.IsNaN(position.x)) + { + Log("Orbit position is NaN, something went very wrong!"); + return float2.zero; + } + return _orbitPositions[orbit]; + } + + public float2 GetOrbitVelocity(Guid orbit) + { + return _orbitVelocities.ContainsKey(orbit) ? _orbitVelocities[orbit] : float2.zero; } // public int ItemTier(CraftedItemData itemData) diff --git a/Assets/Scripts/ServerShared/GlobalData.cs b/Assets/Scripts/ServerShared/GlobalData.cs index d8b451c73..516ca0dff 100644 --- a/Assets/Scripts/ServerShared/GlobalData.cs +++ b/Assets/Scripts/ServerShared/GlobalData.cs @@ -95,22 +95,25 @@ public class GlobalData : DatabaseEntry [InspectableField, JsonProperty("beltMassExponent"), Key(27)] public float BeltMassExponent = 100f; - [InspectableField, JsonProperty("asteroidSizeMin"), Key(28)] + [InspectableField, JsonProperty("asteroidSizeMin"), Key(28)] public float AsteroidSizeMin = 2f; - [InspectableField, JsonProperty("asteroidSizeMax"), Key(29)] + [InspectableField, JsonProperty("asteroidSizeMax"), Key(29)] public float AsteroidSizeMax = 10f; - [InspectableField, JsonProperty("asteroidSizeExponent"), Key(30)] + [InspectableField, JsonProperty("asteroidSizeExponent"), Key(30)] public float AsteroidSizeExponent = 2f; - [InspectableField, JsonProperty("asteroidRotationSpeed"), Key(31)] + [InspectableField, JsonProperty("asteroidRotationSpeed"), Key(31)] public float AsteroidRotationSpeed = 2f; - [InspectableField, JsonProperty("dockingDistance"), Key(32)] - public float DockingDistance = 10; + [InspectableField, JsonProperty("dockingDistance"), Key(32)] + public float DockingDistance = 25; - [InspectableField, JsonProperty("orbitSpeedMultiplier"), Key(33)] + [InspectableField, JsonProperty("warpDistance"), Key(33)] + public float WarpDistance = 25; + + [InspectableField, JsonProperty("orbitSpeedMultiplier"), Key(34)] public float OrbitSpeedMultiplier = .25f; public float PlanetRadius(float mass) diff --git a/Assets/Scripts/ServerShared/OrbitalEntity.cs b/Assets/Scripts/ServerShared/OrbitalEntity.cs index 5c83131a5..1f8eaff90 100644 --- a/Assets/Scripts/ServerShared/OrbitalEntity.cs +++ b/Assets/Scripts/ServerShared/OrbitalEntity.cs @@ -8,45 +8,15 @@ using float2 = Unity.Mathematics.float2; public class OrbitalEntity : Entity { private Guid _orbitData; - private static Dictionary _orbitPositions = new Dictionary(); public OrbitalEntity(GameContext context, Gear hull, IEnumerable items, IEnumerable cargo, Guid orbit) : base(context, hull, items, cargo) { _orbitData = orbit; } - public static void ClearOrbits() - { - _orbitPositions.Clear(); - } - - // Determine orbital position recursively, caching parent positions to avoid repeated calculations - private float2 GetOrbitPosition(Guid orbit) - { - // Root orbit is fixed at center - if(orbit==Guid.Empty) - return float2.zero; - - if (!_orbitPositions.ContainsKey(orbit)) - { - var orbitData = Context.Cache.Get(orbit); - _orbitPositions[orbit] = GetOrbitPosition(orbitData.Parent) + (orbitData.Period < .01f ? float2.zero : - OrbitData.Evaluate((float) (Context.Time / -orbitData.Period * Context.GlobalData.OrbitSpeedMultiplier + orbitData.Phase)) * - orbitData.Distance); - } - - var position = _orbitPositions[orbit]; - if (float.IsNaN(position.x)) - { - Context.Log("Orbit position is NaN, something went very wrong!"); - return float2.zero; - } - return _orbitPositions[orbit]; - } - public override void Update(float delta) { - var newPosition = GetOrbitPosition(_orbitData); + var newPosition = Context.GetOrbitPosition(_orbitData); Velocity = (newPosition - Position) / delta; Position = newPosition; base.Update(delta); diff --git a/Assets/Scripts/ServerShared/ZoneData.cs b/Assets/Scripts/ServerShared/ZoneData.cs index 33cfea64c..9af7fdac2 100644 --- a/Assets/Scripts/ServerShared/ZoneData.cs +++ b/Assets/Scripts/ServerShared/ZoneData.cs @@ -9,29 +9,26 @@ using static Unity.Mathematics.math; [RethinkTable("Galaxy"), MessagePackObject, JsonObject(MemberSerialization.OptIn)] public class ZoneData : DatabaseEntry, INamedEntry { - [JsonProperty("name"), Key(1)] + [JsonProperty("name"), Key(1)] public string Name; - [JsonProperty("position"), Key(2)] + [JsonProperty("position"), Key(2)] public float2 Position = 500; - [JsonProperty("wormholes"), Key(3)] - public List Wormholes = new List(); - - [JsonProperty("stations"), Key(4)] - public List Stations = new List(); - - [JsonProperty("planets"), Key(5)] - public List Planets = new List(); - - [JsonProperty("orbits"), Key(6)] - public List Orbits = new List(); - - [JsonProperty("radius"), Key(7)] + [JsonProperty("radius"), Key(3)] public float Radius = 2000; - [JsonProperty("visited"), Key(8)] + [JsonProperty("visited"), Key(4)] public bool Visited; + + [JsonProperty("wormholes"), Key(5)] + public List Wormholes = new List(); + + [JsonProperty("planets"), Key(6)] + public Guid[] Planets;// = new List(); + + [JsonProperty("orbits"), Key(7)] + public List Orbits = new List(); [IgnoreMember] public string EntryName { diff --git a/Assets/Scripts/ServerShared/ZoneGenerator.cs b/Assets/Scripts/ServerShared/ZoneGenerator.cs index 97b1f3e8a..ea19a16e6 100644 --- a/Assets/Scripts/ServerShared/ZoneGenerator.cs +++ b/Assets/Scripts/ServerShared/ZoneGenerator.cs @@ -104,7 +104,7 @@ public class ZoneGenerator return planetData; }).ToArray(); - zone.Planets = planetsData.Select(pd => pd.ID).ToList(); + zone.Planets = planetsData.Select(pd => pd.ID).ToArray(); zone.Orbits = orbitData.Select(od => od.ID).ToList(); } diff --git a/Assets/Scripts/StrategyGameManager.cs b/Assets/Scripts/StrategyGameManager.cs index 3a620ee87..a1e8fd07e 100644 --- a/Assets/Scripts/StrategyGameManager.cs +++ b/Assets/Scripts/StrategyGameManager.cs @@ -75,8 +75,8 @@ public class StrategyGameManager : MonoBehaviour private GalaxyZone _selectedGalaxyZone; private Dictionary _galaxyResponseZones; private Dictionary _galaxyZoneObjects = new Dictionary(); - private Dictionary _zoneObjects = new Dictionary(); - private Dictionary _zoneBelts = new Dictionary(); + private Dictionary _zoneObjects = new Dictionary(); // Key is Orbit + private Dictionary _zoneBelts = new Dictionary(); private Dictionary _zoneShips = new Dictionary(); private List _wormholes = new List(); private List _zonePropertiesResources = new List(); @@ -192,12 +192,12 @@ public class StrategyGameManager : MonoBehaviour { foreach (var planet in _zoneObjects) { - planet.Value.transform.position = float3(planet.Key.Position * ZoneSizeScale, .1f); + planet.Value.transform.position = float3(_context.GetOrbitPosition(planet.Key) * ZoneSizeScale, .1f); } foreach (var belt in _zoneBelts) { - belt.Value.Transform.position = float3(belt.Key.Position * ZoneSizeScale, .15f); + belt.Value.Transform.position = float3(_context.GetOrbitPosition(belt.Key) * ZoneSizeScale, .15f); belt.Value.Update(); } @@ -291,7 +291,7 @@ public class StrategyGameManager : MonoBehaviour _zoneShips.Clear(); if(_populatedZone!=Guid.Empty) - _context.UnloadZone(_cache.Get(_populatedZone)); + _context.UnloadZone(_populatedZone); _populatedZone = _selectedZone; @@ -321,67 +321,37 @@ public class StrategyGameManager : MonoBehaviour zoneData.Visited = true; } - var zoneContents = _context.InitializeZone(_populatedZone); + _context.InitializeZone(_populatedZone); float zoneDepth = 0; - foreach (var kvp in zoneContents) + foreach (var planet in _context.ZonePlanets[_populatedZone]) { - var entity = kvp.Value; - if (kvp.Key is PlanetData planetData) + var planetData = _cache.Get(planet); + if (!planetData.Belt) { - if (!planetData.Belt) - { - var planetObject = Instantiate(ZoneObjectPrefab, ZoneRoot); - _zoneObjects[entity as OrbitalEntity] = planetObject; - planetObject.Label.text = planetData.Name; - planetObject.GravityMesh.gameObject.SetActive(true); - planetObject.GravityMesh.transform.localScale = - Vector3.one * (pow(planetData.Mass, _context.GlobalData.GravityRadiusExponent) * - _context.GlobalData.GravityRadiusMultiplier * 2 * ZoneSizeScale); - var depth = pow(planetData.Mass, ZoneMassPower) * ZoneMassScale; - if (depth > zoneDepth) - zoneDepth = depth; - planetObject.GravityMesh.material.SetFloat("_Depth", depth); - planetObject.Icon.material.SetTexture("_MainTex", - planetData.Mass > _context.GlobalData.SunMass ? SunSprite : - planetData.Mass > _context.GlobalData.GasGiantMass ? GasGiantSprite : - planetData.Mass > _context.GlobalData.PlanetMass ? PlanetSprite : - PlanetoidSprite); - planetObject.Icon.GetComponent().OnClick += (collider, data) => - { - ZonePropertiesPanel.gameObject.SetActive(true); - foreach (var zonePlanetProperty in ZonePlanetProperties) - zonePlanetProperty.gameObject.SetActive(true); - - foreach (var zonePropertiesResource in _zonePropertiesResources) - Destroy(zonePropertiesResource.gameObject); - _zonePropertiesResources.Clear(); - - ZonePropertiesName.text = planetData.Name; - ZonePropertiesMass.text = $"{planetData.Mass}"; - foreach (var resource in planetData.Resources) - { - var itemData = _context.Cache.Get(resource.Key); - var resourceInstance = Instantiate(ZonePropertiesResourcePrefab, ZonePropertiesResourcesParent); - resourceInstance.NameLabel.text = itemData.Name; - resourceInstance.QuantityLabel.text = $"{resource.Value:0}"; - _zonePropertiesResources.Add(resourceInstance); - } - }; - } - else - { - var beltObject = Instantiate(BeltPrefab, ZoneRoot); - var collider = beltObject.GetComponent(); - var belt = new AsteroidBelt(_context, beltObject, collider, planetData, AsteroidSpritesheetWidth, AsteroidSpritesheetHeight, ZoneSizeScale); - _zoneBelts[entity as OrbitalEntity] = belt; - beltObject.GetComponent().OnClick += (_, data) => + var planetObject = Instantiate(ZoneObjectPrefab, ZoneRoot); + _zoneObjects[planetData.Orbit] = planetObject; + planetObject.Label.text = planetData.Name; + planetObject.GravityMesh.gameObject.SetActive(true); + planetObject.GravityMesh.transform.localScale = + Vector3.one * (pow(planetData.Mass, _context.GlobalData.GravityRadiusExponent) * + _context.GlobalData.GravityRadiusMultiplier * 2 * ZoneSizeScale); + var depth = pow(planetData.Mass, ZoneMassPower) * ZoneMassScale; + if (depth > zoneDepth) + zoneDepth = depth; + planetObject.GravityMesh.material.SetFloat("_Depth", depth); + planetObject.Icon.material.SetTexture("_MainTex", + planetData.Mass > _context.GlobalData.SunMass ? SunSprite : + planetData.Mass > _context.GlobalData.GasGiantMass ? GasGiantSprite : + planetData.Mass > _context.GlobalData.PlanetMass ? PlanetSprite : + PlanetoidSprite); + planetObject.Icon.GetComponent().OnClick += (collider, data) => { ZonePropertiesPanel.gameObject.SetActive(true); foreach (var zonePlanetProperty in ZonePlanetProperties) zonePlanetProperty.gameObject.SetActive(true); - + foreach (var zonePropertiesResource in _zonePropertiesResources) Destroy(zonePropertiesResource.gameObject); _zonePropertiesResources.Clear(); @@ -397,19 +367,34 @@ public class StrategyGameManager : MonoBehaviour _zonePropertiesResources.Add(resourceInstance); } }; - // var beltEmission = beltObject.emission; - // beltEmission.rateOverTime = - // new ParticleSystem.MinMaxCurve( - // pow(planetData.Mass,_context.GlobalData.BeltMassExponent) - // / _context.GlobalData.BeltMassRatio * orbit.Distance); - // var beltShape = beltObject.shape; - // beltShape.radius = orbit.Distance * ZoneSizeScale; - // beltShape.donutRadius = orbit.Distance * ZoneSizeScale / 2; - // var beltVelocity = beltObject.velocityOverLifetime; - // beltVelocity.orbitalZ = _context.GlobalData.OrbitSpeedMultiplier * orbit.Distance * ZoneSizeScale / orbit.Period; - // beltObject.Simulate(60); - // beltObject.Play(); - } + } + else + { + var beltObject = Instantiate(BeltPrefab, ZoneRoot); + var collider = beltObject.GetComponent(); + var belt = new AsteroidBelt(_context, beltObject, collider, planetData, AsteroidSpritesheetWidth, AsteroidSpritesheetHeight, ZoneSizeScale); + _zoneBelts[_cache.Get(planetData.Orbit).Parent] = belt; + beltObject.GetComponent().OnClick += (_, data) => + { + ZonePropertiesPanel.gameObject.SetActive(true); + foreach (var zonePlanetProperty in ZonePlanetProperties) + zonePlanetProperty.gameObject.SetActive(true); + + foreach (var zonePropertiesResource in _zonePropertiesResources) + Destroy(zonePropertiesResource.gameObject); + _zonePropertiesResources.Clear(); + + ZonePropertiesName.text = planetData.Name; + ZonePropertiesMass.text = $"{planetData.Mass}"; + foreach (var resource in planetData.Resources) + { + var itemData = _context.Cache.Get(resource.Key); + var resourceInstance = Instantiate(ZonePropertiesResourcePrefab, ZonePropertiesResourcesParent); + resourceInstance.NameLabel.text = itemData.Name; + resourceInstance.QuantityLabel.text = $"{resource.Value:0}"; + _zonePropertiesResources.Add(resourceInstance); + } + }; } } @@ -423,8 +408,7 @@ public class StrategyGameManager : MonoBehaviour var otherZone = _galaxyResponseZones[wormhole]; var wormholeObject = Instantiate(ZoneObjectPrefab, ZoneRoot); _wormholes.Add(wormholeObject); - var direction = otherZone.Position - zoneData.Position; - wormholeObject.transform.position = (Vector2) (normalize(direction) * zoneData.Radius * .95f * ZoneSizeScale); + wormholeObject.transform.position = (Vector2) (_context.WormholePosition(zoneData.ID, wormhole) * ZoneSizeScale); wormholeObject.GravityMesh.gameObject.SetActive(false); wormholeObject.Icon.material.SetTexture("_MainTex", WormholeSprite); wormholeObject.Label.text = otherZone.Name; @@ -505,13 +489,9 @@ public class StrategyGameManager : MonoBehaviour if (args[0] == "ship") { var entity = new Ship(_context, hull, gear, Enumerable.Empty()); - var shipData = new ShipData // TODO: Better database entry for ships? - { - ID = Guid.NewGuid() - }; - _cache.Add(shipData); - _context.ZoneContents[zoneData][shipData] = entity; - _context.Agents.Add(new AgentController(_context, zoneData, entity)); + _context.Cache.Add(entity); + _context.ZoneEntities[_populatedZone][entity.ID] = entity; + _context.Agents.Add(new AgentController(_context, _populatedZone, entity)); var zoneShip = Instantiate(ZoneShipPrefab, ZoneRoot); zoneShip.Label.text = $"Ship {_zoneShips.Count}"; _zoneShips[entity] = zoneShip; @@ -533,7 +513,7 @@ public class StrategyGameManager : MonoBehaviour } if(_populatedZone!=Guid.Empty) - _context.UnloadZone(_cache.Get(_populatedZone)); + _context.UnloadZone(_populatedZone); _cache.Delete(zoneData); _galaxyResponseZones.Remove(zoneData.ID); diff --git a/Assets/Scripts/UI/ClickCatcher.cs b/Assets/Scripts/UI/ClickCatcher.cs index 3859d535a..dc2058622 100644 --- a/Assets/Scripts/UI/ClickCatcher.cs +++ b/Assets/Scripts/UI/ClickCatcher.cs @@ -9,7 +9,7 @@ public class ClickCatcher : MonoBehaviour, IPointerEnterHandler, IPointerExitHan { //public bool EnableMouse => PointerIsInside && !_catching; public bool PointerIsInside { get; private set; } - public float ClickTime = .5f; + public float DragDistance = 25f; public event Action OnEnter; public event Action OnExit; @@ -56,6 +56,7 @@ public class ClickCatcher : MonoBehaviour, IPointerEnterHandler, IPointerExitHan public void OnPointerClick(PointerEventData eventData) { - OnClick?.Invoke(eventData); + if((eventData.pressPosition - eventData.position).sqrMagnitude < DragDistance) + OnClick?.Invoke(eventData); } }