Armed-Assault.de Twitter
Antwort
 
Themen-Optionen Ansicht
Alt 26.12.2011, 21:26   #1 (permalink)
50 Beiträge100 Beiträge250 Beiträge
 
Benutzerbild von Wolkenbeisser
 
Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 294
Standard Random Markerwahl mit abnehmender Markerzahl

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)))));}
Dabei habe ich jedoch ein Problem:

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.
Wolkenbeisser ist offline   Mit Zitat antworten
Alt 26.12.2011, 21:44   #2 (permalink)
Newbie
 
Registriert seit: 08.01.2011
Beiträge: 41
Standard

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"];
In ZufallsAufgabe.sqf
Code:
_taskMarker = taskMarkers call BIS_fnc_selectRandom;
taskMarkers = taskMarkers - [ _taskMarker ];
Dadurch werden die Aufgaben (Tasks) in einem globalen Array 'taskMarkers' gehalten. Nachdem eine Aufgabe ausgewaehlt wurde, wird sie aus dem globalen Array geloescht.

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;
Das findet alle 'HeliHEmpty' 10000 Meter um den Spieler herum, muss ggf auf Kartengroesse angepasst werden. Die 'HeliHEmpty' kannst du dann nach belieben loeschen oder auch verschieben, zum Beispiel fuer Folgemissionen.
TeTeT ist offline   Mit Zitat antworten
Alt 27.12.2011, 08:12   #3 (permalink)
50 Beiträge100 Beiträge250 Beiträge
 
Benutzerbild von Wolkenbeisser
 
Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 294
Standard

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.
Wolkenbeisser ist offline   Mit Zitat antworten
Alt 27.12.2011, 10:06   #4 (permalink)
Newbie
 
Registriert seit: 08.01.2011
Beiträge: 41
Standard

Zitat von Wolkenbeisser Beitrag anzeigen

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?

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;
Wenn du ein vollbesetztes Fahrzeug brauchst, nutz einfach bis_fnc_spawnvehicle.


Zitat von Wolkenbeisser Beitrag anzeigen

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.

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.
TeTeT ist offline   Mit Zitat antworten
Alt 27.12.2011, 10:12   #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

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;
Vienna ist offline   Mit Zitat antworten
Alt 27.12.2011, 11:03   #6 (permalink)
Newbie
 
Registriert seit: 08.01.2011
Beiträge: 41
Standard

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.
TeTeT ist offline   Mit Zitat antworten
Alt 27.12.2011, 12:48   #7 (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

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.
Vienna ist offline   Mit Zitat antworten
Alt 27.12.2011, 13:59   #8 (permalink)
50 Beiträge100 Beiträge250 Beiträge
 
Benutzerbild von Wolkenbeisser
 
Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 294
Standard

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;
...das "if (isServer) then {....} verwenden? Oder geht das gleich so wie von Dir gepostet?

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?
Wolkenbeisser ist offline   Mit Zitat antworten
Alt 27.12.2011, 15:58   #9 (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

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 16:04 Uhr).
Vienna ist offline   Mit Zitat antworten
Alt 27.12.2011, 16:19   #10 (permalink)
Newbie
 
Registriert seit: 08.01.2011
Beiträge: 41
Standard

Zitat von Vienna Beitrag anzeigen

...

if (isNil "Markers") then {Markers = [...]};

Diese Abfrage ist ja nur beim ersten Skript-Aufruf positiv.

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.
TeTeT ist offline   Mit Zitat antworten
Alt 27.12.2011, 16:56   #11 (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

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.
Vienna ist offline   Mit Zitat antworten
Alt 30.12.2011, 09:51   #12 (permalink)
50 Beiträge100 Beiträge250 Beiträge
 
Benutzerbild von Wolkenbeisser
 
Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 294
Standard

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;
}
Das funktioniert im Editor schon mal sehr zuverlässig. Ich konnte es aber noch nicht in einem echten MP-Spiel testen.

Sollte das wider erwarten im MP nicht gehen, würde ich mich hier wahrscheinlich nochmals melden... .

Grüsse aus der Schweiz
Wolkenbeisser
Wolkenbeisser ist offline   Mit Zitat antworten
Alt 13.01.2012, 13:16   #13 (permalink)
50 Beiträge100 Beiträge250 Beiträge
 
Benutzerbild von Wolkenbeisser
 
Registriert seit: 05.11.2010
Ort: Schweiz
Beiträge: 294
Standard

Wollte nur noch kurz rapportieren:

Obiger Code funzt auch im MP tadellos

Grüsse aus der Schweiz
Wolkenbeisser
Wolkenbeisser 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
Arti eine gewisse Zeitlang in ein Gebiet schießen lassen Bruklin Editing & Scripting 10 25.08.2010 16:44


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