Banner left   Banner center   Banner right

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

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

Zur Zeit online: keiner ausser dir

 X-Force - Fight For Destiny - Forum —› X-Skript / Developer-Pack —› Units und Konstanten

Autor Mitteilung
verfasst am: 09.10.2009, 15:48
Registrierdatum: 22.08.2008, 15:51

 Beiträge: 403
Ich hab ein paar Schwierigkeiten mit den Units:
Ich hab eine Unit "Konstanten" in der, logischer Weise, nur Konstanten stehen. Dann hab ich einige Funktionen, die ich zur dynamischen Erzeugung von Gegnern in vielen anderen Skripten verwenden will. Allerdings hab ich die Fehlermeldung an der Stelle 0:0 Variable Expected. Im Smirkovich gibts Skripte, die genauso aufgebaut sind aber was hab ich falsch gemacht?

Header des Skripts:
unit Util_Gegner;

uses Konstanten;

var
  AllEnemies : Array of TAlienModel;

//diese Funktion filtert alle brauchbaren Gegner
procedure FillAllEnemies;
var
  aktuell : TAlienModel;

verfasst am: 09.10.2009, 16:07 · Edited by: sujin
Spielsatz Alliances

Registrierdatum: 14.07.2004, 14:47

 Beiträge: 1185
Hm... an dem Header kann ich nichts falsches erkennen, aber ehrlich gesagt erkenn ich garnichts xD
Poste mal Unit und Skript komplett, evtl fällt mir dann was auf.

Habe den Fehler bisher nur bekommen, wenn ich einer Prozedur, die extra eine Variable erwartet, etwas anderes vorwerfe (z.B. inc(var x) mit einer Konstante füttere). Aber das trott ja wohl kaum bei 0:0 auf o.O

Edit: Wenn es du die Alien-IDs nur als Array und nie einzeln brauchst, kannst du auch so:
const
  Aliens = [0123456, 1357912{, usw}];

einen konstanten Array definieren. Aber das nur am Rande...
verfasst am: 09.10.2009, 19:07
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
Wie sujin schon sagte brauchen wir zur Beurteilung die kompletten Skripte.
Der Fehler deutet imho auf ein Problem innerhalb der Unit Konstanten hin, die solltest Du auch posten.
verfasst am: 10.10.2009, 10:45
Registrierdatum: 22.08.2008, 15:51

 Beiträge: 403
Da ich eh immer brav kommentiere sollte das lesen kein Problem sein.
unit Konstanten:
[code]
unit Konstanten;

const
//Phasen
EINSAMKEIT = 100;
AUFBAU = 200;
UNAUFFAELLIG = 300; //Wurde in Phase zwei eingegliedert
SABOTAGE = 400;
GEJAGT = 500;
REBELLION = 600;
VERTREIBUNG = 700;

//Schwierigkeit
EINFACH = 50;
MITTEL = 100;
SCHWER = 150;

//Gegner
BRAUNBAER = 3097061427;
RENTIER = 1062077771;
WACHSOLDAT1 = 3986974134; //MG Soldat
WACHSOLDAT2 = 3114128258; //Raketensoldat
WACHSOLDAT3 = 2867752545; //Scharfschütze
WACHDROHNE_mkII = 530507241;
GEFANGENER_SPION = 3513004662;
AMSEL = 3128962944;
COMPUTER_TERMINAL = 4216632892;
TECHNIKER = 4270639035;
A_AUFSEHER = 2205854098;

//Flugzeuge
ZIVILTRANSPORTER_I_MENKARER = 1969774557; //Ziviltransporter der Menkarer
ZIVILTRANSPORTER_I_POLLUXER = 100013463; //Ziviltransporter der Polluxer
SCOUT_I_MENKARER = 2026541235; //Überwachungsschiff der Menkarer
SCOUT_I_POLLUXER = 255954348; //Scoutschiff der Polluxer
ESKORTE_I_AQUARIIER = 191387478; //Blaue Eskorte der Aquariier

//Material
NAHRUNG = 2925683382;

//Gebäude
BAUM = 3725601901;
GARAGE = 1952039865;
HAUS = 199756417;
KELLER = 4234780669;
ZELT = 382681185;
FELD = 1658678619;


//Spielsatz balancing
LAUNCH_TRANSPORTER_PHASE_GEJAGT = 600; //Zeit in Minuten
LAUNCH_SCOUT_PHASE_GEJAGT = 600; //Zeit Minuten
ENERGIETECHS = 6;
TECH_MAX = 2;

