Armed-Assault.de Twitter


Antwort
 
Themen-Optionen Ansicht
Alt 13.09.2014, 23:16   #1 (permalink)
Newbie
 
Registriert seit: 27.11.2013
Alter: 43
Beiträge: 10
Standard Nehmbares Objekt an Spieler heften und für andere Spieler nehmbar machen

Moin,

in meiner Coop-Mission (für dedicated Server) sollen die Spieler einen Laptop finden und diesen in die eigene Basis verbringen. Dabei wird der Laptop per addAction über ein Script an den aufhebenden Spieler geheftet (attachTo) und kann durch eine neue addAction von diesem auch wieder abgelegt werden. So ist für die anderen Mitspieler tatsächlich sichtbar, wer den Laptop trägt. Zuletzt fragt ein Trigger ab, ob der Laptop sich in der Basis befindet und ob er dort abgelegt wurde.

Problem:
Der Laptop lässt sich zwar nehmen und beliebig oft wieder ablegen und erneut aufheben, jedoch nur von dem Spieler, der ihn ursprünglich an sich genommen hat. Andere Spieler können den Laptop nicht aufheben oder dem ersten Spieler abnehmen (z.B. wenn der tragende Spieler gefallen ist). Genau das soll aber jederzeit möglich sein.


Mein Aufbau :

1. Objekt im Editor (laptop)

Initzeile:
Code:
this addAction["<t color='#ff1111'>Laptop nehmen</t>",  "scripts\laptop_nehmen.sqf", nil, 6, true, true, "", "alive _target  && ((getPos _target) distance (getPos _this)) <=  2"];
2. laptop_nehmen.sqf:
Code:
private ["_laptop","_activatingPlayer"];

_laptop = _this select 0;
_activatingPlayer = _this select 1;

//Laptop beim Wegnehmen löschen
deleteVehicle _laptop;

//Variable für Triggerabfrage setzen
abgelegt = false; 
publicVariable "abgelegt";

//Neuen Laptop zur Darstellung am Körper des nehmenden Spielers erzeugen
laptop = "Land_Laptop_F" createVehicle (getPos _activatingPlayer);

//Addaction für den neuen Laptop erzeugen
laptop  addAction["<t color='#ff1111'>Laptop nehmen</t>",  "scripts\laptop_nehmen.sqf", nil, 6, true, true, "", "alive _target  && ((getPos _target) distance (getPos _this)) <= 2"];

//Neuen Laptop an den aufhebenden Spieler heften
laptop attachTo [Player, [-0.25, -0.04, 0], "pelvis"];
laptop setVectorDirAndUp [[0.1,1,0],[-1,0,0.2]];

//Aktion 'Laptop ablegen' für aufhebenden Spieler im Actionmenü erzeugen
NewAct  = _activatingPlayer addAction [("<t color=""#CC2900"">" +  ("Laptop ablegen") + "</t>"), "scripts\laptop_ablegen.sqf",  "radio", -1, false, true,"", "_this == _target"];
3. laptop_ablegen.sqf
Code:
_activatingPlayer = _this select 1;
detach laptop;
abgelegt = true; 
publicVariable "abgelegt";
_activatingPlayer removeAction NewAct;
Die Ursache für das Problem scheint ja ganz offensichtlich darin zu liegen, dass der neue addAction Befehl, bzw. dessen Effekt für den Laptop nicht global verfügbar ist. Darum habe ich versucht, dass Problem mit einem Trigger zu lösen:

Trigger Typ: Keine
Aktivierung: Keine - Mehrfach
Bedingung: !abgelegt
Bei Akt.:
Code:
laptop addAction["<t color='#ff1111'>Laptop nehmen</t>", "scripts\laptop_nehmen.sqf", nil, 6, true, true, "", "alive _target && ((getPos _target) distance (getPos _this)) <= 2"];
Das hat aber leider nicht funktioniert. Nun bin ich mit meinem Latein am Ende. Wäre super, wenn da mal jemand von Euch Cracks draufschauen könnte!

Beispielmission im Anhang
Angehängte Dateien
Dateityp: zip FAS-Laptop-Test.Altis.zip (3,3 KB, 28x aufgerufen)
Grollig ist offline   Mit Zitat antworten
Alt 14.09.2014, 01:11   #2 (permalink)
SQF Zauberer 10 Jahre hx3
500 Beiträge1000 Beiträge
 
Benutzerbild von Vienna
 
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
Standard

