Created control module abstraction, vastly simplifying current and future control module code
Created context menu option for creating towing tasks
This commit is contained in:
hyperion51 2020-05-27 02:23:25 +01:00
commit 139c593ccd
21 changed files with 685 additions and 291 deletions

View file

@ -1,64 +0,0 @@
// using System;
// using System.Collections;
// using System.Collections.Generic;
// using System.Linq;
// using static Unity.Mathematics.math;
// using Random = Unity.Mathematics.Random;
//
// public class AgentController
// {
// public Guid Entity { get; }
// public EntityAgent EntityAgent { get; }
// public GameContext Context { get; }
// public Guid Zone { get; set; }
//
// 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, Guid entity)
// {
// Entity = entity;
// Zone = zone;
// Context = context;
// EntityAgent = new EntityAgent(context, entity, zone, Guid.Empty);
// _locomotion = new Locomotion(context, entity);
// _velocityMatch = new VelocityMatch(context, entity);
// _velocityMatch.OnMatch += () =>
// {
// EntityAgent.CurrentBehavior = _locomotion;
// RandomTarget();
// };
// EntityAgent.CurrentBehavior = _locomotion;
// RandomTarget();
// }
//
// public void Update(float delta)
// {
// EntityAgent.Update(delta);
// // Context.Log(
// // $"Agent Mode: {EntityAgent.CurrentBehavior.GetType()} " +
// // $"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)
// {
// var orbitData = Context.Cache.Get<OrbitData>(_targetOrbit);
// _velocityMatch.TargetOrbit = _targetOrbit;
// var matchDistanceTime = _velocityMatch.MatchDistanceTime;
// _locomotion.Objective = Context.GetOrbitPosition(_targetOrbit) + Context.GetOrbitVelocity(_targetOrbit) * matchDistanceTime.y;
// var distance = length(_locomotion.Objective - entity.Position);
// if (distance < matchDistanceTime.x)
// EntityAgent.CurrentBehavior = _velocityMatch;
// }
// }
//
// private void RandomTarget()
// {
// var entities = Context.ZonePlanets[Zone];
// _targetOrbit = Context.Cache.Get<PlanetData>(entities[_random.NextInt(entities.Length)]).Orbit;
// }
// }

View file

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ee1e3350676acb044bd87c1d76c535a4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -1,29 +0,0 @@
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
{
[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 EntityAgent(GameContext context, Guid entity, Guid homeZone, Guid homeColony)
{
Entity = entity;
HomeZone = homeZone;
Context = context;
}
public void Update(float delta)
{
CurrentBehavior?.Update(delta);
}
}

View file

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: fdefbc1e15541d8448061e9d97e44648
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -20,11 +20,11 @@ public class StationTowing : AgentTask
[JsonProperty("orbitDistance"), Key(6)]
public float OrbitDistance;
public StationTowing(Guid zone, Guid station, Guid orbitParent, float orbitDistance)
{
Zone = zone;
Station = station;
OrbitParent = orbitParent;
OrbitDistance = orbitDistance;
}
// public StationTowing(Guid zone, Guid station, Guid orbitParent, float orbitDistance)
// {
// Zone = zone;
// Station = station;
// OrbitParent = orbitParent;
// OrbitDistance = orbitDistance;
// }
}

View file