//XTags
//Verwendungstyp der Gegner
NICHTS = 's';
ELITE = 'e';
SOLDAT = 's';
SWARMER = 'w';

//Länder
CHINA = 8;
RUSSLAND = 6;

//Nachrichten
//Deutsch
{$ifdef DEUTSCH}
{$define CONSTOK}
Soldaten_kommen_Nachricht = 'Die Soldaten haben ihre Zelte aufgeschlagen.'+#13#10+'Ich sollte eine Besprechung einberufen.';
Alphatronmine_Nachricht = 'Wir haben genug Teile für eine eigene Alphatronmine gesammelt. Der Bau kann umgehend beginnen.';
Fabriken_Sabotieren_Nachricht = 'Wir haben den menschlichen Streitkräften einen herben Schlag versetzt.';
Forscher_befreien_Nachricht = 'Es wurden einige Wissenschaftler befreit!';
Soldaten_befreien_Nachricht = 'Es wurden einige Soldaten befreit!';
Techniker_befreien_Nachricht = 'Es wurden einige Techniker befreit!';
Hochsicherheitstrakt_Nachricht = 'Peter van Daan konnte gerettet werden!';
Radiostation_Nachricht = 'Wir haben die Radiostation erobert.'+#13#10+'Es wird allerdings einen Tag dauern sie in'+#13#10+'Betrieb zu nehmen.';
Phasensteuerung_Weiterplanung = 'Gestern Nacht haben wir geplant wie die XForce weitermacht.';
Phasensteuerung_Radiostation = 'Wir sollten damit beginnen die Radiostation'+#13#10+'Einsatz bereit zu machen.';
Phasensteuerung_Peter = 'Die Rettung von Peter van Daan muss augenblicklich beginnen.';
Phasensteuerung_Felix = 'Felix Pfeffer muss aus der Alphatronmine befreit werden.';
Hydrolab_Nachricht = 'Ich habe die Standorte der Hydrokulturlabore erfahren.';
EnergieTech_Nachricht = 'Ich plane die Überfälle auf die Forschungslabore.';
Hacken_Complete = 'Das Computerterminal wurde gehackt!';
Silo_Hinterhalt = 'Die Soldaten sind in einen Hinterhalt geraten!';
//Energie Techs
TECH_CASIMIR = 'Casimir Effekt';
TECH_FUSION = 'Kernfusion';
TECH_KOSMOS = 'Kosmische Strahlung';
TECH_NUKE = 'Nukleare Energie';
TECH_SCHWERKRAFT = 'Schwerkraftenergie';
TECH_BIO = 'Bioelektrische Energie';
Sensor_Text = 'Es ist unbekannt, wie die Einrichtung bewacht wird.';
//Ende Energie Techs
{$endif}

//Englisch
{$ifdef ENGLISH}
{$define CONSTOK}
Soldaten_kommen_Nachricht = 'The soldiers have arrived. I shall call a meeting.';
Alphatronmine_Nachricht = 'We have gathered enough material for our own alphatronmine. The construction can start immediately.';
Fabriken_Sabotieren_Nachricht = 'We have weakened the human forces.';
Forscher_befreien_Nachricht = 'We have rescued some scientists.';
Soldaten_befreien_Nachricht = 'We have rescued some soldiers.';
Techniker_befreien_Nachricht = 'We have rescued some technicans.';
Hochsicherheitstrakt_Nachricht = 'Peter van Daan has been rescued!';
Radiostation_Nachricht = 'We have conquered the radio station,'+#13#10+'but it will take a day time'+#13#10+'to make it fuctional.';
Phasensteuerung_Weiterplanung = 'Yesterday night, we have planed how the XForce will proceed';
Phasensteuerung_Radiostation = 'We should start to prepare the radiostation'+#13#10+'for our uses.';
Phasensteuerung_Peter = 'Peter van Daan must be rescued immediately.';
Phasensteuerung_Felix = 'Felix Pfeffer has to be freed from the alphatron mine.';
Hydrolab_Nachricht = 'I have recieved the locations of the hydrocultures laboratories.';
EnergieTech_Nachricht = 'I am planing the raids of the research institution.';
Hacken_Complete = 'The computerterminal has been hacked!';
Silo_Hinterhalt = 'The soldiers have been ambushed!';
//Energie Techs
TECH_CASIMIR = 'Casimir effect';
TECH_FUSION = 'Nuclear fission';
TECH_KOSMOS = 'Cosmic rays';
TECH_NUKE = 'Nucleare power';
TECH_SCHWERKRAFT = 'Gravity energy';
TECH_BIO = 'Bio-electrical energy';
Sensor_Text = 'It is unknown how the institution is guarded.';
//Ende Energie Techs
{$endif}

