PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Komisches Verhalten beim AI plündern im MP


Wolkenbeisser
23.04.2015, 10:11
Hallo zusammen

Ich habe hier ein Problem mit einer gehosteten MP-Mission, dessen Ursache ich bisher nicht herausfinden konnte.

Ziel
Die Spieler starten nur mit Pistole und ohne Karte. Sobald sie den ersten KI-Gegner getötet haben, sollten sie dessen Karte nehmen (erst damit können sie erkennen, wo sie sich befinden).

Problem
Ich als Host kann auf das Inventar des getöteten KI-Gegners zugreifen, kein Problem. Die Clients hingegen können das Inventar des toten KI-Gegners zwar sehen (!?!), aber sie können die Karte nicht in ihr eigenes Inventar ziehen. Das Kartenfeld im Inventar des Spielers/Clients bleibt rot und verweigert somit die Annahme der Karte! :stupid:

Script um die AI-Gegner auszurüsten
Da die KI-Gegner in meiner Mission ganz bestimmte Ausrüstung haben müssen, teile ich ihnen diese per Script zu.

Init-Zeile KI-Gegner:
null = [this] execVM "inventar\inventar_leichter_AAF_Soldat.sqf"

Script-Inhalt 'inventar_leichter_AAF_Soldat.sqf':
// Füge in die Init-Zeile der zu bewaffnenden Einheit den nachfolgenden Code ein ('scriptname' muss aber Name des Scripts sein!)
// null = [this] execVM "inventar\scriptname.sqf"
// Nachfolgend der Code des Scripts, welches MP-Probleme mit Ausrüstung und 'join in progress' verhindern sollte
// Nachtsichtbrille kann bei Bedarf mit _unit linkItem "NVGoggles" zugefügt werden

sleep 1;

waitUntil {!isNull player};
_unit = _this select 0;
if (local _unit) then {

removeuniform _unit;
removeallcontainers _unit;
removeAllWeapons _unit;
removeGoggles _unit;
removeHeadgear _unit;
removeVest _unit;
removeAllAssignedItems _unit;
removebackpack _unit;

_unit addUniform "U_I_CombatUniform_shortsleeve";
_unit addHeadgear "H_MilCap_dgtl";

_unit linkItem "ItemMap";
_unit linkItem "ItemCompass";
_unit linkItem "ItemWatch";

_unit addMagazine "9Rnd_45ACP_Mag";
_unit addWeapon "hgun_ACPC2_F";

_unit addItem "FirstAidKit";

_unit addMagazine "9Rnd_45ACP_Mag";
_unit addMagazine "9Rnd_45ACP_Mag";
_unit addMagazine "9Rnd_45ACP_Mag";
};

if(true) exitWith{};

Mögliche Ursachen des Fehlers im Verdacht
a) Mit dem Script stimmt etwas nicht (Lokalitätenproblem?)
b) Die Spieler beginnen ohne Primärwaffe (also nur mit Pistole)

Hat jemand eine Idee, wo das Problem liegen könnte? Ein Lokalitätenproblem weil die KI... ja wo genau... beheimatet ist? Dann jedoch ist unklar, warum die Spieler deren Inventar anschauen können. Wäre dankbar für jeden Hinweis.

P.S: Die Spieler werden übrigens auf dieselbe Art ausgerüstet (natürlich mit BLUFOR-Uniformen und so).

Drunken Officer
23.04.2015, 19:14
Mal ganz nebenbei, du mußt Karte und GPS entfernen damit man keine Karte sehen kann. Dier Erfahrung habe ich bei SAINT MICHAEL gemacht.

Also um die Spieler abzurüsten, startest du ganz einfach in der initplayerlocal.sqf

sleep 1;
waitUntil {!isNull player};
waitUntil {player == player};
player unlinkitem "itemmap"; player unlinkitem "itemgps";


Nun zur KI