@ -52,7 +52,7 @@ public interface IController
bool Available { get; }
TaskType TaskType { get; }
Guid Zone { get; }
void AssignTask(Guid task, List<SimplifiedZoneData> path);
void AssignTask(Guid task);
}
[MessagePackObject,

View file

@ -3,6 +3,9 @@ using System.Collections;
using System.Collections.Generic;
using MessagePack;
using Newtonsoft.Json;
using Unity.Mathematics;
using static Unity.Mathematics.math;
using float2 = Unity.Mathematics.float2;
[Union(0, typeof(TowingControllerData))]
public abstract class ControllerData : BehaviorData
@ -18,27 +21,171 @@ public abstract class ControllerData : BehaviorData
[InspectableField, JsonProperty("tangentSensitivity"), Key(4)]
public float TangentSensitivity = 4;
[InspectableField, JsonProperty("targetDistance"), Key(5)]
public float TargetDistance = 10;
}
// public abstract class Controller : IController
// {
// public abstract bool Available { get; }
// public abstract TaskType TaskType { get; }
// public Guid Zone { get; }
//
// private GameContext _context;
// private Entity _entity;
// private Guid _task;
// private List<SimplifiedZoneData> _path;
//
// public Controller(GameContext context, Entity entity)
// {
//
// }
//
// public void AssignTask(Guid task, List<SimplifiedZoneData> path)
// {
// _task = task;
// _path = path;
// }
// }
public abstract class ControllerBase : IBehavior, IController, IInitializableBehavior
{
public Guid HomeEntity;
public bool Available => Task == Guid.Empty;
public abstract TaskType TaskType { get; }
public Guid Zone => _entity.Zone;
public BehaviorData Data => _controllerData;
protected Locomotion Locomotion;
protected VelocityMatch VelocityMatch;
protected Func<float2> TargetPosition;
protected Func<float2> TargetVelocity;
protected bool MatchVelocity;
protected List<SimplifiedZoneData> Path;
protected Guid Task;
private GameContext _context;
private Entity _entity;
private ControllerData _controllerData;
private MovementPhase _movementPhase;
private bool _moving;
private Action _onFinishMoving;
public ControllerBase(GameContext context, ControllerData data, Entity entity)
{
_context = context;
_controllerData = data;
_entity = entity;
}
public void Initialize()
{
Locomotion = new Locomotion(_context, _entity, _controllerData);
VelocityMatch = new VelocityMatch(_context, _entity, _controllerData);
_context.CorporationControllers[_entity.Corporation].Add(this);
}
public void AssignTask(Guid task)
{
Task = task;
_moving = false;
}
public bool Update(float delta)
{
if (Available)
{
// No task is assigned and we're at home, do nothing!
if (_entity.Parent == HomeEntity)
return false;
// No task is assigned, but we're not home, go home!
var homeEntity = _context.Cache.Get<Entity>(HomeEntity);
if (!_moving)
{
if (Zone == homeEntity.Zone) MoveTo(homeEntity, true, () =>
_context.SetParent(_entity, homeEntity));
else MoveTo(homeEntity.Zone, () => MoveTo(homeEntity, true, () =>
_context.SetParent(_entity, homeEntity)));
}
}
if (_moving)
{
var distance = length(TargetPosition() - _entity.Position);
if (MatchVelocity)
{
VelocityMatch.TargetVelocity = TargetVelocity();
if (_movementPhase == MovementPhase.Locomotion)
{
var matchDistanceTime = VelocityMatch.MatchDistanceTime;
Locomotion.Objective = TargetPosition() + TargetVelocity() * matchDistanceTime.y;
Locomotion.Update(delta);
if (distance < matchDistanceTime.x)
{
_movementPhase = MovementPhase.Slowdown;
_context.Log($"Controller {_entity.Name} has entered slowdown phase.");
VelocityMatch.Clear();
VelocityMatch.OnMatch += () =>
{
_moving = false;
_onFinishMoving();
};
}
}
else
{
VelocityMatch.Update(delta);
}
}
else
{
Locomotion.Objective = TargetPosition();
Locomotion.Update(delta);
if (distance < _controllerData.TargetDistance)
{
_moving = false;
_onFinishMoving();
}
}
}
return true;
}
public void MoveTo(Entity entity, bool matchVelocity = true, Action onFinish = null)
{
TargetPosition = () => entity.Position;
TargetVelocity = () => entity.Velocity;
MatchVelocity = matchVelocity;
_movementPhase = MovementPhase.Locomotion;
_moving = true;
_onFinishMoving = onFinish;
}
public void MoveTo(float2 position, bool matchVelocity = true, Action onFinish = null)
{
TargetPosition = () => position;
TargetVelocity = () => float2.zero;
MatchVelocity = matchVelocity;
_movementPhase = MovementPhase.Locomotion;
_moving = true;
_onFinishMoving = onFinish;
}
public void MoveTo(Func<float2> position, Func<float2> velocity, Action onFinish = null)
{
TargetPosition = position;
TargetVelocity = velocity;
MatchVelocity = true;
_movementPhase = MovementPhase.Locomotion;
_moving = true;
_onFinishMoving = onFinish;
}
public void MoveTo(Guid zone, Action onFinish = null)
{
var path = _context.FindPath(_context.GalaxyZones[Zone], _context.GalaxyZones[zone]);
void OnNextZone()
{
path.RemoveAt(0);
if (path.Count > 0)
{
MoveTo(_context.WormholePosition(_entity.Zone, Path[0].ZoneID), false, OnNextZone);
}
else
{
onFinish?.Invoke();
}
}
OnNextZone();
}
}
public enum MovementPhase
{
Locomotion,
Slowdown
}