//Maps
JAGD_MAP = 229497333;
LAGERHAUS_MAP = 1817673964;
GEFANGENENTRAKT_MAP = 2897434254;
HOCHSICHERHEITSTRAKT_MAP = 1556075757;
RADIOSTATION_MAP = 4078809181;
SIPHER_MAP = 685229778;
TRINITY_MAP = 3916097184;
SILO_AUFBAU_MAP = 2195077871;
SILO_SABOTAGE_MAP = 1544742576;
FLUGZEUGWERFT_MAP = 1296228615;
FABRIKSANLAGE_MAP = 2198874757;
HYDROLABOR_MAP = 2273442585;
ALPHATRONMINE_MAP = 3044486979;
ENERGIE_TECH_MAP = 27807132;

//Ende//////////////////////////////////////////////////////////////// //////////
end.
[/code]
verfasst am: 10.10.2009, 10:50
Registrierdatum: 22.08.2008, 15:51

 Beiträge: 403
Kurz zur Erklärung: util_Gegner verwendet die XTags um die Funktion (bzw Schwierikeit) des Gegners festzustellen. Abhängig von der Schwierigkeit, werden auch unterschiedlich viele Gegner zusammengestellt. Die Schwierigkeit wird durch die Anzahl der Gegner bestimmt.
unit Util_Gegner;

uses Konstanten;

var
  AllEnemies : Array of TAlienModel;

//diese Funktion filtert alle brauchbaren Gegner
procedure FillAllEnemies;
var
  aktuell : TAlienModel;
  count : LongInt;
  i,j : LongInt;
begin
  //"Echte" Gegner zählen
  count := 0;
  for i := 0 to (i < (alien_api_GetAlienCount - 1)) do begin
    if (alien_api_GetAlienByID(i).UserTag <> NICHTS) then
      inc(count);
  end;
  //Arraygröße definieren
  setlength(AllEnemies,count);
  //Array füllen
  i := 0;
  //Es werden nochmal alle Gegner durchlaufen, j zählt den AlienIndex, i den Arrayindex
  for j := 0 to (j < (alien_api_GetAlienCount - 1)) do begin
    aktuell := alien_api_GetAlienByID(j);
    if (aktuell.UserTag <> NICHTS) then begin
      AllEnemies[i] := aktuell;
      inc(i);
    end;
  end;
end;

function SelectRandomEnemies(AnzahlGegner : LongInt) : Array of TAlienModel;
var
  Gegner : Array of TAlienModel;
  aktuell : TAlienModel;
  i,l : LongInt;
begin
  l := getarraylength(AllEnemies);
  //Anfangs Arraygröße definieren
  setlength(Gegner,AnzahlGegner);
  //Array füllen
  for i := 0 to (i < (AnzahlGegner - 1)) do begin
    aktuell := AllEnemies[random(l - 1)];
    case aktuell.UserTag of
      ELITE: begin //Ein Elite zählt für zwei Soldaten
        if (i < (AnzahlGegner - 1)) then //Um komplikationen bei der letzten Arraystelle zu vermeiden
          setlength(Gegner,getarraylength(AnzahlGegner - 1));
        Gegner[i] := aktuell;
      end;
      Soldat: begin //Falls sich mal was ändern sollte
        Gegner[i] := aktuell;
      end;
      SWARMER: begin //Vier Swarmer zählen wie ein Soldat
        AnzahlGegner := AnzahlGegner + 3;
        setlength(Gegner,AnzahlGegner);
        Gegner[i] := aktuell;
        Gegner[i + 1] := aktuell;
        Gegner[i + 2] := aktuell;
        Gegner[i + 3] := aktuell;
        i := i + 3;
      end;
    end;
  end;
  
  //Result setzen
  Result := Gegner;
end;

begin
  MissionName := 'UtilGegner';
  MissionType := mzUser;
end.

