From a2a5f04dd4ea5ff4be054d7b06d59b38ba7ea16d Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 11 Mar 2026 19:14:40 +0100 Subject: [PATCH] V 0.5 --- Configs/ControlHints/AvailableActions.conf | 14 ++ .../ControlHints/AvailableActions.conf.meta | 17 +++ Configs/System/chimeraInputCommon.conf | 57 +++++++++ Configs/System/chimeraInputCommon.conf.meta | 17 +++ Configs/System/keyBindingMenu.conf | 20 +++ Configs/System/keyBindingMenu.conf.meta | 17 +++ .../Configuration/PlayerController.conf | 2 + .../Configuration/PlayerController.conf.meta | 17 +++ Prefabs/Characters/Core/Character_Base.et | 11 ++ .../Characters/Core/Character_Base.et.meta | 17 +++ .../Core/DefaultPlayerController.et | 14 ++ .../Core/DefaultPlayerController.et.meta | 17 +++ .../VoiceRange/VoiceRangeDynamicNumber.layout | 22 ++++ .../VoiceRangeDynamicNumber.layout.meta | 17 +++ UserMaps.desc | 2 + addon.gproj | 8 ++ resourceDatabase.rdb | Bin 0 -> 1007 bytes scripts/Game/VON/SCR_ModdedVONController.c | 21 +++ scripts/Game/VON/SCR_VoiceComponents.c | 11 ++ scripts/Game/VON/SCR_VoiceRangeController.c | 121 ++++++++++++++++++ scripts/Game/VON/SCR_VoiceRangeDisplay.c | 43 +++++++ thumbnail.png | Bin 0 -> 8679 bytes worlds/GameMaster/GM_Cain.ent | Bin 0 -> 1305 bytes worlds/GameMaster/GM_Cain.ent.meta | 17 +++ 24 files changed, 482 insertions(+) create mode 100644 Configs/ControlHints/AvailableActions.conf create mode 100644 Configs/ControlHints/AvailableActions.conf.meta create mode 100644 Configs/System/chimeraInputCommon.conf create mode 100644 Configs/System/chimeraInputCommon.conf.meta create mode 100644 Configs/System/keyBindingMenu.conf create mode 100644 Configs/System/keyBindingMenu.conf.meta create mode 100644 Configs/Systems/Persistence/Configuration/PlayerController.conf create mode 100644 Configs/Systems/Persistence/Configuration/PlayerController.conf.meta create mode 100644 Prefabs/Characters/Core/Character_Base.et create mode 100644 Prefabs/Characters/Core/Character_Base.et.meta create mode 100644 Prefabs/Characters/Core/DefaultPlayerController.et create mode 100644 Prefabs/Characters/Core/DefaultPlayerController.et.meta create mode 100644 UI/layouts/VoiceRange/VoiceRangeDynamicNumber.layout create mode 100644 UI/layouts/VoiceRange/VoiceRangeDynamicNumber.layout.meta create mode 100644 UserMaps.desc create mode 100644 addon.gproj create mode 100644 resourceDatabase.rdb create mode 100644 scripts/Game/VON/SCR_ModdedVONController.c create mode 100644 scripts/Game/VON/SCR_VoiceComponents.c create mode 100644 scripts/Game/VON/SCR_VoiceRangeController.c create mode 100644 scripts/Game/VON/SCR_VoiceRangeDisplay.c create mode 100644 thumbnail.png create mode 100644 worlds/GameMaster/GM_Cain.ent create mode 100644 worlds/GameMaster/GM_Cain.ent.meta diff --git a/Configs/ControlHints/AvailableActions.conf b/Configs/ControlHints/AvailableActions.conf new file mode 100644 index 0000000..53a1d0a --- /dev/null +++ b/Configs/ControlHints/AvailableActions.conf @@ -0,0 +1,14 @@ +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/ControlHints/AvailableActions.conf.meta b/Configs/ControlHints/AvailableActions.conf.meta new file mode 100644 index 0000000..e2d93a2 --- /dev/null +++ b/Configs/ControlHints/AvailableActions.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{80CC0413DDBDFCB9}Configs/ControlHints/AvailableActions.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/Configs/System/chimeraInputCommon.conf b/Configs/System/chimeraInputCommon.conf new file mode 100644 index 0000000..1f8858e --- /dev/null +++ b/Configs/System/chimeraInputCommon.conf @@ -0,0 +1,57 @@ +ActionManager { + Actions { + Action SCR_VoiceRangeUp { + Type Digital + InputSource InputSourceSum "{68D6FBBD3B92F0A9}" { + Sources { + InputSourceValue "{68D6FBBD04A41546}" { + FilterPreset "pressed" + Input "keyboard:KC_ADD" + Filter InputFilterDown "{68D6FBBD15448370}" { + } + } + InputSourceCombo "{68D6FBBD1E1DCEA4}" { + Sources { + InputSourceValue "{68D6FBBD65FB75E6}" { + Input "gamepad0:shoulder_right" + Filter InputFilterHold "{68D6FBBD74D4254F}" { + } + } + InputSourceValue "{68D6FBBD72AB82E9}" { + Input "gamepad0:x" + Filter InputFilterClick "{68D6FBBD7DB89B1E}" { + } + } + } + } + } + } + } + Action SCR_VoiceRangeDown { + Type Digital + InputSource InputSourceSum "{68D6FBBD58BA9137}" { + Sources { + InputSourceValue "{68D6FBBDA234B42A}" { + Input "keyboard:KC_SUBTRACT" + Filter InputFilterDown "{68D6FBBD9D2AB21E}" { + } + } + InputSourceCombo "{68D6FBBDE7ADF840}" { + Sources { + InputSourceValue "{68D6FBBDE00A1085}" { + Input "gamepad0:shoulder_right" + Filter InputFilterHold "{68D6FBBDF7959817}" { + } + } + InputSourceValue "{68D6FBBDF20DB59B}" { + Input "gamepad0:x" + Filter InputFilterClick "{68D6FBBDCC27AE10}" { + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Configs/System/chimeraInputCommon.conf.meta b/Configs/System/chimeraInputCommon.conf.meta new file mode 100644 index 0000000..f1e7b1a --- /dev/null +++ b/Configs/System/chimeraInputCommon.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{795184CF9AD764DB}Configs/System/chimeraInputCommon.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/Configs/System/keyBindingMenu.conf b/Configs/System/keyBindingMenu.conf new file mode 100644 index 0000000..2244120 --- /dev/null +++ b/Configs/System/keyBindingMenu.conf @@ -0,0 +1,20 @@ +SCR_KeyBindingMenuConfig { + m_KeyBindingCategories { + SCR_KeyBindingCategory "{68D6FBA22F320604}" { + m_sName "GTG" + m_sDisplayName "GTG" + m_KeyBindingEntries { + SCR_KeyBindingEntry "{68D6FBA228BCCB97}" { + m_sActionName "SCR_VoiceRangeUp" + m_sDisplayName "Voicce Range +" + m_sPreset "pressed" + } + SCR_KeyBindingEntry "{68D6FBA207B1F8D9}" { + m_sActionName "SCR_VoiceRangeDown" + m_sDisplayName "Voice Range -" + m_sPreset "pressed" + } + } + } + } +} \ No newline at end of file diff --git a/Configs/System/keyBindingMenu.conf.meta b/Configs/System/keyBindingMenu.conf.meta new file mode 100644 index 0000000..f54af76 --- /dev/null +++ b/Configs/System/keyBindingMenu.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{4EE7794C9A3F11EF}Configs/System/keyBindingMenu.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/Configs/Systems/Persistence/Configuration/PlayerController.conf b/Configs/Systems/Persistence/Configuration/PlayerController.conf new file mode 100644 index 0000000..30066fc --- /dev/null +++ b/Configs/Systems/Persistence/Configuration/PlayerController.conf @@ -0,0 +1,2 @@ +EntityPersistenceConfig { +} \ No newline at end of file diff --git a/Configs/Systems/Persistence/Configuration/PlayerController.conf.meta b/Configs/Systems/Persistence/Configuration/PlayerController.conf.meta new file mode 100644 index 0000000..fb7e3f9 --- /dev/null +++ b/Configs/Systems/Persistence/Configuration/PlayerController.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{3CEC5D580421E71E}Configs/Systems/Persistence/Configuration/PlayerController.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/Prefabs/Characters/Core/Character_Base.et b/Prefabs/Characters/Core/Character_Base.et new file mode 100644 index 0000000..65ae021 --- /dev/null +++ b/Prefabs/Characters/Core/Character_Base.et @@ -0,0 +1,11 @@ +SCR_ChimeraCharacter { + ID "520EC961A090B1EE" + components { + SCR_VoNLoud "{68D6FBB9294FC854}" { + } + SCR_VoNNormal "{68D6FBB92B468B18}" { + } + SCR_VoNWhispering "{68D6FBB92DA4FA57}" { + } + } +} \ No newline at end of file diff --git a/Prefabs/Characters/Core/Character_Base.et.meta b/Prefabs/Characters/Core/Character_Base.et.meta new file mode 100644 index 0000000..7ea296f --- /dev/null +++ b/Prefabs/Characters/Core/Character_Base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{37578B1666981FCE}Prefabs/Characters/Core/Character_Base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/Prefabs/Characters/Core/DefaultPlayerController.et b/Prefabs/Characters/Core/DefaultPlayerController.et new file mode 100644 index 0000000..b6ee312 --- /dev/null +++ b/Prefabs/Characters/Core/DefaultPlayerController.et @@ -0,0 +1,14 @@ +SCR_PlayerController { + ID "1A9BA6BEFA06E3B1" + components { + SCR_HUDManagerComponent "{2FDC275D9EBCDB8B}" { + InfoDisplays { + SCR_VoiceRangeDisplay "{68D6FBB914C425E5}" { + } + } + } + SCR_VoiceRangeController "{68D6FBA83607BC45}" { + m_iCurrentRange 10 + } + } +} \ No newline at end of file diff --git a/Prefabs/Characters/Core/DefaultPlayerController.et.meta b/Prefabs/Characters/Core/DefaultPlayerController.et.meta new file mode 100644 index 0000000..4cc4d98 --- /dev/null +++ b/Prefabs/Characters/Core/DefaultPlayerController.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{6E2BB64764E3BE9B}Prefabs/Characters/Core/DefaultPlayerController.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/UI/layouts/VoiceRange/VoiceRangeDynamicNumber.layout b/UI/layouts/VoiceRange/VoiceRangeDynamicNumber.layout new file mode 100644 index 0000000..6a4932a --- /dev/null +++ b/UI/layouts/VoiceRange/VoiceRangeDynamicNumber.layout @@ -0,0 +1,22 @@ +FrameWidgetClass { + Name "rootFrame" + { + TextWidgetClass "{68D6FBBE0B6ABDA5}" { + Name "RangeText" + Slot FrameWidgetSlot "{68D6FBBE0B6ABD4F}" { + PositionX 10 + OffsetLeft 10 + PositionY 639 + OffsetTop 639 + SizeX 100 + OffsetRight -110 + SizeY 30 + OffsetBottom -669 + } + components { + SCR_FadeUIComponent "{68D6FBBE57CE5F98}" { + } + } + } + } +} \ No newline at end of file diff --git a/UI/layouts/VoiceRange/VoiceRangeDynamicNumber.layout.meta b/UI/layouts/VoiceRange/VoiceRangeDynamicNumber.layout.meta new file mode 100644 index 0000000..9fc0426 --- /dev/null +++ b/UI/layouts/VoiceRange/VoiceRangeDynamicNumber.layout.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{52CB3045C167E6D8}UI/layouts/VoiceRange/VoiceRangeDynamicNumber.layout" + Configurations { + LayoutResourceClass PC { + } + LayoutResourceClass XBOX_ONE : PC { + } + LayoutResourceClass XBOX_SERIES : PC { + } + LayoutResourceClass PS4 : PC { + } + LayoutResourceClass PS5 : PC { + } + LayoutResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/UserMaps.desc b/UserMaps.desc new file mode 100644 index 0000000..cb68455 --- /dev/null +++ b/UserMaps.desc @@ -0,0 +1,2 @@ +UserMapDescClass { +} \ No newline at end of file diff --git a/addon.gproj b/addon.gproj new file mode 100644 index 0000000..caf6733 --- /dev/null +++ b/addon.gproj @@ -0,0 +1,8 @@ +GameProject { + ID "VoiceRange" + GUID "68D6F5422C10ACFC" + TITLE "VoiceRange" + Dependencies { + "58D0FB3206B6F859" + } +} \ No newline at end of file diff --git a/resourceDatabase.rdb b/resourceDatabase.rdb new file mode 100644 index 0000000000000000000000000000000000000000..18277e3367e58c509bd3da719281c3b7fd88b603 GIT binary patch literal 1007 zcmZ?s5AtPTV16Ft;^fT6z`*dH8Aw2ZFpy>hv00%45UTypwG0r82Z$3>Qu6ck(hG|6 zvlv()(oizw>$QwhAe#e-o%8e3GSiEp<}7lZ{Xd1dq@#9-Cl`@zr^#f9iiZg+l@{&`b=I`)PU71-pmkXv#3%@RXi0ev=5=%1k^PpyY zeV%nr<;^z{m>CYFn4uq#lUSKr1T?p#C_g7BwMZ`+7yt~Q;ALQtd#=b55&OmlWU@4n z52E9Mp$rPAfTGm2#3Y#S&k6q)x^{r+Xg@TZK+yqJq3@iLSd^Gt0`xn~!FAgw8}1Tc z3{xzDRWZ=7MX+Fc&X?#u>#NKrm<~`dVHywCfv_&#DX}wROq`W=ED52_Q~Qp(TOTMr$LnoqAAl4^Y?=WP@FdVkCrK+k;}h9 zOw`7rR6p1`DBd?eB_%Zls1Z5-&>X%NXvjJy1_m8mhJ@v3CZ`4^=B20NF=Z>z)tNw_ zX%aTYC9}8yn5guU(Ht@z=nzw2!r}uOQIb)bo0ONBnWI;bmyV{66ByFZ6&V-+V^|?0 literal 0 HcmV?d00001 diff --git a/scripts/Game/VON/SCR_ModdedVONController.c b/scripts/Game/VON/SCR_ModdedVONController.c new file mode 100644 index 0000000..17c75e6 --- /dev/null +++ b/scripts/Game/VON/SCR_ModdedVONController.c @@ -0,0 +1,21 @@ +modded class SCR_VONController { + override void DeactivateVON(EVONTransmitType transmitType = EVONTransmitType.NONE) { + super.DeactivateVON(transmitType); + } + + override void SetVONProximityToggle(bool activate) { + if (!m_VONComp) return; + if (!m_DirectSpeechEntry || !m_DirectSpeechEntry.IsUsable()) return; + if (m_bIsToggledDirect == activate) return; + + m_bIsToggledDirect = activate; + + if (activate) { + ActivateVON(EVONTransmitType.DIRECT); + } else { + DeactivateVON(EVONTransmitType.DIRECT); + } + + m_OnVONActiveToggled.Invoke(m_bIsToggledDirect, false); + } +} \ No newline at end of file diff --git a/scripts/Game/VON/SCR_VoiceComponents.c b/scripts/Game/VON/SCR_VoiceComponents.c new file mode 100644 index 0000000..567b497 --- /dev/null +++ b/scripts/Game/VON/SCR_VoiceComponents.c @@ -0,0 +1,11 @@ +[ComponentEditorProps(category: "GameScripted/", description: "Whispering VoN component")] +class SCR_VoNWhisperingClass: SCR_VoNComponentClass {} +class SCR_VoNWhispering: SCR_VoNComponent {} + +[ComponentEditorProps(category: "GameScripted/", description: "Normal VoN component")] +class SCR_VoNNormalClass: SCR_VoNComponentClass {} +class SCR_VoNNormal: SCR_VoNComponent {} + +[ComponentEditorProps(category: "GameScripted/", description: "Loud VoN component")] +class SCR_VoNLoudClass: SCR_VoNComponentClass {} +class SCR_VoNLoud: SCR_VoNComponent {} \ No newline at end of file diff --git a/scripts/Game/VON/SCR_VoiceRangeController.c b/scripts/Game/VON/SCR_VoiceRangeController.c new file mode 100644 index 0000000..0a686ca --- /dev/null +++ b/scripts/Game/VON/SCR_VoiceRangeController.c @@ -0,0 +1,121 @@ +[ComponentEditorProps(category: "GameScripted/", description: "Voice Range Controller (Per Meter)")] +class SCR_VoiceRangeControllerClass: ScriptComponentClass {} + +class SCR_VoiceRangeController: ScriptComponent { + + [Attribute("25", UIWidgets.Slider, "Start-Reichweite in Metern", "1 100 1")] + protected int m_iCurrentRange; + + [Attribute("1", UIWidgets.Slider, "Minimale Reichweite", "1 100 1")] + protected int m_iMinRange; + + [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")] + protected int m_iStepSize; + + protected ref Shape m_RangeCircleShape; + + 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); + } + + 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); + } + + void IncreaseRange() { + ChangeRange(1); + } + + void DecreaseRange() { + 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; + + ApplyRangeToVON(); + UpdateUI(); + DrawRangeCircle(); + } + + protected void ApplyRangeToVON() { + IEntity player = GetGame().GetPlayerController().GetControlledEntity(); + if (!player) return; + + SCR_VONController vonContr = SCR_VONController.Cast(GetOwner().FindComponent(SCR_VONController)); + if (!vonContr) return; + + // --- HYBRID LÖSUNG --- + // Da die Engine "pro Meter" im echten Voice-Chat nicht zulässt, + // ordnen wir die Meterzahl im Hintergrund den 3 Komponenten zu. + typename compType = SCR_VoNNormal; // Standard + + if (m_iCurrentRange <= 15) { + compType = SCR_VoNWhispering; + } else if (m_iCurrentRange >= 50) { + compType = SCR_VoNLoud; + } + + SCR_VoNComponent newVonComp = SCR_VoNComponent.Cast(player.FindComponent(compType)); + if (newVonComp) { + vonContr.SetVONComponent(newVonComp); + } + } + + void UpdateUI() { + 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); + } + } + + void DrawRangeCircle() { + IEntity player = GetGame().GetPlayerController().GetControlledEntity(); + if (!player) return; + + if (m_RangeCircleShape) { + m_RangeCircleShape = null; + } + + vector mat[4]; + player.GetTransform(mat); + + vector boundsMin, boundsMax; + player.GetBounds(boundsMin, boundsMax); + mat[3][1] = mat[3][1] + boundsMin[1] + 0.1; + + 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); + + GetGame().GetCallqueue().Remove(HideRangeCircle); + GetGame().GetCallqueue().CallLater(HideRangeCircle, 2000, false); + } + + void HideRangeCircle() { + m_RangeCircleShape = null; + } +} \ No newline at end of file diff --git a/scripts/Game/VON/SCR_VoiceRangeDisplay.c b/scripts/Game/VON/SCR_VoiceRangeDisplay.c new file mode 100644 index 0000000..3e8581a --- /dev/null +++ b/scripts/Game/VON/SCR_VoiceRangeDisplay.c @@ -0,0 +1,43 @@ +class SCR_VoiceRangeDisplay: SCR_InfoDisplay { + protected TextWidget m_wRangeText; + protected SCR_FadeUIComponent m_FadeComponent; + + protected override event void OnStartDraw(IEntity owner) { + super.OnStartDraw(owner); + + if (!m_wRoot) { + // Passe den Pfad zu deiner UI Layout-Datei an + m_wRoot = GetGame().GetWorkspace().CreateWidgets("68D6F5422C10ACFC/UI/layouts/VoiceRange/VoiceRangeDynamicNumber.layout"); + if (!m_wRoot) return; + } + + m_wRangeText = TextWidget.Cast(m_wRoot.FindAnyWidget("RangeText")); + if (!m_wRangeText) return; + + m_FadeComponent = SCR_FadeUIComponent.Cast(m_wRangeText.FindHandler(SCR_FadeUIComponent)); + + m_wRangeText.SetVisible(false); + } + + 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); + } + + GetGame().GetCallqueue().Remove(StartFadeOut); + GetGame().GetCallqueue().CallLater(StartFadeOut, 3000, false); + } + + protected void StartFadeOut() { + if (m_FadeComponent) { + m_FadeComponent.FadeOut(false); + } else if (m_wRangeText) { + m_wRangeText.SetVisible(false); + } + } +} \ No newline at end of file diff --git a/thumbnail.png b/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..6fb5d206ffe21271b7775403de1904a1a151b1a4 GIT binary patch literal 8679 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 FV1hZOk|qEE literal 0 HcmV?d00001 diff --git a/worlds/GameMaster/GM_Cain.ent b/worlds/GameMaster/GM_Cain.ent new file mode 100644 index 0000000000000000000000000000000000000000..04dc9df5a25c7a7d57e4053a84c1695efc1bf8b3 GIT binary patch literal 1305 zcmZvaZAcSw9LIk?%{g~BAEu)uMI|+QQ97(l3f=8ymfBJzgG$fsHV?Kt+imv3m#LHx zOC>~Kgh-Hzj}YW5b%sIV-XuLJy^*wtd`Ju=FLY1e!%0jcW0?d?)X5Fz+MO4-nmtN&u4r>^kRe^`;*+3)YI4$i11b`- zu94*`+U;goJFk`n)R!RtnHUGn6C7(}?8#uDcv_lmpPmRr1LLG!)PAD`6sd%A(&e0$ zCasK{bEP9KFeZeGi!#zS%Hwbg22xx#IBO|0$1`q*V}dXw^=EhgWL@>>fM=p9 zWj8ZnV^gfRZ#>-=^}Sq+25nrC_Dl(DvgrNOKDzUAR8+pqLD)aS$Z-+LGGFK#T@ z2QUC!c*O?`gDBw}4p;<4g#q3y$&r9JisdLE!vQ}bsS3cNfs6n=RT7kd#Q+(J=qSLW zC0U>p2PoBlsAxnf_o!GPl0ZJs+Q1>!nmi6it{5%`aD6zM9}~jm2t!N_#>M5FAxdY zrCB2NnMaK8Ha{Z9KY!f^MKwWYzU@|BD6>{DM?P-+Z18Tym_(o6o|iM%y_bW`DU(tc z%6KbljBD{lg!bFIlx<;VGIh})XZyo-M}{(KTczZ=p$Eh zRFih}9253Xmn z=2d4XqrKTf`W^kmPRm`1dF1Oov>MFz;_pyfDAWA5k8Ex^ZG87*4l%tw6Fz_0;H;dj zFMR$b|ooFIlgCtP$ N4ISsjv8PK}^bY~eTR;E+ literal 0 HcmV?d00001 diff --git a/worlds/GameMaster/GM_Cain.ent.meta b/worlds/GameMaster/GM_Cain.ent.meta new file mode 100644 index 0000000..52b7896 --- /dev/null +++ b/worlds/GameMaster/GM_Cain.ent.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{BF1144AB6CB06A9E}worlds/GameMaster/GM_Cain.ent" + Configurations { + ENTResourceClass PC { + } + ENTResourceClass XBOX_ONE : PC { + } + ENTResourceClass XBOX_SERIES : PC { + } + ENTResourceClass PS4 : PC { + } + ENTResourceClass PS5 : PC { + } + ENTResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file