So wie es sich ließt, hast du mehrere scripts für leichte, mittlere und schwere Ausrüstung.
Warum packst du es nicht alles in ein Script und arbeitest mit swich-do?
Desweiteren solltest du die KI vom Server verwalten lassen.
Also als Beispiel:
0=[this, "leicht"] execVM "ausruestung.sqf"

if (isServer) then {
_ki = _this select 0;
_asrt = _this select 1;

switch (_asrt) do
{
case "leicht": {.....};
case "mittel": {....};
case "schwer": {.....};
};
}

Drunken Officer
23.04.2015, 19:17
Mal ganz nebenbei, du mußt Karte und GPS entfernen damit man keine Karte sehen kann. Dier Erfahrung habe ich bei SAINT MICHAEL gemacht.

Also um die Spieler abzurüsten, startest du ganz einfach in der initplayerlocal.sqf

sleep 1;
waitUntil {!isNull player};
waitUntil {player == player};
player unlinkitem "itemmap"; player unlinkitem "itemgps";


Nun zur KI

So wie es sich ließt, hast du mehrere scripts für leichte, mittlere und schwere Ausrüstung.
Warum packst du es nicht alles in ein Script und arbeitest mit swich-do?
Desweiteren solltest du die KI vom Server verwalten lassen.
Also als Beispiel:
0=[this, "leicht"] execVM "ausruestung.sqf"

if (isServer) then {
_ki = _this select 0;
_asrt = _this select 1;

// ------ entfernt das Zeug von der KI
removeuniform _ki;
removeallcontainers _ki;
removeAllWeapons _ki;
removeGoggles _ki;
removeHeadgear _ki;
removeVest _ki;
removeAllAssignedItems_ki;
removebackpack _ki;

// ----- prüft welche Ausrüstung vergeben werden soll
switch (_asrt) do
{
case "leicht": {.....};
case "mittel": {....};
case "schwer": {.....};
};
}

Wolkenbeisser
23.04.2015, 22:36
Karte und GPS von den Spielern entfernen ist nicht das Problem, das funzt bereits bestens. Auch kann das Inventar eines Spielers problemlos geplündert werden, wenn er stirbt. Soweit ist alles ok.

Das Problem liegt wirklich beim Inventar der KI. Sowohl Host, als auch Client können es öffnen und alles darin sehen (wie vom Script zugeteilt), aber wenn ein Client die Karte (die ihm eben noch fehlt) vom KI-Inventar nehmen will, ist sein Kartenslot rot.

Und genau hier blicke ich nicht mehr durch: Entweder klappt die Zuteilung der Ausrüstung, dann kann man sie sowohl sehen, als auch nehmen, oder sie klappt nicht. Dann kann man sie weder sehen, noch nehmen.

Es ist die Inkonsistenz die mir Sorgen macht. Das Inventar ist so sichtbar, wie es sein sollte, aber es kann nicht geplündert werden... jedenfalls nicht vom Client. Der Host kann... :nachdenklich:

Zu Deinem Beispiel: Ich bin nicht sehr gut im Scripten und ich möchte auch die einzelnen Inventarscripte teilweise in andere Missionen kopieren können, ohne jeweils das ganze Script anpassen zu müssen.

Verstehe ich das richtig, dass der Aufruf in der Initzeile der betroffenen KI gleich bleiben würde, wie in meinem Beispiel, also...
null = [this] execVM "inventar\inventar_leichter_AAF_Soldat.sqf"

