Properties Panel Overhaul

Marking player location on galaxy map
Fixed non-input field focus disabling global key map
Player start ship is now always the same
Loadout generator now demands exact match for item dimensions
Thermal damage now triggers ItemDamaged event = player can die from cockpit wear!
Properties panel now has a much more attractive UI
Implemented curve control for properties UI
Centralized number formatting in player settings
Moved significant digits to player settings
Added temperature unit option in player settings
This commit is contained in:
Reinier Vens 2021-04-13 01:50:42 +01:00
commit 54f7e3a66f
152 changed files with 8691 additions and 179 deletions

View file

@ -115,7 +115,9 @@ public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior
}
}
Item.EquippableItem.Durability -= Item.Wear * delta;
var dmg = Item.Wear * delta;
Item.EquippableItem.Durability -= dmg;
Item.Entity.ItemDamage.OnNext((Item, dmg));
Item.AddHeat(Item.Evaluate(_data.Heat) * delta);
Item.Entity.VisibilitySources[this] = Item.Evaluate(_data.Visibility);
}

View file

@ -170,6 +170,7 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior
_burstTimer -= _burstInterval;
OnFire?.Invoke();
Item.EquippableItem.Durability -= Item.Wear;
Item.Entity.ItemDamage.OnNext((Item, Item.Wear));
Item.AddHeat(Heat);
Item.Entity.VisibilitySources[this] = Visibility;
}

View file

@ -30,13 +30,13 @@ public abstract class WeaponData : BehaviorData
[InspectableRangedFloat(0,1), JsonProperty("damageSpread"), Key(4)]
public PerformanceStat DamageSpread = new PerformanceStat();
[Inspectable, JsonProperty("minRange"), Key(5), RuntimeInspectable]
[Inspectable, JsonProperty("minRange"), Key(5)]
public PerformanceStat MinRange = new PerformanceStat();
[Inspectable, JsonProperty("range"), Key(6), RuntimeInspectable]
[Inspectable, JsonProperty("range"), Key(6)]
public PerformanceStat Range = new PerformanceStat();
[InspectableAnimationCurve, JsonProperty("damageCurve"), Key(7), RuntimeInspectable]
[InspectableAnimationCurve, JsonProperty("damageCurve"), Key(7)]
public BezierCurve DamageCurve;
[InspectablePrefab, JsonProperty("effect"), Key(8)]

View file

@ -37,8 +37,16 @@ public class Wear : IBehavior
public bool Execute(float delta)
{
if (_data.PerSecond)
Item.EquippableItem.Durability -= Item.Wear * delta;
else Item.EquippableItem.Durability -= Item.Wear;
{
var dmg = Item.Wear * delta;
Item.EquippableItem.Durability -= dmg;
Item.Entity.ItemDamage.OnNext((Item, dmg));
}
else
{
Item.EquippableItem.Durability -= Item.Wear;
Item.Entity.ItemDamage.OnNext((Item, Item.Wear));
}
return true;
}
}

View file

@ -1,4 +1,5 @@
using System;
using System.Linq;
using MessagePack;
using Newtonsoft.Json;
using Unity.Mathematics;
@ -11,6 +12,33 @@ public class BezierCurve
[IgnoreMember] private int2 _cachedIndices;
[IgnoreMember] private const int STEPS = 64;
[IgnoreMember] private float? _maximum;
[IgnoreMember]
public float Maximum
{
get
{
if (_maximum != null) return _maximum ?? 0;
var samples = Enumerable.Range(0, STEPS).Select(i => (float) i / STEPS).ToArray();
float max = 0;
_maximum = 0;
foreach (var f in samples)
{
var p = Evaluate(f);
if (p > max)
{
max = p;
_maximum = f;
}
}
return _maximum??0;
}
}
// Integrate area under curve between start and end time
public float IntegrateCurve(float startTime, float endTime, int steps)
{

View file

@ -770,8 +770,9 @@ public abstract class Entity
}
UpdateTemperature(delta);
foreach (var item in _orderedEquipment) item.UpdatePerformance();
if (_active)
{
if(Cockpit != null)
@ -1042,11 +1043,8 @@ public class EquippedItem
Entity.AddHeat(hullCoord, heat / InsetShape.Coordinates.Length, ignoreThermalMass);
}
public void Update(float delta)
public void UpdatePerformance()
{
foreach (var behavior in Behaviors)
if(behavior is IAlwaysUpdatedBehavior alwaysUpdatedBehavior) alwaysUpdatedBehavior.Update(delta);
var temp = Temperature;
ThermalPerformance = Data.Performance(temp);
DurabilityPerformance = EquippableItem.Durability / Data.Durability;
@ -1057,6 +1055,12 @@ public class EquippedItem
) * Data.Durability / Data.ThermalResilience;
ThermalOnline.Value = ThermalPerformance > performanceThreshold || Entity.OverrideShutdown && EquippableItem.OverrideShutdown;
DurabilityOnline.Value = EquippableItem.Durability > .01f;
}
public void Update(float delta)
{
foreach (var behavior in Behaviors)
if(behavior is IAlwaysUpdatedBehavior alwaysUpdatedBehavior) alwaysUpdatedBehavior.Update(delta);
if (Active.Value)
{

View file

@ -162,4 +162,11 @@ public enum CompoundCommodityCategory
Tools = 3,
Manufacturing = 4,
Assemblies = 5
}
public enum TemperatureUnit
{
Kelvin,
Celsius,
Fahrenheit
}

View file

@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Numerics;
using System.Reflection;
@ -116,17 +117,6 @@ public static class Extensions
throw new ArgumentOutOfRangeException(nameof(rotation), rotation, null);
}
}
public static string SignificantDigits(this float d, int digits=10)
{
int magnitude = d == 0.0f ? 0 : (int)Math.Floor(Math.Log10(Math.Abs(d))) + 1;
digits -= magnitude;
if (digits < 0)
digits = 0;
string fmt = "f" + digits;
string strdec = d.ToString(fmt);
return strdec.Contains(".") ? strdec.TrimEnd('0').TrimEnd('.') : strdec;
}
private static Random? _random;
//private static Random Random => (Random) (_random ??= new Random((uint) (DateTime.Now.Ticks%uint.MaxValue)));

