Banner left   Banner center   Banner right

Germanenglish Home · News · Diary · Screenshots · Documentation (Wiki) · Downloads · Guestbook · Forum

Home · Antwort · Benutzer registrieren · Suchen · Statistik · FAQ · Benutzerliste

Zur Zeit online: keiner ausser dir

 X-Force - Fight For Destiny - Forum —› Spieler helfen Spielern —› Hilfe zu Problemen

Autor Mitteilung
verfasst am: 22.01.2013, 18:50
Registrierdatum: 31.01.2010, 20:05

 Beiträge: 122
Ich habe beim Testen meines Spiels einige Probleme festgestellt, die wahrscheinlich behoben werden können.
1. Wird der Schalter "NoSaveGameMessage_lmUFOs" vom Spiel automatisch registriert? Im Spiel wirft er nämlich die Fehlermeldung "...nicht registriert" raus.Wenn ich ihn registriere, erfüllt er dann noch seine Funktion?
2. Ich starte mehrere Ufos zeitlich vesetzt. Nun kommt es öfters vor, dass ein Ufo regungslos verharrt und nicht mehr reagiert - die anderen tun es. Hat der zuständige CommandComplete-Event es verloren? Wie wäre das zu verhindern? Wenn ich es mit ".. MissionwithObject" starten würde, müsste ich auf vorher festgelegte Daten zugreifen - ist das möglich? Ich kann wegen des Umfangs der Daten diese nicht global zur Verfügung stellen, zu mal ich sie in einem Array speichere.
Es haben sich noch einige andere Probleme gezeigt, aber die dürften gelöst sein, wenn die beiden oben genannten Probleme gelöst sind.
Ich hoffe, dass meine Probleme ausreichend dargestellt sind, wenn nicht, dann fragt bitte nach.
verfasst am: 22.01.2013, 20:23
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
zu 1: das müsste normalerweise eine der vordefinierten Variablen unter Schwierigkeitsgrad sein, aber das weis ich jetzt nicht ausqendig. Eine eigenständige Registrierung dürfte keinen Effekt haben, da der Schalter für Funktionen steht auf die es im X-Skript keinen direkten Zugriff gibt.
Alternativ mal im Wiki in der Referenz suchen.

zu 2: Das ist das Problem, das mir meine späteren Eariol-Skripte (das Drone-Skript und seine Varianten im letzten Galwar) durcheinander gebracht hatte. Da habe ich nie eine Lösung gefunden, bevor ich die arbeiten abbrechen musste.
Wenn ich mich richtig erinnere, dann lag das Problem relativ tief. Die Skripte liefen weiter, aber das UFO-Objekt reagierte nicht mehr auf Bewegungs-Kommandos.
Ich wollte damals noch eine etwas andere Art der Verwaltung unter X-Skript ausprobieren, leider gab es dann bei mir gesundheitliche Probleme, die auch heute noch nicht ganz beseitigt sind.

Du kannst übrigens MissionwithObject benutzen und variable Daten übermitteln, bevor Du das neue UFO erzeugst. So hatte ich das teilweise im Galwar gemacht (dort sind Beispiele wie Funktionen zum Datentausch zwischen Skripten aussehen müssen), aber der beschriebene Fehler trat trotzdem irgendwann auf.