View file

@ -9,9 +9,6 @@ using static Unity.Mathematics.math;
[MessagePackObject, JsonObject(MemberSerialization.OptIn), EntityTypeRestriction(HullType.Ship), Order(-100)]
public class PatrolControllerData : ControllerData
{
[InspectableField, JsonProperty("targetDistance"), Key(5)]
public float TargetDistance = 10;
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
{
return new PatrolController(context, this, entity, item);
@ -58,7 +55,7 @@ public class PatrolController : IBehavior, IController, IInitializableBehavior
return true;
}
public void AssignTask(Guid task, List<SimplifiedZoneData> path)
public void AssignTask(Guid task)
{
throw new NotImplementedException();
}

View file

@ -16,156 +16,84 @@ public class TowingControllerData : ControllerData
}
}
public class TowingController : IBehavior, IPersistentBehavior, IController, IInitializableBehavior
public class TowingController : ControllerBase, IBehavior, IPersistentBehavior
{
public TaskType TaskType => TaskType.Tow;
public bool Available => _towingTask != Guid.Empty;
public Guid Zone => _entity.Zone;
public override TaskType TaskType => TaskType.Tow;
public BehaviorData Data => _data;
private TowingControllerData _data;
private GameContext _context;
private Entity _entity;
private Gear _item;
private Guid _towingTask;
private List<SimplifiedZoneData> _path;
private TowingPhase _towingPhase = TowingPhase.Pickup;
private MovementPhase _movementPhase = MovementPhase.Locomotion;
private Locomotion _locomotion;
private VelocityMatch _velocityMatch;
private bool _taskStarted;
public TowingController(GameContext context, TowingControllerData data, Entity entity, Gear item)
public TowingController(GameContext context, TowingControllerData data, Entity entity, Gear item) : base(context, data, entity)
{
_context = context;
_data = data;
_entity = entity;
_item = item;
}
public void Initialize()
public new bool Update(float delta)
{
_locomotion = new Locomotion(_context, _entity, _data);
_velocityMatch = new VelocityMatch(_context, _entity, _data);
}
public bool Update(float delta)
{
var towingTask = _context.Cache.Get<StationTowing>(_towingTask);
if (towingTask == null)
return false;
if (_path.Any())
var towingTask = _context.Cache.Get<StationTowing>(Task);
if (towingTask != null)
{
_locomotion.Update(delta);
if(_entity.Parent!=Guid.Empty)
_context.RemoveParent(_entity);
if (length(_entity.Position - _locomotion.Objective) < _context.GlobalData.WarpDistance)
if (!_taskStarted)
{
_context.Warp(_entity, _path[0].ZoneID);
_path.RemoveAt(0);
if(_path.Any())
SetWormholeDestination();
}
}
else
{
var destination = float2(0);
var velocity = float2(0);
if (_towingPhase == TowingPhase.Pickup)
{
destination = _context.ZoneEntities[_entity.Zone][towingTask.Station].Position;
velocity = _context.ZoneEntities[_entity.Zone][towingTask.Station].Velocity;
}
else
{
var orbitParent = _context.GetOrbitPosition(towingTask.OrbitParent);
var parentToUs = _entity.Position - orbitParent;
var nearestPointInOrbit = orbitParent + normalize(parentToUs) * towingTask.OrbitDistance;
destination = nearestPointInOrbit;
velocity = _context.GetOrbitVelocity(towingTask.OrbitParent);
}
_velocityMatch.TargetVelocity = velocity;
if (_movementPhase == MovementPhase.Locomotion)
{
var matchDistanceTime = _velocityMatch.MatchDistanceTime;
_locomotion.Objective = destination + velocity * matchDistanceTime.y;
_locomotion.Update(delta);
var distance = length(destination - _entity.Position);
if (distance < matchDistanceTime.x)
MoveTo(towingTask.Zone, () =>
{
_movementPhase = MovementPhase.Slowdown;
_velocityMatch.Clear();
if (_towingPhase == TowingPhase.Pickup)
_velocityMatch.OnMatch += () =>
_context.Log($"Towing Controller {_entity.Name} has entered pickup phase.");
MoveTo(_context.Cache.Get<Entity>(towingTask.Station), true, () =>
{
var target = _context.ZoneEntities[_entity.Zone][towingTask.Station] as OrbitalEntity;
_context.SetParent(target, _entity);
_context.Log($"Towing Controller {_entity.Name} has entered delivery phase.");
MoveTo(() =>
{
var target = _context.ZoneEntities[_entity.Zone][towingTask.Station];
_context.SetParent(target, _entity);
_towingPhase = TowingPhase.Delivery;
_movementPhase = MovementPhase.Locomotion;
};
else
_velocityMatch.OnMatch += () =>
var orbitParent = _context.GetOrbitPosition(towingTask.OrbitParent);
var parentToUs = _entity.Position - orbitParent;
return orbitParent + normalize(parentToUs) * towingTask.OrbitDistance;
}, () => _context.GetOrbitVelocity(towingTask.OrbitParent), () =>
{
var target = _context.ZoneEntities[_entity.Zone][towingTask.Station] as OrbitalEntity;
_context.RemoveParent(target);
_context.Log($"Towing Controller {_entity.Name} has delivered the target. Returning Home.");
var orbit = _context.CreateOrbit(towingTask.OrbitParent, _entity.Position);
target.OrbitData = orbit.ID;
};
}
}
else
{
_velocityMatch.Update(delta);
Task = Guid.Empty;
_taskStarted = false;
});
});
});
_taskStarted = true;
}
}
return true;
return base.Update(delta);
}
public PersistentBehaviorData Store()
{
return new TowingControllerPersistence
{
TowingTask = _towingTask
Task = Task
};
}
public void Restore(PersistentBehaviorData data)
{
var towingControllerPersistence = data as TowingControllerPersistence;
_towingTask = towingControllerPersistence.TowingTask;
}
public void AssignTask(Guid task, List<SimplifiedZoneData> path)
{
_towingTask = task;
_path = path;
_path.RemoveAt(0);
if(_path.Any())
SetWormholeDestination();
}
private void SetWormholeDestination()
{
_locomotion.Objective = _context.WormholePosition(_entity.Zone, _path[0].ZoneID);
Task = towingControllerPersistence.Task;
}
}
public class TowingControllerPersistence : PersistentBehaviorData
{
[JsonProperty("towingTask"), Key(0)]
public Guid TowingTask;
}
public enum TowingPhase
{
Pickup,
Delivery
}
public enum MovementPhase
{
Locomotion,
Slowdown
[JsonProperty("task"), Key(0)]
public Guid Task;
}

