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:
Reinier Vens 2021-04-18 05:13:20 +01:00
commit 4489b18452
217 changed files with 5105 additions and 5703 deletions

View file

@ -34,54 +34,6 @@ public class @AetheriaInput : IInputActionCollection, IDisposable
""processors"": """",
""interactions"": """"
},
{
""name"": ""Fire Group 1"",
""type"": ""Button"",
""id"": ""575943b0-4866-4be0-a289-3253973523b1"",
""expectedControlType"": ""Button"",
""processors"": """",
""interactions"": """"
},
{
""name"": ""Fire Group 2"",
""type"": ""Button"",
""id"": ""b9bdfa1f-db61-4ec3-883a-fc3f9e88c5f5"",
""expectedControlType"": ""Button"",
""processors"": """",
""interactions"": """"
},
{
""name"": ""Fire Group 3"",
""type"": ""Button"",
""id"": ""d79871a2-8565-4cf3-809f-9c979adfcd81"",
""expectedControlType"": ""Button"",
""processors"": """",
""interactions"": """"
},
{
""name"": ""Fire Group 4"",
""type"": ""Button"",
""id"": ""59902e9e-1dfb-4624-9599-72ff763ef327"",
""expectedControlType"": ""Button"",
""processors"": """",
""interactions"": """"
},
{
""name"": ""Fire Group 5"",
""type"": ""Button"",
""id"": ""80b549c1-7378-48c5-8da2-ce95b9c92913"",
""expectedControlType"": ""Button"",
""processors"": """",
""interactions"": """"
},
{
""name"": ""Fire Group 6"",
""type"": ""Button"",
""id"": ""4ba5091e-051a-41df-9985-6c0e082b20a5"",
""expectedControlType"": ""Button"",
""processors"": """",
""interactions"": """"
},
{
""name"": ""Minimap Zoom"",
""type"": ""Button"",
@ -90,46 +42,6 @@ public class @AetheriaInput : IInputActionCollection, IDisposable
""processors"": """",
""interactions"": """"
},
{
""name"": ""Next Weapon Group"",
""type"": ""Button"",
""id"": ""8ed69fe0-d934-44ea-94c0-d5d69cc33b32"",
""expectedControlType"": ""Button"",
""processors"": """",
""interactions"": """"
},
{
""name"": ""Previous Weapon Group"",
""type"": ""Button"",
""id"": ""93f19768-6c19-4bab-8b53-4e3e5ba764fc"",
""expectedControlType"": ""Button"",
""processors"": """",
""interactions"": """"
},
{
""name"": ""Next Weapon"",
""type"": ""Button"",
""id"": ""09a5e315-6290-4ab5-9e7c-55b7523562b7"",
""expectedControlType"": ""Button"",
""processors"": """",
""interactions"": """"
},
{
""name"": ""Previous Weapon"",
""type"": ""Button"",
""id"": ""ed923265-545f-4475-ba7c-885371612325"",
""expectedControlType"": ""Button"",
""processors"": """",
""interactions"": """"
},
{
""name"": ""Toggle Weapon Group"",
""type"": ""Button"",
""id"": ""c61da4ef-e0bc-4d17-aab0-8e2979c3de3c"",
""expectedControlType"": ""Button"",
""processors"": """",
""interactions"": """"
},
{
""name"": ""Target Reticle"",
""type"": ""Button"",
@ -374,50 +286,6 @@ public class @AetheriaInput : IInputActionCollection, IDisposable
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""143bb1cd-cc10-4eca-a2f0-a3664166fe91"",
""path"": ""<Gamepad>/rightTrigger"",
""interactions"": """",
""processors"": """",
""groups"": "";Gamepad"",
""action"": ""Fire Group 1"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""05f6913d-c316-48b2-a6bb-e225f14c7960"",
""path"": ""<Mouse>/leftButton"",
""interactions"": """",
""processors"": """",
""groups"": "";Keyboard&Mouse"",
""action"": ""Fire Group 1"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""ee3d0cd2-254e-47a7-a8cb-bc94d9658c54"",
""path"": ""<Joystick>/trigger"",
""interactions"": """",
""processors"": """",
""groups"": ""Joystick"",
""action"": ""Fire Group 1"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""8c676533-8c53-4b6a-9368-d194b8a997f8"",
""path"": ""<Keyboard>/1"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard&Mouse"",
""action"": ""Fire Group 1"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""495c3ec6-3188-4309-9072-f958e89c87ec"",
@ -429,138 +297,6 @@ public class @AetheriaInput : IInputActionCollection, IDisposable
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""444b4049-a11e-4bef-8a57-345c3d1a7545"",
""path"": ""<Keyboard>/rightArrow"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard&Mouse"",
""action"": ""Next Weapon Group"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""fb6c0d4c-dae6-406b-b35a-c35b5d25022c"",
""path"": ""<Keyboard>/leftArrow"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard&Mouse"",
""action"": ""Previous Weapon Group"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""bac8c902-3cad-4a7f-8773-35800a2ee3b9"",
""path"": ""<Keyboard>/downArrow"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard&Mouse"",
""action"": ""Next Weapon"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""969aff21-097a-4c35-9c46-2239e5f321f5"",
""path"": ""<Keyboard>/upArrow"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard&Mouse"",
""action"": ""Previous Weapon"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""a2bcbfda-f091-433f-8ac9-112396507408"",
""path"": ""<Keyboard>/rightCtrl"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard&Mouse"",
""action"": ""Toggle Weapon Group"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""48b8b6ee-8435-439a-96a1-c968254ff605"",
""path"": ""<Mouse>/rightButton"",
""interactions"": """",
""processors"": """",
""groups"": "";Keyboard&Mouse"",
""action"": ""Fire Group 2"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""8ae75721-10ab-4d83-8322-82cbb3fdcc44"",
""path"": ""<Keyboard>/2"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard&Mouse"",
""action"": ""Fire Group 2"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""7f89c9af-795b-4b1e-ad43-dac3350cfbe3"",
""path"": ""<Mouse>/middleButton"",
""interactions"": """",
""processors"": """",
""groups"": "";Keyboard&Mouse"",
""action"": ""Fire Group 3"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""c249f018-c10a-4c2c-a4ba-9fba54ed33e9"",
""path"": ""<Keyboard>/3"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard&Mouse"",
""action"": ""Fire Group 3"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""421e49a0-897e-4ea3-af8d-af96989d2957"",
""path"": ""<Keyboard>/4"",
""interactions"": """",
""processors"": """",
""groups"": "";Keyboard&Mouse"",
""action"": ""Fire Group 4"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""1c8a43b7-4200-43b9-925c-c1634554083c"",
""path"": ""<Keyboard>/5"",
""interactions"": """",
""processors"": """",
""groups"": "";Keyboard&Mouse"",
""action"": ""Fire Group 5"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""0680216e-b462-45a3-8050-2b89dcb615aa"",
""path"": ""<Keyboard>/6"",
""interactions"": """",
""processors"": """",
""groups"": "";Keyboard&Mouse"",
""action"": ""Fire Group 6"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""5211a58c-428b-4ee6-820d-2f67789806d6"",
@ -1287,18 +1023,7 @@ public class @AetheriaInput : IInputActionCollection, IDisposable
m_Player = asset.FindActionMap("Player", throwIfNotFound: true);
m_Player_Move = m_Player.FindAction("Move", throwIfNotFound: true);
m_Player_Look = m_Player.FindAction("Look", throwIfNotFound: true);
m_Player_FireGroup1 = m_Player.FindAction("Fire Group 1", throwIfNotFound: true);
m_Player_FireGroup2 = m_Player.FindAction("Fire Group 2", throwIfNotFound: true);
m_Player_FireGroup3 = m_Player.FindAction("Fire Group 3", throwIfNotFound: true);
m_Player_FireGroup4 = m_Player.FindAction("Fire Group 4", throwIfNotFound: true);
m_Player_FireGroup5 = m_Player.FindAction("Fire Group 5", throwIfNotFound: true);
m_Player_FireGroup6 = m_Player.FindAction("Fire Group 6", throwIfNotFound: true);
m_Player_MinimapZoom = m_Player.FindAction("Minimap Zoom", throwIfNotFound: true);
m_Player_NextWeaponGroup = m_Player.FindAction("Next Weapon Group", throwIfNotFound: true);
m_Player_PreviousWeaponGroup = m_Player.FindAction("Previous Weapon Group", throwIfNotFound: true);
m_Player_NextWeapon = m_Player.FindAction("Next Weapon", throwIfNotFound: true);
m_Player_PreviousWeapon = m_Player.FindAction("Previous Weapon", throwIfNotFound: true);
m_Player_ToggleWeaponGroup = m_Player.FindAction("Toggle Weapon Group", throwIfNotFound: true);
m_Player_TargetReticle = m_Player.FindAction("Target Reticle", throwIfNotFound: true);
m_Player_TargetPrevious = m_Player.FindAction("Target Previous", throwIfNotFound: true);
m_Player_TargetNext = m_Player.FindAction("Target Next", throwIfNotFound: true);
@ -1379,18 +1104,7 @@ public class @AetheriaInput : IInputActionCollection, IDisposable
private IPlayerActions m_PlayerActionsCallbackInterface;
private readonly InputAction m_Player_Move;
private readonly InputAction m_Player_Look;
private readonly InputAction m_Player_FireGroup1;
private readonly InputAction m_Player_FireGroup2;
private readonly InputAction m_Player_FireGroup3;
private readonly InputAction m_Player_FireGroup4;
private readonly InputAction m_Player_FireGroup5;
private readonly InputAction m_Player_FireGroup6;
private readonly InputAction m_Player_MinimapZoom;
private readonly InputAction m_Player_NextWeaponGroup;
private readonly InputAction m_Player_PreviousWeaponGroup;
private readonly InputAction m_Player_NextWeapon;
private readonly InputAction m_Player_PreviousWeapon;
private readonly InputAction m_Player_ToggleWeaponGroup;
private readonly InputAction m_Player_TargetReticle;
private readonly InputAction m_Player_TargetPrevious;
private readonly InputAction m_Player_TargetNext;
@ -1408,18 +1122,7 @@ public class @AetheriaInput : IInputActionCollection, IDisposable
public PlayerActions(@AetheriaInput wrapper) { m_Wrapper = wrapper; }
public InputAction @Move => m_Wrapper.m_Player_Move;
public InputAction @Look => m_Wrapper.m_Player_Look;
public InputAction @FireGroup1 => m_Wrapper.m_Player_FireGroup1;
public InputAction @FireGroup2 => m_Wrapper.m_Player_FireGroup2;
public InputAction @FireGroup3 => m_Wrapper.m_Player_FireGroup3;
public InputAction @FireGroup4 => m_Wrapper.m_Player_FireGroup4;
public InputAction @FireGroup5 => m_Wrapper.m_Player_FireGroup5;
public InputAction @FireGroup6 => m_Wrapper.m_Player_FireGroup6;
public InputAction @MinimapZoom => m_Wrapper.m_Player_MinimapZoom;
public InputAction @NextWeaponGroup => m_Wrapper.m_Player_NextWeaponGroup;
public InputAction @PreviousWeaponGroup => m_Wrapper.m_Player_PreviousWeaponGroup;
public InputAction @NextWeapon => m_Wrapper.m_Player_NextWeapon;
public InputAction @PreviousWeapon => m_Wrapper.m_Player_PreviousWeapon;
public InputAction @ToggleWeaponGroup => m_Wrapper.m_Player_ToggleWeaponGroup;
public InputAction @TargetReticle => m_Wrapper.m_Player_TargetReticle;
public InputAction @TargetPrevious => m_Wrapper.m_Player_TargetPrevious;
public InputAction @TargetNext => m_Wrapper.m_Player_TargetNext;
@ -1446,42 +1149,9 @@ public class @AetheriaInput : IInputActionCollection, IDisposable
@Look.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnLook;
@Look.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnLook;
@Look.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnLook;
@FireGroup1.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup1;
@FireGroup1.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup1;
@FireGroup1.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup1;
@FireGroup2.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup2;
@FireGroup2.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup2;
@FireGroup2.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup2;
@FireGroup3.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup3;
@FireGroup3.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup3;
@FireGroup3.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup3;
@FireGroup4.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup4;
@FireGroup4.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup4;
@FireGroup4.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup4;
@FireGroup5.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup5;
@FireGroup5.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup5;
@FireGroup5.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup5;
@FireGroup6.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup6;
@FireGroup6.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup6;
@FireGroup6.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFireGroup6;
@MinimapZoom.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnMinimapZoom;
@MinimapZoom.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnMinimapZoom;
@MinimapZoom.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnMinimapZoom;
@NextWeaponGroup.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnNextWeaponGroup;
@NextWeaponGroup.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnNextWeaponGroup;
@NextWeaponGroup.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnNextWeaponGroup;
@PreviousWeaponGroup.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnPreviousWeaponGroup;
@PreviousWeaponGroup.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnPreviousWeaponGroup;
@PreviousWeaponGroup.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnPreviousWeaponGroup;
@NextWeapon.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnNextWeapon;
@NextWeapon.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnNextWeapon;
@NextWeapon.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnNextWeapon;
@PreviousWeapon.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnPreviousWeapon;
@PreviousWeapon.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnPreviousWeapon;
@PreviousWeapon.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnPreviousWeapon;
@ToggleWeaponGroup.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnToggleWeaponGroup;
@ToggleWeaponGroup.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnToggleWeaponGroup;
@ToggleWeaponGroup.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnToggleWeaponGroup;
@TargetReticle.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnTargetReticle;
@TargetReticle.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnTargetReticle;
@TargetReticle.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnTargetReticle;
@ -1525,42 +1195,9 @@ public class @AetheriaInput : IInputActionCollection, IDisposable
@Look.started += instance.OnLook;
@Look.performed += instance.OnLook;
@Look.canceled += instance.OnLook;
@FireGroup1.started += instance.OnFireGroup1;
@FireGroup1.performed += instance.OnFireGroup1;
@FireGroup1.canceled += instance.OnFireGroup1;
@FireGroup2.started += instance.OnFireGroup2;
@FireGroup2.performed += instance.OnFireGroup2;
@FireGroup2.canceled += instance.OnFireGroup2;
@FireGroup3.started += instance.OnFireGroup3;
@FireGroup3.performed += instance.OnFireGroup3;
@FireGroup3.canceled += instance.OnFireGroup3;
@FireGroup4.started += instance.OnFireGroup4;
@FireGroup4.performed += instance.OnFireGroup4;
@FireGroup4.canceled += instance.OnFireGroup4;
@FireGroup5.started += instance.OnFireGroup5;
@FireGroup5.performed += instance.OnFireGroup5;
@FireGroup5.canceled += instance.OnFireGroup5;
@FireGroup6.started += instance.OnFireGroup6;
@FireGroup6.performed += instance.OnFireGroup6;
@FireGroup6.canceled += instance.OnFireGroup6;
@MinimapZoom.started += instance.OnMinimapZoom;
@MinimapZoom.performed += instance.OnMinimapZoom;
@MinimapZoom.canceled += instance.OnMinimapZoom;
@NextWeaponGroup.started += instance.OnNextWeaponGroup;
@NextWeaponGroup.performed += instance.OnNextWeaponGroup;
@NextWeaponGroup.canceled += instance.OnNextWeaponGroup;
@PreviousWeaponGroup.started += instance.OnPreviousWeaponGroup;
@PreviousWeaponGroup.performed += instance.OnPreviousWeaponGroup;
@PreviousWeaponGroup.canceled += instance.OnPreviousWeaponGroup;
@NextWeapon.started += instance.OnNextWeapon;
@NextWeapon.performed += instance.OnNextWeapon;
@NextWeapon.canceled += instance.OnNextWeapon;
@PreviousWeapon.started += instance.OnPreviousWeapon;
@PreviousWeapon.performed += instance.OnPreviousWeapon;
@PreviousWeapon.canceled += instance.OnPreviousWeapon;
@ToggleWeaponGroup.started += instance.OnToggleWeaponGroup;
@ToggleWeaponGroup.performed += instance.OnToggleWeaponGroup;
@ToggleWeaponGroup.canceled += instance.OnToggleWeaponGroup;
@TargetReticle.started += instance.OnTargetReticle;
@TargetReticle.performed += instance.OnTargetReticle;
@TargetReticle.canceled += instance.OnTargetReticle;
@ -1597,7 +1234,7 @@ public class @AetheriaInput : IInputActionCollection, IDisposable
}
}
}
public PlayerActions @Player => new PlayerActions(this);
public PlayerActions Player => new PlayerActions(this);
// UI
private readonly InputActionMap m_UI;
@ -1791,18 +1428,7 @@ public class @AetheriaInput : IInputActionCollection, IDisposable
{
void OnMove(InputAction.CallbackContext context);
void OnLook(InputAction.CallbackContext context);
void OnFireGroup1(InputAction.CallbackContext context);
void OnFireGroup2(InputAction.CallbackContext context);
void OnFireGroup3(InputAction.CallbackContext context);
void OnFireGroup4(InputAction.CallbackContext context);
void OnFireGroup5(InputAction.CallbackContext context);
void OnFireGroup6(InputAction.CallbackContext context);
void OnMinimapZoom(InputAction.CallbackContext context);
void OnNextWeaponGroup(InputAction.CallbackContext context);
void OnPreviousWeaponGroup(InputAction.CallbackContext context);
void OnNextWeapon(InputAction.CallbackContext context);
void OnPreviousWeapon(InputAction.CallbackContext context);
void OnToggleWeaponGroup(InputAction.CallbackContext context);
void OnTargetReticle(InputAction.CallbackContext context);
void OnTargetPrevious(InputAction.CallbackContext context);
void OnTargetNext(InputAction.CallbackContext context);

View file

@ -0,0 +1,206 @@
using System;
using System.Linq;
using JsonKnownTypes;
using MessagePack;
using Newtonsoft.Json;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class ActionBarSlot : MonoBehaviour
{
public TextMeshProUGUI Label;
public RawImage Icon;
public TextMeshProUGUI InputLabel;
public Image InputIcon;
public TextMeshProUGUI QuantityRemaining;
public Image Fill;
private ActionBarBinding binding;
public Entity Entity { get; set; }
public ActionBarBinding Binding
{
get => binding;
set
{
binding = value;
if (binding == null)
{
QuantityRemaining.gameObject.SetActive(false);
Icon.gameObject.SetActive(false);
}
}
}
private void Update()
{
Binding?.Update();
}
public SavedActionBarBinding Save()
{
return Binding switch
{
ActionBarConsumableBinding actionBarConsumableBinding => new SavedActionBarConsumableBinding
{
Target = new DatabaseLink<ConsumableItemData>{LinkID = actionBarConsumableBinding.Target.ID}
},
ActionBarGearBinding actionBarGearBinding => new SavedActionBarGearBinding
{
EquipmentIndex = Entity.Equipment.IndexOf(actionBarGearBinding.Item),
BehaviorIndex = Array.IndexOf(actionBarGearBinding.Item.Behaviors, actionBarGearBinding.Behavior)
},
ActionBarWeaponGroupBinding actionBarWeaponGroupBinding => new SavedActionBarWeaponGroupBinding
{
Group = actionBarWeaponGroupBinding.Group
},
_ => null
};
}
public void Restore(SavedActionBarBinding binding)
{
Binding = binding switch
{
SavedActionBarConsumableBinding savedActionBarConsumableBinding =>
new ActionBarConsumableBinding(
Entity,
this,
savedActionBarConsumableBinding.Target.Value),
SavedActionBarGearBinding savedActionBarGearBinding =>
new ActionBarGearBinding(
Entity,
this,
Entity.Equipment[savedActionBarGearBinding.EquipmentIndex],
Entity.Equipment[savedActionBarGearBinding.EquipmentIndex]
.Behaviors[savedActionBarGearBinding.BehaviorIndex] as IActivatedBehavior),
SavedActionBarWeaponGroupBinding savedActionBarWeaponGroupBinding =>
new ActionBarWeaponGroupBinding(Entity, this, savedActionBarWeaponGroupBinding.Group),
_ => null
};
}
}
public abstract class ActionBarBinding
{
protected Entity Entity { get; }
protected ActionBarSlot Slot { get; }
public abstract void Activate();
public abstract void Deactivate();
public abstract void Update();
public ActionBarBinding(Entity entity, ActionBarSlot slot)
{
Entity = entity;
Slot = slot;
}
}
public class ActionBarConsumableBinding : ActionBarBinding
{
public ConsumableItemData Target;
public ActionBarConsumableBinding(Entity entity, ActionBarSlot slot, ConsumableItemData target) : base(entity, slot)
{
Target = target;
Slot.QuantityRemaining.gameObject.SetActive(true);
var data = Target;
if(!string.IsNullOrEmpty(data.Icon))
{
Slot.Label.gameObject.SetActive(false);
Slot.Icon.gameObject.SetActive(true);
Slot.Icon.texture = Resources.Load<Texture2D>(data.Icon.Substring("Assets/Resources/".Length).Split('.').First());
}
else Slot.Icon.gameObject.SetActive(false);
}
public override void Activate()
{
Entity.TryActivateConsumable(Target);
}
public override void Deactivate()
{
}
public override void Update()
{
Slot.QuantityRemaining.text = $"{Entity.CountItemsInCargo(Target.ID)}";
var instance = Entity.FindActiveConsumable(Target);
if (instance == null) Slot.Fill.fillAmount = 0;
else Slot.Fill.fillAmount = instance.RemainingDuration / instance.Data.Duration;
}
}
public class ActionBarGearBinding : ActionBarBinding
{
public EquippedItem Item { get; }
public IActivatedBehavior Behavior { get; }
public bool Active;
public ActionBarGearBinding(Entity entity, ActionBarSlot slot, EquippedItem item, IActivatedBehavior behavior) : base(entity, slot)
{
Item = item;
Behavior = behavior;
Slot.QuantityRemaining.gameObject.SetActive(false);
if(!string.IsNullOrEmpty(Item.Data.ActionBarIcon))
{
Slot.Label.gameObject.SetActive(false);
Slot.Icon.gameObject.SetActive(true);
Slot.Icon.texture = Resources.Load<Texture2D>(Item.Data.ActionBarIcon.Substring("Assets/Resources/".Length).Split('.').First());
}
else Slot.Icon.gameObject.SetActive(false);
}
public override void Activate()
{
Active = true;
Behavior.Activate();
}
public override void Deactivate()
{
Active = false;
Behavior.Deactivate();
}
public override void Update()
{
Slot.Fill.fillAmount = Active ? 1 : 0;
}
}
[MessagePackObject]
public class ActionBarWeaponGroupBinding : ActionBarBinding
{
[Key(0)] public int Group;
public ActionBarWeaponGroupBinding(Entity entity, ActionBarSlot slot, int group) : base(entity, slot)
{
Group = group;
slot.Label.text = $"G{Group}";
Slot.Icon.gameObject.SetActive(false);
}
public override void Activate()
{
foreach (var weapon in Entity.TriggerGroups[Group].weapons)
{
weapon.Activate();
}
}
public override void Deactivate()
{
foreach (var weapon in Entity.TriggerGroups[Group].weapons)
{
weapon.Deactivate();
}
}
public override void Update()
{
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f285e0b05ca24b83bd6cd48419cbad6e
timeCreated: 1618532311

View file

@ -62,9 +62,7 @@ public class ActionGameManager : MonoBehaviour
}
public static Sector CurrentSector;
public GameSettings Settings;
//public string StarterShipTemplate = "Longinus";
public float2 Sensitivity;
@ -80,7 +78,14 @@ public class ActionGameManager : MonoBehaviour
public PostProcessVolume SevereHeatstrokePP;
public PostProcessVolume SevereHypothermiaPP;
[Header("Input Icons")]
public Sprite ShiftIcon;
public Sprite MouseLeftIcon;
public Sprite MouseMiddleIcon;
[Header("Scene Links")]
public Transform ActionBar;
public ActionBarSlot ActionBarSlot;
public Transform EffectManagerParent;
public TradeMenu TradeMenu;
public Prototype HostileTargetIndicator;
@ -132,6 +137,8 @@ public class ActionGameManager : MonoBehaviour
private float _severeHeatstrokePhase;
private bool _uiHidden;
private bool _menuShown;
private List<ActionBarSlot> _actionBarSlots = new List<ActionBarSlot>();
private List<InputAction> _actionBarActions = new List<InputAction>();
public AetheriaInput Input { get; private set; }
public EquippedDockingBay DockingBay { get; private set; }
@ -197,7 +204,6 @@ public class ActionGameManager : MonoBehaviour
Input = new AetheriaInput();
Input.Global.Enable();
Input.UI.Enable();
_zoomLevelIndex = Settings.DefaultMinimapZoom;
Input.Player.MinimapZoom.performed += context =>
@ -232,44 +238,7 @@ public class ActionGameManager : MonoBehaviour
else Undock();
};
Input.Global.MainMenu.performed += context =>
{
if (EventSystem.current.currentSelectedGameObject?.GetComponent<TMP_InputField>() != null) return;
if (CurrentEntity == null) return;
if (MainMenu.gameObject.activeSelf)
{
_paused = false;
VolumeRenderer.EnableDepth = true;
MainMenu.gameObject.SetActive(false);
if (_menuShown)
{
Menu.gameObject.SetActive(true);
}
else
{
GameplayUI.gameObject.SetActive(true);
Cursor.lockState = CursorLockMode.Locked;
Input.Player.Enable();
}
}
else
{
_paused = true;
VolumeRenderer.EnableDepth = false;
MainMenu.gameObject.SetActive(true);
_menuShown = Menu.gameObject.activeSelf;
if (_menuShown)
{
Menu.gameObject.SetActive(false);
}
else
{
GameplayUI.gameObject.SetActive(false);
Cursor.lockState = CursorLockMode.None;
Input.Player.Disable();
}
}
};
Input.Global.MainMenu.performed += context => ToggleMainMenu();
Input.Player.EnterWormhole.performed += context =>
{
@ -349,123 +318,42 @@ public class ActionGameManager : MonoBehaviour
#endregion
#region Trigger Groups
#region Action Bar
Input.Player.PreviousWeaponGroup.performed += context =>
ActionBarSlot createBinding(string controlPath)
{
if (CurrentEntity.Parent != null) return;
SchematicDisplay.SelectedGroupIndex--;
};
var action = new InputAction(binding: controlPath);
_actionBarActions.Add(action);
var slot = Instantiate(ActionBarSlot, ActionBar);
_actionBarSlots.Add(slot);
action.started += context => slot.Binding?.Activate();
action.canceled += context => slot.Binding?.Deactivate();
return slot;
}
Input.Player.NextWeaponGroup.performed += context =>
{
if (CurrentEntity.Parent != null) return;
SchematicDisplay.SelectedGroupIndex++;
};
Input.Player.PreviousWeapon.performed += context =>
{
if (CurrentEntity.Parent != null) return;
SchematicDisplay.SelectedItemIndex--;
};
Input.Player.NextWeapon.performed += context =>
{
if (CurrentEntity.Parent != null) return;
SchematicDisplay.SelectedItemIndex++;
};
Input.Player.ToggleWeaponGroup.performed += context =>
{
if (CurrentEntity.Parent != null) return;
var item = SchematicDisplay.SchematicItems[SchematicDisplay.SelectedItemIndex];
if (CurrentEntity.TriggerGroups[SchematicDisplay.SelectedGroupIndex].items.Contains(item.Item))
CurrentEntity.TriggerGroups[SchematicDisplay.SelectedGroupIndex].items.Remove(item.Item);
else CurrentEntity.TriggerGroups[SchematicDisplay.SelectedGroupIndex].items.Add(item.Item);
foreach (var group in item.Item.BehaviorGroups.Values)
{
var weapon = group.GetBehavior<Weapon>();
if(weapon != null)
{
if (CurrentEntity.TriggerGroups[SchematicDisplay.SelectedGroupIndex].weapons.Contains(weapon))
CurrentEntity.TriggerGroups[SchematicDisplay.SelectedGroupIndex].weapons.Remove(weapon);
else CurrentEntity.TriggerGroups[SchematicDisplay.SelectedGroupIndex].weapons.Add(weapon);
}
}
SchematicDisplay.UpdateTriggerGroups();
};
var shift = createBinding("<Keyboard>/leftShift");
shift.InputIcon.sprite = ShiftIcon;
shift.InputLabel.gameObject.SetActive(false);
Input.Player.FireGroup1.started += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[0].weapons) s.Activate();
};
var left = createBinding("<Mouse>/leftButton");
left.InputIcon.sprite = MouseLeftIcon;
left.InputLabel.gameObject.SetActive(false);
var right = createBinding("<Mouse>/rightButton");
right.InputIcon.sprite = MouseLeftIcon;
right.InputIcon.transform.localScale = new Vector3(-1, 1, 1);
right.InputLabel.gameObject.SetActive(false);
var middle = createBinding("<Mouse>/middleButton");
middle.InputIcon.sprite = MouseMiddleIcon;
middle.InputLabel.gameObject.SetActive(false);
Input.Player.FireGroup1.canceled += context =>
for (int i = 1; i < 6; i++)
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[0].weapons) s.Deactivate();
};
Input.Player.FireGroup2.started += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[1].weapons) s.Activate();
};
Input.Player.FireGroup2.canceled += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[1].weapons) s.Deactivate();
};
Input.Player.FireGroup3.started += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[2].weapons) s.Activate();
};
Input.Player.FireGroup3.canceled += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[2].weapons) s.Deactivate();
};
Input.Player.FireGroup4.started += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[3].weapons) s.Activate();
};
Input.Player.FireGroup4.canceled += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[3].weapons) s.Deactivate();
};
Input.Player.FireGroup5.started += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[4].weapons) s.Activate();
};
Input.Player.FireGroup5.canceled += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[4].weapons) s.Deactivate();
};
Input.Player.FireGroup6.started += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[5].weapons) s.Activate();
};
Input.Player.FireGroup6.canceled += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[5].weapons) s.Deactivate();
};
var num = createBinding($"<Keyboard>/{i}");
num.InputIcon.gameObject.SetActive(false);
num.InputLabel.text = i.ToString();
}
#endregion
@ -579,6 +467,18 @@ public class ActionGameManager : MonoBehaviour
});
}
public void EnablePlayerInput()
{
Input.Player.Enable();
foreach (var a in _actionBarActions) a.Enable();
}
public void DisablePlayerInput()
{
Input.Player.Disable();
foreach (var a in _actionBarActions) a.Disable();
}
private void EnterWormhole(Wormhole wormhole)
{
if (!(CurrentEntity is Ship ship)) return;
@ -639,6 +539,45 @@ public class ActionGameManager : MonoBehaviour
}
}
private void ToggleMainMenu()
{
if (EventSystem.current.currentSelectedGameObject?.GetComponent<TMP_InputField>() != null) return;
if (CurrentEntity == null) return;
if (MainMenu.gameObject.activeSelf)
{
_paused = false;
VolumeRenderer.EnableDepth = true;
MainMenu.gameObject.SetActive(false);
if (_menuShown)
{
Menu.gameObject.SetActive(true);
}
else
{
GameplayUI.gameObject.SetActive(true);
EnablePlayerInput();
Cursor.lockState = CursorLockMode.Locked;
}
}
else
{
_paused = true;
VolumeRenderer.EnableDepth = false;
MainMenu.gameObject.SetActive(true);
_menuShown = Menu.gameObject.activeSelf;
if (_menuShown)
{
Menu.gameObject.SetActive(false);
}
else
{
GameplayUI.gameObject.SetActive(false);
Cursor.lockState = CursorLockMode.None;
DisablePlayerInput();
}
}
}
private void ToggleMenuTab(MenuTab tab)
{
if (EventSystem.current.currentSelectedGameObject?.GetComponent<TMP_InputField>() != null) return;
@ -649,7 +588,7 @@ public class ActionGameManager : MonoBehaviour
Menu.gameObject.SetActive(false);
if (CurrentEntity != null && CurrentEntity.Parent == null)
{
Input.Player.Enable();
EnablePlayerInput();
GameplayUI.gameObject.SetActive(true);
SchematicDisplay.ShowShip(CurrentEntity);
@ -659,7 +598,7 @@ public class ActionGameManager : MonoBehaviour
}
Cursor.lockState = CursorLockMode.None;
Input.Player.Disable();
DisablePlayerInput();
Menu.ShowTab(tab);
GameplayUI.gameObject.SetActive(false);
}
@ -832,7 +771,7 @@ public class ActionGameManager : MonoBehaviour
_visibleHostileIndicators.Clear();
if(_lockingIndicators!=null) foreach(var (_, indicator, _) in _lockingIndicators)
indicator.GetComponent<Prototype>().ReturnToPool();
Input.Player.Disable();
DisablePlayerInput();
Cursor.lockState = CursorLockMode.None;
GameplayUI.gameObject.SetActive(false);
@ -862,7 +801,7 @@ public class ActionGameManager : MonoBehaviour
_viewDirection = float3(CurrentEntity.Direction.x,0,CurrentEntity.Direction.y);
Cursor.lockState = CursorLockMode.Locked;
Input.Player.Enable();
EnablePlayerInput();
GameplayUI.gameObject.SetActive(true);
ShipPanel.Display(CurrentEntity, true);
SchematicDisplay.ShowShip(CurrentEntity);

