KI auf via TFAR sprechende Spieler reagieren lassen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • KI auf via TFAR sprechende Spieler reagieren lassen

    Hallo zusammen,

    grundsätzlich bietet TFAR diverse EventHandler an. Liste der EventHandler findet man hier: github.com/michail-nikolaev/ta…-3-radio/wiki/API:-Events

    Besonders interessant für mich wäre der OnSpeak EventHandler. Das Beispiel auf der genannten Website lautet:

    Quellcode

    1. // binding to the player object:
    2. ["MyID", "OnSpeak", {
    3. hint format ["%1 %2 speaking", _this select 0, if(_this select 1)then{"is"}else{"isn't"}];
    4. }, Player] call TFAR_fnc_addEventHandler;

    Ich habs ausprobiert. Auch mit vereinfachtem Code. Hat bei mir nicht funktioniert. Andere EventHandler wie 'OnTangent' funktionieren problemlos.

    Nähere Analysen der relevanten Funktionen in TFAR haben gezeigt, dass die isSpeaking Funktion auf folgenden Code zurückgreift:

    (("task_force_radio_pipe" callExtension format ["IS_SPEAKING %1", name _this]) == "SPEAKING")

    Der Code wird bei mir ebenfalls nicht ausgewertet.

    Frage an die Runde: Hat schon jemand erfolgreich via SQF abgefragt ob eine Einheit gerade via TFAR spricht?Gruß,
    Schmitt


    Bei Interesse am BW Mod/ArmA3/ACE3 empfehle ich die Events des Jägerzug Achilles I
  • Danke für den Hinweis. Hab in der Debug Konsole folgenden Befehl lokal ausgeführt:

    Quellcode

    1. myhandle = [] spawn { while {true} do { sleep 1; systemChat format ["spricht: %1", player getVariable ["tf_isSpeaking", false]]; }; };

    Bleibt die ganze Zeit auf false. Auch wenn ich spreche. Ich nutze Teamspeak 3.0.19 Vielleicht liegts hier auch an Inkompatibilitäten.

    Kann jemand mal den Code in seiner eigenen Debug Konsole testen, ob ihr vielleicht mehr Erfolg habt?


    Bei Interesse am BW Mod/ArmA3/ACE3 empfehle ich die Events des Jägerzug Achilles I
  • Es gibt keine Variable tf_isSpeaking. Es gibt nur die Funktion tfar_fnc_isSpeaking und den onSpeak-Eventhandler.
    Bei mir funktionieren beide.
    probiere mal:
    hint str (player call tfar_fnc_isSpeaking);
    und für den Eventhandler:
    ["areyouspeaking", "OnSpeak", {hint (format ["%1 is speaking",(_this select 0)])}, player] call TFAR_fnc_addEventHandler;
    funktioniert bei mir beides.
  • Belbo schrieb:

    Es gibt keine Variable tf_isSpeaking. Es gibt nur die Funktion tfar_fnc_isSpeaking und den onSpeak-Eventhandler.
    github.com/michail-nikolaev/ta…fn_sendPlayerInfo.sqf#L47 so viel zu es gibt die variable nicht. jedoch wird sie immer getrigger wenn der EH getriggered wird d.h. wenn es sie nicht gibt heißst das das der EH nicht getriggered wird
    SIGNATUR START
    Wer Rechtschreibfehler findet darf sie behalten
    ACE3 Core Developer
    CBA A3 Developer
    Developer of Dynasound, Enhance SoundScape, Immerse, Suppress and Align
    SIGNATUR ENDE
  • player getVariable ["tf_isSpeaking", false]

    funktioniert doch. Über die Debug Konsole hab ichs zwar nicht zum Laufen gebracht (siehe oben), aber im Missionscode selbst funktionierts. Also besten Dank soweit!

    //edit:

    ["MyID", "OnSpeak", {
    systemChat format ["%1 %2 speaking", _this select 0, if(_this select 1)then{"is"}else{"isn't"}];
    }, player] call TFAR_fnc_addEventHandler;

    funktioniert auch, wenn integriert in initPlayerLocal.sqf (serverseitig noch nicht getestet)


    Bei Interesse am BW Mod/ArmA3/ACE3 empfehle ich die Events des Jägerzug Achilles I

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von [JgZg-A] Schmitt ()

  • Trotzdem noch eine Frage zum Thema: Ich suche das Gegenteil zu dieser Funktion:


    TFAR_fnc_setVoiceVolume

    Aber da es TFAR_fnc_getVoiceVolume muss diese Funktion anders heißen. Oder wie komme ich an die Info, ob ein Spieler gerade flüstert oder lauter spricht?

    Notfallplan wäre die ständige Überwachung der Lautstärkenänderungen via OnSpeakVolume Eventhandler, aber das wäre ja der absolute Overload in Sachen CPU Nutzung ...


    Bei Interesse am BW Mod/ArmA3/ACE3 empfehle ich die Events des Jägerzug Achilles I
  • Ok. Das klappt soweit alles wunderbar, dass mich ab sofort Feinde angreifen, sobald ich spreche/funke, während der Feind in Hörreichweite ist. Für Neugierige habe ich mal die Codes beigelegt.

    Da ich jedoch über TFAR keine Schnittstelle habe, welche mir den aktuellen Mikrofonpegel von Teamspeak ausgeben kann, habe ich aktuell noch das Problem, dass das Betätigen der Sprachtaste in Verbindung mit der aktuellen TFAR Sprechreichweite (flüstern, leise oder laut) ausreicht um einen Feind zu aktivieren.

    Ich will jedoch einen real flüsternden Spieler (unabhängig von der TFAR Reichweite) belohnen gegenüber einem real laut redenden Spieler in Teamspeak. Dazu benötige ich eine Abfrage des Mikrofonpegels. In TFAR gibts das scheinbar nicht. Kennt jemand eine DLL mit welcher ich aus ArmA heraus den Teamspeak Mikrofonpegel abfragen kann?

    Quellcode

    1. _aktuellerTeamspeakMikrofonPegel = "primitiveTeamspeakDLL" callExtension "teamspeakMicrophoneVolumeLevel";
    Andernfalls müsste ich diesem Guide folgen und eine komplett eigene DLL programmieren. Aber ich erfinde das Rad nur ungern neu, wenns nicht sein muss. Am Ende muss ich dann eben eine DLL ähnlicher dieser programmieren:

    Quellcode: primitiveTeamspeakDLL.dll (Pseudocode)

    1. #include "stdafx.h"
    2. extern "C"
    3. {
    4. __declspec (dllexport) void __stdcall RVExtension(char *output, int outputSize, const char *function);
    5. }
    6. void __stdcall RVExtension(char *output, int outputSize, const char *function)
    7. {
    8. strncpy_s(output, outputSize, "Aktuelle Teamspeaklautstärke beträgt 64%", _TRUNCATE);
    9. }
    Alles anzeigen

    Quellcode: initPlayerLocal.sqf

    1. // reagiere auf TFAR Sprachkommunikation (ausgehend vom aktiven Spieler, nicht von anderen hörend, sondern was der aktive Spieler selbst sagt)
    2. ["MyID1", "OnSpeak", { [_this select 0, _this select 1] spawn schmitt_fnc_reagiereAufSpielerStimme; }, player] call TFAR_fnc_addEventHandler;
    3. // reagiere auf TFAR Funkkommunikation (ausgehend vom aktiven Spieler, nicht von anderen empfangend/hörend, sondern was der aktive Spieler selbst funkt)
    4. ["MyID2", "OnTangent", { [_this select 0, _this select 4] spawn schmitt_fnc_reagiereAufSpielerStimme; }, player] call TFAR_fnc_addEventHandler;

    Quellcode: fn_reagiereAufSpielerStimme.sqf

    1. /*
    2. File: fn_reagiereAufSpielerStimme.sqf
    3. Autor: Thomas 'smallfly' Ludwig aka 'Schmitt'
    4. Die Funktion kann nur lokal angewendet werden!
    5. _editorNameDerSprechendenEinheit ist also zwangsläufig immer der Editorname des aktuellen 'player'
    6. Lokal globale Variable 'TF_speak_volume_meters' // z. B. 5 (Meter) für "leise", 20 (Meter) für "normal" und 60 (Meter) für "laut"
    7. */
    8. Private [
    9. "_editorNameDerSprechendenEinheit", "_sprichtGerade",
    10. "_lautstaerke", "_dauerLetztesGespraechInSek", "_taskForceSprechReichweiteInMeter"
    11. ];
    12. if (isDedicated || !hasInterface) exitWith { diag_log "FEHLER: 'fn_reagiereAufSpielerStimme' lässt sich nur clientseitig ausführen!"; };
    13. _editorNameDerSprechendenEinheit = [_this,0,"",[""]] call BIS_fnc_param;
    14. _sprichtGerade = [_this,0,false,[false]] call BIS_fnc_param;
    15. if (_sprichtGerade) exitWith { // wenn gerade ein Gespräch begonnen wird, dann merke aktuellen Zeitpunkt und verlasse den Eventhandler
    16. schmitt_startLetztesGespraech = client_taktgeber;
    17. systemChat format ["Sie haben ein Gespräch begonnen zum Zeitpunkt %1", schmitt_startLetztesGespraech];
    18. };
    19. // Es wurde ein Gesprächsende festgestellt; Nun gilt es die Dauer zu ermitteln und entsprechend der Lautstärke darauf zu reagieren
    20. _dauerLetztesGespraechInSek = client_taktgeber - schmitt_startLetztesGespraech;
    21. _lautstaerke = "normal";
    22. _taskForceSprechReichweiteInMeter = if (!isNil {TF_speak_volume_meters}) then { TF_speak_volume_meters } else { 21 };
    23. switch (true) do
    24. {
    25. case (_taskForceSprechReichweiteInMeter < 10) : { _lautstaerke = "leise"; };
    26. case (_taskForceSprechReichweiteInMeter > 30) : { _lautstaerke = "laut"; };
    27. default { _lautstaerke = "normal"; };
    28. };
    29. diag_log format ["Sie haben ein Gespräch abgeschlossen zum Zeitpunkt %1 mit Dauer %2 und Lautstärke %3", client_taktgeber, _dauerLetztesGespraechInSek, _lautstaerke];
    30. if ( (client_taktgeber - schmitt_zeitpunktLetzteLautstaerkeAnalyse) < 20 ) exitWith // Sekunden Cool Down Phase
    31. {
    32. diag_log "Zwar wurde gerade ein TFAR Gespräch erkannt, jedoch befindet sich der Client gerade in einer Analyse Cool Down Phase, sodass keine Auswirkungen folgen.";
    33. };
    34. schmitt_zeitpunktLetzteLautstaerkeAnalyse = client_taktgeber;
    35. // =============================================================================================================
    36. // | Lasse Feind KI im Umkreis von _taskForceSprechReichweiteInMeter Metern den sprechenden Soldaten angreifen |
    37. // =============================================================================================================
    38. // Durchlaufe sämtliche Einheiten auf dem Server ...
    39. {
    40. // FALLS
    41. // 1. die Einheit der Fraktion 'east' angehört
    42. // 2. die Einheit sich NICHT in einem Fahrzeug befindet also aktuell zu Fuß ist
    43. // 3. der Abstand der Feindeinheit zum Spieler geringer oder gleich der TFAR Sprechreichweite ist
    44. // DANN
    45. // lasse die Feindeinheit den sprechenden Spieler angreifen
    46. if (
    47. side _x == east &&
    48. vehicle _x == _x &&
    49. (_x distance player) <= _taskForceSprechReichweiteInMeter
    50. ) exitWith
    51. {
    52. diag_log "Der Feind hat Sie sprechen gehört!";
    53. [[player, _x], "schmitt_fnc_meldeDassSpielerVonFeindGehoertWurde", "AN_SERVER"] spawn schmitt_fnc_mpPaketSenden;
    54. };
    55. }
    56. forEach allUnits;
    Alles anzeigen

    Quellcode: fn_meldeDassSpielerVonFeindGehoertWurde.sqf

    1. /*
    2. File: fn_meldeDassSpielerVonFeindGehoertWurde.sqf
    3. Autor: Thomas 'smallfly' Ludwig aka 'Schmitt'
    4. */
    5. Private [
    6. "_headlessClientIstEingeloggt", "_dieserClientIstDerHeadlessClient",
    7. "_zuLauterSpieler", "_lauschenderFeind", "_wpPositions"
    8. ];
    9. _headlessClientIstEingeloggt = if (isNil "headlessclient") then {false} else {true};
    10. _dieserClientIstDerHeadlessClient = (isMultiplayer && !isServer && !hasInterface);
    11. // der Client ist zwar nicht der Server, hat aber auch kein Interface;
    12. // nach dem Ausschlussverfahren muss es sich um einen (den) 'headless client' handeln
    13. if ( !((_headlessClientIstEingeloggt && _dieserClientIstDerHeadlessClient) || isServer) ) exitWith {
    14. diag_log "FEHLER: 'fn_meldeDassSpielerVonFeindGehoertWurde.sqf' lässt sich nur vom 'headless client' oder serverseitig ausführen!";
    15. };
    16. _zuLauterSpieler = [_this,0,objNull,[objNull]] call BIS_fnc_param;
    17. _lauschenderFeind = [_this,1,objNull,[objNull]] call BIS_fnc_param;
    18. if ( (client_taktgeber - schmitt_zeitpunktLetzerAngriffAufZuLautenSpieler) < 10 ) exitWith // Sekunden Cool Down Phase bis erneuter Angriff auf zu lauten Spieler initiiert wird
    19. {
    20. diag_log format ["Zwar hat ein Client gemeldet, dass der zugehörige Spieler zu laut war, jedoch hat dies aktuell keine Folgen um Spam zu vermeiden, Nähe zum Feind: %1 Meter", ceil(_zuLauterSpieler distance _lauschenderFeind)];
    21. };
    22. diag_log format ["SERVER: Starte Angriff auf zu lauten Spieler seitens %1 Meter entferntem Feind ...", ceil(_zuLauterSpieler distance _lauschenderFeind)];
    23. if (!isDedicated) then {
    24. ["hinweis", format ["SERVER: Starte Angriff auf zu lauten Spieler seitens %1 Meter entferntem Feind ...", ceil(_zuLauterSpieler distance _lauschenderFeind)] ] call schmitt_fnc_meldungEinreihen;
    25. };
    26. schmitt_zeitpunktLetzerAngriffAufZuLautenSpieler = client_taktgeber;
    27. _wpPositions = [
    28. getPos _zuLauterSpieler
    29. ];
    30. [group _lauschenderFeind, _wpPositions, "ANGRIFF_OHNE_CYCLE"] call schmitt_fnc_zuordnenVonWegpunktenZuFeindGruppe;
    31. diag_log format ["Achtung: Soldat '%1' der Feindgruppe '%2' hat den Spieler '%3' gehört und greift diesen nun mit seiner Gruppe an!", str _lauschenderFeind, str (group _lauschenderFeind), str _zuLauterSpieler];
    Alles anzeigen


    Bei Interesse am BW Mod/ArmA3/ACE3 empfehle ich die Events des Jägerzug Achilles I