commit a2a5f04dd4ea5ff4be054d7b06d59b38ba7ea16d Author: Alex Date: Wed Mar 11 19:14:40 2026 +0100 V 0.5 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 0000000..18277e3 Binary files /dev/null and b/resourceDatabase.rdb differ 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 0000000..6fb5d20 Binary files /dev/null and b/thumbnail.png differ diff --git a/worlds/GameMaster/GM_Cain.ent b/worlds/GameMaster/GM_Cain.ent new file mode 100644 index 0000000..04dc9df Binary files /dev/null and b/worlds/GameMaster/GM_Cain.ent differ 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