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 —› AiSkripte testen

Autor Mitteilung
verfasst am: 28.08.2011, 09:55
Registrierdatum: 31.01.2010, 20:05

 Beiträge: 122
Ich habe für meine Ufosteuerung verschiedene Skripte geschrieben, aber die tun an einigen Stellen nicht das, was ich vorgesehen habe. Dazu nun meine Frage: Wie kann ich ein zugeordnetes AIscript (Ufo.UfoModel.AIScript := 'Steuerungsscript') testen?

Ich komme bei der Abfrage " if (IsObject(MissionObject)) then ... " nicht weiter. Es gelingt mir nicht, ein Ufo als MissionObject zu registrieren. Erzeuge ich das Ufo im übergeordnetem Programm, dann werden wiederum die Haltepunkte im AISkript nicht berücksichtigt und an den Fehlerstellen erhalte ich dann die Fehlermeldungen, mit deren Werte ich nichts anfangen kann.

Noch eine Anmerkung: Ich möchte mehrere verschiedene Ufotypen als Gruppe starten und brauche dazu verschiedene AiSkripte, da eine Steuerung über ein externes Programm oft die Ufos verwechselte, während die AiSkripte das nicht taten, dafür die Fehlerstellen für sich behielten.
verfasst am: 28.08.2011, 10:21 · Edited by: DirkF
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
Der externe Befehl zum Start eines Skriptes mit einer Objektübergabe lautet:

mission_api_StartScriptWithObject(ScriptName: string; Object: TOBJECT): TMission;

Das an dieser Stelle übergebene Objekt wird dann im aufgerufenen Skript jeweils unter "MissionObject" gespeichert sein.

Wenn man dagegen ein AI-Skript einem UFO zuordnet, dann wird dieses Skript bei der Erzeugung des UFOs gestartet und automatisch das UFO als MissionObject zugeordnet haben.

Wo liegen also Deine Probleme bei der Zuordnung eines UFOs als MissionObjekt? Diese Zuordnung muss natürlich geschehen, bevor das jeweilige Skript gestartet wird und kann/darf nicht mehr geändert werden.

Bitte gebe mal genauer an, was gemacht werden soll - ich habe so etwas ähnliches im GalWar mit den UFOs (insbesondere den Eariol-Dronen) gebastelt, aber das war damals nicht ganz fertig und musste vorübergehend herausgenommen werden (such also gar nicht erst danach)


edit/Ergänzung:
Es gibt eine Technik zum beliebigen Datenaustausch zwischen verschiedenen Skripten über externe Befehlsaufrufe (mit den ensprechenden Daten als Argumenten), siehe:
XSkriptReferenz.TypTMission
(CallProcedure)
Dazu kann ich auch einige Beispiele liefern, und die müssten auch in der letzten Version des GalWar enthalten sein.
verfasst am: 28.08.2011, 11:53 · Edited by: Natter
Programmierer, allgemeines

Registrierdatum: 06.06.2004, 17:19

 Beiträge: 3186
Das Problem ist vermutlich, dass er sein Skript in medit testen will. Und da funktioniert das mit dem Missionsobjekt nicht. Mir fällt dazu momentan nur ein, per Compilerschalter (Scriptedit?) zu Beginn von StartMission ein UFO zu erzeugen, und dieses an MissionObject zuzuweisen. Im Spiel würden die Zeilen dann ignoriert. Dort wird das Missionsobjekt ja von X-Force zugewiesen (wie DirkF schon geschrieben hat).
verfasst am: 28.08.2011, 13:32
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
UFO-AI-Skripte können meiner Meinung nach in medit sowieso nicht vernünftig getestet werden, da man dafür den Geoscape braucht - schon alleine um die Reaktionen auf sich nähernde Flugzeuge etc zu bestimmen, für die Prüfung der genauen Fluugbahnen etc.

In medit könnte man zwar die Ereignisse auslösen lassen, aber zum einen die Ergebnisse nur mit fiktiven Koordinaten prüfen und zum anderen keine kombinierten Ereignisse:
Wie reagiert die AI, wenn mehrere Abfangjäger von verschiedenen Seiten kommen...
verfasst am: 28.08.2011, 18:38
Programmierer, allgemeines

Registrierdatum: 06.06.2004, 17:19

 Beiträge: 3186
Imho spielt beides eine Rolle. Zwar kann man nur im Spiel prüfen, ob wirklich alles so klappt, wie geplant. Wenn allerdings unerwartete Fehler auftreten, lassen sich diese in medit oft besser aufspüren, als im Spiel.
verfasst am: 28.08.2011, 21:47
Registrierdatum: 31.01.2010, 20:05

 Beiträge: 122
Danke für eure Hinweise.

