Action Bar (WIP)
Refactor item instance to use DatabaseLink Labels now pop up when aiming at loot Yeeted HUD trigger group UI into the abyss Created rebindable action bar (missing: assigning actions) Created Consumable Items Refactored behaviors to work on consumable items Implemented Velocity Conversion Behavior
This commit is contained in:
parent
282035dd25
commit
4489b18452
217 changed files with 5105 additions and 5703 deletions
|
|
@ -28,6 +28,16 @@ public static class AetheriaMath
|
|||
return lerp(a, b, 1 - exp(-lambda * dt));
|
||||
}
|
||||
|
||||
public static float2 Damp(float2 a, float2 b, float lambda, float dt)
|
||||
{
|
||||
return lerp(a, b, 1 - exp(-lambda * dt));
|
||||
}
|
||||
|
||||
public static float3 Damp(float3 a, float3 b, float lambda, float dt)
|
||||
{
|
||||
return lerp(a, b, 1 - exp(-lambda * dt));
|
||||
}
|
||||
|
||||
//first-order intercept using absolute target position
|
||||
public static float3 FirstOrderIntercept
|
||||
(
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public class Minion : Agent
|
|||
Ship.VisibleHostiles.ObserveAdd().Where(_ => Ship.Target.Value == null).Subscribe(add => Ship.Target.Value = add.Value);
|
||||
|
||||
var combatState = new CombatState(this);
|
||||
_rootState.AddTransition(combatState,
|
||||
_rootState.AddTransition(combatState,
|
||||
() => Ship.Target.Value != null, null, true, _rootState);
|
||||
|
||||
combatState.AddTransition(_rootState,
|
||||
|
|
|
|||
|
|
@ -37,23 +37,26 @@ public class AetherDriveData : BehaviorData
|
|||
[Inspectable, JsonProperty("passiveCoupling"), Key(9), RuntimeInspectable]
|
||||
public PerformanceStat PassiveCoupling;
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new AetherDrive(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new AetherDrive(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class AetherDrive : IBehavior
|
||||
public class AetherDrive : Behavior
|
||||
{
|
||||
private AetherDriveData _data;
|
||||
private float3 _axis;
|
||||
|
||||
public EquippedItem Item { get; }
|
||||
public float3 Thrust { get; private set; }
|
||||
public float3 Rpm { get; private set; }
|
||||
public float MaximumRpm { get; private set; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
public AetherDriveData DriveData => _data;
|
||||
|
||||
public float3 Axis
|
||||
|
|
@ -62,54 +65,58 @@ public class AetherDrive : IBehavior
|
|||
set => _axis = clamp(value, -1, 1);
|
||||
}
|
||||
|
||||
public AetherDrive(AetherDriveData data, EquippedItem item)
|
||||
public AetherDrive(AetherDriveData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public AetherDrive(AetherDriveData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
var rotorSpeed = Rpm * _data.RotorDiameter / 100;
|
||||
|
||||
var forward = normalize(Item.Entity.Direction);
|
||||
var forward = normalize(Entity.Direction);
|
||||
var right = forward.Rotate(ItemRotation.Clockwise);
|
||||
|
||||
var speed = float2(dot(Item.Entity.Velocity, forward), dot(Item.Entity.Velocity, right));
|
||||
var couplingEfficiency = Item.Evaluate(_data.CouplingEfficiency);
|
||||
var speed = float2(dot(Entity.Velocity, forward), dot(Entity.Velocity, right));
|
||||
var couplingEfficiency = Evaluate(_data.CouplingEfficiency);
|
||||
var efficiency = float3(saturate(1 - speed / max(rotorSpeed.xy, 1) * sign(_axis.xy)) * couplingEfficiency, 1);
|
||||
|
||||
Thrust = (Rpm - AetheriaMath.Decay(Rpm, _data.CouplingLambda, dt)) * _data.RotorMass * efficiency;
|
||||
|
||||
var couplingLambda = _data.CouplingLambda * max(abs(_axis), Item.Evaluate(_data.PassiveCoupling));
|
||||
var couplingLambda = _data.CouplingLambda * max(abs(_axis), Evaluate(_data.PassiveCoupling));
|
||||
var previousRpm = Rpm;
|
||||
Rpm = AetheriaMath.Decay(Rpm, couplingLambda, dt);
|
||||
var rpmLoss = previousRpm - Rpm;
|
||||
var force = rpmLoss * _data.RotorMass * efficiency;
|
||||
|
||||
var heat = rpmLoss * _data.RotorMass * (1 - couplingEfficiency);
|
||||
Item.AddHeat((heat.x + heat.y + heat.z)*Item.ItemManager.GameplaySettings.AetherHeatMultiplier);
|
||||
AddHeat((heat.x + heat.y + heat.z)*ItemManager.GameplaySettings.AetherHeatMultiplier);
|
||||
|
||||
Item.Entity.Velocity += forward * (_axis.x * force.x / Item.Entity.Mass);
|
||||
Item.Entity.Velocity += right * (_axis.y * force.y / Item.Entity.Mass);
|
||||
Item.Entity.Direction = mul(Item.Entity.Direction,
|
||||
Unity.Mathematics.float2x2.Rotate(force.z * _axis.z * Item.ItemManager.GameplaySettings.AetherTorqueMultiplier / Item.Entity.Mass));
|
||||
Entity.Velocity += forward * (_axis.x * force.x / Entity.Mass);
|
||||
Entity.Velocity += right * (_axis.y * force.y / Entity.Mass);
|
||||
Entity.Direction = mul(Entity.Direction,
|
||||
Unity.Mathematics.float2x2.Rotate(force.z * _axis.z * ItemManager.GameplaySettings.AetherTorqueMultiplier / Entity.Mass));
|
||||
|
||||
if(float.IsNaN(Item.Entity.Velocity.x))
|
||||
Item.ItemManager.Log("FUCK FUCK FUCK FUCK");
|
||||
if(float.IsNaN(Entity.Velocity.x))
|
||||
ItemManager.Log("FUCK FUCK FUCK FUCK");
|
||||
|
||||
MaximumRpm = Item.Evaluate(_data.MaximumRpm);
|
||||
MaximumRpm = Evaluate(_data.MaximumRpm);
|
||||
var torqueProfile = float3(
|
||||
_data.TorqueProfile.Evaluate(Rpm.x / MaximumRpm),
|
||||
_data.TorqueProfile.Evaluate(Rpm.y / MaximumRpm),
|
||||
_data.TorqueProfile.Evaluate(Rpm.z / MaximumRpm));
|
||||
var potentialTorque = Item.Evaluate(_data.Torque) * torqueProfile;
|
||||
var potentialTorque = Evaluate(_data.Torque) * torqueProfile;
|
||||
var potentialRpmDelta = potentialTorque / length(_data.RotorMass) * dt;
|
||||
var actualRpmDelta = min(MaximumRpm - Rpm, potentialRpmDelta);
|
||||
var torqueRatio = actualRpmDelta / potentialRpmDelta;
|
||||
var draw = torqueRatio * Item.Evaluate(_data.EnergyDraw) / 3;
|
||||
var draw = torqueRatio * Evaluate(_data.EnergyDraw) / 3;
|
||||
|
||||
if (Item.Entity.TryConsumeEnergy((draw.x + draw.y + draw.z)*dt))
|
||||
if (Entity.TryConsumeEnergy((draw.x + draw.y + draw.z)*dt))
|
||||
{
|
||||
Rpm += actualRpmDelta;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ using static Unity.Mathematics.math;
|
|||
[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn), RuntimeInspectable]
|
||||
public class AutoWeaponData : InstantWeaponData
|
||||
{
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new AutoWeapon(this, item);
|
||||
}
|
||||
|
|
@ -18,9 +18,8 @@ public class AutoWeaponData : InstantWeaponData
|
|||
public class AutoWeapon : InstantWeapon
|
||||
{
|
||||
|
||||
public AutoWeapon(InstantWeaponData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
}
|
||||
public AutoWeapon(InstantWeaponData data, EquippedItem item) : base(data, item) { }
|
||||
public AutoWeapon(InstantWeaponData data, ConsumableItemEffect item) : base(data, item) { }
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,28 +13,94 @@ using Unity.Mathematics;
|
|||
using static Unity.Mathematics.math;
|
||||
using static Unity.Mathematics.noise;
|
||||
|
||||
public interface IBehavior
|
||||
public abstract class Behavior
|
||||
{
|
||||
bool Execute(float dt);
|
||||
BehaviorData Data { get; }
|
||||
public BehaviorData Data { get; }
|
||||
public EquippedItem Item { get; }
|
||||
private ConsumableItemEffect Consumable { get; }
|
||||
protected ItemManager ItemManager { get; }
|
||||
|
||||
protected Entity Entity => Item?.Entity ?? Consumable.Entity;
|
||||
public float Temperature => Item?.Temperature ?? Consumable.Entity.MaxTemp;
|
||||
|
||||
public float3 Direction
|
||||
{
|
||||
get
|
||||
{
|
||||
if(Item != null)
|
||||
{
|
||||
var hardpoint = Entity.Hardpoints[Item.Position.x, Item.Position.y];
|
||||
if (hardpoint != null && Entity.HardpointTransforms.ContainsKey(hardpoint))
|
||||
{
|
||||
return normalize(Entity.HardpointTransforms[hardpoint].direction);
|
||||
}
|
||||
else
|
||||
{
|
||||
var itemDirection = Entity.Direction.Rotate(Item.EquippableItem.Rotation);
|
||||
return float3(itemDirection.x, 0, itemDirection.y);
|
||||
}
|
||||
}
|
||||
|
||||
return float3(Entity.Direction.x, 0, Entity.Direction.y);
|
||||
}
|
||||
}
|
||||
|
||||
protected Behavior(BehaviorData data, EquippedItem item)
|
||||
{
|
||||
Data = data;
|
||||
Item = item;
|
||||
ItemManager = Item.ItemManager;
|
||||
}
|
||||
|
||||
protected Behavior(BehaviorData data, ConsumableItemEffect consumable)
|
||||
{
|
||||
Data = data;
|
||||
Consumable = consumable;
|
||||
ItemManager = consumable.Entity.ItemManager;
|
||||
}
|
||||
|
||||
public float Evaluate(PerformanceStat stat) => Item?.Evaluate(stat) ?? Consumable.Evaluate(stat);
|
||||
protected void AddHeat(float heat) => Item?.AddHeat(heat); // TODO: Heat for Consumables
|
||||
|
||||
protected void CauseDamage(float damage)
|
||||
{
|
||||
if (Item != null)
|
||||
{
|
||||
Item.EquippableItem.Durability -= damage;
|
||||
Entity.ItemDamage.OnNext((Item, damage));
|
||||
}
|
||||
else
|
||||
{
|
||||
Consumable.Entity.Hull.Durability -= damage;
|
||||
Consumable.Entity.HullDamage.OnNext(damage);
|
||||
}
|
||||
}
|
||||
|
||||
protected void CauseWearDamage(float multiplier)
|
||||
{
|
||||
if (Item != null)
|
||||
{
|
||||
CauseDamage(Item.Wear * multiplier);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Execute(float dt)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public interface IActivatedBehavior : IBehavior
|
||||
public interface IActivatedBehavior
|
||||
{
|
||||
void Activate();
|
||||
void Deactivate();
|
||||
}
|
||||
|
||||
public interface IAnalogBehavior : IBehavior
|
||||
public interface IAnalogBehavior
|
||||
{
|
||||
float Axis { get; set; }
|
||||
}
|
||||
|
||||
public interface IDisposableBehavior
|
||||
{
|
||||
void Dispose();
|
||||
}
|
||||
|
||||
public interface IEventBehavior
|
||||
{
|
||||
void ResetEvents();
|
||||
|
|
@ -128,12 +194,11 @@ public abstract class BehaviorData
|
|||
[Inspectable, JsonProperty("group"), Key(0)]
|
||||
public int Group;
|
||||
|
||||
public abstract IBehavior CreateInstance(EquippedItem item);
|
||||
public abstract Behavior CreateInstance(EquippedItem item);
|
||||
public abstract Behavior CreateInstance(ConsumableItemEffect consumable);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var className = base.ToString();
|
||||
var dataIndex = className.IndexOf("data", StringComparison.InvariantCultureIgnoreCase);
|
||||
return dataIndex>0 ? className.Substring(0,dataIndex).SplitCamelCase() : className;
|
||||
return base.ToString().FormatTypeName();
|
||||
}
|
||||
}
|
||||
|
|
@ -17,20 +17,21 @@ public class CapacitorData : BehaviorData
|
|||
[Inspectable, JsonProperty("efficiency"), Key(2), RuntimeInspectable]
|
||||
public PerformanceStat Efficiency = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Capacitor(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Capacitor(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Capacitor : IBehavior
|
||||
public class Capacitor : Behavior
|
||||
{
|
||||
private CapacitorData _data;
|
||||
|
||||
public EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public float Charge { get; private set; }
|
||||
public float Capacity { get; private set; }
|
||||
public float Efficiency { get; private set; } = 1;
|
||||
|
|
@ -38,19 +39,23 @@ public class Capacitor : IBehavior
|
|||
public void AddCharge(float charge)
|
||||
{
|
||||
Charge = clamp(Charge + charge, 0, Capacity);
|
||||
Item.AddHeat(abs(charge) * (1-Efficiency));
|
||||
AddHeat(abs(charge) * (1-Efficiency));
|
||||
}
|
||||
|
||||
public Capacitor(CapacitorData data, EquippedItem item)
|
||||
public Capacitor(CapacitorData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public Capacitor(CapacitorData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
Capacity = Item.Evaluate(_data.Capacity);
|
||||
Efficiency = Item.Evaluate(_data.Efficiency);
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
Capacity = Evaluate(_data.Capacity);
|
||||
Efficiency = Evaluate(_data.Efficiency);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -45,13 +45,18 @@ public class ChargedWeaponData : InstantWeaponData
|
|||
[Inspectable, JsonProperty("chargeHeatMul"), Key(32)]
|
||||
public float ChargeFiringHeatMultiplier = 1;
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new ChargedWeapon(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new ChargedWeapon(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class ChargedWeapon : InstantWeapon, IEventBehavior
|
||||
public class ChargedWeapon : InstantWeapon
|
||||
{
|
||||
private ChargedWeaponData _data;
|
||||
private bool _charging;
|
||||
|
|
@ -97,13 +102,18 @@ public class ChargedWeapon : InstantWeapon, IEventBehavior
|
|||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public ChargedWeapon(ChargedWeaponData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
protected override void UpdateStats()
|
||||
{
|
||||
base.UpdateStats();
|
||||
ChargeTime = Item.Evaluate(_data.ChargeTime);
|
||||
ChargeEnergy = Item.Evaluate(_data.ChargeEnergy);
|
||||
ChargeHeat = Item.Evaluate(_data.ChargeHeat);
|
||||
ChargeTime = Evaluate(_data.ChargeTime);
|
||||
ChargeEnergy = Evaluate(_data.ChargeEnergy);
|
||||
ChargeHeat = Evaluate(_data.ChargeHeat);
|
||||
Damage *= lerp(1, _data.ChargeFiringDamageMultiplier, saturate(_charge));
|
||||
Heat *= lerp(1, _data.ChargeFiringHeatMultiplier, saturate(_charge));
|
||||
Spread *= lerp(1, _data.ChargeFiringSpreadMultiplier, saturate(_charge));
|
||||
|
|
@ -119,7 +129,7 @@ public class ChargedWeapon : InstantWeapon, IEventBehavior
|
|||
_charge += dt / ChargeTime;
|
||||
if (!_charged)
|
||||
{
|
||||
Item.AddHeat(ChargeHeat * (dt / ChargeTime));
|
||||
AddHeat(ChargeHeat * (dt / ChargeTime));
|
||||
if(_charge > 1)
|
||||
{
|
||||
_charged = true;
|
||||
|
|
@ -133,7 +143,7 @@ public class ChargedWeapon : InstantWeapon, IEventBehavior
|
|||
_coolingDown = true;
|
||||
_charge = 0;
|
||||
OnFailed?.Invoke();
|
||||
Item.EquippableItem.Durability -= _data.FailureDamage;
|
||||
CauseDamage(_data.FailureDamage);
|
||||
}
|
||||
}
|
||||
return base.Execute(dt);
|
||||
|
|
|
|||
|
|
@ -11,29 +11,27 @@ using static Unity.Mathematics.math;
|
|||
[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn), RuntimeInspectable]
|
||||
public class CockpitData : BehaviorData
|
||||
{
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Cockpit(this, item);
|
||||
}
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Cockpit(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Cockpit : IBehavior
|
||||
public class Cockpit : Behavior
|
||||
{
|
||||
private CockpitData _data;
|
||||
|
||||
public EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
|
||||
public Cockpit(CockpitData data, EquippedItem item)
|
||||
public Cockpit(CockpitData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
|
||||
public Cockpit(CockpitData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
return true;
|
||||
_data = data;
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,12 @@ public class ConstantWeaponData : WeaponData
|
|||
[InspectablePrefab, JsonProperty("ammoInterval"), Key(17)]
|
||||
public float AmmoInterval = 1;
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new ConstantWeapon(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new ConstantWeapon(this, item);
|
||||
}
|
||||
|
|
@ -62,12 +67,17 @@ public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior
|
|||
_data = data;
|
||||
}
|
||||
|
||||
public ConstantWeapon(ConstantWeaponData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
base.Execute(dt);
|
||||
if (_firing)
|
||||
{
|
||||
if (!Item.Entity.TryConsumeEnergy(Item.Evaluate(_data.Energy) * dt))
|
||||
if (!Entity.TryConsumeEnergy(Evaluate(_data.Energy) * dt))
|
||||
{
|
||||
_firing = false;
|
||||
OnStopFiring?.Invoke();
|
||||
|
|
@ -93,7 +103,7 @@ public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior
|
|||
if (_data.MagazineSize > 1 && _ammo > 0) _ammo--;
|
||||
else
|
||||
{
|
||||
var cargo = Item.Entity.FindItemInCargo(_data.AmmoType);
|
||||
var cargo = Entity.FindItemInCargo(_data.AmmoType);
|
||||
if (cargo != null)
|
||||
{
|
||||
var item = cargo.ItemsOfType[_data.AmmoType][0];
|
||||
|
|
@ -115,11 +125,9 @@ public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior
|
|||
}
|
||||
}
|
||||
|
||||
var dmg = Item.Wear * dt;
|
||||
Item.EquippableItem.Durability -= dmg;
|
||||
Item.Entity.ItemDamage.OnNext((Item, dmg));
|
||||
Item.AddHeat(Item.Evaluate(_data.Heat) * dt);
|
||||
Item.Entity.VisibilitySources[this] = Item.Evaluate(_data.Visibility);
|
||||
CauseWearDamage(dt);
|
||||
AddHeat(Evaluate(_data.Heat) * dt);
|
||||
Entity.VisibilitySources[this] = Evaluate(_data.Visibility);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,30 +15,36 @@ public class CooldownData : BehaviorData
|
|||
[Inspectable, JsonProperty("cooldown"), Key(1), RuntimeInspectable]
|
||||
public PerformanceStat Cooldown = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Cooldown(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Cooldown(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Cooldown : IBehavior, IAlwaysUpdatedBehavior, IProgressBehavior
|
||||
public class Cooldown : Behavior, IAlwaysUpdatedBehavior, IProgressBehavior
|
||||
{
|
||||
private CooldownData _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private EquippedItem Item { get; }
|
||||
|
||||
private float _cooldown; // Normalized
|
||||
|
||||
public float Progress => saturate(_cooldown);
|
||||
|
||||
public Cooldown(CooldownData data, EquippedItem item)
|
||||
public Cooldown(CooldownData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public Cooldown(CooldownData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
if (_cooldown < 0)
|
||||
{
|
||||
|
|
@ -47,11 +53,10 @@ public class Cooldown : IBehavior, IAlwaysUpdatedBehavior, IProgressBehavior
|
|||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public void Update(float delta)
|
||||
{
|
||||
_cooldown -= delta / Item.Evaluate(_data.Cooldown);
|
||||
_cooldown -= delta / Evaluate(_data.Cooldown);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,28 +16,33 @@ public class EnergyDrawData : BehaviorData
|
|||
[Inspectable, JsonProperty("perSecond"), Key(2)]
|
||||
public bool PerSecond;
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new EnergyDraw(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new EnergyDraw(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class EnergyDraw : IBehavior
|
||||
public class EnergyDraw : Behavior
|
||||
{
|
||||
private EnergyDrawData _data;
|
||||
|
||||
private EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public EnergyDraw(EnergyDrawData data, EquippedItem item)
|
||||
public EnergyDraw(EnergyDrawData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public EnergyDraw(EnergyDrawData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
return Item.Entity.TryConsumeEnergy(Item.Evaluate(_data.EnergyDraw) * (_data.PerSecond ? dt : 1));
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
return Entity.TryConsumeEnergy(Evaluate(_data.EnergyDraw) * (_data.PerSecond ? dt : 1));
|
||||
}
|
||||
}
|
||||
|
|
@ -16,29 +16,33 @@ public class HeatData : BehaviorData
|
|||
[Inspectable, JsonProperty("perSecond"), Key(2)]
|
||||
public bool PerSecond;
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Heat(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Heat(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Heat : IBehavior
|
||||
public class Heat : Behavior
|
||||
{
|
||||
private HeatData _data;
|
||||
|
||||
private EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public Heat(HeatData data, EquippedItem item)
|
||||
public Heat(HeatData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
public Heat(HeatData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
Item.AddHeat(Item.Evaluate(_data.Heat) * (_data.PerSecond ? dt : 1));
|
||||
AddHeat(Evaluate(_data.Heat) * (_data.PerSecond ? dt : 1));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,28 +11,27 @@ using static Unity.Mathematics.math;
|
|||
[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn), RuntimeInspectable]
|
||||
public class HeatStorageData : BehaviorData
|
||||
{
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new HeatStorage(this, item);
|
||||
}
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new HeatStorage(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class HeatStorage : IBehavior
|
||||
public class HeatStorage : Behavior
|
||||
{
|
||||
private HeatStorageData _data;
|
||||
|
||||
public EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public HeatStorage(HeatStorageData data, EquippedItem item)
|
||||
public HeatStorage(HeatStorageData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public HeatStorage(HeatStorageData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
return true;
|
||||
_data = data;
|
||||
}
|
||||
}
|
||||
|
|
@ -21,7 +21,12 @@ public class InstantWeaponData : WeaponData
|
|||
[InspectablePrefab, JsonProperty("ammoInterval"), Key(20)]
|
||||
public bool SingleAmmoBurst;
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new InstantWeapon(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new InstantWeapon(this, item);
|
||||
}
|
||||
|
|
@ -77,11 +82,17 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior
|
|||
_ammo = data.MagazineSize;
|
||||
}
|
||||
|
||||
public InstantWeapon(InstantWeaponData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
_ammo = data.MagazineSize;
|
||||
}
|
||||
|
||||
protected void Trigger()
|
||||
{
|
||||
// If 1 ammo is consumed per burst, perform ammo and energy consumption here
|
||||
// UseAmmo returns false when triggering reload; cancel firing if that is the case
|
||||
if(_data.SingleAmmoBurst && (!Item.Entity.TryConsumeEnergy(Energy) || !UseAmmo())) return;
|
||||
if(_data.SingleAmmoBurst && (!Entity.TryConsumeEnergy(Energy) || !UseAmmo())) return;
|
||||
|
||||
_burstRemaining = (int) BurstCount;
|
||||
_burstInterval = BurstTime / _burstRemaining;
|
||||
|
|
@ -93,9 +104,9 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior
|
|||
protected override void UpdateStats()
|
||||
{
|
||||
base.UpdateStats();
|
||||
BurstCount = Item.Evaluate(_data.Count);
|
||||
BurstTime = Item.Evaluate(_data.BurstTime);
|
||||
Cooldown = Item.Evaluate(_data.Cooldown);
|
||||
BurstCount = Evaluate(_data.Count);
|
||||
BurstTime = Evaluate(_data.BurstTime);
|
||||
Cooldown = Evaluate(_data.Cooldown);
|
||||
|
||||
Damage /= (int) BurstCount;
|
||||
Heat /= (int) BurstCount;
|
||||
|
|
@ -115,7 +126,7 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior
|
|||
var hasAmmo = true;
|
||||
if (_data.AmmoType != Guid.Empty)
|
||||
{
|
||||
var cargo = Item.Entity.FindItemInCargo(_data.AmmoType);
|
||||
var cargo = Entity.FindItemInCargo(_data.AmmoType);
|
||||
if (cargo != null)
|
||||
{
|
||||
var item = cargo.ItemsOfType[_data.AmmoType][0];
|
||||
|
|
@ -160,7 +171,7 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior
|
|||
{
|
||||
// If multiple ammo is consumed per burst, perform ammo and energy consumption here
|
||||
// UseAmmo returns false when triggering reload; cancel firing if that is the case
|
||||
if (!_data.SingleAmmoBurst && (!Item.Entity.TryConsumeEnergy(Energy) || !UseAmmo()))
|
||||
if (!_data.SingleAmmoBurst && (!Entity.TryConsumeEnergy(Energy) || !UseAmmo()))
|
||||
{
|
||||
_burstRemaining = 0;
|
||||
return false;
|
||||
|
|
@ -169,10 +180,9 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior
|
|||
_burstRemaining--;
|
||||
_burstTimer -= _burstInterval;
|
||||
OnFire?.Invoke();
|
||||
Item.EquippableItem.Durability -= Item.Wear;
|
||||
Item.Entity.ItemDamage.OnNext((Item, Item.Wear));
|
||||
Item.AddHeat(Heat);
|
||||
Item.Entity.VisibilitySources[this] = Visibility;
|
||||
CauseWearDamage(1);
|
||||
AddHeat(Heat);
|
||||
Entity.VisibilitySources[this] = Visibility;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,29 +13,34 @@ public class ItemUsageData : BehaviorData
|
|||
[InspectableDatabaseLink(typeof(SimpleCommodityData)), JsonProperty("item"), Key(1), RuntimeInspectable]
|
||||
public Guid Item;
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new ItemUsage(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new ItemUsage(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class ItemUsage : IBehavior
|
||||
public class ItemUsage : Behavior
|
||||
{
|
||||
private ItemUsageData _data;
|
||||
|
||||
private EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public ItemUsage(ItemUsageData data, EquippedItem item)
|
||||
public ItemUsage(ItemUsageData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public ItemUsage(ItemUsageData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
var cargo = Item.Entity.FindItemInCargo(_data.Item);
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
var cargo = Entity.FindItemInCargo(_data.Item);
|
||||
if (cargo == null) return false;
|
||||
|
||||
var item = cargo.ItemsOfType[_data.Item][0];
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public class LauncherData : LockWeaponData
|
|||
[Inspectable, JsonProperty("missileSpeed"), Key(31), RuntimeInspectable]
|
||||
public PerformanceStat MissileVelocity = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new LockWeapon(this, item);
|
||||
}
|
||||
|
|
@ -54,7 +54,7 @@ public class GuidedWeaponData : InstantWeaponData
|
|||
[Inspectable, JsonProperty("missileSpeed"), Key(26), RuntimeInspectable]
|
||||
public PerformanceStat MissileVelocity = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new InstantWeapon(this, item);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,11 @@ public class LockWeaponData : InstantWeaponData
|
|||
[Inspectable, JsonProperty("decay"), Key(25)]
|
||||
public PerformanceStat Decay = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new LockWeapon(this, item);
|
||||
}
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new LockWeapon(this, item);
|
||||
}
|
||||
|
|
@ -49,7 +53,7 @@ public class LockWeapon : InstantWeapon
|
|||
|
||||
public override float Progress => saturate(_cooldown > 0 ? _cooldown : _lock);
|
||||
|
||||
public override bool CanFire => base.CanFire && _lock > .99f && Item.Entity.TargetRange > MinRange && Item.Entity.TargetRange < Range;
|
||||
public override bool CanFire => base.CanFire && _lock > .99f && Entity.TargetRange > MinRange && Entity.TargetRange < Range;
|
||||
|
||||
public float Lock
|
||||
{
|
||||
|
|
@ -60,28 +64,32 @@ public class LockWeapon : InstantWeapon
|
|||
{
|
||||
_data = data;
|
||||
}
|
||||
public LockWeapon(LockWeaponData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
if (_target != Item.Entity.Target.Value)
|
||||
if (_target != Entity.Target.Value)
|
||||
{
|
||||
_lock = 0;
|
||||
_target = Item.Entity.Target.Value;
|
||||
_target = Entity.Target.Value;
|
||||
}
|
||||
|
||||
if (Item.Entity.Target.Value != null && Item.Entity.Target.Value.IsHostileTo(Item.Entity))
|
||||
if (Entity.Target.Value != null && Entity.Target.Value.IsHostileTo(Entity))
|
||||
{
|
||||
LockSpeed = Item.Evaluate(_data.LockSpeed);
|
||||
SensorImpact = Item.Evaluate(_data.SensorImpact);
|
||||
LockAngle = Item.Evaluate(_data.LockAngle);
|
||||
DirectionImpact = Item.Evaluate(_data.DirectionImpact);
|
||||
Decay = Item.Evaluate(_data.Decay);
|
||||
LockSpeed = Evaluate(_data.LockSpeed);
|
||||
SensorImpact = Evaluate(_data.SensorImpact);
|
||||
LockAngle = Evaluate(_data.LockAngle);
|
||||
DirectionImpact = Evaluate(_data.DirectionImpact);
|
||||
Decay = Evaluate(_data.Decay);
|
||||
|
||||
var degrees = acos(dot(normalize(Item.Entity.Target.Value.Position - Item.Entity.Position), normalize(Item.Entity.LookDirection))) * 57.2958f;
|
||||
var degrees = acos(dot(normalize(Entity.Target.Value.Position - Entity.Position), normalize(Entity.LookDirection))) * 57.2958f;
|
||||
if (degrees < LockAngle)
|
||||
{
|
||||
var lerp = 1 - unlerp(0, 90, degrees);
|
||||
_lock = saturate(_lock + pow(lerp, DirectionImpact) * dt * LockSpeed * pow(Item.Entity.EntityInfoGathered[Item.Entity.Target.Value], SensorImpact));
|
||||
_lock = saturate(_lock + pow(lerp, DirectionImpact) * dt * LockSpeed * pow(Entity.EntityInfoGathered[Entity.Target.Value], SensorImpact));
|
||||
}
|
||||
else _lock = saturate(_lock - dt * Decay);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,45 +24,49 @@ public class MiningToolData : BehaviorData
|
|||
[Inspectable, JsonProperty("range"), Key(4)]
|
||||
public PerformanceStat Range = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new MiningTool(this, item);
|
||||
}
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new MiningTool(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class MiningTool : IBehavior
|
||||
public class MiningTool : Behavior
|
||||
{
|
||||
public Guid AsteroidBelt;
|
||||
public int Asteroid;
|
||||
|
||||
private MiningToolData _data;
|
||||
|
||||
private EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
public float Range { get; private set; }
|
||||
|
||||
public MiningTool(MiningToolData data, EquippedItem item)
|
||||
public MiningTool(MiningToolData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public MiningTool(MiningToolData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
Range = Item.Evaluate(_data.Range);
|
||||
var belt = Item.Entity.Zone.AsteroidBelts[AsteroidBelt];
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
Range = Evaluate(_data.Range);
|
||||
var belt = Entity.Zone.AsteroidBelts[AsteroidBelt];
|
||||
if (AsteroidBelt != Guid.Empty &&
|
||||
Item.Entity.Zone.AsteroidExists(AsteroidBelt, Asteroid) &&
|
||||
length(Item.Entity.Position.xz - belt.Positions[Asteroid].xz) - belt.Scales[Asteroid] < Range)
|
||||
Entity.Zone.AsteroidExists(AsteroidBelt, Asteroid) &&
|
||||
length(Entity.Position.xz - belt.Positions[Asteroid].xz) - belt.Scales[Asteroid] < Range)
|
||||
{
|
||||
Item.Entity.Zone.MineAsteroid(
|
||||
Item.Entity,
|
||||
Entity.Zone.MineAsteroid(
|
||||
Entity,
|
||||
AsteroidBelt,
|
||||
Asteroid,
|
||||
Item.Evaluate(_data.DamagePerSecond) * dt,
|
||||
Item.Evaluate(_data.Efficiency),
|
||||
Item.Evaluate(_data.Penetration));
|
||||
Evaluate(_data.DamagePerSecond) * dt,
|
||||
Evaluate(_data.Efficiency),
|
||||
Evaluate(_data.Penetration));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,19 +25,24 @@ public class RadiatorData : BehaviorData
|
|||
[Inspectable, JsonProperty("energyUsage"), Key(5), RuntimeInspectable]
|
||||
public PerformanceStat EnergyUsage = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
[Inspectable, JsonProperty("thermalMass"), Key(6), RuntimeInspectable]
|
||||
public PerformanceStat ThermalMass = new PerformanceStat();
|
||||
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Radiator(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Radiator(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Radiator : IBehavior, IAlwaysUpdatedBehavior, IInitializableBehavior
|
||||
public class Radiator : Behavior, IAlwaysUpdatedBehavior, IInitializableBehavior
|
||||
{
|
||||
public EquippedItem Item { get; }
|
||||
public float Temperature { get; private set; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public float RadiatorTemperature { get; private set; }
|
||||
|
||||
public float Emissivity { get; private set; }
|
||||
public float PumpedHeat { get; private set; }
|
||||
public float WasteHeat { get; private set; }
|
||||
|
|
@ -45,25 +50,28 @@ public class Radiator : IBehavior, IAlwaysUpdatedBehavior, IInitializableBehavio
|
|||
|
||||
private RadiatorData _data;
|
||||
|
||||
public Radiator(RadiatorData data, EquippedItem item)
|
||||
public Radiator(RadiatorData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
public Radiator(RadiatorData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
PumpedHeat = Item.Evaluate(_data.PumpedHeat);
|
||||
WasteHeat = Item.Evaluate(_data.WasteHeat);
|
||||
EnergyUsage = Item.Evaluate(_data.EnergyUsage);
|
||||
PumpedHeat = Evaluate(_data.PumpedHeat);
|
||||
WasteHeat = Evaluate(_data.WasteHeat);
|
||||
EnergyUsage = Evaluate(_data.EnergyUsage);
|
||||
|
||||
var itemTemperature = Item.Temperature;
|
||||
var tempRatio = max(Temperature / itemTemperature, 1);
|
||||
var itemTemperature = Temperature;
|
||||
var tempRatio = max(RadiatorTemperature / itemTemperature, 1);
|
||||
|
||||
// Temperature ratio would cause more waste heat than pump capacity, stop executing
|
||||
if (tempRatio > PumpedHeat / WasteHeat) return true;
|
||||
|
||||
if (!Item.Entity.TryConsumeEnergy(EnergyUsage * tempRatio * dt)) return false;
|
||||
if (!Entity.TryConsumeEnergy(EnergyUsage * tempRatio * dt)) return false;
|
||||
|
||||
var pumpedHeat = PumpedHeat * max(itemTemperature - _data.TemperatureFloor, 0);
|
||||
|
||||
|
|
@ -72,22 +80,22 @@ public class Radiator : IBehavior, IAlwaysUpdatedBehavior, IInitializableBehavio
|
|||
|
||||
var wasteHeat = WasteHeat * tempRatio;
|
||||
|
||||
Item.AddHeat((wasteHeat - pumpedHeat) * dt);
|
||||
Temperature += pumpedHeat / Item.ItemManager.GetThermalMass(Item.EquippableItem) * dt;
|
||||
AddHeat((wasteHeat - pumpedHeat) * dt);
|
||||
RadiatorTemperature += pumpedHeat / Evaluate(_data.ThermalMass) * dt;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Update(float delta)
|
||||
{
|
||||
Emissivity = Item.Evaluate(_data.Emissivity);
|
||||
var rad = pow(Temperature, Item.ItemManager.GameplaySettings.HeatRadiationExponent) * Item.ItemManager.GameplaySettings.HeatRadiationMultiplier * Emissivity;
|
||||
Temperature -= rad * delta;
|
||||
Item.Entity.VisibilitySources[this] = rad;
|
||||
Emissivity = Evaluate(_data.Emissivity);
|
||||
var rad = pow(RadiatorTemperature, ItemManager.GameplaySettings.HeatRadiationExponent) * ItemManager.GameplaySettings.HeatRadiationMultiplier * Emissivity;
|
||||
RadiatorTemperature -= rad * delta;
|
||||
Entity.VisibilitySources[this] = rad;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
Temperature = Item.Temperature;
|
||||
RadiatorTemperature = Temperature;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MessagePack;
|
||||
|
|
@ -25,45 +26,55 @@ public class ReactorData : BehaviorData
|
|||
[Inspectable, JsonProperty("underload"), Key(4), RuntimeInspectable]
|
||||
public PerformanceStat ThrottlingFactor = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Reactor(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Reactor(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Reactor : IBehavior, IOrderedBehavior
|
||||
public class Reactor : Behavior, IOrderedBehavior, IDisposable
|
||||
{
|
||||
private ReactorData _data;
|
||||
|
||||
public Entity Entity { get; }
|
||||
public EquippedItem Item { get; }
|
||||
public ItemManager Context { get; }
|
||||
|
||||
public float Draw { get; private set; }
|
||||
|
||||
public float CurrentLoadRatio { get; private set; }
|
||||
|
||||
public int Order => 100;
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private List<Capacitor> _capacitors;
|
||||
|
||||
public Reactor(ReactorData data, EquippedItem item)
|
||||
private List<IDisposable> _subscriptions = new List<IDisposable>();
|
||||
|
||||
public Reactor(ReactorData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
_capacitors = Item.Entity.GetBehaviors<Capacitor>().ToList();
|
||||
Item.Entity.Equipment.ObserveAdd().Subscribe(onAdd =>
|
||||
FindCapacitors();
|
||||
}
|
||||
public Reactor(ReactorData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
FindCapacitors();
|
||||
}
|
||||
|
||||
private void FindCapacitors()
|
||||
{
|
||||
_capacitors = Entity.GetBehaviors<Capacitor>().ToList();
|
||||
_subscriptions.Add(Entity.Equipment.ObserveAdd().Subscribe(onAdd =>
|
||||
{
|
||||
var capacitor = onAdd.Value.GetBehavior<Capacitor>();
|
||||
if (capacitor != null) _capacitors.Add(capacitor);
|
||||
});
|
||||
Item.Entity.Equipment.ObserveRemove().Subscribe(onRemove =>
|
||||
}));
|
||||
_subscriptions.Add(Entity.Equipment.ObserveRemove().Subscribe(onRemove =>
|
||||
{
|
||||
var capacitor = onRemove.Value.GetBehavior<Capacitor>();
|
||||
if (capacitor != null) _capacitors.Remove(capacitor);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
public void ConsumeEnergy(float energy)
|
||||
|
|
@ -71,10 +82,10 @@ public class Reactor : IBehavior, IOrderedBehavior
|
|||
Draw += energy;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
var charge = Item.Evaluate(_data.Charge) * dt;
|
||||
var efficiency = Item.Evaluate(_data.Efficiency);
|
||||
var charge = Evaluate(_data.Charge) * dt;
|
||||
var efficiency = Evaluate(_data.Efficiency);
|
||||
|
||||
// This behavior executes last, so any components drawing power have already done so
|
||||
|
||||
|
|
@ -88,7 +99,7 @@ public class Reactor : IBehavior, IOrderedBehavior
|
|||
if (Draw > .01f)
|
||||
{
|
||||
CurrentLoadRatio = (Draw + charge) / max(charge, .01f);
|
||||
var overloadEfficiency = Item.Evaluate(_data.OverloadEfficiency);
|
||||
var overloadEfficiency = Evaluate(_data.OverloadEfficiency);
|
||||
|
||||
// Generate heat using overload efficiency, usually much less efficient!
|
||||
heat += Draw / overloadEfficiency;
|
||||
|
|
@ -121,7 +132,7 @@ public class Reactor : IBehavior, IOrderedBehavior
|
|||
if (Draw < -.01f)
|
||||
{
|
||||
CurrentLoadRatio = (Draw + charge) / max(charge, .01f);
|
||||
heat -= Draw / efficiency * (1 - 1 / Item.Evaluate(_data.ThrottlingFactor));
|
||||
heat -= Draw / efficiency * (1 - 1 / Evaluate(_data.ThrottlingFactor));
|
||||
Draw = 0;
|
||||
}
|
||||
else
|
||||
|
|
@ -129,7 +140,13 @@ public class Reactor : IBehavior, IOrderedBehavior
|
|||
CurrentLoadRatio = 1;
|
||||
}
|
||||
|
||||
Item.AddHeat(heat);
|
||||
AddHeat(heat);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach(var sub in _subscriptions)
|
||||
sub.Dispose();
|
||||
}
|
||||
}
|
||||
|
|
@ -16,29 +16,34 @@ public class ReflectorData : BehaviorData
|
|||
// [InspectableAnimationCurve, JsonProperty("visibility"), Key(1)]
|
||||
// public float4[] VisibilityCurve;
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Reflector(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Reflector(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Reflector : IBehavior
|
||||
public class Reflector : Behavior
|
||||
{
|
||||
public EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private ReflectorData _data;
|
||||
|
||||
public Reflector(ReflectorData data, EquippedItem item)
|
||||
public Reflector(ReflectorData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public Reflector(ReflectorData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
Item.Entity.VisibilitySources[this] = Item.Evaluate(_data.CrossSection) * Item.Entity.Zone.GetLight(Item.Entity.Position.xz);
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
Entity.VisibilitySources[this] = Evaluate(_data.CrossSection) * Entity.Zone.GetLight(Entity.Position.xz);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,18 @@ public class ResourceScannerData : BehaviorData
|
|||
[Inspectable, JsonProperty("scanDuration"), Key(3), RuntimeInspectable]
|
||||
public PerformanceStat ScanDuration = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new ResourceScanner(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new ResourceScanner(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class ResourceScanner : IBehavior, IAlwaysUpdatedBehavior
|
||||
public class ResourceScanner : Behavior, IAlwaysUpdatedBehavior
|
||||
{
|
||||
public int Asteroid = -1;
|
||||
|
||||
|
|
@ -35,9 +40,6 @@ public class ResourceScanner : IBehavior, IAlwaysUpdatedBehavior
|
|||
private float _scanTime;
|
||||
private Guid _scanTarget;
|
||||
|
||||
private EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
public float Range { get; private set; }
|
||||
public float MinimumDensity { get; private set; }
|
||||
public float ScanDuration { get; private set; }
|
||||
|
|
@ -55,22 +57,26 @@ public class ResourceScanner : IBehavior, IAlwaysUpdatedBehavior
|
|||
}
|
||||
}
|
||||
|
||||
public ResourceScanner(ResourceScannerData data, EquippedItem item)
|
||||
public ResourceScanner(ResourceScannerData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public ResourceScanner(ResourceScannerData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
var planetData = Item.Entity.Zone.Planets[ScanTarget];
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
var planetData = Entity.Zone.Planets[ScanTarget];
|
||||
if (planetData != null)
|
||||
{
|
||||
if (planetData is AsteroidBeltData beltData)
|
||||
{
|
||||
if(Asteroid > -1 &&
|
||||
Asteroid < beltData.Asteroids.Length &&
|
||||
length(Item.Entity.Position.xz - Item.Entity.Zone.AsteroidBelts[ScanTarget].Positions[Asteroid].xz) < Range)
|
||||
length(Entity.Position.xz - Entity.Zone.AsteroidBelts[ScanTarget].Positions[Asteroid].xz) < Range)
|
||||
{
|
||||
_scanTime += dt;
|
||||
if (_scanTime > ScanDuration)
|
||||
|
|
@ -84,7 +90,7 @@ public class ResourceScanner : IBehavior, IAlwaysUpdatedBehavior
|
|||
}
|
||||
else
|
||||
{
|
||||
if(length(Item.Entity.Position.xz - Item.Entity.Zone.GetOrbitPosition(planetData.Orbit)) < Range)
|
||||
if(length(Entity.Position.xz - Entity.Zone.GetOrbitPosition(planetData.Orbit)) < Range)
|
||||
{
|
||||
_scanTime += dt;
|
||||
if (_scanTime > ScanDuration)
|
||||
|
|
@ -101,8 +107,8 @@ public class ResourceScanner : IBehavior, IAlwaysUpdatedBehavior
|
|||
|
||||
public void Update(float delta)
|
||||
{
|
||||
Range = Item.Evaluate(_data.Range);
|
||||
MinimumDensity = Item.Evaluate(_data.MinimumDensity);
|
||||
ScanDuration = Item.Evaluate(_data.ScanDuration);
|
||||
Range = Evaluate(_data.Range);
|
||||
MinimumDensity = Evaluate(_data.MinimumDensity);
|
||||
ScanDuration = Evaluate(_data.ScanDuration);
|
||||
}
|
||||
}
|
||||
|
|
@ -39,13 +39,18 @@ public class SensorData : BehaviorData
|
|||
[Inspectable, JsonProperty("pingRadiusExponent"), Key(11)]
|
||||
public float PingRadiusExponent = .5f;
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Sensor(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Sensor(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Sensor : IBehavior, IEventBehavior
|
||||
public class Sensor : Behavior, IEventBehavior
|
||||
{
|
||||
private SensorData _data;
|
||||
private float _pingCooldown;
|
||||
|
|
@ -54,10 +59,6 @@ public class Sensor : IBehavior, IEventBehavior
|
|||
private float _pingRadius;
|
||||
private HashSet<Entity> _pingedEntities = new HashSet<Entity>();
|
||||
|
||||
private EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public float Cooldown
|
||||
{
|
||||
get => saturate(_pingCooldown);
|
||||
|
|
@ -81,9 +82,9 @@ public class Sensor : IBehavior, IEventBehavior
|
|||
|
||||
public void Ping()
|
||||
{
|
||||
if(_pingCooldown < 0 && Item.Entity.TryConsumeEnergy(Item.Evaluate(_data.PingEnergy)))
|
||||
if(_pingCooldown < 0 && Entity.TryConsumeEnergy(Evaluate(_data.PingEnergy)))
|
||||
{
|
||||
Item.Entity.VisibilitySources[this] = Item.Evaluate(_data.PingVisibility);
|
||||
Entity.VisibilitySources[this] = Evaluate(_data.PingVisibility);
|
||||
_pinging = true;
|
||||
_pingCooldown = 1;
|
||||
_pingLerp = 0;
|
||||
|
|
@ -93,18 +94,22 @@ public class Sensor : IBehavior, IEventBehavior
|
|||
}
|
||||
}
|
||||
|
||||
public Sensor(SensorData data, EquippedItem item)
|
||||
public Sensor(SensorData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public Sensor(SensorData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
if (_pinging)
|
||||
{
|
||||
_pingLerp += dt / _data.PingDuration;
|
||||
_pingRadius = lerp(0, Item.Evaluate(_data.PingRange), pow(_pingLerp, _data.PingRadiusExponent));
|
||||
_pingRadius = lerp(0, Evaluate(_data.PingRange), pow(_pingLerp, _data.PingRadiusExponent));
|
||||
if (_pingLerp > 1)
|
||||
{
|
||||
_pinging = false;
|
||||
|
|
@ -112,30 +117,27 @@ public class Sensor : IBehavior, IEventBehavior
|
|||
}
|
||||
}
|
||||
|
||||
_pingCooldown -= dt / Item.Evaluate(_data.PingCooldown);
|
||||
_pingCooldown -= dt / Evaluate(_data.PingCooldown);
|
||||
|
||||
// TODO: Handle Active Detection / Visibility From Reflected Radiance
|
||||
var hardpoint = Item.Entity.Hardpoints[Item.Position.x, Item.Position.y];
|
||||
var forward = hardpoint != null && Item.Entity.HardpointTransforms.ContainsKey(hardpoint) ?
|
||||
normalize(Item.Entity.HardpointTransforms[hardpoint].direction.xz) :
|
||||
Item.Entity.Direction;
|
||||
foreach (var entity in Item.Entity.Zone.Entities)
|
||||
var forward = Direction.xz;
|
||||
foreach (var entity in Entity.Zone.Entities)
|
||||
{
|
||||
if (entity == Item.Entity) continue;
|
||||
if (entity == Entity) continue;
|
||||
|
||||
var diff = entity.Position.xz - Item.Entity.Position.xz;
|
||||
var diff = entity.Position.xz - Entity.Position.xz;
|
||||
var angle = acos(dot(forward, normalize(diff)));
|
||||
var dist = length(diff);
|
||||
float previous, next;
|
||||
Item.Entity.EntityInfoGathered.TryGetValue(entity, out previous);
|
||||
Entity.EntityInfoGathered.TryGetValue(entity, out previous);
|
||||
if (!_pingedEntities.Contains(entity) && dist < _pingRadius)
|
||||
{
|
||||
_pingedEntities.Add(entity);
|
||||
next = saturate(
|
||||
previous +
|
||||
entity.Visibility *
|
||||
Item.Evaluate(_data.Sensitivity) *
|
||||
Item.Evaluate(_data.PingBoost) *
|
||||
Evaluate(_data.Sensitivity) *
|
||||
Evaluate(_data.PingBoost) *
|
||||
dist);
|
||||
}
|
||||
else
|
||||
|
|
@ -143,13 +145,13 @@ public class Sensor : IBehavior, IEventBehavior
|
|||
next = saturate(
|
||||
previous +
|
||||
entity.Visibility *
|
||||
Item.Evaluate(_data.Sensitivity) *
|
||||
Evaluate(_data.Sensitivity) *
|
||||
_data.SensitivityCurve.Evaluate(angle / PI) *
|
||||
dt / dist);
|
||||
}
|
||||
next *= 1 - Item.ItemManager.GameplaySettings.TargetInfoDecay * dt;
|
||||
next *= 1 - ItemManager.GameplaySettings.TargetInfoDecay * dt;
|
||||
//Context.Log($"{entity.Name} visibility {(int)(previous * 100)}% -> {(int)(next * 100)}%");
|
||||
Item.Entity.EntityInfoGathered[entity] = next;
|
||||
Entity.EntityInfoGathered[entity] = next;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,44 +16,48 @@ public class ShieldData : BehaviorData
|
|||
[Inspectable, JsonProperty("energy"), Key(2), RuntimeInspectable]
|
||||
public PerformanceStat EnergyUsage = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Shield(this, item);
|
||||
}
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Shield(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Shield : IBehavior
|
||||
public class Shield : Behavior
|
||||
{
|
||||
public EquippedItem Item { get; }
|
||||
|
||||
public float Efficiency { get; private set; }
|
||||
public float EnergyUsage { get; private set; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private ShieldData _data;
|
||||
|
||||
public Shield(ShieldData data, EquippedItem item)
|
||||
public Shield(ShieldData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
public Shield(ShieldData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
Efficiency = Item.Evaluate(_data.Efficiency);
|
||||
EnergyUsage = Item.Evaluate(_data.EnergyUsage);
|
||||
Efficiency = Evaluate(_data.Efficiency);
|
||||
EnergyUsage = Evaluate(_data.EnergyUsage);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CanTakeHit(DamageType type, float damage)
|
||||
{
|
||||
return Item.Entity.CanConsumeEnergy(damage * EnergyUsage);
|
||||
return Entity.CanConsumeEnergy(damage * EnergyUsage);
|
||||
}
|
||||
|
||||
public void TakeHit(DamageType type, float damage)
|
||||
{
|
||||
Item.Entity.TryConsumeEnergy(damage * EnergyUsage);
|
||||
Item.AddHeat(damage / Efficiency);
|
||||
Entity.TryConsumeEnergy(damage * EnergyUsage);
|
||||
AddHeat(damage / Efficiency);
|
||||
}
|
||||
}
|
||||
|
|
@ -22,19 +22,21 @@ public class StatModifierData : BehaviorData
|
|||
[InspectableType(typeof(BehaviorData)), JsonProperty("requireBehavior"), Key(4)]
|
||||
public Type RequireBehavior;
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new StatModifier(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect consumable)
|
||||
{
|
||||
return new StatModifier(this, consumable);
|
||||
}
|
||||
}
|
||||
|
||||
[Order(-4)]
|
||||
public class StatModifier : IBehavior, IInitializableBehavior, IDisposableBehavior
|
||||
public class StatModifier : Behavior, IInitializableBehavior, IDisposable
|
||||
{
|
||||
private StatModifierData _data;
|
||||
private EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private PerformanceStat[] _stats;
|
||||
|
||||
|
|
@ -43,10 +45,14 @@ public class StatModifier : IBehavior, IInitializableBehavior, IDisposableBehavi
|
|||
private static Type[] StatObjects => _statObjects = _statObjects ?? typeof(BehaviorData).GetAllChildClasses()
|
||||
.Concat(typeof(EquippableItemData).GetAllChildClasses()).ToArray();
|
||||
|
||||
public StatModifier(StatModifierData data, EquippedItem item)
|
||||
public StatModifier(StatModifierData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public StatModifier(StatModifierData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
|
|
@ -59,17 +65,17 @@ public class StatModifier : IBehavior, IInitializableBehavior, IDisposableBehavi
|
|||
if (statField != null)
|
||||
{
|
||||
if (typeof(EquippableItemData).IsAssignableFrom(targetType))
|
||||
_stats = Item.Entity.Equipment
|
||||
_stats = Entity.Equipment
|
||||
.Select(hp => hp.EquippableItem)
|
||||
.Where(gear => _data.RequireBehavior == null || Item.ItemManager.GetData(gear).Behaviors.Any(behavior => behavior.GetType() == _data.RequireBehavior))
|
||||
.Where(gear => Item.ItemManager.GetData(gear).GetType() == targetType)
|
||||
.Select(gear => statField.GetValue(Item.ItemManager.GetData(gear)) as PerformanceStat)
|
||||
.Where(gear => _data.RequireBehavior == null || ItemManager.GetData(gear).Behaviors.Any(behavior => behavior.GetType() == _data.RequireBehavior))
|
||||
.Where(gear => ItemManager.GetData(gear).GetType() == targetType)
|
||||
.Select(gear => statField.GetValue(ItemManager.GetData(gear)) as PerformanceStat)
|
||||
.ToArray();
|
||||
else
|
||||
_stats = Item.Entity.Equipment
|
||||
_stats = Entity.Equipment
|
||||
.Select(hp => hp.EquippableItem)
|
||||
.Where(gear => _data.RequireBehavior == null || Item.ItemManager.GetData(gear).Behaviors.Any(behavior => behavior.GetType() == _data.RequireBehavior))
|
||||
.SelectMany(gear => Item.ItemManager.GetData(gear).Behaviors)
|
||||
.Where(gear => _data.RequireBehavior == null || ItemManager.GetData(gear).Behaviors.Any(behavior => behavior.GetType() == _data.RequireBehavior))
|
||||
.SelectMany(gear => ItemManager.GetData(gear).Behaviors)
|
||||
.Where(behaviorData => behaviorData.GetType() == targetType)
|
||||
.Select(behaviorData => statField.GetValue(behaviorData) as PerformanceStat)
|
||||
.ToArray();
|
||||
|
|
@ -77,19 +83,19 @@ public class StatModifier : IBehavior, IInitializableBehavior, IDisposableBehavi
|
|||
}
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
foreach (var stat in _stats)
|
||||
(_data.Type == StatModifierType.Constant
|
||||
? stat.GetConstantModifiers(Item.Entity)
|
||||
: stat.GetScaleModifiers(Item.Entity))[this] = Item.Evaluate(_data.Modifier);
|
||||
? stat.GetConstantModifiers(Entity)
|
||||
: stat.GetScaleModifiers(Entity))[this] = Evaluate(_data.Modifier);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var stat in _stats)
|
||||
(_data.Type == StatModifierType.Constant ? stat.GetConstantModifiers(Item.Entity) : stat.GetScaleModifiers(Item.Entity)).Remove(this);
|
||||
(_data.Type == StatModifierType.Constant ? stat.GetConstantModifiers(Entity) : stat.GetScaleModifiers(Entity)).Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,29 +10,32 @@ using Newtonsoft.Json;
|
|||
[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn), Order(-25)]
|
||||
public class SwitchData : BehaviorData
|
||||
{
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Switch(this, item);
|
||||
}
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Switch(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Switch : IBehavior
|
||||
public class Switch : Behavior
|
||||
{
|
||||
private SwitchData _data;
|
||||
|
||||
private EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public bool Activated { get; set; }
|
||||
|
||||
public Switch(SwitchData data, EquippedItem item)
|
||||
public Switch(SwitchData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
public Switch(SwitchData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
return Activated;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,31 +19,36 @@ public class ThermotoggleData : BehaviorData
|
|||
[Inspectable, JsonProperty("adjustable"), Key(3)]
|
||||
public bool Adjustable;
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Thermotoggle(this, item);
|
||||
}
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Thermotoggle(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Thermotoggle : IBehavior
|
||||
public class Thermotoggle : Behavior
|
||||
{
|
||||
public float TargetTemperature;
|
||||
private ThermotoggleData _data;
|
||||
|
||||
private EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
public ThermotoggleData ThermotoggleData => _data;
|
||||
|
||||
public Thermotoggle(ThermotoggleData data, EquippedItem item)
|
||||
public Thermotoggle(ThermotoggleData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
TargetTemperature = data.TargetTemperature;
|
||||
}
|
||||
public Thermotoggle(ThermotoggleData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
TargetTemperature = data.TargetTemperature;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
return Item.Temperature < TargetTemperature ^ _data.HighPass;
|
||||
return Temperature < TargetTemperature ^ _data.HighPass;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,16 +25,19 @@ public class ThrusterData : BehaviorData
|
|||
[InspectablePrefab, JsonProperty("Particles"), Key(5)]
|
||||
public string ParticlesPrefab;
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Thruster(this, item);
|
||||
}
|
||||
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Thruster(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Thruster : IAnalogBehavior
|
||||
public class Thruster : Behavior, IAnalogBehavior
|
||||
{
|
||||
public EquippedItem Item { get; }
|
||||
|
||||
public float Thrust { get; private set; }
|
||||
public float Torque { get; }
|
||||
|
||||
|
|
@ -44,37 +47,41 @@ public class Thruster : IAnalogBehavior
|
|||
set => _input = saturate(value);
|
||||
}
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private ThrusterData _data;
|
||||
|
||||
private float _input;
|
||||
|
||||
public Thruster(ThrusterData data, EquippedItem item)
|
||||
public Thruster(ThrusterData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
var hullData = Item.ItemManager.GetData(Item.Entity.Hull) as HullData;
|
||||
var hullData = ItemManager.GetData(Entity.Hull) as HullData;
|
||||
var hullCenter = hullData.Shape.CenterOfMass;
|
||||
var itemData = Item.ItemManager.GetData(item.EquippableItem);
|
||||
var itemData = ItemManager.GetData(item.EquippableItem);
|
||||
var itemCenter = hullData.Shape.Inset(itemData.Shape, item.Position, item.EquippableItem.Rotation).CenterOfMass;
|
||||
var toCenter = hullCenter - itemCenter;
|
||||
Torque = -dot(normalize(toCenter), float2(1, 0).Rotate(item.EquippableItem.Rotation));
|
||||
Thrust = Item.Evaluate(_data.Thrust);
|
||||
Thrust = Evaluate(_data.Thrust);
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public Thruster(ThrusterData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
if(_input > .01f && Item.Entity.TryConsumeEnergy(_input * Item.Evaluate(_data.EnergyUsage)))
|
||||
_data = data;
|
||||
Torque = 0;
|
||||
Thrust = Evaluate(_data.Thrust);
|
||||
}
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
if(_input > .01f && Entity.TryConsumeEnergy(_input * Evaluate(_data.EnergyUsage)))
|
||||
{
|
||||
Thrust = Item.Evaluate(_data.Thrust);
|
||||
Item.Entity.Velocity -= Item.Entity.Direction.Rotate(Item.EquippableItem.Rotation) * _input * Thrust / Item.Entity.Mass * dt;
|
||||
Item.Entity.Direction = mul(Item.Entity.Direction,
|
||||
Unity.Mathematics.float2x2.Rotate(_input * Torque * Thrust * Item.ItemManager.GameplaySettings.TorqueMultiplier / Item.Entity.Mass * dt));
|
||||
Item.AddHeat(_input * Item.Evaluate(_data.Heat) * dt);
|
||||
var vis = _input * Item.Evaluate(_data.Visibility);
|
||||
if (!Item.Entity.VisibilitySources.ContainsKey(this) || vis > Item.Entity.VisibilitySources[this])
|
||||
Item.Entity.VisibilitySources[this] = vis;
|
||||
Thrust = Evaluate(_data.Thrust);
|
||||
Entity.Velocity -= Direction.xz * _input * Thrust / Entity.Mass * dt;
|
||||
Entity.Direction = mul(Entity.Direction,
|
||||
Unity.Mathematics.float2x2.Rotate(_input * Torque * Thrust * ItemManager.GameplaySettings.TorqueMultiplier / Entity.Mass * dt));
|
||||
AddHeat(_input * Evaluate(_data.Heat) * dt);
|
||||
var vis = _input * Evaluate(_data.Visibility);
|
||||
if (!Entity.VisibilitySources.ContainsKey(this) || vis > Entity.VisibilitySources[this])
|
||||
Entity.VisibilitySources[this] = vis;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -10,29 +10,24 @@ using Newtonsoft.Json;
|
|||
[Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn), Order(-20)]
|
||||
public class TriggerData : BehaviorData
|
||||
{
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Trigger(this, item);
|
||||
}
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Trigger(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Trigger : IBehavior, IActivatedBehavior
|
||||
public class Trigger : Behavior, IActivatedBehavior
|
||||
{
|
||||
private TriggerData _data;
|
||||
|
||||
public EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public bool _pulled;
|
||||
|
||||
public Trigger(TriggerData data, EquippedItem item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
public Trigger(TriggerData data, EquippedItem item) : base(data, item) { }
|
||||
public Trigger(TriggerData data, ConsumableItemEffect item) : base(data, item) { }
|
||||
|
||||
public bool Execute(float dt)
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
if (_pulled)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,84 +14,74 @@ using float3 = Unity.Mathematics.float3;
|
|||
[MessagePackObject, JsonObject(MemberSerialization.OptIn), RuntimeInspectable]
|
||||
public class TurretControllerData : BehaviorData
|
||||
{
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new TurretController(this, item);
|
||||
}
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new TurretController(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class TurretController : IBehavior
|
||||
public class TurretController : Behavior, IInitializableBehavior
|
||||
{
|
||||
private TurretControllerData _data;
|
||||
private List<Weapon> _weapons = new List<Weapon>();
|
||||
private float _shotSpeed;
|
||||
private bool _predictShots;
|
||||
|
||||
public EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public TurretController(TurretControllerData data, EquippedItem item)
|
||||
public TurretController(TurretControllerData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
var weapons = Item.Entity.Equipment.Where(e => e.Behaviors.Any(b => b.Data is WeaponData));
|
||||
foreach (var weapon in weapons)
|
||||
{
|
||||
CheckWeapon(weapon);
|
||||
}
|
||||
|
||||
Item.Entity.Equipment.ObserveAdd().Subscribe(add => CheckWeapon(add.Value));
|
||||
Item.Entity.Equipment.ObserveRemove().Subscribe(remove =>
|
||||
{
|
||||
foreach (var b in remove.Value.Behaviors)
|
||||
if (b is Weapon weapon)
|
||||
_weapons.Remove(weapon);
|
||||
});
|
||||
}
|
||||
|
||||
private void CheckWeapon(EquippedItem item)
|
||||
public TurretController(TurretControllerData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
foreach (var b in item.Behaviors)
|
||||
if (b is Weapon weapon)
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
foreach (var weapon in Entity.GetBehaviors<Weapon>())
|
||||
{
|
||||
_weapons.Add(weapon);
|
||||
var vel = weapon.Evaluate(weapon.WeaponData.Velocity);
|
||||
if (vel > .1f)
|
||||
{
|
||||
_weapons.Add(weapon);
|
||||
var vel = weapon.Item.Evaluate(weapon.WeaponData.Velocity);
|
||||
if (vel > .1f)
|
||||
{
|
||||
_predictShots = true;
|
||||
_shotSpeed = vel;
|
||||
}
|
||||
_predictShots = true;
|
||||
_shotSpeed = vel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
if (Item.Entity.Target.Value != null)
|
||||
if (Entity.Target.Value != null)
|
||||
{
|
||||
var diff = Item.Entity.Target.Value.Position - Item.Entity.Position;
|
||||
var diff = Entity.Target.Value.Position - Entity.Position;
|
||||
if (_predictShots)
|
||||
{
|
||||
var targetHullData = Item.Entity.ItemManager.GetData(Item.Entity.Target.Value.Hull) as HullData;
|
||||
var targetVelocity = float3(Item.Entity.Target.Value.Velocity.x, 0, Item.Entity.Target.Value.Velocity.y);
|
||||
var targetHullData = Entity.ItemManager.GetData(Entity.Target.Value.Hull) as HullData;
|
||||
var targetVelocity = float3(Entity.Target.Value.Velocity.x, 0, Entity.Target.Value.Velocity.y);
|
||||
var predictedPosition = AetheriaMath.FirstOrderIntercept(
|
||||
Item.Entity.Position, float3.zero, _shotSpeed,
|
||||
Item.Entity.Target.Value.Position, targetVelocity
|
||||
Entity.Position, float3.zero, _shotSpeed,
|
||||
Entity.Target.Value.Position, targetVelocity
|
||||
);
|
||||
predictedPosition.y = Item.Entity.Zone.GetHeight(predictedPosition.xz) + targetHullData.GridOffset;
|
||||
Item.Entity.LookDirection = normalize(predictedPosition - Item.Entity.Position);
|
||||
predictedPosition.y = Entity.Zone.GetHeight(predictedPosition.xz) + targetHullData.GridOffset;
|
||||
Entity.LookDirection = normalize(predictedPosition - Entity.Position);
|
||||
}
|
||||
else
|
||||
Item.Entity.LookDirection = normalize(diff);
|
||||
Entity.LookDirection = normalize(diff);
|
||||
var dist = length(diff);
|
||||
|
||||
foreach (var x in _weapons)
|
||||
{
|
||||
var data = x.Data as WeaponData;
|
||||
var fire = dot(
|
||||
Item.Entity.HardpointTransforms[Item.Entity.Hardpoints[x.Item.Position.x, x.Item.Position.y]].direction,
|
||||
Item.Entity.LookDirection) > .99f;
|
||||
if (x.Item.Evaluate(data.Range) > dist && fire)
|
||||
x.Direction,
|
||||
Entity.LookDirection) > .99f;
|
||||
if (x.Evaluate(data.Range) > dist && fire)
|
||||
{
|
||||
x.Activate();
|
||||
}
|
||||
|
|
@ -106,7 +96,7 @@ public class TurretController : IBehavior
|
|||
if (x.Firing)
|
||||
x.Deactivate();
|
||||
}
|
||||
Item.Entity.Target.Value = Item.Entity.VisibleHostiles.FirstOrDefault(e => e is Ship);
|
||||
Entity.Target.Value = Entity.VisibleHostiles.FirstOrDefault(e => e is Ship);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,31 +10,35 @@ using static Unity.Mathematics.math;
|
|||
[MessagePackObject, JsonObject(MemberSerialization.OptIn), RuntimeInspectable]
|
||||
public class VelocityConversionData : BehaviorData
|
||||
{
|
||||
[Inspectable, JsonProperty("traction"), Key(1), RuntimeInspectable]
|
||||
public PerformanceStat Traction = new PerformanceStat();
|
||||
[Inspectable, JsonProperty("lambda"), Key(1), RuntimeInspectable]
|
||||
public PerformanceStat Lambda = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new VelocityConversion(this, item);
|
||||
}
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new VelocityConversion(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class VelocityConversion : IBehavior
|
||||
public class VelocityConversion : Behavior
|
||||
{
|
||||
public EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private VelocityConversionData _data;
|
||||
|
||||
public VelocityConversion(VelocityConversionData data, EquippedItem item)
|
||||
public VelocityConversion(VelocityConversionData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
public VelocityConversion(VelocityConversionData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
Entity.Velocity = AetheriaMath.Damp(Entity.Velocity, Entity.Direction * length(Entity.Velocity), Evaluate(_data.Lambda), dt);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,35 +13,40 @@ public class VelocityLimitData : BehaviorData
|
|||
[Inspectable, JsonProperty("topSpeed"), Key(1), RuntimeInspectable]
|
||||
public PerformanceStat TopSpeed = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new VelocityLimit(this, item);
|
||||
}
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new VelocityLimit(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
[Order(100)]
|
||||
public class VelocityLimit : IBehavior
|
||||
public class VelocityLimit : Behavior
|
||||
{
|
||||
public EquippedItem Item { get; }
|
||||
|
||||
public float Limit { get; private set; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private VelocityLimitData _data;
|
||||
|
||||
public VelocityLimit(VelocityLimitData data, EquippedItem item)
|
||||
public VelocityLimit(VelocityLimitData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
Limit = Item.Evaluate(_data.TopSpeed);
|
||||
Limit = Evaluate(_data.TopSpeed);
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public VelocityLimit(VelocityLimitData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
Limit = Item.Evaluate(_data.TopSpeed);
|
||||
if (length(Item.Entity.Velocity) > Limit)
|
||||
Item.Entity.Velocity = normalize(Item.Entity.Velocity) * Limit;
|
||||
_data = data;
|
||||
Limit = Evaluate(_data.TopSpeed);
|
||||
}
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
Limit = Evaluate(_data.TopSpeed);
|
||||
if (length(Entity.Velocity) > Limit)
|
||||
Entity.Velocity = normalize(Entity.Velocity) * Limit;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,31 +16,32 @@ public class VisibilityData : BehaviorData
|
|||
[Inspectable, JsonProperty("visibilityDecay"), Key(2)]
|
||||
public PerformanceStat VisibilityDecay = new PerformanceStat();
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Visibility(this, item);
|
||||
}
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Visibility(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Visibility : IBehavior
|
||||
public class Visibility : Behavior
|
||||
{
|
||||
private VisibilityData _data;
|
||||
|
||||
private EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
private float _cooldown; // Normalized
|
||||
|
||||
public Visibility(VisibilityData data, EquippedItem item)
|
||||
public Visibility(VisibilityData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
public Visibility(VisibilityData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
Item.Entity.VisibilitySources[this] = Item.Evaluate(_data.Visibility);
|
||||
Entity.VisibilitySources[this] = Evaluate(_data.Visibility);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -67,17 +67,14 @@ public abstract class WeaponData : BehaviorData
|
|||
public PerformanceStat Velocity = new PerformanceStat();
|
||||
}
|
||||
|
||||
public abstract class Weapon : IActivatedBehavior
|
||||
public abstract class Weapon : Behavior, IActivatedBehavior
|
||||
{
|
||||
private WeaponData _data;
|
||||
|
||||
public EquippedItem Item { get; }
|
||||
|
||||
public abstract float DamagePerSecond { get; }
|
||||
public abstract float RangeDamagePerSecond(float range);
|
||||
public abstract int Ammo { get; }
|
||||
public WeaponData WeaponData => _data;
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public float Damage { get; protected set; }
|
||||
public float Penetration { get; protected set; }
|
||||
|
|
@ -96,29 +93,32 @@ public abstract class Weapon : IActivatedBehavior
|
|||
{
|
||||
get => _firing;
|
||||
}
|
||||
|
||||
|
||||
public Weapon(WeaponData data, EquippedItem item)
|
||||
|
||||
public Weapon(WeaponData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public Weapon(WeaponData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
Item = item;
|
||||
_data = data;
|
||||
}
|
||||
|
||||
protected virtual void UpdateStats()
|
||||
{
|
||||
Damage = Item.Evaluate(_data.Damage);
|
||||
Penetration = Item.Evaluate(_data.Penetration);
|
||||
DamageSpread = Item.Evaluate(_data.DamageSpread);
|
||||
MinRange = Item.Evaluate(_data.MinRange);
|
||||
Range = Item.Evaluate(_data.Range);
|
||||
Energy = Item.Evaluate(_data.Energy);
|
||||
Heat = Item.Evaluate(_data.Heat);
|
||||
Visibility = Item.Evaluate(_data.Visibility);
|
||||
Spread = Item.Evaluate(_data.Spread);
|
||||
Velocity = Item.Evaluate(_data.Velocity);
|
||||
Damage = Evaluate(_data.Damage);
|
||||
Penetration = Evaluate(_data.Penetration);
|
||||
DamageSpread = Evaluate(_data.DamageSpread);
|
||||
MinRange = Evaluate(_data.MinRange);
|
||||
Range = Evaluate(_data.Range);
|
||||
Energy = Evaluate(_data.Energy);
|
||||
Heat = Evaluate(_data.Heat);
|
||||
Visibility = Evaluate(_data.Visibility);
|
||||
Spread = Evaluate(_data.Spread);
|
||||
Velocity = Evaluate(_data.Velocity);
|
||||
}
|
||||
|
||||
public virtual bool Execute(float dt)
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
UpdateStats();
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -14,39 +14,32 @@ public class WearData : BehaviorData
|
|||
[InspectableTemperature, JsonProperty("perSecond"), Key(1)]
|
||||
public bool PerSecond = true;
|
||||
|
||||
public override IBehavior CreateInstance(EquippedItem item)
|
||||
public override Behavior CreateInstance(EquippedItem item)
|
||||
{
|
||||
return new Wear(this, item);
|
||||
}
|
||||
public override Behavior CreateInstance(ConsumableItemEffect item)
|
||||
{
|
||||
return new Wear(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
public class Wear : IBehavior
|
||||
public class Wear : Behavior
|
||||
{
|
||||
private WearData _data;
|
||||
|
||||
public EquippedItem Item { get; }
|
||||
|
||||
public BehaviorData Data => _data;
|
||||
|
||||
public Wear(WearData data, EquippedItem item)
|
||||
public Wear(WearData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
public Wear(WearData data, ConsumableItemEffect item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool Execute(float dt)
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
if (_data.PerSecond)
|
||||
{
|
||||
var dmg = Item.Wear * dt;
|
||||
Item.EquippableItem.Durability -= dmg;
|
||||
Item.Entity.ItemDamage.OnNext((Item, dmg));
|
||||
}
|
||||
else
|
||||
{
|
||||
Item.EquippableItem.Durability -= Item.Wear;
|
||||
Item.Entity.ItemDamage.OnNext((Item, Item.Wear));
|
||||
}
|
||||
CauseWearDamage(_data.PerSecond ? dt : 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ public static class ReflectionExtensions
|
|||
|
||||
public static string FormatTypeName(this string typeName)
|
||||
{
|
||||
return (typeName.EndsWith("Data")
|
||||
return (typeName.EndsWith("Data", StringComparison.InvariantCultureIgnoreCase)
|
||||
? typeName.Substring(0, typeName.Length - 4)
|
||||
: typeName).SplitCamelCase();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ public abstract class Entity
|
|||
public Zone Zone;
|
||||
public Faction Faction;
|
||||
public EquippableItem Hull;
|
||||
public EquippedItem EquippedHull;
|
||||
|
||||
public float3 Position;
|
||||
public float2 Direction = float2(0,1);
|
||||
|
|
@ -62,6 +63,9 @@ public abstract class Entity
|
|||
private List<Capacitor> _capacitors = new List<Capacitor>();
|
||||
private List<Reactor> _reactors = new List<Reactor>();
|
||||
private List<Radiator> _heatsinks = new List<Radiator>();
|
||||
|
||||
private List<ConsumableItemEffect> _activeConsumables = new List<ConsumableItemEffect>();
|
||||
|
||||
protected bool _active;
|
||||
|
||||
private bool _heatsinksEnabled = true;
|
||||
|
|
@ -208,6 +212,34 @@ public abstract class Entity
|
|||
EntityInfoGathered.ObserveRemove().Subscribe(remove => VisibleEntities.Remove(remove.Key));
|
||||
}
|
||||
|
||||
public void ActivateConsumable(ConsumableItem item)
|
||||
{
|
||||
_activeConsumables.Add(new ConsumableItemEffect(item, this));
|
||||
}
|
||||
|
||||
public ConsumableItemEffect FindActiveConsumable(ConsumableItemData data)
|
||||
{
|
||||
return _activeConsumables.FirstOrDefault(ac => ac.Data.ID == data.ID);
|
||||
}
|
||||
|
||||
public bool CanActivateConsumable(ConsumableItemData data)
|
||||
{
|
||||
return data.Stackable || FindActiveConsumable(data) == null;
|
||||
}
|
||||
|
||||
public bool TryActivateConsumable(ConsumableItemData data)
|
||||
{
|
||||
if (!CanActivateConsumable(data)) return false;
|
||||
|
||||
var bay = FindItemInCargo(data.ID);
|
||||
if (bay == null) return false;
|
||||
|
||||
var item = (ConsumableItem) bay.ItemsOfType[data.ID].First();
|
||||
ActivateConsumable(item);
|
||||
bay.Remove(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsHostileTo(Entity other)
|
||||
{
|
||||
if (Faction == null)
|
||||
|
|
@ -221,7 +253,8 @@ public abstract class Entity
|
|||
private void MapEntity()
|
||||
{
|
||||
var hullData = ItemManager.GetData(Hull) as HullData;
|
||||
Equipment.Add(new EquippedItem(ItemManager, Hull, int2.zero, this));
|
||||
EquippedHull = new EquippedItem(ItemManager, Hull, int2.zero, this);
|
||||
Equipment.Add(EquippedHull);
|
||||
Mass = hullData.Mass;
|
||||
Temperature = new float[hullData.Shape.Width, hullData.Shape.Height];
|
||||
NewTemperature = new float[hullData.Shape.Width, hullData.Shape.Height];
|
||||
|
|
@ -257,7 +290,8 @@ public abstract class Entity
|
|||
public void GenerateTriggerGroups()
|
||||
{
|
||||
foreach (var group in Weapons
|
||||
.GroupBy(w => w.Item.EquippableItem.Data)
|
||||
.GroupBy(w => w.Item.EquippableItem.Data.LinkID)
|
||||
.OrderBy(wg=>wg.Average(w=>w.Range))
|
||||
.Select((weapons, index) => (weapons, index)))
|
||||
{
|
||||
TriggerGroups[group.index].weapons = group.weapons.ToList();
|
||||
|
|
@ -695,7 +729,7 @@ public abstract class Entity
|
|||
Parent = null;
|
||||
}
|
||||
|
||||
public T GetBehavior<T>() where T : class, IBehavior
|
||||
public T GetBehavior<T>() where T : Behavior
|
||||
{
|
||||
foreach (var equippedItem in Equipment)
|
||||
if(equippedItem.Behaviors != null)
|
||||
|
|
@ -705,7 +739,7 @@ public abstract class Entity
|
|||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<T> GetBehaviors<T>() where T : class, IBehavior
|
||||
public IEnumerable<T> GetBehaviors<T>() where T : Behavior
|
||||
{
|
||||
foreach (var equippedItem in Equipment)
|
||||
if(equippedItem.Behaviors != null)
|
||||
|
|
@ -779,12 +813,13 @@ public abstract class Entity
|
|||
{
|
||||
if(Cockpit != null)
|
||||
{
|
||||
if (Cockpit.Item.Temperature > ItemManager.GameplaySettings.HeatstrokeTemperature)
|
||||
var cockpitTemp = Cockpit.Temperature;
|
||||
if (cockpitTemp > ItemManager.GameplaySettings.HeatstrokeTemperature)
|
||||
{
|
||||
var previous = Heatstroke;
|
||||
Heatstroke = saturate(
|
||||
Heatstroke +
|
||||
pow(Cockpit.Item.Temperature - ItemManager.GameplaySettings.HeatstrokeTemperature, ItemManager.GameplaySettings.HeatstrokeExponent) *
|
||||
pow(cockpitTemp - ItemManager.GameplaySettings.HeatstrokeTemperature, ItemManager.GameplaySettings.HeatstrokeExponent) *
|
||||
ItemManager.GameplaySettings.HeatstrokeMultiplier * delta);
|
||||
if(previous < ItemManager.GameplaySettings.SevereHeatstrokeRiskThreshold && Heatstroke > ItemManager.GameplaySettings.SevereHeatstrokeRiskThreshold)
|
||||
HeatstrokeRisk.OnNext(Unit.Default);
|
||||
|
|
@ -798,12 +833,13 @@ public abstract class Entity
|
|||
{
|
||||
Heatstroke = saturate(Heatstroke - ItemManager.GameplaySettings.HeatstrokeRecoverySpeed * delta);
|
||||
}
|
||||
if (Cockpit.Item.Temperature < ItemManager.GameplaySettings.HypothermiaTemperature)
|
||||
|
||||
if (cockpitTemp < ItemManager.GameplaySettings.HypothermiaTemperature)
|
||||
{
|
||||
var previous = Hypothermia;
|
||||
Hypothermia = saturate(
|
||||
Hypothermia +
|
||||
pow(ItemManager.GameplaySettings.HypothermiaTemperature - Cockpit.Item.Temperature, ItemManager.GameplaySettings.HypothermiaExponent) *
|
||||
pow(ItemManager.GameplaySettings.HypothermiaTemperature - cockpitTemp, ItemManager.GameplaySettings.HypothermiaExponent) *
|
||||
ItemManager.GameplaySettings.HypothermiaMultiplier * delta);
|
||||
if(previous < ItemManager.GameplaySettings.SevereHeatstrokeRiskThreshold && Heatstroke > ItemManager.GameplaySettings.SevereHeatstrokeRiskThreshold)
|
||||
HypothermiaRisk.OnNext(Unit.Default);
|
||||
|
|
@ -818,7 +854,13 @@ public abstract class Entity
|
|||
Hypothermia = saturate(Hypothermia - ItemManager.GameplaySettings.HypothermiaRecoverySpeed * delta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (var i = 0; i < _activeConsumables.Count; i++)
|
||||
{
|
||||
_activeConsumables[i].Update(delta);
|
||||
if(_activeConsumables[i].RemainingDuration < 0) _activeConsumables.RemoveAt(i--);
|
||||
}
|
||||
|
||||
foreach (var equippedItem in _orderedEquipment)
|
||||
{
|
||||
equippedItem.Update(delta);
|
||||
|
|
@ -935,17 +977,64 @@ public abstract class Entity
|
|||
}
|
||||
}
|
||||
|
||||
public class ConsumableItemEffect
|
||||
{
|
||||
public float RemainingDuration { get; private set; }
|
||||
public Entity Entity { get; }
|
||||
public ConsumableItem Item { get; }
|
||||
public ConsumableItemData Data { get; }
|
||||
public Behavior[] Behaviors { get; }
|
||||
|
||||
public ConsumableItemEffect(ConsumableItem item, Entity entity)
|
||||
{
|
||||
Item = item;
|
||||
Entity = entity;
|
||||
Data = (ConsumableItemData) item.Data.Value;
|
||||
RemainingDuration = Data.Duration;
|
||||
|
||||
Behaviors = Data.StatModifiers
|
||||
.Select(bd => bd.CreateInstance(this))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public void Update(float delta)
|
||||
{
|
||||
foreach (var behavior in Behaviors)
|
||||
if(behavior is IAlwaysUpdatedBehavior alwaysUpdatedBehavior) alwaysUpdatedBehavior.Update(delta);
|
||||
|
||||
foreach (var behavior in Behaviors)
|
||||
{
|
||||
if (!behavior.Execute(delta))
|
||||
break;
|
||||
}
|
||||
|
||||
RemainingDuration -= delta;
|
||||
}
|
||||
|
||||
public float Evaluate(PerformanceStat stat)
|
||||
{
|
||||
var effectiveness = Data.Effectiveness.Evaluate((Data.Duration - RemainingDuration) / Data.Duration);
|
||||
var quality = pow(Item.Quality, stat.QualityExponent);
|
||||
|
||||
var result = lerp(stat.Min, stat.Max, effectiveness * quality);
|
||||
|
||||
if (float.IsNaN(result))
|
||||
return stat.Min;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class EquippedItem
|
||||
{
|
||||
public int SortPosition;
|
||||
public EquippableItem EquippableItem;
|
||||
public int2 Position;
|
||||
public Dictionary<int, BehaviorGroup> BehaviorGroups;
|
||||
|
||||
private bool _thermalOnline;
|
||||
private bool _durabilityOnline;
|
||||
|
||||
public IBehavior[] Behaviors { get; }
|
||||
public Behavior[] Behaviors { get; }
|
||||
public Dictionary<int, BehaviorGroup> BehaviorGroups { get; }
|
||||
public float Conductivity { get; }
|
||||
public float ThermalPerformance { get; private set; }
|
||||
public float ThermalExponent { get; }
|
||||
|
|
@ -1077,7 +1166,7 @@ public class EquippedItem
|
|||
}
|
||||
}
|
||||
|
||||
public T GetBehavior<T>() where T : class, IBehavior
|
||||
public T GetBehavior<T>() where T : Behavior
|
||||
{
|
||||
foreach (var behavior in Behaviors)
|
||||
if (behavior is T b)
|
||||
|
|
@ -1125,7 +1214,7 @@ public class EquippedCargoBay : EquippedItem
|
|||
// Check whether the given item will fit when its origin is placed at the given coordinate
|
||||
public bool ItemFits(ItemInstance item, int2 cargoCoord)
|
||||
{
|
||||
var itemData = ItemManager.GetData(item);
|
||||
var itemData = item.Data.Value;
|
||||
// Check every cell of the item's shape
|
||||
foreach (var i in itemData.Shape.Coordinates)
|
||||
{
|
||||
|
|
@ -1249,9 +1338,9 @@ public class EquippedCargoBay : EquippedItem
|
|||
}
|
||||
Cargo[item] = cargoCoord;
|
||||
|
||||
if(!ItemsOfType.ContainsKey(item.Data))
|
||||
ItemsOfType[item.Data] = new List<ItemInstance>();
|
||||
ItemsOfType[item.Data].Add(item);
|
||||
if(!ItemsOfType.ContainsKey(item.Data.LinkID))
|
||||
ItemsOfType[item.Data.LinkID] = new List<ItemInstance>();
|
||||
ItemsOfType[item.Data.LinkID].Add(item);
|
||||
}
|
||||
else if (Occupancy[cargoCoord.x, cargoCoord.y] is SimpleCommodity cargoCommodity && cargoCommodity.Data == item.Data)
|
||||
{
|
||||
|
|
@ -1293,9 +1382,9 @@ public class EquippedCargoBay : EquippedItem
|
|||
}
|
||||
Cargo[item] = cargoCoord;
|
||||
|
||||
if(!ItemsOfType.ContainsKey(item.Data))
|
||||
ItemsOfType[item.Data] = new List<ItemInstance>();
|
||||
ItemsOfType[item.Data].Add(item);
|
||||
if(!ItemsOfType.ContainsKey(item.Data.LinkID))
|
||||
ItemsOfType[item.Data.LinkID] = new List<ItemInstance>();
|
||||
ItemsOfType[item.Data.LinkID].Add(item);
|
||||
|
||||
Mass += ItemManager.GetMass(item);
|
||||
ThermalMass += ItemManager.GetThermalMass(item);
|
||||
|
|
@ -1318,9 +1407,9 @@ public class EquippedCargoBay : EquippedItem
|
|||
Occupancy[v.x, v.y] = null;
|
||||
|
||||
Cargo.Remove(item);
|
||||
ItemsOfType[item.Data].Remove(item);
|
||||
if (!ItemsOfType[item.Data].Any())
|
||||
ItemsOfType.Remove(item.Data);
|
||||
ItemsOfType[item.Data.LinkID].Remove(item);
|
||||
if (!ItemsOfType[item.Data.LinkID].Any())
|
||||
ItemsOfType.Remove(item.Data.LinkID);
|
||||
|
||||
Mass -= ItemManager.GetMass(item);
|
||||
ThermalMass -= ItemManager.GetThermalMass(item);
|
||||
|
|
@ -1347,9 +1436,9 @@ public class EquippedCargoBay : EquippedItem
|
|||
Occupancy[v.x, v.y] = null;
|
||||
|
||||
Cargo.Remove(item);
|
||||
ItemsOfType[item.Data].Remove(item);
|
||||
if (!ItemsOfType[item.Data].Any())
|
||||
ItemsOfType.Remove(item.Data);
|
||||
ItemsOfType[item.Data.LinkID].Remove(item);
|
||||
if (!ItemsOfType[item.Data.LinkID].Any())
|
||||
ItemsOfType.Remove(item.Data.LinkID);
|
||||
|
||||
Mass -= ItemManager.GetMass(item);
|
||||
ThermalMass -= ItemManager.GetThermalMass(item);
|
||||
|
|
@ -1408,9 +1497,9 @@ public class EquippedDockingBay : EquippedCargoBay
|
|||
|
||||
public class BehaviorGroup
|
||||
{
|
||||
public IBehavior[] Behaviors;
|
||||
public Behavior[] Behaviors;
|
||||
|
||||
public T GetBehavior<T>() where T : class, IBehavior
|
||||
public T GetBehavior<T>() where T : Behavior
|
||||
{
|
||||
foreach (var b in Behaviors)
|
||||
{
|
||||
|
|
@ -1421,7 +1510,7 @@ public class BehaviorGroup
|
|||
return null;
|
||||
}
|
||||
|
||||
public T GetExposed<T>() where T : class, IBehavior, IInteractiveBehavior
|
||||
public T GetExposed<T>() where T : Behavior, IInteractiveBehavior
|
||||
{
|
||||
foreach (var b in Behaviors)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ public abstract class EntityPack
|
|||
{
|
||||
foreach (var (_, item) in t)
|
||||
{
|
||||
var itemData = itemManager.GetData(item);
|
||||
var itemData = item.Data.Value;
|
||||
if (item is SimpleCommodity s)
|
||||
_price += itemData.Price * s.Quantity;
|
||||
else
|
||||
|
|
@ -242,7 +242,7 @@ public abstract class EntityPack
|
|||
{
|
||||
foreach (var (_, item) in t)
|
||||
{
|
||||
var itemData = itemManager.GetData(item);
|
||||
var itemData = item.Data.Value;
|
||||
if (item is SimpleCommodity s)
|
||||
_price += itemData.Price * s.Quantity;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -284,8 +284,8 @@ public class SimpleCommodityData : ItemData
|
|||
[MessagePackObject, JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<CraftedItemData>))]
|
||||
public abstract class CraftedItemData : ItemData
|
||||
{
|
||||
[Inspectable, JsonProperty("ingredientQualityWeight"), Key(9)]
|
||||
public float IngredientQualityWeight = .5f;
|
||||
// [Inspectable, JsonProperty("ingredientQualityWeight"), Key(9)]
|
||||
// public float IngredientQualityWeight = .5f;
|
||||
}
|
||||
|
||||
[RethinkTable("Items"), Inspectable, MessagePackObject]
|
||||
|
|
@ -298,7 +298,26 @@ public class CompoundCommodityData : CraftedItemData
|
|||
public CompoundCommodityCategory Category;
|
||||
}
|
||||
|
||||
[JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<EquippableItemData>))]
|
||||
[RethinkTable("Items"), Inspectable, MessagePackObject]
|
||||
public class ConsumableItemData : CraftedItemData
|
||||
{
|
||||
[Inspectable, JsonProperty("behaviors"), Key(10)]
|
||||
public List<StatModifierData> StatModifiers = new List<StatModifierData>();
|
||||
|
||||
[Inspectable, JsonProperty("stackable"), Key(11)]
|
||||
public bool Stackable;
|
||||
|
||||
[Inspectable, JsonProperty("duration"), Key(12)]
|
||||
public float Duration;
|
||||
|
||||
[InspectableTexture, JsonProperty("icon"), Key(13)]
|
||||
public string Icon;
|
||||
|
||||
[Inspectable, JsonProperty("effectiveness"), Key(14)]
|
||||
public BezierCurve Effectiveness;
|
||||
}
|
||||
|
||||
[JsonObject(MemberSerialization.OptIn)]
|
||||
public abstract class EquippableItemData : CraftedItemData
|
||||
{
|
||||
[InspectableTexture, JsonProperty("schematic"), Key(10)]
|
||||
|
|
@ -331,6 +350,9 @@ public abstract class EquippableItemData : CraftedItemData
|
|||
[Inspectable, JsonProperty("sfx"), Key(19)]
|
||||
public string SoundEffectTrigger;
|
||||
|
||||
[InspectableTexture, JsonProperty("actionIcon"), Key(20)]
|
||||
public string ActionBarIcon;
|
||||
|
||||
[IgnoreMember]
|
||||
public abstract HardpointType HardpointType { get; }
|
||||
|
||||
|
|
@ -372,7 +394,7 @@ public abstract class EquippableItemData : CraftedItemData
|
|||
[RethinkTable("Items"), Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class GearData : EquippableItemData
|
||||
{
|
||||
[Inspectable, JsonProperty("hardpointType"), Key(20)]
|
||||
[Inspectable, JsonProperty("hardpointType"), Key(21)]
|
||||
public HardpointType Hardpoint;
|
||||
|
||||
[IgnoreMember] public override HardpointType HardpointType => Hardpoint;
|
||||
|
|
@ -381,7 +403,7 @@ public class GearData : EquippableItemData
|
|||
[RethinkTable("Items"), Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class CargoBayData : EquippableItemData
|
||||
{
|
||||
[Inspectable, JsonProperty("interiorShape"), Key(20)]
|
||||
[Inspectable, JsonProperty("interiorShape"), Key(21)]
|
||||
public Shape InteriorShape;
|
||||
[IgnoreMember] public override HardpointType HardpointType => HardpointType.Tool;
|
||||
}
|
||||
|
|
@ -389,48 +411,48 @@ public class CargoBayData : EquippableItemData
|
|||
[RethinkTable("Items"), Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class DockingBayData : CargoBayData
|
||||
{
|
||||
[Inspectable, JsonProperty("maxSize"), Key(21)]
|
||||
[Inspectable, JsonProperty("maxSize"), Key(22)]
|
||||
public int2 MaxSize;
|
||||
}
|
||||
|
||||
[RethinkTable("Items"), MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class WeaponItemData : GearData
|
||||
{
|
||||
[Inspectable, JsonProperty("range"), Key(21)]
|
||||
[Inspectable, JsonProperty("range"), Key(22)]
|
||||
public WeaponRange WeaponRange;
|
||||
|
||||
[Inspectable, JsonProperty("caliber"), Key(22)]
|
||||
[Inspectable, JsonProperty("caliber"), Key(23)]
|
||||
public WeaponCaliber WeaponCaliber;
|
||||
|
||||
[Inspectable, JsonProperty("weaponType"), Key(23)]
|
||||
[Inspectable, JsonProperty("weaponType"), Key(24)]
|
||||
public WeaponType WeaponType;
|
||||
|
||||
[Inspectable, JsonProperty("fireTypes"), Key(24)]
|
||||
[Inspectable, JsonProperty("fireTypes"), Key(25)]
|
||||
public WeaponFireType WeaponFireTypes;
|
||||
|
||||
[Inspectable, JsonProperty("modifiers"), Key(25)]
|
||||
[Inspectable, JsonProperty("modifiers"), Key(26)]
|
||||
public WeaponModifiers WeaponModifiers;
|
||||
}
|
||||
|
||||
[RethinkTable("Items"), Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class HullData : EquippableItemData
|
||||
{
|
||||
[Inspectable, JsonProperty("hardpoints"), Key(20)]
|
||||
[Inspectable, JsonProperty("hardpoints"), Key(21)]
|
||||
public List<HardpointData> Hardpoints = new List<HardpointData>();
|
||||
|
||||
[InspectablePrefab, JsonProperty("prefab"), Key(21)]
|
||||
[InspectablePrefab, JsonProperty("prefab"), Key(22)]
|
||||
public string Prefab;
|
||||
|
||||
[Inspectable, JsonProperty("hullType"), Key(22)]
|
||||
[Inspectable, JsonProperty("hullType"), Key(23)]
|
||||
public HullType HullType;
|
||||
|
||||
[Inspectable, JsonProperty("gridOffset"), Key(23)]
|
||||
[Inspectable, JsonProperty("gridOffset"), Key(24)]
|
||||
public float GridOffset;
|
||||
|
||||
[Inspectable, JsonProperty("armor"), Key(24)]
|
||||
[Inspectable, JsonProperty("armor"), Key(25)]
|
||||
public float Armor;
|
||||
|
||||
[Inspectable, JsonProperty("drag"), Key(25)]
|
||||
[Inspectable, JsonProperty("drag"), Key(26)]
|
||||
public float Drag;
|
||||
|
||||
[IgnoreMember]
|
||||
|
|
@ -511,29 +533,29 @@ public class PerformanceStat
|
|||
|
||||
// [JsonProperty("ingredient"), Key(5)] public Guid? Ingredient;
|
||||
|
||||
[IgnoreMember] private Dictionary<Entity,Dictionary<IBehavior,float>> _scaleModifiers;
|
||||
[IgnoreMember] private Dictionary<Entity,Dictionary<IBehavior,float>> _constantModifiers;
|
||||
[IgnoreMember] private Dictionary<Entity,Dictionary<Behavior,float>> _scaleModifiers;
|
||||
[IgnoreMember] private Dictionary<Entity,Dictionary<Behavior,float>> _constantModifiers;
|
||||
|
||||
[IgnoreMember]
|
||||
private Dictionary<Entity, Dictionary<IBehavior, float>> ScaleModifiers =>
|
||||
_scaleModifiers = _scaleModifiers ?? new Dictionary<Entity, Dictionary<IBehavior, float>>();
|
||||
private Dictionary<Entity, Dictionary<Behavior, float>> ScaleModifiers =>
|
||||
_scaleModifiers = _scaleModifiers ?? new Dictionary<Entity, Dictionary<Behavior, float>>();
|
||||
|
||||
[IgnoreMember]
|
||||
private Dictionary<Entity, Dictionary<IBehavior, float>> ConstantModifiers =>
|
||||
_constantModifiers = _constantModifiers ?? new Dictionary<Entity, Dictionary<IBehavior, float>>();
|
||||
private Dictionary<Entity, Dictionary<Behavior, float>> ConstantModifiers =>
|
||||
_constantModifiers = _constantModifiers ?? new Dictionary<Entity, Dictionary<Behavior, float>>();
|
||||
|
||||
public Dictionary<IBehavior, float> GetScaleModifiers(Entity entity)
|
||||
public Dictionary<Behavior, float> GetScaleModifiers(Entity entity)
|
||||
{
|
||||
if(!ScaleModifiers.ContainsKey(entity))
|
||||
ScaleModifiers[entity] = new Dictionary<IBehavior, float>();
|
||||
ScaleModifiers[entity] = new Dictionary<Behavior, float>();
|
||||
|
||||
return ScaleModifiers[entity];
|
||||
}
|
||||
|
||||
public Dictionary<IBehavior, float> GetConstantModifiers(Entity entity)
|
||||
public Dictionary<Behavior, float> GetConstantModifiers(Entity entity)
|
||||
{
|
||||
if(!ConstantModifiers.ContainsKey(entity))
|
||||
ConstantModifiers[entity] = new Dictionary<IBehavior, float>();
|
||||
ConstantModifiers[entity] = new Dictionary<Behavior, float>();
|
||||
|
||||
return ConstantModifiers[entity];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,16 +18,18 @@ using static Unity.Mathematics.math;
|
|||
[Union(0, typeof(SimpleCommodity)),
|
||||
Union(1, typeof(CompoundCommodity)),
|
||||
Union(2, typeof(EquippableItem)),
|
||||
Union(3, typeof(ConsumableItem)),
|
||||
JsonObject(MemberSerialization.OptIn),
|
||||
JsonConverter(typeof(JsonKnownTypesConverter<ItemInstance>))]
|
||||
public abstract class ItemInstance
|
||||
{
|
||||
[JsonProperty("data"), Key(0)] public Guid Data;
|
||||
[JsonProperty("data"), Key(0)] public DatabaseLink<ItemData> Data;
|
||||
[JsonProperty("rotation"), Key(1)] public ItemRotation Rotation;
|
||||
}
|
||||
|
||||
[Union(0, typeof(CompoundCommodity)),
|
||||
Union(1, typeof(EquippableItem)),
|
||||
Union(2, typeof(ConsumableItem)),
|
||||
JsonObject(MemberSerialization.OptIn),
|
||||
JsonConverter(typeof(JsonKnownTypesConverter<CraftedItemInstance>))]
|
||||
public abstract class CraftedItemInstance : ItemInstance
|
||||
|
|
@ -57,4 +59,9 @@ public class EquippableItem : CraftedItemInstance
|
|||
{
|
||||
[JsonProperty("durability"), Key(7)] public float Durability;
|
||||
[JsonProperty("override"), Key(8)] public bool OverrideShutdown;
|
||||
}
|
||||
|
||||
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
|
||||
public class ConsumableItem : CraftedItemInstance
|
||||
{
|
||||
}
|
||||
|
|
@ -107,52 +107,40 @@ public class ItemManager
|
|||
// return Tier[itemData];
|
||||
// }
|
||||
|
||||
public ItemData GetData(ItemInstance item)
|
||||
{
|
||||
return ItemData.Get<ItemData>(item.Data);
|
||||
}
|
||||
|
||||
public SimpleCommodityData GetData(SimpleCommodity item)
|
||||
{
|
||||
return ItemData.Get<SimpleCommodityData>(item.Data);
|
||||
return item.Data.Value as SimpleCommodityData;
|
||||
}
|
||||
|
||||
public CraftedItemData GetData(CraftedItemInstance item)
|
||||
{
|
||||
return ItemData.Get<CraftedItemData>(item.Data);
|
||||
return item.Data.Value as CraftedItemData;
|
||||
}
|
||||
|
||||
public EquippableItemData GetData(EquippableItem equippableItem)
|
||||
public EquippableItemData GetData(EquippableItem item)
|
||||
{
|
||||
return ItemData.Get<EquippableItemData>(equippableItem.Data);
|
||||
return item.Data.Value as EquippableItemData;
|
||||
}
|
||||
|
||||
public float GetMass(ItemInstance item)
|
||||
{
|
||||
var data = GetData(item);
|
||||
switch (item)
|
||||
return item switch
|
||||
{
|
||||
case CraftedItemInstance _:
|
||||
return data.Mass;
|
||||
case SimpleCommodity commodity:
|
||||
return data.Mass * commodity.Quantity;
|
||||
}
|
||||
|
||||
return 0;
|
||||
CraftedItemInstance _ => item.Data.Value.Mass,
|
||||
SimpleCommodity commodity => item.Data.Value.Mass * commodity.Quantity,
|
||||
_ => 0
|
||||
};
|
||||
}
|
||||
|
||||
public float GetThermalMass(ItemInstance item)
|
||||
{
|
||||
var data = GetData(item);
|
||||
switch (item)
|
||||
var data = item.Data.Value;
|
||||
return item switch
|
||||
{
|
||||
case CraftedItemInstance _:
|
||||
return data.Mass * data.SpecificHeat;
|
||||
case SimpleCommodity commodity:
|
||||
return data.Mass * data.SpecificHeat * commodity.Quantity;
|
||||
}
|
||||
|
||||
return 0;
|
||||
CraftedItemInstance _ => data.Mass * data.SpecificHeat,
|
||||
SimpleCommodity commodity => data.Mass * data.SpecificHeat * commodity.Quantity,
|
||||
_ => 0
|
||||
};
|
||||
}
|
||||
|
||||
// Returns stat when not equipped
|
||||
|
|
@ -184,7 +172,7 @@ public class ItemManager
|
|||
{
|
||||
var newItem = new SimpleCommodity
|
||||
{
|
||||
Data = item.ID,
|
||||
Data = new DatabaseLink<ItemData>{LinkID = item.ID},
|
||||
Quantity = count
|
||||
};
|
||||
//ItemData.Add(newItem);
|
||||
|
|
@ -197,7 +185,7 @@ public class ItemManager
|
|||
|
||||
public ItemInstance Instantiate(ItemInstance item)
|
||||
{
|
||||
var data = GetData(item);
|
||||
var data = item.Data.Value;
|
||||
if(data is CraftedItemData c)
|
||||
{
|
||||
var i = CreateInstance(c);
|
||||
|
|
@ -217,18 +205,15 @@ public class ItemManager
|
|||
{
|
||||
if (item is EquippableItemData equippableItemData)
|
||||
{
|
||||
var newGear = new EquippableItem
|
||||
return new EquippableItem
|
||||
{
|
||||
Data = item.ID,
|
||||
Quality = quality
|
||||
Data = new DatabaseLink<ItemData> {LinkID = item.ID}, Quality = quality, Durability = equippableItemData.Durability
|
||||
};
|
||||
newGear.Durability = equippableItemData.Durability;
|
||||
return newGear;
|
||||
}
|
||||
|
||||
var newCommodity = new CompoundCommodity
|
||||
{
|
||||
Data = item.ID,
|
||||
Data = new DatabaseLink<ItemData>{LinkID = item.ID},
|
||||
Quality = quality
|
||||
};
|
||||
return newCommodity;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ public class SavedGame
|
|||
|
||||
[Key(9)]
|
||||
public int[] DiscoveredZones;
|
||||
|
||||
[Key(10)]
|
||||
public SavedActionBarBinding[] ActionBarBindings;
|
||||
|
||||
public SavedGame() { }
|
||||
|
||||
|
|
@ -91,4 +94,32 @@ public class SavedZone
|
|||
|
||||
[Key(5)]
|
||||
public ZonePack Contents;
|
||||
}
|
||||
|
||||
[MessagePackObject,
|
||||
Union(0, typeof(SavedActionBarConsumableBinding)),
|
||||
Union(1, typeof(SavedActionBarGearBinding)),
|
||||
Union(2, typeof(SavedActionBarWeaponGroupBinding))
|
||||
]
|
||||
public abstract class SavedActionBarBinding
|
||||
{
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public class SavedActionBarConsumableBinding : SavedActionBarBinding
|
||||
{
|
||||
[Key(0)] public DatabaseLink<ConsumableItemData> Target;
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public class SavedActionBarGearBinding : SavedActionBarBinding
|
||||
{
|
||||
[Key(0)] public int EquipmentIndex;
|
||||
[Key(1)] public int BehaviorIndex;
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public class SavedActionBarWeaponGroupBinding : SavedActionBarBinding
|
||||
{
|
||||
[Key(0)] public int Group;
|
||||
}
|
||||
Loading…
Reference in a new issue