View file

@ -53,10 +53,11 @@ public abstract class Entity : DatabaseEntry, IMessagePackSerializationCallbackR
}
public Entity(GameContext context, Guid hull, IEnumerable<Guid> items, IEnumerable<Guid> cargo, Guid zone)
public Entity(GameContext context, Guid hull, IEnumerable<Guid> items, IEnumerable<Guid> cargo, Guid zone, Guid corporation)
{
Context = context;
Zone = zone;
Corporation = corporation;
EquippedItems = items.ToList();
Cargo = cargo.ToList();

View file

@ -134,7 +134,7 @@ public class GameContext
}
}
task.Reserved = true;
nearestController.AssignTask(task.ID, nearestControllerPath);
nearestController.AssignTask(task.ID);
}
}
}
@ -257,7 +257,8 @@ public class GameContext
var distance = length(delta);
var period = OrbitalPeriod(distance);
var phase = atan2(delta.y, delta.x) / (PI * 2);
var storedPhase = (float) frac(Time / -period * GlobalData.OrbitSpeedMultiplier - phase);
var currentPhase = frac(Time / -period * GlobalData.OrbitSpeedMultiplier);
var storedPhase = (float) frac(phase - currentPhase);
var orbit = new OrbitData
{
@ -644,7 +645,7 @@ public class GameContext
if (hullData.HullType == HullType.Ship)
{
var entity = new Ship(this, hull.ID, gear.Select(g => g.ID),
cargo.Select(c => c.ID).Concat(simpleCargo.Select(c => c.ID)), zone)
cargo.Select(c => c.ID).Concat(simpleCargo.Select(c => c.ID)), zone, corporation)
{
Name = $"{loadoutData.Name} {Random.NextInt(1,255):X}"
};
@ -671,7 +672,7 @@ public class GameContext
Cache.Add(orbit);
var entity = new OrbitalEntity(this, hull.ID, gear.Select(g => g.ID),
cargo.Select(c => c.ID).Concat(simpleCargo.Select(c => c.ID)), orbit.ID, zone)
cargo.Select(c => c.ID).Concat(simpleCargo.Select(c => c.ID)), orbit.ID, zone, corporation)
{
Name = $"{loadoutData.Name} {Random.NextInt(1,255):X}",
Temperature = 293
@ -800,6 +801,7 @@ public class GameContext
var parent = Cache.Get<Entity>(child.Parent);
parent.Children.Remove(child.ID);
parent.RecalculateMass();
child.Parent = Guid.Empty;
}
}

