![]() |
#1 (permalink) |
![]() ![]() ![]() Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 297
|
![]()
Hallo zusammen
Ich hoffe, der Titel ist nicht zu unklar. Ich kämpfe zurzeit mit einem "random"-problem. Vielleicht weiss jemand von euch Abhilfe. Ich versuche folgendes zu erreichen: 1. Es gibt zu Beginn 10 Marker im Spiel mit den Namen "M1" bis "M10" 2. Ein Trigger startet das Script "Zufallsaufgabe.sqf", welches ein leeres Fahrzeug mit dem Namen "Springer" per Zufallsgenerator zu einem der 10 Marker setzt. 3. Sobald der Springer bei diesem Marker steht, wird der Marker gelöscht. 4. Irgendwann später wird der Trigger erneut gezündet und damit das Script neu gestartet. Nun soll der Springer zu einem der verbleibenden 9 Marker gebeamt werden. Auch dieser Marker wird nun gelöscht. 5. Das Szenario soll sich fortsetzen können, bis der Springer beim letzen verbleibenden Marker angekommen ist. Danach sollte das Script nicht mehr ausgeführt werden. Meine bisherige Zufallsaufgabe.sqf sieht so aus: Code:
if (isServer) then {_markers = ["M1", "M2", "M3", "m4", "M5", "M6", "M7", "m8", "M9", "M10"]; Springer setpos (getMarkerPos (_markers select (floor(random(count _markers)))));} Obwohl die Marker gelöscht werden, versucht das Script den Springer (wenn's der Zufallsgenerator will) an gelöschte Marker zu beamen. Dann landet der Springer im Nirwana, bis das Script erneut abläuft und hoffentlich einen Marker trifft, der noch nich "erledigt" wurde. Das ist nicht gewünscht. Es sollen nur noch die verbleibenden Marker verwendet werden. P.S: Ausserdem bin ich mir nicht ganz sicher, ob ich das mit der Lokalität für ein gehostetes Coop-MP-Game so richtig gelöst habe. Weiss jemand Hilfe? Wäre für jeden Tip dankbar. |
![]() |
![]() |
#2 (permalink) |
![]() Registriert seit: 08.01.2011
Beiträge: 41
|
![]()
Du definierst _markers jedes Mal bei Aufruf von ZufallsAufgabe.sqf neu. Ich würde folgendes vorschlagen:
In Init.sqf Code:
taskMarkers = ["M1", "M2", "M3", "m4", "M5", "M6", "M7", "m8", "M9", "M10"]; Code:
_taskMarker = taskMarkers call BIS_fnc_selectRandom; taskMarkers = taskMarkers - [ _taskMarker ]; Eine alternative Methode wäre z.B. das Setzen von unsichtbaren Helipads (HeliHEmpty) und der dynamischen Abfrage welche noch vorhanden sind: Code:
_objects = nearestObjects [player, ["HeliHEmpty", "HeliH"], 10000]; _taskLocation = _objects call BIS_fnc_selectRandom; |
![]() |
![]() |
#3 (permalink) |
![]() ![]() ![]() Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 297
|
![]()
Hi TeTeT
Vielen Dank für die Hilfe. Leider habe ich bis jetzt nicht kapiert, wie mir Deine Lösung hilft. Wie bewegt sich denn der Springer in Deinem Beispiel? Vielleicht verstehen wir uns falsch? Ich möchte nicht, dass die Spieler irgendwelche Aufgaben auswählen. Ich möchte, dass zu zehn verschiedenen Zeitpunkten in meiner Mission (per Auslöser) eines von zehn möglichen Ereignissen eintritt. Dies in zufälliger Reihenfolge und nie eines zwei Mal. Ein Beispiel: Die Spieler fahren in Dorf XYZ, wo sie gemäss Briefing ein Ziel zerstören müssen. Sobald das Ziel zerstört ist, muss eines der zehn möglichen Ereignisse eintreffen (für die Spieler geschieht das überraschend und ohne Warnung). Danach müssen die Spieler weiter ziehen und z.B. ein Fahrzeug von A nach B bringen. Sobald das Fahrzeug am Punkt B angekommen ist, muss das nächste Ereignis stattfinden (wieder per Auslöser ausgelöst) und zwar eines der neun verbleibenden. Danach geht die Mission weiter. Und so soll sich das hinziehen, bis alle zehn möglichen Ereignisse stattgefunden haben. Meine Idee (weil ich es nicht besser weiss), war es, am Kartenrand das Objekt "Springer" zufällig zu einem von zehn Markern springen zu lassen. Um jeden Marker habe ich dann einen Auslöser. Sobald dieser Auslöser das vorhandensein des Springers feststellt (Springer in thislist), löst er das mit ihm verknüpfte Ereignis aus. Noch besser wäre wahrscheinlich die zufällige Auswahl aus einem Set von 10 vorgegebenen Variablen. Wobei auch hier bei der nächsten Runde nur noch eine Zufällige der verbleibenden 9 ausgewählt werden sollte. P.S: Bei dem ganzen Vorhaben mus natürlich sichergestellt sein, dass nur der Server die Zufälle festlegt, so dass für alle Spieler dieselbe zufällige Variable/Marker gewählt wird. |
![]() |
![]() |
#4 (permalink) |
![]() Registriert seit: 08.01.2011
Beiträge: 41
|
![]() Du musst den Springer mit setPos an die Stelle des Markers oder Heli-Pads stellen. Code:
_pos = getPos _taskLocation; // oder: _pos = getMarkerPos _marker; _springer = "UAZ" createVehicle _pos; Ich denke, dass habe ich verstanden. Die Zufallsauswahl in deinem Skript war zwar prinzipiell in Ordnung, du musst jedoch das gezogene Ereignis auch aus dem Array löschen, damit es nicht noch mal gezogen werden kann. Deswegen habe ich vorgeschlagen, die Marker in einem globalen Array 'marker' zu verwalten und den zufällig gewählten Marker aus dem Array zu löschen. Wegen der Server Problematik weiss ich leider auch nicht weiter, ich habe noch keine MP Mission erstellt. |
![]() |
![]() |
#5 (permalink) |
![]() ![]() ![]() ![]() Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
![]()
Vielleicht ist es so leichter verständlich, wenn es aus deinem Beispiel abgeleitet wird:
Code:
//Initialisierung des Array Markers if (isNil "Markers") then {Markers = ["M1", "M2", "M3", "M4", "M5", "M6", "M7", "M8", "M9", "M10"]}; //ein Element des Arrays zufällig auswählen _m = Markers select (floor(random(count Markers))); //gewähltes Element aus dem Array entfernen Markers = Markers - [_m]; //Springer auf die Position des gewählten Elementes setzen Springer setpos getMarkerPos _m; |
![]() |
![]() |
#6 (permalink) |
![]() Registriert seit: 08.01.2011
Beiträge: 41
|
![]()
Das Problem ist, dass die marker Initialisierung und die Zufallsauswahl an getrennten Stellen erfolgen muss. Ansonsten wird beim Aufruf marker doch wieder neu initiliasiert. Daher mein Vorschlag in der Init.sqf das globale Array marker zu setzen und dann in einer eigenen Funktion Zufallsauswahl zu ändern.
|
![]() |
![]() |
#7 (permalink) |
![]() ![]() ![]() ![]() Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
![]()
In meinem Beispiel geht das aber auch im selben Skript. Finde das ist auch besser so, als die Initialisierung in einem anderen Skript. Wegen der globalen Variablen muss man nur auf einen einmaligen Variablen-Namen achten.
if (isNil "Markers") then {Markers = [...]}; Diese Abfrage ist ja nur beim ersten Skript-Aufruf positiv. |
![]() |
![]() |
#8 (permalink) |
![]() ![]() ![]() Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 297
|
![]()
Hallo Vienna und TeTeT
Wenn ich es richtig verstanden habe machen eure Lösungen in etwa dasselbe. Viennas Script ist natürlich insofern elegant, als dass es nur 1 File ist. Noch zwei Fragen an Vienna: 1. Muss ich bei diesem Code hier... Code:
//Initialisierung des Array Markers if (isNil "Markers") then {Markers = ["M1", "M2", "M3", "M4", "M5", "M6", "M7", "M8", "M9", "M10"]}; //ein Element des Arrays zufällig auswählen _m = Markers select (floor(random(count Markers))); //gewähltes Element aus dem Array entfernen Markers = Markers - [_m]; //Springer auf die Position des gewählten Elementes setzen Springer setpos getMarkerPos _m; 2. Wenn der zufällig gewählte Marker aus dem Array entfernt wird, ist der Marker selbst im Spiel immer noch vorhanden, steht aber nicht mehr zur Auswahl. Habe ich das richtig begriffen? Dann könnte ich mir das Löschen der Marker nämlich sparen (sie sind eh für den Spieler unsichtbar), richtig? |
![]() |
![]() |
#9 (permalink) |
![]() ![]() ![]() ![]() Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
![]()
Die Auswahl soll nur auf einem PC erfolgen, da der setPos Befehl publik ist. Das kann der Server oder ein anderer PC sein. Wie du das aufrufst ist dir überlassen, muss aber immer beim selben sein. Sollen es mehrere Aufrufen können, dann ist die Variable Markers mit dem Befehl publicVariable zu synchronisieren. Soll es nur der Server sein, dann am Beginn des Skripts einfügen: if(!isServer)exitWith{};
Den Marker selbst brauchst du nicht löschen. Wenn er unsichtbar ist, dann reicht es den Namen aus dem Markers Array zu entfernen. Anstelle von leeren Markern kannst du auch Logic-Objekte nehmen. Die sind im Editor immer sichtbar, Marker nur wenn du sie anwählst. Soll an der Position ein Heli landen, dann ist auch das unsichtbare Lande-H möglich. Geändert von Vienna (27.12.2011 um 17:04 Uhr). |
![]() |
![]() |
#10 (permalink) |
![]() Registriert seit: 08.01.2011
Beiträge: 41
|
![]() Ah, interessant. Hatte nicht bedacht, dass ein leeres Array natürlich nicht gleich Nil ist - wäre ja fatal einfach eine leere Datenstruktur ganz zu löschen, ohne spezielle Anweisung. |
![]() |
![]() |
#11 (permalink) |
![]() ![]() ![]() ![]() Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
![]()
Damit bei einer Variablen isNil wieder true ergibt, musst man sie mit nil "entleeren".
z.B.: Markers = nil; "Reserviert" man eine lokale Variable mit Private, dann ergibt isNil noch immer true, solange die Variable noch keinen "Wert" erhalten hat. |
![]() |
![]() |
#12 (permalink) |
![]() ![]() ![]() Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 297
|
![]()
Kurzer Zwischenbericht. Mein Code sieht im Moment so aus:
Code:
If (isServer) then { if (isNil "Markers") then {Markers = ["M1", "M2", "M3", "M4", "M5", "M6", "M7", "M8", "M9", "M10"]}; _m = Markers select (floor(random(count Markers))); Markers = Markers - [_m]; Springer setpos getMarkerPos _m; } Sollte das wider erwarten im MP nicht gehen, würde ich mich hier wahrscheinlich nochmals melden... ![]() Grüsse aus der Schweiz Wolkenbeisser |
![]() |
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1) | |
Themen-Optionen | |
Ansicht | |
|
|
![]() |
||||
Thema | Autor | Forum | Antworten | Letzter Beitrag |
Arti eine gewisse Zeitlang in ein Gebiet schießen lassen | Bruklin | Editing & Scripting | 10 | 25.08.2010 17:44 |