11.09.2014, 00:09 | #1 (permalink) |
Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 297
|
Objekt zuerst zum Spieler, dann auf den Boden setPos-en
Hallo zusammen
Ich könnte wieder einmal zu einem Code-Schnipsel Unterstützung gebrauchen. AUSGANGSLAGE: - Spielbare Einheit mit dem Namen AL1 auf der Karte - Kleiner Rasenmäher mit dem Namen Stao_AL1 auf der Karte - Nach dem (Base-) Respawn wird die Einheit AL1 zum Rasenmäher Stao_AL1 gebeamt - Ziel: Respawn soll nicht exakt beim Todesort sein Mit einem Auslöser (jeder/mehrfach/vorhanden) setze ich den Rasenmäher 70m hinter die Einheit AL1, sobald diese sich 100m von Stao_AL1 entfernt hat. Somit hat AL1 quasi seinen persönlichen Respawnpunkt im Schlepptau. Dieser Auslöser funktioniert bereits. Er ist so aufgebaut: BED: Code:
this and vehicle AL1 in thislist and vehicle AL1 distance Stao_AL1 > 100 Code:
Stao_AL1 setPos [(getPos vehicle AL1 select 0) -70, (getPos vehicle AL1 select 1) +0, (getPos vehicle AL1 select 2) +0] PROBLEM: Am Boden und in Fahrzeugen funktioniert der obige Auslöser perfekt. Leider jedoch nicht, wenn AL1 aus 1000m Höhe aus dem Heli springt und vergisst die Reissleine zu ziehen. Er schlägt dann ein, und der Rasenmäher Stao_AL1 ist wie geplant 70m hinter ihm. Leider ist 'hinter ihm' im Falle eines senkrechen Falles 'über ihm' . Resultat: AL1 respawnt in 70m Höhe, fällt runter und stirbt. Dann respawnt er wieder in 70m Höhe, fällt runter und stirbt. Dann respawnt er wieder, usw... ewiges Fegefeuer sozusagen... LÖSUNGSANSATZ: Offenbar gibt es im Arma3 den Befehl SetPosATL (above Terrain Level). Die Frage ist nur: Wie muss ich den obigen Auslöser anpassen, dass der Rasenmäher Stao_AL1 nicht nur 70m hinter AL1, sondern gleichzeitig auch immer 'auf Grund' ist (es wäre auch egal, wenn er gleich unter AL1 ist, während der senkrechten Bewegung)? Ich kämpfe derzeit mit den verschiedenen 'this selec 0,1 und 2' - und habe deshalb bisher noch keinen Plan, wie der Auslöser aussehen muss. Vielleicht hat sogar jemand eine Idee, wie man die Aktivierungszeile des Auslösers noch besser machen kann... Jedenfalls jetzt schon vielen Dank für die Hilfe. |
11.09.2014, 11:05 | #2 (permalink) |
Registriert seit: 10.10.2006
Beiträge: 263
|
Code:
Stao_AL1 setPos [(getPos vehicle AL1 select 0) -70, (getPos vehicle AL1 select 1) +0, (getPos vehicle AL1 select 2) +0] Code:
Stao_AL1 setPos [(getPos vehicle AL1 select 0) -70, (getPos vehicle AL1 select 1),0] Wenn du getposatl verwendest musst du bei setpos dann auch setposatl verwenden (ausser du willst denn Effekt der falschen Höhe erzielen) In einen Falle ist aber der Getpos befehl mit Setpos voll und ganz ausreichend Was nun auch noch ist du Ziehst im Grunde denn spawn nicht hinter dir her Sondern Schiebst ihn 70m weiter auf der x achse was auch je nach bewegung Vor, neben oder hinter dir sein kann Geändert von Nokman (11.09.2014 um 11:10 Uhr). |
11.09.2014, 16:56 | #3 (permalink) |
Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 297
|
Danke für die Antwort Nokman.
Der 'Schleppspawn' sollte theoretisch immer rückwärts auf der Strecke liegen, die der Spieler zurückgelegt hat. Da ich aber nicht weiss, wie man eine solche 'Spur' speichern könnte, begnüge ich mich zurzeit damit den Respawnpunkt auf der X-Achse abzulegen. Solange der Spieler sich nicht seitwärts oder rückwärts bewegt (sprich, solange er die Taste "W" benutzt), ist dieser Punkt dann schon in etwa "dort, wo der Spieler herkommt". Trotzdem: Falls jemand eine bessere Methode wüsste, bin ich dankbarer Abnehmer dafür. |
11.09.2014, 19:39 | #4 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Versuche einmal diesen Code. z.B. mit einem Auslöser starten.
Beim Übergabewert 100 wird in 50m Abständen in zwei Variable die Position des Spielers gespeichert. Unter 100 sollte der Wert nicht liegen. Respawn 50 bis 100 Meter entfernt der letzten Position: Code:
temp = 100 spawn { sleep1; if (!local player) exitwith {}; private ["_posX","_pos1","_pos2"]; _posX = [getPos player select 0,getPos player select 1]; _pos1 = _posX; _pos2 = _posX; while {true} do { waitUntil {alive player}; if (_posX distance _pos1 > _posX distance _pos2)then{_posX=_pos1}else{_posX=_pos2}; player setPos _posX; while {alive player} do { waitUntil {sleep 0.5; !alive player or _pos1 distance getPos player > _this/2}; if (alive player) then { _pos2 = [getPos player select 0,getPos player select 1] }; waitUntil {sleep 0.5; !alive player or _pos2 distance getPos player > _this/2}; if (alive player) then { _pos1 = [getPos player select 0,getPos player select 1] } }; _posX = [getPos player select 0,getPos player select 1] } }; |
11.09.2014, 21:14 | #5 (permalink) |
Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 297
|
Danke für den Code Vienna. Ich werde das sobald wie möglich ausprobieren.
Übrigens: Der Zufall wollte es, dass ich beim Testen m.o.w. immer von West nach Ost unterwegs war. Darum war mein bisheriger Schlepp-Respawn immer hinter dem Spieler. Hätte ich mich beim Testen auch mal von Ost nach West bewegt, hätte ich herausgefunden, dass der Schlepp-Respawn plötzlich vor mir liegt... Somit ist meine bisherige Methode hinfällig. Ich versuche es nun mit Vienna's Code. @ Vienna, noch eine Frage: Ich vermute bei Deinem Code reicht ein Auslöser für alle Spieler, da der Schlepprespawn hier offenbar für jeden Spieler lokal durchgeführt wird, oder? Das 'if (!local Player) exitwith...' lässt darauf schliessen. Stimmt's? |
11.09.2014, 22:27 | #6 (permalink) |
Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 297
|
Ok, Vienna's Code funktioniert... fast. Ich glaube mit einem anderen Auslöser funke ich noch ein wenig dazwischen (dazu gleich mehr).
Das Tolle an Vienna's Code ist, dass ich folgende Dinge nicht mehr brauche: - Marker respawn_west - Rasenmäher, welche als Hinbeampunkt für die Spieler verwendet wurden - Ausl. um respawn_west, welche jeden Spieler zu seinem Rasenmäher beamte Im Moment ist es aber noch so, dass mit Vienna's Code die Spieler nicht mehr in den Heli gebeamt werden, der sie ins Zielgebiet bringt. Grund dafür, dürfte wohl das hier sein: ------------------ Damit im Heli wirklich nur diejenigen Spielfiguren sitzen, die durch menschliche Spieler besetzt werden (die anderen müssen an einem bestimmten Punkt auf der Karte stehen bleiben!), benutze ich folgenden Code in der Init-Zeile jeder spielbaren Figur: Code:
temp = [this,Tarnheli1] spawn {private "_time", _time = 60; while {_time > time} do {if (player == _this select 0) then {player moveInCargo (_this select 1); if (player != vehicle player) then {_time = 0}}; sleep 1}}; this allowDamage false; this addRating 50000; null = [this] execVM "inventar\inventar_Tester1.sqf" Nun passiert folgendes: a) Wenn ich Vienna's Code mit einem Auslöser starte dessen BED auf 'true' steht, werden die Spieler nicht mehr in den Heli gebeamt (oder grad sofort wieder raus). b) Schreibe ich hingegen ins BED-Feld des Auslösers 'vehicle player != Tarnheli1' dann sind die Spieler zwar wieder im Heli, werden aber sofort nach dem rausspringen auf den Boden ge-setPos-ed. Ich muss also eine Möglichkeit finden, dass Vienna's Code erst startet, wenn keine spielbare Einheit mehr im Tarnheli ist und zugleich einen normalen Fallschirmsprung zulässt. Da ich den Schlepp-Respawn (ich taufe Dein Ding hiermit so, Vienna) auch in anderen Missionen verwenden möchte, würde ich dessen Start jedoch gerne in einem separaten Auslöser (mittels wahrmachen einer Variable?) initiieren. Wie könnte ich das Problem lösen? Geändert von Wolkenbeisser (11.09.2014 um 22:30 Uhr). |
12.09.2014, 00:55 | #7 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Es reicht ein Auslöser mit dem Code für alle Spieler.
Die fett gedruckte Zeile wurde so abgeändert, dass die Umstellung des Spielers nur durchgeführt wird, wenn er nicht in einem fahrbaren Objekt ist. Code:
temp = 100 spawn { sleep1; if (!local player) exitwith {}; private ["_posX","_pos1","_pos2"]; _posX = [getPos player select 0,getPos player select 1]; _pos1 = _posX; _pos2 = _posX; while {true} do { waitUntil {alive player}; if (_posX distance _pos1 > _posX distance _pos2)then{_posX=_pos1}else{_posX=_pos2}; if(player == vehicle player) then {player setPos _posX}; while {alive player} do { waitUntil {sleep 0.5; !alive player or _pos1 distance getPos player > _this/2}; if (alive player) then { _pos2 = [getPos player select 0,getPos player select 1] }; waitUntil {sleep 0.5; !alive player or _pos2 distance getPos player > _this/2}; if (alive player) then { _pos1 = [getPos player select 0,getPos player select 1] } }; _posX = [getPos player select 0,getPos player select 1] } }; |
12.09.2014, 11:22 | #8 (permalink) |
Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 297
|
Hmm, ich wollte eigentlich schon, dass der Respawnpunkt auch dann mitgezogen wird, wenn der Spieler in einem Fahr-/Flugzeug sitzt. Gleichzeitig sollten HALO-Sprünge aber trotzdem möglich bleiben.... wobei... das bringt mich auf eine neue Idee: Könnte man es evtl. auch so einrichten, dass der Spieler...
- So respawnt, wie in Vienna's letztem Post, wenn er zu Fuss unterwegs ist - Sobald er in einem Vehicel sitzt/stirbt, aber mit 'moveInCargo' in das Vehicel zurückgesetzt wird (sofern es noch, bzw. wieder lebt, sonst zum letzten 'zuFussRespawnpunkt'). Falls das nicht geht, werde ich den Schlepprespawn so einrichten, dass er erst zündet, wenn der Spieler im Auslöserbereich ist (player in thislist). So kann ich den Auslöser nachträglich (nach dem HALO-Sprung) ins 'Spielgebiet' schieben, wodurch der Spieler erst dann in den Auslöserbereich gerät. Bis dies soweit ist verwende ich den normalen Todespunkt-Respawn. Was haltet ihr davon? |
12.09.2014, 13:47 | #9 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Daran hat sich doch nichts geändert! Die beiden Respawn-Positionen werden unabhängig davon gespeichert, ob der Spieler "Vehicle" ist oder nicht. Was geschieht im Code, wenn der Spieler gestorben ist? Code:
... 1. waitUntil {alive player}; 2. if (_posX distance _pos1 > _posX distance_pos2)then{_posX=_pos1}else{_posX=_pos2}; 3. if(player == vehicle player) then {player setPos _posX}; ... 2. Hier wird die weitest entfernte der beiden Respawn-Positionen zur Todes-Position gewählt (beim Start des Codes sind es die momentane Position des Spielers). Die Respawn-Position steht dann in Variabler _posX. 3. Diese Zeile stellt sicher, dass die Versetzung nur dann erfolgt, wenn der Spieler nicht in einem Fahrzeug ist. So wird z.B. verhindert, dass der Spieler beim Spielstart aus dem Heli entfernt wird! |
12.09.2014, 15:36 | #10 (permalink) |
Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 297
|
Ahaaaa, ich glaube, jetzt hab' ich's verstanden. Kontrolle, ob ich's begriffen habe - Vienna will mir sagen:
Wenn der Spieler im Fahrzeug getötet wird (z.B. Kopfschuss durch die Windschutzscheibe) dann befindet er sich in dem Moment wo er wieder 'alive' wird trotzdem nicht in einem Vehicel. Somit findet die Versetzung zum Schleppspawnpunkt wie geplant statt. Er wird einfach nicht versetzt, während er in einem Vehicel sitzt. Alles klar, werde das ausprobieren, sobald ich dazu komme. Vielen Dank schon mal für die Ergänzung, Vienna. Geändert von Wolkenbeisser (12.09.2014 um 15:55 Uhr). |
13.09.2014, 18:28 | #12 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
So tadellos wird das auf Dauer nicht klappen. z.B. wenn die beide Respawn-Positionen über Wasser liegen oder du an beiden Positionen immer gleich getötet wirst.
Hier eine bessere Lösung mit einem Skript, wo ich versucht habe dem vorzubeugen. Anweisung für die Anwendung im Skript-Kopf. schleppRespawn.sqf Skript nur einmal aufrufen! Code:
// 10 Respawn-Positionen im Bewegungsbereich des Spielers [Vienna 13.08.2014] // // Es ist zu beachten, dass sich der Spieler beim Skriptstart nicht über Wasser befindet! // // Aufruf: [<a>,<b>,<c>] execVM "schleppRespawn.sqf" // <a> in Meter der Abstand bis zum Setzen der nächsten Position. // <b> in Meter der maximale Abstand beim Respawn. // <c> in Sekunden die Zeit, innerhalb der bei zwei Respawns eine // Rückstellung an die Skriptstart-Position erfolgt. // // Beispiel für Auslöser: temp = [50,400,60] execVM "schleppRespawn.sqf"; // // SKRIPT NUR EINMAL AUFRUFEN! //Lokal nur für Spieler. sleep 1; if (!local player) exitwith {}; private ["_anzahl","_abstand","_maxAbst","_zeit","_minZeit","_i","_j","_index","_posX","_startPos","_positionen","_distanzen","_temp","_wahl"]; //Parameter _abstand = _this select 0; //Abstand der Positionen _maxAbst = _this select 1; //maximaler Abstand beim Respawn _minZeit = _this select 2; //Zeitbereich innerhalb der bei 2 Toden die Rückstellung zur _startPos erfolgt //Anzahl der Positionsspeicherungen _anzahl = 10; //Schleifenzähler für die Positionen _j = 0; //Positionen initialisieren _startPos = [getPos player select 0,getPos player select 1]; //Position beim Skriptstart _posX = _startPos; _positionen = []; for "_i" from 0 to _anzahl -1 do {_positionen =_positionen + [_startPos]}; //Endlosschleife =============================================================== while {true} do { //warten auf lebenden Spieler waitUntil {alive player}; _zeit = Time; //Referenzzeit //wenn Spieler nicht in Fahr-/Flugobjet, dann zur Respawn-Position versetzen. if (player == vehicle player) then {player setPos _posX}; //falls Position im Wasser, dann zur _startPos if (surfaceIsWater position player) then {player setPos _startPos}; //Schleife solange Spieler lebt ---------------------------------------------- while {alive player} do { //Respawn-Positionen in Array _positionen speichern if (_j==0) then {_index = _anzahl-1} else {_index = _j-1}; //vorherige Position zum Vergleich _temp = _positionen select _index; //Vergleichsposition rückstellen wenn Abstand über _maxAbst if (_temp distance getPos player > _maxAbst) then { _temp = [getPos player select 0,getPos player select 1]; _positionen set [_index,_temp] }; //warten bis Spieler tot oder Bedingung für neue Position-Speicherung erfüllt waitUntil {sleep 0.5; !alive player or _temp distance getPos player > _abstand}; if (alive player) then { _positionen set [_j,[getPos player select 0,getPos player select 1]]; _j = _j + 1; if (_j == _anzahl) then {_j = 0} } };//Schleifenende nach Spielertod ------------------------------------------- //Todesposition speichern _posX = [getPos player select 0,getPos player select 1]; //Respawn-Position festlegen _distanzen = []; //Distanzen der Positionen zur Todesposition speichern {_distanzen = _distanzen + [_posX distance _x]}forEach _positionen; //zufällige Wahl aus den Distanzen for "_i" from 1 to _anzahl*5 do { _wahl = (_distanzen select (floor(random _anzahl))); if (_wahl < _maxAbst and _wahl > _abstand) exitwith {} //wenn innerhalb des Bereichs, dann fertig. }; //Respawn-Position aus _positionen entnehmen und in _posX speichern {if (_posX distance _x == _wahl) exitwith {_posX = _x}} forEach _positionen; //zwei Tode im Zeitbereich? if (time < _zeit + _minZeit) then {_posX = _startPos}//wenn ja, dann zur _startPos } //Skriptende =================================================================== |
13.09.2014, 19:13 | #13 (permalink) |
Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 297
|
Nach dem neuen Script respawne ich etwa bei jedem 4 - 5 Versuch wieder an der Startposition. Wenn ich mit dem Auto aber vorher 2 Km gefahren bin, habe ich ein Problem. Bis ich meine Kameraden zu Fuss eingeholt habe, ist die Mission zu Ende.
Mit dem Auto bin ich übrigens einfach querfeldein. Auf der ganzen Strecke gab es nur Steine, Bäume Gras und diese kleinen Steinmäuerchen, die es überall gibt. Keine anderen Einheiten, kein Wasser, keine Häuser. Keine Ahnung, warum ich so oft wieder am Start stehe. Leider bin ich zu wenig gut im Scripten, als dass ich wüsste, an welchem Zahnrad man hier drehen müsste... Ich teste mal noch ein wenig weiter (habe aber heute leider nicht mehr so viel Zeit)... --- Nachtrag: Ich glaube, ich weiss jetzt, wieso ich immer wieder am Start stand. Ich habe natürlich nicht immer die 60 Sekunden abgewartet. Muss das bei Gelegenheit mal testen mit 5 Sekunden oder so.... Geändert von Wolkenbeisser (13.09.2014 um 20:38 Uhr). |
14.09.2014, 01:37 | #14 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Zum Testen mit einem Fahrzeug sind die 60 Sekunden natürlich zu lange.
Die Zeit beginnt nach der Respawn-Zeit zu laufen und ist nur für einen "Notausstieg" zur Startposition gedacht. Wenn man das weiß, dann reicht generell eine 10 Sekunden Einstellung dafür. Diese Rückstellung zum Start erfolgt auch wenn ein Respawn im Wasser erfolgen würde. |
14.09.2014, 17:21 | #15 (permalink) |
Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 297
|
A und C sind mir klar. A legt eine neue Position an, wenn die Distanz zur letzten Position grösser 50m ist. C setzt mich zurück an die startposition, wenn ich innerhalb der Zeit C 2x respawne. Aber wie genau ist B zu verstehen"?
--- Nachtrag: B dürfte die maximale Distanz zwischen Respawnpunkt und Todespunkt sein. Wie auch immer: Auch dieses Script klappt wunderbar. Merci, Vienna. Geändert von Wolkenbeisser (15.09.2014 um 00:16 Uhr). |
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1) | |
Themen-Optionen | |
Ansicht | |
|
|
Ähnliche Themen | ||||
Thema | Autor | Forum | Antworten | Letzter Beitrag |
Objekt nur sichtbar wenn Spieler existiert | killshot | Editing & Scripting | 5 | 22.08.2014 21:30 |
SetOwner Problematik | manatarms | Editing & Scripting | 11 | 05.05.2014 17:11 |
Objekt mit cursorTarget bewegen | Nokman | Editing & Scripting | 0 | 08.03.2014 11:19 |
Camps an zufälliger Position | Rubbermen | Editing & Scripting | 3 | 04.10.2012 18:13 |
Spieler (Zivilist) wird manchmal (!?) aus Auto gekickt | Wolkenbeisser | Editing & Scripting | 8 | 06.09.2011 08:19 |