Nimm anstelle des Laptops eine Fahne und verwende dafür die Flag-Befehle von Arma. Beim Aufnehmen wird die Fahne automatisch an den Spieler geheftet. Benützt der Spieler dann ein Fahrzeug, so ist die Fahne am Fahrzeug sichtbar.

Die Flag-Befehle sind hier angeführt: flagge
Vienna ist offline   Mit Zitat antworten
Alt 14.09.2014, 10:02   #3 (permalink)
Newbie
 
Registriert seit: 27.11.2013
Alter: 43
Beiträge: 10
Standard

Danke für den Tip, aber eine Fahne scheidet definitiv aus. Es muß schon das Laptop sein.

Im Grunde fehlt mir ja "nur" die passende Methode, den neu erzeugten Laptop global (also für alle anderen Spieler) mit der passenden addAction zu versehen. Leider gibt es den Befehl setVehicleInit in Arma3 nicht mehr.

Ich habe einen Beitrag von Kylania gefunden, der sich mit der Problematik befasst. Er verwendet dort eine eigene Funktion, um die addAction per BIS_fnc_MP global zu erstellen. Ganz verstanden habe ich das aber nicht. Wohin schreibe ich diese Funktion? In der init.sqf vordefinieren? Oder kommt die direkt mit in das laptop_aufnehmen script? Bislang habe ich es leider nicht hinbekommen.

Geändert von Grollig (14.09.2014 um 10:34 Uhr).
Grollig ist offline   Mit Zitat antworten
Alt 14.09.2014, 10:57   #4 (permalink)
50 Beiträge100 Beiträge
 
Registriert seit: 01.06.2009
Beiträge: 103
Standard

Guck Dir mal addPublicVariableEventHandler an.
Asso-Loki ist offline   Mit Zitat antworten
Alt 14.09.2014, 13:54   #5 (permalink)
SQF Zauberer 10 Jahre hx3
500 Beiträge1000 Beiträge
 
Benutzerbild von Vienna
 
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
Standard

Wenn es keine Fahne sein darf, dann versuche einmal das folgende Skript. Es sollte dafür ein im Editor erstellter Laptop reichen. Er kann ja mehrmals verwendet werden. Erforderlichen Falls den Laptop auf unzerstörbar setzen: https://community.bistudio.com/wiki/allowDamage

Es bedarf keiner publiken Variablen. Das Verhindern des Aufnehmens durch mehrere Spieler erfolgt durch den Befehl: https://community.bistudio.com/wiki/attachedTo

Anleitung zur Anwendung siehe im Kopf des Skripts.

Laptop1Attach.sqf
Code:
// Skript: "Laptop1Attach.sqf", zum Aufnehmen und Ablegen eines Objekts. [Vienna 14.08.2014]
// MP-tauglich. Läuft auf Arma3 ab V1.14, wegen Befehl attachedTo! 
//
// Laptop im Editor erstellen und folgende Aktion die Initzeile des Laptops kopieren:
//
// this addAction["---> Laptop aufnehmen","Laptop1Attach.sqf",[this,true], 1,true,false];

private ["_laptop","_aufnehmen","_aktionID"];

_laptop    = (_this select 3)select 0;
_aufnehmen = (_this select 3)select 1;

//Globale Variable erstellen. Status: Laptop aufgenommen = true, sonst false
if (isNil "Laptop1attached") then {Laptop1attached = false};

if (_aufnehmen) then //Aktionswahl aufnehmen
 {
  //Skript beenden wenn Laptop bereits aufgenommen!
  if (!isNull attachedTo _laptop) exitwith
   {
    if (Laptop1attached)
    then {player groupChat "---> Ich trage den Laptop bereits!"}
    else {player groupChat "---> Der Soldat gibt den Laptop nicht her!"}
   };
  //Laptop aufnehmen
  _laptop attachTo [player, [-0.25, -0.04, 0], "pelvis"];
  _laptop setVectorDirAndUp [[0.1,1,0],[-1,0,0.2]];
  player groupChat "---> Der Laptop wurde aufgenommen!";
  Laptop1attached = true;
  //Aktion zum Ablegen des Laptop dem Spieler hinzufügen
  _aktionID = player addAction["---> Laptop ablegen",  "Laptop1Attach.sqf",[_laptop,false],1,false,true];
  //Skript wartent bis Spieler tot oder er Ablegen befiehlt
  waitUntil {sleep 0.5; !alive player or !Laptop1attached};
  //Laptop ablegen
  detach _laptop;
  Laptop1attached = false;
  player removeAction _aktionID;
  player groupChat "---> Der Laptop wurde abgelegt!"
 }
else  //Aktionswahl ablegen
 {
  if (Laptop1attached)
  then {Laptop1attached = false}
  else {player groupChat "---> Ich habe keinen Laptop zum Ablegen!"}
 }
//Skript Ende
Ich konnte das Skript mangels Arma3 nicht mit dem hier verwendeten attachedTo testen. Es sollte aber damit laufen.
Vienna ist offline   Mit Zitat antworten
Alt 15.09.2014, 23:19   #6 (permalink)
Newbie
 
Registriert seit: 27.11.2013
Alter: 43
Beiträge: 10
Standard

Wow, Vienna! Danke, dass Du Dir die Mühe gemacht hast, ein komplettes Script dafür zu schreiben. Ich habe es bereits im MP Editor getestet und es läuft soweit ohne Fehler.

Hätte ich gewusst, dass Du Dir so viel Arbeit damit machst, wäre ich natürlich mehr ins Detail gegangen. Ich arbeite mit zwei unterschiedlichen Objekten (ein aufgeklappter Laptop der in der Mission per Editor platziert wird) und später (nach dem Aufnehmen) nur noch mit einem geschlossenen Laptop (anderes Editor-Objekt). Darum wird der Laptop in meinem Script nach dem Nehmen erstmal gelöscht und ein neuer erzeugt.

Zudem (und ich trau mich kaum, es zu sagen) hast Du mein eigentliches Problem oben vermutlich nur überflogen und dabei übersehen, dass es mir gerade darauf ankam, dass die anderen Spieler den Laptop auch aufnehmen können... sowohl vom Boden, als auch vom tragenden Spieler!

Gründe für das mögliche Fehlschlagen der Mission wären sonst:
1. Der tragende Spieler hat einen Disconnect oder Spielabsturz.
2. Der tragende Spieler ist handlungsunfähig (wir nutzen xmedsys, daher kommt !alive nur im Extremfall zum tragen).

Ich kann nicht recht beurteilen, ob man Dein Script so ohne weiteres dafür umschreiben kann (Laptop jederzeit nehmbar für jeden Spieler).

Du hast mich aber mit Deinem Script auf einen interessanten Befehl gebracht (attachedObjects).

Meine überarbeitete Version funktioniert nun (auch auf dem dedicated Server) eigentlich genau so wie ich es möchte:

Init.sqf (Funktion um die addAction für den neuen Laptop global zuzuweisen)
Code:
FAS_fnc_addAction = {
    private["_object","_script"];
    _object = _this select 0;
    _script = _this select 1;
    _object addAction _script;
};
laptop_nehmen.sqf
Code:
private ["_laptop","_activatingPlayer"];
_laptop = _this select 0;
_activatingPlayer = _this select 1;

//Laptop beim Wegnehmen löschen
deleteVehicle _laptop;

//Variable für Triggerabfrage setzen
abgelegt = false; 
publicVariable "abgelegt";

//Neuen Laptop zur Darstellung am Körper des nehmenden Spielers erzeugen
laptop = "Land_Laptop_F" createVehicle (getPos _activatingPlayer);

//Addaction für den neuen Laptop erzeugen (Funktion "FAS_fnc_addAction" aus init.sqf)
[[laptop, ["<t color='#ff1111'>Laptop nehmen</t>", "scripts\laptop_nehmen.sqf", nil, 6, true, true, "", "alive _target && ((getPos _target) distance (getPos _this)) <= 2"]], "FAS_fnc_addAction", nil, true] spawn BIS_fnc_MP;  

//Neuen Laptop an den aufhebenden Spieler heften
laptop attachTo [Player, [-0.25, -0.04, 0], "pelvis"];
laptop setVectorDirAndUp [[0.1,1,0],[-1,0,0.2]];

//Aktion 'Laptop ablegen' für aufhebenden Spieler im Actionmenü erzeugen
NewAct = _activatingPlayer addAction [("<t color=""#CC2900"">" + ("Laptop ablegen") + "</t>"), "scripts\laptop_ablegen.sqf", "radio", -1, false, true,"", "_this == _target"];

//Falls der Laptop dem Spieler abgenommen wird, beim zuletzt tragenden Spieler die Aktion "Laptop ablegen" entfernen
waitUntil {sleep 0.5; count attachedObjects _activatingPlayer == 0};
_activatingPlayer removeAction NewAct;
laptop_ablegen.sqf
Code:
_activatingPlayer = _this select 1;
detach laptop;
abgelegt = true; 
publicVariable "abgelegt";
Das einzige was mich daran noch stört ist Folgendes:

