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:
Reinier Vens 2020-12-10 23:20:38 +00:00
commit f643f6cc8a
330 changed files with 24242 additions and 2830 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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)]

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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)];
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
});
}
}