Beiträge von Jeffry

    Es sind aber trotzdem globale Variabeln, ich kann 2 globalen Var´s nicht den gleichen Namen geben

    Du könntest beiden Arrays das gleiche enum vergeben. Ist zwar dann für das Array mit den weniger Werten etwas Speicher verschwendet, da einige enum Werte unbelegt bleiben, entspricht dann aber auch deinem Wunsch.

    Er liest den account nicht aus darum muss er sich jeders mal neu regestrieren

    Wenn du mysql_pquery/mysql_tquery nutzt, dann muss der Cache in einem separaten Callback ausgelesen werden, somit kann der Wert nicht mehr zurück gegeben werden.
    Beispiel hier: http://wiki.sa-mp.com/wiki/MySQL/R40#mysql_pquery
    Sowie alle Codes in diesem Tutorial.


    Für deine Funktion könnte man es so machen:


    Eindeutig besser und empfohlen ist:
    stock mysql_CheckAccount(playerid)
    {
    new Query[128];
    mysql_format(handle, Query, sizeof(Query), "SELECT * FROM `users` WHERE `Name` = '%e'", SpielerName(playerid));
    mysql_pquery(handle, Query, "OnAccountChecked", "d", playerid);
    return 1;
    }


    forward OnAccountChecked(playerid);
    public OnAccountChecked(playerid)
    {
    new count;
    cache_get_row_count(count);
    if(count)
    {
    //Hier der Code, der ausgeführt werden soll, wenn der Spieler
    //schon ein Konto hat.
    }
    else
    {
    //Hier der Code, der ausgeführt werden soll, wenn der Spieler
    //kein Konto hat.
    }
    return 1;
    }

    Beide meiner Wege führen zum gleichen Ziel.
    Was du möchtest, zumindest wie ich es verstanden habe, dass ein Spieler zum Beispiel /kaufe Apfel 10 eingeben kann, und dein Code dann nur so ist:
    AddItem(playerid, x, item, amount); //in "item" steht in dem Fall das "Apfel" drin, das der Spieler eingegeben hat


    "item" und "amount" kommen in dem Fall aus sscanf z.B.
    Das klappt mit beiden meiner Wege so.


    Oder meinst du etwas anderes?

    Klappt bei mir auch problemlos.
    Vielleicht sind dort irgendwelche "unsichtbaren" Zeichen? Das hatte ich schon mal, da war ein Zeichen, welches nicht angezeigt wurde, da kam durch die Kopie von einer Webseite.


    Versuche mal das enum und das Array komplett zu löschen, dann zu kompilieren, und dann kopiere dann den Code von deinem Post oben, und füge den dann im Code ein.
    Klappt es dann?

    [19:08:58] [WARNING] mysql_connect: no password specified

    Verbindung ohne Passwort.



    [19:08:58] [ERROR] cache_get_row_count: no active cache

    Hier versuchst du einen Cache auszulesen, ohne zuvor mysql_pquery/mysql_tquery verwendet zu haben.



    Unknown column 'DeaglespawnZeit' in 'field list'

    Das Feld gibt es in deiner Tabelle "users" nicht. Füge das hinzu.



    [19:09:25] [ERROR] mysql_format: no value for specifier '%s' passed

    Ein Platzhalter %s wird in mysql_format nicht gefüllt.



    [19:09:25] [ERROR] error #1065 while executing query "": Query was empty

    Ein leeres Query wird mit mysql_pquery/mysql_tquery gesendet.

    Das geht problemlos mit PVars.
    http://wiki.sa-mp.com/wiki/SetPVarInt


    SetPVarInt(playerid, item, GetPVarInt(playerid, item) + amount);
    Gegebenenfalls für das "x" dem item das noch mitgeben:
    format(item, sizeof(item), "%s%d", item, x);


    Für die globalen Variablen (nicht spielerabhängig) (ItemSpace) kannst du setproperty/getproperty nutzen.
    http://wiki.sa-mp.com/wiki/Setproperty


    Bzw, mit dieser kleinen Include fällt es dir wahrscheinlich leichter, da diese gleich genutzt werden kann, wie PVars:
    http://forum.sa-mp.com/showthread.php?t=479912




    Alternativ ließe sich auch ein Array anlegen, welches die Variablen als String beinhaltet, dazu eine Funktion mit Loop durch das Array, um anschließend damit auf den Index im Player-Array zuzugreifen.
    new varNames[][] = {
    "Banane",
    "Apfel",
    "Birne"
    };


    Sowie:
    stock getVarIdx(item[])
    {
    if(!strlen(item)) return -1;
    for(new i = 0; i < sizeof(varNames); i++)
    {
    if(!strcmp(varNames[i], item)) return i;
    }
    return -1;
    }


    Dann:
    stock AddItem(playerid, x, item[28], amount)
    {
    new idx = getVarIdx(item);
    if(idx == -1) return 0;
    PlayerCar[playerid][x][idx] += amount;
    PlayerCar[playerid][x][idx] += ItemSpace[idx];
    return 1;
    }


    PlayerCar wäre dann so deklariert:
    new PlayerCar[MAX_PLAYERS][MAX_X][MAX_ITEMS];

    Umgeschrieben. Ich hoffe das der Code jetzt etwas besser aussieht und mit den auch arbeiten kann.

    Sieht schon besser aus, nur ist der Code nicht vom Tutorial und daher nicht für R41-4 geeignet.



    Das habe ich Unter OnGameModeInit gepackt:

    Selbiges hier. Das hast du nicht aus dem Tutorial.
    Die Funktion gibt es in R41-4 nicht mal.



    Wo hast du das her und warum nutzt du nicht die Codes aus dem Tutorial, die für R41-4 passend sind?

    Warum 2 unterschiedliche Reifen? :o

    Mischbereifung auf dem BMW 320d. Hab ich bei den Sommerreifen so.
    Ein kleines optisches Merkmal vor allem.


    BMW hat die dämliche Angewohnheit ihre Kunden durch untypische Reifendimensionen und Herstellerbindung um ihr Geld zu erleichtern

    Herstellerbindung wüsste ich nichts von. Gut, die Bridgestone werden empfohlen, aber im Winter fahre ich Pirelli, und auch ohne Mischbereifung, aktuell zumindest.
    Laut CoC dürfte ich auch beidachsig 205/60 R16 fahren, aber wer will das schon xD



    Und weil die Karren sonst die Kraft nicht auf den Asphalt bekommen würden (Stichwort: Heckschleuder)

    Stimmt, schafft ein Fronttriebler aber auch nicht. Deshalb xDrive :D




    Damit das nicht unter Smalltalk hier fällt:
    - Einmal volltanken 32,55l für 39,35€ bei der Shell um's Eck.

    Um nun auch andere Variablen wie z.B. das Gewicht, Funktion und Beschreibung zu beziehen, soll ich dann die Funktion entsprechend umschreiben?

    Ja, entweder du erstellst Funktionen dafür nach gleichem Prinzip (die dann eben Gewicht, etc... zurückgeben), oder du erstellst folgende Funktion:
    stock getItemIndex(id)
    {
    for(new i = 0; i < sizeof(ItemList); i++)
    {
    if(ItemList[i][itemlID] == id)
    {
    return i;
    }
    }
    return -1;
    }


    Das wäre dann etwas performanter, so zuzugreifen, allerdings nur, wenn es zwei oder mehr Eigenschaften des Items betrifft:
    Anstelle von:
    printf("[OnPlayerItemsLoad] itemid: %d | name: %s | amount: %d", Items[playerid][i][itemID], getItemName(Items[playerid][i][itemID]), Items[playerid][i][itemAmount]);
    Wäre es dann:
    new idx = getItemIndex(Items[playerid][i][itemID]);
    if(idx != -1) printf("[OnPlayerItemsLoad] itemid: %d | name: %s | amount: %d", Items[playerid][i][itemID], ItemList[idx][itemlName], Items[playerid][i][itemAmount]);


    Das ist dann allerdings etwas unübersichtlicher.



    Da sich die Anzahl der Items ja in Grenzen hält, würde ich da eher zu etwas unperformanteren - dafür aber übersichtlicheren - Lösung tendieren, einzelne Funktionen "getItem..." zu erstellen.

    Der @Jeffry , wirst du nicht langsam müde von den ganzen helfen ?

    Nein, eigentlich nicht. Ich gebe die Hilfe gerne, wenn es zeitlich passt :)


    Je nach Problem ist es auch zum Teil ganz hilfreich für die generelle Problemanalyse, die über die Jahre angeeignete Denkweise hilft oft auch im Job.
    Dort muss ich mich nämlich öfters auch mal durch ältere Codes arbeiten, diese umschreiben oder analysieren, weil Fehler auftreten.

    Den itemName kannst du aus dem enum "enum_Items" entfernen.
    Dann:
    new Items[MAX_PLAYER_ITEMS][enum_Items];
    zu:
    new Items[MAX_PLAYERS][MAX_PLAYER_ITEMS][enum_Items];


    Und in itemsOnPlayerItemsLoad:
    cache_get_value_name(i, "name", Items[i][itemName], 24);
    entfernen.


    Alle Items[i] zu Items[playerid][i] ändern.
    Über das mysql_tquery gibst du die playerid mit.


    Dann dort:
    printf("[OnPlayerItemsLoad] itemid: %d | name: %s | amount: %d", Items[i][itemID], Items[i][itemName], Items[i][itemAmount]);
    zu:
    printf("[OnPlayerItemsLoad] itemid: %d | name: %s | amount: %d", Items[playerid][i][itemID], getItemName(Items[playerid][i][itemID]), Items[playerid][i][itemAmount]);


    Folgende Funktion unten im Gamemode einfügen:
    stock getItemName(id)
    {
    new str[24];
    format(str, sizeof(str), "?Unbekannt?");
    for(new i = 0; i < sizeof(ItemList); i++)
    {
    if(ItemList[i][itemlID] == id)
    {
    format(str, sizeof(str), ItemList[i][itemlName]);
    break;
    }
    }
    return str;
    }

    Deshalb sollst du dich eingehend mit dem Tutorial beschäftigen.
    Du kannst mir nicht erzählen, dass du das innerhalb von 9 Minuten gemacht hast.


    Wenn du es nicht mal im Ansatz verstehst, dann ist die klare Empfehlung, den Code den du da hast, so zu lassen wie er ist, da du ihn, ohne es zu verstehen, nicht umgeschrieben bekommst. MySQL muss man verstehen, dass passiert auch nicht von heute auf morgen. Man muss sich damit beschäftigen und nicht nur irgendetwas hin kopieren.


    Wenn andernfalls in deinem Code zu sehen ist, dass du dich mit dem Tutorial beschäftigt hast, und die Richtung stimmt, dann macht es auch Sinn dir am Code weiter zu helfen. Aktuell macht das aber keinen Sinn, da du weder Energie rein steckst, noch Interesse daran zeigst, sondern nur auf "schnell schnell" eine Lösung willst.

    Eigentlich alles.
    Und genau das zeigt, dass du dich überhaupt nicht mit dem Tutorial beschäftigt hast. Ansonsten wäre immerhin ein Ansatz der Richtigkeit zu sehen.


    Wie gesagt, beschäftige dich zuerst mit dem Tutorial, eingehend, um die Technik zu verstehen. Im Tutorial ist alles erklärt.

    Mein Problem ist gerade allerdings, wie ich den von dir beschriebenen korrekten Index für das Item bekomme.

    Das kann ich dir so nicht sagen, da ich nicht weiß was du vor hast, und es keinen Code dazu gibt.



    Nebenbei: wie definiere ich MAX_PLAYER_ITEMS so, dass jeder Spieler maximal z.B. 20 verschiedene Items tragen kann.

    [MAX_PLAYERS][MAX_PLAYER_ITEMS]


    Für weitere Fragen zu dem Thema mache bitte einen separaten Thread auf, da es sich bei der Entwicklung eines kompletten Systems nicht um eine kleine Frage handelt.

    Muss ich die ganzen Codes komplett neu schreiben?

    Ja, da die Technik komplett anders zu den alten R5-R7 Versionen ist.
    Das ist nicht mal eben in einer Stunde gemacht.


    Zu empfehlen ist es, sich selbst an Hand des Tutorials ein "selbstgeschriebenes" System zu erstellen, und nicht an einem vorhandenen Gamemode ein fertiges System, welches man nicht kennt, da man es nicht selbst geschrieben hat, umzuschreiben.



    Weiß ich nicht bin mit mysql updaten wirklich nicht erfahren lese mir das Tutorial jetzt schon mehrmals durch und verstehe es nicht.

    Was verstehst du denn am Tutorial nicht?

    Als Beispiel: Ich möchte aus dem Enum "Items" über die 'itemID' den korrekten 'itemName' aus dem Enum "ItemList" herausbekommen.

    Kommt drauf an, wie die Zuweisung stattfindet, sprich welchen Wert itemID hat, den von item1ID, oder den des Indexes.


    Beim Index:
    printf("Name: %s", ItemList[Items[idx][itemID]][item1Name]);


    Beim Wert von item1ID:
    for(new i = 0; i < sizeof(ItemList); i++)
    {
    if(ItemList[i][item1ID] == Items[idx][itemID])
    {
    printf("Name: %s", ItemList[i][item1Name]);
    break;
    }
    }


    idx steht dabei beides mal für den Index aus MAX_PLAYER_ITEMS, der sollte bekannt sein.


    Sinnvoller ist die erste Variante, ebenfalls performanter.

    Du hast dich offensichtlich überhaupt nicht mit dem Tutorial beschäftigt, die Antworten auf alle deine Fragen finden sich im Tutorial.



    Warum das?

    So sieht es richtig aus:
    new row_count;
    cache_get_row_count(row_count);
    if(row_count != 0)


    Ist das so richtig?
    Falls ich das so richtig rausgelesen habe?

    Nein, das ist komplett falsch. Beschäftige dich mit dem Tutorial und arbeite es Schritt für Schritt durch, sonst wirst du die Technik nicht verstehen.
    Kapitel 5 und 6.



    Nichts im Tutorial entweder ich bin blind oder ich weiß es nicht.

    Es ist keine 1:1 Ersetzung. Es muss alle neu geschrieben werden.


    mysql_free_result: Gibt es nicht mehr, da aus Cache gelesen wird.
    mysql_real_escape_string: Wird mit %e in mysql_format gemacht.
    mysql_insert_id: Ist jetzt cache_insert_id


    http://wiki.sa-mp.com/wiki/MySQL/R40