Zu dem was Natter sagt muss ich leider ergänzen, dass ich im AiScript kein Ufo erzeugen konnte und es mit diesem AiScript steuern konnte, geschweige denn die Fehler suchen. Mir kommt hier Baron Münchhausen in den Sinn, der sich an den Haaren aus dem Sumpf zog.
Den Hinweis von DirkF (mission_api_StartScriptWithObject(ScriptName: string; Object: TOBJECT): TMission) habe ich nicht probiert, denn das hat schon einmal bei mir nicht funktioniert und ich habe mich deshalb mit den AiSkripten befasst.
Einige Fehler habe ich aber inzwischen finden können, indem ich mit einer Messagebox an den verdächtigen Stellen einige Werte mir habe anzeigen lassen. Das ist zwar nicht der Königsweg, eher ein Pilgerpfad, aber es geht damit langsam vorwärts.

Nochmals ein Dankeschön für die Ratschläge
verfasst am: 28.08.2011, 22:04
Programmierer, allgemeines

Registrierdatum: 06.06.2004, 17:19

 Beiträge: 3186
Zitat: AlterKnacker

Zu dem was Natter sagt muss ich leider ergänzen, dass ich im AiScript kein Ufo erzeugen konnte und es mit diesem AiScript steuern konnte,

Ok, dann hier mal ein Beispiel mit einer der Standard-AIs.
program UFOAI_fighter;

uses GEN90path, GEN20geo;

const
  KIrandomsearch = 0; // Normalfall, sucht Gegner
  KIrandomflight = 1; // Beschädigt, weicht Gegnern aus
  KIhunttarget = 2; // Auf der Jagd nach Flugzeugen
  KIhuntbase = 3; // Wenn UFO während der Jagd in eine Basisverteidigung gelockt wurde

var
  UFO:TUFO;
  path:String;
  Startpoint:TFloatpoint;
  pathcounter:Integer;
  LastPoint:TFloatpoint;
  FinalCommand:Boolean;
  Returnfunction:string;
  ReturnMission:TMission;

procedure ACCStartFinalCommand(sender:TObject);
begin
  Finalcommand:=true;
  UFO.FlyToPoint(LastPoint);
end;

procedure ACCLastDestination(Destx:double;Desty:double;now:boolean;funct:string; mission:TMission);
begin
  LastPoint.x:=Destx;
  LastPoint.y:=Desty;
  Returnfunction:=funct;
  ReturnMission:=mission;
  if (now) then
    ACCStartFinalCommand(UFO)
  else
    register_timed_event(@ACCStartFinalCommand,UFO,60*(UFO.HoursALive-1)); 
end;


function critical(UFO:TUFO):boolean;
begin
  result:=false;
  if (UFO.HitPoints<UFO.model.Hitpoints/2) then result:=true;
end;


// Funktion für das Ereignis "HitByBase"
procedure ACCHitByBase(sender:TObject);
var
  base:TBase;
  ziel:TFloatPoint;
begin
  if (Finalcommand) then
    exit;
  base:=GEN20nearestBase(UFO.position);
  case UFO.AIstep of
    KIrandomsearch, KIrandomflight:
      begin
        ziel.x:=2*UFO.Position.x-base.Position.x;
        ziel.y:=2*UFO.Position.y-base.Position.y;
        UFO.FlyToPoint(ziel);
      end;
    KIhunttarget:
      begin
        UFO.AIstep:=KIhuntbase;
        UFO.huntobject(base);
      end;
    KIhuntbase:
      begin
        if (critical(UFO)) then
        begin
          UFO.AIstep:=KIrandomflight;
          // Ziel muss anders bestimmt werden, da das UFO wahrscheinlich genau über
          // der Basis steht - Distanz also 0 ist. Dieser Fluchtpunkt sollte noch
          // randomisiert werden
          Ziel:=UFO.Position;
          Ziel.x:=Ziel.x+20;
          UFO.FlytoPoint(ziel);
        end;
      end;
  end;
end;



// Funktion für das Ereignis "CommandComplete"
procedure ACCCommandComplete(sender:TObject);
begin
  if (Finalcommand) then
  begin
    if (isobject(ReturnMission) AND (length(Returnfunction)>0)) then
      ReturnMission.CallProcedure(Returnfunction,[UFO]);
    exit;
  end;
  if (critical(UFO)) then UFO.AIstep:=KIrandomflight
    else UFO.AIstep:=KIrandomsearch;
  UFO.FlyToPoint(GEN20getnextPathPoint(path,Startpoint,pathcounter));
end;

// Funktion für das Ereignis "NearestEnemyChanged"
procedure ACCEnemyNear(sender:TObject);
begin
  if (Finalcommand) then
    exit;
  if (isObject(UFO.nearestEnemy) AND NOT(critical(UFO))) then
    begin
      UFO.AIstep:=KIhunttarget;
      UFO.HuntObject(UFO.NearestEnemy);
    end
    else
    begin
      UFO.AIstep:=KIrandomflight;
      UFO.FlyToPoint(GEN20getnextPathPoint(path,Startpoint,pathcounter));
    end;
end;

procedure ACCsetpath(code:string);
begin
  //Pathcheck einbauen
  path:=earth_api_getPath(code);
end;

procedure ACCsetPorigin(x:double;y:double);
begin
  Startpoint.x:=x;
  Startpoint.y:=y;
