Größe eines 2 dimensionalen Arrays auslesen

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
  • Einen wunderschönen guten Abend liebe Breadfish Communtiy,


    wir sind grad mal wieder an unserem Selfmade Projekt am werkeln und haben folgendes Problem.


    Wir lassen unsere Skinauswahl Ingame über eigene Textdraws laufen und wollen folgendes realisieren.


    In einem Array stehen verschiedene Skins für verschiedene Fraktionen:


    new skinChange[][] = {
    {188,0}, //ZiviSkins
    {265,266,267,280,281,282,283,284,288}, //CopSkins
    {171,172,187,194,240}, //FahrschulSkins
    {272,273,292,298} //LosZetasSkins
    };


    Jetzt suchen wir eine Möglichkeit abzufragen wieviele Skins denn in der jeweiligen Zeile stehen, um somit wenn er beim letzten Skin angekommen ist ihn wieder zum ersten zu schicken.
    Bis jetzt sind wir bis hier her gekommen:



    public OnPlayerClickPlayerTextDraw(playerid,PlayerText:playertextid)
    {
    if(playertextid == SkinMenu[playerid][0]) //Links
    {
    new fID;
    fID=sInfo[playerid][fraktion];
    if(GetPVarInt(playerid,"pos")>=0)
    {
    SetPlayerSkin(playerid,skinChange[fID][GetPVarInt(playerid,"pos")]);
    SetPVarInt(playerid,"SkinNew",skinChange[fID][GetPVarInt(playerid,"pos")]);
    SetPVarInt(playerid,"pos",GetPVarInt(playerid,"pos")-1);
    }
    else
    {


    SetPVarInt(playerid,"pos",sizeof(skinChange[fID][])); <---- Hier liegt unser Fehler
    }
    }
    return 1;
    }



    Wir möchten ihm also sagen wenn er am Ende des Arrays angekommen ist fange wieder von an.
    Hat da vielleicht jemand eine Idee?



    Mit freundlichen Grüßen,


    The.Boonze

  • Hallo Jeffry,


    korrigier mich bitte wenn ich falsch liege, wenn ich sizeof(skinChange[]) nehme, liest er mir dann nicht nur die zeilen aus? also in diesem fall 3?
    Ich möchte ja wissen wieviel in den einzelnen zeilen steht.. und sizeof(skinChange[fID][]) geht nicht..


    Mit freundlichen Grüßen,


    The.Boonze

  • Super danke wird direkt mal probiert.


    Mit freundlichen Grüßen,


    The.Boonze


    EDIT: Da fällt mir aber ein wie sage ich ihm nun schaue in der Zeile 2 nach wieviel Spalten dort sind? Weil ich ja mit skinChange[fID][] arbeite.


    Wenn ich nur


    SetPVarInt(playerid,"pos",sizeof(skinChange[]));


    schreibe, kommt folgender Fehler,


    warning 224: indeterminate array size in "sizeof" expression (symbol "")


    Mit freundlichen Grüßen,


    The.Boonze

    Einmal editiert, zuletzt von The.Boonze ()

  • Beitrag von Jeffry ()

    Dieser Beitrag wurde gelöscht, Informationen über den Löschvorgang sind nicht verfügbar.
  • new skinChange[][] = {
    {188,0}, //ZiviSkins
    {265,266,267,280,281,282,283,284,288}, //CopSkins
    {171,172,187,194,240}, //FahrschulSkins
    {272,273,292,298} //LosZetasSkins
    };


    public OnPlayerClickPlayerTextDraw(playerid,PlayerText:playertextid)
    {
    if(playertextid == SkinMenu[playerid][0]) //Links
    {
    new fID;
    fID=sInfo[playerid][fraktion];
    if(GetPVarInt(playerid,"pos")>=0)
    {
    SetPlayerSkin(playerid,skinChange[fID][GetPVarInt(playerid,"pos")]);
    SetPVarInt(playerid,"SkinNew",skinChange[fID][GetPVarInt(playerid,"pos")]);
    SetPVarInt(playerid,"pos",GetPVarInt(playerid,"pos")-1);
    }
    else
    {
    SetPVarInt(playerid,"pos",strlen(skinChange[fID])-1);
    }
    return 1;
    }



    if(playertextid == SkinMenu[playerid][1]) //Rechts
    {
    new fID;
    fID=sInfo[playerid][fraktion];
    if(GetPVarInt(playerid,"pos")<= strlen(skinChange[fID])-1)
    {
    SetPlayerSkin(playerid,skinChange[fID][GetPVarInt(playerid,"pos")]);
    SetPVarInt(playerid,"SkinNew",skinChange[fID][GetPVarInt(playerid,"pos")]);
    SetPVarInt(playerid,"pos",GetPVarInt(playerid,"pos")+1);
    }
    else
    {
    SetPVarInt(playerid,"pos",0);
    }
    return 1;
    }
    }


    Das haut leider so garnicht hin, er schmeißt jetzt egal welche Fraktion alle Skins immer rein. Und auch welche die eigentlich nicht dabei sind ?( ?(


    Mit freundlichen Grüßen,


    The.Boonze

  • Sorry, ich hab dir Müll erzählt. Mit dem jetzt geposteten ganzen Code bin ich erst dahinter gekommen, was du eigentlich genau machen willst. Ich bin komplett auf dem Schlauch gestanden. :wacko:



    Also, folgendes Prinzip:
    Das Array speichert alle Werte untereinander:

    Code
    188
    0
    265
    266
    ...


    Sprich, du kannst auf verschiedene Art und Weisen auf die Werte zugreifen, so komme ich zum Beispiel über [0][3] auf die 266, obwohl die gar nicht in Zeile 0 steht. Das liegt daran, dass das Array die Zeilen nicht interessiert.



    Was du machen kannst ist:
    new skinChange[4][9] = {
    {188,0,-1,-1,-1,-1,-1,-1,-1}, //ZiviSkins
    {265,266,267,280,281,282,283,284,288}, //CopSkins
    {171,172,187,194,240,-1,-1,-1,-1}, //FahrschulSkins
    {272,273,292,298,-1,-1,-1,-1,-1} //LosZetasSkins
    };


    Und dann abfragen, ob die "pos" im nächsten Index -1 ist, falls ja, bist du am Ende dieser Zeile, falls nein, kannst du das nächste Item anzeigen. Oder falls deine "pos" sizeof(skinChange[]) (= 9) ist, bist du auch am Ende. Wichtig ist eben, dass alle Zeilen gleich lang sind.


    Aber bei unterschiedlich Langen "Zeilen" (wir stellen uns das nur als Zeilen vor) in Arrays kannst du die jeweilige Länge nicht direkt abfragen.



    Eine weitere Möglichkeit wäre, die Zahlen in einem String zu speichern, den dann zu splitten und darüber auszulesen, dann würde es theoretisch klappen, das ganze dynamisch aufzubauen.
    Wenn du willst kann ich dir da morgen ein Beispiel dazu machen, bzw. wenn du die erste Methode nimmst, auch dazu.






    EDIT: The.Boonze: Werde ich heute Abend machen, wenn ich Feierabend habe.

    3HZXdYd.png

    Einmal editiert, zuletzt von Jeffry ()

  • Guten Morgen Jeffry,


    ich war gestern dann zu müde und bin schlafen gegangen. Kein Problem zwecks der ganzen Umstände war ja auch spät gestern.


    Dynamisch wäre meiner Meinung nach besser, weil ich ja sonst nach jedem Einfügen eines neuen Skins die anderen Zeilen auch anpassen müsste.. Und das wollte ich eigentlich verhindern :(


    Kannst du mir vielleicht zeigen wie mein Vorhaben mit einem dynamischen System lösbar wäre?


    Mit freundlichen Grüßen,


    The.Boonze

  • Kannst du mir vielleicht zeigen wie mein Vorhaben mit einem dynamischen System lösbar wäre?


    #define MAX_FACTIONS 4
    #define MAX_SKINS 10


    new skinChangeTEXT[MAX_FACTIONS][MAX_SKINS*4 + 1] = {
    {"188 0"}, //ZiviSkins
    {"265 266 267 280 281 282 283 284 288"}, //CopSkins
    {"171 172 187 194 240"}, //FahrschulSkins
    {"272 273 292 298"} //LosZetasSkins
    };


    new skinChange[MAX_FACTIONS][MAX_SKINS];
    new sizeSkinChange[MAX_FACTIONS];


    public OnFilterScriptInit() //Oder eben OnGameModeInit
    {
    for(new fID = 0; fID < MAX_FACTIONS; fID++)
    {
    new tmp[20], idx, i;
    tmp = strtok(skinChangeTEXT[fID], idx);
    while(strlen(tmp))
    {
    skinChange[fID][i] = strval(tmp);
    i++;
    sizeSkinChange[fID]++;
    tmp = "";
    tmp = strtok(skinChangeTEXT[fID], idx);
    }
    }
    return 1;
    }


    Ganz unten in dem GM/FS:
    stock strtok(const string[], &index) //©Jeffry
    {
    new result[20], length = strlen(string), i = index;
    while ((i < length) && (string[i] == ' ')) i++;
    strmid(result,string,i,((index = strfind(string, " ", false, i)) == -1) ? (index = length) : (index) , 20);
    index++;
    return result;
    }




    Und in deinem Menü Code schreibst du anstatt:
    strlen(skinChange[fID])
    das:
    sizeSkinChange[fID]


    Falls du Fragen dazu hast, oder es nicht klappt, sag einfach Bescheid.

  • Hey Jeffry,


    vielen lieben Dank schonmal.
    Ich werde mich jetzt dran setzten und es mal einsetzten und versuchen es zu verstehen.
    Ich melde mich dann nochmal wie weit ich gekommen bin.


    Mit freundlichen Grüßen,


    The.Boonze



    EDIT:


    Also alles eingebaut und getest, funktioniert einwandfrei mit einer kleinen Ausnahme jedoch.
    In jeder Skinauswahl taucht die SKIN ID 0 auf also der CJ Skin, obwohl er ja nur in der Zivi Fraktion eingebaut ist.


    public OnPlayerClickPlayerTextDraw(playerid,PlayerText:playertextid)
    {
    if(playertextid == SkinMenu[playerid][0]) //Links
    {
    new fID;
    fID=sInfo[playerid][fraktion];
    if(GetPVarInt(playerid,"pos")>=0)
    {
    SetPlayerSkin(playerid,skinChange[fID][GetPVarInt(playerid,"pos")]);
    SetPVarInt(playerid,"SkinNew",skinChange[fID][GetPVarInt(playerid,"pos")]);
    SetPVarInt(playerid,"pos",GetPVarInt(playerid,"pos")-1);
    }
    else
    {
    SetPVarInt(playerid,"pos",sizeSkinChange[fID]);
    }
    return 1;
    }



    if(playertextid == SkinMenu[playerid][1]) //Rechts
    {
    new fID;
    fID=sInfo[playerid][fraktion];
    if(GetPVarInt(playerid,"pos")<= sizeSkinChange[fID])
    {
    SetPlayerSkin(playerid,skinChange[fID][GetPVarInt(playerid,"pos")]);
    SetPVarInt(playerid,"SkinNew",skinChange[fID][GetPVarInt(playerid,"pos")]);
    SetPVarInt(playerid,"pos",GetPVarInt(playerid,"pos")+1);
    }
    else
    {
    SetPVarInt(playerid,"pos",0);
    }
    return 1;
    }
    }


    Meine anderen Fragen stell ich dann danach ;)

    Einmal editiert, zuletzt von The.Boonze ()

  • Vielen dank :D


    Wenn ich nun eine neue Fraktion mit neuen Fraktionen einsetzte muss ich:


    new skinChangeTEXT[MAX_FACTIONS][MAX_SKINS*4 + 1] = {
    {"188 0"}, //ZiviSkins
    {"265 266 267 280 281 282 283 284 288"}, //CopSkins
    {"171 172 187 194 240"}, //FahrschulSkins
    {"272 273 292 298"} //LosZetasSkins
    };


    Bei der MAX_SKINS*4 das dann zu MAX_SKINS*5 schreiben oder läuft das alles dynamisch jetzt?


    Mfg The.Boonze


    PS: Gut geschrieben, musste es ein paar mal lesen und im wiki einige Befehle nachschauen bevor ich es verstanden habe :)

  • Nein, du musst nur diesen define ändern, wenn du einen Skin hinzufügen willst. Du kannst es auch gleich auf 100 setzen, aber dann braucht es halt ein paar Bytes mehr Arbeitsspeicher.


    #define MAX_SKINS 10


    Und wenn du eine neue Fraktion willst, den anderen define erhöhen, und einfach wie zuvor eine Zeile dazu machen im Array mit den Skins.

  • Hallo Community,


    ich muss dieses Thema nochmals aufgreifen. Ich habe das selbe Sytsem mal wieder in unserem neuen Skript verwendet und mir sind 2 Sachen aufgefallen


    Wenn ich mich rechts durch meine Skins klicke passt alles, wenn ich mich links durchklicke taucht mal wieder der CJ Skin auf obwohl er in keinem Skin Array steht.
    Weiterhin fällt mir auf wenn ich bei einem Skin beginne und 2 weiter klicke Skin1 Skin2 Skin3 und dann ab Skin3 wieder 2 zurück also Skin3 Skin2 und dann kommt komischerweise wieder Skin3.
    Woran kann sowas liegen?


    Gruß,


    The.Boonze

  • Sorry für die späte Antwort, bin nicht früher dazu gekommen mir das anzuschauen.

    Woran kann sowas liegen?

    Das Problem, bzw. beide Probleme kann ich nicht nachvollziehen, aber versuche es mal so: