PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Fraktionen verfeinden - Eventhandler MPKilled


Loooci
16.02.2015, 14:23
Hallo Zusammen,

ich sitze gerade an einer Coop+ Mission, also Multiplayer mit 2 Spielerfraktionen und AI. In dieser ist ein Teil der Spieler als Blufor gesetzt.

Der zweite Teil der Spieler soll die Wahl erhalten, eine Fraktion (Blufor / Opfor/ Guerilla) zu unterstützen.

Mein Ansatz dazu ist es, diese zweite Spielerfraktion als Guerilla einzubinden und diese zum Missionsstart mit allen zu befreunden. Im Laufe der Mission sollen sie sich dann entscheiden, welche Fraktion sie unterstützen.

Mit dem Befehl setFriend (https://community.bistudio.com/wiki/getFriend) kann man das Verhalten der Fraktionen zueinander beeinflussen.
Beispiel:
Resistance setFriend [East, 0];
East setFriend [Resistance, 0];


Bisher hab ich das über den Umweg umgesetzt, eine bestimmte Einheit in der Mission erschießen zu lassen, um die Entscheidung herbeizuführen. (CSATHeini1 = tot -> AAF feindlich zu CSAT und andersrum).
Passender wäre es jedoch wenn das bei allen Einheiten funktionieren würde.

Wie schaffe ich es also, die Fraktionen miteinander zu verfeinden, sobald eine KI Einheit ausgeschaltet wurde?

Ich hab das Gefühl, dass das mit einem MPKilled - Eventhandler (https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#MPKilled) umgesetzt werden könnte, habe jedoch keine Ahnung wie das genau funktioniert.


Wie bringe ich den Eventhandler an allen OPfor Einheiten an?
Wie sage ich dem Eventhandler dass er aktiviert werden soll ( und die Fraktionen verfeindet), sobald eine Opfor Einheit von der Guerilla getötet wird?


Die Suchfunktion habe ich benutzt, bei mir scheitert es jedoch leider an den Grundlagen zu Eventhandlern:oh:.. erbarmt sich jemand und erklärt mir den Sachverhalt?

burns
16.02.2015, 19:37
{
if (side _x == east) then {
_x addMPEventHandler ["MPKilled",{East setFriend [Resistance, 0]; }]
};
} foreach allunits;


Habsch geil zusammengefrankensteint :trill:

Loooci
16.02.2015, 23:03
{
if (side _x == east) then {
_x addMPEventHandler ["MPKilled",{East setFriend [Resistance, 0]; }]
};
} foreach allunits;


Habsch geil zusammengefrankensteint :trill:


:D Danke Dir Burns!

Läuft das so ab?

wenn die seite "east" entspricht dann pack an alle "east" den Eventhandler MPKilled mit {für das aus wenn dieser EV zündet}; Und das pack an alle Einheiten auf der Map;

Klingt wahrscheinlich ziemlich dämlich, muss das aber mal so nachvollziehen, um es zu verstehen ^^

burns
16.02.2015, 23:30
Ich versteh das selber nie! :D

War ein reiner Glückstreffer, daß Teilstücke (Aufruf aus einer meiner Missionen, EH Zeilen Beispiel aus dem Biki, und dein Befehlsschnipsel) genau so zusammen funktioniert haben. Darum "gefrankensteint".

Aber im Grunde ist deine Aufassung so richtig.

Den Eventhandler zu befüttern scheint auch relativ easy, aber bevor ich hier Anfang Mist zu erklären, lass ich lieber jmd. ran der auch versteht wovon er redet (wie z.B. Hoschi, der meint das dieses _x auch wichtig ist).

Nokman
17.02.2015, 09:54
{
if (side _x == east) then { //wenn es opfor ist sonst springt er weiter
_x addMPEventHandler ["MPKilled",{East setFriend [Resistance, 0]; }]//fügt jeder einheit Opfor denn MP eventhändler zu (befehl wird Global übertragen im gegensatz zu killed EH)
};
} foreach allunits; //wiederholt die Arbeit für alle Einheiten die in den Moment wo der Befehl ausgeführt wird auf der Karte vorhanden sind

Kleine erklärung dazu im Code

Was zu beachten ist wenn du Respawn oder einheiten nach den Mapstart (oder wann der Befehl ausgeführt wird) erzeugst ist der MP Eventhändler nicht mehr auf der Einheit drauf.

Loooci
17.02.2015, 12:17
Danke auch Dir Nokman! Ich werd das heute abend in die Mission reinbauen und mich dann nochmal melden.

Drunken Officer
17.02.2015, 19:17
Der obere EH erfüllt nicht zu 100% die Forderung des TE! Der TE will, dass
Wie sage ich dem Eventhandler dass er aktiviert werden soll ( und die Fraktionen verfeindet), sobald eine Opfor Einheit von der Guerilla getötet wird?


In den bisher aufgelisteten Versionen würde es auch zutreffen, wenn z.B. Spieler A den Spieler B aus Unachtsamkeit überfährt und beide OpFor sind.

Es muss die Seite des "Verbrechers" abgefragt werden.

{
if (side _x == east) then {
_x addMPEventHandler ["MPKilled",{ if ( side (_this select 1) == restiance) then {East setFriend [Resistance, 0];} }]
};
} foreach allunits;

jetzt ist Rot feindlich zu Grün. Grün ist aber deswegen nicht feindlich rot. Das muss wie im ersten Beitrag schon geschrieben ergänzt werden

Loooci
17.02.2015, 23:51
Hallo Drunken Officer,
auch an Dich ein Dankeschön für deinen Beitrag!

Leider bin ich heute abend doch nicht dazu gekommen, das auszuprobieren. Wird nachgeholt, anschließend pack ich eine Beispieldatei hier in den Thread.

An den Umstand eines Friendly - Kills hatte ich überhaupt nicht gedacht, da wir meist mit agm mod und 10min zeit bis zum ausbluten spielen. Allerdings ein sehr wichtiges Detail, eine Granate geht daneben und schon geht es rund ;)
Wenn jedoch kein spieler der opfor angehört, tritt das genannte doch nicht auf? (Spieler sind resistance und blufor, es wird nur ai für die Opfor gesetzt + ein paar wenige Zivilisten)

Eine Frage habe ich noch:
Woher wisst ihr, wann ihr lokale variablen oder globale variablen benutzen müsst? Bei_this kann ich das noch halbwegs nachvollziehen. Jedoch nicht bei_x.
Nachtrag:
Zu dem _x hab ich gerade folgendes gefunden (http://killzonekid.com/arma-scripting-tutorials-special-variables/).
Das n link mach ich schön, sobal ich am pc sitze :)
Gruß
Loooci

Drunken Officer
18.02.2015, 02:27
Lokal ist eine Variable, wenn sie nur in diesem Script verwendet wird. Was auch nur die halbe Wahrheit ist, wenn du z.B. in dem Script eine EH hast, kannst du nicht auf diese lokale Variable zugreifen. Diese muss dann ebenfalls Global sein.

Global ist eine Variable, wenn diese für andere Scripte mit genutzt werden soll.
Global ist nicht gleich Public auf allen Rechnern!!

PublicVariable muss via Befehl durch das Netzwerk geboxt werden.

Das _x ist einfach nur eine "magic variable" für die forEach-Schleife. Findest du auch bei dem Befehl count.

Ansonsten bei den Befehlen darauf achten was BIS-Wiki schreibt. AL/AG, EL/EG

Manche Befehle finden nur auf dem Clienten statt (z.B. addaction). Andere Befehle werden sofort über das Netzwerk verteilt (z.B. createVehicle)
Da mußt du bissel aufpassen, dass nur z.B. bei createVehicle wirklich nur der Server oder ein Client den Befelh ausführt sonst hast du mehrere Objekte (Server+Anzahl aktiver Clienten)

Pfandgiraffe
27.02.2015, 10:41
MP is überflüssig, der normale EH reicht auch, kann eh nur vom Server ausgeführt werden.
Sinnloser Traffic vom feinsten.

Saint
27.02.2015, 16:36
MP is überflüssig, der normale EH reicht auch, kann eh nur vom Server ausgeführt werden.
Sinnloser Traffic vom feinsten.

erkläre das doch bitte genauer. :)

Loooci
27.02.2015, 16:46
Hi Zusammen,

lange ist es her.. :)

@Pfandgiraffe
Wenn das in der Form überflüssig ist erklär bitte wie Du es umsetzen würdest. So hätte jeder was davon. Bei einem normalen EH wird das doch nicht an alle clients weiterverteilt ?

In Verbindung mit dem AGM Mod funktioniert es übrigens nicht mit dem MPKilled Eventhandler! Habe dafür den MPHit verwendet.

Eintrag in die init.sqf
//Eventhandler CSAT
{
if (side _x == opfor) then
{
_x addMPEventHandler ["MPHit",
{
if ( side (_this select 1) == resistance) then
{
opfor setFriend [resistance, 0];
resistance setFriend [opfor, 0];
};
}]
};
} forEach allUnits;


Alternativ dazu hat mir ein netter Mitspieler mal gezeigt wie man selbst Funktionen erstellt, diese ist etwas allgemeiner gefasst:
//function
fnc_becomeEnemy = {
private["_faction1","_faction2","_killer", "_killed"];
_faction1 = _this select 0;
_faction2 = _this select 1;
_killer = _this select 2;
_killed = _this select 3;
if (side (_killer) == _faction1) then
{
_faction2 setFriend [_faction1, 0];
_faction1 setFriend [_faction2, 0];

hint format["%1 wurde von %2 angegriffen", _killed, _killer];
/*
Oder auch:
hint format["%1 wurde von %2 erschossen", _this select 3, _this select 2];
*/
};
};
{
if (side _x == opfor) then
{
_x addMPEventHandler ["MPHit", {[resistance, opfor, _this select 1, _this select 0 ] call fnc_becomeEnemy;}];
};
if (side _x == blufor) then
{
_x addMPEventHandler ["MPHit", {[resistance, blufor, _this select 1] call fnc_becomeEnemy;}];
};
} forEach allUnits;

Pfandgiraffe
27.02.2015, 18:56
@Pfandgiraffe
Wenn das in der Form überflüssig ist erklär bitte wie Du es umsetzen würdest. So hätte jeder was davon. Bei einem normalen EH wird das doch nicht an alle clients weiterverteilt ?
[/code]

Weil es die Clients nicht zu interessieren hat. Führe den Befehl doch mal von einem Client aus in der Serverumgebung aus. Da wird sich rein garnichts verändern.

Entferne einfach das MP an jedem EH und sorge dafür, dass nur der Server den Code ausführt.
if (isServer) then {...


Grüße

Drunken Officer
27.02.2015, 19:16
erkläre das doch bitte genauer. :)
ganz einfach.

KI ist Server-Side. Warum übers Netzwerk schiessen. Nur der Server muss doch wissen, wer feindlich ist. Der Spieler entscheidet über sein Ziel.