Wenn Spieler A den Laptop trägt und Spieler B den Laptop von dessen Körper an sich nimmt, dann wird für Spieler A die addAction "Laptop ablegen" nicht entfernt. Dieser hätte dann bei erneutem Aufheben des Laptops zweimal die Aktion "Laptop ablegen" und das würde sich sogar noch weiter stapeln. Vielleicht lässt sich das ja ganz einfach lösen... ich sehe nur gerade den Wald vor lauter Bäumen nicht. Diese Form von Script stellt gerade meinen persönlichen Horizont in Sachen .sqf dar.
Grollig ist offline   Mit Zitat antworten
Alt 15.09.2014, 23:19   #7 (permalink)
Newbie
 
Registriert seit: 27.11.2013
Alter: 43
Beiträge: 10
Standard

@Asso-Loki: Auch Dir danke für den Tip. Ich bin sicher, dass mein eigentliches Ziel mit einem publicVariableEventhandler sogar weit eleganter realisierbar wäre. Jedoch übersteigt das derzeit eindeutig meine Fähigkeiten. Mit Eventhandlern habe ich mich generell noch nicht wirklich beschäftigt. Rudimentär ja, aber es reicht derzeit nicht, um daraus etwas zu machen, ohne dass man mich mit der Nase draufstößt, sorry!

Geändert von Grollig (15.09.2014 um 23:25 Uhr).
Grollig ist offline   Mit Zitat antworten
Alt 16.09.2014, 11:33   #8 (permalink)
SQF Zauberer 10 Jahre hx3
500 Beiträge1000 Beiträge
 
Benutzerbild von Vienna
 
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
Standard

Ich weiß nicht wie du deine Version testest. Wenn du dabei nur die Spielfigur wechselst, dann wird beim Übernehmen des Laptops vermutlich die Ablegen-Aktion nicht gelöscht. Das müsste mit einem zweiten Spieler getestet werden. Vielleicht klappt es, falls du es allein testest, wenn bei waitUntil das sleep 0.5 entfernt wird.


Eine neue Version meines Skripts. Bei dieser sollte das Objekt dem tragenden Spieler abgenommen werden können.

Es wird dabei auch der Befehl attachedObjects verwendet. Mit diesem Befehl kann festgestellt werden ob der Spieler einen Laptop trägt.

Es werden dabei ein offener und ein geschlossener Laptop im Editor erstellt. Der geschlossene Laptop ist beim Spielstart im Abseits aufzustellen. Angebunden wird nur der geschlossene Laptop. Der offene wird dann im Spiel ins Abseits gestellt. Die Übergabe der Laptop-Namen an das Skript steuert diesen Vorgang.

Die Namen der Laptops und die Einträge der Aktionen in deren Initzeile sind im Kopf des Skripts ersichtlich.

"Laptop1Attach_v2.sqf"
Code:
// Skript: "Laptop1Attach_v2.sqf", zum Aufnehmen und Ablegen eines eines Laptops. [Vienna 16.08.2014]
// Verwendet wird dabei ein offener Laptop mit Namen: Laptop_offen
//            und ein geschlossener Laptop mit Namen: Laptop_zu
// MP-tauglich. Läuft erst auf Arma3 ab V1.14, wegen Befehl attachedTo und attachedObjects! 
//
// Laptops im Editor erstellen und folgende Aktion die Initzeile
// a) des offenen Laptops kopieren:
// this addAction["---> Laptop aufnehmen","Laptop1Attach_v2.sqf",[Laptop_zu,Laptop_offen,true], 1,true,false];
// b) des geschlossenen Laptops kopieren:
// this addAction["---> Laptop aufnehmen","Laptop1Attach_v2.sqf",[Laptop_zu,Laptop_zu,   true], 1,true,false];

private ["_laptop","_laptop_x","_aufnehmen","_aktionID"];

_laptop    = (_this select 3)select 0;//geschlossener Laptop (nur dieser wird aufgenommen)
_laptop_x  = (_this select 3)select 1;//offener Laptop
_aufnehmen = (_this select 3)select 2;//true = aufnehmen, false = ablegen 

//Globale Variable erstellen. Status: Laptop aufgenommen = true, sonst false
if (isNil "Laptop1attached") then {Laptop1attached = false};