verfasst am: 10.10.2009, 11:16 · Edited by: DirkF
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
Sag mal - bist Du Dir sicher das die for-Schleifen auch das machen, was Du willst?
Ich würde nämlich sagen, das dort Dein Problem liegt...

Selbst wenn das X-Skript einen Logikwert aus einer Formelüberprüfung als Zielwert für das Ende einer For-Schleife akzeptiert (und ich glaube eher das die Fehlermeldung "Variable erwartet" dorther kommt), ist es wohl nicht in Deinem Sinne, die Schleifen je nach Logikergebnis mal von 0 bis 0 und mal von 0 bis 1 laufen zu lassen - das ginge über IF einfacher...

Ich tippe mal eher, das die Position 0 aus der Fehlermeldung daher kommt, weil XSkript bei solchen schrägen Konstrukten keine Zuordnung mehr vornehmen kann und nicht weil der Fehler zu Beginn des Skriptes kam - bei einem ordnungsgemäßen Fehler gibt es immer eine Zeilennummer, auch wenn der in units liegen würde (was hier wohl nicht der Fall ist)
verfasst am: 10.10.2009, 12:13
Registrierdatum: 22.08.2008, 15:51

 Beiträge: 403
Hätte nicht gedacht, dass es im Sourcecode liegt. Der Fehler lag im setarraylength, da hab ich die falsche Variable verwendet und die Klammer zuspät zu gemacht.
Der Grund für diese schräge Konstruktion ist die Größe des dynamischen Arrays. Ob die for-Schleife Logikwerte akzeptiert, werde ich bald herausfinden, wenn nicht kann ich es einfach durch eine while-Schleife ersetzen.

Danke für deine rasche Hilfe!!
verfasst am: 10.10.2009, 15:02 · Edited by: Natter
Programmierer, allgemeines

Registrierdatum: 06.06.2004, 17:19

 Beiträge: 3186
Zitat: Kreks
for j := 0 to (j < (alien_api_GetAlienCount - 1)) do begin aktuell := alien_api_GetAlienByID(j); if (aktuell.UserTag <> NICHTS) then begin AllEnemies[i] := aktuell; inc(i); end;

DirkF hat imho recht. Ich kann mir auch nicht vorstellen, dass das so klappt, wie du dir das denkst. Selbst wenn der Booleanwert automatisch zu Integer gewandelt wird, wird deine Schleife maximal einmal durchlaufen. for ... to ... erhöht die Zählervariable in jedem Durchlauf um 1. Der to-Wert gibt einfach nur an, bei welchem Wert abgebrochen werden soll. Außerdem ist der to-Wert glaube eine Konstante, soll heißen, wenn da ein komplexer Ausdruck steht, so wird der Ausdruck beim ersten Durchlauf berechnet, und danach immer der selbe Wert genommen (selbst wenn dem nicht so wäre - deine Schleife würde trotzdem höchstens einmal durchlaufen, denn im zweiten Durchlauf hätte j den Wert 1 - der Maximalwert der bei einem Logikwert denkbar ist).

Wenn du (aus welchem Grund auch immer) unbedingt eine for ... to -Schleife nehmen willst, dann kannst du deine Prüfung in die Schleife setzen ( if not Bedingung then break;).
verfasst am: 10.10.2009, 21:37
Admin, Spielsatz GalWar

Registrierdatum: 31.08.2005, 21:51

 Beiträge: 5595
Ich hab mir den Code nochmal angeschaut...

Kreks, vergess den einfach - da sind soviele logische Fehler drin, der kann einfach nicht funktionieren...

setlength und setarraylength sind zwei verschiedene Befehle, den zweiten verwendest Du gar nicht und setzt stattdessen den ersteren ein, der Zeichenketten und nicht Arrays definiert...

bei
for i := 0 to (i < (alien_api_GetAlienCount - 1)) do begin
kann i niemals größer werden als 1, die Schleife geht immer nur von i:=0 bis i:=1. Es sei denn es gibt keine Aliens - dann geht das von 0 bis 0.

das was Du machen willst bräüchte den code:
for i:=0 to alien_api_GetAlienCount-1 do ...

Und der Rest sieht mir auch etwas schräg und umständlich aus, auch wenn ich da gerade keine Fehler sehe...
verfasst am: 10.10.2009, 23:59 · Edited by: sujin
Spielsatz Alliances

Registrierdatum: 14.07.2004, 14:47

 Beiträge: 1185
Zitat: DirkF
Kreks, vergess den einfach - da sind soviele logische Fehler drin, der kann einfach nicht funktionieren...

