New Inventory System + Overhaul
Removed universal GameContext references Refactored GameContext: It's now only responsible for item management. As such it's now called ItemManager GlobalData is gone, relevant settings are distributed amongst specialized settings classes Entities are no longer database entries, references to them are now direct - Zone is reponsible for storing them in ZonePacks Controller subtypes are now generic classes, class argument is task type Inventory is now a 2D grid instead of a list Entity temperature is now a 2D grid instead of a number Item sizes are now arbitrary shapes instead of a number Hardpoints are now arbitrary shapes instead Equipped items have their own temperatures Map view now displays sunlight colors Integrated Allegorithmic Substance Plugin Imported Djinni ship and assigned Substance materials Removed Node Editor framework (might come back later but needs work to integrate with behavior system)
This commit is contained in:
parent
53a91351b7
commit
f643f6cc8a
330 changed files with 24242 additions and 2830 deletions
|
|
@ -18,10 +18,10 @@ public abstract class AgentBehavior
|
|||
protected float TurningInput(float2 deltaV) => clamp(-Entity.Direction.AngleDiff(deltaV) * ControllerData.TurningSensitivity, -1, 1);
|
||||
|
||||
protected ControllerData ControllerData;
|
||||
protected GameContext Context;
|
||||
protected ItemManager Context;
|
||||
protected Entity Entity;
|
||||
|
||||
public AgentBehavior(GameContext context, Entity entity, ControllerData controllerData)
|
||||
public AgentBehavior(ItemManager context, Entity entity, ControllerData controllerData)
|
||||
{
|
||||
Context = context;
|
||||
Entity = entity;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public class Aim : AgentBehavior
|
|||
private Turning _turning;
|
||||
private VelocityLimit _velocityLimit;
|
||||
|
||||
public Aim(GameContext context, Entity entity, ControllerData controllerData) : base(context, entity, controllerData)
|
||||
public Aim(ItemManager context, Entity entity, ControllerData controllerData) : base(context, entity, controllerData)
|
||||
{
|
||||
_velocityLimit = Entity.GetBehaviors<VelocityLimit>().FirstOrDefault();
|
||||
_thrust = Entity.GetBehavior<Thruster>();
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ public class HaulingTask : AgentTask
|
|||
public override TaskType Type => TaskType.Haul;
|
||||
|
||||
[JsonProperty("origin"), Key(4)]
|
||||
public Guid Origin;
|
||||
public Entity Origin;
|
||||
|
||||
[JsonProperty("target"), Key(5)]
|
||||
public Guid Target;
|
||||
public Entity Target;
|
||||
|
||||
[JsonProperty("itemType"), Key(6)]
|
||||
public Guid ItemType;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public class Locomotion : AgentBehavior
|
|||
private Turning _turning;
|
||||
private VelocityLimit _velocityLimit;
|
||||
|
||||
public Locomotion(GameContext context, Entity entity, ControllerData controllerData) : base(context, entity, controllerData)
|
||||
public Locomotion(ItemManager context, Entity entity, ControllerData controllerData) : base(context, entity, controllerData)
|
||||
{
|
||||
_velocityLimit = Entity.GetBehaviors<VelocityLimit>().FirstOrDefault();
|
||||
_thrust = Entity.GetBehavior<Thruster>();
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public class StationTowing : AgentTask
|
|||
[IgnoreMember] public override TaskType Type => TaskType.Tow;
|
||||
|
||||
[JsonProperty("station"), Key(4)]
|
||||
public Guid Station;
|
||||
public OrbitalEntity Station;
|
||||
|
||||
[JsonProperty("orbitParent"), Key(5)]
|
||||
public Guid OrbitParent;
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ public class VelocityMatch : AgentBehavior
|
|||
private Turning _turning;
|
||||
private const float TargetThreshold = .1f;
|
||||
|
||||
private GameContext _context;
|
||||
private ItemManager _context;
|
||||
|
||||
public VelocityMatch(GameContext context, Entity entity, ControllerData controllerData) : base(context, entity, controllerData)
|
||||
public VelocityMatch(ItemManager context, Entity entity, ControllerData controllerData) : base(context, entity, controllerData)
|
||||
{
|
||||
_context = context;
|
||||
_thrust = Entity.GetBehavior<Thruster>();
|
||||
|
|
|
|||
5
Assets/Scripts/ServerShared/Agents/WanderTask.cs
Normal file
5
Assets/Scripts/ServerShared/Agents/WanderTask.cs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
public class WanderTask : AgentTask
|
||||
{
|
||||
public override TaskType Type => TaskType.None;
|
||||
}
|
||||
3
Assets/Scripts/ServerShared/Agents/WanderTask.cs.meta
Normal file
3
Assets/Scripts/ServerShared/Agents/WanderTask.cs.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2320c5e3a86f42eeacb133b6529bfe89
|
||||
timeCreated: 1607467429
|
||||
|
|
@ -41,6 +41,11 @@ public interface IAlwaysUpdatedBehavior
|
|||
void AlwaysUpdate(float delta);
|
||||
}
|
||||
|
||||
public interface IOrderedBehavior
|
||||
{
|
||||
int Order { get; }
|
||||
}
|
||||
|
||||
public interface IPersistentBehavior//<T> where T : IBehavior
|
||||
{
|
||||
PersistentBehaviorData Store();
|
||||
|
|
@ -52,12 +57,12 @@ public interface IPopulationAssignment
|
|||
int AssignedPopulation { get; set; }
|
||||
}
|
||||
|
||||
public interface IController
|
||||
public interface IController<T> where T: AgentTask
|
||||
{
|
||||
bool Available { get; }
|
||||
TaskType TaskType { get; }
|
||||
//TaskType TaskType { get; }
|
||||
Zone Zone { get; }
|
||||
void AssignTask(Guid task);
|
||||
void AssignTask(T task);
|
||||
}
|
||||
|
||||
[MessagePackObject,
|
||||
|
|
@ -106,5 +111,5 @@ public abstract class BehaviorData
|
|||
[InspectableField, JsonProperty("group"), Key(0)]
|
||||
public int Group;
|
||||
|
||||
public abstract IBehavior CreateInstance(GameContext context, Entity entity, Gear item);
|
||||
public abstract IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item);
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ using System.Collections;
|
|||
using System.Collections.Generic;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using UniRx;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
using float2 = Unity.Mathematics.float2;
|
||||
|
|
@ -26,27 +27,28 @@ public abstract class ControllerData : BehaviorData
|
|||
public float TargetDistance = 10;
|
||||
}
|
||||
|
||||
public abstract class ControllerBase : IBehavior, IController, IInitializableBehavior
|
||||
public abstract class ControllerBase<T> : IBehavior, IController<T>, IInitializableBehavior where T : AgentTask
|
||||
{
|
||||
protected Guid HomeEntity => (_entity as Ship)?.HomeEntity ?? Guid.Empty;
|
||||
public bool Available => _spaceworthy && Task == Guid.Empty;
|
||||
public abstract TaskType TaskType { get; }
|
||||
public Zone Zone => _entity.Zone;
|
||||
protected Entity HomeEntity => (Entity as Ship)?.HomeEntity;
|
||||
public bool Available => _spaceworthy && Task == null;
|
||||
//public abstract TaskType TaskType { get; }
|
||||
public Zone Zone => Entity.Zone;
|
||||
public BehaviorData Data => _controllerData;
|
||||
|
||||
protected ItemManager ItemManager { get; }
|
||||
protected Entity Entity { get; }
|
||||
|
||||
protected Locomotion Locomotion;
|
||||
protected VelocityMatch VelocityMatch;
|
||||
protected Aim Aim;
|
||||
protected Func<float2> TargetPosition;
|
||||
protected Func<float2> TargetVelocity;
|
||||
protected bool MatchVelocity;
|
||||
protected List<ZoneDefinition> Path;
|
||||
protected Guid Task;
|
||||
// protected List<ZoneDefinition> Path;
|
||||
protected T Task;
|
||||
protected bool Moving;
|
||||
protected bool Waiting;
|
||||
|
||||
private GameContext _context;
|
||||
private Entity _entity;
|
||||
private ControllerData _controllerData;
|
||||
private MovementPhase _movementPhase;
|
||||
private Action _onFinishMoving;
|
||||
|
|
@ -54,33 +56,36 @@ public abstract class ControllerBase : IBehavior, IController, IInitializableBeh
|
|||
private float _waitTime;
|
||||
private Action _onFinishWaiting;
|
||||
|
||||
public ControllerBase(GameContext context, ControllerData data, Entity entity)
|
||||
public ControllerBase(ItemManager itemManager, ControllerData data, Entity entity)
|
||||
{
|
||||
_context = context;
|
||||
ItemManager = itemManager;
|
||||
Entity = entity;
|
||||
_controllerData = data;
|
||||
_entity = entity;
|
||||
entity.GearEvent.OnChanged += () =>
|
||||
{
|
||||
_spaceworthy = entity.GetBehavior<Thruster>() != null && entity.GetBehavior<Reactor>() != null;
|
||||
if(_spaceworthy)
|
||||
CreateBehaviors();
|
||||
};
|
||||
CheckSpaceworthiness();
|
||||
entity.EquippedItems.ObserveAdd().Subscribe(added => CheckSpaceworthiness());
|
||||
}
|
||||
|
||||
private void CheckSpaceworthiness()
|
||||
{
|
||||
_spaceworthy = Entity.GetBehavior<Thruster>() != null && Entity.GetBehavior<Reactor>() != null;
|
||||
if(_spaceworthy)
|
||||
CreateBehaviors();
|
||||
}
|
||||
|
||||
public void CreateBehaviors()
|
||||
{
|
||||
Locomotion = new Locomotion(_context, _entity, _controllerData);
|
||||
VelocityMatch = new VelocityMatch(_context, _entity, _controllerData);
|
||||
Aim = new Aim(_context, _entity, _controllerData);
|
||||
Locomotion = new Locomotion(ItemManager, Entity, _controllerData);
|
||||
VelocityMatch = new VelocityMatch(ItemManager, Entity, _controllerData);
|
||||
Aim = new Aim(ItemManager, Entity, _controllerData);
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
CreateBehaviors();
|
||||
_context.CorporationControllers[_entity.Corporation].Add(this);
|
||||
// _context.CorporationControllers[_entity.Corporation].Add(this);
|
||||
}
|
||||
|
||||
public void AssignTask(Guid task)
|
||||
public void AssignTask(T task)
|
||||
{
|
||||
Task = task;
|
||||
Moving = false;
|
||||
|
|
@ -91,7 +96,7 @@ public abstract class ControllerBase : IBehavior, IController, IInitializableBeh
|
|||
if (Available)
|
||||
{
|
||||
// No task is assigned and we're at home, do nothing!
|
||||
if (_entity.Parent == HomeEntity)
|
||||
if (Entity.Parent == HomeEntity)
|
||||
return false;
|
||||
|
||||
// No task is assigned, but we're not home, go home!
|
||||
|
|
@ -115,11 +120,11 @@ public abstract class ControllerBase : IBehavior, IController, IInitializableBeh
|
|||
|
||||
if (Moving)
|
||||
{
|
||||
if(_entity.Parent!=Guid.Empty)
|
||||
_entity.RemoveParent();
|
||||
if(Entity.Parent!=null)
|
||||
Entity.RemoveParent();
|
||||
|
||||
var targetPosition = TargetPosition();
|
||||
var distance = length(targetPosition - _entity.Position);
|
||||
var distance = length(targetPosition - Entity.Position);
|
||||
if (MatchVelocity)
|
||||
{
|
||||
var targetVelocity = TargetVelocity();
|
||||
|
|
@ -165,28 +170,24 @@ public abstract class ControllerBase : IBehavior, IController, IInitializableBeh
|
|||
|
||||
public void FinishTask()
|
||||
{
|
||||
if (Task == Guid.Empty)
|
||||
if (Task == null)
|
||||
return;
|
||||
|
||||
var task = _context.Cache.Get(Task);
|
||||
_context.Cache.Delete(task);
|
||||
_context.Cache.Get<Corporation>(_entity.Corporation).Tasks.Remove(task.ID);
|
||||
Task = Guid.Empty;
|
||||
Task = null;
|
||||
}
|
||||
|
||||
public void GoHome(Action onFinish = null)
|
||||
{
|
||||
var homeEntity = _context.Cache.Get<Entity>(HomeEntity);
|
||||
if (Zone == homeEntity.Zone) MoveTo(homeEntity, true, () =>
|
||||
MoveTo(HomeEntity, true, () =>
|
||||
{
|
||||
_entity.SetParent(homeEntity);
|
||||
Entity.SetParent(HomeEntity);
|
||||
onFinish?.Invoke();
|
||||
});
|
||||
else MoveTo(homeEntity.Zone.Data.ID, () => MoveTo(homeEntity, true, () =>
|
||||
{
|
||||
_entity.SetParent(homeEntity);
|
||||
onFinish?.Invoke();
|
||||
}));
|
||||
// else MoveTo(homeEntity.Zone.Data.ID, () => MoveTo(homeEntity, true, () =>
|
||||
// {
|
||||
// _entity.SetParent(homeEntity);
|
||||
// onFinish?.Invoke();
|
||||
// }));
|
||||
}
|
||||
|
||||
public void Wait(float time, Action onFinish = null)
|
||||
|
|
@ -226,25 +227,25 @@ public abstract class ControllerBase : IBehavior, IController, IInitializableBeh
|
|||
_onFinishMoving = onFinish;
|
||||
}
|
||||
|
||||
public void MoveTo(Guid zone, Action onFinish = null)
|
||||
{
|
||||
var path = _context.FindPath(_context.GalaxyZones[Zone.Data.ID], _context.GalaxyZones[zone]);
|
||||
|
||||
void OnNextZone()
|
||||
{
|
||||
path.RemoveAt(0);
|
||||
if (path.Count > 0)
|
||||
{
|
||||
MoveTo(Zone.WormholePosition(Path[0]), false, OnNextZone);
|
||||
}
|
||||
else
|
||||
{
|
||||
onFinish?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
OnNextZone();
|
||||
}
|
||||
// public void MoveTo(Guid zone, Action onFinish = null)
|
||||
// {
|
||||
// var path = _context.FindPath(_context.GalaxyZones[Zone.Data.ID], _context.GalaxyZones[zone]);
|
||||
//
|
||||
// void OnNextZone()
|
||||
// {
|
||||
// path.RemoveAt(0);
|
||||
// if (path.Count > 0)
|
||||
// {
|
||||
// MoveTo(Zone.WormholePosition(Path[0]), false, OnNextZone);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// onFinish?.Invoke();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// OnNextZone();
|
||||
// }
|
||||
}
|
||||
|
||||
public enum MovementPhase
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ public class CooldownData : BehaviorData
|
|||
[InspectableField, JsonProperty("cooldown"), Key(1), RuntimeInspectable]
|
||||
public PerformanceStat Cooldown = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Cooldown(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -18,16 +18,15 @@ public class CooldownData : BehaviorData
|
|||
public class Cooldown : IBehavior, IAlwaysUpdatedBehavior
|
||||
{
|
||||
private CooldownData _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
private float _cooldown; // Normalized
|
||||
|
||||
public Cooldown(GameContext context, CooldownData data, Entity entity, Gear item)
|
||||
public Cooldown(ItemManager context, CooldownData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
|
|
@ -49,6 +48,6 @@ public class Cooldown : IBehavior, IAlwaysUpdatedBehavior
|
|||
|
||||
public void AlwaysUpdate(float delta)
|
||||
{
|
||||
_cooldown -= delta / Context.Evaluate(_data.Cooldown, Item, Entity);
|
||||
_cooldown -= delta / Context.Evaluate(_data.Cooldown, Item.EquippableItem, Entity);
|
||||
}
|
||||
}
|
||||
|
|
@ -12,23 +12,24 @@ public class EnergyDrawData : BehaviorData
|
|||
[InspectableField, JsonProperty("perSecond"), Key(2)]
|
||||
public bool PerSecond;
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new EnergyDraw(context, this, entity, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class EnergyDraw : IBehavior
|
||||
public class EnergyDraw : IBehavior, IOrderedBehavior
|
||||
{
|
||||
private EnergyDrawData _data;
|
||||
|
||||
public int Order => -100;
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public EnergyDraw(GameContext context, EnergyDrawData data, Entity entity, Gear item)
|
||||
public EnergyDraw(ItemManager context, EnergyDrawData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
|
|
@ -38,7 +39,7 @@ public class EnergyDraw : IBehavior
|
|||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
Entity.Energy -= Context.Evaluate(_data.Draw, Item, Entity) * (_data.PerSecond ? delta : 1);
|
||||
Entity.Energy -= Context.Evaluate(_data.Draw, Item.EquippableItem, Entity) * (_data.PerSecond ? delta : 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -22,13 +22,13 @@ public class FactoryData : BehaviorData
|
|||
[InspectableDatabaseLink(typeof(PersonalityAttribute)), JsonProperty("productionProfile"), Key(4)]
|
||||
public Dictionary<Guid, float> ProductionProfile = new Dictionary<Guid, float>();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Factory(context, this, entity, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Factory : IBehavior, IPersistentBehavior, IPopulationAssignment
|
||||
public class Factory : IBehavior//, IPersistentBehavior, IPopulationAssignment
|
||||
{
|
||||
public float ProductionQuality;
|
||||
public double RetoolingTime;
|
||||
|
|
@ -38,8 +38,8 @@ public class Factory : IBehavior, IPersistentBehavior, IPopulationAssignment
|
|||
public int AssignedPopulation { get; set; }
|
||||
|
||||
public Entity Entity { get; }
|
||||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
public EquippedItem Item { get; }
|
||||
public ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
|
|
@ -56,11 +56,10 @@ public class Factory : IBehavior, IPersistentBehavior, IPopulationAssignment
|
|||
Active = false;
|
||||
if(value != Guid.Empty)
|
||||
{
|
||||
ItemName = Context.Cache.Get<ItemData>(Context.Cache.Get<BlueprintData>(value).Item).Name;
|
||||
ItemName = Context.ItemData.Get<ItemData>(Context.ItemData.Get<BlueprintData>(value).Item).Name;
|
||||
RetoolingTime = ToolingTime;
|
||||
_retooling = true;
|
||||
}
|
||||
Item.Change();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -71,102 +70,207 @@ public class Factory : IBehavior, IPersistentBehavior, IPopulationAssignment
|
|||
private bool _retooling = false;
|
||||
private float _currentProductionQuality;
|
||||
|
||||
public Factory(GameContext context, FactoryData data, Entity entity, Gear item)
|
||||
public Factory(ItemManager context, FactoryData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
Context = context;
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
ToolingTime = Context.Evaluate(_data.ToolingTime, Item, Entity);
|
||||
var blueprint = Context.Cache.Get<BlueprintData>(_blueprint);
|
||||
if (blueprint == null)
|
||||
return false;
|
||||
|
||||
if (ItemUnderConstruction != Guid.Empty)
|
||||
{
|
||||
Entity.IncompleteCargo[ItemUnderConstruction] =
|
||||
Entity.IncompleteCargo[ItemUnderConstruction] - delta * (AssignedPopulation + _data.AutomationPoints) /
|
||||
pow(lerp(blueprint.QualityFloor, 1, saturate(_currentProductionQuality)),
|
||||
blueprint.ProductionExponent);
|
||||
|
||||
if(Entity.IncompleteCargo[ItemUnderConstruction] < 0)
|
||||
{
|
||||
var item = Context.Cache.Get<ItemInstance>(ItemUnderConstruction);
|
||||
if (item is SimpleCommodity simpleCommodity)
|
||||
Entity.AddCargo(simpleCommodity);
|
||||
else if (item is CraftedItemInstance craftedItemInstance)
|
||||
Entity.AddCargo(craftedItemInstance);
|
||||
Entity.IncompleteCargo.Remove(ItemUnderConstruction);
|
||||
ItemUnderConstruction = Guid.Empty;
|
||||
foreach (var attribute in _data.ProductionProfile)
|
||||
Entity.Personality[attribute.Key] = lerp(Entity.Personality[attribute.Key], attribute.Value,
|
||||
Context.GlobalData.ProductionPersonalityLerp * ((float) AssignedPopulation / Entity.Population));
|
||||
Item.Change();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (RetoolingTime > 0)
|
||||
{
|
||||
RetoolingTime -= delta;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_retooling)
|
||||
{
|
||||
_retooling = false;
|
||||
Item.Change();
|
||||
}
|
||||
|
||||
if (Active)
|
||||
{
|
||||
var profileDistance = 0f;
|
||||
if (_data.ProductionProfile.Any())
|
||||
profileDistance = _data.ProductionProfile.Sum(x => abs(x.Value - Entity.Personality[x.Key])) /
|
||||
_data.ProductionProfile.Count;
|
||||
var personalityQuality =
|
||||
(_data.AutomationPoints * _data.AutomationQuality + AssignedPopulation * (1 - profileDistance)) /
|
||||
(_data.AutomationPoints + AssignedPopulation);
|
||||
ItemUnderConstruction = Entity.Build(blueprint,
|
||||
blueprint.Quality *
|
||||
pow(personalityQuality, blueprint.PersonalityExponent) *
|
||||
pow(ProductionQuality, blueprint.QualityExponent) *
|
||||
// Applying exponents to two random numbers and averaging them produces a range of interesting probability distributions for quality
|
||||
(pow(Context.Random.NextFloat(), blueprint.RandomQualityExponent) +
|
||||
pow(Context.Random.NextFloat(), blueprint.RandomQualityExponent)) / 2, ItemName);
|
||||
|
||||
if(ItemUnderConstruction!=Guid.Empty)
|
||||
Item.Change();
|
||||
}
|
||||
|
||||
// ToolingTime = Context.Evaluate(_data.ToolingTime, Item, Entity);
|
||||
// var blueprint = Context.ItemData.Get<BlueprintData>(_blueprint);
|
||||
// if (blueprint == null)
|
||||
// return false;
|
||||
//
|
||||
// if (ItemUnderConstruction != Guid.Empty)
|
||||
// {
|
||||
// Entity.IncompleteCargo[ItemUnderConstruction] =
|
||||
// Entity.IncompleteCargo[ItemUnderConstruction] - delta * (AssignedPopulation + _data.AutomationPoints) /
|
||||
// pow(lerp(blueprint.QualityFloor, 1, saturate(_currentProductionQuality)),
|
||||
// blueprint.ProductionExponent);
|
||||
//
|
||||
// if(Entity.IncompleteCargo[ItemUnderConstruction] < 0)
|
||||
// {
|
||||
// var item = Context.ItemData.Get<ItemInstance>(ItemUnderConstruction);
|
||||
// if (item is SimpleCommodity simpleCommodity)
|
||||
// Entity.AddCargo(simpleCommodity);
|
||||
// else if (item is CraftedItemInstance craftedItemInstance)
|
||||
// Entity.AddCargo(craftedItemInstance);
|
||||
// Entity.IncompleteCargo.Remove(ItemUnderConstruction);
|
||||
// ItemUnderConstruction = Guid.Empty;
|
||||
// foreach (var attribute in _data.ProductionProfile)
|
||||
// Entity.Personality[attribute.Key] = lerp(Entity.Personality[attribute.Key], attribute.Value,
|
||||
// Context.GameplaySettings.ProductionPersonalityLerp * ((float) AssignedPopulation / Entity.Population));
|
||||
// }
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// if (RetoolingTime > 0)
|
||||
// {
|
||||
// RetoolingTime -= delta;
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (_retooling)
|
||||
// {
|
||||
// _retooling = false;
|
||||
// }
|
||||
//
|
||||
// if (Active)
|
||||
// {
|
||||
// var profileDistance = 0f;
|
||||
// if (_data.ProductionProfile.Any())
|
||||
// profileDistance = _data.ProductionProfile.Sum(x => abs(x.Value - Entity.Personality[x.Key])) /
|
||||
// _data.ProductionProfile.Count;
|
||||
// var personalityQuality =
|
||||
// (_data.AutomationPoints * _data.AutomationQuality + AssignedPopulation * (1 - profileDistance)) /
|
||||
// (_data.AutomationPoints + AssignedPopulation);
|
||||
// ItemUnderConstruction = Entity.Build(blueprint,
|
||||
// blueprint.Quality *
|
||||
// pow(personalityQuality, blueprint.PersonalityExponent) *
|
||||
// pow(ProductionQuality, blueprint.QualityExponent) *
|
||||
// // Applying exponents to two random numbers and averaging them produces a range of interesting probability distributions for quality
|
||||
// (pow(Context.Random.NextFloat(), blueprint.RandomQualityExponent) +
|
||||
// pow(Context.Random.NextFloat(), blueprint.RandomQualityExponent)) / 2, ItemName);
|
||||
// }
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO Update Factory Persistence
|
||||
public PersistentBehaviorData Store()
|
||||
{
|
||||
return new FactoryPersistence
|
||||
{
|
||||
Blueprint = _blueprint,
|
||||
RetoolingTime = RetoolingTime,
|
||||
AssignedPopulation = AssignedPopulation,
|
||||
ProductionQuality = ProductionQuality
|
||||
};
|
||||
}
|
||||
|
||||
public void Restore(PersistentBehaviorData data)
|
||||
{
|
||||
var factoryPersistence = data as FactoryPersistence;
|
||||
_blueprint = factoryPersistence.Blueprint;
|
||||
RetoolingTime = factoryPersistence.RetoolingTime;
|
||||
AssignedPopulation = factoryPersistence.AssignedPopulation;
|
||||
ProductionQuality = factoryPersistence.ProductionQuality;
|
||||
}
|
||||
//
|
||||
// // TODO Update Factory Persistence
|
||||
// public PersistentBehaviorData Store()
|
||||
// {
|
||||
// return new FactoryPersistence
|
||||
// {
|
||||
// Blueprint = _blueprint,
|
||||
// RetoolingTime = RetoolingTime,
|
||||
// AssignedPopulation = AssignedPopulation,
|
||||
// ProductionQuality = ProductionQuality
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// public void Restore(PersistentBehaviorData data)
|
||||
// {
|
||||
// var factoryPersistence = data as FactoryPersistence;
|
||||
// _blueprint = factoryPersistence.Blueprint;
|
||||
// RetoolingTime = factoryPersistence.RetoolingTime;
|
||||
// AssignedPopulation = factoryPersistence.AssignedPopulation;
|
||||
// ProductionQuality = factoryPersistence.ProductionQuality;
|
||||
// }
|
||||
//
|
||||
// public Guid Build(BlueprintData blueprint, float quality, string name, bool direct = false)
|
||||
// {
|
||||
// if (direct)
|
||||
// {
|
||||
// if(blueprint.FactoryItem!=Guid.Empty)
|
||||
// throw new ArgumentException("Attempted to directly build a blueprint which requires a factory!");
|
||||
// var blueprintItem = Context.Cache.Get<GearData>(blueprint.Item);
|
||||
// if(blueprintItem == null)
|
||||
// throw new ArgumentException("Attempted to directly build a blueprint for a missing or incompatible item!");
|
||||
// }
|
||||
//
|
||||
// //var newItemID = Guid.Empty;
|
||||
//
|
||||
// // GetBlueprintIngredients will assign the output lists with the items matching the blueprint, and return false if they are not found
|
||||
// if (!GetBlueprintIngredients(blueprint, out var simpleIngredients, out var compoundIngredients))
|
||||
// return Guid.Empty;
|
||||
//
|
||||
// // These will be bundled with the data for the compound commodity instance
|
||||
// var ingredients = new List<ItemInstance>();
|
||||
// ingredients.AddRange(compoundIngredients.Select(RemoveCargo));
|
||||
// ingredients.AddRange(simpleIngredients.Select(sc => RemoveCargo(sc, blueprint.Ingredients[sc.Data])));
|
||||
//
|
||||
// var blueprintItemData = Context.Cache.Get(blueprint.Item);
|
||||
//
|
||||
// // Creating new crafted item instances is a bit more complicated
|
||||
// if (blueprintItemData is CraftedItemData)
|
||||
// {
|
||||
// CraftedItemInstance newItem;
|
||||
//
|
||||
// if (blueprintItemData is EquippableItemData equippableItemData)
|
||||
// {
|
||||
// var newGear = new EquippableItem
|
||||
// {
|
||||
// Context = Context,
|
||||
// Data = blueprintItemData.ID,
|
||||
// Ingredients = ingredients.Select(ii=>ii.ID).ToList(),
|
||||
// Quality = quality,
|
||||
// Blueprint = blueprint.ID,
|
||||
// Name = name,
|
||||
// SourceEntity = ID
|
||||
// };
|
||||
// newGear.Durability = Context.Evaluate(equippableItemData.Durability, newGear);
|
||||
// newItem = newGear;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// newItem = new CompoundCommodity
|
||||
// {
|
||||
// Context = Context,
|
||||
// Data = blueprintItemData.ID,
|
||||
// Ingredients = ingredients.Select(ii=>ii.ID).ToList(),
|
||||
// Quality = quality,
|
||||
// Blueprint = blueprint.ID,
|
||||
// Name = name,
|
||||
// SourceEntity = ID
|
||||
// };
|
||||
// }
|
||||
// Context.Cache.Add(newItem);
|
||||
// if (direct)
|
||||
// IncompleteGear[newItem.ID] = blueprint.ProductionTime;
|
||||
// else
|
||||
// IncompleteCargo[newItem.ID] = blueprint.ProductionTime;
|
||||
// return newItem.ID;
|
||||
// }
|
||||
//
|
||||
// var newSimpleCommodity = new SimpleCommodity
|
||||
// {
|
||||
// Context = Context,
|
||||
// Data = blueprintItemData.ID,
|
||||
// Quantity = 1
|
||||
// };
|
||||
// Context.Cache.Add(newSimpleCommodity);
|
||||
// IncompleteCargo[newSimpleCommodity.ID] = blueprint.ProductionTime;
|
||||
// return newSimpleCommodity.ID;
|
||||
// }
|
||||
//
|
||||
// public bool GetBlueprintIngredients(BlueprintData blueprint, out List<SimpleCommodity> simpleIngredients,
|
||||
// out List<CompoundCommodity> compoundIngredients)
|
||||
// {
|
||||
// simpleIngredients = new List<SimpleCommodity>();
|
||||
// compoundIngredients = new List<CompoundCommodity>();
|
||||
// var hasAllIngredients = true;
|
||||
// var cargoInstances = Cargo.Select(c => Context.Cache.Get<ItemInstance>(c));
|
||||
// foreach (var kvp in blueprint.Ingredients)
|
||||
// {
|
||||
// var itemData = Context.Cache.Get(kvp.Key);
|
||||
// if (itemData is SimpleCommodityData)
|
||||
// {
|
||||
// var matchingItem = cargoInstances.FirstOrDefault(ii =>
|
||||
// {
|
||||
// if (!(ii is SimpleCommodity simpleCommodity)) return false;
|
||||
// return simpleCommodity.Data == itemData.ID && simpleCommodity.Quantity >= kvp.Value;
|
||||
// }) as SimpleCommodity;
|
||||
// hasAllIngredients = hasAllIngredients && matchingItem != null;
|
||||
// if(matchingItem != null)
|
||||
// simpleIngredients.Add(matchingItem);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var matchingItems =
|
||||
// cargoInstances.Where(ii => (ii as CompoundCommodity)?.Data == itemData.ID).Cast<CompoundCommodity>().ToArray();
|
||||
// hasAllIngredients = hasAllIngredients && matchingItems.Length >= kvp.Value;
|
||||
// if(matchingItems.Length >= kvp.Value)
|
||||
// compoundIngredients.AddRange(matchingItems.Take(kvp.Value));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return hasAllIngredients;
|
||||
// }
|
||||
}
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
|
|
|
|||
|
|
@ -12,136 +12,121 @@ public class HaulingControllerData : ControllerData
|
|||
{
|
||||
[InspectableField, JsonProperty("targetDistance"), Key(6)]
|
||||
public float DockTime = 2;
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new HaulingController(context, this, entity, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class HaulingController : ControllerBase, IBehavior, IPersistentBehavior
|
||||
public class HaulingController : ControllerBase<HaulingTask>, IBehavior, IPersistentBehavior
|
||||
{
|
||||
public override TaskType TaskType => TaskType.Haul;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private HaulingControllerData _data;
|
||||
private GameContext _context;
|
||||
private Entity _entity;
|
||||
private Gear _item;
|
||||
|
||||
private ItemManager ItemManager { get; }
|
||||
private Entity Entity { get; }
|
||||
private EquippedItem Item { get; }
|
||||
|
||||
private bool _taskStarted;
|
||||
private int _itemsDelivered;
|
||||
private int _itemsCarried;
|
||||
private SimpleCommodity _simpleCommodityDelivery;
|
||||
private List<CraftedItemInstance> _craftedItemDelivery = new List<CraftedItemInstance>();
|
||||
|
||||
public HaulingController(GameContext context, HaulingControllerData data, Entity entity, Gear item) : base(context, data, entity)
|
||||
public HaulingController(ItemManager itemManager, HaulingControllerData data, Entity entity, EquippedItem item) : base(itemManager, data, entity)
|
||||
{
|
||||
_context = context;
|
||||
ItemManager = itemManager;
|
||||
_data = data;
|
||||
_entity = entity;
|
||||
_item = item;
|
||||
Entity = entity;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public new bool Update(float delta)
|
||||
{
|
||||
var haulingTask = _context.Cache.Get<HaulingTask>(Task);
|
||||
if (haulingTask != null)
|
||||
if (Task != null)
|
||||
{
|
||||
if (!_taskStarted)
|
||||
{
|
||||
MoveTo(haulingTask.Zone, OnOriginZoneArrival);
|
||||
MoveTo(Task.Origin, true, OnPickup);
|
||||
//MoveTo(haulingTask.Zone, OnOriginZoneArrival);
|
||||
_taskStarted = true;
|
||||
}
|
||||
}
|
||||
return base.Update(delta);
|
||||
}
|
||||
|
||||
void OnOriginZoneArrival()
|
||||
{
|
||||
var haulingTask = _context.Cache.Get<HaulingTask>(Task);
|
||||
|
||||
_entity.SetMessage("Entering pickup phase.");
|
||||
|
||||
MoveTo(_context.Cache.Get<Entity>(haulingTask.Origin), true, OnPickup);
|
||||
}
|
||||
// void OnOriginZoneArrival()
|
||||
// {
|
||||
// var haulingTask = _context.ItemData.Get<HaulingTask>(Task);
|
||||
//
|
||||
// _entity.SetMessage("Entering pickup phase.");
|
||||
//
|
||||
// MoveTo(_context.ItemData.Get<Entity>(haulingTask.Origin), true, OnPickup);
|
||||
// }
|
||||
|
||||
void OnPickup()
|
||||
{
|
||||
var haulingTask = _context.Cache.Get<HaulingTask>(Task);
|
||||
var target = Zone.Entities[haulingTask.Origin] as OrbitalEntity;
|
||||
Entity.SetParent(Task.Origin);
|
||||
|
||||
_itemsCarried = Task.Origin.TryTransferItems(Entity, Task.ItemType, Task.Quantity - _itemsDelivered);
|
||||
|
||||
if (_itemsCarried == 0)
|
||||
{
|
||||
FinishTask();
|
||||
return;
|
||||
}
|
||||
|
||||
_entity.SetParent(target);
|
||||
var itemData = _context.Cache.Get<ItemData>(haulingTask.ItemType);
|
||||
int quantity = min((int) ((_entity.Capacity - _entity.OccupiedCapacity) / itemData.Size), haulingTask.Quantity - _itemsDelivered);
|
||||
if (itemData is SimpleCommodityData)
|
||||
{
|
||||
var itemMatch = target.Cargo
|
||||
.Select(id => _context.Cache.Get<SimpleCommodity>(id))
|
||||
.FirstOrDefault(ii => ii != null && ii.Data == haulingTask.ItemType);
|
||||
if(itemMatch==null)
|
||||
FinishTask();
|
||||
_simpleCommodityDelivery = _entity.AddCargo(target.RemoveCargo(itemMatch, quantity));
|
||||
}
|
||||
else if (itemData is CraftedItemData)
|
||||
{
|
||||
var itemMatches = target.Cargo
|
||||
.Select(id => _context.Cache.Get<CraftedItemInstance>(id))
|
||||
.Where(ii => ii != null && ii.Data == haulingTask.ItemType)
|
||||
.ToArray();
|
||||
if(!itemMatches.Any())
|
||||
FinishTask();
|
||||
foreach (var match in itemMatches)
|
||||
_craftedItemDelivery.Add(_entity.AddCargo(target.RemoveCargo(match)));
|
||||
}
|
||||
Wait(_data.DockTime, OnItemObtained);
|
||||
}
|
||||
|
||||
void OnItemObtained()
|
||||
{
|
||||
var haulingTask = _context.Cache.Get<HaulingTask>(Task);
|
||||
_entity.SetMessage("Entering delivery phase.");
|
||||
Entity.SetMessage("Entering delivery phase.");
|
||||
|
||||
var target = _context.Cache.Get<Entity>(haulingTask.Target);
|
||||
|
||||
MoveTo(target.Zone.Data.ID, OnTargetZoneArrival);
|
||||
MoveTo(Task.Target, true, OnDelivery);
|
||||
//MoveTo(target.Zone.Data.ID, OnTargetZoneArrival);
|
||||
}
|
||||
|
||||
void OnTargetZoneArrival()
|
||||
{
|
||||
var haulingTask = _context.Cache.Get<HaulingTask>(Task);
|
||||
|
||||
MoveTo(_context.Cache.Get<Entity>(haulingTask.Target), true, OnDelivery);
|
||||
}
|
||||
// void OnTargetZoneArrival()
|
||||
// {
|
||||
// var haulingTask = _context.ItemData.Get<HaulingTask>(Task);
|
||||
//
|
||||
// MoveTo(_context.ItemData.Get<Entity>(haulingTask.Target), true, OnDelivery);
|
||||
// }
|
||||
|
||||
void OnDelivery()
|
||||
{
|
||||
var haulingTask = _context.Cache.Get<HaulingTask>(Task);
|
||||
var target = Zone.Entities[haulingTask.Target] as OrbitalEntity;
|
||||
|
||||
_entity.SetParent(target);
|
||||
|
||||
var itemData = _context.Cache.Get<ItemData>(haulingTask.ItemType);
|
||||
if (itemData is SimpleCommodityData)
|
||||
{
|
||||
target.AddCargo(_entity.RemoveCargo(_simpleCommodityDelivery, _simpleCommodityDelivery.Quantity));
|
||||
_itemsDelivered += _simpleCommodityDelivery.Quantity;
|
||||
_simpleCommodityDelivery = null;
|
||||
}
|
||||
else if (itemData is CraftedItemData)
|
||||
{
|
||||
foreach (var item in _craftedItemDelivery)
|
||||
target.AddCargo(_entity.RemoveCargo(item));
|
||||
_itemsDelivered += _craftedItemDelivery.Count;
|
||||
_craftedItemDelivery.Clear();
|
||||
}
|
||||
|
||||
Entity.SetParent(Task.Target);
|
||||
|
||||
var itemsDelivered = Entity.TryTransferItems(Task.Target, Task.ItemType, _itemsCarried);
|
||||
_itemsCarried -= itemsDelivered;
|
||||
_itemsDelivered += itemsDelivered;
|
||||
|
||||
Wait(_data.DockTime, () =>
|
||||
{
|
||||
if(_itemsDelivered == haulingTask.Quantity)
|
||||
// We were unable to transfer all onboard items to target entity, cargo is probably full. Bring back the surplus and end the mission
|
||||
if(_itemsCarried > 0)
|
||||
MoveTo(Task.Origin, true, ReturnSurplusToOrigin);
|
||||
// We have delivered the target quantity of items, end the mission
|
||||
else if(_itemsDelivered >= Task.Quantity)
|
||||
FinishTask();
|
||||
// We aren't done yet. Resetting the task will make us go for another delivery run
|
||||
else
|
||||
_taskStarted = false;
|
||||
});
|
||||
}
|
||||
|
||||
void ReturnSurplusToOrigin()
|
||||
{
|
||||
Entity.SetParent(Task.Origin);
|
||||
|
||||
Entity.TryTransferItems(Task.Origin, Task.ItemType, _itemsCarried);
|
||||
|
||||
Wait(_data.DockTime, OnItemObtained);
|
||||
|
||||
FinishTask();
|
||||
}
|
||||
|
||||
public PersistentBehaviorData Store()
|
||||
{
|
||||
return new HaulingControllerPersistence
|
||||
|
|
@ -160,5 +145,5 @@ public class HaulingController : ControllerBase, IBehavior, IPersistentBehavior
|
|||
public class HaulingControllerPersistence : PersistentBehaviorData
|
||||
{
|
||||
[JsonProperty("task"), Key(0)]
|
||||
public Guid Task;
|
||||
public HaulingTask Task;
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ public class HeatData : BehaviorData
|
|||
[InspectableField, JsonProperty("perSecond"), Key(2)]
|
||||
public bool PerSecond;
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Heat(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -23,12 +23,12 @@ public class Heat : IBehavior
|
|||
private HeatData _data;
|
||||
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public Heat(GameContext context, HeatData data, Entity entity, Gear item)
|
||||
public Heat(ItemManager context, HeatData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
|
|
@ -38,7 +38,7 @@ public class Heat : IBehavior
|
|||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
Entity.AddHeat(Context.Evaluate(_data.Heat, Item, Entity) * (_data.PerSecond ? delta : 1));
|
||||
Item.Temperature += Context.Evaluate(_data.Heat, Item.EquippableItem, Entity) * (_data.PerSecond ? delta : 1) / Context.GetThermalMass(Item.EquippableItem);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ public class HitscanData : WeaponData
|
|||
[InspectableField, JsonProperty("perSecond"), Key(6)]
|
||||
public bool PerSecond;
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Hitscan(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -19,14 +19,14 @@ public class Hitscan : IBehavior
|
|||
private float _cooldown; // normalized
|
||||
private HitscanData _data;
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
private float _firingVisibility;
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
public float Range { get; private set; }
|
||||
|
||||
public Hitscan(GameContext context, HitscanData c, Entity entity, Gear item)
|
||||
public Hitscan(ItemManager context, HitscanData c, Entity entity, EquippedItem item)
|
||||
{
|
||||
Context = context;
|
||||
_data = c;
|
||||
|
|
@ -37,7 +37,7 @@ public class Hitscan : IBehavior
|
|||
public bool Update(float delta)
|
||||
{
|
||||
// TODO: Implement hitscan weapons!
|
||||
Range = Context.Evaluate(_data.Range, Item, Entity);
|
||||
Range = Context.Evaluate(_data.Range, Item.EquippableItem, Entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ public class ItemUsageData : BehaviorData
|
|||
[InspectableDatabaseLink(typeof(SimpleCommodityData)), JsonProperty("item"), Key(1), RuntimeInspectable]
|
||||
public Guid Item;
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new ItemUsage(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -21,12 +21,12 @@ public class ItemUsage : IBehavior
|
|||
private ItemUsageData _data;
|
||||
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public ItemUsage(GameContext context, ItemUsageData data, Entity entity, Gear item)
|
||||
public ItemUsage(ItemManager context, ItemUsageData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
|
|
@ -36,19 +36,15 @@ public class ItemUsage : IBehavior
|
|||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
var cargoInstances = Entity.Cargo.Select(c => Context.Cache.Get<ItemInstance>(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);
|
||||
}
|
||||
var cargo = Entity.FindItemInCargo(_data.Item);
|
||||
if (cargo == null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
var item = cargo.ItemsOfType[_data.Item][0];
|
||||
if (item is SimpleCommodity simpleCommodity)
|
||||
cargo.Remove(simpleCommodity, 1);
|
||||
if (item is CraftedItemInstance craftedItemInstance)
|
||||
cargo.Remove(craftedItemInstance);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ public class LauncherData : WeaponData
|
|||
[InspectableField, JsonProperty("lockOnTime"), Key(15)]
|
||||
public PerformanceStat LockOnTime = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Launcher(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -52,13 +52,13 @@ public class Launcher : IBehavior, IAlwaysUpdatedBehavior
|
|||
|
||||
private LauncherData _data;
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
private float _firingVisibility;
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public Launcher(GameContext context, LauncherData m, Entity entity, Gear item)
|
||||
public Launcher(ItemManager context, LauncherData m, Entity entity, EquippedItem item)
|
||||
{
|
||||
Context = context;
|
||||
_data = m;
|
||||
|
|
|
|||
|
|
@ -10,117 +10,110 @@ using static Unity.Mathematics.math;
|
|||
[MessagePackObject, JsonObject(MemberSerialization.OptIn), EntityTypeRestriction(HullType.Ship), Order(-100)]
|
||||
public class MiningControllerData : ControllerData
|
||||
{
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new MiningController(context, this, entity, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class MiningController : ControllerBase, IBehavior, IPersistentBehavior, IInitializableBehavior
|
||||
public class MiningController : ControllerBase<Mining>, IBehavior, IPersistentBehavior, IInitializableBehavior
|
||||
{
|
||||
public override TaskType TaskType => TaskType.Mine;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private MiningControllerData _data;
|
||||
private GameContext _context;
|
||||
private Entity _entity;
|
||||
private Gear _item;
|
||||
private EquippedItem Item { get; }
|
||||
private bool _taskStarted;
|
||||
private int _asteroid = -1;
|
||||
private MiningTool _miningTool;
|
||||
private Switch _toolSwitch;
|
||||
|
||||
public MiningController(GameContext context, MiningControllerData data, Entity entity, Gear item) : base(context, data, entity)
|
||||
public MiningController(ItemManager itemManager, MiningControllerData data, Entity entity, EquippedItem item) : base(itemManager, data, entity)
|
||||
{
|
||||
_context = context;
|
||||
_data = data;
|
||||
_entity = entity;
|
||||
_item = item;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public new void Initialize()
|
||||
{
|
||||
_miningTool = _entity.GetBehavior<MiningTool>();
|
||||
_toolSwitch = _entity.GetSwitch<MiningTool>();
|
||||
_miningTool = Entity.GetBehavior<MiningTool>();
|
||||
_toolSwitch = Entity.GetSwitch<MiningTool>();
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
public new bool Update(float delta)
|
||||
{
|
||||
var miningTask = _context.Cache.Get<Mining>(Task);
|
||||
if (miningTask != null)
|
||||
{
|
||||
if (!_taskStarted)
|
||||
{
|
||||
NextAsteroid();
|
||||
_taskStarted = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Moving)
|
||||
{
|
||||
if (_entity.OccupiedCapacity < _entity.Capacity - 1)
|
||||
{
|
||||
var asteroidTransform = Zone.GetAsteroidTransform(miningTask.Asteroids, _asteroid);
|
||||
if (length(_entity.Position - asteroidTransform.xy) - asteroidTransform.w > _miningTool.Range)
|
||||
{
|
||||
_entity.SetMessage("Moving to target asteroid.");
|
||||
MoveTo(() => Zone.GetAsteroidTransform(miningTask.Asteroids, _asteroid).xy,
|
||||
() => Zone.GetAsteroidVelocity(miningTask.Asteroids, _asteroid));
|
||||
_toolSwitch.Activated = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Zone.AsteroidExists(miningTask.Asteroids, _asteroid))
|
||||
{
|
||||
_miningTool.AsteroidBelt = miningTask.Asteroids;
|
||||
_miningTool.Asteroid = _asteroid;
|
||||
_toolSwitch.Activated = true;
|
||||
Aim.Objective = Zone.GetAsteroidTransform(miningTask.Asteroids, _asteroid).xy;
|
||||
Aim.Update(delta);
|
||||
}
|
||||
else NextAsteroid();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_entity.SetMessage("Out of cargo space. Returning home to offload cargo.");
|
||||
GoHome(OnArriveHome);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (Task != null)
|
||||
// {
|
||||
// if (!_taskStarted)
|
||||
// {
|
||||
// NextAsteroid();
|
||||
// _taskStarted = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (!Moving)
|
||||
// {
|
||||
// if (_entity.OccupiedCapacity < _entity.Capacity - 1)
|
||||
// {
|
||||
// var asteroidTransform = Zone.GetAsteroidTransform(Task.Asteroids, _asteroid);
|
||||
// if (length(_entity.Position - asteroidTransform.xy) - asteroidTransform.w > _miningTool.Range)
|
||||
// {
|
||||
// _entity.SetMessage("Moving to target asteroid.");
|
||||
// MoveTo(() => Zone.GetAsteroidTransform(Task.Asteroids, _asteroid).xy,
|
||||
// () => Zone.GetAsteroidVelocity(Task.Asteroids, _asteroid));
|
||||
// _toolSwitch.Activated = false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (Zone.AsteroidExists(Task.Asteroids, _asteroid))
|
||||
// {
|
||||
// _miningTool.AsteroidBelt = Task.Asteroids;
|
||||
// _miningTool.Asteroid = _asteroid;
|
||||
// _toolSwitch.Activated = true;
|
||||
// Aim.Objective = Zone.GetAsteroidTransform(Task.Asteroids, _asteroid).xy;
|
||||
// Aim.Update(delta);
|
||||
// }
|
||||
// else NextAsteroid();
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// _entity.SetMessage("Out of cargo space. Returning home to offload cargo.");
|
||||
// GoHome(OnArriveHome);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return base.Update(delta);
|
||||
}
|
||||
|
||||
private void OnArriveHome()
|
||||
{
|
||||
var homeEntity = _context.Cache.Get<Entity>(HomeEntity);
|
||||
foreach (var item in _entity.Cargo
|
||||
.Select(id => _context.Cache.Get<ItemInstance>(id))
|
||||
.Where(item => item is SimpleCommodity)
|
||||
.Cast<SimpleCommodity>()
|
||||
.ToArray())
|
||||
{
|
||||
int quantity = min((int) ((homeEntity.Capacity - homeEntity.OccupiedCapacity) / item.ItemData.Size), item.Quantity);
|
||||
var newItem = _entity.RemoveCargo(item, quantity);
|
||||
homeEntity.AddCargo(newItem);
|
||||
|
||||
if (quantity < item.Quantity)
|
||||
{
|
||||
homeEntity.SetMessage("Colony is out of cargo space. Closing Mining Task.");
|
||||
FinishTask();
|
||||
_taskStarted = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// private void OnArriveHome()
|
||||
// {
|
||||
// var homeEntity = _context.ItemData.Get<Entity>(HomeEntity);
|
||||
// foreach (var item in _entity.Cargo
|
||||
// .Select(id => _context.ItemData.Get<ItemInstance>(id))
|
||||
// .Where(item => item is SimpleCommodity)
|
||||
// .Cast<SimpleCommodity>()
|
||||
// .ToArray())
|
||||
// {
|
||||
// int quantity = min((int) ((homeEntity.Capacity - homeEntity.OccupiedCapacity) / _context.GetData(item).Size), item.Quantity);
|
||||
// var newItem = _entity.RemoveCargo(item, quantity);
|
||||
// homeEntity.AddCargo(newItem);
|
||||
//
|
||||
// if (quantity < item.Quantity)
|
||||
// {
|
||||
// homeEntity.SetMessage("Colony is out of cargo space. Closing Mining Task.");
|
||||
// FinishTask();
|
||||
// _taskStarted = false;
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private void NextAsteroid()
|
||||
{
|
||||
var miningTask = _context.Cache.Get<Mining>(Task);
|
||||
_asteroid = Zone.NearestAsteroid(miningTask.Asteroids, _entity.Position);
|
||||
_entity.SetMessage("Selecting new asteroid.");
|
||||
_asteroid = Zone.NearestAsteroid(Task.Asteroids, Entity.Position);
|
||||
Entity.SetMessage("Selecting new asteroid.");
|
||||
}
|
||||
|
||||
public PersistentBehaviorData Store()
|
||||
|
|
@ -141,5 +134,5 @@ public class MiningController : ControllerBase, IBehavior, IPersistentBehavior,
|
|||
public class MiningControllerPersistence : PersistentBehaviorData
|
||||
{
|
||||
[JsonProperty("task"), Key(0)]
|
||||
public Guid Task;
|
||||
public Mining Task;
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ public class MiningToolData : BehaviorData
|
|||
[InspectableField, JsonProperty("range"), Key(4)]
|
||||
public PerformanceStat Range = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new MiningTool(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -34,13 +34,13 @@ public class MiningTool : IBehavior
|
|||
private MiningToolData _data;
|
||||
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
public float Range { get; private set; }
|
||||
|
||||
public MiningTool(GameContext context, MiningToolData data, Entity entity, Gear item)
|
||||
public MiningTool(ItemManager context, MiningToolData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
|
|
@ -50,7 +50,7 @@ public class MiningTool : IBehavior
|
|||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
Range = Context.Evaluate(_data.Range, Item, Entity);
|
||||
Range = Context.Evaluate(_data.Range, Item.EquippableItem, Entity);
|
||||
var asteroidTransform = Entity.Zone.GetAsteroidTransform(AsteroidBelt, Asteroid);
|
||||
if (AsteroidBelt != Guid.Empty &&
|
||||
Entity.Zone.AsteroidExists(AsteroidBelt, Asteroid) &&
|
||||
|
|
@ -60,9 +60,9 @@ public class MiningTool : IBehavior
|
|||
Entity,
|
||||
AsteroidBelt,
|
||||
Asteroid,
|
||||
Context.Evaluate(_data.DamagePerSecond, Item, Entity) * delta,
|
||||
Context.Evaluate(_data.Efficiency, Item, Entity),
|
||||
Context.Evaluate(_data.Penetration, Item, Entity));
|
||||
Context.Evaluate(_data.DamagePerSecond, Item.EquippableItem, Entity) * delta,
|
||||
Context.Evaluate(_data.Efficiency, Item.EquippableItem, Entity),
|
||||
Context.Evaluate(_data.Penetration, Item.EquippableItem, Entity));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,58 +10,50 @@ using static Unity.Mathematics.math;
|
|||
[MessagePackObject, JsonObject(MemberSerialization.OptIn), EntityTypeRestriction(HullType.Ship), Order(-100)]
|
||||
public class PatrolControllerData : ControllerData
|
||||
{
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new PatrolController(context, this, entity, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class PatrolController : IBehavior, IController, IInitializableBehavior
|
||||
public class PatrolController : IBehavior, IInitializableBehavior
|
||||
{
|
||||
public TaskType TaskType => TaskType.None;
|
||||
public bool Available => false;
|
||||
public Zone Zone => _entity.Zone;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private PatrolControllerData _data;
|
||||
private GameContext _context;
|
||||
private Entity _entity;
|
||||
private Gear _item;
|
||||
private ItemManager Context { get; }
|
||||
private Entity Entity { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private Locomotion _locomotion;
|
||||
private Guid _targetOrbit;
|
||||
|
||||
public PatrolController(GameContext context, PatrolControllerData data, Entity entity, Gear item)
|
||||
public PatrolController(ItemManager context, PatrolControllerData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_context = context;
|
||||
Context = context;
|
||||
_data = data;
|
||||
_entity = entity;
|
||||
_item = item;
|
||||
Entity = entity;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_locomotion = new Locomotion(_context, _entity, _data);
|
||||
_locomotion = new Locomotion(Context, Entity, _data);
|
||||
RandomTarget();
|
||||
}
|
||||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
_locomotion.Objective = Zone.GetOrbitPosition(_targetOrbit);
|
||||
_locomotion.Objective = Entity.Zone.GetOrbitPosition(_targetOrbit);
|
||||
_locomotion.Update(delta);
|
||||
|
||||
if(length(_entity.Position - _locomotion.Objective) < _data.TargetDistance)
|
||||
if(length(Entity.Position - _locomotion.Objective) < _data.TargetDistance)
|
||||
RandomTarget();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void AssignTask(Guid task)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void RandomTarget()
|
||||
{
|
||||
_targetOrbit = Zone.Planets.Keys.ToArray()[_context.Random.NextInt(Zone.Planets.Count)];
|
||||
_targetOrbit = Entity.Zone.Planets.Keys.ToArray()[Context.Random.NextInt(Entity.Zone.Planets.Count)];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public class ProjectileWeaponData : WeaponData
|
|||
[InspectableField, JsonProperty("bulletVelocity"), Key(9)]
|
||||
public PerformanceStat Velocity = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new ProjectileWeapon(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -26,12 +26,12 @@ public class ProjectileWeapon : IBehavior
|
|||
{
|
||||
private ProjectileWeaponData _data;
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public ProjectileWeapon(GameContext context, ProjectileWeaponData c, Entity entity, Gear item)
|
||||
public ProjectileWeapon(ItemManager context, ProjectileWeaponData c, Entity entity, EquippedItem item)
|
||||
{
|
||||
Context = context;
|
||||
_data = c;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ public class RadianceData : BehaviorData
|
|||
[InspectableField, JsonProperty("radiance"), Key(1), RuntimeInspectable]
|
||||
public PerformanceStat Radiance = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Radiance(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -20,12 +20,12 @@ public class Radiance : IBehavior
|
|||
private RadianceData _data;
|
||||
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public Radiance(GameContext context, RadianceData data, Entity entity, Gear item)
|
||||
public Radiance(ItemManager context, RadianceData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ public class RadiatorData : BehaviorData
|
|||
[InspectableField, JsonProperty("emissivity"), Key(1), RuntimeInspectable]
|
||||
public PerformanceStat Emissivity = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Radiator(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -18,8 +18,8 @@ public class RadiatorData : BehaviorData
|
|||
public class Radiator : IBehavior
|
||||
{
|
||||
public Entity Entity { get; }
|
||||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
public EquippedItem Item { get; }
|
||||
public ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ public class Radiator : IBehavior
|
|||
|
||||
private RadiatorData _data;
|
||||
|
||||
public Radiator(GameContext context, RadiatorData data, Entity entity, Gear item)
|
||||
public Radiator(ItemManager context, RadiatorData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
Context = context;
|
||||
_data = data;
|
||||
|
|
@ -37,9 +37,9 @@ public class Radiator : IBehavior
|
|||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
Emissivity = Context.Evaluate(_data.Emissivity, Item, Entity);
|
||||
var rad = pow(Entity.Temperature, Context.GlobalData.HeatRadiationPower) * Context.GlobalData.HeatRadiationMultiplier * Emissivity;
|
||||
Entity.Temperature -= rad * delta;
|
||||
Emissivity = Context.Evaluate(_data.Emissivity, Item.EquippableItem, Entity);
|
||||
var rad = pow(Item.Temperature, Context.GameplaySettings.HeatRadiationExponent) * Context.GameplaySettings.HeatRadiationMultiplier * Emissivity;
|
||||
Item.Temperature -= rad * delta;
|
||||
Entity.VisibilitySources[this] = rad;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public class ReactorData : BehaviorData
|
|||
[InspectableField, JsonProperty("underload"), Key(5), RuntimeInspectable]
|
||||
public PerformanceStat ThrottlingFactor = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Reactor(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -30,13 +30,13 @@ public class Reactor : IBehavior
|
|||
private ReactorData _data;
|
||||
|
||||
public Entity Entity { get; }
|
||||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
public EquippedItem Item { get; }
|
||||
public ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
public float Capacitance;
|
||||
|
||||
public Reactor(GameContext context, ReactorData data, Entity entity, Gear item)
|
||||
public Reactor(ItemManager context, ReactorData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
Context = context;
|
||||
_data = data;
|
||||
|
|
@ -46,22 +46,22 @@ public class Reactor : IBehavior
|
|||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
Capacitance = Context.Evaluate(_data.Capacitance, Item, Entity);
|
||||
var charge = Context.Evaluate(_data.Charge, Item, Entity) * delta;
|
||||
var efficiency = Context.Evaluate(_data.Efficiency, Item, Entity);
|
||||
Capacitance = Context.Evaluate(_data.Capacitance, Item.EquippableItem, Entity);
|
||||
var charge = Context.Evaluate(_data.Charge, Item.EquippableItem, Entity) * delta;
|
||||
var efficiency = Context.Evaluate(_data.Efficiency, Item.EquippableItem, Entity);
|
||||
|
||||
Entity.AddHeat(charge / efficiency);
|
||||
Item.Temperature += (charge / efficiency) / Context.GetThermalMass(Item.EquippableItem);
|
||||
Entity.Energy += charge;
|
||||
|
||||
if (Entity.Energy > Capacitance)
|
||||
{
|
||||
Entity.AddHeat(-(Entity.Energy - Capacitance) / efficiency * (1 - 1 / Context.Evaluate(_data.ThrottlingFactor, Item, Entity)));
|
||||
Item.Temperature -= (Entity.Energy - Capacitance) / efficiency * (1 - 1 / Context.Evaluate(_data.ThrottlingFactor, Item.EquippableItem, Entity)) / Context.GetThermalMass(Item.EquippableItem);
|
||||
Entity.Energy = Capacitance;
|
||||
}
|
||||
|
||||
if (Entity.Energy < 0)
|
||||
{
|
||||
Entity.AddHeat( -Entity.Energy / Context.Evaluate(_data.OverloadEfficiency, Item, Entity));
|
||||
Item.Temperature += -Entity.Energy / Context.Evaluate(_data.OverloadEfficiency, Item.EquippableItem, Entity) / Context.GetThermalMass(Item.EquippableItem);
|
||||
Entity.Energy = 0;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public class ReflectorData : BehaviorData
|
|||
// [InspectableAnimationCurve, JsonProperty("visibility"), Key(1)]
|
||||
// public float4[] VisibilityCurve;
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Reflector(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -21,14 +21,14 @@ public class ReflectorData : BehaviorData
|
|||
public class Reflector : IBehavior
|
||||
{
|
||||
public Entity Entity { get; }
|
||||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
public EquippedItem Item { get; }
|
||||
public ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private ReflectorData _data;
|
||||
|
||||
public Reflector(GameContext context, ReflectorData data, Entity entity, Gear item)
|
||||
public Reflector(ItemManager context, ReflectorData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
Context = context;
|
||||
_data = data;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public class ResourceScannerData : BehaviorData
|
|||
[InspectableField, JsonProperty("scanDuration"), Key(3), RuntimeInspectable]
|
||||
public PerformanceStat ScanDuration = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new ResourceScanner(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -32,8 +32,8 @@ public class ResourceScanner : IBehavior, IAlwaysUpdatedBehavior
|
|||
private Guid _scanTarget;
|
||||
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
public float Range { get; private set; }
|
||||
|
|
@ -53,7 +53,7 @@ public class ResourceScanner : IBehavior, IAlwaysUpdatedBehavior
|
|||
}
|
||||
}
|
||||
|
||||
public ResourceScanner(GameContext context, ResourceScannerData data, Entity entity, Gear item)
|
||||
public ResourceScanner(ItemManager context, ResourceScannerData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
|
|
@ -63,7 +63,7 @@ public class ResourceScanner : IBehavior, IAlwaysUpdatedBehavior
|
|||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
var planetData = Context.Cache.Get<BodyData>(ScanTarget);
|
||||
var planetData = Context.ItemData.Get<BodyData>(ScanTarget);
|
||||
if (planetData != null)
|
||||
{
|
||||
if (planetData is AsteroidBeltData beltData)
|
||||
|
|
@ -75,7 +75,8 @@ public class ResourceScanner : IBehavior, IAlwaysUpdatedBehavior
|
|||
_scanTime += delta;
|
||||
if (_scanTime > ScanDuration)
|
||||
{
|
||||
Context.Cache.Get<Corporation>(Entity.Corporation).PlanetSurveyFloor[ScanTarget] = MinimumDensity;
|
||||
// TODO: Implement Scanning!
|
||||
//Context.ItemData.Get<Corporation>(Entity.Corporation).PlanetSurveyFloor[ScanTarget] = MinimumDensity;
|
||||
_scanTime = 0;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -88,7 +89,7 @@ public class ResourceScanner : IBehavior, IAlwaysUpdatedBehavior
|
|||
_scanTime += delta;
|
||||
if (_scanTime > ScanDuration)
|
||||
{
|
||||
Context.Cache.Get<Corporation>(Entity.Corporation).PlanetSurveyFloor[ScanTarget] = MinimumDensity;
|
||||
//Context.ItemData.Get<Corporation>(Entity.Corporation).PlanetSurveyFloor[ScanTarget] = MinimumDensity;
|
||||
_scanTime = 0;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -100,8 +101,8 @@ public class ResourceScanner : IBehavior, IAlwaysUpdatedBehavior
|
|||
|
||||
public void AlwaysUpdate(float delta)
|
||||
{
|
||||
Range = Context.Evaluate(_data.Range, Item, Entity);
|
||||
MinimumDensity = Context.Evaluate(_data.MinimumDensity, Item, Entity);
|
||||
ScanDuration = Context.Evaluate(_data.ScanDuration, Item, Entity);
|
||||
Range = Context.Evaluate(_data.Range, Item.EquippableItem, Entity);
|
||||
MinimumDensity = Context.Evaluate(_data.MinimumDensity, Item.EquippableItem, Entity);
|
||||
ScanDuration = Context.Evaluate(_data.ScanDuration, Item.EquippableItem, Entity);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ public class SensorData : BehaviorData
|
|||
[InspectableField, JsonProperty("sensitivity"), Key(3), RuntimeInspectable]
|
||||
public PerformanceStat Sensitivity = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Sensor(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -19,12 +19,12 @@ public class Sensor : IBehavior
|
|||
private SensorData _data;
|
||||
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public Sensor(GameContext context, SensorData data, Entity entity, Gear item)
|
||||
public Sensor(ItemManager context, SensorData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public class ShieldData : BehaviorData
|
|||
[InspectableField, JsonProperty("shielding"), Key(2), RuntimeInspectable]
|
||||
public PerformanceStat Shielding = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Shield(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -21,14 +21,14 @@ public class ShieldData : BehaviorData
|
|||
public class Shield : IBehavior
|
||||
{
|
||||
public Entity Entity { get; }
|
||||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
public EquippedItem Item { get; }
|
||||
public ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private ShieldData _data;
|
||||
|
||||
public Shield(GameContext context, ShieldData data, Entity entity, Gear item)
|
||||
public Shield(ItemManager context, ShieldData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
Context = context;
|
||||
_data = data;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public class StatModifierData : BehaviorData
|
|||
[InspectableType(typeof(BehaviorData)), JsonProperty("requireBehavior"), Key(4)]
|
||||
public Type RequireBehavior;
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new StatModifier(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -29,8 +29,8 @@ public class StatModifier : IBehavior, IInitializableBehavior, IDisposableBehavi
|
|||
{
|
||||
private StatModifierData _data;
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
|
|
@ -38,10 +38,10 @@ public class StatModifier : IBehavior, IInitializableBehavior, IDisposableBehavi
|
|||
|
||||
private static Type[] _statObjects;
|
||||
|
||||
private static Type[] StatObjects => _statObjects ?? (_statObjects = typeof(BehaviorData).GetAllChildClasses()
|
||||
.Concat(typeof(EquippableItemData).GetAllChildClasses()).ToArray());
|
||||
private static Type[] StatObjects => _statObjects = _statObjects ?? typeof(BehaviorData).GetAllChildClasses()
|
||||
.Concat(typeof(EquippableItemData).GetAllChildClasses()).ToArray();
|
||||
|
||||
public StatModifier(GameContext context, StatModifierData data, Entity entity, Gear item)
|
||||
public StatModifier(ItemManager context, StatModifierData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
|
|
@ -59,19 +59,17 @@ public class StatModifier : IBehavior, IInitializableBehavior, IDisposableBehavi
|
|||
if (statField != null)
|
||||
{
|
||||
if (typeof(EquippableItemData).IsAssignableFrom(targetType))
|
||||
_stats = Entity.Hardpoints
|
||||
.Select(hp => hp.Gear)
|
||||
.Where(gear => gear != null)
|
||||
.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)
|
||||
_stats = Entity.EquippedItems
|
||||
.Select(hp => hp.EquippableItem)
|
||||
.Where(gear => _data.RequireBehavior == null || Context.GetData(gear).Behaviors.Any(behavior => behavior.GetType() == _data.RequireBehavior))
|
||||
.Where(gear => Context.GetData(gear).GetType() == targetType)
|
||||
.Select(gear => statField.GetValue(Context.GetData(gear)) as PerformanceStat)
|
||||
.ToArray();
|
||||
else
|
||||
_stats = Entity.Hardpoints
|
||||
.Select(hp => hp.Gear)
|
||||
.Where(gear => gear != null)
|
||||
.Where(gear => _data.RequireBehavior == null || gear.ItemData.Behaviors.Any(behavior => behavior.GetType() == _data.RequireBehavior))
|
||||
.SelectMany(gear => gear.ItemData.Behaviors)
|
||||
_stats = Entity.EquippedItems
|
||||
.Select(hp => hp.EquippableItem)
|
||||
.Where(gear => _data.RequireBehavior == null || Context.GetData(gear).Behaviors.Any(behavior => behavior.GetType() == _data.RequireBehavior))
|
||||
.SelectMany(gear => Context.GetData(gear).Behaviors)
|
||||
.Where(behaviorData => behaviorData.GetType() == targetType)
|
||||
.Select(behaviorData => statField.GetValue(behaviorData) as PerformanceStat)
|
||||
.ToArray();
|
||||
|
|
@ -84,7 +82,7 @@ public class StatModifier : IBehavior, IInitializableBehavior, IDisposableBehavi
|
|||
foreach (var stat in _stats)
|
||||
(_data.Type == StatModifierType.Constant
|
||||
? stat.GetConstantModifiers(Entity)
|
||||
: stat.GetScaleModifiers(Entity))[this] = Context.Evaluate(_data.Modifier, Item, Entity);
|
||||
: stat.GetScaleModifiers(Entity))[this] = Context.Evaluate(_data.Modifier, Item.EquippableItem, Entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,109 +11,102 @@ using static Unity.Mathematics.math;
|
|||
[MessagePackObject, JsonObject(MemberSerialization.OptIn), EntityTypeRestriction(HullType.Ship), Order(-100)]
|
||||
public class SurveyControllerData : ControllerData
|
||||
{
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new SurveyController(context, this, entity, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class SurveyController : ControllerBase, IBehavior, IPersistentBehavior, IInitializableBehavior
|
||||
public class SurveyController : ControllerBase<Survey>, IBehavior, IPersistentBehavior, IInitializableBehavior
|
||||
{
|
||||
public override TaskType TaskType => TaskType.Explore;
|
||||
private EquippedItem Item { get; }
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private SurveyControllerData _data;
|
||||
private GameContext _context;
|
||||
private Entity _entity;
|
||||
private Gear _item;
|
||||
private bool _taskStarted;
|
||||
private ResourceScanner _scanningTool;
|
||||
private Switch _toolSwitch;
|
||||
private Guid _targetPlanet;
|
||||
private int _asteroid = -1;
|
||||
|
||||
public SurveyController(GameContext context, SurveyControllerData data, Entity entity, Gear item) : base(context, data, entity)
|
||||
public SurveyController(ItemManager itemManager, SurveyControllerData data, Entity entity, EquippedItem item) : base(itemManager, data, entity)
|
||||
{
|
||||
_context = context;
|
||||
_data = data;
|
||||
_entity = entity;
|
||||
_item = item;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public new void Initialize()
|
||||
{
|
||||
_scanningTool = _entity.GetBehavior<ResourceScanner>();
|
||||
_toolSwitch = _entity.GetSwitch<ResourceScanner>();
|
||||
_scanningTool = Entity.GetBehavior<ResourceScanner>();
|
||||
_toolSwitch = Entity.GetSwitch<ResourceScanner>();
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
public new bool Update(float delta)
|
||||
{
|
||||
var surveyTask = _context.Cache.Get<Survey>(Task);
|
||||
var corporation = _context.Cache.Get<Corporation>(_entity.Corporation);
|
||||
if (surveyTask != null)
|
||||
{
|
||||
if (!_taskStarted)
|
||||
{
|
||||
if (surveyTask.Planets.Any())
|
||||
{
|
||||
_entity.SetMessage("Moving to survey target.");
|
||||
NextPlanet();
|
||||
_scanningTool.ScanTarget = _targetPlanet;
|
||||
_scanningTool.Asteroid = _asteroid;
|
||||
if (!corporation.PlanetSurveyFloor.ContainsKey(_targetPlanet) ||
|
||||
corporation.PlanetSurveyFloor[_targetPlanet] + .5f < _scanningTool.MinimumDensity)
|
||||
{
|
||||
var planetData = _context.Cache.Get<BodyData>(_targetPlanet);
|
||||
MoveTo(() =>
|
||||
{
|
||||
var target = GetPosition(planetData, _asteroid);
|
||||
var targetToUs = _entity.Position - target;
|
||||
return target + normalize(targetToUs) * _scanningTool.Range / 2;
|
||||
},
|
||||
() => GetVelocity(planetData, _asteroid),
|
||||
() => _entity.SetMessage("Arrived at target. Scanning for resources."));
|
||||
_taskStarted = true;
|
||||
}
|
||||
else
|
||||
surveyTask.Planets.Remove(_targetPlanet);
|
||||
}
|
||||
else
|
||||
{
|
||||
_entity.SetMessage("Survey complete. Returning Home.");
|
||||
FinishTask();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Moving)
|
||||
{
|
||||
var planetData = _context.Cache.Get<BodyData>(_targetPlanet);
|
||||
if ((!corporation.PlanetSurveyFloor.ContainsKey(_targetPlanet) ||
|
||||
corporation.PlanetSurveyFloor[_targetPlanet] + .5f < _scanningTool.MinimumDensity) &&
|
||||
length(_entity.Position - GetPosition(planetData, _asteroid)) < _scanningTool.Range)
|
||||
{
|
||||
_toolSwitch.Activated = true;
|
||||
Aim.Objective = GetPosition(planetData, _asteroid);
|
||||
Aim.Update(delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
_toolSwitch.Activated = false;
|
||||
_taskStarted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// var corporation = _context.ItemData.Get<Corporation>(_entity.Corporation);
|
||||
// if (surveyTask != null)
|
||||
// {
|
||||
// if (!_taskStarted)
|
||||
// {
|
||||
// if (surveyTask.Planets.Any())
|
||||
// {
|
||||
// _entity.SetMessage("Moving to survey target.");
|
||||
// NextPlanet();
|
||||
// _scanningTool.ScanTarget = _targetPlanet;
|
||||
// _scanningTool.Asteroid = _asteroid;
|
||||
// if (!corporation.PlanetSurveyFloor.ContainsKey(_targetPlanet) ||
|
||||
// corporation.PlanetSurveyFloor[_targetPlanet] + .5f < _scanningTool.MinimumDensity)
|
||||
// {
|
||||
// var planetData = _context.ItemData.Get<BodyData>(_targetPlanet);
|
||||
// MoveTo(() =>
|
||||
// {
|
||||
// var target = GetPosition(planetData, _asteroid);
|
||||
// var targetToUs = _entity.Position - target;
|
||||
// return target + normalize(targetToUs) * _scanningTool.Range / 2;
|
||||
// },
|
||||
// () => GetVelocity(planetData, _asteroid),
|
||||
// () => _entity.SetMessage("Arrived at target. Scanning for resources."));
|
||||
// _taskStarted = true;
|
||||
// }
|
||||
// else
|
||||
// surveyTask.Planets.Remove(_targetPlanet);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// _entity.SetMessage("Survey complete. Returning Home.");
|
||||
// FinishTask();
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (!Moving)
|
||||
// {
|
||||
// var planetData = _context.ItemData.Get<BodyData>(_targetPlanet);
|
||||
// if ((!corporation.PlanetSurveyFloor.ContainsKey(_targetPlanet) ||
|
||||
// corporation.PlanetSurveyFloor[_targetPlanet] + .5f < _scanningTool.MinimumDensity) &&
|
||||
// length(_entity.Position - GetPosition(planetData, _asteroid)) < _scanningTool.Range)
|
||||
// {
|
||||
// _toolSwitch.Activated = true;
|
||||
// Aim.Objective = GetPosition(planetData, _asteroid);
|
||||
// Aim.Update(delta);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// _toolSwitch.Activated = false;
|
||||
// _taskStarted = false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return base.Update(delta);
|
||||
}
|
||||
|
||||
private void NextPlanet()
|
||||
{
|
||||
var surveyTask = _context.Cache.Get<Survey>(Task);
|
||||
var planets = surveyTask.Planets.Select(id => Zone.Planets[id]);
|
||||
var nearestPlanet = planets.MinBy(p => lengthsq(_entity.Position - GetPosition(p)));
|
||||
_asteroid = nearestPlanet is AsteroidBeltData ? Zone.NearestAsteroid(nearestPlanet.ID, _entity.Position) : -1;
|
||||
var planets = Task.Planets.Select(id => Zone.Planets[id]);
|
||||
var nearestPlanet = planets.MinBy(p => lengthsq(Entity.Position - GetPosition(p)));
|
||||
_asteroid = nearestPlanet is AsteroidBeltData ? Zone.NearestAsteroid(nearestPlanet.ID, Entity.Position) : -1;
|
||||
_targetPlanet = nearestPlanet.ID;
|
||||
}
|
||||
|
||||
|
|
@ -121,7 +114,7 @@ public class SurveyController : ControllerBase, IBehavior, IPersistentBehavior,
|
|||
{
|
||||
if (planet is AsteroidBeltData)
|
||||
{
|
||||
if(asteroid == -1) asteroid = Zone.NearestAsteroid(planet.ID, _entity.Position);
|
||||
if(asteroid == -1) asteroid = Zone.NearestAsteroid(planet.ID, Entity.Position);
|
||||
return Zone.GetAsteroidTransform(planet.ID, asteroid).xy;
|
||||
}
|
||||
return Zone.GetOrbitPosition(planet.Orbit);
|
||||
|
|
@ -131,7 +124,7 @@ public class SurveyController : ControllerBase, IBehavior, IPersistentBehavior,
|
|||
{
|
||||
if (planet is AsteroidBeltData)
|
||||
{
|
||||
if(asteroid == -1) asteroid = Zone.NearestAsteroid(planet.ID, _entity.Position);
|
||||
if(asteroid == -1) asteroid = Zone.NearestAsteroid(planet.ID, Entity.Position);
|
||||
return Zone.GetAsteroidVelocity(planet.ID, asteroid);
|
||||
}
|
||||
return Zone.GetOrbitVelocity(planet.Orbit);
|
||||
|
|
@ -155,5 +148,5 @@ public class SurveyController : ControllerBase, IBehavior, IPersistentBehavior,
|
|||
public class SurveyControllerPersistence : PersistentBehaviorData
|
||||
{
|
||||
[JsonProperty("task"), Key(0)]
|
||||
public Guid Task;
|
||||
public Survey Task;
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ using Newtonsoft.Json;
|
|||
[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn), Order(-25)]
|
||||
public class SwitchData : BehaviorData
|
||||
{
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Switch(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -17,14 +17,14 @@ public class Switch : IBehavior
|
|||
private SwitchData _data;
|
||||
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public bool Activated { get; set; }
|
||||
|
||||
public Switch(GameContext context, SwitchData data, Entity entity, Gear item)
|
||||
public Switch(ItemManager context, SwitchData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public class ThermotoggleData : BehaviorData
|
|||
[InspectableField, JsonProperty("highPass"), Key(2)]
|
||||
public bool HighPass;
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Thermotoggle(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -24,12 +24,12 @@ public class Thermotoggle : IBehavior
|
|||
private ThermotoggleData _data;
|
||||
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public Thermotoggle(GameContext context, ThermotoggleData data, Entity entity, Gear item)
|
||||
public Thermotoggle(ItemManager context, ThermotoggleData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
|
|
@ -40,6 +40,6 @@ public class Thermotoggle : IBehavior
|
|||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
return Entity.Temperature < TargetTemperature ^ _data.HighPass;
|
||||
return Item.Temperature < TargetTemperature ^ _data.HighPass;
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@ public class ThrusterData : BehaviorData
|
|||
[InspectableField, JsonProperty("heat"), Key(3)]
|
||||
public PerformanceStat Heat = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Thruster(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -24,8 +24,8 @@ public class ThrusterData : BehaviorData
|
|||
public class Thruster : IAnalogBehavior
|
||||
{
|
||||
public Entity Entity { get; }
|
||||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
public EquippedItem Item { get; }
|
||||
public ItemManager Context { get; }
|
||||
|
||||
public float Thrust { get; private set; }
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ public class Thruster : IAnalogBehavior
|
|||
|
||||
private float _input;
|
||||
|
||||
public Thruster(GameContext context, ThrusterData data, Entity entity, Gear item)
|
||||
public Thruster(ItemManager context, ThrusterData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
Context = context;
|
||||
_data = data;
|
||||
|
|
@ -51,10 +51,10 @@ public class Thruster : IAnalogBehavior
|
|||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
Thrust = Context.Evaluate(_data.Thrust, Item, Entity);
|
||||
Thrust = Context.Evaluate(_data.Thrust, Item.EquippableItem, Entity);
|
||||
Entity.Velocity += Entity.Direction * _input * Thrust / Entity.Mass * delta;
|
||||
Entity.AddHeat(_input * Context.Evaluate(_data.Heat, Item, Entity) * delta);
|
||||
Entity.VisibilitySources[this] = _input * Context.Evaluate(_data.Visibility, Item, Entity);
|
||||
Item.Temperature += (_input * Context.Evaluate(_data.Heat, Item.EquippableItem, Entity) * delta) / Context.GetThermalMass(Item.EquippableItem);
|
||||
Entity.VisibilitySources[this] = _input * Context.Evaluate(_data.Visibility, Item.EquippableItem, Entity);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -10,82 +10,70 @@ using static Unity.Mathematics.math;
|
|||
[MessagePackObject, JsonObject(MemberSerialization.OptIn), EntityTypeRestriction(HullType.Ship), Order(-100)]
|
||||
public class TowingControllerData : ControllerData
|
||||
{
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new TowingController(context, this, entity, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class TowingController : ControllerBase, IBehavior, IPersistentBehavior
|
||||
public class TowingController : ControllerBase<StationTowing>, IBehavior, IPersistentBehavior
|
||||
{
|
||||
public override TaskType TaskType => TaskType.Tow;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private TowingControllerData _data;
|
||||
private GameContext _context;
|
||||
private Entity _entity;
|
||||
private Gear _item;
|
||||
private EquippedItem Item { get; }
|
||||
private bool _taskStarted;
|
||||
|
||||
public TowingController(GameContext context, TowingControllerData data, Entity entity, Gear item) : base(context, data, entity)
|
||||
public TowingController(ItemManager itemManager, TowingControllerData data, Entity entity, EquippedItem item) : base(itemManager, data, entity)
|
||||
{
|
||||
_context = context;
|
||||
_data = data;
|
||||
_entity = entity;
|
||||
_item = item;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public new bool Update(float delta)
|
||||
{
|
||||
var towingTask = _context.Cache.Get<StationTowing>(Task);
|
||||
if (towingTask != null)
|
||||
if (Task != null)
|
||||
{
|
||||
if (!_taskStarted)
|
||||
{
|
||||
MoveTo(towingTask.Zone, OnZoneArrival);
|
||||
MoveTo(Task.Station, true, OnPickup);
|
||||
_taskStarted = true;
|
||||
}
|
||||
}
|
||||
return base.Update(delta);
|
||||
}
|
||||
|
||||
void OnZoneArrival()
|
||||
{
|
||||
var towingTask = _context.Cache.Get<StationTowing>(Task);
|
||||
|
||||
_entity.SetMessage("Entering pickup phase.");
|
||||
|
||||
MoveTo(_context.Cache.Get<Entity>(towingTask.Station), true, OnPickup);
|
||||
}
|
||||
// void OnZoneArrival()
|
||||
// {
|
||||
// var towingTask = _context.ItemData.Get<StationTowing>(Task);
|
||||
//
|
||||
// _entity.SetMessage("Entering pickup phase.");
|
||||
//
|
||||
// MoveTo(_context.ItemData.Get<Entity>(towingTask.Station), true, OnPickup);
|
||||
// }
|
||||
|
||||
void OnPickup()
|
||||
{
|
||||
var towingTask = _context.Cache.Get<StationTowing>(Task);
|
||||
var target = Zone.Entities[towingTask.Station] as OrbitalEntity;
|
||||
Task.Station.SetParent(Entity);
|
||||
|
||||
target.SetParent(_entity);
|
||||
|
||||
_entity.SetMessage("Entering delivery phase.");
|
||||
Entity.SetMessage("Entering delivery phase.");
|
||||
|
||||
MoveTo(() =>
|
||||
{
|
||||
var orbitParent = Zone.GetOrbitPosition(towingTask.OrbitParent);
|
||||
var parentToUs = _entity.Position - orbitParent;
|
||||
return orbitParent + normalize(parentToUs) * towingTask.OrbitDistance;
|
||||
}, () => Zone.GetOrbitVelocity(towingTask.OrbitParent), OnDelivery);
|
||||
var orbitParent = Zone.GetOrbitPosition(Task.OrbitParent);
|
||||
var parentToUs = Entity.Position - orbitParent;
|
||||
return orbitParent + normalize(parentToUs) * Task.OrbitDistance;
|
||||
}, () => Zone.GetOrbitVelocity(Task.OrbitParent), OnDelivery);
|
||||
}
|
||||
|
||||
void OnDelivery()
|
||||
{
|
||||
var towingTask = _context.Cache.Get<StationTowing>(Task);
|
||||
var target = Zone.Entities[towingTask.Station] as OrbitalEntity;
|
||||
Task.Station.RemoveParent();
|
||||
|
||||
target.RemoveParent();
|
||||
|
||||
_entity.SetMessage("Target delivered. Returning Home.");
|
||||
Entity.SetMessage("Target delivered. Returning Home.");
|
||||
|
||||
var orbit = Zone.CreateOrbit(towingTask.OrbitParent, _entity.Position);
|
||||
target.OrbitData = orbit.ID;
|
||||
var orbit = Zone.CreateOrbit(Task.OrbitParent, Entity.Position);
|
||||
Task.Station.OrbitData = orbit.ID;
|
||||
|
||||
FinishTask();
|
||||
_taskStarted = false;
|
||||
|
|
@ -109,5 +97,5 @@ public class TowingController : ControllerBase, IBehavior, IPersistentBehavior
|
|||
public class TowingControllerPersistence : PersistentBehaviorData
|
||||
{
|
||||
[JsonProperty("task"), Key(0)]
|
||||
public Guid Task;
|
||||
public StationTowing Task;
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ using Newtonsoft.Json;
|
|||
[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn), Order(-20)]
|
||||
public class TriggerData : BehaviorData
|
||||
{
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Trigger(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -17,8 +17,8 @@ public class Trigger : IBehavior
|
|||
private TriggerData _data;
|
||||
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ public class Trigger : IBehavior
|
|||
_pulled = true;
|
||||
}
|
||||
|
||||
public Trigger(GameContext context, TriggerData data, Entity entity, Gear item)
|
||||
public Trigger(ItemManager context, TriggerData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public class TurningData : BehaviorData
|
|||
[InspectableField, JsonProperty("heat"), Key(3)]
|
||||
public PerformanceStat Heat = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Turning(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -24,8 +24,8 @@ public class TurningData : BehaviorData
|
|||
public class Turning : IAnalogBehavior
|
||||
{
|
||||
public Entity Entity { get; }
|
||||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
public EquippedItem Item { get; }
|
||||
public ItemManager Context { get; }
|
||||
|
||||
public float Torque { get; private set; }
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ public class Turning : IAnalogBehavior
|
|||
|
||||
private float _input;
|
||||
|
||||
public Turning(GameContext context, TurningData data, Entity entity, Gear item)
|
||||
public Turning(ItemManager context, TurningData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
Context = context;
|
||||
_data = data;
|
||||
|
|
@ -55,10 +55,10 @@ public class Turning : IAnalogBehavior
|
|||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
Torque = Context.Evaluate(_data.Torque, Item, Entity);
|
||||
Torque = Context.Evaluate(_data.Torque, Item.EquippableItem, Entity);
|
||||
Entity.Direction = mul(Entity.Direction, Unity.Mathematics.float2x2.Rotate(_input * Torque / Entity.Mass * delta));
|
||||
Entity.AddHeat(abs(_input) * Context.Evaluate(_data.Heat, Item, Entity) * delta);
|
||||
Entity.VisibilitySources[this] = abs(_input) * Context.Evaluate(_data.Visibility, Item, Entity);
|
||||
Item.Temperature += (abs(_input) * Context.Evaluate(_data.Heat, Item.EquippableItem, Entity) * delta) / Context.GetThermalMass(Item.EquippableItem);
|
||||
Entity.VisibilitySources[this] = abs(_input) * Context.Evaluate(_data.Visibility, Item.EquippableItem, Entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ public class VelocityConversionData : BehaviorData
|
|||
[InspectableField, JsonProperty("traction"), Key(1), RuntimeInspectable]
|
||||
public PerformanceStat Traction = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new VelocityConversion(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -18,14 +18,14 @@ public class VelocityConversionData : BehaviorData
|
|||
public class VelocityConversion : IBehavior
|
||||
{
|
||||
public Entity Entity { get; }
|
||||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
public EquippedItem Item { get; }
|
||||
public ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private VelocityConversionData _data;
|
||||
|
||||
public VelocityConversion(GameContext context, VelocityConversionData data, Entity entity, Gear item)
|
||||
public VelocityConversion(ItemManager context, VelocityConversionData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
Context = context;
|
||||
_data = data;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ public class VelocityLimitData : BehaviorData
|
|||
[InspectableField, JsonProperty("topSpeed"), Key(1), RuntimeInspectable]
|
||||
public PerformanceStat TopSpeed = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new VelocityLimit(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -19,8 +19,8 @@ public class VelocityLimitData : BehaviorData
|
|||
public class VelocityLimit : IBehavior
|
||||
{
|
||||
public Entity Entity { get; }
|
||||
public Gear Item { get; }
|
||||
public GameContext Context { get; }
|
||||
public EquippedItem Item { get; }
|
||||
public ItemManager Context { get; }
|
||||
|
||||
public float Limit { get; private set; }
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ public class VelocityLimit : IBehavior
|
|||
|
||||
private VelocityLimitData _data;
|
||||
|
||||
public VelocityLimit(GameContext context, VelocityLimitData data, Entity entity, Gear item)
|
||||
public VelocityLimit(ItemManager context, VelocityLimitData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
Context = context;
|
||||
_data = data;
|
||||
|
|
@ -42,7 +42,7 @@ public class VelocityLimit : IBehavior
|
|||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
Limit = Context.Evaluate(_data.TopSpeed, Item, Entity);
|
||||
Limit = Context.Evaluate(_data.TopSpeed, Item.EquippableItem, Entity);
|
||||
if (length(Entity.Velocity) > Limit)
|
||||
Entity.Velocity = normalize(Entity.Velocity) * Limit;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public class VisibilityData : BehaviorData
|
|||
[InspectableField, JsonProperty("visibilityDecay"), Key(2)]
|
||||
public PerformanceStat VisibilityDecay = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new Visibility(context, this, entity, item);
|
||||
}
|
||||
|
|
@ -23,14 +23,14 @@ public class Visibility : IBehavior, IAlwaysUpdatedBehavior
|
|||
private VisibilityData _data;
|
||||
|
||||
private Entity Entity { get; }
|
||||
private Gear Item { get; }
|
||||
private GameContext Context { get; }
|
||||
private EquippedItem Item { get; }
|
||||
private ItemManager Context { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private float _cooldown; // Normalized
|
||||
|
||||
public Visibility(GameContext context, VisibilityData data, Entity entity, Gear item)
|
||||
public Visibility(ItemManager context, VisibilityData data, Entity entity, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Entity = entity;
|
||||
|
|
@ -40,14 +40,14 @@ public class Visibility : IBehavior, IAlwaysUpdatedBehavior
|
|||
|
||||
public bool Update(float delta)
|
||||
{
|
||||
Entity.VisibilitySources[this] = Context.Evaluate(_data.Visibility, Item, Entity);
|
||||
Entity.VisibilitySources[this] = Context.Evaluate(_data.Visibility, Item.EquippableItem, Entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void AlwaysUpdate(float delta)
|
||||
{
|
||||
// TODO: Time independent decay?
|
||||
Entity.VisibilitySources[this] *= Context.Evaluate(_data.VisibilityDecay, Item, Entity);
|
||||
Entity.VisibilitySources[this] *= Context.Evaluate(_data.VisibilityDecay, Item.EquippableItem, Entity);
|
||||
|
||||
if (Entity.VisibilitySources[this] < 0.01f) Entity.VisibilitySources.Remove(this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,32 +14,26 @@ public class WanderControllerData : ControllerData
|
|||
[InspectableField, JsonProperty("randomDockTime"), Key(6)]
|
||||
public float RandomDockTime = 5;
|
||||
|
||||
public override IBehavior CreateInstance(GameContext context, Entity entity, Gear item)
|
||||
public override IBehavior CreateInstance(ItemManager context, Entity entity, EquippedItem item)
|
||||
{
|
||||
return new WanderController(context, this, entity, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class WanderController : ControllerBase, IBehavior
|
||||
public class WanderController : ControllerBase<WanderTask>, IBehavior
|
||||
{
|
||||
public WanderTarget WanderTarget;
|
||||
public override TaskType TaskType => TaskType.None;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private WanderControllerData _data;
|
||||
private GameContext _context;
|
||||
private Entity _entity;
|
||||
private Gear _item;
|
||||
private EquippedItem Item { get; }
|
||||
private Guid _target;
|
||||
private float _dockTime = -1;
|
||||
|
||||
public WanderController(GameContext context, WanderControllerData data, Entity entity, Gear item) : base(context, data, entity)
|
||||
public WanderController(ItemManager itemManager, WanderControllerData data, Entity entity, EquippedItem item) : base(itemManager, data, entity)
|
||||
{
|
||||
_context = context;
|
||||
_data = data;
|
||||
_entity = entity;
|
||||
_item = item;
|
||||
Task = Guid.NewGuid();
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public new bool Update(float delta)
|
||||
|
|
@ -58,17 +52,17 @@ public class WanderController : ControllerBase, IBehavior
|
|||
if (WanderTarget == WanderTarget.Planets)
|
||||
{
|
||||
var planets = Zone.Planets.Values.ToArray();
|
||||
var randomPlanet = planets[_context.Random.NextInt(planets.Length)];
|
||||
var randomPlanet = planets[ItemManager.Random.NextInt(planets.Length)];
|
||||
MoveTo(() => Zone.GetOrbitPosition(randomPlanet.Orbit), () => Zone.GetOrbitVelocity(randomPlanet.Orbit));
|
||||
}
|
||||
else if (WanderTarget == WanderTarget.Orbitals)
|
||||
{
|
||||
var entities = Zone.Entities.Values.ToArray();
|
||||
var randomEntity = entities[_context.Random.NextInt(entities.Length)];
|
||||
var entities = Zone.Entities.Where(e=>e is OrbitalEntity).ToArray();
|
||||
var randomEntity = entities[ItemManager.Random.NextInt(entities.Length)];
|
||||
MoveTo(randomEntity, true, () =>
|
||||
{
|
||||
_entity.SetParent(randomEntity);
|
||||
_dockTime = _context.Random.NextFloat(_data.RandomDockTime);
|
||||
Entity.SetParent(randomEntity);
|
||||
_dockTime = ItemManager.Random.NextFloat(_data.RandomDockTime);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ public interface INamedEntry
|
|||
Union(3, typeof(HullData)),
|
||||
Union(4, typeof(SimpleCommodity)),
|
||||
Union(5, typeof(CompoundCommodity)),
|
||||
Union(6, typeof(Gear)),
|
||||
Union(6, typeof(EquippableItem)),
|
||||
Union(7, typeof(BlueprintData)),
|
||||
Union(8, typeof(GalaxyMapLayerData)),
|
||||
Union(9, typeof(GlobalData)),
|
||||
// Union(9, typeof(GlobalData)),
|
||||
Union(10, typeof(ZoneData)),
|
||||
Union(11, typeof(PlayerData)),
|
||||
Union(12, typeof(Corporation)),
|
||||
|
|
@ -50,5 +50,4 @@ public abstract class DatabaseEntry
|
|||
{
|
||||
[JsonProperty("id"), Key(0)]
|
||||
public Guid ID = Guid.NewGuid();
|
||||
[IgnoreMember] public GameContext Context { get; set; }
|
||||
}
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
"name": "Economy.Shared.Unity",
|
||||
"references": [
|
||||
"MessagePack",
|
||||
"MagicOnion.Abstractions",
|
||||
"Unity.Mathematics",
|
||||
"UniRx"
|
||||
"UniRx",
|
||||
"com.alelievr.NodeGraphProcessor.Runtime"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -10,6 +10,7 @@ public enum LauncherCaliber
|
|||
public enum HardpointType
|
||||
{
|
||||
Hull,
|
||||
Thermal,
|
||||
Thruster,
|
||||
WarpThruster,
|
||||
Reactor,
|
||||
|
|
|
|||
|
|
@ -29,12 +29,12 @@ public static class Extensions
|
|||
peer.Send(MessagePackSerializer.Serialize(message as Message), method);
|
||||
}
|
||||
|
||||
public static float Performance(this EquippableItemData itemData, float temperature)
|
||||
{
|
||||
return saturate(itemData.HeatPerformanceCurve.Evaluate(saturate(
|
||||
(temperature - itemData.MinimumTemperature) /
|
||||
(itemData.MaximumTemperature - itemData.MinimumTemperature))));
|
||||
}
|
||||
// public static float Performance(this EquippableItemData itemData, float temperature)
|
||||
// {
|
||||
// return saturate(itemData.HeatPerformanceCurve.Evaluate(saturate(
|
||||
// (temperature - itemData.MinimumTemperature) /
|
||||
// (itemData.MaximumTemperature - itemData.MinimumTemperature))));
|
||||
// }
|
||||
|
||||
public static string SplitCamelCase( this string str )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,162 +8,6 @@ using static Unity.Mathematics.math;
|
|||
using static Unity.Mathematics.noise;
|
||||
using static NoiseFbm;
|
||||
|
||||
[Inspectable, Serializable, RethinkTable("Galaxy"), MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class GlobalData : DatabaseEntry
|
||||
{
|
||||
[InspectableField, JsonProperty("galaxyName"), Key(1)]
|
||||
public string GalaxyName;
|
||||
|
||||
[InspectableDatabaseLink(typeof(ZoneData)), JsonProperty("arrivalZone"), Key(2)]
|
||||
public Guid ArrivalZone;
|
||||
|
||||
[InspectableField, JsonProperty("galaxyArms"), Key(4)]
|
||||
public int Arms = 4;
|
||||
|
||||
[InspectableField, JsonProperty("galaxyTwist"), Key(5)]
|
||||
public float Twist = 10;
|
||||
|
||||
[InspectableField, JsonProperty("galaxyTwistPower"), Key(6)]
|
||||
public float TwistPower = 2;
|
||||
|
||||
[InspectableField, JsonProperty("radiusPower"), Key(7)]
|
||||
public float RadiusPower = 1.75f;
|
||||
|
||||
[InspectableField, JsonProperty("massFloor"), Key(8)]
|
||||
public float MassFloor = 1;
|
||||
|
||||
[InspectableField, JsonProperty("sunMass"), Key(9)]
|
||||
public float SunMass = 10000;
|
||||
|
||||
[InspectableField, JsonProperty("gasGiantMass"), Key(10)]
|
||||
public float GasGiantMass = 2000;
|
||||
|
||||
[InspectableField, JsonProperty("planetMass"), Key(11)]
|
||||
public float PlanetMass = 100f;
|
||||
|
||||
[InspectableField, JsonProperty("satelliteCreationMassFloor"), Key(12)]
|
||||
public float SatelliteCreationMassFloor = 100;
|
||||
|
||||
[InspectableField, JsonProperty("satelliteCreationProbability"), Key(13)]
|
||||
public float SatelliteCreationProbability = .25f;
|
||||
|
||||
[InspectableField, JsonProperty("binaryCreationProbability"), Key(14)]
|
||||
public float BinaryCreationProbability = .25f;
|
||||
|
||||
[InspectableField, JsonProperty("rosetteProbability"), Key(15)]
|
||||
public float RosetteProbability = .25f;
|
||||
|
||||
// [InspectableField] [JsonProperty("mapLayers")] [Key(16)]
|
||||
// public Dictionary<string, Guid> MapLayers = new Dictionary<string, Guid>();
|
||||
|
||||
[InspectableField, JsonProperty("zoneRadiusMin"), Key(16)]
|
||||
public float MinimumZoneRadius = 500;
|
||||
|
||||
[InspectableField, JsonProperty("zoneRadiusMax"), Key(17)]
|
||||
public float MaximumZoneRadius = 2000;
|
||||
|
||||
[InspectableField, JsonProperty("zoneRadiusExp"), Key(18)]
|
||||
public float ZoneRadiusExponent = -.75f;
|
||||
|
||||
[InspectableField, JsonProperty("zoneMassMin"), Key(19)]
|
||||
public float MinimumZoneMass = 10000;
|
||||
|
||||
[InspectableField, JsonProperty("zoneMassMax"), Key(20)]
|
||||
public float MaximumZoneMass = 100000;
|
||||
|
||||
[InspectableField, JsonProperty("zoneMassExp"), Key(21)]
|
||||
public float ZoneMassExponent = -.75f;
|
||||
|
||||
[InspectableField, JsonProperty("orbitPeriodExponent"), Key(22)]
|
||||
public float OrbitPeriodExponent = 1.5f;
|
||||
|
||||
[InspectableField, JsonProperty("orbitPeriodMultiplier"), Key(23)]
|
||||
public float OrbitPeriodMultiplier = 1f;
|
||||
|
||||
[InspectableField, JsonProperty("beltProbability"), Key(26)]
|
||||
public float BeltProbability = .05f;
|
||||
|
||||
[InspectableField, JsonProperty("beltMassCeiling"), Key(27)]
|
||||
public float BeltMassCeiling = 500f;
|
||||
|
||||
[InspectableField, JsonProperty("beltMassRatio"), Key(28)]
|
||||
public float BeltMassRatio = 100f;
|
||||
|
||||
[InspectableField, JsonProperty("beltMassExponent"), Key(29)]
|
||||
public float BeltMassExponent = 100f;
|
||||
|
||||
[InspectableField, JsonProperty("asteroidSizeMin"), Key(30)]
|
||||
public float AsteroidSizeMin = 2f;
|
||||
|
||||
[InspectableField, JsonProperty("asteroidSizeMax"), Key(31)]
|
||||
public float AsteroidSizeMax = 10f;
|
||||
|
||||
[InspectableField, JsonProperty("asteroidSizeExponent"), Key(32)]
|
||||
public float AsteroidSizeExponent = 2f;
|
||||
|
||||
[InspectableField, JsonProperty("asteroidRotationSpeed"), Key(33)]
|
||||
public float AsteroidRotationSpeed = 2f;
|
||||
|
||||
[InspectableField, JsonProperty("dockingDistance"), Key(34)]
|
||||
public float DockingDistance = 25;
|
||||
|
||||
[InspectableField, JsonProperty("warpDistance"), Key(35)]
|
||||
public float WarpDistance = 25;
|
||||
|
||||
[InspectableField, JsonProperty("targetPersistenceDuration"), Key(37)]
|
||||
public float TargetPersistenceDuration = 3;
|
||||
|
||||
[InspectableField, JsonProperty("heatRadiationPower"), Key(38)]
|
||||
public float HeatRadiationPower = 1;
|
||||
|
||||
[InspectableField, JsonProperty("heatRadiationMultiplier"), Key(39)]
|
||||
public float HeatRadiationMultiplier = 1;
|
||||
|
||||
[InspectableField, JsonProperty("resourceDensityMinimum"), Key(40)]
|
||||
public float ResourceDensityMinimum = .1f;
|
||||
|
||||
[InspectableField, JsonProperty("resourceDensityMaximum"), Key(41)]
|
||||
public float ResourceDensityMaximum = 1.5f;
|
||||
|
||||
[InspectableField, JsonProperty("startingGearQualityMin"), Key(42)]
|
||||
public float StartingGearQualityMin = .1f;
|
||||
|
||||
[InspectableField, JsonProperty("startingGearQualityMax"), Key(43)]
|
||||
public float StartingGearQualityMax = .5f;
|
||||
|
||||
[InspectableField, JsonProperty("asteroidHitpointsMin"), Key(44)]
|
||||
public float AsteroidHitpointsMin = 10f;
|
||||
|
||||
[InspectableField, JsonProperty("asteroidHitpointsMax"), Key(45)]
|
||||
public float AsteroidHitpointsMax = 200f;
|
||||
|
||||
[InspectableField, JsonProperty("asteroidHitpointsPower"), Key(46)]
|
||||
public float AsteroidHitpointsPower = 2f;
|
||||
|
||||
[InspectableField, JsonProperty("asteroidRespawnMin"), Key(47)]
|
||||
public float AsteroidRespawnMin = 10f;
|
||||
|
||||
[InspectableField, JsonProperty("asteroidRespawnMax"), Key(48)]
|
||||
public float AsteroidRespawnMax = 100f;
|
||||
|
||||
[InspectableField, JsonProperty("miningDifficulty"), Key(49)]
|
||||
public float MiningDifficulty = 500f;
|
||||
|
||||
[InspectableField, JsonProperty("messageDuration"), Key(50)]
|
||||
public float MessageDuration = 4f;
|
||||
|
||||
[InspectableField, JsonProperty("significantDigits"), Key(51)]
|
||||
public int SignificantDigits = 3;
|
||||
|
||||
[InspectableField, JsonProperty("productionPersonalityLerp"), Key(52)]
|
||||
public float ProductionPersonalityLerp = .05f;
|
||||
|
||||
public float PlanetRadius(float mass)
|
||||
{
|
||||
return pow(mass, 1 / RadiusPower);
|
||||
}
|
||||
}
|
||||
|
||||
[Inspectable, Serializable, RethinkTable("Galaxy"), MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class GalaxyMapLayerData : DatabaseEntry, INamedEntry
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
public interface IChangeSource
|
||||
{
|
||||
event Action OnChanged;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9188eb1236c6f6f42b4c2d04b3111867
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -1,10 +1,93 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JsonKnownTypes;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
using int2 = Unity.Mathematics.int2;
|
||||
|
||||
public class Shape
|
||||
{
|
||||
[JsonProperty("name"), Key(0)] public bool[,] Cells;
|
||||
|
||||
private bool _dirty = true;
|
||||
|
||||
public Shape(int width, int height)
|
||||
{
|
||||
Cells = new bool[width, height];
|
||||
}
|
||||
|
||||
public int Width => Cells.GetLength(0);
|
||||
|
||||
public int Height => Cells.GetLength(1);
|
||||
|
||||
private static int mod(int x, int m) {
|
||||
int r = x%m;
|
||||
return r<0 ? r+m : r;
|
||||
}
|
||||
|
||||
public int2 Rotate(int2 position, int rotation)
|
||||
{
|
||||
switch (mod(rotation, 4))
|
||||
{
|
||||
case 1:
|
||||
return int2(position.y, Width - 1 - position.x);
|
||||
case 2:
|
||||
return int2(Width - 1 - position.x, Height - 1 - position.y);
|
||||
case 3:
|
||||
return int2(Height - 1 - position.y, position.x);
|
||||
default:
|
||||
return int2(position.x, position.y);
|
||||
}
|
||||
}
|
||||
|
||||
private int2[] _cachedShapeCoordinates;
|
||||
|
||||
[IgnoreMember]
|
||||
public int2[] Coordinates
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_dirty) _cachedShapeCoordinates = EnumerateShapeCoordinates().ToArray();
|
||||
return _cachedShapeCoordinates;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<int2> EnumerateShapeCoordinates()
|
||||
{
|
||||
for(int x = 0; x < Cells.GetLength(0); x++)
|
||||
{
|
||||
for (int y = 0; y < Cells.GetLength(0); y++)
|
||||
{
|
||||
if(Cells[x,y]) yield return int2(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool this[int2 pos] {
|
||||
get { return pos.x >= 0 && pos.y >= 0 && pos.x < Cells.GetLength(0) && pos.y < Cells.GetLength(1) && Cells[pos.x, pos.y]; }
|
||||
set
|
||||
{
|
||||
_dirty = true;
|
||||
Cells[pos.x, pos.y] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Shape Shrink()
|
||||
{
|
||||
var shape = new Shape(Width, Height);
|
||||
foreach(var shapeCoord in Coordinates)
|
||||
shape[shapeCoord] = (
|
||||
this[shapeCoord + int2(-1,-1)] && this[shapeCoord + int2(0,-1)] && this[shapeCoord + int2(1,-1)] &&
|
||||
this[shapeCoord + int2(-1,0)] && this[shapeCoord + int2(1,0)] &&
|
||||
this[shapeCoord + int2(-1,1)] && this[shapeCoord + int2(0,1)] && this[shapeCoord + int2(1,1)]
|
||||
);
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
|
||||
[MessagePackObject,
|
||||
Union(0, typeof(SimpleCommodityData)),
|
||||
|
|
@ -23,8 +106,8 @@ public abstract class ItemData : DatabaseEntry, INamedEntry
|
|||
[InspectableField, JsonProperty("mass"), Key(3)]
|
||||
public float Mass;
|
||||
|
||||
[InspectableField, JsonProperty("size"), Key(4)]
|
||||
public float Size;
|
||||
[InspectableField, JsonProperty("shape"), Key(4)]
|
||||
public Shape Shape;
|
||||
|
||||
// Heat needed to change temperature of 1 gram by 1 degree
|
||||
[InspectableField, JsonProperty("specificHeat"), Key(5)]
|
||||
|
|
@ -35,36 +118,32 @@ public abstract class ItemData : DatabaseEntry, INamedEntry
|
|||
get => Name;
|
||||
set => Name = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[RethinkTable("Items"), Inspectable, MessagePackObject]
|
||||
public class SimpleCommodityData : ItemData
|
||||
{
|
||||
// Types of body where this resource can be found
|
||||
[InspectableField, JsonProperty("resourceBodyType"), Key(6)]
|
||||
public BodyType ResourceBodyType;
|
||||
// // Types of body where this resource can be found
|
||||
// [InspectableField, JsonProperty("resourceBodyType"), Key(6)]
|
||||
// public BodyType ResourceBodyType;
|
||||
//
|
||||
// // Link to map(s) controlling density of resource, multiplied together when more than one
|
||||
// [InspectableDatabaseLink(typeof(GalaxyMapLayerData)), JsonProperty("resourceDensity"), Key(7)]
|
||||
// public List<Guid> ResourceDensity = new List<Guid>();
|
||||
//
|
||||
// // Controls the lowest value in the resource distribution curve
|
||||
// [InspectableField, JsonProperty("distribution"), Key(8)]
|
||||
// public ExponentialLerp Distribution;
|
||||
//
|
||||
// // Minimum amount of resources needed for presence to register
|
||||
// [InspectableField, JsonProperty("floor"), Key(11)]
|
||||
// public float Floor = 5f;
|
||||
|
||||
// Link to map(s) controlling density of resource, multiplied together when more than one
|
||||
[InspectableDatabaseLink(typeof(GalaxyMapLayerData)), JsonProperty("resourceDensity"), Key(7)]
|
||||
public List<Guid> ResourceDensity = new List<Guid>();
|
||||
[InspectableField, JsonProperty("maxStackSize"), Key(6)]
|
||||
public int MaxStack;
|
||||
|
||||
// Controls the lowest value in the resource distribution curve
|
||||
[InspectableField, JsonProperty("minimum"), Key(8)]
|
||||
public float Minimum = 1;
|
||||
|
||||
// Controls the highest value in the resource distribution curve
|
||||
[InspectableField, JsonProperty("maximum"), Key(9)]
|
||||
public float Maximum = 100;
|
||||
|
||||
// Controls the shape of the resource distribution curve
|
||||
[InspectableField, JsonProperty("exponent"), Key(10)]
|
||||
public float Exponent = -.75f;
|
||||
|
||||
// Minimum amount of resources needed for presence to register
|
||||
[InspectableField, JsonProperty("floor"), Key(11)]
|
||||
public float Floor = 5f;
|
||||
|
||||
[InspectableField, JsonProperty("category"), Key(12)]
|
||||
[InspectableField, JsonProperty("category"), Key(7)]
|
||||
public SimpleCommodityCategory Category;
|
||||
}
|
||||
|
||||
|
|
@ -83,10 +162,10 @@ public abstract class CraftedItemData : ItemData
|
|||
[RethinkTable("Items"), Inspectable, MessagePackObject]
|
||||
public class CompoundCommodityData : CraftedItemData
|
||||
{
|
||||
[InspectableDatabaseLink(typeof(PersonalityAttribute)), JsonProperty("demandProfile"), Key(7)]
|
||||
[InspectableDatabaseLink(typeof(PersonalityAttribute)), JsonProperty("demandProfile"), Key(7)]
|
||||
public Dictionary<Guid, float> DemandProfile = new Dictionary<Guid, float>();
|
||||
|
||||
[InspectableField, JsonProperty("category"), Key(8)]
|
||||
[InspectableField, JsonProperty("category"), Key(8)]
|
||||
public CompoundCommodityCategory Category;
|
||||
}
|
||||
|
||||
|
|
@ -95,26 +174,20 @@ public class CompoundCommodityData : CraftedItemData
|
|||
JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<EquippableItemData>))]
|
||||
public abstract class EquippableItemData : CraftedItemData
|
||||
{
|
||||
[InspectableAnimationCurve, JsonProperty("performanceCurve"), Key(7)]
|
||||
public float4[] HeatPerformanceCurve;
|
||||
[InspectableField, JsonProperty("behaviors"), Key(7)]
|
||||
public List<BehaviorData> Behaviors = new List<BehaviorData>();
|
||||
|
||||
[TemperatureInspectable, JsonProperty("minTemp"), Key(8)]
|
||||
[InspectableField, JsonProperty("durability"), Key(8)]
|
||||
public float Durability;
|
||||
|
||||
[TemperatureInspectable, JsonProperty("minTemp"), Key(9)]
|
||||
public float MinimumTemperature;
|
||||
|
||||
[TemperatureInspectable, JsonProperty("maxTemp"), Key(9)]
|
||||
[TemperatureInspectable, JsonProperty("maxTemp"), Key(10)]
|
||||
public float MaximumTemperature;
|
||||
|
||||
[InspectableField, JsonProperty("durabilityStat"), Key(10), SimplePerformanceStat]
|
||||
public PerformanceStat Durability = new PerformanceStat();
|
||||
|
||||
[InspectableField, JsonProperty("durabilityExponent"), Key(11), SimplePerformanceStat]
|
||||
public PerformanceStat DurabilityExponent = new PerformanceStat();
|
||||
|
||||
[InspectableField, JsonProperty("heatExponent"), Key(12), SimplePerformanceStat]
|
||||
public PerformanceStat HeatExponent = new PerformanceStat();
|
||||
|
||||
[InspectableField, JsonProperty("behaviors"), Key(13)]
|
||||
public List<BehaviorData> Behaviors = new List<BehaviorData>();
|
||||
|
||||
[IgnoreMember]
|
||||
public abstract HardpointType HardpointType { get; }
|
||||
|
|
@ -122,63 +195,63 @@ public abstract class EquippableItemData : CraftedItemData
|
|||
[IgnoreMember] private const int STEPS = 64;
|
||||
|
||||
[IgnoreMember] private float? _optimum;
|
||||
[IgnoreMember]
|
||||
public float OptimalTemperature
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_optimum==null)
|
||||
{
|
||||
var samples = Enumerable.Range(0, STEPS).Select(i => (float) i / STEPS).ToArray();
|
||||
float max = 0;
|
||||
_optimum = 0;
|
||||
foreach (var f in samples)
|
||||
{
|
||||
var p = HeatPerformanceCurve?.Evaluate(f)??0;
|
||||
if (p > max)
|
||||
{
|
||||
max = p;
|
||||
_optimum = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (float) (MinimumTemperature + _optimum * (MaximumTemperature - MinimumTemperature));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[RethinkTable("Items"), Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class GearData : EquippableItemData
|
||||
{
|
||||
[InspectableField, JsonProperty("hardpointType"), Key(14)]
|
||||
[InspectableField, JsonProperty("hardpointType"), Key(12)]
|
||||
public HardpointType Hardpoint;
|
||||
|
||||
[IgnoreMember] public override HardpointType HardpointType => Hardpoint;
|
||||
}
|
||||
|
||||
[RethinkTable("Items"), Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class CargoBayData : EquippableItemData
|
||||
{
|
||||
[InspectableField, JsonProperty("interiorShape"), Key(12)]
|
||||
public Shape InteriorShape;
|
||||
[IgnoreMember] public override HardpointType HardpointType => HardpointType.Tool;
|
||||
}
|
||||
|
||||
[RethinkTable("Items"), Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class HullData : EquippableItemData
|
||||
{
|
||||
[InspectableField, JsonProperty("hullCapacity"), Key(14)]
|
||||
public PerformanceStat Capacity = new PerformanceStat();
|
||||
|
||||
[InspectableField, JsonProperty("hardpoints"), Key(15)]
|
||||
[InspectableField, JsonProperty("hardpoints"), Key(12)]
|
||||
public List<HardpointData> Hardpoints = new List<HardpointData>();
|
||||
|
||||
[InspectablePrefab, JsonProperty("prefab"), Key(16)]
|
||||
[InspectablePrefab, JsonProperty("prefab"), Key(13)]
|
||||
public string Prefab;
|
||||
|
||||
[InspectableField, JsonProperty("hullType"), Key(17)]
|
||||
[InspectableField, JsonProperty("hullType"), Key(14)]
|
||||
public HullType HullType;
|
||||
|
||||
[IgnoreMember]
|
||||
public Shape InteriorCells
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_interiorCells == null)
|
||||
{
|
||||
_interiorCells = Shape.Shrink();
|
||||
}
|
||||
|
||||
return _interiorCells;
|
||||
}
|
||||
}
|
||||
|
||||
private Shape _interiorCells;
|
||||
|
||||
[IgnoreMember] public override HardpointType HardpointType => HardpointType.Hull;
|
||||
}
|
||||
|
||||
[RethinkTable("Items"), InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
[InspectableField, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class HardpointData
|
||||
{
|
||||
[InspectableField, JsonProperty("type"), Key(0)] public HardpointType Type;
|
||||
[InspectableField, JsonProperty("type"), Key(0)] public HardpointType Type;
|
||||
[InspectableField, JsonProperty("position"), Key(1)] public int2 Position;
|
||||
[InspectableField, JsonProperty("shape"), Key(2)] public Shape Shape;
|
||||
[InspectableField, JsonProperty("transform"), Key(3)] public string Transform;
|
||||
}
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
|
|
@ -191,10 +264,10 @@ public class PerformanceStat
|
|||
[JsonProperty("durabilityDependent"), Key(2)]
|
||||
public bool DurabilityDependent;
|
||||
|
||||
[JsonProperty("heatDependent"), Key(3)]
|
||||
public bool HeatDependent;
|
||||
// [JsonProperty("heatDependent"), Key(3)]
|
||||
// public bool HeatDependent;
|
||||
|
||||
[JsonProperty("qualityExponent"), Key(4)]
|
||||
[JsonProperty("qualityExponent"), Key(3)]
|
||||
public float QualityExponent;
|
||||
|
||||
//[JsonProperty("id"), Key(5)] public Guid ID = Guid.NewGuid();
|
||||
|
|
@ -206,11 +279,11 @@ public class PerformanceStat
|
|||
|
||||
[IgnoreMember]
|
||||
private Dictionary<Entity, Dictionary<IBehavior, float>> ScaleModifiers =>
|
||||
_scaleModifiers ?? (_scaleModifiers = new Dictionary<Entity, Dictionary<IBehavior, float>>());
|
||||
_scaleModifiers = _scaleModifiers ?? new Dictionary<Entity, Dictionary<IBehavior, float>>();
|
||||
|
||||
[IgnoreMember]
|
||||
private Dictionary<Entity, Dictionary<IBehavior, float>> ConstantModifiers =>
|
||||
_constantModifiers ?? (_constantModifiers = new Dictionary<Entity, Dictionary<IBehavior, float>>());
|
||||
_constantModifiers = _constantModifiers ?? new Dictionary<Entity, Dictionary<IBehavior, float>>();
|
||||
|
||||
public Dictionary<IBehavior, float> GetScaleModifiers(Entity entity)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,32 +9,28 @@ using MessagePack;
|
|||
using MessagePack.Formatters;
|
||||
using Newtonsoft.Json;
|
||||
using Unity.Mathematics;
|
||||
// TODO: USE THIS EVERYWHERE
|
||||
using static Unity.Mathematics.math;
|
||||
|
||||
[Union(0, typeof(SimpleCommodity)),
|
||||
Union(1, typeof(CompoundCommodity)),
|
||||
Union(2, typeof(Gear)),
|
||||
Union(2, typeof(EquippableItem)),
|
||||
JsonObject(MemberSerialization.OptIn),
|
||||
JsonConverter(typeof(JsonKnownTypesConverter<ItemInstance>))]
|
||||
public abstract class ItemInstance : DatabaseEntry
|
||||
public abstract class ItemInstance
|
||||
{
|
||||
[JsonProperty("data"), Key(1)] public Guid Data;
|
||||
|
||||
public float Mass => Context.GetMass(this);
|
||||
public float ThermalMass => Context.GetThermalMass(this);
|
||||
public float Size => Context.GetSize(this);
|
||||
[JsonProperty("data"), Key(0)] public Guid Data;
|
||||
[JsonProperty("rotation"), Key(1)] public int Rotation;
|
||||
}
|
||||
|
||||
[Union(0, typeof(CompoundCommodity)),
|
||||
Union(1, typeof(Gear)),
|
||||
Union(1, typeof(EquippableItem)),
|
||||
JsonObject(MemberSerialization.OptIn),
|
||||
JsonConverter(typeof(JsonKnownTypesConverter<CraftedItemInstance>))]
|
||||
public abstract class CraftedItemInstance : ItemInstance
|
||||
{
|
||||
[JsonProperty("quality"), Key(2)] public float Quality;
|
||||
|
||||
[JsonProperty("ingredients"), Key(3)] public List<Guid> Ingredients = new List<Guid>();
|
||||
[JsonProperty("ingredients"), Key(3)] public List<ItemInstance> Ingredients = new List<ItemInstance>();
|
||||
|
||||
[JsonProperty("blueprint"), Key(4)] public Guid Blueprint;
|
||||
|
||||
|
|
@ -44,27 +40,16 @@ public abstract class CraftedItemInstance : ItemInstance
|
|||
}
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class CompoundCommodity : CraftedItemInstance {}
|
||||
public class CompoundCommodity : CraftedItemInstance { }
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class SimpleCommodity : ItemInstance
|
||||
{
|
||||
[JsonProperty("quantity"), Key(2)] public int Quantity;
|
||||
|
||||
public SimpleCommodityData ItemData => Context.GetData(this);
|
||||
}
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class Gear : CraftedItemInstance, IChangeSource
|
||||
public class EquippableItem : CraftedItemInstance
|
||||
{
|
||||
[JsonProperty("durability"), Key(7)] public float Durability;
|
||||
|
||||
public EquippableItemData ItemData => Context.GetData(this);
|
||||
|
||||
public event Action OnChanged;
|
||||
|
||||
public void Change()
|
||||
{
|
||||
OnChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
|
@ -10,13 +10,13 @@ using JM.LinqFaster;
|
|||
using UniRx;
|
||||
using float4 = Unity.Mathematics.float4;
|
||||
|
||||
public class GameContext
|
||||
public class ItemManager
|
||||
{
|
||||
public Random Random = new Random((uint) (DateTime.Now.Ticks%uint.MaxValue));
|
||||
public Dictionary<string, GalaxyMapLayerData> MapLayers = new Dictionary<string, GalaxyMapLayerData>();
|
||||
public SimpleCommodityData[] Resources;
|
||||
public Dictionary<Guid, List<IController>> CorporationControllers = new Dictionary<Guid, List<IController>>();
|
||||
public Dictionary<Guid, ZoneDefinition> GalaxyZones;
|
||||
// public Dictionary<string, GalaxyMapLayerData> MapLayers = new Dictionary<string, GalaxyMapLayerData>();
|
||||
// public SimpleCommodityData[] Resources;
|
||||
// public Dictionary<Guid, List<IController>> CorporationControllers = new Dictionary<Guid, List<IController>>();
|
||||
// public Dictionary<Guid, ZoneDefinition> GalaxyZones;
|
||||
|
||||
private Action<string> _logger;
|
||||
|
||||
|
|
@ -25,25 +25,12 @@ public class GameContext
|
|||
|
||||
private double _time;
|
||||
private float _deltaTime;
|
||||
private GlobalData _globalData;
|
||||
private Dictionary<Guid, Zone> _zones = new Dictionary<Guid, Zone>();
|
||||
// private Guid _forceLoadZone;
|
||||
|
||||
public GlobalData GlobalData => _globalData ?? (_globalData = Cache.GetAll<GlobalData>().FirstOrDefault());
|
||||
public DatabaseCache Cache { get; }
|
||||
|
||||
// public Guid ForceLoadZone
|
||||
// {
|
||||
// get => _forceLoadZone;
|
||||
// set
|
||||
// {
|
||||
// if(_forceLoadZone != Guid.Empty && ZoneEntities[_forceLoadZone].Count == 0)
|
||||
// UnloadZone(_forceLoadZone);
|
||||
// _forceLoadZone = value;
|
||||
// if(!_loadedZones.Contains(_forceLoadZone))
|
||||
// LoadZone(_forceLoadZone);
|
||||
// }
|
||||
// }
|
||||
// public GlobalData GlobalData => _globalData ?? (_globalData = ItemData.GetAll<GlobalData>().FirstOrDefault());
|
||||
public DatabaseCache ItemData { get; }
|
||||
public GameplaySettings GameplaySettings { get; }
|
||||
|
||||
public double Time
|
||||
{
|
||||
|
|
@ -58,18 +45,10 @@ public class GameContext
|
|||
|
||||
// private readonly Dictionary<CraftedItemData, int> Tier = new Dictionary<CraftedItemData, int>();
|
||||
|
||||
public GameContext(DatabaseCache cache, Action<string> logger)
|
||||
public ItemManager(DatabaseCache itemData, GameplaySettings settings, Action<string> logger)
|
||||
{
|
||||
Cache = cache;
|
||||
MapLayers = cache.GetAll<GalaxyMapLayerData>().ToDictionary(ml => ml.Name);
|
||||
Resources = cache.GetAll<SimpleCommodityData>().Where(i => i.ResourceDensity.Any()).ToArray();
|
||||
ItemData = itemData;
|
||||
_logger = logger;
|
||||
// var globalData = Cache.GetAll<GlobalData>().FirstOrDefault();
|
||||
// if (globalData == null)
|
||||
// {
|
||||
// globalData = new GlobalData();
|
||||
// Cache.Add(globalData);
|
||||
// }
|
||||
}
|
||||
|
||||
public void Log(string s)
|
||||
|
|
@ -116,137 +95,6 @@ public class GameContext
|
|||
//
|
||||
// }
|
||||
|
||||
// public Zone GetZone(Guid zone)
|
||||
// {
|
||||
// if (_zones.ContainsKey(zone)) return _zones[zone];
|
||||
//
|
||||
// // var zoneData = Cache.Get<ZoneData>(zone);
|
||||
// // if (zoneData == null) throw new ArgumentException("Zone parameter is not a valid zone ID!", nameof(zone));
|
||||
// //
|
||||
// // return GetZone(zoneData);
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// public Zone GetZone(ZonePack zonePack)
|
||||
// {
|
||||
// var z = new Zone(this, zonePack);
|
||||
// _zones.Add(zonePack.Data.ID, z);
|
||||
// return z;
|
||||
// }
|
||||
//
|
||||
// public void UnloadZone(Guid zone)
|
||||
// {
|
||||
// _zones.Remove(zone);
|
||||
// }
|
||||
|
||||
// public void Warp(Entity entity, Guid targetZone)
|
||||
// {
|
||||
// if (length(entity.Position - WormholePosition(entity.Zone, targetZone)) < GlobalData.WarpDistance)
|
||||
// {
|
||||
// var sourceZone = entity.Zone;
|
||||
//
|
||||
// // Remove entity from source zone
|
||||
// ZoneEntities[sourceZone].Remove(entity.ID);
|
||||
//
|
||||
// // Unload source zone if empty and unobserved
|
||||
// if(ForceLoadZone != sourceZone && ZoneEntities[sourceZone].Count == 0)
|
||||
// UnloadZone(sourceZone);
|
||||
//
|
||||
// // Load target zone if not yet loaded
|
||||
// if(!_loadedZones.Contains(targetZone))
|
||||
// LoadZone(targetZone);
|
||||
//
|
||||
// entity.Zone = targetZone;
|
||||
// entity.Position = WormholePosition(targetZone, sourceZone);
|
||||
// ZoneEntities[targetZone][entity.ID] = entity;
|
||||
// }
|
||||
// }
|
||||
|
||||
public void PlaceMegas()
|
||||
{
|
||||
var megas = Cache.GetAll<MegaCorporation>();
|
||||
|
||||
var availableZones = Cache.GetAll<ZoneData>()
|
||||
.Where(z => megas.All(m => m.HomeZone != z.ID))
|
||||
.ToList();
|
||||
|
||||
foreach(var megaPlacement in megas
|
||||
.OrderBy(m=>m.PlacementType)
|
||||
.GroupBy(m=>m.PlacementType))
|
||||
switch (megaPlacement.Key)
|
||||
{
|
||||
case MegaPlacementType.Mass:
|
||||
foreach (var mega in megaPlacement)
|
||||
{
|
||||
var zone = availableZones
|
||||
.MaxBy(z => z.Mass);
|
||||
availableZones.Remove(zone);
|
||||
mega.HomeZone = zone.ID;
|
||||
}
|
||||
break;
|
||||
// case MegaPlacementType.Planets:
|
||||
// foreach (var mega in megaPlacement)
|
||||
// {
|
||||
// var zone = availableZones
|
||||
// .MaxBy(z => z.Planets.Length);
|
||||
// availableZones.Remove(zone);
|
||||
// mega.HomeZone = zone.ID;
|
||||
// }
|
||||
// break;
|
||||
// case MegaPlacementType.Resources:
|
||||
// foreach (var mega in megaPlacement)
|
||||
// {
|
||||
// var zone = availableZones
|
||||
// .MaxBy(z => z.Planets
|
||||
// .SelectMany(id=>Cache.Get<PlanetData>(id).Resources
|
||||
// .Select(r=>r.Key))
|
||||
// .Distinct()
|
||||
// .Count());
|
||||
// availableZones.Remove(zone);
|
||||
// mega.HomeZone = zone.ID;
|
||||
// }
|
||||
// break;
|
||||
case MegaPlacementType.Connected:
|
||||
foreach (var mega in megaPlacement)
|
||||
{
|
||||
var zone = availableZones
|
||||
.OrderByDescending(z => z.Wormholes.Count)
|
||||
.ThenBy(z=>megas
|
||||
.Sum(m=>m.HomeZone==Guid.Empty?0:lengthsq(Cache.Get<ZoneData>(m.HomeZone).Position - z.Position)))
|
||||
.First();
|
||||
availableZones.Remove(zone);
|
||||
mega.HomeZone = zone.ID;
|
||||
}
|
||||
break;
|
||||
case MegaPlacementType.Isolated:
|
||||
foreach (var mega in megaPlacement)
|
||||
{
|
||||
var zone = availableZones
|
||||
.Where(z=>z.Wormholes.Count==1)
|
||||
.MaxBy(z =>
|
||||
{
|
||||
int soloChain = 0;
|
||||
var previous = z;
|
||||
var next = Cache.Get<ZoneData>(z.Wormholes.First());
|
||||
while (next.Wormholes.Count == 2)
|
||||
{
|
||||
var temp = next;
|
||||
next = Cache.Get<ZoneData>(next.Wormholes.First(w=>w != previous.ID));
|
||||
previous = temp;
|
||||
soloChain++;
|
||||
}
|
||||
|
||||
return soloChain;
|
||||
});
|
||||
availableZones.Remove(zone);
|
||||
mega.HomeZone = zone.ID;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
// public int ItemTier(CraftedItemData itemData)
|
||||
// {
|
||||
// if (Tier.ContainsKey(itemData)) return Tier[itemData];
|
||||
|
|
@ -258,22 +106,22 @@ public class GameContext
|
|||
|
||||
public ItemData GetData(ItemInstance item)
|
||||
{
|
||||
return Cache.Get<ItemData>(item.Data);
|
||||
return ItemData.Get<ItemData>(item.Data);
|
||||
}
|
||||
|
||||
public SimpleCommodityData GetData(SimpleCommodity item)
|
||||
{
|
||||
return Cache.Get<SimpleCommodityData>(item.Data);
|
||||
return ItemData.Get<SimpleCommodityData>(item.Data);
|
||||
}
|
||||
|
||||
public CraftedItemData GetData(CraftedItemInstance item)
|
||||
{
|
||||
return Cache.Get<CraftedItemData>(item.Data);
|
||||
return ItemData.Get<CraftedItemData>(item.Data);
|
||||
}
|
||||
|
||||
public EquippableItemData GetData(Gear gear)
|
||||
public EquippableItemData GetData(EquippableItem equippableItem)
|
||||
{
|
||||
return Cache.Get<EquippableItemData>(gear.Data);
|
||||
return ItemData.Get<EquippableItemData>(equippableItem.Data);
|
||||
}
|
||||
|
||||
public float GetMass(ItemInstance item)
|
||||
|
|
@ -290,20 +138,6 @@ public class GameContext
|
|||
return 0;
|
||||
}
|
||||
|
||||
public float GetSize(ItemInstance item)
|
||||
{
|
||||
var data = GetData(item);
|
||||
switch (item)
|
||||
{
|
||||
case CraftedItemInstance _:
|
||||
return data.Size;
|
||||
case SimpleCommodity commodity:
|
||||
return data.Size * commodity.Quantity;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public float GetThermalMass(ItemInstance item)
|
||||
{
|
||||
var data = GetData(item);
|
||||
|
|
@ -324,7 +158,7 @@ public class GameContext
|
|||
if (AffectedStats.ContainsKey(effect)) return AffectedStats[effect];
|
||||
|
||||
// Get the data for the item the blueprint is for, return null if not found or not equippable
|
||||
var blueprintItem = Cache.Get<EquippableItemData>(blueprint.Item);
|
||||
var blueprintItem = ItemData.Get<EquippableItemData>(blueprint.Item);
|
||||
if (blueprintItem == null)
|
||||
{
|
||||
_logger($"Attempted to get stat effect but Blueprint {blueprint.ID} is not for an equippable item!");
|
||||
|
|
@ -364,7 +198,7 @@ public class GameContext
|
|||
var craftedIngredients = item.Ingredients.Where(i => i is CraftedItemInstance).ToArray();
|
||||
if (craftedIngredients.Length > 0)
|
||||
{
|
||||
var ingredientQualityWeight = Cache.Get<CraftedItemData>(item.Data).IngredientQualityWeight;
|
||||
var ingredientQualityWeight = ItemData.Get<CraftedItemData>(item.Data).IngredientQualityWeight;
|
||||
quality = quality * (1 - ingredientQualityWeight) +
|
||||
craftedIngredients.Cast<CraftedItemInstance>().Average(CompoundQuality) * ingredientQualityWeight;
|
||||
}
|
||||
|
|
@ -375,21 +209,21 @@ public class GameContext
|
|||
}
|
||||
|
||||
// Determine quality of either the item itself or the specific ingredient this stat depends on
|
||||
public float Quality(PerformanceStat stat, Gear item)
|
||||
public float Quality(PerformanceStat stat, EquippableItem item)
|
||||
{
|
||||
var blueprint = Cache.Get<BlueprintData>(item.Blueprint);
|
||||
var itemData = GetData(item);
|
||||
var blueprint = ItemData.Get<BlueprintData>(item.Blueprint);
|
||||
var activeEffects = blueprint.StatEffects.Where(x => GetAffectedStat(blueprint, x) == stat).ToArray();
|
||||
float quality;
|
||||
if (!activeEffects.Any())
|
||||
quality = CompoundQuality(item);
|
||||
else
|
||||
{
|
||||
var ingredientInstances = item.Ingredients.Select(i => Cache.Get<ItemInstance>(i)).ToArray();
|
||||
var ingredients = ingredientInstances.Where(i => activeEffects.Any(e => e.Ingredient == i.Data)).ToArray();
|
||||
var ingredients = item.Ingredients.Where(i => activeEffects.Any(e => e.Ingredient == i.Data)).ToArray();
|
||||
var distinctIngredients = ingredients.Select(i => i.Data).Distinct();
|
||||
if(distinctIngredients.Count() != activeEffects.Length)
|
||||
{
|
||||
_logger($"Item {item.ID} does not have the ingredients specified by the stat effects of its blueprint!");
|
||||
_logger($"Item {itemData.Name} does not have the ingredients specified by the stat effects of its blueprint!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -398,7 +232,7 @@ public class GameContext
|
|||
{
|
||||
if (i is CraftedItemInstance ci)
|
||||
sum += CompoundQuality(ci);
|
||||
else _logger($"Blueprint stat effect for item {item.ID} specifies invalid (non crafted) ingredient!");
|
||||
else _logger($"Blueprint stat effect for item {itemData.Name} specifies invalid (non crafted) ingredient!");
|
||||
}
|
||||
|
||||
quality = sum / ingredients.Length;
|
||||
|
|
@ -408,7 +242,7 @@ public class GameContext
|
|||
}
|
||||
|
||||
// Returns stat when not equipped
|
||||
public float Evaluate(PerformanceStat stat, Gear item)
|
||||
public float Evaluate(PerformanceStat stat, EquippableItem item)
|
||||
{
|
||||
var quality = pow(Quality(stat, item), stat.QualityExponent);
|
||||
|
||||
|
|
@ -421,174 +255,173 @@ public class GameContext
|
|||
}
|
||||
|
||||
// Returns stat using ship temperature and modifiers
|
||||
public float Evaluate(PerformanceStat stat, Gear item, Entity entity)
|
||||
public float Evaluate(PerformanceStat stat, EquippableItem item, Entity entity)
|
||||
{
|
||||
var itemData = GetData(item);
|
||||
|
||||
var heat = !stat.HeatDependent ? 1 : pow(itemData.Performance(entity.Temperature), Evaluate(itemData.HeatExponent,item));
|
||||
var durability = !stat.DurabilityDependent ? 1 : pow(item.Durability / Evaluate(itemData.Durability, item), Evaluate(itemData.DurabilityExponent,item));
|
||||
|
||||
//var heat = !stat.HeatDependent ? 1 : pow(itemData.Performance(entity.Temperature), Evaluate(itemData.HeatExponent,item));
|
||||
var durability = !stat.DurabilityDependent ? 1 : pow(item.Durability / itemData.Durability, Evaluate(itemData.DurabilityExponent,item));
|
||||
var quality = pow(Quality(stat, item), stat.QualityExponent);
|
||||
|
||||
|
||||
var scaleModifier = stat.GetScaleModifiers(entity).Values.Aggregate(1.0f, (current, mod) => current * mod);
|
||||
|
||||
|
||||
var constantModifier = stat.GetConstantModifiers(entity).Values.Sum();
|
||||
|
||||
var result = lerp(stat.Min, stat.Max, heat * durability * quality) * scaleModifier + constantModifier;
|
||||
|
||||
var result = lerp(stat.Min, stat.Max, durability * quality) * scaleModifier + constantModifier;
|
||||
if (float.IsNaN(result))
|
||||
return stat.Min;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Entity CreateEntity(Guid zoneID, Guid corporation, Guid loadout)
|
||||
{
|
||||
if (!(Cache.Get(loadout) is LoadoutData loadoutData))
|
||||
{
|
||||
_logger("Attempted to spawn invalid loadout ID");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!(Cache.Get(loadoutData.Hull) is HullData hullData))
|
||||
{
|
||||
_logger("Attempted to spawn loadout with invalid hull ID");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!(Cache.Get(zoneID) is ZoneData zoneData))
|
||||
{
|
||||
_logger("Attempted to spawn entity with invalid zone ID");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!(Cache.Get(corporation) is Corporation corpData))
|
||||
{
|
||||
_logger("Attempted to spawn entity with invalid corporation ID");
|
||||
return null;
|
||||
}
|
||||
|
||||
var gearData = loadoutData.Gear
|
||||
.Take(hullData.Hardpoints.Count)
|
||||
.Where(id => id != Guid.Empty)
|
||||
.Select(id => Cache.Get<GearData>(id))
|
||||
.ToArray();
|
||||
|
||||
if (gearData.Any(g=>g==null))
|
||||
{
|
||||
_logger("Attempted to spawn loadout with invalid gear ID");
|
||||
return null;
|
||||
}
|
||||
|
||||
var gear = gearData
|
||||
.Select(gd => CreateInstance(gd.ID, GlobalData.StartingGearQualityMin, GlobalData.StartingGearQualityMax))
|
||||
.ToArray();
|
||||
|
||||
if (gear.Any(g=>g==null))
|
||||
return null;
|
||||
|
||||
foreach(var g in gear)
|
||||
Cache.Add(g);
|
||||
|
||||
var cargoData = loadoutData.CompoundCargo
|
||||
.SelectMany(x => Enumerable.Repeat(Cache.Get<CraftedItemData>(x.Key), x.Value))
|
||||
.ToArray();
|
||||
|
||||
if (cargoData.Any(g=>g==null))
|
||||
{
|
||||
_logger("Attempted to spawn loadout with invalid cargo ID");
|
||||
return null;
|
||||
}
|
||||
|
||||
var cargo = cargoData
|
||||
.Select(gd => CreateInstance(gd.ID, GlobalData.StartingGearQualityMin, GlobalData.StartingGearQualityMax))
|
||||
.ToArray();
|
||||
|
||||
if (cargo.Any(g=>g==null))
|
||||
return null;
|
||||
|
||||
foreach(var c in cargo)
|
||||
Cache.Add(c);
|
||||
|
||||
var simpleCargo = loadoutData.SimpleCargo?
|
||||
.Select(x => CreateInstance(x.Key, x.Value))
|
||||
.ToArray() ?? new SimpleCommodity[0];
|
||||
|
||||
if (simpleCargo.Any(g=>g==null))
|
||||
return null;
|
||||
|
||||
var hull = CreateInstance(loadoutData.Hull, GlobalData.StartingGearQualityMin, GlobalData.StartingGearQualityMax);
|
||||
|
||||
if(hull==null)
|
||||
return null;
|
||||
|
||||
// Get target zone
|
||||
var zone = _zones[zoneID];
|
||||
|
||||
if (hullData.HullType == HullType.Ship)
|
||||
{
|
||||
var entity = CreateShip(hull.ID, gear.Select(g => g.ID),
|
||||
cargo.Select(c => c.ID).Concat(simpleCargo.Select(c => c.ID)), zone, corporation, Guid.Empty, loadoutData.Name);
|
||||
entity.Active = true;
|
||||
return entity;
|
||||
}
|
||||
|
||||
if (hullData.HullType == HullType.Station)
|
||||
{
|
||||
var distance = lerp(.2f, .8f, Random.NextFloat()) * zoneData.Radius;
|
||||
var orbit = new OrbitData
|
||||
{
|
||||
Context = this,
|
||||
Distance = new ReactiveProperty<float>(distance),
|
||||
Parent = zone.Orbits.Values.Select(o=>o.Data)
|
||||
.First(orbitData => orbitData.Parent == Guid.Empty).ID,
|
||||
Phase = Random.NextFloat()
|
||||
};
|
||||
zone.AddOrbit(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, corporation)
|
||||
{
|
||||
Name = $"{loadoutData.Name} {Random.NextInt(1,255):X}",
|
||||
Temperature = 293,
|
||||
Population = 4
|
||||
};
|
||||
entity.Active = true;
|
||||
var parentCorp = Cache.Get<MegaCorporation>(corpData.Parent);
|
||||
foreach (var attribute in parentCorp.Personality)
|
||||
entity.Personality[attribute.Key] = attribute.Value;
|
||||
Cache.Add(entity);
|
||||
|
||||
zone.Entities[entity.ID] = entity;
|
||||
return entity;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Ship CreateShip(Guid hull, IEnumerable<Guid> gear, IEnumerable<Guid> cargo, Zone zone, Guid corporation, Guid homeEntity, string typeName)
|
||||
{
|
||||
|
||||
var ship = new Ship(this, hull, gear, cargo, zone, corporation)
|
||||
{
|
||||
Name = $"{typeName} {Random.NextInt(1,255):X}",
|
||||
HomeEntity = homeEntity
|
||||
};
|
||||
Cache.Add(ship);
|
||||
|
||||
zone.Entities[ship.ID] = ship;
|
||||
return ship;
|
||||
}
|
||||
// public Entity CreateEntity(Guid zoneID, Guid corporation, Guid loadout)
|
||||
// {
|
||||
// if (!(ItemData.Get(loadout) is LoadoutData loadoutData))
|
||||
// {
|
||||
// _logger("Attempted to spawn invalid loadout ID");
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// if (!(ItemData.Get(loadoutData.Hull) is HullData hullData))
|
||||
// {
|
||||
// _logger("Attempted to spawn loadout with invalid hull ID");
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// if (!(ItemData.Get(zoneID) is ZoneData zoneData))
|
||||
// {
|
||||
// _logger("Attempted to spawn entity with invalid zone ID");
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// if (!(ItemData.Get(corporation) is Corporation corpData))
|
||||
// {
|
||||
// _logger("Attempted to spawn entity with invalid corporation ID");
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// var gearData = loadoutData.Gear
|
||||
// .Take(hullData.Hardpoints.Count)
|
||||
// .Where(id => id != Guid.Empty)
|
||||
// .Select(id => ItemData.Get<GearData>(id))
|
||||
// .ToArray();
|
||||
//
|
||||
// if (gearData.Any(g=>g==null))
|
||||
// {
|
||||
// _logger("Attempted to spawn loadout with invalid gear ID");
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// var gear = gearData
|
||||
// .Select(gd => CreateInstance(gd.ID, GlobalData.StartingGearQualityMin, GlobalData.StartingGearQualityMax))
|
||||
// .ToArray();
|
||||
//
|
||||
// if (gear.Any(g=>g==null))
|
||||
// return null;
|
||||
//
|
||||
// foreach(var g in gear)
|
||||
// ItemData.Add(g);
|
||||
//
|
||||
// var cargoData = loadoutData.CompoundCargo
|
||||
// .SelectMany(x => Enumerable.Repeat(ItemData.Get<CraftedItemData>(x.Key), x.Value))
|
||||
// .ToArray();
|
||||
//
|
||||
// if (cargoData.Any(g=>g==null))
|
||||
// {
|
||||
// _logger("Attempted to spawn loadout with invalid cargo ID");
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// var cargo = cargoData
|
||||
// .Select(gd => CreateInstance(gd.ID, GlobalData.StartingGearQualityMin, GlobalData.StartingGearQualityMax))
|
||||
// .ToArray();
|
||||
//
|
||||
// if (cargo.Any(g=>g==null))
|
||||
// return null;
|
||||
//
|
||||
// foreach(var c in cargo)
|
||||
// ItemData.Add(c);
|
||||
//
|
||||
// var simpleCargo = loadoutData.SimpleCargo?
|
||||
// .Select(x => CreateInstance(x.Key, x.Value))
|
||||
// .ToArray() ?? new SimpleCommodity[0];
|
||||
//
|
||||
// if (simpleCargo.Any(g=>g==null))
|
||||
// return null;
|
||||
//
|
||||
// var hull = CreateInstance(loadoutData.Hull, GlobalData.StartingGearQualityMin, GlobalData.StartingGearQualityMax);
|
||||
//
|
||||
// if(hull==null)
|
||||
// return null;
|
||||
//
|
||||
// // Get target zone
|
||||
// var zone = _zones[zoneID];
|
||||
//
|
||||
// if (hullData.HullType == HullType.Ship)
|
||||
// {
|
||||
// var entity = CreateShip(hull.ID, gear.Select(g => g.ID),
|
||||
// cargo.Select(c => c.ID).Concat(simpleCargo.Select(c => c.ID)), zone, corporation, Guid.Empty, loadoutData.Name);
|
||||
// entity.Active = true;
|
||||
// return entity;
|
||||
// }
|
||||
//
|
||||
// if (hullData.HullType == HullType.Station)
|
||||
// {
|
||||
// var distance = lerp(.2f, .8f, Random.NextFloat()) * zoneData.Radius;
|
||||
// var orbit = new OrbitData
|
||||
// {
|
||||
// Context = this,
|
||||
// Distance = new ReactiveProperty<float>(distance),
|
||||
// Parent = zone.Orbits.Values.Select(o=>o.Data)
|
||||
// .First(orbitData => orbitData.Parent == Guid.Empty).ID,
|
||||
// Phase = Random.NextFloat()
|
||||
// };
|
||||
// zone.AddOrbit(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, corporation)
|
||||
// {
|
||||
// Name = $"{loadoutData.Name} {Random.NextInt(1,255):X}",
|
||||
// Temperature = 293,
|
||||
// Population = 4
|
||||
// };
|
||||
// entity.Active = true;
|
||||
// var parentCorp = ItemData.Get<MegaCorporation>(corpData.Parent);
|
||||
// foreach (var attribute in parentCorp.Personality)
|
||||
// entity.Personality[attribute.Key] = attribute.Value;
|
||||
// ItemData.Add(entity);
|
||||
//
|
||||
// zone.Entities[entity.ID] = entity;
|
||||
// return entity;
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// public Ship CreateShip(Guid hull, IEnumerable<Guid> gear, IEnumerable<Guid> cargo, Zone zone, Guid corporation, Guid homeEntity, string typeName)
|
||||
// {
|
||||
//
|
||||
// var ship = new Ship(this, hull, gear, cargo, zone, corporation)
|
||||
// {
|
||||
// Name = $"{typeName} {Random.NextInt(1,255):X}",
|
||||
// HomeEntity = homeEntity
|
||||
// };
|
||||
// ItemData.Add(ship);
|
||||
//
|
||||
// zone.Entities[ship.ID] = ship;
|
||||
// return ship;
|
||||
// }
|
||||
|
||||
public SimpleCommodity CreateInstance(Guid data, int count)
|
||||
{
|
||||
var item = Cache.Get<SimpleCommodityData>(data);
|
||||
var item = ItemData.Get<SimpleCommodityData>(data);
|
||||
if (item != null)
|
||||
{
|
||||
var newItem = new SimpleCommodity
|
||||
{
|
||||
Context = this,
|
||||
Data = data,
|
||||
Quantity = count
|
||||
};
|
||||
Cache.Add(newItem);
|
||||
//ItemData.Add(newItem);
|
||||
return newItem;
|
||||
}
|
||||
|
||||
|
|
@ -598,14 +431,14 @@ public class GameContext
|
|||
|
||||
public CraftedItemInstance CreateInstance(Guid data, float qualityMin, float qualityMax)
|
||||
{
|
||||
var item = Cache.Get<CraftedItemData>(data);
|
||||
var item = ItemData.Get<CraftedItemData>(data);
|
||||
if (item == null)
|
||||
{
|
||||
_logger("Attempted to create crafted item instance using missing or incorrect item id!");
|
||||
return null;
|
||||
}
|
||||
|
||||
var blueprint = Cache.GetAll<BlueprintData>().FirstOrDefault(b => b.Item == data);
|
||||
var blueprint = ItemData.GetAll<BlueprintData>().FirstOrDefault(b => b.Item == data);
|
||||
if (blueprint == null)
|
||||
{
|
||||
_logger("Attempted to create crafted item instance which has no blueprint!");
|
||||
|
|
@ -617,7 +450,7 @@ public class GameContext
|
|||
var ingredients = new List<ItemInstance>();
|
||||
foreach (var ingredient in blueprint.Ingredients)
|
||||
{
|
||||
var itemData = Cache.Get<ItemData>(ingredient.Key);
|
||||
var itemData = ItemData.Get<ItemData>(ingredient.Key);
|
||||
if (itemData is SimpleCommodityData)
|
||||
{
|
||||
var itemInstance = CreateInstance(ingredient.Key, ingredient.Value);
|
||||
|
|
@ -651,69 +484,63 @@ public class GameContext
|
|||
_logger($"Unable to create crafted item ingredient: {invalidIngredient?.Name??"null"} for item {item.Name}");
|
||||
}
|
||||
|
||||
Cache.AddAll(ingredients);
|
||||
|
||||
if (item is EquippableItemData equippableItemData)
|
||||
{
|
||||
var newGear = new Gear
|
||||
var newGear = new EquippableItem
|
||||
{
|
||||
Context = this,
|
||||
Data = data,
|
||||
Ingredients = ingredients.Select(i=>i.ID).ToList(),
|
||||
Ingredients = ingredients,
|
||||
Quality = Random.NextFloat(qualityMin, qualityMax),
|
||||
Blueprint = blueprint.ID,
|
||||
Name = $"{item.Name}"
|
||||
};
|
||||
newGear.Durability = Evaluate(equippableItemData.Durability, newGear);
|
||||
Cache.Add(newGear);
|
||||
newGear.Durability = equippableItemData.Durability;
|
||||
return newGear;
|
||||
}
|
||||
|
||||
var newCommodity = new CompoundCommodity
|
||||
{
|
||||
Context = this,
|
||||
Data = data,
|
||||
Ingredients = ingredients.Select(i=>i.ID).ToList(),
|
||||
Ingredients = ingredients,
|
||||
Quality = Random.NextFloat(qualityMin, qualityMax),
|
||||
Blueprint = blueprint.ID,
|
||||
Name = $"{item.Name}"
|
||||
};
|
||||
Cache.Add(newCommodity);
|
||||
return newCommodity;
|
||||
}
|
||||
|
||||
class DijkstraNode
|
||||
{
|
||||
public float Cost;
|
||||
public DijkstraNode Parent;
|
||||
public ZoneDefinition Zone;
|
||||
}
|
||||
|
||||
public List<ZoneDefinition> FindPath(ZoneDefinition source, ZoneDefinition target, bool bestFirst = false)
|
||||
{
|
||||
SortedList<float,DijkstraNode> members = new SortedList<float,DijkstraNode>{{0,new DijkstraNode{Zone = source}}};
|
||||
List<DijkstraNode> searched = new List<DijkstraNode>();
|
||||
while (true)
|
||||
{
|
||||
var s = members.FirstOrDefault(m => !searched.Contains(m.Value)).Value; // Lowest cost unsearched node
|
||||
if (s == null) return null; // No vertices left unsearched
|
||||
if (s.Zone == target) // We found the path
|
||||
{
|
||||
Stack<DijkstraNode> path = new Stack<DijkstraNode>(); // Since we start at the end, use a LIFO collection
|
||||
path.Push(s);
|
||||
while(path.Peek().Parent!=null) // Keep pushing until we reach the start, which has no parent
|
||||
path.Push(path.Peek().Parent);
|
||||
return path.Select(dv => dv.Zone).ToList();
|
||||
}
|
||||
// For each adjacent star (filter already visited zones unless heuristic is in use)
|
||||
foreach (var dijkstraStar in s.Zone.Links.WhereSelectF(i => !bestFirst || members.All(m => m.Value.Zone != GalaxyZones[i]),
|
||||
// Cost is parent cost plus distance
|
||||
i => new DijkstraNode {Parent = s, Zone = GalaxyZones[i], Cost = s.Cost + length(s.Zone.Position - GalaxyZones[i].Position)}))
|
||||
// Add new member to list, sorted by cost plus optional heuristic
|
||||
members.Add(bestFirst ? dijkstraStar.Cost + length(dijkstraStar.Zone.Position - target.Position) : dijkstraStar.Cost, dijkstraStar);
|
||||
searched.Add(s);
|
||||
}
|
||||
}
|
||||
// class DijkstraNode
|
||||
// {
|
||||
// public float Cost;
|
||||
// public DijkstraNode Parent;
|
||||
// public ZoneDefinition Zone;
|
||||
// }
|
||||
//
|
||||
// public List<ZoneDefinition> FindPath(ZoneDefinition source, ZoneDefinition target, bool bestFirst = false)
|
||||
// {
|
||||
// SortedList<float,DijkstraNode> members = new SortedList<float,DijkstraNode>{{0,new DijkstraNode{Zone = source}}};
|
||||
// List<DijkstraNode> searched = new List<DijkstraNode>();
|
||||
// while (true)
|
||||
// {
|
||||
// var s = members.FirstOrDefault(m => !searched.Contains(m.Value)).Value; // Lowest cost unsearched node
|
||||
// if (s == null) return null; // No vertices left unsearched
|
||||
// if (s.Zone == target) // We found the path
|
||||
// {
|
||||
// Stack<DijkstraNode> path = new Stack<DijkstraNode>(); // Since we start at the end, use a LIFO collection
|
||||
// path.Push(s);
|
||||
// while(path.Peek().Parent!=null) // Keep pushing until we reach the start, which has no parent
|
||||
// path.Push(path.Peek().Parent);
|
||||
// return path.Select(dv => dv.Zone).ToList();
|
||||
// }
|
||||
// // For each adjacent star (filter already visited zones unless heuristic is in use)
|
||||
// foreach (var dijkstraStar in s.Zone.Links.WhereSelectF(i => !bestFirst || members.All(m => m.Value.Zone != GalaxyZones[i]),
|
||||
// // Cost is parent cost plus distance
|
||||
// i => new DijkstraNode {Parent = s, Zone = GalaxyZones[i], Cost = s.Cost + length(s.Zone.Position - GalaxyZones[i].Position)}))
|
||||
// // Add new member to list, sorted by cost plus optional heuristic
|
||||
// members.Add(bestFirst ? dijkstraStar.Cost + length(dijkstraStar.Zone.Position - target.Position) : dijkstraStar.Cost, dijkstraStar);
|
||||
// searched.Add(s);
|
||||
// }
|
||||
// }
|
||||
|
||||
// public bool MoveCargo(Entity source, Entity target, ItemInstance item, int quantity = int.MaxValue)
|
||||
// {
|
||||
|
|
@ -46,6 +46,47 @@ public class Float2Formatter : MessagePack.Formatters.IMessagePackFormatter<floa
|
|||
}
|
||||
}
|
||||
|
||||
public class Int2Formatter : MessagePack.Formatters.IMessagePackFormatter<int2>
|
||||
{
|
||||
public void Serialize(ref MessagePackWriter writer, int2 value, MessagePackSerializerOptions options)
|
||||
{
|
||||
writer.WriteArrayHeader(2);
|
||||
writer.Write(value.x);
|
||||
writer.Write(value.y);
|
||||
}
|
||||
|
||||
public int2 Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
|
||||
{
|
||||
if (reader.IsNil)
|
||||
{
|
||||
throw new InvalidOperationException("typecode is null, struct not supported");
|
||||
}
|
||||
|
||||
var length = reader.ReadArrayHeader();
|
||||
var x = default(int);
|
||||
var y = default(int);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
var key = i;
|
||||
switch (key)
|
||||
{
|
||||
case 0:
|
||||
x = reader.ReadInt32();
|
||||
break;
|
||||
case 1:
|
||||
y = reader.ReadInt32();
|
||||
break;
|
||||
default:
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var result = int2(x, y);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class Float3Formatter : MessagePack.Formatters.IMessagePackFormatter<float3>
|
||||
{
|
||||
public void Serialize(ref MessagePackWriter writer, float3 value, MessagePackSerializerOptions options)
|
||||
|
|
|
|||
|
|
@ -37,25 +37,31 @@ internal static class MathResolverResolverGetFormatterHelper
|
|||
{
|
||||
// standard
|
||||
{ typeof(float2), new Float2Formatter() },
|
||||
{ typeof(int2), new Int2Formatter() },
|
||||
{ typeof(float3), new Float3Formatter() },
|
||||
{ typeof(float4), new Float4Formatter() },
|
||||
{ typeof(float2?), new StaticNullableFormatter<float2>(new Float2Formatter()) },
|
||||
{ typeof(int2?), new StaticNullableFormatter<int2>(new Int2Formatter()) },
|
||||
{ typeof(float3?), new StaticNullableFormatter<float3>(new Float3Formatter()) },
|
||||
{ typeof(float4?), new StaticNullableFormatter<float4>(new Float4Formatter()) },
|
||||
|
||||
// standard + array
|
||||
{ typeof(float2[]), new ArrayFormatter<float2>() },
|
||||
{ typeof(int2[]), new ArrayFormatter<int2>() },
|
||||
{ typeof(float3[]), new ArrayFormatter<float3>() },
|
||||
{ typeof(float4[]), new ArrayFormatter<float4>() },
|
||||
{ typeof(float2?[]), new ArrayFormatter<float2?>() },
|
||||
{ typeof(int2?[]), new ArrayFormatter<float2?>() },
|
||||
{ typeof(float3?[]), new ArrayFormatter<float3?>() },
|
||||
{ typeof(float4?[]), new ArrayFormatter<float4?>() },
|
||||
|
||||
// standard + list
|
||||
{ typeof(List<float2>), new ListFormatter<float2>() },
|
||||
{ typeof(List<int2>), new ListFormatter<int2>() },
|
||||
{ typeof(List<float3>), new ListFormatter<float3>() },
|
||||
{ typeof(List<float4>), new ListFormatter<float4>() },
|
||||
{ typeof(List<float2?>), new ListFormatter<float2?>() },
|
||||
{ typeof(List<int2?>), new ListFormatter<int2?>() },
|
||||
{ typeof(List<float3?>), new ListFormatter<float3?>() },
|
||||
{ typeof(List<float4?>), new ListFormatter<float4?>() },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ public class GalaxyResponseMessage : Message
|
|||
{
|
||||
[Key(0)] public ZoneDefinition[] Zones;
|
||||
[Key(1)] public GalaxyMapLayerData StarDensity;
|
||||
[Key(2)] public GlobalData GlobalData;
|
||||
// [Key(2)] public GlobalData GlobalData;
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ public class OrbitalEntity : Entity
|
|||
{
|
||||
public Guid OrbitData;
|
||||
|
||||
public OrbitalEntity(GameContext context, Guid hull, IEnumerable<Guid> gear, IEnumerable<Guid> cargo, Guid orbit, Zone zone, Guid corporation) : base(context, hull, gear, cargo, zone, corporation)
|
||||
public OrbitalEntity(ItemManager itemManager, Zone zone, EquippableItem hull, Guid orbit) : base(itemManager, zone, hull)
|
||||
{
|
||||
OrbitData = orbit;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,3 +80,18 @@ public class ZoneGenerationSettings
|
|||
public ExponentialLerp GasGiantBandSaturation;
|
||||
public ExponentialLerp GasGiantBandBrightness;
|
||||
}
|
||||
|
||||
[Serializable, MessagePackObject(keyAsPropertyName: true), JsonObject]
|
||||
public class GameplaySettings
|
||||
{
|
||||
public float WarpDistance = 25;
|
||||
public float DockingDistance = 25;
|
||||
public int SignificantDigits = 3;
|
||||
public float ProductionPersonalityLerp = .05f;
|
||||
public float MessageDuration = 4f;
|
||||
public float TargetPersistenceDuration = 3;
|
||||
public ExponentialLerp StartingGearQuality;
|
||||
public float HeatRadiationExponent = 1;
|
||||
public float HeatRadiationMultiplier = 1;
|
||||
|
||||
}
|
||||
|
|
@ -17,10 +17,9 @@ public class Ship : Entity
|
|||
|
||||
// [IgnoreMember] public Dictionary<Targetable, float> Contacts = new Dictionary<Targetable, float>();
|
||||
// [IgnoreMember] public Targetable Target;
|
||||
[JsonProperty("homeEntity"), Key(19)]
|
||||
public Guid HomeEntity;
|
||||
public Entity HomeEntity;
|
||||
|
||||
public Ship(GameContext context, Guid hull, IEnumerable<Guid> gear, IEnumerable<Guid> cargo, Zone zone, Guid corporation) : base(context, hull, gear, cargo, zone, corporation)
|
||||
public Ship(ItemManager itemManager, Zone zone, EquippableItem hull) : base(itemManager, zone, hull)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ using Random = Unity.Mathematics.Random;
|
|||
public class Zone
|
||||
{
|
||||
//public HashSet<Guid> Planets = new HashSet<Guid>();
|
||||
public Dictionary<Guid, Entity> Entities = new Dictionary<Guid, Entity>();
|
||||
public List<Entity> Entities = new List<Entity>();
|
||||
//public Dictionary<Guid, OrbitData> Orbits = new Dictionary<Guid, OrbitData>();
|
||||
public Dictionary<Guid, BodyData> Planets = new Dictionary<Guid, BodyData>();
|
||||
public Dictionary<Guid, Planet> PlanetInstances = new Dictionary<Guid, Planet>();
|
||||
|
|
@ -55,7 +55,7 @@ public class Zone
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var entity in pack.Entities) Entities.Add(entity.ID, entity);
|
||||
foreach (var entity in pack.Entities) Entities.Add(entity);
|
||||
|
||||
// TODO: Associate planets with stored entities for planetary colonies
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ public class Zone
|
|||
return new ZonePack
|
||||
{
|
||||
Data = Data,
|
||||
Entities = Entities.Values.ToList(),
|
||||
Entities = Entities,
|
||||
Orbits = Orbits.Values.Select(o=>o.Data).ToList(),
|
||||
Planets = Planets.Values.ToList()
|
||||
};
|
||||
|
|
@ -90,7 +90,7 @@ public class Zone
|
|||
foreach (var asteroids in AsteroidBelts.Keys)
|
||||
UpdateAsteroidTransforms(asteroids);
|
||||
|
||||
foreach (var entity in Entities.Values) entity.Update(deltaTime);
|
||||
foreach (var entity in Entities) entity.Update(deltaTime);
|
||||
}
|
||||
|
||||
public float2 WormholePosition(ZoneDefinition target)
|
||||
|
|
@ -236,29 +236,30 @@ public class Zone
|
|||
belt.Damage[asteroid] = 0;
|
||||
belt.Damage[asteroid] = belt.Damage[asteroid] + damage;
|
||||
|
||||
if (!belt.MiningAccumulator.ContainsKey((miner.ID, asteroid)))
|
||||
belt.MiningAccumulator[(miner.ID, asteroid)] = 0;
|
||||
belt.MiningAccumulator[(miner.ID, asteroid)] = belt.MiningAccumulator[(miner.ID, asteroid)] + damage;
|
||||
if (!belt.MiningAccumulator.ContainsKey((miner, asteroid)))
|
||||
belt.MiningAccumulator[(miner, asteroid)] = 0;
|
||||
belt.MiningAccumulator[(miner, asteroid)] = belt.MiningAccumulator[(miner, asteroid)] + damage;
|
||||
|
||||
if (belt.Damage[asteroid] > asteroidHitpoints)
|
||||
{
|
||||
belt.RespawnTimers[asteroid] = _settings.AsteroidRespawnTime.Evaluate(size);
|
||||
belt.Damage.Remove(asteroid);
|
||||
belt.MiningAccumulator.Remove((miner.ID, asteroid));
|
||||
belt.MiningAccumulator.Remove((miner, asteroid));
|
||||
return;
|
||||
}
|
||||
|
||||
var resourceCount = beltData.Resources.Sum(x => x.Value);
|
||||
var resource = beltData.Resources.MaxBy(x => pow(x.Value, 1f / penetration) * _random.NextFloat());
|
||||
if (efficiency * _random.NextFloat() * belt.MiningAccumulator[(miner.ID, asteroid)] * resourceCount / _settings.MiningDifficulty > 1 && miner.OccupiedCapacity < miner.Capacity - 1)
|
||||
if (efficiency * _random.NextFloat() * belt.MiningAccumulator[(miner, asteroid)] * resourceCount / _settings.MiningDifficulty > 1)
|
||||
{
|
||||
belt.MiningAccumulator.Remove((miner.ID, asteroid));
|
||||
var newSimpleCommodity = new SimpleCommodity
|
||||
{
|
||||
Data = resource.Key,
|
||||
Quantity = 1
|
||||
};
|
||||
miner.AddCargo(newSimpleCommodity);
|
||||
belt.MiningAccumulator.Remove((miner, asteroid));
|
||||
// var newSimpleCommodity = new SimpleCommodity
|
||||
// {
|
||||
// Data = resource.Key,
|
||||
// Quantity = 1
|
||||
// };
|
||||
// TODO: Drop item onto the Grid
|
||||
//miner.AddCargo(newSimpleCommodity);
|
||||
}
|
||||
}
|
||||
public float GetHeight(float2 position)
|
||||
|
|
@ -393,7 +394,7 @@ public class AsteroidBelt
|
|||
public float4[] PreviousTransforms; // x, y, rotation, scale
|
||||
public Dictionary<int, float> RespawnTimers = new Dictionary<int, float>();
|
||||
public Dictionary<int, float> Damage = new Dictionary<int, float>();
|
||||
public Dictionary<(Guid, int), float> MiningAccumulator = new Dictionary<(Guid, int), float>();
|
||||
public Dictionary<(Entity, int), float> MiningAccumulator = new Dictionary<(Entity, int), float>();
|
||||
|
||||
public AsteroidBelt(AsteroidBeltData data)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,24 +11,24 @@ using Random = Unity.Mathematics.Random;
|
|||
|
||||
public class ZoneGenerator
|
||||
{
|
||||
public static ZonePack GenerateZone(
|
||||
ZoneGenerationSettings settings,
|
||||
Dictionary<string,GalaxyMapLayerData> mapLayers,
|
||||
IEnumerable<SimpleCommodityData> resources,
|
||||
string name,
|
||||
float2 position)
|
||||
{
|
||||
var random = new Random(Convert.ToUInt32(abs(name.GetHashCode())));
|
||||
var radius = settings.ZoneRadius.Evaluate(random.NextFloat() * mapLayers["Radius"].Evaluate(position, settings.ShapeSettings));
|
||||
var mass = settings.ZoneMass.Evaluate(random.NextFloat() * mapLayers["Mass"].Evaluate(position, settings.ShapeSettings));
|
||||
|
||||
return GenerateZone(settings, mapLayers, resources, name, position, mass, radius, random);
|
||||
}
|
||||
// public static ZonePack GenerateZone(
|
||||
// ZoneGenerationSettings settings,
|
||||
// Dictionary<string,GalaxyMapLayerData> mapLayers,
|
||||
// IEnumerable<SimpleCommodityData> resources,
|
||||
// string name,
|
||||
// float2 position)
|
||||
// {
|
||||
// var random = new Random(Convert.ToUInt32(abs(name.GetHashCode())));
|
||||
// var radius = settings.ZoneRadius.Evaluate(random.NextFloat() * mapLayers["Radius"].Evaluate(position, settings.ShapeSettings));
|
||||
// var mass = settings.ZoneMass.Evaluate(random.NextFloat() * mapLayers["Mass"].Evaluate(position, settings.ShapeSettings));
|
||||
//
|
||||
// return GenerateZone(settings, mapLayers, resources, name, position, mass, radius, random);
|
||||
// }
|
||||
|
||||
public static ZonePack GenerateZone(
|
||||
ZoneGenerationSettings settings,
|
||||
Dictionary<string,GalaxyMapLayerData> mapLayers,
|
||||
IEnumerable<SimpleCommodityData> resources,
|
||||
// Dictionary<string,GalaxyMapLayerData> mapLayers,
|
||||
// IEnumerable<SimpleCommodityData> resources,
|
||||
float mass,
|
||||
float radius)
|
||||
{
|
||||
|
|
@ -36,13 +36,13 @@ public class ZoneGenerator
|
|||
var position = float2(0f);
|
||||
var random = new Random(Convert.ToUInt32(abs(name.GetHashCode())));
|
||||
|
||||
return GenerateZone(settings, mapLayers, resources, name, position, mass, radius, random);
|
||||
return GenerateZone(settings, name, position, mass, radius, random);
|
||||
}
|
||||
|
||||
private static ZonePack GenerateZone(
|
||||
ZoneGenerationSettings settings,
|
||||
Dictionary<string,GalaxyMapLayerData> mapLayers,
|
||||
IEnumerable<SimpleCommodityData> resources,
|
||||
// Dictionary<string,GalaxyMapLayerData> mapLayers,
|
||||
// IEnumerable<SimpleCommodityData> resources,
|
||||
string name,
|
||||
float2 position,
|
||||
float mass,
|
||||
|
|
@ -92,25 +92,25 @@ public class ZoneGenerator
|
|||
: Guid.Empty;
|
||||
|
||||
// Cache resource densities
|
||||
var resourceMaps = mapLayers.Values
|
||||
.ToDictionary(m => m.ID, m => m.Evaluate(zone.Position, settings.ShapeSettings));
|
||||
// var resourceMaps = mapLayers.Values
|
||||
// .ToDictionary(m => m.ID, m => m.Evaluate(zone.Position, settings.ShapeSettings));
|
||||
|
||||
pack.Planets = planets.Where(p=>!p.Empty).Select(planet =>
|
||||
{
|
||||
Dictionary<Guid, float> planetResources = new Dictionary<Guid, float>();
|
||||
// Dictionary<Guid, float> planetResources = new Dictionary<Guid, float>();
|
||||
BodyType bodyType = planet.Belt ? BodyType.Asteroid :
|
||||
planet.Mass > settings.SunMass ? BodyType.Sun :
|
||||
planet.Mass > settings.GasGiantMass ? BodyType.GasGiant :
|
||||
planet.Mass > settings.PlanetMass ? BodyType.Planet : BodyType.Planetoid;
|
||||
|
||||
foreach (var r in resources)
|
||||
{
|
||||
if ((bodyType & r.ResourceBodyType) != 0)
|
||||
{
|
||||
float quantity = ResourceValue(ref random, settings, r, r.ResourceDensity.Aggregate(1f, (m, rdm) => m * resourceMaps[rdm]));
|
||||
if (r.Floor < quantity) planetResources.Add(r.ID, quantity);
|
||||
}
|
||||
}
|
||||
// foreach (var r in resources)
|
||||
// {
|
||||
// if ((bodyType & r.ResourceBodyType) != 0)
|
||||
// {
|
||||
// float quantity = ResourceValue(ref random, settings, r, r.ResourceDensity.Aggregate(1f, (m, rdm) => m * resourceMaps[rdm]));
|
||||
// if (r.Floor < quantity) planetResources.Add(r.ID, quantity);
|
||||
// }
|
||||
// }
|
||||
|
||||
BodyData planetData;
|
||||
switch (bodyType)
|
||||
|
|
@ -134,7 +134,7 @@ public class ZoneGenerator
|
|||
|
||||
planetData.Mass.Value = planet.Mass;
|
||||
planetData.Orbit = orbitMap[planet].ID;
|
||||
planetData.Resources = planetResources;
|
||||
// planetData.Resources = planetResources;
|
||||
planetData.Name.Value = planetData.ID.ToString().Substring(0, 8);
|
||||
if (planetData is AsteroidBeltData beltData)
|
||||
{
|
||||
|
|
@ -199,11 +199,11 @@ public class ZoneGenerator
|
|||
return pack;
|
||||
}
|
||||
|
||||
static float ResourceValue(ref Random random, ZoneGenerationSettings settings, SimpleCommodityData resource, float density)
|
||||
{
|
||||
return random.NextPowerDistribution(resource.Minimum, resource.Maximum, resource.Exponent,
|
||||
1 / lerp(settings.ResourceDensityMinimum, settings.ResourceDensityMaximum, density));
|
||||
}
|
||||
// static float ResourceValue(ref Random random, ZoneGenerationSettings settings, SimpleCommodityData resource, float density)
|
||||
// {
|
||||
// return random.NextPowerDistribution(resource.Minimum, resource.Maximum, resource.Exponent,
|
||||
// 1 / lerp(settings.ResourceDensityMinimum, settings.ResourceDensityMaximum, density));
|
||||
// }
|
||||
|
||||
public static GeneratorPlanet[] GenerateEntities(ZoneGenerationSettings settings, ref Random random, ZoneData zone)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue