This commit is contained in:
2026-03-11 19:14:40 +01:00
commit a2a5f04dd4
24 changed files with 482 additions and 0 deletions

View File

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