...dann aber das Inventarscript so beginnen müsste...
_unit = _this select 0;
if (isServer) then {

removeuniform _unit;
removeallcontainers _unit;
removeAllWeapons _unit;
removeGoggles _unit;
removeHeadgear _unit;
removeVest _unit;
removeAllAssignedItems _unit;
removebackpack _unit;

_unit addUniform "U_I_CombatUniform_shortsleeve";
etc.

P.S: Nochmals wegen dieser Inkonsistenz. Könnte es evtl. sein, dass es gar nicht am Script, bzw. dessen Aufruf liegt? Wie kann es ein Lokalitätenproblem sein, wenn der Client alles richtig sieht (nur da nehmen klappt ja nicht). Bin im Moment absolut ratlos...

Drunken Officer
23.04.2015, 22:54
Probiere es mal, der KI die Karte als Waffe zu geben. Ich bin jetzt zu faul zum testen. Vlt löst das dein Problem

Es gab mal ein Problem mit den Werkzeugkisten. Die konnte man auch als Waffe bzw. als Item anhängen. War total putzig.

**********
Wenn du die Ausrüstungsgeschichte der KI nicht nur durch den Server ausführen läßt, bekommst du ein Problem.
Server und Clienten laden alle die selbe Mission. Jetzt steht da z.B. removeallweapons this.
Dieser Befehl hat einen globalen Effekt, die Einheit ist entwaffent.
Kurze Zeit später hat die Einheit jetzt z.b. eine Waffe aufgenommen, alles toll. Aber jetzt kommt ein Spieler noch nachgejoint, weil er sich paar Minuten verspätet hat.
Der Spieler lädt die Mission und da steht: removeallweapons this -> na klar, wenn es der Ersteller will, löscht ArmA die Waffen. Der Effekt ist jedoch global und schwups ist alles weg.

Ich persönlich lasse KI nur durch den Server verwalten.

Wolkenbeisser
24.04.2015, 11:36
...
Wenn du die Ausrüstungsgeschichte der KI nicht nur durch den Server ausführen läßt, bekommst du ein Problem...

Ok, ich probiere das. Wäre dann der Aufruf so wie in meinem letzten Post beschrieben (so mit "if (isServer) then {...." und so im Script)?

Drunken Officer
24.04.2015, 12:58
jo, genau so

Buliwyf
24.04.2015, 16:34
...oder du lässt die Clients außen vor, indem Du die nötigen Scripte in der initServer.sqf (https://community.bistudio.com/wiki/Event_Scripts) startest.

Wolkenbeisser
25.04.2015, 16:22
Hallo zusammen

Der MP-Test, die KI auf dem Server auszurüsten (nach Methode aus Post vom 23.04.2015 um 22:36) hat nichts gebracht. Dafür habe ich jetzt ein genaueres Fehlerbild:

-------------------------------------------------
1. Nach wie vor geht das Ziehen der Karte (übrigens vermutlich auch Kompass, Uhr, GPS und Funkgerät - sprich verm. alle Items) vom KI-Inventar ins eigene Inventar nur beim Host. Beim Client geht es nicht.

2. Der Client hat das Problem bei beiden Scriptvarianten. Also egal ob ich die KI-Inventarscripts mit if (isServer) then { starte oder mit if (local _unit) then {. Das macht überhaupt keinen Unterschied.

3. Jetzt wird's interessant: Der Client sieht an (und in) der KI exakt die gemäss Script zugeteilte Ausrüstung. D.h. sie wird bei Host und Client identisch (!) dargestellt. Somit...

4. Können sowohl Mütze, als auch Waffen, Erste Hilfe Packs und Magazine problemlos von beiden (Host und Client) aus dem KI-Inventar genommen werden (dass die Uniform nicht geht, ist klar, das ist ein Feature, kein Bug).

5. Verwende ich im KI-Ausrüstungsscript _unit addWeapon "ItemMap"; und anschliessend _unit linkItem "ItemMap"; dann existiert der Fehler immer noch.

6. Verwende ich im KI-Ausrüstungsscript _unit addWeapon "ItemMap"; anstatt_unit linkItem "ItemMap"; dann existiert der Fehler immer noch.

7. Verwende ich im KI-Ausrüstungsscript nur _unit addItem "ItemMap"; dann hat die KI die Karte nicht im Kartenslot, sondern in der Uniform. Und dann, oh Wunder, kann der Client die Karte daraus nehmen!

8. Wenn der Client einen von BIS fertig ausgerüsteten KI-Gegner tötet, kann er die Karte auch nehmen! Und diese KI hat die Karte dann im Kartenslot.
-------------------------------------------------

Fazit: Es muss daher zwingend etwas damit zu tun haben, wie der KI die Karte zugewiesen wird (und die Karte muss auch irgendwie anders 'gestrickt' sein, als z.B. eine Mütze).

Ich vermute den Fehler irgendwo im Bereich von Punkt 5 bis 7. Wenn ich nur wüsste, wie BIS die vorgefertigten Soldaten ausrüstet, dann könnte ich das vielleicht irgendwie nachvollziehen.

Bei dieser Mission ist es entscheidend, dass ich die KI-Gegner so ausrüsten kann, wie ich sie brauche. Wenn ich das nicht fertig bringe, muss ich einen Workaround finden (z.B. Punkt 7). Und das möchte ich soweit wie möglich vermeiden.

Hat jemand eine Idee, wie man das Problem lösen könnte?

Vielen Dank für eure Hilfe.

Drunken Officer
25.04.2015, 18:26
Die Dinger werden in der Config folgendermaßen zugewiesen

class wasweißich : Soldier_F
{
....
linkedItems[] = {""ItemGPS","ItemMap","ItemCompass","ItemWatch","ItemRadio","NVGoggles"};
....
};

Wie verhält es sich auf einem Dedi-Server?


EDIT:
Ich habe es mal getestet, auf dem Dedi-Server funktioniert es wunderbar.
In der ZIP ist zu einem der Ordner und die MP Misison PBO

Wolkenbeisser
26.04.2015, 21:43
Hallo Drunken Officer

Ich habe Deine Mission soeben als gehostete Coop mit einem Kumpel getestet.

Dazu musste ich eine zweite spielbare Einheit hinzufügen. Und damit Dein Inventarscript keine Unterhosensoldaten prodzuziert (:zahn:) habe ich die EAST-Mannen durch GUER-Mannen ersetzt (natürlich verfeindet mit BLUFOR). Alles andere habe ich unverändert bestehen lassen. Die abgeänderte Version findest Du im Anhang.

Resultat: Es hat auch bei Deiner Mission nicht geklappt. Der Host kann die Karte und das GPS nehmen, der Client nicht.

Somit wissen wir wieder was Neues: Auf einem Dedi geht es, in einem gehosteten Spiel nicht.

Woran das wohl wieder liegt? Inwiefern unterscheidet sich ein 'Client-auf-einem-Dedi' von einem 'Client-auf-einem-Host'?

Drunken Officer
27.04.2015, 08:18
BIS rockt!!!

Bei deiner Variante kann ich auf einem Dedi nur noch das GPS aufnehmen. Egal mit welcher Figur. :motz:

Wolkenbeisser
27.04.2015, 14:18
Wie das? Ich habe ja nur EAST-Männer gegen GUER-Männer getauscht (und eine spielbare Einheit hinzugefügt, die vermutlich keinen Einfluss hat). Die Scripts habe ich nicht angerührt... !?!

BIS... :schlagen:

Naja, ich warte mal ab, ob noch jemand eine Idee hat. Wenn nicht, werde ich die Items der KI halt in der Uniform deponieren (anstatt im dafür vorgesehenen Slot).

Nokman
04.05.2015, 19:33
Ist jetzt nur mal die Idee das Inv und Rucksack zu speeren von Anderen Einheiten. Könnte man nun auch umlegen auf KI etc.
player addEventHandler["InventoryOpened", {_this call fnc_open}];

fnc_open = {
_unit = _this select 0;
_container = _this select 1;
_exit = {
[] spawn {
for "_i" from 1 to 6 do {
closeDialog 0;
sleep 0.2;
};
if(!isNull (findDisplay 602)) then {
closeDialog 0;
closeDialog 0;
};
};
};
_isPack = getNumber(configFile >> "CfgVehicles" >> (typeOf _container) >> "isBackpack");
if(_isPack == 1) then {
call _exit;
};
if(_container isKindOf "Man") exitWith {
[] spawn {
waitUntil {!isNull (findDisplay 602)};
closeDialog 0;
};
};}