Denkanstoß bei Privatfahrzeugen.

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
  • Hallo Leute,


    ich brauche etwas Hilfe, bzw. einen Denkanstoß beim erstellen von Privatfahrzeugen.


    Ich hatte eigentlich vor, dass jeder Spieler 3 Fahrzeuge besitzen kann, die in einer extra Tabelle erstellt, geladen und gespeichert werden.
    Diese Tabelle soll alle Privatfahrzeuge von jedem Spieler beinhalten.


    Wenn ein Spieler Online geht, werden die Fahrzeuge des Spielers da erstellt wo sie mit /park geparkt wurden, wenn ein Spieler Offline geht werden die Fahrzeuge vom Spieler abgespeichert & zerstört.


    Nun stehe ich unter anderen vor dem Problem die Fahrzeuge eines bestimmten Spieler auf der Tabelle abzurufen,
    daher wäre es nett, wenn mir jemand einen Denkanstoß geben könnte.




    Gruß
    AlphaGen!

    DIVIDE ET IMPERA

  • Das ist eigl recht simple, beim abspeichern den Usernamen als besitzer in die mysql schreiben und dann beim auslesen eben über den Usernamen


    Ich habs mal hiermit probiert, es wird allerdings immer nur ein Fahrzeug erstellt.

    stock LoadPlayerVehicle(playerid)
    {
    new string[16], name[MAX_PLAYER_NAME]; GetPlayerName(playerid,name,sizeof(name));
    if(IsPlayerConnected(playerid) && !IsPlayerNPC(playerid))
    {
    GetPlayerName(playerid, SpielerVehInfo[playerid][pvBesitzer], MAX_PLAYER_NAME);
    SpielerVehInfo[playerid][pvKennzeichen] = mysql_GetInt("privatfahrzeuge", "Kennzeichen", "Besitzer", SpielerVehInfo[playerid][pvBesitzer]);
    SpielerVehInfo[playerid][pvModel] = mysql_GetInt("privatfahrzeuge", "Model", "Besitzer", SpielerVehInfo[playerid][pvBesitzer]);
    SpielerVehInfo[playerid][pvPosX] = mysql_GetFloat("privatfahrzeuge", "PosX", "Besitzer", SpielerVehInfo[playerid][pvBesitzer]);
    SpielerVehInfo[playerid][pvPosY] = mysql_GetFloat("privatfahrzeuge", "PosY", "Besitzer", SpielerVehInfo[playerid][pvBesitzer]);
    SpielerVehInfo[playerid][pvPosZ] = mysql_GetFloat("privatfahrzeuge", "PosZ", "Besitzer", SpielerVehInfo[playerid][pvBesitzer]);
    SpielerVehInfo[playerid][pvPosA] = mysql_GetFloat("privatfahrzeuge", "PosA", "Besitzer", SpielerVehInfo[playerid][pvBesitzer]);
    format(string,sizeof(string),"%d",SpielerVehInfo[playerid][pvKennzeichen]);
    SetVehicleNumberPlate(CreateVehicle(SpielerVehInfo[playerid][pvModel], SpielerVehInfo[playerid][pvPosX], SpielerVehInfo[playerid][pvPosY], SpielerVehInfo[playerid][pvPosZ], SpielerVehInfo[playerid][pvPosA], 1, 1, -1),string);
    }
    return 1;
    }

    DIVIDE ET IMPERA

  • Pille und wie identifizierst du die autos beim speichern?
    Wenn da da WHERE `Name` = 'AlphaGen' benutzt schreibst du in alle 3 spalten das selbe...

  • gib jedem fahrzeug eine slot id auch in die tabelle mit, so kannst du mehrere Fahrzeuge identifizieren.


    Das wäre doch mit den Kennzeichen möglich, die Kennzeichen fangen in der Tabelle bei 1 an und erhöhen sich bei jeden Fahrzeug welches in die Tabelle eingetragen wird um 1.
    Nur wie ich das machen soll weiß ich nicht. :S

    DIVIDE ET IMPERA

  • Und was machst du wenn jemand 2 mal das selbe Fahrzeug kauft?


    Man muss natürlich überprüfen wieviel Autos der User bereits hat,
    das ist aber mit einem neuen Query ganz einfach...


    SQL
    SELECT COUNT(*) FROM `privatfahrzeuge` WHERE Name = 'AlphaGen'
    -- 0 = kein Fahrzeug
    -- 1 = ein Fahrzeug
    -- 2 = zwei Fahrzeuge
    -- 3 = drei Fahrzeuge
  • Jaja immer die Sache mit dem Primärschlüssel :D


    Ich würde ein Relationenschema folgendermaßen aufbauen:


    Fahrzeuge = {Eintrag,Spieleridentifikation,Model,...}


    Das bietet die Möglichkeit, dass ein Spieler das exakt gleiche Auto besitzt, eventuell sogar das gleiche Kennzeichen. Sollte nämlich mal alles gleich sein und kein Attribut Eintrag o.Ä vorhanden sein, wird das Fahrzeug nicht erstellt.
    Die einzelnen Tupel unterscheiden sich nur durch den Primärschlüssel Eintrag, welcher durch Auto Increment hochgezählt werden kann.


    Aus deiner SpielerRelation kannst du z.B. den Namen oder auch eine ID (wenn du eine speicherst, aber Name dürfte einfacher sein) als Fremschlüssel für Fahrzeuge(Spieleridentifikation) nutzen.


    edit:
    Desweiteren würde ich keine Funktion wie
    mysql_GetFloat("privatfahrzeuge", "PosZ", "Besitzer", SpielerVehInfo[playerid][pvBesitzer]);
    nutzen, da diese meiner Meinung nach einfach zu steif sind. Man kann damit eigentlich nur bei Querys mit LIMIT 1 arbeiten.
    Anstattdessen mach den Query einfach in deine stock Funktion und lies alle Tupel via while oder for schleife aus.


  • Das ist wahrscheinlich ziehmlich hübsch erklärt, aber leider habe ich nur maximal die hälfte verstanden, ich bin mit Mysql allgemein noch nicht so wirklich vertraut.
    Könntest Du mir vielleicht den Aufbau davon zeigen?

    DIVIDE ET IMPERA

  • Table in der MYSQL:

    Code
    CREATE TABLE IF NOT EXISTS `fahrzeuge` (
      `id` int(4) NOT NULL AUTO_INCREMENT,
      `spieler` varchar(24) NOT NULL,
      `model` int(4) NOT NULL,
      `xPos` float NOT NULL,
      `yPos` float NOT NULL,
      `zPos` float NOT NULL,
      `angle` float NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;


    Im Grunde heißt es fürs Script erstmal nur: "Nutze nicht deine stock Funktionen zum auslesen von Werten (zumindest nicht in dieser Situation)
    Ich würde das so machen (mit Strickenkid, ka ob du BlueG benutzt)



    stock LoadPlayerVehicle(playerid)
    {
    new query[128],playername[24];
    GetPlayerName(playerid,playername,sizeof(playername);
    format(query,sizeof(query),"SELECT * FROM `fahrzeuge` WHERE `besitzer` = 's'",playername);
    mysql_query(query);
    mysql_store_result();
    if(mysql_num_rows() == 0) return 1; // keine Fahrzeuge da
    new data[64];
    while(mysql_fetch_row(data))
    {
    new field[12 /*erhöhen wenn mehr Attribute in der MYSQL Table stehen*/][32];
    spliter(data, field, '|');

    // in field[0] steht nun das erste Attribut aus der MYSQL, das brauchen wir nicht, da es die Identifikation des Tupels ist
    // in field[1] steht der Spielername. Den brauchen wir auch nicht, da wir ihn schon kennen
    // alle weiteren Fields sind Parameter des Autos und werden benötigt. Diese liegen hier erstmal als String vor, müssen also wenn sie als Integer benötigt werden gecastet werden (strval(field[]) oder wenn als Float( floatstr(field[])
    // nach obigem Tabellenansatz ergibt sich folgendes:
    new veh = CreateVehicle(strval(field[2]),floatstr(field[3]),floatstr(field[4]),floatstr(field[5]),floatstr(field[6]).....);
    // mit veh kannst du jetzt weiterarbeiten und z.B. auch das Nummernschild setzen, den besitzer setzen (mit nem Array fbesitzer[MAX_VEHICLES])
    }
    }
    edit: die spliter Funktion:
    stock spliter(const strsrc[], strdest[][], delimiter)
    {
    new i, li;
    new aNum;
    new len;
    while(i <= strlen(strsrc))
    {
    if(strsrc[i] == delimiter || i == strlen(strsrc))
    {
    len = strmid(strdest[aNum], strsrc, li, i, 128);
    strdest[aNum][len] = 0;
    li = i+1;
    aNum++;
    }
    i++;
    }
    return 1;
    }


    edit2: Du kannst natürlich auch erstmal alle Attribute in dein Array speichern:

    SpielerVehInfo[playerid][pvBesitzer] = playername
    SpielerVehInfo[playerid][pvModel] = floatstr(field[2]);
    SpielerVehInfo[playerid][pvPosX] = floatstr(field[3]);
    SpielerVehInfo[playerid][pvPosY] = floatstr(field[4]);
    SpielerVehInfo[playerid][pvPosZ] = floatstr(field[5]);
    SpielerVehInfo[playerid][pvPosA] = floatstr(field[6]);



  • Danke für die Vorlage, damit konnte ich mich wenigstens etwas zurecht finden


    stock LoadPlayerVehicle(playerid)
    {
    new data[64], query[128], name[MAX_PLAYER_NAME]; GetPlayerName(playerid,name,sizeof(name));
    format(query,sizeof(query),"SELECT * FROM `privatfahrzeuge` WHERE `Besitzer` = '%s'",name);
    mysql_query(query); mysql_store_result();
    if(mysql_num_rows() == 0) return 1;
    while(mysql_fetch_row(data))
    {
    new field[7][24]; split(data, field, '|');
    CreateVehicle(strval(field[2]),floatstr(field[3]),floatstr(field[4]),floatstr(field[5]),floatstr(field[6]),floatstr(field[7]), 1, 1, -1);
    }
    return 1;
    }


    new field[7][24];
    Mit sowas habe ich mich bisher noch nicht befasst, ich gehe aber mal davon aus, dass [24] als sizeof dient?


    Desweiteren kamen einige Fehlermeldungen, die ich alle bis auf einer im handumdrehen beheben konnte.
    Folgendes kommt beim Compilen:

    Code
    C:\Users\Vega\Desktop\MySQL-Server SAMP\gamemodes\Script1.pwn(150840) : error 032: array index out of bounds (variable "field")


    Und das ist die Zeile:
    new field[7][24]; split(data, field, '|');

    DIVIDE ET IMPERA