Added hold trigger on action belts

This commit is contained in:
Nilton Constantino 2026-07-02 15:37:06 +01:00
parent 453aa2a7c4
commit 80cf81a451
No known key found for this signature in database
23 changed files with 1106 additions and 999 deletions

View File

@ -254,6 +254,8 @@ MonoBehaviour:
generateRandomId: 1
id: a2bcfde700d74b6397798ea30791316a
actionCategory: 0
activationMode: 1
holdDuration: 1.5
canBeDropped: 0
shouldDropFromBeltWhenActivated: 0
saveStationModelPrototype: {fileID: 3729166946730868368}

View File

@ -1,82 +1,5 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &59835503042511852
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3574551811571842361}
- component: {fileID: 3109608898981227386}
- component: {fileID: 2126827617727953615}
m_Layer: 0
m_Name: Requirements
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &3574551811571842361
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 59835503042511852}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 3065747640148493024}
- {fileID: 207078502424873291}
m_Father: {fileID: 3792200456268233999}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 0}
m_AnchoredPosition: {x: 45, y: 30}
m_SizeDelta: {x: -110, y: 20}
m_Pivot: {x: 0.5, y: 0}
--- !u!222 &3109608898981227386
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 59835503042511852}
m_CullTransparentMesh: 1
--- !u!114 &2126827617727953615
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 59835503042511852}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
m_Material: {fileID: 0}
m_Color: {r: 0.3584906, g: 0.3584906, b: 0.3584906, a: 0.5176471}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &905323619288396985
GameObject:
m_ObjectHideFlags: 0
@ -218,6 +141,7 @@ MonoBehaviour:
m_EditorClassIdentifier: Assembly-CSharp::Intrepid.Gameplay.Entities.Sentinel.ActionBelt.UI.ActionBeltUI
subscriptionId: event-listener.action-belt-ui
managedWindow: {fileID: 8491231505598950554}
actionBeltManager: {fileID: 0}
left: {fileID: 767535166410223100}
right: {fileID: 3069517553568958000}
center: {fileID: 402030598129591330}
@ -227,6 +151,8 @@ MonoBehaviour:
contentIconAnimation: {fileID: 4585446525987646012}
actionTextMeshPro: {fileID: 5762960713052211735}
localNewsTicker: {fileID: 7245772345663289783}
activationProgressSlider: {fileID: 8952480322169062639}
activationCancelReturnDuration: 0.5
--- !u!1 &1478941751597598230
GameObject:
m_ObjectHideFlags: 0
@ -385,7 +311,7 @@ GameObject:
- component: {fileID: 207078502424873291}
- component: {fileID: 8952480322169062639}
m_Layer: 0
m_Name: Slider
m_Name: ActivationProgressSlider
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@ -398,7 +324,7 @@ RectTransform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2169731595684440506}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
@ -406,12 +332,12 @@ RectTransform:
- {fileID: 7466791990491633505}
- {fileID: 7503623689909037506}
- {fileID: 6833698128948887784}
m_Father: {fileID: 3574551811571842361}
m_Father: {fileID: 3792200456268233999}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_AnchoredPosition: {x: 45, y: -22}
m_SizeDelta: {x: -110, y: -104}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &8952480322169062639
MonoBehaviour:
@ -432,13 +358,13 @@ MonoBehaviour:
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 0
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_NormalColor: {r: 0.10568706, g: 0.8962264, b: 0.11908737, a: 1}
m_HighlightedColor: {r: 0.25943398, g: 0.3588821, b: 1, a: 1}
m_PressedColor: {r: 0.93985593, g: 0.9716981, b: 0.0045834924, a: 1}
m_SelectedColor: {r: 0.7735849, g: 0.12041653, b: 0.22918065, a: 1}
m_DisabledColor: {r: 0.9339623, g: 0.057271298, b: 0.057271298, a: 1}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
@ -452,8 +378,8 @@ MonoBehaviour:
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 0
m_TargetGraphic: {fileID: 1207572472190608188}
m_Interactable: 1
m_TargetGraphic: {fileID: 771189666964977926}
m_FillRect: {fileID: 1871686618912787988}
m_HandleRect: {fileID: 500382630258192431}
m_Direction: 0
@ -500,143 +426,6 @@ RectTransform:
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: -20, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &4250407111632201249
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3065747640148493024}
- component: {fileID: 1115664675865992316}
- component: {fileID: 7080949131309913885}
m_Layer: 0
m_Name: RequirementsText
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!224 &3065747640148493024
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4250407111632201249}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 3574551811571842361}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &1115664675865992316
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4250407111632201249}
m_CullTransparentMesh: 1
--- !u!114 &7080949131309913885
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4250407111632201249}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: REQUIREMENTS
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 36
m_fontSizeBase: 36
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &4532779326603281172
GameObject:
m_ObjectHideFlags: 0
@ -741,8 +530,8 @@ RectTransform:
m_Children: []
m_Father: {fileID: 207078502424873291}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.25}
m_AnchorMax: {x: 1, y: 0.75}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
@ -761,21 +550,21 @@ MonoBehaviour:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5379922815610353284}
m_Enabled: 0
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Color: {r: 0.35686275, g: 0.35686275, b: 0.35686275, a: 0.5176471}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
@ -1798,7 +1587,7 @@ PrefabInstance:
addedObject: {fileID: 3709604138270240298}
- targetCorrespondingSourceObject: {fileID: 9098186480249319762, guid: 18f44b986d2754181a3a9695f6898774, type: 3}
insertIndex: -1
addedObject: {fileID: 3574551811571842361}
addedObject: {fileID: 207078502424873291}
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 18f44b986d2754181a3a9695f6898774, type: 3}
--- !u!114 &402030598129591330 stripped