View file

@ -9,7 +9,7 @@ public class OrbitalEntity : Entity
{
public Guid OrbitData;
public OrbitalEntity(GameContext context, Guid hull, IEnumerable<Guid> items, IEnumerable<Guid> cargo, Guid orbit, Guid zone) : base(context, hull, items, cargo, zone)
public OrbitalEntity(GameContext context, Guid hull, IEnumerable<Guid> items, IEnumerable<Guid> cargo, Guid orbit, Guid zone, Guid corporation) : base(context, hull, items, cargo, zone, corporation)
{
OrbitData = orbit;
}

View file

@ -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, Guid hull, IEnumerable<Guid> items, IEnumerable<Guid> cargo, Guid zone) : base(context, hull, items, cargo, zone)
public Ship(GameContext context, Guid hull, IEnumerable<Guid> items, IEnumerable<Guid> cargo, Guid zone, Guid corporation) : base(context, hull, items, cargo, zone, corporation)
{
}

View file

@ -33,6 +33,7 @@ public class StrategyGameManager : MonoBehaviour
public CorporationMenuItem CorpOptionPrefab;
public TabButton CorpMenuContinueButton;
public TMP_InputField CorpNameInputField;
public LineRenderer OrbitLineRenderer;
[Section("Tab Links")]
public TabGroup PrimaryTabGroup;
@ -71,6 +72,7 @@ public class StrategyGameManager : MonoBehaviour
public float ChildEntityDistance = .66f;
public float ChildEntityScale = .25f;
public float ChildEntityOffsetDegrees = 30f;
public int OrbitCircleSegments = 128;
private DatabaseCache _cache;
private GameContext _context;
@ -97,6 +99,10 @@ public class StrategyGameManager : MonoBehaviour
private Dictionary<CorporationMenuItem, Guid> _corpOptionMap = new Dictionary<CorporationMenuItem, Guid>();
private CorporationMenuItem _selectedParent;
private Dictionary<int, float2[]> _childEntityPositions = new Dictionary<int, float2[]>();
private bool _orbitSelectMode;
private Guid _selectedOrbit = Guid.Empty;
private Guid _selectedTowingTarget = Guid.Empty;
private float _orbitRadius;
void Start()
{
@ -183,7 +189,9 @@ public class StrategyGameManager : MonoBehaviour
Parent = _corpOptionMap[_selectedParent]
};
_cache.Add(newCorp);
_context.CorporationControllers[newCorp.ID] = new List<IController>();
player.Corporation = newCorp.ID;
_playerCorporation = newCorp.ID;
GameMenuRoot.gameObject.SetActive(true);
CorpMenuRoot.gameObject.SetActive(false);
@ -198,7 +206,12 @@ public class StrategyGameManager : MonoBehaviour
entities.Add(_context.CreateEntity(_selectedZone, newCorp.ID, loadout.Key));
var colony = entities.First(e => e is OrbitalEntity);
foreach (var ship in entities.Where(e => e is Ship))
{
foreach (var controller in ship.GetBehaviors<ControllerBase>())
controller.HomeEntity = colony.ID;
_context.SetParent(ship, colony);
}
}
};
}
@ -232,7 +245,7 @@ public class StrategyGameManager : MonoBehaviour
foreach (var entry in zone.Contents) _cache.Add(entry);
if(_currentTab==GalaxyTabButton && _selectedZone == zone.Zone.ID)
PopulatePropertiesPanel(_selectedZone);
Select(_selectedZone);
if (_currentTab == ZoneTabButton && _populatedZone != zone.Zone.ID) PopulateZone();
});
@ -256,7 +269,7 @@ public class StrategyGameManager : MonoBehaviour
var zone = _cache.Get<ZoneData>(_selectedZone);
if (_populatedZone != _selectedZone && zone != null)
PopulateZone();
PopulatePropertiesPanel(_populatedZone);
Select(_populatedZone);
Camera.transform.position = -Vector3.forward;
if (zone != null)
Camera.orthographicSize = zone.Radius * ZoneSizeScale;
@ -286,12 +299,36 @@ public class StrategyGameManager : MonoBehaviour
else if (_currentTab == ZoneTabButton)
{
if (data.button == PointerEventData.InputButton.Left)
PopulatePropertiesPanel(_populatedZone);
{
if (_orbitSelectMode)
{
var playerCorp = _cache.Get<Corporation>(_playerCorporation);
var towingTask = new StationTowing
{
Context = _context,
OrbitDistance = _orbitRadius,
OrbitParent = _selectedOrbit,
Priority = 0,
Reserved = false,
Station = _selectedTowingTarget,
Zone = _populatedZone
};
_cache.Add(towingTask);
playerCorp.Tasks.Add(towingTask.ID);
_orbitSelectMode = false;
OrbitLineRenderer.gameObject.SetActive(false);
}
else
Select(_populatedZone);
}
else if (data.button == PointerEventData.InputButton.Right)
ShowContextMenu(_populatedZone);
}
else if (_currentTab == TechTabButton) PopulateTechProperties();
};
OrbitLineRenderer.positionCount = OrbitCircleSegments;
OrbitLineRenderer.gameObject.SetActive(false);
}
private void PopulateGalaxyProperties()
@ -369,7 +406,7 @@ public class StrategyGameManager : MonoBehaviour
childGameObject.GetComponent<ClickableCollider>().OnClick += (collider, data) =>
{
if (data.button == PointerEventData.InputButton.Left)
PopulatePropertiesPanel(child);
Select(child);
else if (data.button == PointerEventData.InputButton.Right)
ShowContextMenu(child);
};
@ -389,7 +426,7 @@ public class StrategyGameManager : MonoBehaviour
zoneShip.Icon.GetComponent<ClickableCollider>().OnClick += (collider, data) =>
{
if (data.button == PointerEventData.InputButton.Left)
PopulatePropertiesPanel(ship.ID);
Select(ship.ID);
else if (data.button == PointerEventData.InputButton.Right)
ShowContextMenu(ship.ID);
};
@ -425,7 +462,7 @@ public class StrategyGameManager : MonoBehaviour
zoneOrbital.Icon.GetComponent<ClickableCollider>().OnClick += (collider, data) =>
{
if (data.button == PointerEventData.InputButton.Left)
PopulatePropertiesPanel(orbital.ID);
Select(orbital.ID);
else if (data.button == PointerEventData.InputButton.Right)
ShowContextMenu(orbital.ID);
};
@ -446,6 +483,22 @@ public class StrategyGameManager : MonoBehaviour
Destroy(_zoneOrbitals[orbital].gameObject);
_zoneOrbitals.Remove(orbital);
}
if (_orbitSelectMode)
{
var center = _context.GetOrbitPosition(_selectedOrbit) * ZoneSizeScale;
var mousePos = Camera.ScreenToWorldPoint(Input.mousePosition);
var radius = length(float2(mousePos.x, mousePos.y) - center);
_orbitRadius = radius / ZoneSizeScale;
var positions = new Vector3[OrbitCircleSegments];
for (int i = 0; i < OrbitCircleSegments; i++)
{
var deg = ((float) i) / OrbitCircleSegments * 2 * PI;
positions[i] = float3(float2(sin(deg), cos(deg)) * radius + center, 0);
}
OrbitLineRenderer.gameObject.SetActive(true);
OrbitLineRenderer.SetPositions(positions);
}
}
}
@ -500,6 +553,20 @@ public class StrategyGameManager : MonoBehaviour
});
ContextMenu.AddOption("Test Option 3", () => Debug.Log("Test Option 3 Selected"));
}
else if (targetObject is Ship ship)
{
}
else if (targetObject is OrbitalEntity orbital)
{
ContextMenu.AddOption("Create Towing Task", () =>
{
_selectedOrbit = Guid.Empty;
_selectedTowingTarget = orbital.ID;
_orbitSelectMode = true;
OrbitLineRenderer.gameObject.SetActive(true);
});
}
else
{
ContextMenu.gameObject.SetActive(false);
@ -508,28 +575,35 @@ public class StrategyGameManager : MonoBehaviour
ContextMenu.Show();
}
void PopulatePropertiesPanel(Guid clickTarget)
void Select(Guid clickTarget)
{
var targetObject = _context.Cache.Get(clickTarget);
if (targetObject is PlanetData planet)
{
PropertiesPanel.Clear();
PropertiesPanel.Title.text = planet.Name;
if(planet.Belt)
PropertiesPanel.AddSection("Asteroid Belt");
else
PropertiesPanel.AddSection(
planet.Mass > _context.GlobalData.SunMass ? "Star" :
planet.Mass > _context.GlobalData.GasGiantMass ? "Gas Giant" :
planet.Mass > _context.GlobalData.PlanetMass ? "Planet" :
"Planetoid");
PropertiesPanel.AddProperty("Mass", () => $"{planet.Mass}");
PropertiesPanel.AddList("Resources", planet.Resources.Select(resource =>
if (_orbitSelectMode)
{
var itemData = _context.Cache.Get<SimpleCommodityData>(resource.Key);
return new Tuple<string, string>(itemData.Name, $"{resource.Value:0}");
}));
_selectedOrbit = planet.Orbit;
}
else
{
PropertiesPanel.Clear();
PropertiesPanel.Title.text = planet.Name;
if(planet.Belt)
PropertiesPanel.AddSection("Asteroid Belt");
else
PropertiesPanel.AddSection(
planet.Mass > _context.GlobalData.SunMass ? "Star" :
planet.Mass > _context.GlobalData.GasGiantMass ? "Gas Giant" :
planet.Mass > _context.GlobalData.PlanetMass ? "Planet" :
"Planetoid");
PropertiesPanel.AddProperty("Mass", () => $"{planet.Mass}");
PropertiesPanel.AddList("Resources", planet.Resources.Select(resource =>
{
var itemData = _context.Cache.Get<SimpleCommodityData>(resource.Key);
return new Tuple<string, string>(itemData.Name, $"{resource.Value:0}");
}));
}
}
if (targetObject is Entity entity)
@ -599,7 +673,7 @@ public class StrategyGameManager : MonoBehaviour
CultClient.Send(new ZoneRequestMessage{ZoneID = zone.ZoneID});
if (TestMode)
{
PopulatePropertiesPanel(zone.ZoneID);
Select(zone.ZoneID);
}
_selectedZone = zone.ZoneID;
_selectedGalaxyZone = instanceZone;
@ -700,7 +774,7 @@ public class StrategyGameManager : MonoBehaviour
planetObject.Icon.GetComponent<ClickableCollider>().OnClick += (collider, data) =>
{
if (data.button == PointerEventData.InputButton.Left)
PopulatePropertiesPanel(planetData.ID);
Select(planetData.ID);
else if (data.button == PointerEventData.InputButton.Right)
ShowContextMenu(planetData.ID);
};
@ -714,7 +788,7 @@ public class StrategyGameManager : MonoBehaviour
beltObject.GetComponent<ClickableCollider>().OnClick += (_, data) =>
{
if (data.button == PointerEventData.InputButton.Left)
PopulatePropertiesPanel(planetData.ID);
Select(planetData.ID);
else if (data.button == PointerEventData.InputButton.Right)
ShowContextMenu(planetData.ID);
};