Beiträge von Jeffry

    new gesuchtid = strval(inputtext);
    new name[MAX_PLAYER_NAME];
    GetPlayerName(gesuchtid, name, sizeof(name));
    for(new i = 0; i < sizeof(AkteInfo); i++)
    {
    if(!strcmp(AkteInfo[i][akte_name],name))
    {
    /* etc... */
    }
    }


    Zum Vergleichen von Strings muss man strcmp nutzen (gibt 0 zurück wenn beide gleich sind).
    Setze außerdem Werte die immer gleich sind, bei jedem Schleifendurchlauf, außerhalb der Schleife hin.

    Versuche es so:
    stock DropWeapon(amount)
    {
    //Zwischenspeichern des RandomPos Arrays um darin zu arbeiten
    new Float:tmp[sizeof(RandomPos)][3];
    tmp = RandomPos;

    //Werte deklarieren
    new r,w,count = sizeof(RandomPos);

    //Schleife für die Anzahl der Waffen die erstellt werden sollen
    for(new i = 0; i < amount; i++)
    {
    //Zufallswerte generieren
    r = random(count);
    w = random(sizeof(RandomWeaponsIDs));

    //Pickup an der gefundenen Position erstellen
    CreatePickup(RandomWeaponsIDs[w], 19, tmp[r][0], tmp[r][1], tmp[r][2]);

    //Den gefundenen Ort aus dem tmp-Array entfernen, indem
    //alle nachfolgenden Orte eins nach vorne gezogen werden (=keine doppelten Orte)
    for(new j = r; j < count - 1; j++)
    {
    tmp[j][0] = tmp[j+1][0];
    tmp[j][1] = tmp[j+1][1];
    tmp[j][2] = tmp[j+1][2];
    }
    count--;
    }
    return 1;
    }


    Der Aufruf:
    DropWeapon(5);


    Das würde dann 5 von den 10 Plätzen mit jeweils einer zufälligen Waffe ausstatten.

    new RandomWeaponsIDs[] = {
    5, 6, 7, 8, 9, 10, 12, 13, 14, 15
    };
    stock DropWeapon()
    {
    new r = random(sizeof(RandomWeapons));
    new w = random(sizeof(RandomWeaponsIDs));
    CreateDynamicPickup(RandomWeaponsIDs[w], 19, RandomWeapons[r][0], RandomWeapons[r][1], RandomWeapons[r][2]);
    return 1;
    }

    Beim Starten:
    SetTimerEx("Tutorial", 1000, false, "dd", playerid, 0);


    Und das Public:
    forward Tutorial(playerid, step);
    public Tutorial(playerid, step)
    {
    switch(step)
    {
    case 0:
    {
    //Erster Step ... mache etwas hier
    SetTimerEx("Tutorial", 10000, false, "dd", playerid, step + 1);
    }
    case 1:
    {
    //Zweiter Step ... mache etwas hier
    SetTimerEx("Tutorial", 5000, false, "dd", playerid, step + 1);
    }
    case 2:
    {
    //Dritter Step ... mache etwas hier
    SetTimerEx("Tutorial", 12000, false, "dd", playerid, step + 1);
    }
    //...
    }
    return 1;
    }


    Die Zeiten jeweils beim SetTimerEx anpassen, wie lange der jeweilige Step angezeigt werden soll.

    Du musst eine Schleife durch alle Spieler machen:
    forward VUTimer();
    public VUTimer()
    {
    new engine,lights,alarm,doors,bonnet,boot,objective,vehicle,Float:health;
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(IsPlayerInAnyVehicle(i))
    {
    vehicle = GetPlayerVehicleID(i);
    GetVehicleHealth(vehicle, health);
    if(health < 350)
    {
    SetVehicleHealth(vehicle, 350);
    GetVehicleParamsEx(vehicle,engine,lights,alarm,doors,bonnet,boot,objective);
    SetVehicleParamsEx(vehicle,VEHICLE_PARAMS_OFF,lights,alarm,doors,bonnet,boot,objective);
    Motorschaden[vehicle] = 1;
    }
    }
    }
    return 1;
    }

    Funktioniert jetzt auch, kann ich den neuen Define IS_FIXED eigentlich zum Enum hinzufügen?

    Ja, dann müsste das enum so aussehen:
    enum DoorState
    {
    IS_FIXED,
    IS_OPENED,
    IS_DAMAGED,
    DS_DUMMY,
    IS_REMOVED
    }
    Der Dummy ist notwendig, da IS_REMOVED den Wert 4 haben muss.


    Man könnte es auch komplett über Defines regeln, aber da der Stock GetDoorState schon so aufgebaut ist habe ich das einfach übernommen, damit der nicht geändert werden muss.

    Nutze anstatt IsTrailerAttachedToVehicle diese Funktion:
    stock IsTrailerAttachedToAnyVeh(trailerid)
    {
    for(new i = 1; i < MAX_VEHICLES; i++) if(GetVehicleTrailer(i) == trailerid) return 1;
    return 0;
    }

    Ich habe eine Funktion geschrieben, mit der das zu realisieren wäre:
    stock SetDoorState(doorStates, Door:door, DoorState:doorState) //©Jeffry
    {
    new tmp[4];
    for(new i = 3; i >= 0; i--)
    {
    tmp[i] = (doorStates >> i * 8);
    doorStates -= (tmp[i] << i * 8);
    }
    tmp[_:door] = _:doorState;
    return ((tmp[3] << 24) + (tmp[2] << 16) + (tmp[1] << 8) + (tmp[0]));
    }


    Warum wäre?
    Ich habe es ausführlich getestet, nur scheint hier SA-MP mal wieder nicht so richtig funktionieren zu wollen. Es gibt einige Szenarios, bei denen der DamageStatus nicht korrekt geändert wird, obwohl der Wert, den SetDoorState zurück gibt offensichtlich stimmt (per Rechner die Bits ausgelesen und verglichen mit dem Wiki Beispiel: https://i.imgur.com/hox3Mz0.png).


    Für den Fixed-Status wäre noch das hier notwendig:
    #define IS_FIXED DoorState:0


    So hat dies aber zum Beispiel die Motorhaube nur geschlossen, aber nicht repariert.
    Ein weiteres Beispiel: Die Motorhaube war weg, nutzt man dann den Status IS_OPENED passierte gar nichts. Mit IS_DAMAGED allerdings war die Motorhaube wieder da, geschlossen aber kaputt. Das ist meiner Ansicht nach ein Problem von SA-MP, welches sich nicht wirklich beheben lässt.


    Ich konnte es dann so umgehen, um mein Ergebnis (Motorhaube offen und kaputt) hinzubekommen:
    if(!strcmp(cmdtext, "/test", true))
    {
    new panels, doors, lights, tires;
    GetVehicleDamageStatus(GetPlayerVehicleID(playerid),panels,doors,lights,tires);
    doors = SetDoorState(doors, DOOR_HOOD, IS_DAMAGED);
    UpdateVehicleDamageStatus(GetPlayerVehicleID(playerid),panels,doors,lights,tires);
    doors = SetDoorState(doors, DOOR_HOOD, IS_OPENED);
    UpdateVehicleDamageStatus(GetPlayerVehicleID(playerid),panels,doors,lights,tires);
    return 1;
    }
    Hier ist interessant, dass es wirklich nur klappt, wenn UpdateVehicleDamageStatus separat ausgeführt wird, obwohl das Ergebnis in "doors" nachher falsch ist (sollte ja nur IS_OPENED sein), ist die Motorhaube sowohl offen als auch kaputt gewesen. Die Ausgabe von doors war "1", was "Offen/Nicht-Kaputt" entspricht. Korrekt, aber nicht das, was im Spiel angezeigt wird. Die Gegenprüfung mit GetVehicleDamageStatus gab auch "1" zurück, was dem entspricht was gesetzt wurde, aber nicht dem entspricht, was im Spiel der Stand ist.


    Übrigens, in dem Test-Befehl, wenn man IS_DAMAGED und IS_OPENED vertauscht kam auch ein anderes Ergebnis raus, es war dann nämlich die Motorhaube nur kaputt, aber nicht offen, was ja korrekt ist, dem Ablauf nach, aber nicht erklärt, warum, wenn man es andersherum macht, beides genommen wird.


    Je nach dem was du am Ende machen willst könntest du es über RepairVehicle und SetDoorState/UpdateVehicleDamageStatus irgendwie hinbiegen. Das hilft allerdings nur viel Ausprobieren.

    Ich habe es jetzt mal testweise bei mir ausprobiert.
    Das klappt ohne Probleme, beide Varianten.


    Du kannst es ja mal auf einem leeren Server mit nur diesem Code hier versuchen, damit habe ich es auch getestet:
    #define DIALOG_GARAGE 9942
    public OnPlayerCommandText(playerid, cmdtext[])
    {
    if(strcmp(cmdtext, "/tps", true) == 0)
    {
    ShowPlayerDialog(playerid, DIALOG_GARAGE, DIALOG_STYLE_LIST, "{FFFFFF}LSPD {35ABFF}Aufzug", "{35ABFF}1.{FFFFFF} Garage/Hof\n{35ABFF}2.{FFFFFF} Heliplatz\n{35ABFF}2.{FFFFFF} Präsidium","Weiter","Abbrechen");
    return 1;
    }
    return 0;
    }
    #define COLOR_WHITE 0xFFFFFFFF
    public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
    {
    if(dialogid == DIALOG_GARAGE)
    {
    if(response)
    {
    if(listitem == 0)
    {// LSPD Hof
    if(IsPlayerInRangeOfPoint(playerid, 6.0, 1560.5579, -1689.9689, 25.5188/* LSPD Interior */) || IsPlayerInRangeOfPoint(playerid, 6.0, 1549.0814, -1673.4092, 44.8531/* LSPD Heliplatz */))
    {
    SetPlayerPos(playerid, 1572.7601, -1646.0165, 13.5639);
    //CreateBox(playerid, "", "~w~Du ~g~bist~w~ nun am LSPD Hof.");
    }
    else SendClientMessage(playerid, COLOR_WHITE, "Du befindest dich {FF8484}bereits{FFFFFF} im LSPD Hof!");
    }
    if(listitem == 1)
    {// LSPD Heliplatz
    if(IsPlayerInRangeOfPoint(playerid, 6.0, 1572.7601, -1646.0165, 13.5639/* LSPD Hof */) || IsPlayerInRangeOfPoint(playerid, 6.0, 1560.5579, -1689.9689, 25.5188/* LSPD Interior */))
    {
    SetPlayerPos(playerid, 1549.0814, -1673.4092, 44.8531);
    //CreateBox(playerid, "", "~w~Du ~g~bist~w~ nun am LSPD Heliplatz.");
    }
    else SendClientMessage(playerid, COLOR_WHITE, "Du befindest dich {FF8484}bereits{FFFFFF} im LSPD Heliplatz!");
    }
    if(listitem == 2)
    {// LSPD Präsidium
    if(IsPlayerInRangeOfPoint(playerid, 6.0, 1572.7601, -1646.0165, 13.5639/* LSPD Hof */) || IsPlayerInRangeOfPoint(playerid, 6.0, 1549.0814, -1673.4092, 44.8531/* LSPD Heliplatz */))
    {
    SetPlayerPos(playerid, 1560.5579, -1689.9689, 25.5188);
    //CreateBox(playerid, "","~w~Du ~g~bist~w~ nun im LSPD Praesidium.");
    }
    else SendClientMessage(playerid, COLOR_WHITE, "Du befindest dich {FF8484}bereits{FFFFFF} im Präsidium!");
    }
    }
    else SendClientMessage(playerid, COLOR_WHITE, "{FF8484}Abgebrochen{FFFFFF}.");
    return 1;
    }
    return 0;
    }


    Eventuell musst du den Spieler freezen, wenn der leere Server deine Map am Polizeirevier nicht hat, so habe ich es gemacht.

    Ändere bitte beim Register und beim Speichern:
    format(var, 32, "Key=%s\n", PlayerInfo[playerid][pKey]);fwrite(hFile, var);
    zu:
    format(var, 32, "Dummy=Dummy\n");fwrite(hFile, var);
    format(var, 32, "Key=%s\n", PlayerInfo[playerid][pKey]);fwrite(hFile, var);


    Zum Teil wird nämlich bei manchen in der ersten Zeile ein falsches Zeichen angelegt, das kann so umgangen werden.


    Registriere dich danach neu.