View File

@ -70,7 +70,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 2, y: 2}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &8359634894432514940
CanvasRenderer:
@ -280,7 +280,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: -1, y: -1}
m_SizeDelta: {x: -6, y: -6}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &6269582886694731172
CanvasRenderer:

File diff suppressed because one or more lines are too long

View File

@ -8,5 +8,6 @@ namespace Intrepid.Core.Themes
{
Palettes = palettes;
}
}
}

View File

@ -2,6 +2,7 @@ using System;
using Intrepid.Utilities;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.UI;
namespace Intrepid.Core.Themes
{
@ -31,6 +32,20 @@ namespace Intrepid.Core.Themes
public Color Available => available;
public Color Clicked => clicked;
public Color Denied => denied;
public ColorBlock AsColorBlock(float colorMultiplier = 1f, float fadeDuration = 0.1f)
{
return new ColorBlock
{
normalColor = Available,
highlightedColor = Selected,
pressedColor = Clicked,
selectedColor = Selected,
disabledColor = Denied,
colorMultiplier = colorMultiplier,
fadeDuration = fadeDuration,
};
}
}
[Serializable]
@ -63,6 +78,20 @@ namespace Intrepid.Core.Themes
public Color Clicked => clicked;
public Color Denied => denied;
public Color Hijacked => hijacked;
public ColorBlock AsColorBlock(float colorMultiplier = 1f, float fadeDuration = 0.1f)
{
return new ColorBlock
{
normalColor = Available,
highlightedColor = Selected,
pressedColor = Clicked,
selectedColor = Selected,
disabledColor = Denied,
colorMultiplier = colorMultiplier,
fadeDuration = fadeDuration,
};
}
}
[Serializable]

View File

@ -1,24 +1,14 @@
using System;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Serialization;
namespace Intrepid.Core.Themes
{
[Serializable]
public class Palettes
{
[FormerlySerializedAs("main")] // don't remove that...
[Title("Bundle"), SerializeField, HideLabel, InlineProperty] private PaletteBundle bundle = new();
[Title("Common Colors"), PropertySpace(10)]
[SerializeField] private Color energyGauge = Color.yellow;
[SerializeField] private Color o2Gauge = Color.cyan;
[SerializeField] private Color counterFilling = Color.magenta;
public PaletteBundle Bundle => bundle;
public Color EnergyGaugeColor => energyGauge;
public Color O2GaugeColor => o2Gauge;
public Color CounterFillingColor => counterFilling;
}
}

View File