if (_aufnehmen) then //Aktionswahl aufnehmen
 {
  //Skript beenden wenn Spieler einen Laptop bereits aufgenommen hat!
  if (count attachedObjects player > 0) exitwith {player groupChat "---> Ich trage bereits einen Laptop!"};
  //offenen Laptop ins Abseits stellen.(Aufgenommen wird nur der geschlossene Laptop!)
  If (_laptop != _laptop_x) then {_laptop_x setPos [0,0]};
  //Laptop aufnehmen
  _laptop attachTo [Player, [-0.25, -0.04, 0], "pelvis"];
  _laptop setVectorDirAndUp [[0.1,1,0],[-1,0,0.2]];
  player groupChat "---> Der Laptop wurde aufgenommen!";
  Laptop1attached = true;
  //Aktion zum Ablegen des Laptop dem Spieler hinzufügen
  _aktionID = player addAction["---> Laptop ablegen",  "Laptop1Attach_v2.sqf",[_laptop,_laptop,false],1,false,true];
  //Skript wartet bis Spieler tot oder er kein Objekt mehr angeheftet hat
  waitUntil {sleep 0.5; !alive player or !Laptop1attached or count attachedObjects player == 0};
  //Laptop ablegen
  if (count attachedObjects player > 0) then {detach _laptop};
  Laptop1attached = false;
  player removeAction _aktionID;
  player groupChat "---> Der Laptop wurde abgelegt!"
 }
else  //Aktionswahl ablegen
 {
  if (Laptop1attached)
  then {Laptop1attached = false}
  else {player groupChat "---> Ich habe keinen Laptop zum Ablegen!"}
 }
//Skript Ende
Beim Aufrufen den neuen Skriptnamen beachten! Mangels Arma3 konnte ich das Skript nicht testen.
Vienna ist offline   Mit Zitat antworten
Alt 16.09.2014, 23:01   #9 (permalink)
Newbie
 
Registriert seit: 27.11.2013
Alter: 43
Beiträge: 10
Standard

Wahnsinn! Vielen Dank, dass Du Dir solche Mühe machst.

Ich hätte es natürlich gern mit eigenen Mitteln hinbekommen - bin aber völlig fasziniert vom Aufbau Deines Scripts und wie Du die gesamte Funktionalität darin untergebracht hast. Ich habe bereits eine Menge daraus gelernt - insbesondere was die Übergabe der Array-Einträge betrifft. Danke auch für die ausführliche Kommentierung und die Erläuterungen! Auf die Lösung mit dem Austausch der Laptops anstelle des Löschens und neu Erstellens bin ich in meiner Anfänger-Blindheit gar nicht gekommen, obwohl ich soetwas in anderen Scripten natürlich schon mehrfach gesehen habe.

Noch kurz zur Info: Ich habe Scripte bislang immer auf unserem dedicated Clanserver und gemeinsam mit einem anderen Spieler getestet.

In Deiner letzten Version habe ich bislang noch zwei Probleme festgestellt, wobei ich das erste allein lösen konnte:

1. Der offene Laptop, welcher in der Mission gesucht und eingesammelt werden soll, steht in der fertigen Mission auf einem Schreibtisch (Editor Objekt) und ist mit dem Befehl "attachTo" daran angeheftet. Darum funktionierte das Verschieben zunächst nicht.

Ich hatte daher zunächst Deine Zeile
Code:
If (_laptop != _laptop_x) then {_laptop_x setPos [0,0]};
abgeändert in:
Code:
If (_laptop != _laptop_x) then {detach _laptop_x; _laptop_x setPos [0,0]};
Das funktionierte aber nur bei einem selbst gehosteten MP Spiel. Auf dem dedicated Server wurde der Laptop zwar detached, aber nicht verschoben. Abhilfe schaffte die folgende Änderung:
Code:
If (_laptop != _laptop_x) then {detach _laptop_x; sleep 0.5; _laptop_x setPos [0,0]};
Ich gehe davon aus, dass der Server hier einfach ein wenig Zeit braucht, um diese beiden aufeinander folgenden Befehle korrekt abzuarbeiten. Eventuell lassen sich die 0.5 Sekunden ja noch reduzieren - dass würde ich später noch testen.