Ich hatte ihn aber immer nur mit dem Drone-Skript, nie mit den UFOs anderer Rassen (diese nutzten auch die Datenübertragung zwischen Skripten, aber sie waren halt einzelne UFOs während ein einzelnes Drone-Skript für die Eariol gleich dutzende UFOs erzeugte. Da kann das durchaus statistisch begründet sein dass ich das immer nur mit den Eariol hatte...
verfasst am: 22.01.2013, 20:30
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
Der Schlüssel zur Datenübrgabe ist CallProcedure auf dem Skriptobjekt, das zu dem neu gestarteten (oder irgendeeinem anderen bekannten Skript) gehört.

http://doc.xforce-online.de/ger_pages/XSkriptReferenz/TypTMission.html

Das TMission kriegst Du auf verschiedene Arten, entweder beim indirekten Start des Skriptes speichern oder alle laufenden Skripte namentlich vergleichen oder ein Basis-Verwaltungsskript ausführen, bei dem sich alle späteren Skripte zum abholen ihrer Daten anmelden.

Im letzten Galwar stehen verschiedene Beispiele, da ich dies zur Vereinfachung der Variablenverwaltung genutzt habe.
verfasst am: 24.01.2013, 08:10 · Edited by: AlterKnacker
Registrierdatum: 31.01.2010, 20:05

 Beiträge: 122
Müsste es nicht auch mit "TDataHolder" gehen? Im startenden Programm die notwendigen Werte im TDataHolder-Objekt("TDH") registrieren (TDH.RegisterInteger(Name)), Daten darin speichern(TDH.SetInteger(Name,Value) und in der gestarteten Mission mit (TDH.GetInteger(Name)) darauf zugreifen? Das startende Programm läuft ja weiter, während die Ufos mit "mission_api_StartScriptWithObject('Ufomission',Ufo)" nacheinander gestartet werden und sich dann die Daten holen.
verfasst am: 24.01.2013, 09:02
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
Zitat: AlterKnacker
Müsste es nicht auch mit "TDataHolder" gehen?

Ja, aber zum einen musst Du das TDH-Objekt korrekt speichern und übertragen und zum anderen lohnt sich so ein relativ aufwendiges Konstrukt nicht, wenn es nur um einfache Werte oder Signale geht. Ist zum guten Teil Geschmackssache,welchen Weg man nutzt.
verfasst am: 28.01.2013, 15:30 · Edited by: AlterKnacker
Registrierdatum: 31.01.2010, 20:05

 Beiträge: 122
Fragen zu TDataHolder und CallProcedure
Ich habe versucht in Galwar die Anwendung dieser beiden Funktionen zur Datenweitergabe zu ergründen. aber ich verstehe es nicht.
Ich war der Meinung, das "TDataHolder" die Werte bereitstellt, die dann von einem später gestartetem Programm abgerufen werden können.
Dazu eine Erklärung mit Text:
Progam DatenSpeicher;
var
 XData: TDataHolder;
procedure startmission;
{ 
  initialisiert XData und speichert die Werte
)
begin
  Xdata:=TDataHolder.create;
  Xdata.RegisterInteger('Zahl');
  Xdata.RegisterString('String');
  Xdata.setInteger('Zahl',123);
  Xdata.setString('String','321');
  mission_api_StartScript('BraucheDaten')
 end;
 
 Program BraucheDaten;
 {
 jetzt werden die Daten abgerufen
 }
 Procedure Startmission;
 var
   Zahlx: integer;
   Stringx: string;
 begin
   Zahlx := Xdata.GetInteger('Zahl');
   Stringx := Xdata.GetString('String');
   Weiterverarbeitung(Zahlx,Stringx);
 end;


Mein Sohn sagte immer wenn etwas nicht funktionierte: "Papa, es wullt nit!"

Mit "CallProcedure" sieht es noch trüber aus. Mir ist die Syntax klar, aber welche Werte und wie bekomme ich sie zurück? Ein "googeln" im Galwar hilft mir nicht weiter, da die Namen nicht eindeutig sind, sondern berechnet werden.
verfasst am: 28.01.2013, 16:43
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
Zu TDataholder:
Eine Definition von eines Objektes wie Xdata in Deinem Beispiel ist erstmal nur lokal. Damit das in einem anderen Skript abgerufen werden kann, muss dieses andere Skript einen Pointer auf dieses Objekt erhalten.

Die primäre Funktion von TDataholder ist die Organisation von Datengruppen innerhalb eines Skriptes, zur Übertragung an ein anderes Skript muss man das Objekt dorthin übergeben.
Es erspart also die Erstellung von dutzenden globaler Variablen, aber ist kein automatischer Datentransfer.
verfasst am: 28.01.2013, 17:27 · Edited by: DirkF
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
zu Callprocedure:
Die Skriptnamen werden zwar "berechnet", aber nicht besonders aufwendig.

Es gibt eine Reihe von RCS-Skripten, deren Namen immer zusammengesetzt sind aud dem Präfix RCS_ und einem Buchstaben für die Rasse. Ähnliches gilt für die GCS-Scripte etc.
Der Grund dafür ist die Zufallsauswahl, welche Rassen aktiviert werden - für die Analyse kannst Du also davon ausgehen, das nur eine Rasse aktiv ist (z.B. X für Xeltaan oder N für Nekrilu) und dass jede Referenz zu RCS_+racecode dabb auf das passende Skript RCS_N verweist.

Wenn Du Dir das Skript RCS_N anschaust, dann wirst Du sehen das es zwar Funktionen zur UFO-Erzeugung enthält, aber selber beim Start nur einige Variablen definiert und dann gar nichts mehr macht.

Der Aufruf zur Erzeugung des UFOs wird im Skript CON002action mittels callprocedure erzeugt. Genau genommen in Zeile 64-68, wo zuerst mit dem Namen der zufällig ausgewählten Rasse das Mission-Objekt des dazugehörigen Rassenskriptes bestimmt wird und dann die Funktion "createaction" innerhalb dieses Skriptes gestartet wird, um das UFO (oder was auch immer der Gegner sein sollte, z.B. Bodeneinsatz ohne UFO) in dem Skript zu erzeugen.

Auf diese Art konnte ich den Rassen unterschiedliches verhalten geben, ohne die internen Zufallsmechanismen des Spiels zu nutzen.

Dieses Beispiel ist allerdings ohne Parameterübergabe.
Wenn man mit CallProcedure Daten übergeben will, dann muss die aufgerufene Funktion derartige Daten erwarten. Und die Callprocedure-Funktion muss darauf abgestimmt sein.

Dies habe ich effektiv in ACC91drone gemacht - das dieses Skript dann nicht funktionierte, hatte andere Gründe.
Hierbei ist zu bedenken, dass dieses Skript einmal pro UFO ausgeführt werden sollte und das ein "Basis-UFO" verschiedene untergeordnete UFOs kontrollieren sollte. Deswegen gab es keine Möglichkeit, über die Skriptnamen zu steuern - stattdessen musste sich das Basis-Skript die Mission-Objekte der untergeordneten UFOs bei der Erzeugung ermitteln und merken, und dann diesem vom Code identischen aber auf einem andern UFO liegenden Skript die notwendigen Steuerdaten geben.

Eine der Funktionen die das macht ist z.B. ACCsetdefended in Zeile 261. Diese Funktion wird immer extern aufgerufen (von einem anderen UFO mit demselben Skript oder einem übergeordneten Steuerskript), niemals aus dem eigenen Skriptobjekt.
Der Aufruf geschieht in diesem Fall durch die Funktion Dronecontrol im Skript RCS_E (Zeile 311 folgend), allerdings ist dies in den letzten Versionen des Galwar wieder deaktiviert worden, weil das Drone-Skript nicht verlässlich funktionierte. Die Syntax ist aber trotzdem ablesbar.
Ich hoffe diese Beispiele helfen bei dem Verständnis der CallProcedure
verfasst am: 28.01.2013, 17:39
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
Nochmal zur Klarstellung: ACC91drone ist eine Baustelle mit zusätzlichem Fehlersuch-Code und Rückmeldungen sowie abwechselnd auskommentierten Varianten. Versuche dort keine Funktionen im Detail nachzuvollziehen, das klappt nicht.

Nehme nur die genannten Teilstellen um die Funktionsdefinitionen zur Parameterübergabe zu vergleichen.
verfasst am: 07.02.2013, 10:53
Registrierdatum: 31.01.2010, 20:05

 Beiträge: 122
Die Datenübergabe mit TDataHolder funktioniert. Ich habe es aber auch mit globalen Variablen (game_api_GetInteger()) versucht - auch das funktioniert. Welchen Vorteil bietet daher TDataHolder?
Mit CallProcedure habe ich nichts unternommen, denn so wie ich es verstehe, kann ich damit andere Funktionen aufrufen, die mir dann meine übergebenen Daten bearbeiten und 1 Ergebnis liefern - ich möchte aber mehrere haben. Bietet diese Funktion vielleicht aber die Möglichkeit Units abzuschaffen? Ich packe alle Units in einer Datei zusammen, definiere alle notwendigen Variablen im Hauptprogramm und hole mir per Callprocedure die gewünschte Funktion? Das ärgerliche an den Units ist, dass ich manchmal eine Unit in einer Unit aufrufen muss, um eine Variable überall bekannt zu machen.
verfasst am: 07.02.2013, 14:43
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
Zitat: AlterKnacker
Mit CallProcedure habe ich nichts unternommen, denn so wie ich es verstehe, kann ich damit andere Funktionen aufrufen, die mir dann meine übergebenen Daten bearbeiten und 1 Ergebnis liefern - ich möchte aber mehrere haben.

Du hast die Funktionsweise von Callprocedure nur unvollständig verstanden.

CallProcedure ermöglicht zwei Haupteffekte:
1) Daten weitergeben an ein anderes Skript
2) gesteuerter Aufruf des anderen Skriptes.