@ -1,4 +1,5 @@
using UnityEngine;
using UnityEngine.UI;
namespace Intrepid.Core.Themes
{
@ -14,5 +15,17 @@ namespace Intrepid.Core.Themes
public Color Selected => Palettes.Bundle.States.Selected;
public Color Clicked => Palettes.Bundle.States.Clicked;
public Color Denied => Palettes.Bundle.States.Denied;
public ColorBlock AsColorBlock(
float colorMultiplier = 1f,
float fadeDuration = 0.1f,
bool interactable = false)
{
if (interactable)
{
return Palettes.Bundle.Interactable.AsColorBlock(colorMultiplier, fadeDuration);
}
return Palettes.Bundle.States.AsColorBlock(colorMultiplier, fadeDuration);
}
}
}

View File

@ -0,0 +1,8 @@
namespace Intrepid.Gameplay.Entities.Player.ActionBelt
{
public enum ActionActivationMode
{
Instant,
Hold,
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c67f1d16fb114a878f33f49c21a5e710
timeCreated: 1782997848

View File

@ -9,15 +9,22 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt
public abstract class ActionCallable : Identification
{
[GroupConfigurations, SerializeField, EnumPaging] private ActionCategory actionCategory = ActionCategory.General;
[GroupConfigurations, SerializeField, EnumPaging] private ActionActivationMode activationMode = ActionActivationMode.Instant;
[ShowIf(nameof(IsHoldActivation))]
[GroupConfigurations, SerializeField, Range(0, 5)] private float holdDuration = 1.5f;
[GroupConfigurations, SerializeField, ToggleLeft, PropertySpace] private bool canBeDropped;
[ShowIf("IsNotTerminal")]
[ShowIf(nameof(IsNotTerminal))]
[GroupConfigurations, SerializeField, ToggleLeft, PropertySpace] private bool shouldDropFromBeltWhenActivated;
private bool IsNotTerminal => actionCategory != ActionCategory.Terminal;
private bool IsHoldActivation => activationMode == ActionActivationMode.Hold;
private ActionCategory ActionCategory => actionCategory;
private bool CanBeDropped => canBeDropped;
private bool ShouldDropFromBeltWhenActivated => shouldDropFromBeltWhenActivated;
protected ActionCategory ActionCategory => actionCategory;
protected ActionActivationMode ActivationMode => activationMode;
protected float HoldDuration => IsHoldActivation ? holdDuration : 0f;
protected bool CanBeDropped => canBeDropped;
protected bool ShouldDropFromBeltWhenActivated => shouldDropFromBeltWhenActivated;
protected virtual LocalizationTag ActionLocalization { get; }
protected virtual LocalizationTag DescriptionLocalization { get; }
protected virtual List<string> Parameters { get; } = new();
@ -37,6 +44,8 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt
},
CanBeDropped = CanBeDropped,
ActionCategory = ActionCategory,
ActivationMode = ActivationMode,
HoldDuration = HoldDuration,
ActionLocalization = ActionLocalization,
DescriptionLocalization = DescriptionLocalization,
DescriptionParams = Functions.GetParams(Parameters),

View File

@ -12,6 +12,8 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt
public ActionIdentifier ActionIdentifier { get; set; } = new();
public bool CanBeDropped { get; set; }
public ActionCategory ActionCategory { get; set; } = ActionCategory.General;
public ActionActivationMode ActivationMode { get; set; } = ActionActivationMode.Instant;
public float HoldDuration { get; set; }
public ILocalization ActionLocalization { get; set; }
public ILocalization DescriptionLocalization { get; set; }
public Parameter[] DescriptionParams { get; set; }
@ -21,6 +23,7 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt
return false;
};
public override string ToString()
{
return $"Id: {ActionIdentifier.Id}, Category: {ActionCategory}";

View File

@ -0,0 +1,6 @@
namespace Intrepid.Gameplay.Entities.Player.ActionBelt.Events
{
public class ActionBeltActivationCanceledEvent : ActionBeltBaseEvent
{
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 56c73f41c0e548c3a5625f4ca2c1aea4
timeCreated: 1782998528

View File

@ -0,0 +1,7 @@
namespace Intrepid.Gameplay.Entities.Player.ActionBelt.Events
{
public class ActionBeltActivationProgressEvent : ActionBeltBaseEvent
{
public float Progress { get; set; }
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 15d2177c65084174b404c1ca2d4a3ae2
timeCreated: 1782998496

View File

@ -0,0 +1,6 @@
namespace Intrepid.Gameplay.Entities.Player.ActionBelt.Events
{
public class ActionBeltActivationStartedEvent : ActionBeltBaseEvent
{
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d1c0f45254524274bec1b9f34b98ae00
timeCreated: 1782998549

View File

@ -2,6 +2,7 @@ using System;
using System.Collections;
using Intrepid.Core.UI;
using Intrepid.Core.UI.Dialog;
using Intrepid.Diagnostics;
using Intrepid.GameManagers;
using Intrepid.Gameplay.Entities.Player.ActionBelt.Events;
using Intrepid.Gameplay.Entities.Player.UI;
@ -11,6 +12,7 @@ using Intrepid.Utilities.Sprite;
using Sirenix.OdinInspector;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Intrepid.Gameplay.Entities.Player.ActionBelt.UI
{
@ -26,6 +28,8 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt.UI
[GroupInjections, SerializeField] private SpriteAnimationController contentIconAnimation;
[GroupInjections, SerializeField, PropertySpace] private TextMeshProUGUI actionTextMeshPro;
[GroupInjections, SerializeField] private NewsTickerUI localNewsTicker;
[GroupInjections, SerializeField] private Slider activationProgressSlider;
[GroupConfigurations, SerializeField, Range(0.01f, 1f)] private float activationCancelReturnDuration = .5f;
private UIActionBeltTheme CurrentTheme { get; set; }
private Func<ActionEnvelope> GetFocus { get; set; }
@ -33,6 +37,7 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt.UI
private Func<ActionEnvelope> SneakPeekLeft { get; set; }
private Func<int> GetNumberOfActionsInBelt { get; set; } = () => 0;
private bool IsOptionActive => GetNumberOfActionsInBelt() > 1;
private Coroutine ActivationCancelReturnCoroutine { get; set; }
protected override void InitializeVariables()
{
@ -40,11 +45,15 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt.UI
SneakPeekRight = () => actionBeltManager.PeekRight;
SneakPeekLeft = () => actionBeltManager.PeekLeft;
GetNumberOfActionsInBelt = () => actionBeltManager.Count;
ResetActivationProgress();
activationProgressSlider.gameObject.SetActive(false);
}
protected override void OnBootstrap()
{
UpdateTheme();
ResetActivationProgress();
activationProgressSlider.gameObject.SetActive(false);
}
private void UpdateTheme()
@ -58,6 +67,7 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt.UI
local.Theme = theme.Local;
actionTextMeshPro.color = theme.TextColor;
localNewsTicker.TextMesh.color = theme.TextColor;
activationProgressSlider.colors = theme.Main.Button.AsColorBlock();
}
protected override void Subscriptions()
@ -65,6 +75,10 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt.UI
Subscribe<ActionBeltShowEvent>(_ => ManagedWindow.Show());
Subscribe<ActionBeltHideEvent>(_ => ManagedWindow.Hide());
Subscribe<ActionBeltActivationStartedEvent>(WhenActionBeltActivationStarted);
Subscribe<ActionBeltActivationProgressEvent>(WhenActionBeltActivationProgress);
Subscribe<ActionBeltActivationCanceledEvent>(WhenActionBeltActivationCanceled);
Subscribe<ActionBeltUIToRightEvent>(WhenActionBeltNextRight);
Subscribe<ActionBeltUIToLeftEvent>(WhenActionBeltNextLeft);
@ -72,6 +86,60 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt.UI
Subscribe<ActionBeltUIDropEvent>(WhenActionBeltUIDrop);
}
private void WhenActionBeltActivationStarted(ActionBeltActivationStartedEvent e)
{
DLogger.LogDebug("activation started");
}
private void WhenActionBeltActivationProgress(ActionBeltActivationProgressEvent e)
{
StopActivationCancelReturn();
activationProgressSlider.value = Mathf.Clamp01(e.Progress);
}
private void WhenActionBeltActivationCanceled(ActionBeltActivationCanceledEvent e)
{
StartActivationCancelReturn();
}
private void StartActivationCancelReturn()
{
StopActivationCancelReturn();
ActivationCancelReturnCoroutine = StartCoroutine(ReturnActivationProgressToZero());
}
private void StopActivationCancelReturn()
{
if (ActivationCancelReturnCoroutine == null)
{
return;
}
StopCoroutine(ActivationCancelReturnCoroutine);
ActivationCancelReturnCoroutine = null;
}
private IEnumerator ReturnActivationProgressToZero()
{
var startValue = activationProgressSlider.value;
var elapsedTime = 0f;
while (elapsedTime < activationCancelReturnDuration)
{
elapsedTime += Time.deltaTime;
var time = Mathf.Clamp01(elapsedTime / activationCancelReturnDuration);
var easedTime = 1f - Mathf.Pow(1f - time, 3f);
activationProgressSlider.value = Mathf.Lerp(startValue, 0f, easedTime);
yield return null;
}
activationProgressSlider.value = 0f;
ActivationCancelReturnCoroutine = null;
}
private void WhenActionBeltUIDrop(ActionBeltUIDropEvent e)
{
if (!actionBeltManager.IsOperational) return;
@ -114,6 +182,8 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt.UI
{
if (!actionBeltManager.IsOperational) return;
ResetActivationProgress();
center.BlinkBorderActionTaken();
if (local.gameObject.activeSelf) local.BlinkBorderActionTaken();
}
@ -121,6 +191,15 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt.UI
private void UpdateContent()
{
var focus = GetFocus();
if (focus.ActivationMode == ActionActivationMode.Instant)
{
ResetActivationProgress();
activationProgressSlider.gameObject.SetActive(false);
}
else
{
activationProgressSlider.gameObject.SetActive(true);
}
contentIconAnimation.SpriteAnimation.ChangeAnimation(MapActionCategoryRUNNING(focus.ActionCategory));
actionTextMeshPro.text = Proxy.Instance.I18N.Localise(focus.ActionLocalization);
if (focus.DescriptionLocalization.IsNull())
@ -135,12 +214,23 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt.UI
}
}
private void ResetActivationProgress()
{
StopActivationCancelReturn();
if (activationProgressSlider.IsNull())
{
return;
}
activationProgressSlider.value = 0f;
}
private void Update()
{
UpdateTheme();
if (!actionBeltManager.IsOperational)
{
ResetActivationProgress();
Proxy.Instance.EventBus.Raise(new ActionBeltUICloseEvent());
return;
}
@ -148,6 +238,7 @@ namespace Intrepid.Gameplay.Entities.Player.ActionBelt.UI
switch (GetNumberOfActionsInBelt())
{
case 0:
ResetActivationProgress();
Proxy.Instance.EventBus.Raise(new ActionBeltUICloseEvent());
return;
case 1:

View File

@ -10,6 +10,8 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.Inputs
public Func<Vector2> Movement { get; set; }
public Func<bool> Interact { get; set; }
public Func<bool> InteractHeld { get; set; }
public Func<bool> InteractReleased { get; set; }
public Func<bool> DPadLeft { get; set; }
public Func<bool> DPadRight { get; set; }
public Func<bool> EnterPDA { get; set; }
@ -28,6 +30,8 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.Inputs
? inputActions.Movement.ReadValue<Vector2>()
: Vector2.zero,
Interact = () => locking.IsNotLocked && inputActions.Interact.WasPressedThisFrame(),
InteractHeld = () => locking.IsNotLocked && inputActions.Interact.IsPressed(),
InteractReleased = () => locking.IsNotLocked && inputActions.Interact.WasReleasedThisFrame(),
DPadLeft = () => locking.IsNotLocked && inputActions.DPadLeft.WasPressedThisFrame(),
DPadRight = () => locking.IsNotLocked && inputActions.DPadRight.WasPressedThisFrame(),
EnterPDA = () => locking.IsNotLocked && inputActions.EnterPDA.WasPressedThisFrame(),

View File

@ -84,6 +84,8 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.Inputs
// No Buffered Input Actions
public Func<Vector2> Movement => SentinelInputActions.Movement;
public Func<bool> Interact => SentinelInputActions.Interact;
public Func<bool> InteractHeld => SentinelInputActions.InteractHeld;
public Func<bool> InteractReleased => SentinelInputActions.InteractReleased;
public Func<bool> DPadLeft => SentinelInputActions.DPadLeft;
public Func<bool> DPadRight => SentinelInputActions.DPadRight;
public Func<bool> Reset => SentinelInputActions.Reset;

View File

@ -7,6 +7,8 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.Inputs
{
Func<Vector2> Movement { get; }
Func<bool> Interact { get; }
Func<bool> InteractHeld { get; }
Func<bool> InteractReleased { get; }
Func<bool> DPadLeft { get; }
Func<bool> DPadRight { get; }

View File

@ -1,13 +1,18 @@
using Intrepid.Core.Entities;
using Intrepid.Diagnostics;
using Intrepid.GameManagers;
using Intrepid.Gameplay.Entities.Player.ActionBelt;
using Intrepid.Gameplay.Entities.Player.ActionBelt.Events;
using Intrepid.Gameplay.Entities.Player.Sentinel.Cadence;
using Intrepid.Utilities;
using UnityEngine;
namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine
{
public abstract class SentinelState : EntityState<SentinelStateType, SentinelState>, IControllableEntityBrain
{
private Timer ActionBeltHoldTimer { get; } = new();
public SentinelBrain Brain { get; set; }
public override bool CanEnterState => true;
@ -42,13 +47,26 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine
protected void VerifyInteraction()
{
if (!Brain.ActionBeltManager.IsOperational) return;
if (Brain.ActionBeltManager.IsEmpty) return;
if (!Brain.ActionBeltManager.IsOperational || Brain.ActionBeltManager.IsEmpty)
{
ResetActionBeltHoldActivation();
return;
}
var actionEnvelope = Brain.ActionBeltManager.Focus;
if (ActionActivationMode.Hold == actionEnvelope.ActivationMode)
{
VerifyHoldInteraction(actionEnvelope);
}
else
{
ResetActionBeltHoldActivation();
if (Brain.InputResolver.Sentinel.Interact())
{
Proxy.Instance.EventBus.Raise(new ActionBeltTakeActionEvent());
return;
}
}
var left = Brain.InputResolver.Sentinel.DPadLeft();
var right = Brain.InputResolver.Sentinel.DPadRight();
@ -56,14 +74,67 @@ namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine
if (left && right) return;
if (left)
{
ResetActionBeltHoldActivation();
Proxy.Instance.EventBus.Raise(new ActionBeltNextLeftEvent());
}
if (right)
{
ResetActionBeltHoldActivation();
Proxy.Instance.EventBus.Raise(new ActionBeltNextRightEvent());
}
}
private void VerifyHoldInteraction(ActionEnvelope actionEnvelope)
{
if (Brain.InputResolver.Sentinel.Interact())
{
ActionBeltHoldTimer.Start();
Proxy.Instance.EventBus.Raise(new ActionBeltActivationStartedEvent());
}
if (Brain.InputResolver.Sentinel.InteractReleased())
{
ResetActionBeltHoldActivation();
return;
}
if (ActionBeltHoldTimer.IsNotRunning)
{
return;
}
if (!Brain.InputResolver.Sentinel.InteractHeld())
{
ResetActionBeltHoldActivation();
return;
}
ActionBeltHoldTimer.Update(Time.deltaTime);
var holdDuration = Mathf.Max(0.01f, actionEnvelope.HoldDuration);
var progress = Mathf.Clamp01((float)ActionBeltHoldTimer.ElapsedTime / holdDuration);
Proxy.Instance.EventBus.Raise(new ActionBeltActivationProgressEvent
{
Progress = progress,
});
if (!ActionBeltHoldTimer.Check(holdDuration))
{
return;
}
ActionBeltHoldTimer.Stop();
Proxy.Instance.EventBus.Raise(new ActionBeltTakeActionEvent());
}
private void ResetActionBeltHoldActivation()
{
if (ActionBeltHoldTimer.IsNotRunning) return;
ActionBeltHoldTimer.Stop();
Proxy.Instance.EventBus.Raise(new ActionBeltActivationCanceledEvent());
}
protected void KeepCadenceWithInputAt(CadenceProfile nextProfile, float targetTime, float inputAt)
{
var previousEvaluation = CadenceService.Instance.TryEndCadenceProfileWithInputAt(inputAt);