View file

@ -1,6 +1,41 @@
using System;
using TMPro;
using Unity.Mathematics;
using UnityEngine;
using static Unity.Mathematics.math;
public class ItemPickup : MonoBehaviour
{
public float LabelFadeDuration = .5f;
public float LabelPersistDuration = 3;
public float LabelDisplayAngle = 15;
public float LabelDisplayMaxDistance = 500;
public Transform ScanLabelContainer;
public TextMeshPro ScanLabel;
public ItemInstance Item { get; set; }
public ZoneRenderer ZoneRenderer { get; set; }
public float3 ViewOrigin { get; set; }
public float3 ViewDirection { get; set; }
private float _displayTime;
private void Update()
{
var diff = (float3) transform.position - ViewOrigin;
var toThis = normalize(diff);
var viewAngle = acos(Vector3.Dot(toThis, ViewDirection)) * Mathf.Rad2Deg;
if (length(diff) < LabelDisplayMaxDistance && viewAngle < LabelDisplayAngle)
_displayTime = Time.time;
var targetAlpha = Time.time - _displayTime < LabelPersistDuration ? 1 : 0;
var c = ScanLabel.color;
c.a = c.a + sign(targetAlpha - c.a) * (Time.deltaTime / LabelFadeDuration);
ScanLabel.color = c;
ScanLabelContainer.rotation = Quaternion.LookRotation(-toThis);
}
private void OnDestroy()
{
ZoneRenderer.DestroyLoot(this);
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -21,6 +21,7 @@ public class ConsoleView : MonoBehaviour {
private string _inputString = "";
private CursorLockMode _previousCursorLockMode;
private bool _playerInputPreviouslyEnabled;
public string InputString
{
@ -113,17 +114,19 @@ public class ConsoleView : MonoBehaviour {
Visible = visible;
if(visible)
{
_playerInputPreviouslyEnabled = GameManager.Input.Player.enabled;
GameManager.Input.Global.Disable();
GameManager.Input.Player.Disable();
GameManager.DisablePlayerInput();
GameManager.Input.UI.Disable();
_previousCursorLockMode = Cursor.lockState;
Cursor.lockState = CursorLockMode.None;
}
else
{
if(_playerInputPreviouslyEnabled)
GameManager.EnablePlayerInput();
else GameManager.Input.UI.Enable();
GameManager.Input.Global.Enable();
GameManager.Input.Player.Enable();
GameManager.Input.UI.Enable();
Cursor.lockState = _previousCursorLockMode;
}
}

View file

@ -87,7 +87,7 @@ public class InventoryMenu : MonoBehaviour
var item = cargoEvent.CargoBay.Occupancy[cargoEvent.Position.x, cargoEvent.Position.y];
if (item != null)
{
var itemData = GameManager.ItemManager.GetData(item);
var itemData = item.Data.Value;
var itemPosition = cargoEvent.CargoBay.Cargo[item];
_originalOccupancy = cargoEvent.CargoBay.Data.InteriorShape.Inset(itemData.Shape, itemPosition, item.Rotation);
@ -244,7 +244,7 @@ public class InventoryMenu : MonoBehaviour
if (cargoEvent.CargoBay.ItemFits(_dragItem, _dragTargetPosition))
{
foreach (var cell in _dragCells) cell.gameObject.SetActive(false);
var itemData = GameManager.ItemManager.GetData(_dragItem);
var itemData = _dragItem.Data.Value;
panel.FakeItem = _dragItem;
panel.FakeOccupancy = cargoEvent.CargoBay.Data.InteriorShape.Inset(itemData.Shape, _dragTargetPosition, _dragItem.Rotation);
_dragTargetValid = true;
@ -258,7 +258,7 @@ public class InventoryMenu : MonoBehaviour
if (eqItem != null && entityEvent.Entity.ItemFits(eqItem, _dragTargetPosition))
{
foreach (var cell in _dragCells) cell.gameObject.SetActive(false);
var itemData = GameManager.ItemManager.GetData(_dragItem);
var itemData = _dragItem.Data.Value;
panel.FakeEquipment = _originalEquippedItem;
panel.FakeOccupancy = hullData.Shape.Inset(itemData.Shape, _dragTargetPosition, _dragItem.Rotation);
_dragTargetValid = true;
@ -325,7 +325,7 @@ public class InventoryMenu : MonoBehaviour
_selectedPanel = panel;
_selectedPosition = cargoEvent.CargoBay.Cargo[item];
_selectedItem = item;
_selectedItemData = GameManager.ItemManager.GetData(item);
_selectedItemData = item.Data.Value;
foreach (var v in _selectedItemData.Shape.Coordinates)
{
var v2 = _selectedItemData.Shape.Rotate(v, _selectedItem.Rotation) + _selectedPosition;

View file

@ -661,7 +661,7 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
return Color.white * .25f;
var c = float3(1);
if (GameManager.ItemManager.GetData(item) is EquippableItemData equippable)
if (item.Data.Value is EquippableItemData equippable)
c = HardpointData.GetColor(equippable.HardpointType);
if(!highlight)

View file

@ -387,7 +387,7 @@ public class PropertiesPanel : MonoBehaviour
private void AddItemProperties(ItemInstance item)
{
var data = ActionGameManager.CultCache.Get<ItemData>(item.Data);
var data = item.Data.Value;
AddProperty(data.Description);
@ -447,7 +447,7 @@ public class PropertiesPanel : MonoBehaviour
private string GetTitle(EquippableItem item)
{
var data = ActionGameManager.CultCache.Get<ItemData>(item.Data);
var data = item.Data.Value;
var (tier, upgrades) = GameManager.ItemManager.GetTier(item);
return
$"<color=#{ColorUtility.ToHtmlStringRGB(tier.Color.ToColor())}>{data.Name}</color><smallcaps><size=60%> ({tier.Name}{new string('+', upgrades)})";

View file

@ -13,7 +13,6 @@ public class SchematicDisplay : MonoBehaviour
{
public GameSettings Settings;
public Prototype ListElementPrototype;
public Prototype TriggerGroupPrototype;
public Color HeaderElementEnabledColor;
public Color HeaderElementDisabledColor;
@ -24,7 +23,6 @@ public class SchematicDisplay : MonoBehaviour
public Image HeatsinkBackground;
public GameObject AetherDriveUi;
public GameObject AetherDriveUiSpacer;
public TextMeshProUGUI EnergyLabel;
public TextMeshProUGUI CockpitTemperatureLabel;
@ -48,12 +46,6 @@ public class SchematicDisplay : MonoBehaviour
public RectTransform StrafeRPMFill;
public RectTransform TurnRPMFill;
public CanvasGroup TriggerGroups;
public float TriggerGroupsFadeDuration = .5f;
public float TriggerGroupsPersistDuration = 5f;
public Color TriggerGroupColor;
private Entity _entity;
private EquippableItem _hull;
private Radiator[] _radiators;
@ -63,14 +55,8 @@ public class SchematicDisplay : MonoBehaviour
private HeatStorage[] _heatStorages;
private EquippedCargoBay[] _cargoBays;
private SchematicDisplayItem[] _schematicItems;
private Graphic[] _groupGraphics;
private AetherDrive _aetherDrive;
private int _selectedGroupIndex;
private int _selectedItemIndex;
private bool _triggerGroupsVisible;
private float _triggerGroupsFadeOutTime;
private bool _enemy;
private Entity _player;
@ -79,31 +65,10 @@ public class SchematicDisplay : MonoBehaviour
get { return _schematicItems; }
}
public int SelectedItemIndex
{
get => _selectedItemIndex;
set
{
_selectedItemIndex = (value + _schematicItems.Length) % _schematicItems.Length;
UpdateTriggerGroups();
}
}
public int SelectedGroupIndex
{
get => _selectedGroupIndex;
set
{
_selectedGroupIndex = (value + Settings.GameplaySettings.TriggerGroupCount) % Settings.GameplaySettings.TriggerGroupCount;
UpdateTriggerGroups();
}
}
public class SchematicDisplayItem
{
public EquippedItem Item;
public SchematicListElement ListElement;
public SchematicTriggerGroupElement TriggerGroupElement;
public IProgressBehavior Cooldown;
// public ItemUsage ItemUsage;
public Weapon Weapon;
@ -117,7 +82,6 @@ public class SchematicDisplay : MonoBehaviour
foreach (var item in _schematicItems)
{
item.ListElement.GetComponent<Prototype>().ReturnToPool();
item.TriggerGroupElement?.GetComponent<Prototype>().ReturnToPool();
}
_entity = entity;
@ -128,7 +92,6 @@ public class SchematicDisplay : MonoBehaviour
_capacitors = entity.GetBehaviors<Capacitor>().ToArray();
_aetherDrive = entity.GetBehavior<AetherDrive>();
AetherDriveUi.SetActive(_aetherDrive != null);
AetherDriveUiSpacer.SetActive(_aetherDrive != null);
_radiators = entity.GetBehaviors<Radiator>().ToArray();
if (_radiators.Length == 0)
@ -149,7 +112,6 @@ public class SchematicDisplay : MonoBehaviour
{
Item = x,
ListElement = ListElementPrototype.Instantiate<SchematicListElement>(),
TriggerGroupElement = _enemy ? null : TriggerGroupPrototype.Instantiate<SchematicTriggerGroupElement>(),
Cooldown = _enemy ? null : (IProgressBehavior) x.Behaviors.FirstOrDefault(b=> b is IProgressBehavior),
// ItemUsage = _enemy ? null : (ItemUsage) x.Behaviors.FirstOrDefault(b=> b is ItemUsage),
Weapon = (Weapon) x.Behaviors.FirstOrDefault(b=>b is Weapon)
@ -164,72 +126,12 @@ public class SchematicDisplay : MonoBehaviour
{
x.ListElement.InfiniteAmmoIcon.gameObject.SetActive(x.Weapon.WeaponData.AmmoType == Guid.Empty);
x.ListElement.AmmoLabel.gameObject.SetActive(x.Weapon.WeaponData.AmmoType != Guid.Empty);
foreach (var group in x.TriggerGroupElement.GroupBackgrounds)
group.color = TriggerGroupColor;
}
}
if (!_enemy)
UpdateTriggerGroups();
}
public void UpdateTriggerGroups()
{
if (!_triggerGroupsVisible)
{
StartCoroutine(FadeInTriggerGroups());
_triggerGroupsVisible = true;
}
_triggerGroupsFadeOutTime = Time.time + TriggerGroupsPersistDuration;
for (var itemIndex = 0; itemIndex < _schematicItems.Length; itemIndex++)
{
var item = _schematicItems[itemIndex];
for (var groupIndex = 0; groupIndex < item.TriggerGroupElement.GroupBackgrounds.Length; groupIndex++)
{
var backgroundColor = TriggerGroupColor;
if (_selectedGroupIndex == groupIndex)
backgroundColor.a *= 2;
if (_selectedItemIndex == itemIndex)
backgroundColor.a *= 2;
item.TriggerGroupElement.GroupBackgrounds[groupIndex].color = backgroundColor;
item.TriggerGroupElement.GroupLabel[groupIndex].color =
_entity.TriggerGroups[groupIndex].items.Contains(item.Item) ? Color.white : Color.gray;
}
}
}
IEnumerator FadeInTriggerGroups()
{
var startTime = Time.time;
while (Time.time - startTime < TriggerGroupsFadeDuration)
{
var lerp = (Time.time - startTime) / TriggerGroupsFadeDuration;
TriggerGroups.alpha = lerp;
yield return null;
}
TriggerGroups.alpha = 1;
}
IEnumerator FadeOutTriggerGroups()
{
var startTime = Time.time;
while (Time.time - startTime < TriggerGroupsFadeDuration)
{
var lerp = (Time.time - startTime) / TriggerGroupsFadeDuration;
TriggerGroups.alpha = 1-lerp;
yield return null;
}
TriggerGroups.alpha = 0;
}
void Update()
{
if (_triggerGroupsVisible && _triggerGroupsFadeOutTime < Time.time)
{
_triggerGroupsVisible = false;
StartCoroutine(FadeOutTriggerGroups());
}
if (_entity != null)
{
if (!_enemy)
@ -237,11 +139,11 @@ public class SchematicDisplay : MonoBehaviour
OverrideIcon.SetActive(_entity.OverrideShutdown && cos(Time.time * OverrideIconBlinkSpeed) > 0);
ShieldIcon.SetActive(_entity.Shield!=null && _entity.Shield.Item.Active.Value);
if (_radiators.Length == 1)
RadiatorTemperatureLabel.text = $"{((int)(_radiators[0].Temperature - 273.15f)).ToString()}°C";
RadiatorTemperatureLabel.text = $"{((int)(_radiators[0].RadiatorTemperature - 273.15f)).ToString()}°C";
else if (_radiators.Length > 1)
RadiatorTemperatureLabel.text =
$"{((int)(_radiators.Min(r => r.Temperature) - 273.15f)).ToString()}-" +
$"{((int)(_radiators.Max(r => r.Temperature) - 273.15f)).ToString()}°C";
$"{((int)(_radiators.Min(r => r.RadiatorTemperature) - 273.15f)).ToString()}-" +
$"{((int)(_radiators.Max(r => r.RadiatorTemperature) - 273.15f)).ToString()}°C";
HeatsinkBackground.color = _entity.HeatsinksEnabled ? HeaderElementEnabledColor : HeaderElementDisabledColor;
if (_heatStorages.Length == 1)

View file

@ -220,7 +220,7 @@ public class TradeMenu : MonoBehaviour
data => data.Shape.Width*data.Shape.Height));
var items = Inventory.Cargo.Keys
.Select<ItemInstance, (ItemInstance item, ItemData data)>(ii=>(ii, GameManager.ItemManager.GetData(ii)));
.Select<ItemInstance, (ItemInstance item, ItemData data)>(ii=>(ii, ii.Data.Value));
if (MinimumSizeFilter.gameObject.activeSelf)
items = items.Where(i =>
@ -287,7 +287,7 @@ public class TradeMenu : MonoBehaviour
x => () =>
{
if (x.data is HullData)
return GameManager.DockedEntity.Children.Count(s => s.Hull.Data == x.data.ID && s is Ship {IsPlayerShip: true}).ToString();
return GameManager.DockedEntity.Children.Count(s => s.Hull.Data.LinkID == x.data.ID && s is Ship {IsPlayerShip: true}).ToString();
if(x.data is SimpleCommodityData)
return (_targetCargo.ItemsOfType.ContainsKey(x.data.ID) ? _targetCargo.ItemsOfType[x.data.ID].Cast<SimpleCommodity>().Sum(s=>s.Quantity) : 0).ToString();
return (_targetCargo.ItemsOfType.ContainsKey(x.data.ID) ? _targetCargo.ItemsOfType[x.data.ID].Count : 0).ToString();
@ -295,7 +295,7 @@ public class TradeMenu : MonoBehaviour
data =>
{
if (data is HullData)
return GameManager.DockedEntity.Children.Count(s => s.Hull.Data == data.ID && s is Ship {IsPlayerShip: true});
return GameManager.DockedEntity.Children.Count(s => s.Hull.Data.LinkID == data.ID && s is Ship {IsPlayerShip: true});
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;

View file

@ -272,7 +272,7 @@ public class TradeMenuDebug : MonoBehaviour
data => () =>
{
if (data is HullData)
return GameManager.DockedEntity.Children.Count(s => s.Hull.Data == data.ID && s is Ship {IsPlayerShip: true}).ToString();
return GameManager.DockedEntity.Children.Count(s => s.Hull.Data.LinkID == data.ID && s is Ship {IsPlayerShip: true}).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();
@ -280,7 +280,7 @@ public class TradeMenuDebug : MonoBehaviour
data =>
{
if (data is HullData)
return GameManager.DockedEntity.Children.Count(s => s.Hull.Data == data.ID && s is Ship {IsPlayerShip: true});
return GameManager.DockedEntity.Children.Count(s => s.Hull.Data.LinkID == data.ID && s is Ship {IsPlayerShip: true});
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;

View file

@ -80,7 +80,7 @@ public class ZoneRenderer : MonoBehaviour
private PlanetObject[] _suns;
public Dictionary<Wormhole, GameObject> WormholeInstances = new Dictionary<Wormhole, GameObject>();
private List<GridObject> _gridObjects = new List<GridObject>();
private List<ItemPickup> _loot = new List<ItemPickup>();
public Zone Zone { get; private set; }
public ItemManager ItemManager { get; set; }
@ -216,9 +216,9 @@ public class ZoneRenderer : MonoBehaviour
subscription.Dispose();
_zoneSubscriptions.Clear();
foreach(var gridObject in _gridObjects)
foreach(var gridObject in _loot)
if(gridObject) Destroy(gridObject.gameObject);
_gridObjects.Clear();
_loot.Clear();
foreach (var entity in Zone.Entities)
{
@ -409,6 +409,12 @@ public class ZoneRenderer : MonoBehaviour
void Update()
{
foreach (var loot in _loot)
{
loot.ViewOrigin = PerspectiveEntity.Position;
loot.ViewDirection = PerspectiveEntity.LookDirection;
}
if (SlimeRenderer.SpawnPositions.Length != _suns.Length)
SlimeRenderer.SpawnPositions = new Vector2[_suns.Length];
for (var i = 0; i < _suns.Length; i++)
@ -474,6 +480,11 @@ public class ZoneRenderer : MonoBehaviour
// MinimapTintQuad.transform.position = gravPos - Vector3.up*10;
}
public void DestroyLoot(ItemPickup loot)
{
_loot.Remove(loot);
}
public void DropItem(Vector3 position, Vector3 velocity, ItemInstance item)
{
var gridObject = item switch
@ -488,9 +499,19 @@ public class ZoneRenderer : MonoBehaviour
gridObject.Zone = Zone;
t.position = position;
gridObject.Velocity = velocity;
gridObject.gameObject.AddComponent<ItemPickup>().Item = item;
var itemPickup = gridObject.gameObject.GetComponent<ItemPickup>();
itemPickup.Item = item;
itemPickup.ZoneRenderer = this;
itemPickup.ScanLabel.text = item.Data.Value.Name;
if (item is CraftedItemInstance craftedItemInstance)
{
var c = ItemManager.GetTier(craftedItemInstance).tier.Color.ToColor();
c.a = 0;
itemPickup.ScanLabel.color = c;
}
else itemPickup.ScanLabel.color = new Color(.75f, .75f, .75f, 0);
gridObject.gameObject.AddComponent<TimedDestroy>().Duration = Settings.PickupLifetime;
_gridObjects.Add(gridObject);
_loot.Add(itemPickup);
}
}