2. Das zweite Problem ist, dass auf dem dedicated Server der geschlossene Laptop nicht korrekt am aufnehmenden Spieler ausgerichtet wird. Der attachTo Befehl scheint dort korrekt ausgeführt zu werden, aber der setVectorDirandUp Befehl scheinbar nicht. Bei meinem eigenen Lösungsansatz gab es dieses Problem nicht. Ich weiß gerade nicht, woran das liegt... ggf. weil ich für den Laptop anstelle einer lokalen Variable den Objektnamen verwendete habe? Hatte bislang keine Gelegenheit, mir das näher anzusehen. Eventuell reicht ja auch hier ein kurzer Sleep zwischen den beiden Befehlen. Werde ich ausprobieren.

3. Mangels Zeit und anwesender Mitspieler habe ich heute noch nicht weiter testen können.

Es fehlt also noch der Test für das "Abnehmen des Laptops, während dieser von einem anderen Spieler getragen wird und korrekte Löschung der addAction beim tragenden Spieler."

Das werde ich so bald wie möglich nachholen und hier berichten.

Geändert von Grollig (16.09.2014 um 23:10 Uhr).
Grollig ist offline   Mit Zitat antworten
Alt 17.09.2014, 07:50   #10 (permalink)
SQF Zauberer 10 Jahre hx3
500 Beiträge1000 Beiträge
 
Benutzerbild von Vienna
 
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
Standard

Kann schon sein, dass es einen (ablaufbedingten) Unterschied macht ob eine globale oder lokale Variable verwendet wird und bei lokal eine kleine Pause notwendig ist, die dem Server die Möglichkeit gibt einen zuvor publiken Befehl (wie attachTo) zu verarbeiten der das selbe Objekt betrifft. Dafür spricht die Notwendigkeit der Pause zwischen detach und setPos.

So wie ich das sehe unterbricht sleep den Ablauf des Skripts und gibt dem System die Möglichkeit seine "Arbeit" zu erledigen. Dazu genügt vermutlich schon ein Sleep von 0.1. Bei waitUntil wurde sleep 0.5 genommen, weil es ausreicht wenn in diesem Takt die Abfrage erfolgt.

Es hat sich gezeigt, dass bei Skripten, die bereits beim Spielstart aufgerufen werden, in der 1. Zeile ein sleep stehen muss, wenn im Skript Befehle stehen die eine vollständige Initialisierung des Spiels benötigen. sleep wartet dabei anscheinend nicht die eingestellte Zeit ab, sondern pausiert bis die Initialisierung abgeschlossen ist.
Vienna ist offline   Mit Zitat antworten
Alt 18.09.2014, 15:17   #11 (permalink)
Newbie
 
Registriert seit: 27.11.2013
Alter: 43
Beiträge: 10
Standard

Gestern Abend hatte ich Gelegenheit, das letzte Script von Vienna mit mehreren Mitspielern auf unserem Clanserver (dedicated) ausführlich zu testen:

Das Abnehmen des Laptops von einem tragenden Spieler funktionierte einwandfrei. Auch wurde danach die Aktion 'Laptop Ablegen' beim zuvor tragenden Spieler korrekt entfernt (das hatte ja in meinem eigenen Script bislang nicht funktioniert).

Das Problem, dass der aufgenommene Laptop nicht korrekt am Spieler ausgerichtet wurde, blieb leider bis zuletzt bestehen. Weder ein Sleep Befehl zwischen dem AttachTo und SetVectorDirAndUp, noch das Verwenden des globalen Objektnamens (laptop_zu) anstelle der lokalen Variablen (_laptop) konnte da Abhilfe schaffen. Warum es in meinem Script funktioniert und bei Viennas Lösung nicht... ich habe keinen Schimmer.

Darüber hinaus blieb der Laptop nach dem Ablegen (über den Aktions Menü Eintrag des tragenden Spielers) teilweise einfach in der Luft hängen, anstatt zu Boden zu fallen. Dies lies sich mit einem setPos Befehl
Code:
_laptop setPos (getPos player);
unmittelbar nach dem detachen beheben, was allerdings optisch nicht ganz so schick aussah, als wenn der Laptop beim Ablegen einfach zu Boden gleitet.

Ich werde nun noch einen letzten Versuch unternehmen, die bislang überprüften Funktionalitäten der beiden Scripte so zu verschmelzen, dass der Laptop korrekt dargestellt wird und zugleich die AddAction Einträge korrekt entfernt werden. Für Letzteres werde ich dem Beispiel von Vienna folgen und eine globale Variable zur Abfrage verwenden.

Das Ergebnis werde ich hier auf jeden Fall noch mitteilen.
Grollig ist offline   Mit Zitat antworten
Alt 18.09.2014, 17:14   #12 (permalink)
SQF Zauberer 10 Jahre hx3
500 Beiträge1000 Beiträge
 
