Damage System Rewrite
New damage system, much easier to understand Splash damage support Hardpoint armor consolidated with hull armor Minimap shows view cone New industry standard palette for temperature display Temperature range display contains palette Restoring loadouts now ignores temperature and armor Items can ignore thermal mass when adding heat Burst weapons can consume single ammo (mainly shotguns) New missile type that follows crosshairs New airburst projectile type that deals splash damage Auto Shotgun and Charged Shotgun
This commit is contained in:
parent
dbc522a224
commit
3a9ee2ccf7
55 changed files with 14253 additions and 2206 deletions
|
|
@ -61,7 +61,9 @@ public class InventoryMenu : MonoBehaviour
|
|||
var cargo = GameManager.DockingBay ?? GameManager.CurrentShip.CargoBays.FirstOrDefault();
|
||||
if (cargo!=null)
|
||||
InventoryPanels[0].Display(cargo);
|
||||
InventoryPanels[1].Display(GameManager.CurrentShip);
|
||||
if(GameManager.CurrentShip != null)
|
||||
InventoryPanels[1].Display(GameManager.CurrentShip);
|
||||
else InventoryPanels[1].Clear();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ public class InventoryPanel : MonoBehaviour
|
|||
public TextMeshProUGUI Title;
|
||||
public TextMeshProUGUI MinTempLabel;
|
||||
public TextMeshProUGUI MaxTempLabel;
|
||||
public GameObject TemperatureRange;
|
||||
public Button Dropdown;
|
||||
public Button Current;
|
||||
public Button Thermal;
|
||||
|
|
@ -140,8 +141,8 @@ public class InventoryPanel : MonoBehaviour
|
|||
(
|
||||
$"{pack.Name} - {pack.Price(GameManager.ItemManager):n0}", () =>
|
||||
{
|
||||
var ship = EntityPack.Unpack(GameManager.ItemManager, GameManager.CurrentShip.Zone, pack, true);
|
||||
ship.SetParent(GameManager.CurrentShip.Parent);
|
||||
var ship = EntityPack.Unpack(GameManager.ItemManager, GameManager.Zone, pack, true);
|
||||
ship.SetParent(GameManager.DockedEntity);
|
||||
GameManager.PlayerShips.Add(ship);
|
||||
GameManager.Credits -= pack.Price(GameManager.ItemManager);
|
||||
GameManager.CurrentShip = ship;
|
||||
|
|
@ -162,8 +163,8 @@ public class InventoryPanel : MonoBehaviour
|
|||
{
|
||||
if(MinTempLabel)
|
||||
{
|
||||
MinTempLabel.text = $"Min: {((int) (_displayedEntity.MinTemp - 273.15f)).ToString()}°C";
|
||||
MaxTempLabel.text = $"Max: {((int) (_displayedEntity.MaxTemp - 273.15f)).ToString()}°C";
|
||||
MinTempLabel.text = $"{((int) (_displayedEntity.MinTemp - 273.15f)).ToString()}°C";
|
||||
MaxTempLabel.text = $"{((int) (_displayedEntity.MaxTemp - 273.15f)).ToString()}°C";
|
||||
}
|
||||
var hullData = GameManager.ItemManager.GetData(_displayedEntity.Hull) as HullData;
|
||||
for(var x = 0; x < _temperatureTexture.width; x++)
|
||||
|
|
@ -210,6 +211,14 @@ public class InventoryPanel : MonoBehaviour
|
|||
|
||||
_subscriptions.Clear();
|
||||
|
||||
if (Current)
|
||||
Current.gameObject.SetActive(false);
|
||||
if (Thermal)
|
||||
Thermal.gameObject.SetActive(false);
|
||||
|
||||
if (TemperatureRange)
|
||||
TemperatureRange.SetActive(false);
|
||||
|
||||
if(TemperatureDisplay)
|
||||
TemperatureDisplay.gameObject.SetActive(false);
|
||||
|
||||
|
|
@ -227,11 +236,8 @@ public class InventoryPanel : MonoBehaviour
|
|||
_displayedCargo = null;
|
||||
_firstRect = null;
|
||||
|
||||
if(MinTempLabel)
|
||||
{
|
||||
MinTempLabel.gameObject.SetActive(true);
|
||||
MaxTempLabel.gameObject.SetActive(true);
|
||||
}
|
||||
if (TemperatureRange)
|
||||
TemperatureRange.SetActive(true);
|
||||
|
||||
if(Title)
|
||||
Title.text = entity.Name;
|
||||
|
|
@ -353,13 +359,6 @@ public class InventoryPanel : MonoBehaviour
|
|||
StartCoroutine(Pulse(hitCells, HitType.Armor, _hitSequence++));
|
||||
RefreshCells(hitCells);
|
||||
}));
|
||||
|
||||
_subscriptions.Add(entity.HardpointDamage.Subscribe(hit =>
|
||||
{
|
||||
var hitCells = hit.hardpoint.Shape.Coordinates.Select(v => v + hit.hardpoint.Position).ToArray();
|
||||
StartCoroutine(Pulse(hitCells, HitType.Armor, _hitSequence++));
|
||||
RefreshCells(hitCells);
|
||||
}));
|
||||
}
|
||||
|
||||
private IEnumerator Pulse(int2[] cells, HitType hitType, int sequence)
|
||||
|
|
@ -384,11 +383,13 @@ public class InventoryPanel : MonoBehaviour
|
|||
var lerp = (Time.time - startTime) / CellHitPulseTime;
|
||||
foreach(var cell in cells)
|
||||
if(_cellAnimationSequence[cell] == sequence)
|
||||
CellInstances[cell].Background.color = Color.Lerp(hitColor, CellBackgroundColor, lerp);
|
||||
if(CellInstances.ContainsKey(cell))
|
||||
CellInstances[cell].Background.color = Color.Lerp(hitColor, CellBackgroundColor, lerp);
|
||||
yield return null;
|
||||
}
|
||||
foreach (var cell in cells)
|
||||
CellInstances[cell].Background.color = CellBackgroundColor;
|
||||
if(CellInstances.ContainsKey(cell))
|
||||
CellInstances[cell].Background.color = CellBackgroundColor;
|
||||
}
|
||||
|
||||
public void Display(EquippedCargoBay cargo)
|
||||
|
|
@ -397,16 +398,6 @@ public class InventoryPanel : MonoBehaviour
|
|||
|
||||
_displayedCargo = cargo;
|
||||
_displayedEntity = null;
|
||||
if(TemperatureDisplay)
|
||||
TemperatureDisplay.gameObject.SetActive(false);
|
||||
|
||||
MinTempLabel.gameObject.SetActive(false);
|
||||
MaxTempLabel.gameObject.SetActive(false);
|
||||
|
||||
if (Current)
|
||||
Current.gameObject.SetActive(false);
|
||||
if (Thermal)
|
||||
Thermal.gameObject.SetActive(false);
|
||||
|
||||
if(Title)
|
||||
Title.text = cargo.Name;
|
||||
|
|
@ -572,13 +563,11 @@ public class InventoryPanel : MonoBehaviour
|
|||
|
||||
if (_hud)
|
||||
{
|
||||
if (!interior && _displayedEntity.Armor[position.x, position.y] > .01f)
|
||||
return Settings.ArmorGradient.Evaluate(_displayedEntity.Armor[position.x, position.y] / hullData.Armor);
|
||||
else if (hardpoint != null && _displayedEntity.HardpointArmor[hardpoint] > .01f)
|
||||
return Settings.ArmorGradient.Evaluate(_displayedEntity.HardpointArmor[hardpoint] / hardpoint.Armor);
|
||||
if (_displayedEntity.Armor[position.x, position.y] > .01f)
|
||||
return Settings.ArmorGradient.Evaluate(_displayedEntity.Armor[position.x, position.y] / _displayedEntity.MaxArmor[position.x, position.y]);
|
||||
|
||||
if (item != null) return Settings.DurabilityGradient.Evaluate(item.EquippableItem.Durability / _displayedEntity.ItemManager.GetData(item.EquippableItem).Durability);
|
||||
return Color.white * .25f;
|
||||
return float3(.25f).ToColor();
|
||||
}
|
||||
|
||||
if (hardpoint == null)
|
||||
|
|
@ -588,13 +577,13 @@ public class InventoryPanel : MonoBehaviour
|
|||
|
||||
if (item == null)
|
||||
{
|
||||
return Color.white * .25f;
|
||||
return float3(.25f).ToColor();
|
||||
}
|
||||
|
||||
if(highlight)
|
||||
return Color.white;
|
||||
|
||||
return Color.white * .5f;
|
||||
return float3(.5f).ToColor();
|
||||
}
|
||||
|
||||
var tint = hardpoint.TintColor;
|
||||
|
|
|
|||
47
Assets/Scripts/UI/MapMenuInput.cs
Normal file
47
Assets/Scripts/UI/MapMenuInput.cs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
public class MapMenuInput : MonoBehaviour, IBeginDragHandler, IDragHandler, IScrollHandler
|
||||
{
|
||||
public MapRenderer Map;
|
||||
public float ZoomSpeed;
|
||||
|
||||
private Vector2 _startMousePosition;
|
||||
|
||||
private Vector2 _startMapPosition;
|
||||
private RectTransform _mapRect;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_mapRect = Map.GetComponent<RectTransform>();
|
||||
}
|
||||
|
||||
public void OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
_startMousePosition = eventData.position;
|
||||
_startMapPosition = Map.Position;
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
Map.Position = _startMapPosition - (eventData.position - _startMousePosition) * Map.Scale;
|
||||
}
|
||||
|
||||
public void OnScroll(PointerEventData eventData)
|
||||
{
|
||||
Vector3[] mapCorners = new Vector3[4];
|
||||
_mapRect.GetWorldCorners(mapCorners);
|
||||
var mapCenter = ((float3)(mapCorners[2] + mapCorners[0]) / 2).xy;
|
||||
var oldPointerPosition = Map.Position + ((float2)eventData.position - mapCenter) * Map.Scale;
|
||||
Map.Scale *= 1 - eventData.scrollDelta.y * ZoomSpeed;
|
||||
var pointerPosition = Map.Position + ((float2)eventData.position - mapCenter) * Map.Scale;
|
||||
Map.Position += oldPointerPosition - pointerPosition;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/UI/MapMenuInput.cs.meta
Normal file
11
Assets/Scripts/UI/MapMenuInput.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d49dbb702a53a4e4196a99b448958958
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
103
Assets/Scripts/UI/MapRenderer.cs
Normal file
103
Assets/Scripts/UI/MapRenderer.cs
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine.UI;
|
||||
using static Unity.Mathematics.math;
|
||||
using int2 = Unity.Mathematics.int2;
|
||||
|
||||
public class MapRenderer : MonoBehaviour
|
||||
{
|
||||
public Canvas Canvas;
|
||||
public Camera MapOverlayCamera;
|
||||
public Camera GravityCamera;
|
||||
public Camera TintCamera;
|
||||
public Image OverlayDisplay;
|
||||
public Image GravityDisplay;
|
||||
public Image TintDisplay;
|
||||
public float Scale;
|
||||
public float2 Position;
|
||||
|
||||
private RectTransform _rect;
|
||||
private RenderTexture _mapTexture;
|
||||
private RenderTexture _gravityTexture;
|
||||
private RenderTexture _tintTexture;
|
||||
private int2 _size;
|
||||
private bool _init;
|
||||
|
||||
void Start()
|
||||
{
|
||||
_rect = GetComponent<RectTransform>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_init = true;
|
||||
MapOverlayCamera.gameObject.SetActive(true);
|
||||
GravityCamera.gameObject.SetActive(true);
|
||||
TintCamera.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (_mapTexture != null)
|
||||
{
|
||||
_mapTexture.Release();
|
||||
_mapTexture = null;
|
||||
_gravityTexture.Release();
|
||||
_gravityTexture = null;
|
||||
_tintTexture.Release();
|
||||
_tintTexture = null;
|
||||
}
|
||||
MapOverlayCamera.gameObject.SetActive(false);
|
||||
GravityCamera.gameObject.SetActive(false);
|
||||
TintCamera.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
var size = int2(Screen.width, Screen.height);
|
||||
if (_init || size.x != _size.x || size.y != _size.y)
|
||||
{
|
||||
_init = false;
|
||||
_size = size;
|
||||
if (_mapTexture != null)
|
||||
{
|
||||
_mapTexture.Release();
|
||||
_mapTexture = null;
|
||||
_gravityTexture.Release();
|
||||
_gravityTexture = null;
|
||||
_tintTexture.Release();
|
||||
_tintTexture = null;
|
||||
}
|
||||
var canvasCorners = new Vector3[4];
|
||||
Canvas.GetComponent<RectTransform>().GetWorldCorners(canvasCorners);
|
||||
_mapTexture = new RenderTexture(_size.x, _size.y, 0, RenderTextureFormat.Default);
|
||||
MapOverlayCamera.targetTexture = _mapTexture;
|
||||
OverlayDisplay.material.SetTexture("_DetailTex", _mapTexture);
|
||||
_gravityTexture = new RenderTexture(_size.x, _size.y, 0, RenderTextureFormat.RFloat);
|
||||
GravityCamera.targetTexture = _gravityTexture;
|
||||
GravityDisplay.material.SetTexture("_DetailTex", _gravityTexture);
|
||||
_tintTexture = new RenderTexture(_size.x / 2, _size.y / 2, 0, RenderTextureFormat.RGB111110Float);
|
||||
TintCamera.targetTexture = _tintTexture;
|
||||
TintDisplay.material.SetTexture("_DetailTex", _tintTexture);
|
||||
}
|
||||
|
||||
var pos = ((Vector2) Position).Flatland(1);
|
||||
|
||||
MapOverlayCamera.transform.position = pos;
|
||||
MapOverlayCamera.orthographicSize = _size.y * Scale * .5f;
|
||||
|
||||
GravityCamera.transform.position = pos;
|
||||
GravityCamera.orthographicSize = _size.y * Scale * .5f;
|
||||
GravityDisplay.material.SetFloat("_Scale", Scale / 2);
|
||||
|
||||
TintCamera.transform.position = pos;
|
||||
TintCamera.orthographicSize = _size.y * Scale * .5f;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/UI/MapRenderer.cs.meta
Normal file
11
Assets/Scripts/UI/MapRenderer.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 95307b613a054bc4a9bb1f9db0a2e3d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
76
Assets/Scripts/UI/MenuPanel.cs
Normal file
76
Assets/Scripts/UI/MenuPanel.cs
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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;
|
||||
using System.Collections.Generic;
|
||||
using UniRx.Triggers;
|
||||
using UnityEngine;
|
||||
|
||||
public class MenuPanel : MonoBehaviour
|
||||
{
|
||||
public ActionGameManager GameManager;
|
||||
public RectTransform TabButtons;
|
||||
public Color ActiveTabColor;
|
||||
public Color InactiveTabColor;
|
||||
|
||||
public event Action<MenuTab> TabChanged;
|
||||
|
||||
private Dictionary<MenuTab, MenuTabButton> _tabs = new Dictionary<MenuTab, MenuTabButton>();
|
||||
private MenuTabButton _current;
|
||||
|
||||
public MenuTab CurrentTab { get; private set; }
|
||||
|
||||
public void ShowTab(MenuTab tab)
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
|
||||
if (_current == _tabs[tab]) return;
|
||||
|
||||
if(_current != null)
|
||||
{
|
||||
_current.TabContents.SetActive(false);
|
||||
_current.Text.color = InactiveTabColor;
|
||||
}
|
||||
|
||||
CurrentTab = tab;
|
||||
_current = _tabs[tab];
|
||||
|
||||
_current.TabContents.SetActive(true);
|
||||
_current.Text.color = ActiveTabColor;
|
||||
|
||||
TabChanged?.Invoke(tab);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
foreach (var tabButton in _tabs.Values)
|
||||
{
|
||||
tabButton.gameObject.SetActive(!tabButton.RequireParent || GameManager.CurrentShip.Parent != null);
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
foreach (var tabButton in TabButtons.GetComponentsInChildren<MenuTabButton>())
|
||||
{
|
||||
tabButton.TabContents.SetActive(false);
|
||||
tabButton.Text.color = InactiveTabColor;
|
||||
_tabs.Add(tabButton.Tab, tabButton);
|
||||
tabButton.Button.onClick.AddListener(() => ShowTab(tabButton.Tab));
|
||||
}
|
||||
}
|
||||
|
||||
// void Start()
|
||||
// {
|
||||
// ShowTab(MenuTab.Inventory);
|
||||
// }
|
||||
}
|
||||
|
||||
public enum MenuTab
|
||||
{
|
||||
Map,
|
||||
Inventory,
|
||||
Trade
|
||||
}
|
||||
11
Assets/Scripts/UI/MenuPanel.cs.meta
Normal file
11
Assets/Scripts/UI/MenuPanel.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ebae71ac39c2d9a42b3cfbaa0d1ae7a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19
Assets/Scripts/UI/MenuTabButton.cs
Normal file
19
Assets/Scripts/UI/MenuTabButton.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class MenuTabButton : MonoBehaviour
|
||||
{
|
||||
public GameObject TabContents;
|
||||
public Button Button;
|
||||
public MenuTab Tab;
|
||||
public TextMeshProUGUI Text;
|
||||
public bool RequireParent;
|
||||
}
|
||||
11
Assets/Scripts/UI/MenuTabButton.cs.meta
Normal file
11
Assets/Scripts/UI/MenuTabButton.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d90317f6ecd38754fad9aee92f46b126
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -10,6 +10,7 @@ public class MinimapCameraTrack : MonoBehaviour
|
|||
{
|
||||
public Transform Camera;
|
||||
public bool Modulo;
|
||||
public bool Flip;
|
||||
public float Offset;
|
||||
private RectTransform _rect;
|
||||
|
||||
|
|
@ -22,6 +23,8 @@ public class MinimapCameraTrack : MonoBehaviour
|
|||
{
|
||||
var dir = Camera.forward.Flatland().normalized;
|
||||
var deg = -Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
|
||||
if (Flip)
|
||||
deg *= -1;
|
||||
if (Modulo)
|
||||
deg = Mathf.Repeat(deg + 15, 30) - 15;
|
||||
_rect.rotation = Quaternion.Euler(0,0,deg+Offset);
|
||||
|
|
|
|||
464
Assets/Scripts/UI/TradeMenu.cs
Normal file
464
Assets/Scripts/UI/TradeMenu.cs
Normal file
|
|
@ -0,0 +1,464 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Remoting.Contexts;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
|
||||
public class TradeMenu : MonoBehaviour
|
||||
{
|
||||
public ActionGameManager GameManager;
|
||||
public ContextMenu ContextMenu;
|
||||
public ConfirmationDialog Dialog;
|
||||
public Button NewFilterButton;
|
||||
public Prototype FilterPrototype;
|
||||
public SizeFilter MinimumSizeFilter;
|
||||
public SizeFilter MaximumSizeFilter;
|
||||
public PropertiesPanel Properties;
|
||||
public Spreadsheet Spreadsheet;
|
||||
public TextMeshProUGUI TargetCargoLabel;
|
||||
public Button FoldoutButton;
|
||||
|
||||
private EquippedCargoBay _targetCargo;
|
||||
private (ItemFilter filter, HardpointType type) _hardpointFilter;
|
||||
private (ItemFilter filter, SimpleCommodityCategory type) _commodityFilter;
|
||||
private (ItemFilter filter, CompoundCommodityCategory type) _compoundCommodityFilter;
|
||||
private List<(ItemFilter filter, Type type)> _behaviorFilters = new List<(ItemFilter filter, Type type)>();
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_targetCargo = GameManager.DockingBay;
|
||||
TargetCargoLabel.text = "Docking Bay";
|
||||
Properties.Context = GameManager.ItemManager;
|
||||
MinimumSizeFilter.Width.onEndEdit.AddListener(_ => Populate());
|
||||
MinimumSizeFilter.Height.onEndEdit.AddListener(_ => Populate());
|
||||
MaximumSizeFilter.Width.onEndEdit.AddListener(_ => Populate());
|
||||
MaximumSizeFilter.Height.onEndEdit.AddListener(_ => Populate());
|
||||
NewFilterButton.onClick.AddListener(() =>
|
||||
{
|
||||
ContextMenu.Clear();
|
||||
IEnumerable<HardpointType> hardpointTypes = (HardpointType[]) Enum.GetValues(typeof(HardpointType));
|
||||
if (_hardpointFilter.filter != null)
|
||||
hardpointTypes = hardpointTypes.Where(x => x != _hardpointFilter.type);
|
||||
|
||||
IEnumerable<SimpleCommodityCategory> commodityTypes = (SimpleCommodityCategory[]) Enum.GetValues(typeof(SimpleCommodityCategory));
|
||||
if (_commodityFilter.filter != null)
|
||||
commodityTypes = commodityTypes.Where(x => x != _commodityFilter.type);
|
||||
|
||||
IEnumerable<CompoundCommodityCategory> compoundCommodityTypes = (CompoundCommodityCategory[]) Enum.GetValues(typeof(CompoundCommodityCategory));
|
||||
if (_compoundCommodityFilter.filter != null)
|
||||
compoundCommodityTypes = compoundCommodityTypes.Where(x => x != _compoundCommodityFilter.type);
|
||||
|
||||
ContextMenu.AddDropdown("Gear Type", hardpointTypes
|
||||
.Select<HardpointType, (string, Action, bool)>(x => (Enum.GetName(typeof(HardpointType), x), () =>
|
||||
{
|
||||
if (_hardpointFilter.filter == null)
|
||||
{
|
||||
_hardpointFilter.filter = FilterPrototype.Instantiate<ItemFilter>();
|
||||
_hardpointFilter.filter.OnDisable += () =>
|
||||
{
|
||||
_hardpointFilter.filter = null;
|
||||
Populate();
|
||||
};
|
||||
}
|
||||
if(_commodityFilter.filter != null)
|
||||
{
|
||||
_commodityFilter.filter.GetComponent<Prototype>().ReturnToPool();
|
||||
_commodityFilter.filter = null;
|
||||
}
|
||||
if(_compoundCommodityFilter.filter != null)
|
||||
{
|
||||
_compoundCommodityFilter.filter.GetComponent<Prototype>().ReturnToPool();
|
||||
_compoundCommodityFilter.filter = null;
|
||||
}
|
||||
|
||||
_hardpointFilter.filter.Label.text = $"Hardpoint: {Enum.GetName(typeof(HardpointType), x)}";
|
||||
_hardpointFilter.type = x;
|
||||
Populate();
|
||||
}, true)));
|
||||
ContextMenu.AddDropdown("Simple Commodity", commodityTypes
|
||||
.Select<SimpleCommodityCategory, (string, Action, bool)>(x => (Enum.GetName(typeof(SimpleCommodityCategory), x), () =>
|
||||
{
|
||||
if (_commodityFilter.filter == null)
|
||||
{
|
||||
_commodityFilter.filter = FilterPrototype.Instantiate<ItemFilter>();
|
||||
_commodityFilter.filter.OnDisable += () =>
|
||||
{
|
||||
_commodityFilter.filter = null;
|
||||
Populate();
|
||||
};
|
||||
}
|
||||
if(_hardpointFilter.filter != null)
|
||||
{
|
||||
_hardpointFilter.filter.GetComponent<Prototype>().ReturnToPool();
|
||||
_hardpointFilter.filter = null;
|
||||
}
|
||||
if(_compoundCommodityFilter.filter != null)
|
||||
{
|
||||
_compoundCommodityFilter.filter.GetComponent<Prototype>().ReturnToPool();
|
||||
_compoundCommodityFilter.filter = null;
|
||||
}
|
||||
|
||||
_commodityFilter.filter.Label.text = $"Hardpoint: {Enum.GetName(typeof(SimpleCommodityCategory), x)}";
|
||||
_commodityFilter.type = x;
|
||||
Populate();
|
||||
}, true)));
|
||||
ContextMenu.AddDropdown("Compound Commodity", compoundCommodityTypes
|
||||
.Select<CompoundCommodityCategory, (string, Action, bool)>(x => (Enum.GetName(typeof(CompoundCommodityCategory), x), () =>
|
||||
{
|
||||
if (_compoundCommodityFilter.filter == null)
|
||||
{
|
||||
_compoundCommodityFilter.filter = FilterPrototype.Instantiate<ItemFilter>();
|
||||
_compoundCommodityFilter.filter.OnDisable += () =>
|
||||
{
|
||||
_compoundCommodityFilter.filter = null;
|
||||
Populate();
|
||||
};
|
||||
}
|
||||
if(_hardpointFilter.filter != null)
|
||||
{
|
||||
_hardpointFilter.filter.GetComponent<Prototype>().ReturnToPool();
|
||||
_hardpointFilter.filter = null;
|
||||
}
|
||||
if(_commodityFilter.filter != null)
|
||||
{
|
||||
_commodityFilter.filter.GetComponent<Prototype>().ReturnToPool();
|
||||
_commodityFilter.filter = null;
|
||||
}
|
||||
|
||||
_compoundCommodityFilter.filter.Label.text = $"Hardpoint: {Enum.GetName(typeof(CompoundCommodityCategory), x)}";
|
||||
_compoundCommodityFilter.type = x;
|
||||
Populate();
|
||||
}, true)));
|
||||
ContextMenu.AddDropdown("Item Behavior", typeof(BehaviorData).GetAllChildClasses()
|
||||
.Where(x=> x.GetCustomAttribute<RuntimeInspectable>() != null && _behaviorFilters.All(f => f.type != x))
|
||||
.Select<Type, (string, Action, bool)>(x=> (x.Name.FormatTypeName(), () =>
|
||||
{
|
||||
var matchingType = _behaviorFilters.FirstOrDefault(y => y.type.IsAssignableFrom(x) || x.IsAssignableFrom(y.type));
|
||||
if (matchingType.filter != null) matchingType.filter.DisableButton.onClick.Invoke();
|
||||
var filter = FilterPrototype.Instantiate<ItemFilter>();
|
||||
filter.Label.text = x.Name.FormatTypeName();
|
||||
filter.OnDisable += () =>
|
||||
{
|
||||
_behaviorFilters.Remove((filter, x));
|
||||
Populate();
|
||||
};
|
||||
_behaviorFilters.Add((filter, x));
|
||||
Populate();
|
||||
}, true)));
|
||||
if(!MinimumSizeFilter.gameObject.activeSelf)
|
||||
ContextMenu.AddOption("Minimum Size",
|
||||
() =>
|
||||
{
|
||||
MinimumSizeFilter.gameObject.SetActive(true);
|
||||
MinimumSizeFilter.OnDisable += () => Populate();
|
||||
});
|
||||
if(!MaximumSizeFilter.gameObject.activeSelf)
|
||||
ContextMenu.AddOption("Maximum Size",
|
||||
() =>
|
||||
{
|
||||
MaximumSizeFilter.gameObject.SetActive(true);
|
||||
MaximumSizeFilter.OnDisable += () => Populate();
|
||||
});
|
||||
ContextMenu.Show();
|
||||
});
|
||||
Populate();
|
||||
}
|
||||
|
||||
void Populate()
|
||||
{
|
||||
var columns = new List<(string name, int size, Func<ItemData, Func<string>> output, Func<ItemData, IComparable> sortKey)>();
|
||||
|
||||
columns.Add(("Name", 3,
|
||||
data => () => data.Name,
|
||||
data => data.Name));
|
||||
if(_hardpointFilter.filter==null)
|
||||
columns.Add(("Type", 2,
|
||||
data => () =>
|
||||
{
|
||||
if (data is SimpleCommodityData s) return Enum.GetName(typeof(SimpleCommodityCategory), s.Category);
|
||||
if(data is CompoundCommodityData c) return Enum.GetName(typeof(CompoundCommodityCategory), c.Category);
|
||||
if(data is EquippableItemData e) return Enum.GetName(typeof(HardpointType), e.HardpointType);
|
||||
return "None";
|
||||
},
|
||||
data =>
|
||||
{
|
||||
if (data is SimpleCommodityData s) return (int) s.Category;
|
||||
var offset = Enum.GetValues(typeof(SimpleCommodityCategory)).Length;
|
||||
if(data is CompoundCommodityData c) return (int) c.Category + offset;
|
||||
offset += Enum.GetValues(typeof(CompoundCommodityCategory)).Length;
|
||||
if(data is EquippableItemData e) return (int) e.HardpointType + offset;
|
||||
return 0;
|
||||
}));
|
||||
columns.Add(("Mass", 1,
|
||||
data => () => data.Mass.SignificantDigits(3),
|
||||
data => data.Mass));
|
||||
columns.Add(("Price", 1,
|
||||
data => () => data.Price.ToString("N0"),
|
||||
data => data.Price));
|
||||
columns.Add(("Size", 1,
|
||||
data => () => $"{data.Shape.Width}x{data.Shape.Height}",
|
||||
data => data.Shape.Width*data.Shape.Height));
|
||||
|
||||
var items = GameManager.ItemManager.ItemData.GetAll<ItemData>().Where(i=>i.Price!=0);
|
||||
|
||||
if (MinimumSizeFilter.gameObject.activeSelf)
|
||||
items = items.Where(i =>
|
||||
!(MinimumSizeFilter.Width.text.Length > 0 && i.Shape.Width < int.Parse(MinimumSizeFilter.Width.text) ||
|
||||
MinimumSizeFilter.Height.text.Length > 0 && i.Shape.Height < int.Parse(MinimumSizeFilter.Height.text)));
|
||||
|
||||
if (MaximumSizeFilter.gameObject.activeSelf)
|
||||
items = items.Where(i =>
|
||||
!(MaximumSizeFilter.Width.text.Length > 0 && i.Shape.Width > int.Parse(MaximumSizeFilter.Width.text) ||
|
||||
MaximumSizeFilter.Height.text.Length > 0 && i.Shape.Height > int.Parse(MaximumSizeFilter.Height.text)));
|
||||
|
||||
if(_commodityFilter.filter != null)
|
||||
items = items.Where(i => i is SimpleCommodityData s && s.Category == _commodityFilter.type);
|
||||
|
||||
if(_compoundCommodityFilter.filter != null)
|
||||
items = items.Where(i => i is CompoundCommodityData c && c.Category == _compoundCommodityFilter.type);
|
||||
|
||||
if (_hardpointFilter.filter != null)
|
||||
items = items.Where(i => i is EquippableItemData e && e.HardpointType == _hardpointFilter.type);
|
||||
|
||||
foreach (var (_, type) in _behaviorFilters)
|
||||
{
|
||||
items = items.Where(i => i is EquippableItemData e && e.Behaviors.Any(b => type.IsInstanceOfType(b)));
|
||||
|
||||
foreach (var field in type.GetFields().Where(f => f.GetCustomAttribute<RuntimeInspectable>() != null))
|
||||
{
|
||||
var fieldType = field.FieldType;
|
||||
if (fieldType == typeof(float))
|
||||
columns.Add((field.Name, 1, data =>
|
||||
{
|
||||
var behavior = ((EquippableItemData) data).Behaviors.FirstOrDefault(b => type.IsInstanceOfType(b));
|
||||
return () => ((float) field.GetValue(behavior)).SignificantDigits(3);
|
||||
}, data =>
|
||||
{
|
||||
var behavior = ((EquippableItemData) data).Behaviors.FirstOrDefault(b => type.IsInstanceOfType(b));
|
||||
return (float) field.GetValue(behavior);
|
||||
}));
|
||||
else if (fieldType == typeof(int))
|
||||
columns.Add((field.Name, 1, data =>
|
||||
{
|
||||
var behavior = ((EquippableItemData) data).Behaviors.FirstOrDefault(b => type.IsInstanceOfType(b));
|
||||
return () => ((int) field.GetValue(behavior)).ToString();
|
||||
}, data =>
|
||||
{
|
||||
var behavior = ((EquippableItemData) data).Behaviors.FirstOrDefault(b => type.IsInstanceOfType(b));
|
||||
return (int) field.GetValue(behavior);
|
||||
}));
|
||||
else if (fieldType == typeof(PerformanceStat))
|
||||
{
|
||||
columns.Add((field.Name, 1, data =>
|
||||
{
|
||||
var behavior = ((EquippableItemData) data).Behaviors.FirstOrDefault(b => type.IsInstanceOfType(b));
|
||||
return () => ((PerformanceStat) field.GetValue(behavior)).Max.SignificantDigits(3);
|
||||
}, data =>
|
||||
{
|
||||
var behavior = ((EquippableItemData) data).Behaviors.FirstOrDefault(b => type.IsInstanceOfType(b));
|
||||
return ((PerformanceStat) field.GetValue(behavior)).Max;
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
columns.Add(("Owned", 1,
|
||||
data => () =>
|
||||
{
|
||||
if (data is HullData)
|
||||
return GameManager.PlayerShips.Count(s => s.Hull.Data == data.ID && s.Parent == GameManager.CurrentShip.Parent).ToString();
|
||||
if(data is SimpleCommodityData)
|
||||
return (_targetCargo.ItemsOfType.ContainsKey(data.ID) ? _targetCargo.ItemsOfType[data.ID].Cast<SimpleCommodity>().Sum(s=>s.Quantity) : 0).ToString();
|
||||
return (_targetCargo.ItemsOfType.ContainsKey(data.ID) ? _targetCargo.ItemsOfType[data.ID].Count : 0).ToString();
|
||||
},
|
||||
data =>
|
||||
{
|
||||
if (data is HullData)
|
||||
return GameManager.PlayerShips.Count(s => s.Hull.Data == data.ID && s.Parent == GameManager.CurrentShip.Parent);
|
||||
if(data is SimpleCommodityData)
|
||||
return _targetCargo.ItemsOfType.ContainsKey(data.ID) ? _targetCargo.ItemsOfType[data.ID].Cast<SimpleCommodity>().Sum(s=>s.Quantity) : 0;
|
||||
return _targetCargo.ItemsOfType.ContainsKey(data.ID) ? _targetCargo.ItemsOfType[data.ID].Count : 0;
|
||||
}));
|
||||
|
||||
Spreadsheet.ShowData(
|
||||
columns.Select(x => x.name).ToArray(),
|
||||
columns.Select(x => x.size).ToArray(),
|
||||
items.Select(i => new SpreadsheetEntryRow
|
||||
{
|
||||
Columns = columns.Select(x => new SpreadsheetEntryColumn
|
||||
{
|
||||
Output = x.output(i),
|
||||
SortKey = x.sortKey(i)
|
||||
}).ToArray(),
|
||||
OnClick = () =>
|
||||
{
|
||||
Properties.Clear();
|
||||
Properties.AddItemDataProperties(i);
|
||||
},
|
||||
OnDoubleClick = () =>
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case HullData h:
|
||||
Buy(h);
|
||||
break;
|
||||
case CraftedItemData c:
|
||||
Buy(c,1);
|
||||
break;
|
||||
case SimpleCommodityData s:
|
||||
Buy(s, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
Populate();
|
||||
},
|
||||
OnRightClick = () =>
|
||||
{
|
||||
if (!(i is HullData))
|
||||
{
|
||||
ContextMenu.Clear();
|
||||
ContextMenu.AddOption("Buy Quantity",
|
||||
() =>
|
||||
{
|
||||
int quantity = 1;
|
||||
Dialog.Clear();
|
||||
Dialog.Title.text = $"Buying {i.Name}";
|
||||
Dialog.AddField("Quantity", () => quantity, q => quantity = min(q, GameManager.Credits/i.Price));
|
||||
Dialog.Show(() =>
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case CraftedItemData c:
|
||||
Buy(c,quantity);
|
||||
break;
|
||||
case SimpleCommodityData s:
|
||||
Buy(s, quantity);
|
||||
break;
|
||||
}
|
||||
|
||||
Populate();
|
||||
});
|
||||
});
|
||||
ContextMenu.Show();
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private void Buy(HullData data)
|
||||
{
|
||||
if (data.Price < GameManager.Credits)
|
||||
{
|
||||
var ship = new Ship(GameManager.ItemManager, GameManager.Zone, GameManager.ItemManager.CreateInstance(data, .1f, 1) as EquippableItem);
|
||||
ship.SetParent(GameManager.CurrentShip.Parent);
|
||||
GameManager.PlayerShips.Add(ship);
|
||||
|
||||
GameManager.Credits -= data.Price;
|
||||
}
|
||||
else
|
||||
{
|
||||
Dialog.Clear();
|
||||
Dialog.Title.text = "Unable to buy: Insufficient Credits!";
|
||||
Dialog.Show();
|
||||
}
|
||||
}
|
||||
|
||||
private void Buy(CraftedItemData data, int quantity)
|
||||
{
|
||||
for (int i = 0; i < quantity; i++)
|
||||
{
|
||||
if (data.Price < GameManager.Credits)
|
||||
{
|
||||
if (_targetCargo.TryStore(GameManager.ItemManager.CreateInstance(data, .1f, 1)))
|
||||
{
|
||||
GameManager.Credits -= data.Price;
|
||||
}
|
||||
else
|
||||
{
|
||||
Dialog.Clear();
|
||||
Dialog.Title.text = "Unable to buy: Insufficient Cargo Space!";
|
||||
Dialog.Show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Dialog.Clear();
|
||||
Dialog.Title.text = "Unable to buy: Insufficient Credits!";
|
||||
Dialog.Show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Buy(SimpleCommodityData data, int quantity)
|
||||
{
|
||||
// Up-rounded integer division from https://stackoverflow.com/a/503201
|
||||
int lots = (quantity - 1) / data.MaxStack + 1;
|
||||
int remaining = quantity;
|
||||
for (int i = 0; i < lots; i++)
|
||||
{
|
||||
int q = min(remaining, data.MaxStack);
|
||||
if (q * data.Price < GameManager.Credits)
|
||||
{
|
||||
if (_targetCargo.TryStore(GameManager.ItemManager.CreateInstance(data, q)))
|
||||
{
|
||||
GameManager.Credits -= q * data.Price;
|
||||
remaining -= q;
|
||||
}
|
||||
else
|
||||
{
|
||||
Dialog.Clear();
|
||||
Dialog.Title.text = "Unable to buy: Insufficient Cargo Space!";
|
||||
Dialog.Show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Dialog.Clear();
|
||||
Dialog.Title.text = "Unable to buy: Insufficient Credits!";
|
||||
Dialog.Show();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
FoldoutButton.onClick.AddListener(() =>
|
||||
{
|
||||
ContextMenu.Clear();
|
||||
if(_targetCargo != GameManager.DockingBay)
|
||||
ContextMenu.AddOption("Docking Bay",
|
||||
() =>
|
||||
{
|
||||
_targetCargo = GameManager.DockingBay;
|
||||
TargetCargoLabel.text = "Docking Bay";
|
||||
});
|
||||
foreach (var ship in GameManager.CurrentShip.Parent.Children.Where(GameManager.PlayerShips.Contains))
|
||||
{
|
||||
foreach (var bay in ship.CargoBays.Select((bay, index) => (bay, index)))
|
||||
ContextMenu.AddOption($"{ship.Name} Bay {bay.index}",
|
||||
() =>
|
||||
{
|
||||
_targetCargo = bay.bay;
|
||||
TargetCargoLabel.text = $"{ship.Name} Bay {bay.index}";
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/UI/TradeMenu.cs.meta
Normal file
11
Assets/Scripts/UI/TradeMenu.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 674196ee85a8a424ab8d3f4d0101ada7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Reference in a new issue