Ob es einen Rückgabewert in der Prozedur gibt, weiß ich jetzt noch nicht einmal - das habe ich nie ausprobiert, weil es schlichtweg unnötig ist.

Wenn man eine Prozedur in einem anderen Skript aufruft, dann kann die prinzipiell alles machen - nicht nur eventuell erhaltene Daten speichern, sondern auch jeden beliebigen Befehl ausführen.

Im Galwar habe ich dies genutzt, um z.B.
1) ein und dasselbe UFO mit Daten und Aufrufen aus unterschiedlichen Skripten zu belegen. Skript 1 hat dann das UFO mit verschiedenen Flug-KI-Kommandos versehen und am Ende das UFO weitergegben an ein Skript 2, das für dasselbe UFO die Reaktionen auf Abschuss etc. programmierte und den Bodeneinsatz einstellte.
Auf diese Art wurde die KI und die Steuerreaktionen auf zwei Skripte verteilt, anstatt aus dem zweiten Skript eine Unit des ersten zu machen - hatte einige Vorteile.

2) Datenabfragen durch Funktionspaare zu erzeugen. Die Funktion in Skript 1 hat Daten an das Skript 2 übergeben. Bei diesen Daten waren zusätzlich zu den zu übertragenden Daten das TMission und ein Funktionsname aus Skript 1.
Skript 2 hat dann innerhalb der Empfangsfunktion für diese Daten einen externen Funktionsaufruf zurück an Skript 1 gemacht, in dem die gewünschten Ergebnisdaten zurück übertragen wurden.
Man muss dazu nur an der Stelle, an der man die Rückgabe erwartet, das Ursprungsskript aufteilen in zwei Funktonen - die erste endet mit dem CallProcedure und die zweite wird dann von der Rückgabefunktion gestartet.

