diff --git a/Configs/ControlHints/AvailableActions.conf b/Configs/ControlHints/AvailableActions.conf index 53a1d0a..48939d4 100644 --- a/Configs/ControlHints/AvailableActions.conf +++ b/Configs/ControlHints/AvailableActions.conf @@ -1,14 +1,2 @@ SCR_AvailableActionsDisplay { - m_aActions { - SCR_AvailableActionContext "{68D6FBBC15855FA5}" { - m_sTag "SCR_VoiceRangeUp" - m_sAction "SCR_VoiceRangeUp" - m_sName "Reichweite erhöhen" - } - SCR_AvailableActionContext "{68D6FBBC798C47B3}" { - m_sTag "SCR_VoiceRangeDown" - m_sAction "SCR_VoiceRangeDown" - m_sName "Reichweite verringern" - } - } } \ No newline at end of file diff --git a/Configs/System/chimeraInputCommon.conf b/Configs/System/chimeraInputCommon.conf index 66f4e1b..0d78e17 100644 --- a/Configs/System/chimeraInputCommon.conf +++ b/Configs/System/chimeraInputCommon.conf @@ -1,12 +1,11 @@ ActionManager { Actions { - Action SCR_VoiceRangeUp { - Type Digital + Action GTG_RangeUp { InputSource InputSourceSum "{68D6FBBD3B92F0A9}" { Sources { InputSourceValue "{68D6FBBD04A41546}" { FilterPreset "pressed" - Input "keyboard:KC_ADD" + Input "keyboard:KC_O" Filter InputFilterDown "{68D6FBBD15448370}" { } } @@ -27,12 +26,11 @@ ActionManager { } } } - Action SCR_VoiceRangeDown { - Type Digital + Action GTG_RangeDown { InputSource InputSourceSum "{68D6FBBD58BA9137}" { Sources { InputSourceValue "{68D6FBBDA234B42A}" { - Input "keyboard:KC_SUBTRACT" + Input "keyboard:KC_P" Filter InputFilterDown "{68D6FBBD9D2AB21E}" { } } @@ -57,12 +55,11 @@ ActionManager { Contexts { ActionContext CharacterGeneralContext { Actions { - Action SCR_VoiceRangeUp { - Type Digital + Action GTG_RangeUp { InputSource InputSourceSum "{68D910D1566B1F69}" { Sources { InputSourceValue "{68D910D19D8247E3}" { - Input "keyboard:KC_ADD" + Input "keyboard:KC_O" Filter InputFilterDown "{68D910D1E211D9EE}" { } } @@ -83,12 +80,11 @@ ActionManager { } } } - Action SCR_VoiceRangeDown { - Type Digital + Action GTG_RangeDown { InputSource InputSourceSum "{68D910D018C9121B}" { Sources { InputSourceValue "{68D910D06648D071}" { - Input "keyboard:KC_SUBTRACT" + Input "keyboard:KC_P" Filter InputFilterDown "{68D910D06BF572E0}" { } } @@ -110,6 +106,10 @@ ActionManager { } } } + ActionRefs +{ + "SCR_VoiceRangeUp" + "SCR_VoiceRangeDown" + } } } } \ No newline at end of file diff --git a/Configs/System/keyBindingMenu.conf b/Configs/System/keyBindingMenu.conf index 2244120..4377039 100644 --- a/Configs/System/keyBindingMenu.conf +++ b/Configs/System/keyBindingMenu.conf @@ -5,12 +5,12 @@ SCR_KeyBindingMenuConfig { m_sDisplayName "GTG" m_KeyBindingEntries { SCR_KeyBindingEntry "{68D6FBA228BCCB97}" { - m_sActionName "SCR_VoiceRangeUp" - m_sDisplayName "Voicce Range +" + m_sActionName "GTG_RangeUp" + m_sDisplayName "Voice Range +" m_sPreset "pressed" } SCR_KeyBindingEntry "{68D6FBA207B1F8D9}" { - m_sActionName "SCR_VoiceRangeDown" + m_sActionName "GTG_RangeDown" m_sDisplayName "Voice Range -" m_sPreset "pressed" } diff --git a/Prefabs/Characters/Core/Character_Base.et b/Prefabs/Characters/Core/Character_Base.et index 65ae021..fb66c46 100644 --- a/Prefabs/Characters/Core/Character_Base.et +++ b/Prefabs/Characters/Core/Character_Base.et @@ -1,6 +1,12 @@ SCR_ChimeraCharacter { ID "520EC961A090B1EE" components { + SCR_HUDManagerComponent "{68D910D79D85CD62}" { + InfoDisplays { + SCR_VoiceRangeDisplay "{68D910D7E3AD384E}" { + } + } + } SCR_VoNLoud "{68D6FBB9294FC854}" { } SCR_VoNNormal "{68D6FBB92B468B18}" { diff --git a/resourceDatabase.rdb b/resourceDatabase.rdb index c4a8114..9ccfea1 100644 Binary files a/resourceDatabase.rdb and b/resourceDatabase.rdb differ diff --git a/scripts/Game/VON/SCR_VoiceRangeController.c b/scripts/Game/VON/SCR_VoiceRangeController.c index f1ea46c..21f19ef 100644 --- a/scripts/Game/VON/SCR_VoiceRangeController.c +++ b/scripts/Game/VON/SCR_VoiceRangeController.c @@ -12,44 +12,58 @@ class SCR_VoiceRangeController: ScriptComponent { [Attribute("100", UIWidgets.Slider, "Maximale Reichweite", "1 100 1")] protected int m_iMaxRange; - [Attribute("1", UIWidgets.Slider, "Schrittgröße (Meter pro Tastendruck)", "1 50 1")] + [Attribute("1", UIWidgets.Slider, "Schrittgroesse (Meter pro Tastendruck)", "1 50 1")] protected int m_iStepSize; - protected ref Shape m_RangeCircleShape; + // Speichert das echte Ring-Objekt (Decal) in der Spielwelt + protected IEntity m_RangeRingEntity; + + // Timer für den Cooldown (verhindert das +1 / -1 Springen bei analogen Tasten) + protected int m_iLastInputTime = 0; static SCR_VoiceRangeController GetInstance() { if (!GetGame().GetPlayerController()) return null; return SCR_VoiceRangeController.Cast(GetGame().GetPlayerController().FindComponent(SCR_VoiceRangeController)); } - void SCR_VoiceRangeController(IEntityComponentSource src, IEntity ent, IEntity parent) { - SetEventMask(ent, EntityEvent.INIT); + override void OnPostInit(IEntity owner) { + super.OnPostInit(owner); + SetEventMask(owner, EntityEvent.INIT); } protected override void EOnInit(IEntity owner) { if (!GetGame().GetInputManager()) return; - // Die Actions, die aufgerufen werden, wenn du + oder - drückst - GetGame().GetInputManager().AddActionListener("SCR_VoiceRangeUp", EActionTrigger.DOWN, IncreaseRange); - GetGame().GetInputManager().AddActionListener("SCR_VoiceRangeDown", EActionTrigger.DOWN, DecreaseRange); + // HIER STEHEN DIE NAMEN DER ACTIONS + GetGame().GetInputManager().AddActionListener("GTG_RangeUp", EActionTrigger.DOWN, IncreaseRange); + GetGame().GetInputManager().AddActionListener("GTG_RangeDown", EActionTrigger.DOWN, DecreaseRange); } void IncreaseRange() { + // Blockiert den Input, wenn seit dem letzten Druck nicht mind. 250ms vergangen sind + if (System.GetTickCount() < m_iLastInputTime + 250) return; + m_iLastInputTime = System.GetTickCount(); // Speichert die aktuelle Zeit + + Print("GTG Voice: PLUS gedrueckt!", LogLevel.WARNING); ChangeRange(1); } void DecreaseRange() { + // Blockiert den Input auch hier für 250ms + if (System.GetTickCount() < m_iLastInputTime + 250) return; + m_iLastInputTime = System.GetTickCount(); + + Print("GTG Voice: MINUS gedrueckt!", LogLevel.WARNING); ChangeRange(-1); } void ChangeRange(int direction) { - // Berechnet die neue Reichweite basierend auf der Schrittgröße int newRange = Math.ClampInt(m_iCurrentRange + (direction * m_iStepSize), m_iMinRange, m_iMaxRange); - // Nichts tun, wenn das Limit bereits erreicht ist if (m_iCurrentRange == newRange) return; m_iCurrentRange = newRange; + Print("GTG Voice: Neue Reichweite ist " + m_iCurrentRange.ToString(), LogLevel.WARNING); ApplyRangeToVON(); UpdateUI(); @@ -79,41 +93,70 @@ class SCR_VoiceRangeController: ScriptComponent { } void UpdateUI() { + Print("GTG Voice: Suche HUD Manager...", LogLevel.WARNING); SCR_HUDManagerComponent hud = SCR_HUDManagerComponent.Cast(GetOwner().FindComponent(SCR_HUDManagerComponent)); - if (!hud) return; - - SCR_VoiceRangeDisplay display = SCR_VoiceRangeDisplay.Cast(hud.FindInfoDisplay(SCR_VoiceRangeDisplay)); - if (display) { - // Übergibt die exakte Meterzahl an dein UI - display.UpdateRangeText(m_iCurrentRange); + if (!hud) { + Print("GTG Voice: FEHLER - HUD Manager nicht auf dem PlayerController gefunden!", LogLevel.ERROR); + return; } + + Print("GTG Voice: Suche VoiceRangeDisplay...", LogLevel.WARNING); + SCR_VoiceRangeDisplay display = SCR_VoiceRangeDisplay.Cast(hud.FindInfoDisplay(SCR_VoiceRangeDisplay)); + if (!display) { + Print("GTG Voice: FEHLER - SCR_VoiceRangeDisplay fehlt in den Info Displays des HUD Managers!", LogLevel.ERROR); + return; + } + + Print("GTG Voice: Display gefunden! Sende Text an UI...", LogLevel.WARNING); + display.UpdateRangeText(m_iCurrentRange); } void DrawRangeCircle() { IEntity player = GetGame().GetPlayerController().GetControlledEntity(); - if (!player) return; - - if (m_RangeCircleShape) { - m_RangeCircleShape = null; + if (!player) { + Print("GTG Voice: FEHLER - Kein spielbarer Charakter (Koerper) fuer den Kreis gefunden!", LogLevel.ERROR); + return; } - vector mat[4]; - player.GetTransform(mat); - - vector boundsMin, boundsMax; - player.GetBounds(boundsMin, boundsMax); - mat[3][1] = mat[3][1] + boundsMin[1] + 0.1; + // Wenn schon ein Ring existiert, sofort löschen + if (m_RangeRingEntity) { + SCR_EntityHelper.DeleteEntityAndChildren(m_RangeRingEntity); + m_RangeRingEntity = null; + } - int color = ARGB(200, 50, 150, 255); - - // Zeichnet den Kreis mit dem exakten Radius in Metern (m_iCurrentRange) - m_RangeCircleShape = Shape.CreateCylinder(color, ShapeFlags.WIREFRAME | ShapeFlags.TRANSP, mat, m_iCurrentRange, 0.05); + // 1. Hole absolute Welt-Position der Füße + vector playerPos = player.GetOrigin(); + // 2. Erstelle Spawn-Parameter + EntitySpawnParams spawnParams = EntitySpawnParams(); + spawnParams.TransformMode = ETransformMode.WORLD; + spawnParams.Transform[3] = playerPos; + + // 3. Spawne das Decal-Prefab + ResourceName ringPrefab = "{E6268D7D980F8A5D}Prefabs/Props/Military/Compositions/US/Decals/Decal_Helipad_US.et"; + Resource res = Resource.Load(ringPrefab); + + if (res && res.IsValid()) { + m_RangeRingEntity = GetGame().SpawnEntityPrefab(res, GetGame().GetWorld(), spawnParams); + + if (m_RangeRingEntity) { + // Skaliere das Objekt passend zu der Meter-Reichweite + float scale = m_iCurrentRange * 1.0; + m_RangeRingEntity.SetScale(scale); + } + } else { + Print("GTG Voice: Ring Prefab konnte nicht geladen werden!", LogLevel.ERROR); + } + + // Nach 2 Sekunden restlos aus der Welt löschen GetGame().GetCallqueue().Remove(HideRangeCircle); GetGame().GetCallqueue().CallLater(HideRangeCircle, 2000, false); } void HideRangeCircle() { - m_RangeCircleShape = null; + if (m_RangeRingEntity) { + SCR_EntityHelper.DeleteEntityAndChildren(m_RangeRingEntity); + m_RangeRingEntity = null; + } } } \ No newline at end of file diff --git a/scripts/Game/VON/SCR_VoiceRangeDisplay.c b/scripts/Game/VON/SCR_VoiceRangeDisplay.c index e7377b7..0c92a9f 100644 --- a/scripts/Game/VON/SCR_VoiceRangeDisplay.c +++ b/scripts/Game/VON/SCR_VoiceRangeDisplay.c @@ -6,7 +6,7 @@ class SCR_VoiceRangeDisplay: SCR_InfoDisplay { super.OnStartDraw(owner); if (!m_wRoot) { - m_wRoot = GetGame().GetWorkspace().CreateWidgets("68D6F5422C10ACFC/UI/layouts/VoiceRange/VoiceRangeDynamicNumber.layout"); + m_wRoot = GetGame().GetWorkspace().CreateWidgets("{52CB3045C167E6D8}UI/layouts/VoiceRange/VoiceRangeDynamicNumber.layout"); if (!m_wRoot) return; } @@ -19,18 +19,11 @@ class SCR_VoiceRangeDisplay: SCR_InfoDisplay { } void UpdateRangeText(int range) { - if (!m_wRangeText) return; - - m_wRangeText.SetText(range.ToString() + " m"); - m_wRangeText.SetVisible(true); - - if (m_FadeComponent) { - m_FadeComponent.FadeIn(true); + if (!m_wRangeText) { + Print("GTG Voice: FEHLER - TextWidget 'RangeText' nicht gefunden! Layout-Pfad falsch?", LogLevel.ERROR); + return; } - - GetGame().GetCallqueue().Remove(StartFadeOut); - GetGame().GetCallqueue().CallLater(StartFadeOut, 3000, false); - } + } protected void StartFadeOut() { if (m_FadeComponent) {