KM Zähler funktioniert nicht so wie er soll...

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
  • Moin / Nabend liebe Community,


    ich benutze auf Empfehlung das KM Include:


    https://forum.sa-mp.com/showthread.php?t=404367


    Meine Codeschnipsel:


    Hier wird der Timer zum Aktualisieren Gestartet beim Anschalten und gekillt beim abschalten.

    Problem ist jetzt folgendes:


    Wenn ich als einziger Spieler (Playerid 0) auf dem Server bin und fahre läuft alles super, doch sobald ein zweiter Spieler (Sandbox) drauf ist, in einem Fahrzeug sitzt MOTOR ist allerdings AUS und ich fahre mit playerid 0 weiter zählt er mehr km als normal ist... Zumal wenn ich mit PlayerID 0 stehen bleibe (egal ob Motor an oder aus), der KM Stand geht immer weiter ...


    Ich hoffe es war einigermaßen verständlich ^^


    MfG
    XonarZ

  • Ehh wieso setzt du die Kilometer nochmal?


    Du kannst doch einfach mit GetKilometers diese Verwenden, die werden doch automatisch gesetzt :o

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S

  • ich setze die KM nicht 2x ... das setVehicleKM sind die Textdraws ... haben meiner Meinung nach nix damit zu tun, dass der weiterzählt sobald 2 spieler in einem auto sitzen und einer davon nen timer am laufen hat oder ?


    MfG
    XonarZ


    #Handy

  • kmstand[vID] += GetKilometers(vID);
    setVehicleKM(playerid, vID);

    Da setzt du das doch jeweils...wieso?


    Wieso +=?


    Das erhöht sich doch schon automatisch.



    new vID = GetPlayerVehicleID(i);
    if(!IsPlayerInVehicle(i, vID)) continue;

    Das ist übrigens auch eine sehr komische Abfrage ^^


    Schreib da einfach if(!vID) continue;

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S

  • Ich vermute mal, das liegt daran, dass du den Timer mehrfach startest.
    Wie und wo startest du denn den Timer? Vermutlich bei OnPlayerConnect?


    Grundsätzlich müsstest du setKiloMeter nur einmal bei OnGameModeInit starten, die playerid aus dem Kopf nehmen und im Code von setKiloMeter alle "playerid" mit "i" ersetzen. Zusätzlich müsstest du noch die Abfrage einbauen, ob der Motor auch an ist.

  • Beitrag von Jeffry ()

    Dieser Beitrag wurde von Canna aus folgendem Grund gelöscht: Doppelpost ().
  • Da setzt du das doch jeweils...wieso?


    Wieso +=?


    Das erhöht sich doch schon automatisch.

    Naja nicht wirklich... kmstand[MAX_VEHICLES] ist ja eine globale Variable, diese wird auch gesetzt mit dem Wert aus der Datenkbank sobald der Spieler sich einloggt... Dann ist es so, dass ich mit GetKilometers(vehicleid) die distance "auslese" und meiner globalen Variable addiere ... ich glaube nämlich, dass GetKilometers auf 0 gesetzt wird sobald der Server restartet und dann wäre der KMStand ja immer 0... Desweiteren kommt nach meinem setVehicleKM, ein ResetMetersTraveled ... Sprich ich resette den auf 0 um einfach immer nur die 0... km zu addieren.


    Hier mal mein Stock setVehicleKM:

    Code
    stock setVehicleKM(playerid){
    	new vID = getCarID(playerid), string[256];
    	if(vID == INVALID_VEHICLE_ID) vID = GetPlayerVehicleID(playerid);
    	format(string, sizeof(string), "%0.2f km", kmstand[vID]);
       	PlayerTextDrawSetString(playerid, Tacho_TD[playerid][6], string);
    	return 1;
    }

    Ich rufe den Stock nur auf wenn ich ein Fahrzeug betrete damit er den Textdraw setzt ...



    Ich vermute mal, das liegt daran, dass du den Timer mehrfach startest.
    Wie und wo startest du denn den Timer? Vermutlich bei OnPlayerConnect?

    Ne nur beim Motor starten, ansonsten rufe ich den Stock auf beim einsteigen wie gesagt...



    Grundsätzlich müsstest du setKiloMeter nur einmal bei OnGameModeInit starten, die playerid aus dem Kopf nehmen und im Code von setKiloMeter alle "playerid" mit "i" ersetzen. Zusätzlich müsstest du noch die Abfrage einbauen, ob der Motor auch an ist.

    Hm okay, aber würde es nicht mehr sinn machen, den Timer nur dann laufen zu lassen, wenn der Motor auch startet ? Weil ich hab ja schon den Timer mit dem tankLost ... geht das nicht iwie auf die Perfomance wenn ich 2 Timer permanent laufen lasse? Immerhin sollen ja nur KM gezählt werden, sobald der Motor an ist... Versteh ich irgendwas falsch ?


    //EDIT Mir ist auch aufgefallen, dass sobald 1 Spieler im Auto sitzt und rumfährt, dass beim Spieler 2 der auch rumfährt, dass der KM Stand nicht addiert wird, da passiert einfach gar nix.


    MfG
    XonarZ

    Einmal editiert, zuletzt von XonarZ ()

  • Ist schon n bisschen her, aber ich hatte sowas auch mal geschrieben gehabt: Kilometer Anzeige / Berechnung


    Da wird das automatisch in SQLite (gespeichert + geladen) & berechnet ^^


    Dort brauchst du nur über die jeweilige Funktion dem Spieler das anzeigen lassen :D


    Dann brauchste aber kein eigenes Schnick Schnack :)

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S

  • Danke dir ... aber ich kann nicht versichern, dass die Vehicle ID's gleich bleiben, da ich gerade noch am Anfang bin und vorallem, die KM Stände von Jobcars die ich später Implementiere sollen nicht gespeichert werden ... :whistling:

  • Immerhin sollen ja nur KM gezählt werden, sobald der Motor an ist... Versteh ich irgendwas falsch ?

    Das stimmt schon, nur hast du im Callback eine Schleife durch alle Spieler. Hast du den Timer jetzt für mehrere Spieler gestartet, dann wird das alles mehrmals für alle Spieler gemacht.


    Das Callback sollte so aussehen:
    forward setKiloMeter();
    public setKiloMeter()
    {
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(!IsPlayerConnected(i) || !pInfo[i][pLoggedIn])continue;
    if(GetPlayerState(i) != PLAYER_STATE_DRIVER) continue;
    new vID = GetPlayerVehicleID(i);
    if(vID && GetKilometers(vID) > 0)
    {
    printf("%i, %0.2f", vID, kmstand[vID]);
    kmstand[vID] += GetKilometers(vID);
    setVehicleKM(playerid, vID);
    ResetMetersTraveled(vID);
    }
    }
    return 1;
    }
    Und dann kannst du den Timer bei OnGameModeInit starten:
    SetTimer("setKiloMeter", 1000, true);
    Sonst bitte nirgends.
    Dann brauchst du ihn auch nirgends beenden.

  • Hab ich jetzt so probiert, wie du es vorgeschlagen hast...


    Leider ist es immer noch nicht so ganz... Ich versuchs mal zu Beschreiben xD^^ (vielleicht sollte ich ein Video machen xD)


    Wenn nur 1 Spieler Online ist, dann funktioniert es so wie es soll... Motor an und sobald man fährt, steigt der kmstand.


    Ab 2 Spieler:


    Spieler 1 Sitzt im Auto (Spieler 2 NICHT) und ist paar Meter gefahren (kmstand erhöht sich)
    Spieler 1 & 2 Sitzen jeweils in einem Auto als Fahrer. Der Motor bei Spieler 1 ist aus, fahre ich nun mit Spieler 2 los passiert gar nix. Wenn ich mit Spieler 1 Fahre, dann ist der KMStand auf einmal der, den Spieler 2 haben müsste (also wird kleiner).


    Man ist das kompliziert zu erklären oder / und ich bin einfach zu dumm :D

  • Gut erklärt, ich verstehe das Problem, kann es nur am Code nicht wirklich nachvollziehen.
    Kannst du es bitte mal so schreiben:
    forward setKiloMeter();
    public setKiloMeter()
    {
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(!IsPlayerConnected(i) || !pInfo[i][pLoggedIn])continue;
    if(GetPlayerState(i) != PLAYER_STATE_DRIVER) continue;
    new vID = GetPlayerVehicleID(i);
    if(vID && GetKilometers(vID) > 0)
    {
    kmstand[vID] += GetKilometers(vID);
    printf("%d / vID: %i, Total: %0.2f, Add: %0.2f, i: %i", GetTickCount(), vID, kmstand[vID], GetKilometers(vID), i);
    setVehicleKM(i, vID);
    ResetMetersTraveled(vID);
    }
    }
    return 1;
    }


    Was wird dann im Log geprintet, wenn du obigen Fehlerfall nochmal durchspielst?

  • Gut erklärt, ich verstehe das Problem, kann es nur am Code nicht wirklich nachvollziehen.
    Kannst du es bitte mal so schreiben:
    forward setKiloMeter();public setKiloMeter(){ for(new i = 0; i < MAX_PLAYERS; i++) { if(!IsPlayerConnected(i) || !pInfo[i][pLoggedIn])continue; if(GetPlayerState(i) != PLAYER_STATE_DRIVER) continue; new vID = GetPlayerVehicleID(i); if(vID && GetKilometers(vID) > 0) { kmstand[vID] += GetKilometers(vID); printf("%d / vID: %i, Total: %0.2f, Add: %0.2f, i: %i", GetTickCount(), vID, kmstand[vID], GetKilometers(vID), i); setVehicleKM(i, vID); ResetMetersTraveled(vID); } } return 1;}


    Was wird dann im Log geprintet, wenn du obigen Fehlerfall nochmal durchspielst?


    Als ich dann mit "testuser" los gefahren bin, hing der Server komplett erst als ich den Server mit "testuser" verlassen habe, kamen die sachen ab Zeile 85


    MfG
    XonarZ

  • Kannst du es bitte hiermit nochmals testen:
    forward setKiloMeter();
    public setKiloMeter()
    {
    printf("Call: %d", gettime());
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(!IsPlayerConnected(i) || !pInfo[i][pLoggedIn])continue;
    if(GetPlayerState(i) != PLAYER_STATE_DRIVER) continue;
    new vID = GetPlayerVehicleID(i);
    if(!vID) continue;
    printf("vID: %d, Motor: %d", vID, motor[vID]);
    if(motor[vID] == 0 || motor[vID] == -1) continue;
    if(GetKilometers(vID) > 0)
    {
    kmstand[vID] += GetKilometers(vID);
    printf("vID: %i, Total: %0.2f, Add: %0.2f, i: %i", vID, kmstand[vID], GetKilometers(vID), i);
    setVehicleKM(i, vID);
    ResetMetersTraveled(vID);
    }
    }
    return 1;
    }


    Bitte auch etwas länger für den zweiten User.
    Aufhängen sollte sich der Server dadurch eigentlich nicht.



    Du startest den Timer auch wirklich nur noch unter OnGameModeInit?

  • Ab Total: 2.67 bin ich stehen geblieben und er hat weiter gezählt.


    Ja ich starte den nur bei OnGameModeInit ^^


    MfG
    XonarZ

  • Ich habe mir die Include grade mal angeschaut. Der Fehler liegt dort. Selbstverständlich werde ich auf diese auch nicht mehr verweisen.
    Die Include funktioniert nur mit einem Fahrzeug. Ich spare mir, diese umzuschreiben, da dein Timer das meiste schon von sich erledigen kann:


    Wirf bitte die Include aus deinem Code und versuche folgendes:
    Unter den Includes:
    new Float:v_oldPos[MAX_VEHICLES][3];


    Timer:
    forward setKiloMeter();
    public setKiloMeter()
    {
    printf("Call: %d", gettime());
    new Float:km;
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(!IsPlayerConnected(i) || !pInfo[i][pLoggedIn])continue;
    if(GetPlayerState(i) != PLAYER_STATE_DRIVER) continue;
    new vID = GetPlayerVehicleID(i);
    if(!vID) continue;
    printf("vID: %d, Motor: %d", vID, motor[vID]);
    if(motor[vID] == 0 || motor[vID] == -1) continue;
    if(GetKilometers(vID) > 0)
    {
    km = GetVehicleDistanceFromPoint(vID, v_oldPos[vID][0], v_oldPos[vID][1], v_oldPos[vID][2]) * 0.001;
    kmstand[vID] += km;
    printf("vID: %i, Total: %0.2f, Add: %0.2f, i: %i", vID, kmstand[vID], km, i);
    setVehicleKM(i, vID);
    GetVehiclePos(vID, v_oldPos[vID][0], v_oldPos[vID][1], v_oldPos[vID][2]);
    }
    }
    return 1;
    }


    OnPlayerStateChange:
    if(newstate == PLAYER_STATE_DRIVER)
    {
    new vID = GetPlayerVehicleID(playerid);
    if(vID) GetVehiclePos(vID, v_oldPos[vID][0], v_oldPos[vID][1], v_oldPos[vID][2]);
    }

  • Okay... Also leider hast du nen minimalen Denkfehler ^^ GetKilometers gibt es nicht mehr (include ist ja raus^^)
    beim Compilen:

    Code
    ...selfmade.pwn(922) : error 017: undefined symbol "GetKilometers"
    Pawn compiler 3.2.3664	 	 	Copyright (c) 1997-2006, ITB CompuPhase
    
    
    
    
    1 Error.


    Mein OnPlayerStateChange sieht nun so aus... ist das so richtig?:


    //EDIT oder ich hab den denkfehler^^

  • Okay... Also leider hast du nen minimalen Denkfehler GetKilometers gibt es nicht mehr (include ist ja raus^^)

    Oh, natürlich, das habe ich übersehen:
    forward setKiloMeter();
    public setKiloMeter()
    {
    printf("Call: %d", gettime());
    new Float:km;
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(!IsPlayerConnected(i) || !pInfo[i][pLoggedIn])continue;
    if(GetPlayerState(i) != PLAYER_STATE_DRIVER) continue;
    new vID = GetPlayerVehicleID(i);
    if(!vID) continue;
    printf("vID: %d, Motor: %d", vID, motor[vID]);
    if(motor[vID] == 0 || motor[vID] == -1) continue;
    km = GetVehicleDistanceFromPoint(vID, v_oldPos[vID][0], v_oldPos[vID][1], v_oldPos[vID][2]) * 0.001;
    if(km > 0)
    {
    kmstand[vID] += km;
    printf("vID: %i, Total: %0.2f, Add: %0.2f, i: %i", vID, kmstand[vID], km, i);
    setVehicleKM(i, vID);
    GetVehiclePos(vID, v_oldPos[vID][0], v_oldPos[vID][1], v_oldPos[vID][2]);
    }
    }
    return 1;
    }


    Mein OnPlayerStateChange sieht nun so aus... ist das so richtig?:

    Ja, das sollte passen.

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen