Beiträge von Jeffry

    Kannst du machen, musst du aber nicht. Schöner wäre es wahrscheinlich, aber das merkt keiner, da das einzige was passiert, dass man eine halbe Sekunde früher das Blut einmalig abgezogen bekommt, an sich kein Problem.
    Aber wenn du deinen Code schön schreiben willst, dann setze es zu 0, entweder dort wo du den Timer startest oder dort wo du ihn beendest, das spielt keine Rolle.




    EDIT: (Post unten)
    Manyula: Da dein Problem behoben ist, wäre es gut, wenn du den Thread auf erledigt setzt. Danke! :)

    Nein, er hat es schon richtig gemacht. Sonst würde es ja nur für Fraktion 0 gehen, so wie du das machst.
    Allerdings ist es schlecht, eine Texteingabe mit 300 Zeichen zu machen, wenn SendClientMessage nur maximal 145 Zeichen anzeigen kann.


    Daher so:

    ocmd:f(playerid,params[])
    {
    if(isPlayerInFrakt(playerid, 0)) return SendClientMessage(playerid, COLOR_RED, "Du bist in keiner Fraktion.");
    new string[145];
    if(sscanf(params, "s[145]", string)) return SendClientMessage(playerid, COLOR_RED, "Nutzung: /f [TEXT]");
    format(string,sizeof(string), "** %s: %s", getPlayerName(playerid), string);
    for(new i = 0; i<MAX_PLAYERS; i++)
    {
    if(!IsPlayerConnected(i)) continue;
    if(!isPlayerInFrakt(i, sInfo[playerid][fraktion])) continue;
    SendClientMessage(i, COLOR_BLUE, string);
    }
    return 1;
    }

    Dann würde ich es ganz einfach machen.
    new bleedCount[MAX_PLAYERS];


    public OnPlayerDeath(playerid, killerid, reason)
    {
    BleedOutTimer[playerid] = SetTimerEx("BleedOut", 333, true, "i", playerid);
    return 1;
    }


    forward BleedOut(playerid);
    public BleedOut(playerid)
    {
    if(!BeingRezzed[playerid])
    {
    bleedCount[playerid]++;
    if(bleedCount[playerid] >= 3)
    {
    //Blut abziehen

    //-------------
    bleedCount[playerid] = 0;
    }
    }
    else
    {
    //Blut abziehen

    //-------------
    bleedCount[playerid] = 0;
    }
    return 1;
    }


    Und dort wo der Spieler nicht mehr verblutet (beim Tod oder bei der "Auferstehung") killst du den Timer dann entsprechend.
    if(BleedOutTimer[playerid] != -1) KillTimer(BleedOutTimer[playerid]);
    BleedOutTimer[playerid] = -1;


    Was macht der Code?
    Er ruft den Timer jede 333ms auf, wenn man nicht wiederbelebt wird, dann wird nur bei jedem dritten Aufruf Blut abgezogen, sonst bei jedem Aufruf.

    Ich bin mir nicht ganz sicher ob ich dein Prinzip richtig angenommen habe, aber so dürfte das auch klappen, wie du es haben willst:
    public OnPlayerDeath(...)
    {
    BleedOut(playerid);
    return 1;
    }


    forward BleedOut(playerid);
    public BleedOut(playerid)
    {
    if(!BeingRezzed[playerid]) BleedOutTimer[playerid] = SetTimerEx("BleedOut", 1000, false, "i", playerid);
    else BleedOutTimer[playerid] = SetTimerEx("BleedOut", 333, false, "i", playerid);
    return 1;
    }


    Da der Timer ja mit jedem Aufruf neu gestartet wird (was du ja machst) sparst du dir das KillTimer.
    Alternativ kannst du zwei Callbacks machen, eins für den langen Timer und eins für den kurzen Timer.
    ...unter der Bedingung, dass ich dich richtig verstanden habe. Falls nicht, sag Bescheid.

    @[LoG]Bread:
    Könntest du dann nochmal bitte den gewünschten Effekt ganz genau erklären? Vielleicht mit einem Bild wie es momentan ist, und dann ein Bild wie es sein soll.
    Ich weiß nämlich nicht, wie du es wirklich haben willst. :S

    Da ich hier auch immer wieder falsche oder komplizierte Funktionen dazu sehe, hier eine funktionierende und einfache Variante:


    new stock g_days_m[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    stock GetPlayerAge(input[]) //©Jeffry
    {
    new date[12];
    strcat(date, input);
    if(date[1] == '.') strins(date, "0", 0, 12);
    if(date[4] == '.') strins(date, "0", 3, 12);
    if(!date[9] || date[10]) return -1;
    new day = 10*(date[0]-48)+(date[1]-48);
    new month = 10*(date[3]-48)+(date[4]-48);
    new year = 1000*(date[6]-48)+100*(date[7]-48)+10*(date[8]-48)+(date[9]-48);
    if(year < 1000 || year > 9999 || month < 1 || month > 12 || day < 1) return -1;
    if(month == 2)
    {
    if(day > 28 && (year % 4 != 0 || (year % 100 == 0 && year % 400 != 0))) return -1;
    }
    else if(day > g_days_m[month-1]) return -1;
    new d, m, y;
    getdate(y, m, d);
    new age = y - year;
    if(m < month) age--;
    else if(m == month && d < day) age--;
    return (age < 0) ? (-1) : (age);
    }


    Beispiel zur Nutzung:

    Spoiler anzeigen
    public OnDialogResponse(playerid, dialogid, response, lisitem, inputtext[])
    {
    if(dialogid == DIALOG_AGE)
    {
    if(!response) return 1;
    new age = GetPlayerAge(inputtext);
    if(age == -1) return ShowPlayerDialog(playerid, DIALOG_AGE, DIALOG_STYLE_INPUT, "Geburtsdatum", "Bitte gebe Dein Geburtsdatum hier ein: (Format: TT.MM.JJJJ)", "Ok", "Abbrechen");
    PlayerInfo[playerid][pAge] = age;
    new str[145];
    format(str, sizeof(str), "Du hast am %s Geburtstag, damit bist Du %d Jahre alt! Sehr schön :)", inputtext, PlayerInfo[playerid][pAge]);
    SendClientMessage(playerid, 0xFF0000FF, str);
    return 1;
    }
    return 0;
    }

    Spoiler anzeigen
    Ausgabe:

    Zitat
    Spoiler anzeigen

    [12/03/2015 19:34:56] Du hast am 24.01.1993 Geburtstag, damit bist Du 22 Jahre alt! Sehr schön :)


    Keywords: GetPlayerAge, GetSpielerAlter, SpielerJahre, Alter eines Spielers, CalculateAge, BerechneAlter, YearsSince, JahreSeit.

    ees funkt jetzt


    Hast du fHealth als Integer oder als Float (Float:fHealth) deklariert?
    Falls ohne den Float, dann liegt es daran, dass du es zu "d" ändern musstest, da es ja kein Float ist. Allerdings ist die Vehicle Health ein Float.

    sscanf(Content,"dffffdddddddddddddddddddddd",
    zu:
    sscanf(Content,"dffffddddddddddddddddddddddf",


    format(Content,sizeof(Content),"%d %.3f %.3f %.3f %.3f %03d %03d %02d %02d %02d %02d %02d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\r\n",
    zu:
    format(Content,sizeof(Content),"%d %.3f %.3f %.3f %.3f %03d %03d %02d %02d %02d %02d %02d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %.3f\r\n",


    Und beim Erstellen nach CreateVehicle natürlich wieder die Health setzen.

    Nein, es passt immer noch nicht.
    Nutze den "Quellcode" Reiter, über der Schriftart. Nicht den Editor.


    EDIT:
    Funktioniert denn eigentlich dein Code, also kannst du den Server mit den ganzen Warnungen starten?

    Heißt du erstellst das Objekt an der Position des Fahrzeugs und verschiebst es von dort an?
    Versuche es dann mal so:
    ocmd:vehicleobject(playerid, params[])
    {
    new objectid;
    if (sscanf(params, "i", objectid)) return SendClientMessage(playerid, COLOR_GREY, " ** [Fehler]{FFFFFF} /vehicleobject [objectid]");
    if(!IsPlayerInAnyVehicle(playerid)) return SendClientMessage(playerid, COLOR_GREY, " ** [Fehler]{FFFFFF} Du befindest dich in keinem Fahrzeug.");
    if(IsValidObject(objectid) || IsValidDynamicObject(objectid))
    {
    if(IsValidObject(objectid))
    {
    new Float:ObjPos[3], Float:VehiclePos[3], Float:NewPos[3], Float:Rot[3];

    GetObjectPos(objectid, ObjPos[0], ObjPos[1], ObjPos[2]);
    GetObjectRot(objectid, Rot[0], Rot[1], Rot[2]);
    GetVehiclePos(GetPlayerVehicleID(playerid), VehiclePos[0], VehiclePos[1], VehiclePos[2]);

    NewPos[0] = ObjPos[0] - VehiclePos[0];
    NewPos[1] = ObjPos[1] - VehiclePos[1];
    NewPos[2] = ObjPos[2] - VehiclePos[2];

    AttachObjectToVehicle(objectid, GetPlayerVehicleID(playerid), NewPos[0], NewPos[1], NewPos[2], Rot[0], Rot[1], Rot[2]);
    }
    }

    Ja, die Position musst du ja aber nur einmal herausfinden.


    ocmd:vehicleobject(playerid, params[])
    {
    new objectid;
    if (sscanf(params, "i", objectid)) return SendClientMessage(playerid, COLOR_GREY, " ** [Fehler]{FFFFFF} /vehicleobject [objectid]");
    if(!IsPlayerInAnyVehicle(playerid)) return SendClientMessage(playerid, COLOR_GREY, " ** [Fehler]{FFFFFF} Du befindest dich in keinem Fahrzeug.");
    if(IsValidObject(objectid) || IsValidDynamicObject(objectid))
    {
    if(IsValidObject(objectid))
    {
    AttachObjectToVehicle(objectid, GetPlayerVehicleID(playerid), 1.0, 0.0, 0.0, 0.0, 0.0, 0.0);
    }
    }
    return 1;
    }


    Zum Beispiel.
    Oder was genau willst du mit der Berechnung bezwecken?

    Ja, er gibt dann zum Beispiel diese Koordinaten aus:
    new Float:scheibeRandom[][] =
    {
    // Positionen
    {743.9,-3959.0,39.2},
    {740.0,-3965.0,39.0},
    {735.0,-3970.0,38.0},
    {730.0,-3975.0,38.5},
    {725.0,-3950.0,37.5},
    {720.0,-3978.0,37.0}
    };