Beiträge von Simon

    Guten Tag


    Ich habe schon seit längerem das Problem, das Textdraw IDs vertauscht werden.


    Die mögliche Ursache habe ich auch schon gefunden, jedoch nur eventuell.


    Wenn ich ein PlayerTextdraw create, hat dieser eine bestimmte id.
    Wenn ich diesen nun wieder zerstöre, behält die Variable "PlayerText:Beispiel" aber den selben Wert (?)
    Wenn ich nun einen neuen PlayerTextdraw erstelle, hat dieser auch wieder eine ID.
    Da ich vorher PlayerText:Beispiel zerstört habe, würde dieser dessen ID einnehmen (?)
    Nun haben PlayerText:Beispiel und PlayerText:Beispiel2 den selben Wert (?)


    Ob es so ist, weiß ich nicht genau, da ich nicht weiß, wie ich mir den Wert der Variablen wiedergeben lassen kann.
    Ich hätte nun folgende Idee: Ich setzte den Wert der Variablen beim zerstören auf -1. Jedoch bekomme ich dann die Error Meldung, dass ich den Typ vertauscht habe (Float, Int...).


    Meine Frage ist nun ob das, was eventuell die Ursache für das Problem ist, sein kann und wie ich das lösen kann.

    selbst damit nicht, habs sogar bis auf 100000 hochgesetzt. es kommt ja noch ein 2. error :S


    //edit: Ich Idiot :D


    Fehler gefunden:


    stock p_CreateDynamicCP(Float:x, Float:y, Float:z, Float:size, worldid = -1, interiorid = -1, playerid = -1, Float:streamdistance = 100.0)
    {
    new cpid = -1;
    if(playerid == -1) p_DestroyAllDynamicCPs();
    else
    {
    if(!IsPlayerConnected(playerid) || !login[playerid] || IsPlayerNPC(playerid)) return -1;
    p_DestroyDynamicCP(playerid);
    }
    cpid = p_CreateDynamicCP(x, y, z, size, worldid, interiorid, playerid, streamdistance); //gibt eine Endlosschleife :D :D


    return cpid;
    }

    Hängt es an einer bestimmten Stelle / wenn man etwas bestimmtes macht?

    Naja ich kann nicht so gut mit Checkpoints. Checkpoints haben keine eindeutige ID, zumindest wüsste ich das nicht das die sowas haben.
    Mit dem Streamerplugin ist es aber möglich Checkpoints eine eindeute ID zu geben und diese abzufragen. Es macht also einiges einfacher.
    Nun bin ich dabei meine Checkpoints dem Streamer anzupassen. ich möchte aber nicht direkt mehrere Checkpoints streamen, sondern einfach nur einen Checkpoint wie vorher erstellen, nur diesesmal mit einer ID. Da das auch wieder nicht so 100% hinhaut, weil Checkpoints numal keine ID haben wie Autos, Objekte, etc.


    Habe es dann so gemacht:


    tock p_CreateDynamicCP(Float:x, Float:y, Float:z, Float:size, worldid = -1, interiorid = -1, playerid = -1, Float:streamdistance = 100.0)
    {
    new cpid = -1;
    if(playerid == -1) p_DestroyAllDynamicCPs();
    else
    {
    if(!IsPlayerConnected(playerid) || !login[playerid] || IsPlayerNPC(playerid)) return -1;
    p_DestroyDynamicCP(playerid);
    }
    cpid = p_CreateDynamicCP(x, y, z, size, worldid, interiorid, playerid, streamdistance);
    return cpid;
    }


    stock p_DestroyAllDynamicCPs()
    {
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    testCP[i] = -1;
    normalCP[i] = -1;
    for(new t = 0; t < 5; t++) tutCP[i][t] = -1;
    }
    DestroyAllDynamicCPs();
    return 1;
    }


    stock p_DestroyDynamicCP(playerid)
    {
    testCP[playerid] = -1;
    normalCP[playerid] = -1;
    for(new t = 0; t < 5; t++) tutCP[playerid][t] = -1;
    DestroyDynamicCP(GetPlayerVisibleDynamicCP(playerid));
    return 1;
    }


    Erklärung: sobald ein Checkpoint für jemand createt wird, werden der vorherige gelöscht. Beim löschen sieht man das ich variablen auf -1 stelle. Hat den Grund das diese Variablen den Wer der Checkpointid haben, dieser Wert der Variablen bleibt aber soweit ich weiß wenn ich den Checkpoint mit dieser ID zerstöre. Deswegen resette ich die einmal und erstelle dann ein neuen Checkpoint.


    Wenn das totaler schwachsinn ist, dann bitte eine einfachere Methode nenen :D Wie gesagt: kann nicht so gut mit Checkpoints :S


    AUfjedenfall bleibt der Server hängen sobald ich ein Checkpoint erstelle. Jedoch erst seitdem ich folgende Zeilen hinzugefügt habe, vorher ging meine Methode wunderbar:


    for(new t = 0; t < 5; t++) tutCP[playerid][t] = -1;
    for(new t = 0; t < 5; t++) tutCP[i][t] = -1;


    Warum genau weiß ich nicht, wollte es mit dem crashdetect herausfinden, jedoch brauche ich mehr Informationen zu den Errormeldungen.

    Guten Tag


    Ich benutze das crashdetect Plugin, da sich mein Script an einer bestimmten Stelle aufgehangen hat.


    Ich bekomme folgende Meldungungen:


    Run time error 3: "Stack/heap collision (insufficient stack size)"
    Run time error 7: "Stack underflow"


    Ich kann damit aber nicht viel anfangen :D


    Eventuell weiß ja einer was genau der Fehler ist.

    Mach doch ein Dialog für beides:


    new pID, vString[100];
    if(sscanf(inputtext, "us", pID, vString))
    {
    SendClientMessage(playerid,FARBE,"Bitte geben Sie die ID und das Verbrechen an!");
    return //Dialog hier anzeigen lassen
    }
    if(!IsPlayerConnected(pID))
    {
    SendClientMessage(playerid,FARBE,"Ungültige Playerid!");


    return //Dialog hier anzeigen lassen
    }
    //weitere Abfragen
    new string[200];
    SendPoliceMessage(ROT, "Polizei Notruf:");
    format(string, sizeof(string), "%s meldet: %s von ID %d", SpielerName(playerid), vString, pID); // Hier
    SendPoliceMessage(ROT, string);
    SendClientMessage(playerid,GREEN,"Du hast das Verbrechen der Polizei gemeldet!");


    //edit:
    Fals nicht vorhanden dann folgendes (am besten ganz unten) ins Script:


    stock sscanf(string[], format[], {Float,_}:...)
    {
    #if defined isnull
    if (isnull(string))
    #else
    if (string[0] == 0 || (string[0] == 1 && string[1] == 0))
    #endif
    {
    return format[0];
    }
    #pragma tabsize 4
    new
    formatPos = 0,
    stringPos = 0,
    paramPos = 2,
    paramCount = numargs(),
    delim = ' ';
    while (string[stringPos] && string[stringPos] <= ' ')
    {
    stringPos++;
    }
    while (paramPos < paramCount && string[stringPos])
    {
    switch (format[formatPos++])
    {
    case '\0':
    {
    return 0;
    }
    case 'i', 'd':
    {
    new
    neg = 1,
    num = 0,
    ch = string[stringPos];
    if (ch == '-')
    {
    neg = -1;
    ch = string[++stringPos];
    }
    do
    {
    stringPos++;
    if ('0' <= ch <= '9')
    {
    num = (num * 10) + (ch - '0');
    }
    else
    {
    return -1;
    }
    }
    while ((ch = string[stringPos]) > ' ' && ch != delim);
    setarg(paramPos, 0, num * neg);
    }
    case 'h', 'x':
    {
    new
    num = 0,
    ch = string[stringPos];
    do
    {
    stringPos++;
    switch (ch)
    {
    case 'x', 'X':
    {
    num = 0;
    continue;
    }
    case '0' .. '9':
    {
    num = (num << 4) | (ch - '0');
    }
    case 'a' .. 'f':
    {
    num = (num << 4) | (ch - ('a' - 10));
    }
    case 'A' .. 'F':
    {
    num = (num << 4) | (ch - ('A' - 10));
    }
    default:
    {
    return -1;
    }
    }
    }
    while ((ch = string[stringPos]) > ' ' && ch != delim);
    setarg(paramPos, 0, num);
    }
    case 'c':
    {
    setarg(paramPos, 0, string[stringPos++]);
    }
    case 'f':
    {


    new changestr[16], changepos = 0, strpos = stringPos;
    while(changepos < 16 && string[strpos] && string[strpos] != delim)
    {
    changestr[changepos++] = string[strpos++];
    }
    changestr[changepos] = '\0';
    setarg(paramPos,0,_:floatstr(changestr));
    }
    case 'p':
    {
    delim = format[formatPos++];
    continue;
    }
    case '\'':
    {
    new
    end = formatPos - 1,
    ch;
    while ((ch = format[++end]) && ch != '\'') {}
    if (!ch)
    {
    return -1;
    }
    format[end] = '\0';
    if ((ch = strfind(string, format[formatPos], false, stringPos)) == -1)
    {
    if (format[end + 1])
    {
    return -1;
    }
    return 0;
    }
    format[end] = '\'';
    stringPos = ch + (end - formatPos);
    formatPos = end + 1;
    }
    case 'u':
    {
    new
    end = stringPos - 1,
    id = 0,
    bool:num = true,
    ch;
    while ((ch = string[++end]) && ch != delim)
    {
    if (num)
    {
    if ('0' <= ch <= '9')
    {
    id = (id * 10) + (ch - '0');
    }
    else
    {
    num = false;
    }
    }
    }
    if (num && IsPlayerConnected(id))
    {
    setarg(paramPos, 0, id);
    }
    else
    {
    #if !defined foreach
    #define foreach(%1,%2) for (new %2 = 0; %2 < MAX_PLAYERS; %2++) if (IsPlayerConnected(%2))
    #define __SSCANF_FOREACH__
    #endif
    string[end] = '\0';
    num = false;
    new
    name[MAX_PLAYER_NAME];
    id = end - stringPos;
    foreach (Player, playerid)
    {
    GetPlayerName(playerid, name, sizeof (name));
    if (!strcmp(name, string[stringPos], true, id))
    {
    setarg(paramPos, 0, playerid);
    num = true;
    break;
    }
    }
    if (!num)
    {
    setarg(paramPos, 0, INVALID_PLAYER_ID);
    }
    string[end] = ch;
    #if defined __SSCANF_FOREACH__
    #undef foreach
    #undef __SSCANF_FOREACH__
    #endif
    }
    stringPos = end;
    }
    case 's', 'z':
    {
    new
    i = 0,
    ch;
    if (format[formatPos])
    {
    while ((ch = string[stringPos++]) && ch != delim)
    {
    setarg(paramPos, i++, ch);
    }
    if (!i)
    {
    return -1;
    }
    }
    else
    {
    while ((ch = string[stringPos++]))
    {
    setarg(paramPos, i++, ch);
    }
    }
    stringPos--;
    setarg(paramPos, i, '\0');
    }
    default:
    {
    continue;
    }
    }
    while (string[stringPos] && string[stringPos] != delim && string[stringPos] > ' ')
    {
    stringPos++;
    }
    while (string[stringPos] && (string[stringPos] == delim || string[stringPos] <= ' '))
    {
    stringPos++;
    }
    paramPos++;
    }
    do
    {
    if ((delim = format[formatPos++]) > ' ')
    {
    if (delim == '\'')
    {
    while ((delim = format[formatPos++]) && delim != '\'') {}
    }
    else if (delim != 'z')
    {
    return delim;
    }
    }
    }
    while (delim > ' ');
    return 0;
    }

    Damit wird es gespeichert und ausgelesen wird es auch, sollte es zumindest.


    Nun musst du einfach an der Stelle wo er auf seine alten position gesetzt werden soll folgendes machen:

    SetPlayerPos(playerid,SpielerInfo[playerid][PosX],SpielerInfo[playerid][PosY],SpielerInfo[playerid][PosZ]);
    SetPlayerFacingAngle(playerid,SpielerInfo[playerid][PosA]);
    SetPlayerInterior(playerid, SpielerInfo[playerid][Interior]);


    //edit:


    Also in der Tabelle steht immer 0..

    Wie sind denn die Eigenschaften der Spalten für die Position?

    genau :D


    du musst die Zeilen löschen in denen sowas Steht:


    GangZoneCreate(...);
    GangZoneShowForPlayer(...);


    Du wirst dann wohl warnings bekommen wie "Variable wird nie benutzt". Du musst natürlich auch die Variablen der Gangzonen löschen

    was für Errors kommen denn?


    such mal sowas wie GangZoneCreate.


    Du musst dann nur alles was damit zu tun hat löschen, GangZoneShowForPlayer und die variablen auch.

    stock SavePlayer(playerid)
    {
    if(IsPlayerConnected(playerid) && !IsPlayerNPC(playerid)) //wir überprüfen ob der Spieler überhaupt noch Connected ist und ob er nicht ein NPC ist.
    {
    if(GetPVarInt(playerid,"Eingeloggt") == 1) //Und hier ob er noch eingeloggt ist.
    {
    //Nun speichern wir die Daten in der Datenbank.
    mysql_SetInt("accounts", "Registriert", SpielerInfo[playerid][Registered], "Name", SpielerInfo[playerid][Name]);


    new Float: PosXX, Float: PosYY, Float: PosZZ, Float: PosAA;
    GetPlayerPos(playerid, PosXX, PosYY, PosZZ);
    GetPlayerFacingAngle(playerid, PosAA);


    mysql_SetInt("accounts", "Stufe", GetPlayerScore(playerid), "Name", SpielerInfo[playerid][Name]);
    mysql_SetInt("accounts", "Skin", SpielerInfo[playerid][Skin], "Name", SpielerInfo[playerid][Name]);
    mysql_SetInt("accounts", "Geld", GetPlayerMoney(playerid), "Name", SpielerInfo[playerid][Name]);
    mysql_SetInt("accounts", "AdminRank", SpielerInfo[playerid][AdminRank], "Name", SpielerInfo[playerid][Name]);
    mysql_SetInt("accounts", "Warnings", SpielerInfo[playerid][Warnings], "Name", SpielerInfo[playerid][Name]);
    mysql_SetInt("accounts", "Gemutet", SpielerInfo[playerid][Muted], "Name", SpielerInfo[playerid][Name]);
    mysql_SetInt("accounts", "Gebannt", SpielerInfo[playerid][Banned], "Name", SpielerInfo[playerid][Name]);


    mysql_SetInt("accounts", "Interior", GetPlayerInterior(playerid), "Name", SpielerInfo[playerid][Name]);
    mysql_SetFloat("accounts", "PosX", PosXX, "Name", SpielerInfo[playerid][Name]);
    mysql_SetFloat("accounts", "PosY", PosYY, "Name", SpielerInfo[playerid][Name]);
    mysql_SetFloat("accounts", "PosZ", PosZZ, "Name", SpielerInfo[playerid][Name]);
    mysql_SetFloat("accounts", "PosA", PosAA, "Name", SpielerInfo[playerid][Name]);


    mysql_SetInt("accounts", "Fraktion", FraktionInfo[playerid][Mitglied], "Name", SpielerInfo[playerid][Name]);
    mysql_SetInt("accounts", "FraktionLeitung", FraktionInfo[playerid][Leitung], "Name", SpielerInfo[playerid][Name]);
    }
    }
    return 1;
    }

    Ich würde das Datum speichern und dir eine Funktion schreiben die aus jeden Datum das Alter errechnet bis zum heutigen Tag.


    Sowas wie GetAge(day, month, year);


    Ein bisschen rechnen und fertig ;)

    Genau sowas hatte ich mal gelesen :D


    Ich verwende 2-3 Timer. der eine Timer hat ein Interval von 1000. In welchen abständen tritt den OnPlayerUpdate auf.


    Ist es denn sinnvoller das Anticheatsystem mit OnPlayerUpdate zu scripten?

    Guten Tag


    Sicher kennen viele OnPlayerUpdate :D


    Es wird immer gesagt, dass man es nicht nutzen soll, deswegen habe ich es seit ich scripte nie benutzt.
    Ich würde mal gerne wissen warum man es denn nicht nutzen soll, da es bestimmt auch Gutes hat.
    Wann wird es denn überhaupt verwendet? Nach einer bestimmten Zeit, bei einer bestimmten Handlung?
    Und wie kann man es sinnvoll nutzen?


    Da man es mal so hört und dann wieder so, würde ich gerne hier fragen was eigentlich "gut" und "schlecht" an diesem Public ist und ob man es nun nutzen sollte oder nicht.


    Liebe Grüße

    joa genau :D


    Mit Textdraws kann man sehr viel anstellen. Dialoge kann man nachbauen und so gestalten wie man möchte, mit eigenen Feldern die man anklicken kann.


    Was ich viel wichtiger finde sind so ein paar Einstellungen wie das Deaktivieren von Werkstädten (Pay n Spray, Transfender, etc) oder der Spawnauswahl beim connecten.
    Dann vorhandene Dinge erweitern, so wie es mit den Cams gemacht wurde. man kann alles mögliche an irgentwas drannehängen. Objekte an Spieler, Fahrzeuge, Objecte, etc.
    Das selbe gilt für 3d texte oder autos. Das könnte man noch erweitern, man könnte zum Beispiel sounds an irgentetwas drankleben.


    Wie es auch hier schon gewünscht wurde könnte man dieses Anklicken von Objekten erweitern, so das man unter anderem auch Fahrzeuge anklicken kann.


    Dann noch solche kleinen Einstellung wie das Anzeigen des HUDs oder der Minimap, das De und Aktivieren von Getränke automaten.


    Das würde ich viel schöner finden :)