View file

@ -30,9 +30,9 @@ public class LoadoutGenerator
PriceExponent = priceExponent;
}
public EntityPack GenerateShipLoadout()
public EntityPack GenerateShipLoadout(Predicate<HullData> hullFilter = null)
{
var hull = ItemManager.CreateInstance(RandomHull(HullType.Ship)) as EquippableItem;
var hull = ItemManager.CreateInstance(RandomHull(HullType.Ship, hullFilter)) as EquippableItem;
var entity = new Ship(ItemManager, null, hull, ItemManager.GameplaySettings.DefaultEntitySettings);
entity.Faction = Faction;
OutfitEntity(entity);
@ -82,10 +82,13 @@ public class LoadoutGenerator
return EntitySerializer.Pack(entity);
}
public HullData RandomHull(HullType type)
public HullData RandomHull(HullType type, Predicate<HullData> hullFilter = null)
{
return ItemManager.ItemData.GetAll<HullData>()
.Where(item => item.HullType == type && (Faction == null || item.Manufacturer == Faction.ID || Faction.Allegiance.ContainsKey(item.Manufacturer)))
.Where(item =>
(hullFilter?.Invoke(item) ?? true) &&
item.HullType == type &&
(Faction == null || item.Manufacturer == Faction.ID || Faction.Allegiance.ContainsKey(item.Manufacturer)))
.WeightedRandomElements(ref Random,
item =>
(Faction == null || item.Manufacturer == Faction.ID ? 1 : Faction.Allegiance[item.Manufacturer]) / // Prioritize items from allied manufacturers
@ -119,7 +122,8 @@ public class LoadoutGenerator
{
return RandomItem<T>(sizeExponent, item => item.HardpointType == hardpoint.Type &&
(filter?.Invoke(item) ?? true) &&
item.Shape.FitsWithin(hardpoint.Shape, hardpoint.Rotation, out _));
item.Shape.FitsWithin(hardpoint.Shape, hardpoint.Rotation, out _) &&
item.Shape.Coordinates.Length==hardpoint.Shape.Coordinates.Length);
}
private void OutfitEntity(Entity entity)

View file

@ -1,4 +1,5 @@
using System;
using System.Globalization;
using MessagePack;
[MessagePackObject, Serializable]
@ -6,4 +7,40 @@ public class PlayerSettings
{
[Key(0)] public string Name = "Anonymous";
[Key(1)] public SavedGame CurrentRun;
[Key(2)] public TemperatureUnit TemperatureUnit = TemperatureUnit.Celsius;
[Key(3)] public int SignificantDigits = 3;
public string FormatTemperature(float t)
{
return TemperatureUnit switch
{
TemperatureUnit.Kelvin => $"{Format(t)}°K",
TemperatureUnit.Celsius => $"{Format(t - 273.15f)}°C",
TemperatureUnit.Fahrenheit => $"{Format((t - 273.15f) * (9f / 5) + 32)}°F",
_ => throw new ArgumentOutOfRangeException()
};
}
public float ParseTemperature(string s)
{
var t = float.Parse(s);
return TemperatureUnit switch
{
TemperatureUnit.Kelvin => t,
TemperatureUnit.Celsius => t + 273.15f,
TemperatureUnit.Fahrenheit => (t - 32) * (5f / 9) + 273.15f,
_ => throw new ArgumentOutOfRangeException()
};
}
public string Format(float d)
{
var magnitude = d == 0.0f ? 0 : (int)Math.Floor(Math.Log10(Math.Abs(d))) + 1;
SignificantDigits -= magnitude;
if (SignificantDigits < 0)
SignificantDigits = 0;
var strdec = d.ToString($"N{SignificantDigits}");
var dec = Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
return strdec.Contains(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator) ? strdec.TrimEnd('0').TrimEnd(dec) : strdec;
}
}

View file

@ -153,7 +153,6 @@ public class GameplaySettings
public int TriggerGroupCount = 6;
public float WarpDistance = 25;
public float DockingDistance = 25;
public int SignificantDigits = 3;
public float ProductionPersonalityLerp = .05f;
public float MessageDuration = 4f;
public float TargetPersistenceDuration = 3;