Benutzerbild von Vienna
 
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
Standard

Hat der Fehler beim Ablegen etwas mit der fehlerhaften Aufnahme zu tun?

Vielleicht hilft es, wenn man den attachTo Teil aus dem Skript auslagert?

Diese Zeilen:
Code:
  //Laptop aufnehmen
  _laptop attachTo [Player, [-0.25, -0.04, 0], "pelvis"];
  _laptop setVectorDirAndUp [[0.1,1,0],[-1,0,0.2]];
  player groupChat "---> Der Laptop wurde aufgenommen!";
durch diese ersetzen:
Code:
  //Laptop aufnehmen
  _laptop spawn
   {
     _this attachTo [Player, [-0.25, -0.04, 0], "pelvis"];
     _this setVectorDirAndUp [[0.1,1,0],[-1,0,0.2]]
   };
  waitUntil {count attachedObjects player > 0};
  player groupChat "---> Der Laptop wurde aufgenommen!";
Vienna ist offline   Mit Zitat antworten
Alt 26.09.2014, 13:59   #13 (permalink)
Newbie
 
Registriert seit: 27.11.2013
Alter: 43
Beiträge: 10
Standard

Vorweg: Sorry, dass ich mich erst so spät zurückmelde. Ich hatte in den vergangenen Tagen wirklich wenig Zeit.

Ich habe Viennas letzte Version des Scripts noch einige Male angepasst, konnte aber das "Problem" mit der Darstellung des Laptops am Körper des Spielers leider nicht lösen. Auch die Auslagerung des Scriptes hat dabei leider nicht zum Erfolg geführt. Ich bin allerdings sicher, dass mein Scheitern an meinen bescheidenen Fähigkeiten und nicht an Viennas Code liegt.

Viennas Script hat mich aber auf eine Lösung für das korrekte Entfernen der Aktion "Laptop ablagen" gebracht. Leider musste bei dafür eine globale Variable herhalten, über welche der Prozess einer Neuaufnahme des Laptops an andere laufende Instanzen des Scriptes übermittelt wird.

Das Ergebnis ist aus Sicht eines erfahreneren Scripters sicherlich alles andere als gut gelöst, jedoch funktioniert es für meine kleine Mission nun fehlerfrei und mit den genannten positiven Nebeneffekten (flüssiges Ablegen des Laptops, korrekte Darstellung am Spieler, korrektes Entfernen der Aktion "Laptop ablegen" beim tragenden Spieler, wenn ihm der Laptop von einem anderen Spieler abgenommen wird).

Ich möchte hier die funktionierende Version nochmal posten, da es anderen vielleicht mal dienlich sein kann, wenn vielleicht auch nur als Grundlage für eine bessere Lösung:

Benötigt wird im Editor:
Ein offener Latop (Land_Laptop_unfolded_F) mit folgendem Eintrag in der Init:
Code:
this addAction["<t color='#ff1111'>Laptop nehmen</t>", "scripts\laptop_nehmen.sqf", nil, 6, true, true, "", "alive _target && ((getPos _target) distance (getPos _this)) <= 3"];
In der init.sqf:
Code:
FAS_fnc_addAction = {
    private["_object","_script"];
    _object = _this select 0;
    _script = _this select 1;
    _object addAction _script;
};
Im Unterordner \scripts:

laptop_nehmen.sqf
Code:
private ["_laptop","_activatingPlayer","_aktionAblegen"];
_laptop = _this select 0;
_activatingPlayer = _this select 1;

//Globale Variable zur Info an andere laufende Instanzen dieses Skriptes: Eine neue Aufnahme des Laptops findet statt
NeueAufnahmeLaptop = true;
publicVariable "NeueAufnahmeLaptop";

//Bisherigen Laptop löschen
deleteVehicle _laptop;

//Globale Variable für Missionsziel-Triggerabfrage setzen
LaptopAbgelegt = false; 
publicVariable "LaptopAbgelegt";

//Neuen Laptop zur Darstellung am Körper des nehmenden Spielers erzeugen
laptop = "Land_Laptop_F" createVehicle (getPos _activatingPlayer);

//Neuen Laptop an den aufhebenden Spieler heften
laptop attachTo [Player, [-0.25, -0.04, 0], "pelvis"];
laptop setVectorDirAndUp [[0.1,1,0],[-1,0,0.2]];