end;

procedure ACCsetPstep(step:integer);
begin
  Pathcounter:=step;
end;

procedure ACCClearDestination;
begin
  Finalcommand:=false;
  ACCCommandComplete(UFO);
end;

procedure StartMission;
var
  dummy:Integer;
begin
  {$IFDEF SKRIPTEDIT}
  MissionObject:=ufo_api_CreateUFO;
  {$ENDIF}
  if (IsObject(MissionObject)) then
  begin
    dummy:=integer(MissionObject);
    UFO:=TUFO(dummy);

    register_mission_object(UFO);
    UFO.UserAI:=true; //Abschalten automatischer Aktionen, der Scout soll nur beobachten
    UFO.AIstep:=KIrandomsearch;

    ACCsetpath('R');
    ACCsetPorigin(UFO.Position.x,UFO.Position.y);
    ACCsetPstep(1);

    UFO.FlyToPoint(GEN20getnextPathPoint(path,Startpoint,pathcounter));
    FinalCommand:=false;

    register_event(@ACCCommandComplete, UFO, EVENT_ONUFOCOMMANDCOMPLETE);
    register_event(@ACCEnemyNear, UFO, EVENT_ONUFONEARESTENEMYCHANGED);
    register_event(@ACCHitbyBase, UFO, EVENT_ONUFOHITBYBASE);
  end;
end;

begin
  MissionName:='UFOAI_fighter';
  MissionType:=mzObjects;
end.
Ich hab lediglich in StartMission folgende Zeilen ergänzt:
  {$IFDEF SKRIPTEDIT}
  MissionObject:=ufo_api_CreateUFO;
  {$ENDIF}

Damit lässt sich das Skript auch in medit testen.
verfasst am: 29.08.2011, 01:14
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
Zitat: AlterKnacker
dass ich im AiScript kein Ufo erzeugen konnte und es mit diesem AiScript steuern konnte, geschweige denn die Fehler suchen.

Das könnte schon das Problem sein, denn es ist nicht vorgesehen, das das AI-Skript das UFO selber erzeugt, das es steuern soll...

Normalerweise sollte das UFO bereits existieren, wenn das AI-Skript für das UFO getartet wird. Es geht zwar auch anders, aber dann muss man mit leeren AI-Skripten als Platzhalter arbeiten.

Wenn ein UFO erzeugt wird (egal wie), dann wird automatisch das im Editor für das UFOmodell eingetragene AI-Skript gestartet. Dies ist die reguläre Vorgehensweise: Ein AI-Skript wird in den Spielsatz geladen und dann im Editor einem oder mehreren UFO-Modellen zugewiesen.
Anschließend wird dieses Skript jedesmal gestartet, wenn ein UFO diesen Typs erzeugt wird und übernimmt die Steuerung.

Wenn ein anderes Skript das UFO erzeugt, dann wird trotzdem für dieses UFO das eingebundene AI-Skript gestartet. Falls das originale Skript die Steuerung behalten soll, dann muss für die AI des UFOs im Editor ein leeres AI-Skript ohne eigene Funktionen eingetragen sein - ansonsten übernimmt das im Editor zugeordnete AI-Skript die Steuerung des UFOs (oder die Funktionen beider Skripte vermischen sich, das kann man auch machen aber nur bei sehr sorgfältiger Planung).

Es gibt eine Methode im UFO-Objekt mit der man dem UFO ein neues AI-Skript zuweisen kann (durch ein übergeordnetes Programm), in diesem Fall werden aber alle bestehenden Steuerungsfunktionen überlagert und das zugeordnete neue AI-Skript verhält sich so, als ob das UFO gerade erst erzeugt worden ist.

Wenn diese Informationen immer noch nicht weiterhelfen, dann solltest Du mal genauer beschreiben was Du machen möchtes und wo dieFehler auftauchen.
verfasst am: 29.08.2011, 10:24
Registrierdatum: 22.08.2008, 15:51

 Beiträge: 403
Das Script von Natter ist ziemlich lang, und ich glaube, die wichtigste Stelle ist diese:
procedure StartMission;
var
  dummy:Integer;
begin
  {$IFDEF SKRIPTEDIT}
  MissionObject:=ufo_api_CreateUFO;
  {$ENDIF}
  if (IsObject(MissionObject)) then
  begin
    dummy:=integer(MissionObject);
    UFO:=TUFO(dummy);

    register_mission_object(UFO);
    UFO.UserAI:=true; //Abschalten automatischer Aktionen, der Scout soll nur beobachten
    [...]//Hier hab ich Code weggeschnitten, ist unnötig für meine Erklärung
end;


Wenn du das AI-Script an ein bestimmtes UFO bindest, hast du mit dieser Methode zugriff auf das UFO selbst (Die Variable "UFO" muss vorher noch global definiert werden, 9. Zeile in Natters Script). Du brauchst diese Dinge wie StartMissionWithObject dafür nicht.



:: 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.039 · Powered by miniBB 1.6 with parts of 1.7 © 2001-2003