Leider wahr. Ich hab mal drübergepfuscht, vielleicht hab ich an ein paar Stellen gepennt, aber die gröbsten Fehler sollten raus sein... wenn noch welche drin sind, dann sind es wenigstens die subtileren, die mit Umkehrung eines Operators behoben werden können ^^
unit Util_Gegner;

uses Konstanten;

var //braucht man nicht, zumindest für keine der Prozeduren in dieser Unit
  AllEnemies: Array of TAlienModel;
// Ein globaler Alien-Array ist an sich evtl nützlich.
// SOllte aber regelmäßig aktualisiert werden!

// FillAllEnemies(AlienModelArr) füllt den Array AlienModelArr
// mit allen "brauchbaren" Gegnern -> flexibler
procedure FillAllEnemies(var Arr: Array of TAlienModel);
var // Mehr braucht es nicht!
  aktuell : TAlienModel;
  i,ii: LongInt;
begin
  // die ganze for-Schleife und die count-Variable dient bei dir nur dazu,
  // die Anzahl der Aliens festzustellen.
  // Doch GetAlienCount liefert das schon zurück!
    for i:=0 to alien_api_GetAlienCount-1 do begin
    aktuell:= alien_api_GetAlienByIndex(i); // INDEX! Ganz wichtig!
    // ID ist die lange Zahl ganz oben im Editorfenster,
    // Index ist die linear fortlaufende Nummerierung!
    if (aktuell.UserTag <> NICHTS) then begin
      Arr[ii]:=aktuell;
      inc(ii);
    end;
  end;
  // Außerdem muss der Array die Aliens mit Usertag=Nichts nicht aufnehmen!
  // Deshalb sollte die Länge nach dem Befüllen nachkorrigiert werden!
  SetArrayLength(Arr, ii);
end;

function SelectRandomEnemies(AnzahlGegner : LongInt) : Array of TAlienModel;
var
  // var Gegner ist überflüssig, weil identisch mit result
  aktuell : TAlienModel;
  i,l : LongInt;
begin
  l:= getarraylength(AllEnemies);
  // Start-Arraygröße definieren
  SetArrayLength(result, l);
  // Weil Endwert einer for-Schleife konstant ist (wird nur einmalig ausgerechnet),
  // muss es eine While-Schleife sein, in der Endwert variabel ist und ggf erhöht
  // werden kann (case Swarmer zB)
  i:= 0; // Geht vermutlich auch ohne - bin aber nicht ganz sicher
  while (i <= l-1) do
  begin
    aktuell := AllEnemies[random(l - 1)];
    case aktuell.UserTag of
      ELITE: //Ein Elite zählt für zwei Soldaten
      begin
        if (i < l-1) then //Um komplikationen bei der letzten Arraystelle zu vermeiden
        begin
          SetArrayLength(result, l-1);
          result[i] := aktuell;
        end;
      end;
      SOLDAT: //Falls sich mal was ändern sollte
      begin
        result[i] := aktuell;
      end;
      SWARMER: //Vier Swarmer zählen wie ein Soldat
      begin
        SetArrayLength(result, l+3);
        result[i]:= aktuell;
        result[i+1]:= aktuell;
        result[i+2]:= aktuell;
        result[i+3]:= aktuell;
        i:= i+3;
      end;
    end;
    inc(i);
  end;
end;

begin
  MissionName := 'UtilGegner';
  MissionType := mzUser;
end.
verfasst am: 11.10.2009, 13:17
Registrierdatum: 22.08.2008, 15:51

 Beiträge: 403
Zitat: DirkF
setlength und setarraylength sind zwei verschiedene Befehle, den zweiten verwendest Du gar nicht und setzt stattdessen den ersteren ein, der Zeichenketten und nicht Arrays definiert...

Stimmt, war ein Lesefehler meinerseits aus der Doku. Jetzt ist mir auch endlich klar geworden wo das Problem mit den for-Schleifen lag. Ich hab in letzter Zeit viel in C# programmiert und bin mit dem Syntax komplett durcheinander gekommen. Danke sujin für den Tipp mit dem Index und der ID, da vertippt ich mich ganz gerne.
Danke für die große Anteilnahme, das Skript funktioniert jetzt ohne Probleme. Danke.



Du musst dich registrieren um auf dieses Thema zu antworten.
Login :: » Name » Passwort

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