3) Zentrale Datensteuerung: Es gibt verschiedene Skripte, die nichts anderes tun als einen bestimmten Datenblock und die damit zusammenhängenden Funktionen zu verwalten. Andere Skripte melden dann Ereignisse an diese zentralen Steuerskripte oder werden von denen aufgerufen - jeweils mit der benötigten Datenübergabe.

Die Verwendung von CallProcedure erlaubt also eine wesentlich einfachere und effektivere Strukturierung als es mit Units der Fall wäre - units sollten imho nur für allgemeine Definitionen und allgemeine Funktionen genutzt werden, die man überall mal braucht.
Z.B. damit in allen mit Callprocedure gesteuerten Skripten dieselben Datendefinitionen vorliegen, denn im Gegensatz zu einer unit übernimmt ein externes Skript nicht automatisch die Definitionen des übergeordneten Hauptprogrammes.
verfasst am: 07.02.2013, 14:53
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
Zitat: AlterKnacker
Das ärgerliche an den Units ist, dass ich manchmal eine Unit in einer Unit aufrufen muss, um eine Variable überall bekannt zu machen.

Das ist normalerweise unnötig, wenn man die Reihenfolge der unit-Einbindung beachtet und bei Schleifen mit forward im Hauptprogramm arbeitet.
d.h. wenn ein Hauptprogramm zwei Units einbindet, dann kann unit 2 auch schon auf die Definitionen in unit 1 zurückgreifen. Falls eine Funktion aus unit 2 in unit 1 benutzt werden muss, dann kann man diese Funktion auch mit forward reservieren - es reicht dann wenn sie später eingebunden wird. Musste ich auch ein paar mal machen...
verfasst am: 07.02.2013, 14:55
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
Zitat: AlterKnacker
Welchen Vorteil bietet daher TDataHolder?

Datenorganisation - wenn Du einige dutzend Werte speichern willst, dann brauchst Du bei den globalen Variablen auch einige dutzend Namen - und irgendwann wird das umständlich...



:: Benutzer
» Name » Passwort
:: Deine Antwort
User: Passwd:
Bold Style  Italic Style  Underlined Style  bug linking  Preformatted  Code  Image Link  Insert URL  Email Link  Abschalten * Hilfe
Hilfe
 

Ladezeit (sec.): 0.026 · Powered by miniBB 1.6 with parts of 1.7 © 2001-2003