//Aktion 'Laptop Nehmen' für den neuen Laptop erzeugen (die Funktion 'FAS_fnc_addAction' muss in der init.sqf definiert sein)
[[laptop, ["<t color='#ff1111'>Laptop nehmen</t>", "scripts\laptop_nehmen.sqf", nil, 6, true, true, "", "alive _target && ((getPos _target) distance (getPos _this)) <= 3"]], "FAS_fnc_addAction", nil, true] spawn BIS_fnc_MP;  

//Aktion 'Laptop ablegen' für nehmenden Spieler im Actionmenü erzeugen
_aktionAblegen = _activatingPlayer addAction [("<t color=""#CC2900"">" + ("Laptop ablegen") + "</t>"), "scripts\laptop_ablegen.sqf", nil, 6, false, true,"", "_this == _target"];

//Globale Variable zur Info an andere laufende Instanzen dieses Skriptes: Die neue Aufnahme des Laptops ist abgeschlossen
sleep 0.5;
NeueAufnahmeLaptop = false;
publicVariable "NeueAufnahmeLaptop";

//Warten bis sich der Laptop nicht mehr am nehmenden Spieler befindet,dann Aktion 'Laptop ablegen' entfernen
waitUntil {sleep 0.2; !alive player or NeueAufnahmeLaptop or LaptopAbgelegt};  // or count attachedObjects player == 0
_activatingPlayer removeAction _aktionAblegen;

//Ende des Scripts
und

laptop_ablegen.sqf
Code:
//Laptop ablegen
detach laptop;

//Globale Variable für Missionsziel-Triggerabfrage setzen
LaptopAbgelegt = true; 
publicVariable "LaptopAbgelegt";
Dann noch im Editor einen Trigger erstellen für die Zone, in welche der Laptop zum Abschluss der Mission verbracht werden soll:

Größe: 20 x 20
Typ: Keine
Aktivierung: Jeder, Einmal, Vorhanden
Bedingung:
Code:
this && {LaptopAbgelegt} && {laptop in thisList}
Bei Aktivierung:
Code:
nul = ["<t size='1.2' color='#ffffff'>Der Laptop wurde gesichert.<br/>Mission erfolgreich!</t>",0,0.3,10,5] spawn bis_fnc_dynamictext;
Alternativ kann bei Aktivierung natürlich auch das Ende der Mission oder die Erfüllung einer Missionsaufgabe veranlasst werden.

Abschließend möchte ich Vienna nochmals ausdrücklich dafür danken, daß er sich soviel Zeit für mich genommen und mir durch sein Script eine - für mich ausreichende und funktionierende - Lösung aufgezeigt hat. Ich hoffe nur, daß Du nicht sauer bist, weil ich Dein Script nun im Grunde doch nicht verwendet habe.
Grollig ist offline   Mit Zitat antworten
Alt 26.09.2014, 17:55   #14 (permalink)
SQF Zauberer 10 Jahre hx3
500 Beiträge1000 Beiträge
 
Benutzerbild von Vienna
 
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
Standard

Ist doch schon ein schöner Erfolg, dass deine Variante jetzt funktioniert. Die bei meinem Skript in MP mangelhaft durchgeführten Befehle führe ich auf einen Bug in Arma3 zurück. Solche Probleme treten leider immer wieder auf. Vielleicht würde es helfen diese Befehle vom Server durchführen zu lassen. Das wäre dann aber aufwändiger als deine Version.

Wenn es kein Denkfehler von mir ist, dann könnte deine Variante noch wesentlich vereinfacht werden. Die beiden publiken Variablen, NeueAufnahmeLaptop und LaptopAbgelegt, scheinen gänzlich überflüssig.

Dazu müsste an deren Stelle die waitUntil Zeile im Skript auf
waitUntil {sleep 0.2; !alive player or count attachedObjects player == 0};
und die Abfrage im Auslöser auf
this && isNull attachedTo laptop && laptop in thisList
abgeändert werden.
Vienna ist offline   Mit Zitat antworten
Antwort


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen
Ansicht

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Objekt nur sichtbar wenn Spieler existiert killshot Editing & Scripting 5 22.08.2014 20:30
Spieler (Zivilist) wird manchmal (!?) aus Auto gekickt Wolkenbeisser Editing & Scripting 8 06.09.2011 07:19


Kontakt - HX3.de - Archiv - Nach oben

Angetrieben durch vBulletin, Entwicklung von Philipp Dörner & Tobias



SEO by vBSEO 3.2.0 ©2008, Crawlability, Inc.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116