Waffen ist bereits definiert..

Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Guten Abend,
    ich habe ein unvorstellbaren Fehler im Script.
    else if(dialogid == DIALOG_MP53)
    {
    new Waffen[13][2],string[144],gid = Spieler[playerid][GruppenID];
    if(response)
    {
    if(!IsNumeric(inputtext))return ShowPlayerDialog(playerid,DIALOG_MP53,DIALOG_STYLE_INPUT,"{FF9000}Waffenschrank (Verstauen){FFFFF} - MP5","{FFFFFF}Wie viele Patronen möchtest du von deiner MP5 in den Waffenschrank verstauen?","Verstauen","Alle");
    for(new i=0;i<13;i++)
    {
    GetPlayerWeaponData(playerid,i,Waffen[i][0],Waffen[i][1]);
    if(Waffen[i][0] != 29)continue;
    if(!strlen(inputtext))return ShowPlayerDialog(playerid,DIALOG_MP53,DIALOG_STYLE_INPUT,"{FF9000}Waffenschrank (Verstauen){FFFFF} - MP5","{FFFFFF}Wie viele Patronen möchtest du von deiner MP5 in den Waffenschrank verstauen?","Verstauen","Alle");
    if(strval(inputtext) > Waffen[i][1])return SendClientMessage(playerid,rot,"[SERVER]:{FFFFFF} Soviele Patronen besitzt deine MP5 nicht!"),ShowPlayerDialog(playerid,DIALOG_MP53,DIALOG_STYLE_INPUT,"{FF9000}Waffenschrank (Verstauen){FFFFF} - MP5","{FFFFFF}Wie viele Patronen möchtest du von deiner MP5 in den Waffenschrank verstauen?","Verstauen","Alle");
    RemovePlayerWeapon(playerid,29,strval(inputtext));
    Gruppe[gid][G_MP5] += strval(inputtext);
    format(string,144,"[ Waffenschrank - MP5 ]:{FFFFFF} %s hat %d Patronen seiner MP5 in den Waffenschrank verstaut!",Name(playerid),strval(inputtext));
    SendGruppenChat(playerid,hblau,string);
    return 1;
    }
    return 1;
    }
    for(new i=0;i<13;i++)
    {
    GetPlayerWeaponData(playerid,i,Waffen[i][0],Waffen[i][1]);
    if(Waffen[i][0] != 29)continue;
    RemovePlayerWeapon(playerid,29);
    Gruppe[gid][G_MP5] += Waffen[i][1];
    format(string,144,"[ Waffenschrank - MP5 ]:{FFFFFF} %s hat alle Patronen (%d) seiner MP5 in den Waffenschrank verstaut!",Name(playerid),Waffen[i][1]);
    SendGruppenChat(playerid,hblau,string);
    return 1;
    }
    }
    In diesen Code wird mir angezeigt, dass Waffen bereits definiert ist.
    Hier habe ich Waffen bereits definiert, ist aber in einem anderen else if.
    else if(dialogid == DIALOG_DEAGLE3)
    {
    new Waffen[13][2],string[144],gid = Spieler[playerid][GruppenID];
    if(response)
    {
    if(!IsNumeric(inputtext))return ShowPlayerDialog(playerid,DIALOG_DEAGLE3,DIALOG_STYLE_INPUT,"{FF9000}Waffenschrank{FFFFFF} - Desert Eagle","{FFFFFF}Wie viele Patronen möchtest du in den Waffenschrank verstauen?","Verstauen","Alle");
    for(new i=0;i<13;i++)
    {
    GetPlayerWeaponData(playerid,i,Waffen[i][0],Waffen[i][1]);
    if(Waffen[i][0] != 24)continue;
    if(strval(inputtext) > Waffen[i][1])return SendClientMessage(playerid,rot,"[SERVER]:{FFFFFF} Soviele Patronen besitzt deine Desert Eagle nicht!"),ShowPlayerDialog(playerid,DIALOG_DEAGLE3,DIALOG_STYLE_INPUT,"{FF9000}Waffenschrank{FFFFFF} - Desert Eagle","{FFFFFF}Wie viele Patronen möchtest du in den Waffenschrank verstauen?","Verstauen","Alle");
    RemovePlayerWeapon(playerid,24,strval(inputtext));
    Gruppe[gid][G_Deagle] += strval(inputtext);
    format(string,144,"[ Waffenschrank - Desert Eagle ]:{FFFFFF} %s hat %d Patronen seiner Desert Eagle in den Waffenschrank verstaut!",Name(playerid),strval(inputtext));
    SendGruppenChat(playerid,hblau,string);
    return 1;
    }
    return 1;
    }
    if(!response)
    {
    for(new i=0;i<13;i++)
    {
    GetPlayerWeaponData(playerid,i,Waffen[i][0],Waffen[i][1]);
    if(Waffen[i][0] != 24)continue;
    RemovePlayerWeapon(playerid,24);
    Gruppe[gid][G_Deagle] += Waffen[i][1];
    format(string,144,"[ Waffenschrank - Desert Eagle ]:{FFFFFF} %s hat alle Patronen (%d) seiner Deagle in den Waffenschrank verstaut!",Name(playerid),Waffen[i][1]);
    SendGruppenChat(playerid,hblau,string);
    return 1;
    }
    return 1;
    }
    return 1;
    }

  • Nein, habe schon das ganze Script untersucht.
    Eigentlich muss das doch funktioniert, da die beiden nicht global sind.

  • Ich habe es grade bei mir getestet, es ist tatsächlich so.
    Und zwar geht es, wenn es ein ein-dimensionales Array ist (Waffen[10]) oder eine normale Variable. Bei zwei-dimensionalen Arrays (Waffen[10][5]) geht es nicht mehr.
    Muss wohl am Kompiler liegen.


    Also: Das zweite Array umbenennen.



    Geht nicht:
    if(dialogid == 1)
    {
    new Waffen[10][2];
    Waffen[0][1] = 1;
    }
    if(dialogid == 2)
    {
    new Waffen[10][2];
    Waffen[0][0] = 1;
    }


    Geht:
    if(dialogid == 1)
    {
    new Waffen[10];
    Waffen[0] = 1;
    }
    if(dialogid == 2)
    {
    new Waffen[10];
    Waffen[0] = 1;
    }

  • Muss wohl am Kompiler liegen.


    einen genauen grund kann ich zwar nicht nennen, aber möglicherweise ist das Problem die Strukturebene und der Compiler schiebt sich das irgendwie zurecht.
    bspw. so


    new Waffen[10][2];
    if(dialogid == 1)
    {
    Waffen[0][1] = 1;
    }
    new Waffen[10][2];
    if(dialogid == 2)
    {
    Waffen[0][0] = 1;
    }
    Es könnte aber auch daran liegen, dass PAWN nur indirekt Mehrdimenionale Arrays unterstützt, denn diese werden sozusagen zusammen gerechnet.
    sprich aus Waffen[10][2] wird Waffen[20].

    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."

    Margarete Stokowski

  • der Compiler schiebt sich das irgendwie zurecht.


    Das macht der Compiler nicht, sonst würde das hier keine Errors ergeben, tatsächlich sagt er aber, dass Waffen2 nicht definiert ist. Würde er es vor die if-Klammer ziehen, wäre es definiert, ebenso wenn er es als globales Array ansehen würde.
    if(dialogid == 1)
    {
    new Waffen[10][5];
    Waffen[0][1] = 1;
    }
    if(dialogid == 2)
    {
    Waffen2[0][1] = 1;
    new Waffen2[10][5];
    Waffen2[0][2] = 1;
    }

    => error 017: undefined symbol "Waffen2" (in Zeile 8)


    Hatte ich mir zuerst auch gedacht, ist aber nicht so.



    Es könnte aber auch daran liegen, dass PAWN nur indirekt Mehrdimenionale Arrays unterstützt, denn diese werden sozusagen zusammen gerechnet.
    sprich aus Waffen[10][2] wird Waffen[20].


    Glaube ich nicht, und selbst wenn, dann müsste es ja funktionieren, da es mit ein-dimensionalen Arrays ohne Probleme geht (siehe Beispiele oben).
    So sieht es eher im RAM aus, zehn Pointer mit der jeweiligen Länge zwei (bei [10][2]) die hintereinander liegen.



    Die Definition fällt schlichtweg durch die kommenden Klammern durch (wie z.B. bei Java switch-case), da auch das hier funktioniert:
    if(dialogid == 1)
    {
    new Waffen[10][5];
    Waffen[0][1] = 1;
    }
    if(dialogid == 2)
    {
    Waffen[0][2] = 1;
    }
    Waffen[0][3] = 1;




    => Wenn das also nicht so gewollt ist (Warum sollte es?), dann ist das ein Fehler im Compiler. Der Compiler ist im Grunde genommen auch nur ein Programm, und jedes Programm kann ja bekanntermaßen Fehler beinhalten.

  • Kann es sein, dass das Script schon ziemlich groß ist ?


    PAWN war ja normalerweise nie dafür gedacht ein zu großes Programm zu sein. War eher für die kleinen Computer (z.B. wie Adruino).

    Mfg Templer


    >>Dein Breadfish-Thema im Unterforum ScriptingBase / Scriptingwünsche wurde nicht richtig beantworter?<<
    >>Es handelt sich um ein Programmier Problem und du nicht einfach weiter kommst wo der Fehler sein könnte?<<
    Dann melde dich bei mir über die PN-Funktion indem du den Link zu deinem Breadfish-Themen Problem schickst.
    Voraussetzung:
    Thema älter als 1 Tag und im Breadfish Forum gespostet!

  • Jap, im gesamten (inklusive Includes).


    // EDIT: Also die beste Lösung statt zwei zu definieren, dass du vor dem großen if die Variable deklarierst. Herumschieben tut PAWN in dem Falle nicht. Aber es wäre wirklich interessant zu wissen ^^ Hier sollte mal ein Profi uns aufklären.

    Mfg Templer


    >>Dein Breadfish-Thema im Unterforum ScriptingBase / Scriptingwünsche wurde nicht richtig beantworter?<<
    >>Es handelt sich um ein Programmier Problem und du nicht einfach weiter kommst wo der Fehler sein könnte?<<
    Dann melde dich bei mir über die PN-Funktion indem du den Link zu deinem Breadfish-Themen Problem schickst.
    Voraussetzung:
    Thema älter als 1 Tag und im Breadfish Forum gespostet!

  • Nein, 3280 Zeilen, ich finde das geht noch ;)
    9 Includes, wovon ich eine gerade nicht benutze ;)
    EDIT:
    Ich habe new Waffen[13][2]; nun mal unter OnDialogResponse ganz oben hingemacht.
    Anscheinend klappt das wohl, so brauche ich auch nur einmal das definieren ;)
    Dankeschön.

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen
  • Hier meine Testläufe (Man bemerke jedoch, dass der Fehler zur Laufzeit nur mit "crashdetect" erkannt werden kann. Ohne dem Plugin sieht man den Fehler überhaupt nicht und er überspringt den Code):



    public OnGameModeInit()
    {
    // Don't use these lines if it's a filterscript
    SetGameModeText("Blank Script");
    AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);

    new test = 5;
    if(test == 5) {
    if(test == 5) {
    if(test == 5) {
    if(test == 5) {
    // Wenn Diese Zeile auskommentiert wird, komm kein Compilterfehler,
    // kann er w‰hrend der Laufzeit nicht darauf zugreifen.
    // new Waffen[10][2];
    }
    }
    }
    new Waffen[10][2];
    Waffen[0][1] = 999;
    printf("DEBUG %d", Waffen[0][1]);

    // Wenn die folgende Initialisierung oberhalb vom 2-dimensionalem Array
    // geschieht, dann erkennt der Compiler dies auch als Fehler.
    new Waffe;
    Waffe = 5;
    printf("DEBUG %d", Waffe);
    }


    if(test == 5) {

    new Waffe;
    Waffe = 6;


    printf("DEBUG %d", Waffe);

    // Ergibt auch keinen Compilerfehler aber einen Fehler zur Laufzeit,
    // wenn auskommentiert.
    // new Waffen[10][2];
    Waffen[0][1] = 888;
    printf("DEBUG %d", Waffen[0][1]);
    }

    return 1;
    }


    Finde die Tatsache mit der Variable "Waffe" lustig, weil wenn man die Deklaration "Waffen" und die Verwendung weglöscht, erkennt der PAWN Compiler es nicht als "already defined" für Waffe.


    Nebenbei das "already defined" für die Variable "Waffe" erscheint nur, wenn sie oberhalb vom Array initialisiert wird.


    Hier ein Test der fehlerfrei ist:



    public OnGameModeInit()
    {
    // Don't use these lines if it's a filterscript
    SetGameModeText("Blank Script");
    AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);

    new test = 5;
    if(test == 5) {
    new Waffe;
    Waffe = 5;
    printf("DEBUG %d", Waffe);
    }


    if(test == 5) {

    new Waffe;
    Waffe = 6;


    printf("DEBUG %d", Waffe);
    }

    return 1;
    }


    Hab aus der Dokumentation folgendes herausgelesen:


    Zitat


    Multi-dimensional arrays are arrays that contain references to the sub-arrays.
    That is, a two-dimensional array is an “array of single-dimensional arrays”.∗
    Below are a few examples of declarations of two-dimensional arrays


    Bedeutet er erstellt in dem Fall zwei 1-dimensionale-Array´s womöglich, die wie folgt aussehen könnten:
    ACHTUNG: Das folgende ist nur Bauernverstand, weil ich mich mit Compiler nie ausgesetzt habe.
    LOGIK: Da PAWN 32-byte Felder erstellt (256 Bit) soll er die Adresse zu Waffen[0] um eben 256-bit verschieben, sodass die Adresse von Waffen[1] mit dem ODER-Parameter eingeordnet wird.

    new Waffen{2], WaffenLink[10] = {&Waffen[1] << 256 | &Waffen[0], ...};


    Letzten Endes vermischt der Compiler den VariablenNamen mit dem Funktionsnamen und den inneren if´s (Ich geh davon aus, dass jedes if eine eigene ID in einer Funktion hat).


    Also es muss ein Compilerfehler selbst sein, da er wahrscheinlich vergisst die 2. Variable (Anschaulich an "WaffenLink") nicht umwandelt und an die if-Strukturen (oder andere wie "switch") anpasst. (An der Funktion schon, sonst würde man nicht in einer anderen Funktion es erneut definieren können)


    Wobei das mit den 32-byte (256 Bit Verschiebung) muss nicht stimmen, da es letztendlich nur auf einem Bauernverstand beruht.


    Lg

    Mfg Templer


    >>Dein Breadfish-Thema im Unterforum ScriptingBase / Scriptingwünsche wurde nicht richtig beantworter?<<
    >>Es handelt sich um ein Programmier Problem und du nicht einfach weiter kommst wo der Fehler sein könnte?<<
    Dann melde dich bei mir über die PN-Funktion indem du den Link zu deinem Breadfish-Themen Problem schickst.
    Voraussetzung:
    Thema älter als 1 Tag und im Breadfish Forum gespostet!

  • Freut mich zu sehen, dass es immer wieder Leute gibt die ihr Gesagtes auch darlegen können, Templer gehört da auf jeden Fall dazu! :thumbup:


    Also es muss ein Compilerfehler selbst sein, da er wahrscheinlich vergisst die 2. Variable (Anschaulich an "WaffenLink") nicht umwandelt und an die if-Strukturen (oder andere wie "switch") anpasst. (An der Funktion schon, sonst würde man nicht in einer anderen Funktion es erneut definieren können)


    Genau. Deine Testläufe mit dem crashdetect-Plugin untermauern meine vorherige Aussage noch, dass es ein Fehler im Compiler ist. Ich habe diese Testläufe selbst auch nochmal gemacht und kann das bestätigen. Wie genau der Compiler das macht, da geht es mir wie dir, weiß ich nicht, aber das könnte eine Möglichkeit sein. Letztendlich ist es ja auch egal wie er es macht, er macht es falsch und zwar komplett falsch.
    Der Fehler bleibt auch innerhalb einer Funktion bzw. eines Callbacks, da man das Multi-dimensionale Array in einer anderen Funktion wieder definieren kann.


    Mit 3-dimensionalen Arrays ist es übrigens genau gleich.


    Finde die Tatsache mit der Variable "Waffe" lustig, weil wenn man die Deklaration "Waffen" und die Verwendung weglöscht, erkennt der PAWN Compiler es nicht als "already defined" für Waffe.
    Nebenbei das "already defined" für die Variable "Waffe" erscheint nur, wenn sie oberhalb vom Array initialisiert wird.


    Habe das eben auch nochmal ausprobiert. Es ist tatsächlich so, dass egal was man über einem Multi-dimensionalen Array auf gleicher Ebene (!) definiert hat, der Compiler erkennt es als Error (bereits definiert). Wirklich interessant, denn wenn man es drunter definiert macht es gar nichts aus.


    Noch interessanter wird es hier: (ich habe mir mal eben dein Beispiel geborgt)
    public OnGameModeInit()
    {
    // Don't use these lines if it's a filterscript
    SetGameModeText("Blank Script");
    AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);


    new test = 5;

    if(test == 5)
    {
    if(test == 5)
    {
    new Waffe;
    new Waffen[10][2];
    Waffen[0][1] = 999;
    printf("DEBUG %d", Waffen[0][1]);


    Waffe = 5;
    printf("DEBUG %d", Waffe);
    }
    }


    if(test == 5)
    {
    new Waffe;
    Waffe = 6;


    printf("DEBUG %d", Waffe);
    }


    return 1;
    }


    => warning 219: local variable "Waffe" shadows a variable at a preceding level


    Es ist jetzt nicht mehr die gleiche Ebene, von der Syntax her passt es immer noch, da es nicht in der gleichen if-Klammer ist, dennoch meint der Compiler es sei schon vorhanden, in diesem Fall aber die Warnung, die normal kommt wenn es in einer tieferen Ebene erneut definiert wird, z.B. so:
    new tmp;
    if(tmp)
    {
    new tmp;
    }

    Hier bekommen wir die Warnung 219.


    Im Beispiel oben mit "Waffe" ist es aber anschaulich dargestellt so:
    new xy;
    if(xy)
    {
    new tmp;
    }
    new tmp;

    Hier findet der Compiler keinen Fehler (ist ja auch korrekt!), abgesehen von den "is never used", die ich hier mal vernachlässige. Durch die nachfolgende Definition eines multi-dimensionalen Arrays wird es plötzlich als falsch erkannt.
    new xy;
    if(xy)
    {
    new tmp;
    new array[10][10];
    }
    new tmp; //219

    => Warnung 219 für tmp.



    Irgendwas bringt den Compiler also mächtig durcheinander, wenn man Multi-dimensionale Arrays innerhalb von Funktionen/Callbacks definiert, auch wenn es von der Syntax her kein Problem sein darf.




    Durch diese Tests und die Tests von Templer sehe ich es als bewiesen an, dass hier ein Fehler im Compiler ist.
    ...und zwar kein kleiner!

  • Zur Vollständigkeit zitiere ich noch Y_Less, warum SAMP nicht auf die neue PAWN Version umgeschrieben wird: Die neue Version würde Sicherheitslücken schließen, welche von anderen Autoren ausgenutzt werden. (besonders weil Systeme von Y_Less nutzlos wären, weil er selbst diese Bug´s ausnutzt :P)


    Ich finde es nur schade, weil in der neuen Version eine Mac Version bereitgestellt worden ist und ein User bei Google Code bereits einen patch schrieb, der das kompilieren einer Mac Version vervollständigte.


    Leider steht aber auch der Source-Code von der PAWN Version 3.2.3664 nichtmehr zur Verfügung.


    Die Änderungen zur Version Version 3.2, build 3664 hier:
    http://pastebin.com/Qn4xmwCf
    (Ein bisschen reinstöbern zeigt auch bereits die volle Änderung der Sprache und wahrscheinlich ist da drinnen auch irgendwo der Bugfix für unser Problem)


    Quelle: http://forum.sa-mp.com/showthread.php?t=274061&page=6


    p.S. Ich entschuldige wenn das Forum bereits ein solches Thema angeschnitten hat. Sollte jemand einen Link zu einem Post betreffend (Neue PAWN Version) finden, so schreibe er ihn bitte unterbei.


    Hier wollte ich nur das endgültige Fazit zum derzeit unbeschreiblichen Fehler bringen, damit auch interessierte Leser in Zukunft damit klar kommen. (Daher auch Zitate beigefügt vom sa-mp.com Forum, wenn dieses vorher offline geschaltet werden sollte, als sa-mp.de :P)


    Der Link zu Pastebin wird wahrscheinlich noch lange halten.


    //EDIT: Tippfehler behoben

    Mfg Templer


    >>Dein Breadfish-Thema im Unterforum ScriptingBase / Scriptingwünsche wurde nicht richtig beantworter?<<
    >>Es handelt sich um ein Programmier Problem und du nicht einfach weiter kommst wo der Fehler sein könnte?<<
    Dann melde dich bei mir über die PN-Funktion indem du den Link zu deinem Breadfish-Themen Problem schickst.
    Voraussetzung:
    Thema älter als 1 Tag und im Breadfish Forum gespostet!