Beiträge von IPrototypeI

    Abgesehen von der aussage von sharpadox muss dein server von deinem pc aus gestartet werden(homeserver) aufgrund vom plugin welches dort dabei ist eventuell wird dieses nicht geladen daher schau dir mal die server.log an.


    das plugin fängt die Position deiner Maus ab von deinem pc daher kann es nur lokal genutzt werden.

    Die Spieler müssen sich doch da einen Tag frei nehmen um die Richtige stelle rauszukriegen wo der andere gerad hinschaut, oder nicht


    Nee da du von dieser position aus den bereich abfragen kannst mit IsPlayerInRangeOfPoint, ich hab die selbe Berechnung vor kurzem gemacht nur in die andere richtung für ein abseilsystem von gebäuden

    IsPlayerInRangeOfPoint


    Dir ist damit bewusst das du damit abfrägst ob der spieler in einem bestimmten radius ist daher kann der spieler auch hinter einem stehen

    Zitat


    wie kann ich abfragen ob ein Spieler genau vor einem anderen Spieler steht?
    Nicht irgendwie mit IsPlayerInRangeOfPoint oder so.

    Aber wie wird Sinus berechnet?
    Beim Taschenrechner hat man dafür spezielle Tasten.
    Könntest du dies vielleicht an einem Beispiel zeigen?




    X += GK * floatsin(winkel,degrees);
    Y += AK * floatcos(winkel,degrees);


    Winkelfunktionen
    floatsin
    floatcos
    floattan
    asin
    acos
    atan
    atan2

    public OnPlayerEnterCheckpoint(playerid)
    {
    new veh = GetPlayerVehicleID(playerid);
    if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER && !strcmp(SpawnCar_Type[veh], "Straßenreinigung", true))
    {
    DisablePlayerCheckpoint(playerid);
    DestroyRubbish(MuellObject[playerid]);
    new id = GetNearestRubbishID(GetPlayerVehicleID(playerid));
    if(id == -1)return 1;
    MuellObject[playerid] = id;
    return SetPlayerCheckpoint(playerid, SRubbishInfo[id][RposX], SRubbishInfo[id][RposY], SRubbishInfo[id][RposZ], 4.5);
    }
    return 1;
    }



    if(id == -1)return 1;


    wie bereits erwähnt


    Zitat

    und auserdem brauche ich diese Fehlermeldung nicht.


    Zitat

    MrPawn dann setze dort ein return 1; hin da sonst der Server abschmiert , wenn man auf einen negativen index eines arrays zugreifst



    schmiert dein server sonst ab, da du auf einen negativen index zugreifst SRubbishInfo[-1][RposX]

    Um die X, Y Koordinaten zu berechnen benutzt man den Winkel des Spielers den man über GetPlayerFacingAngle ermitteln kann.
    Um eine Seite zu errechnen von der X-Achse benötigst du die Sinusfunktion. Die Gegenkathete ist eine kostante die du selbst festlegst und du hast den winkel
    um die Hypotenuse zu berechnen , bei der Y-Achse ist das auch nicht anders. Den berechneten Wert addierst du einfach zu der Position des Spielers dazu somit hast du die Position
    vor dem Spieler.

    /edit: Kann man auch das R39-2 Plugin mit diesem Tutorial verwenden oder muss man dafür unbedingt das R5 Plugin haben?


    Die meisten Tutorials sind leider auf etwas ältere Versionen beschränkt jedoch gibt es ein Wikiartikel darüber wo die ganzen Funktionen erklärt werden, falls du dich lieber an das
    ORM-System wagen möchtest , da du mit dem SQL Syntax nicht zurecht kommst, gibt es noch ein Tutorial auf Deutsch.


    Wiki :


    http://wiki.sa-mp.com/wiki/MySQL/R33


    ORM-Tutorial


    http://gta-sa-mp.de/forum/3-sa…ials/1424-das-orm-system/


    //edit in einer älteren Version ist auch ein beispiel Skript enthalten. (R38 kann es sein musst nochmal die Downloadlinks anschauen)

    Das machst du mit sinus und cosinus. den winkel ermittelst du via GetPlayerFacingAngle.
    sinus für die x Achse und cosinus für die y-Achse.


    Damit errechnest du die position vor dem spieler

    abzubrechen. Es sei denn, es können während Runtime Lücken im Array entstehen.


    Wenn man sein Code anschaut ist es klar das Lücken während der Laufzeit entstehen , abgesehen davon hast du natürlich recht
    ein return reicht da auch, zum Thema iterator es gibt das memory_access plugin und bietet sich perfekt zur Verwaltung des Speichers an.


    MrPawn dann setze dort ein return 1; hin da sonst der Server abschmiert , wenn man auf einen negativen index eines arrays zugreifst

    stock GetNearestRubbishID(veh, MAX_DISTANCE = 500.0){
    new Float:Distance[2]={-1,-1}, index = -1;
    for(new i; i != MAX_RUBBISH; ++i){
    if(!SRubbishInfo[i][RubbishObject])continue;
    Distance[0] = GetVehicleDistanceFromPoint(veh, SRubbishInfo[i][RposX], SRubbishInfo[i][RposY], SRubbishInfo[i][RposZ]);
    if((Distance[1] == -1 || Distance[0] < Distance[1]) && Distance[0] < MAX_DISTANCE){
    Distance[1] = Distance[0];
    index = i;
    }
    }
    return index;
    }
    stock DestroyRubbish(index){
    DestroyDynamicObject(SRubbishInfo[index][RubbishObject]);
    SRubbishInfo[index][RubbishObject] = 0;
    return 1;
    }


    Er muss nur Abfragen ob das Objekt die ID 0 hat um leere zeilen eines Arrays raus zu filtern da die Objekte mit der Ordnungszahl 1 anfangen, dies ist genauso wie bei dem Fahrzeugen.


    Ich hab ihm mal zwei Funktionen geschrieben die ihm helfen sollten, ide erste Funktionen filtert den nächsten Mülleimer raus und die zweite Funktion zum löschen.



    Verwendung:

    public OnPlayerEnterCheckpoint(playerid)
    {
    new veh = GetPlayerVehicleID(playerid);
    if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER && !strcmp(SpawnCar_Type[veh], "Straßenreinigung", true))
    {
    DisablePlayerCheckpoint(playerid);
    DestroyRubbish(MuellObject[playerid]);
    new id = GetNearestRubbishID(GetPlayerVehicleID(playerid));
    if(id == -1)return SendClientMessage(playerid,-1,"In deiner nähe gibt es keine Mülleimer");
    MuellObject[playerid] = id;
    return SetPlayerCheckpoint(playerid, SRubbishInfo[id][RposX], SRubbishInfo[id][RposY], SRubbishInfo[id][RposZ], 4.5);
    }
    return 1;
    }


    //edit kleiner Fehler gefunden

    Hey, weiß jemand welches MySQL-Plugin das Beste ist? Weil es gibt ja mittlerweile viele Versionen davon oder?


    Das von strickenkid und das von dem Dean sind quasi veraltet. ich würde das von BlueG/maddinat0r empfehlen und davon die neuste Version , diese wäre R39


    Wenn ich die Plugins nach einem Ranking bewerten müsste ergäbe sich folgende Anordnung.


    1. https://github.com/pBlueG/SA-MP-MySQL/releases
    2.http://forum.sa-mp.com/showthread.php?t=429464
    3.http://forum.sa-mp.com/showthread.php?t=122983

    ocmd:setrang(playerid,params[])
    {
    if(isPlayerInFrak(playerid,0))return SendClientMessage(playerid,RED,"Du bist Zivilist!");
    if(!isPlayerRang(playerid,5)) return SendClientMessage(playerid,RED,"Dein Rang ist zu niedrig um dessen von jemand anderes zu ändern");
    new pID,rangs,Rank[128];
    if(sscanf(params,"ii",pID,rangs))return SendClientMessage(playerid,RED,"INFO: /setrang [playerid] [Fraktionsrang]");
    if(rangs<0||rangs>6)return SendClientMessage(playerid,CL_BLACK,"Bitte gültigen Rang angeben. (0-6) ");
    if(!IsPlayerConnected(pID)) return SendClientMessage(playerid,RED,"Spieler nicht gefunden!");
    if(sInfo[pID][eingeloggt] == 0) return SendClientMessage(playerid,RED,"Spieler ist nicht eingeloggt");
    sInfo[pID][rang]=rangs;
    savePlayer(pID);
    SendClientMessage(pID,RED,"Dein Memberrang wurde geändert.");
    format(Rank,sizeof(Rank),"Du hast den Memberrang von %s geändert",getPlayerName(pID));
    SendClientMessage(playerid,RED,Rank);
    if(isPlayerInFrak(pID, 1)){
    switch(sInfo[pID][rang]){
    case 1:SendClientMessage(pID,CL_HBLUE,"Du bist nun Praktikant und hast deinen Skin erhalten"),SetPlayerSkin(pID,265);
    case 2:SendClientMessage(pID,CL_HBLUE,"Du bist nun Lehrling und hast deinen Skin erhalten"),SetPlayerSkin(pID,266);
    case 3:SendClientMessage(pID,CL_HBLUE,"Du bist nun ausgebildeter Azubi und hast deinen Skin erhalten"),SetPlayerSkin(pID,267);
    case 4:SendClientMessage(pID,CL_HBLUE,"Du bist nun Ausgebildeter COP und hast deinen Skin erhalten"),SetPlayerSkin(pID,280);
    case 5:SendClientMessage(pID,CL_HBLUE,"Du bist nun Ausgebildeter COP und CO LEADER und hast deinen Skin erhalten"),SetPlayerSkin(pID,284);
    case 6:SendClientMessage(pID,CL_HBLUE,"Du bist nun Ausgebildeter COP und LEADER und hast deinen Skin erhalten"),SetPlayerSkin(pID,284);
    }
    }
    return 1;
    }


    Problem ist Beispielsweise hier if(!isPlayerRang(pID,0)) du frägst ab ob der spieler nicht den rang 0 hat dies zieht sich bei der skinvergabe durch den ganzen code durch if(!isPlayerRang(pID,3)) etc... Dieses ! gehört hier nicht hin


    Problem ist hier

    Das Problem besteht darin das dein string leer ist und wenn ein leerer string verglichen wird so wird dieser als valide anerkannt.


    einfach somit überprüfen ob der spieler erstmal online ist


    stock IsPlayerNameOnline(pname[])
    {
    new playername[MAX_PLAYER_NAME];
    for(new i; i<MAX_PLAYERS;i++){
    if(!IsPlayerConnected(i))continue;
    GetPlayerName(i,playername,sizeof playername);
    if(!strcmp(pname,playername,false))return i;
    }
    return -1;
    }

    static const VehicleNames[212][20 char] = {
    {!"Landstalker"},{!"Bravura"},{!"Buffalo"},{!"Linerunner"},{!"Perrenial"},{!"Sentinel"},{!"Dumper"},
    {!"Firetruck"},{!"Trashmaster"},{!"Stretch"},{!"Manana"},{!"Infernus"},{!"Voodoo"},{!"Pony"},{!"Mule"},
    {!"Cheetah"},{!"Ambulance"},{!"Leviathan"},{!"Moonbeam"},{!"Esperanto"},{!"Taxi"},{!"Washington"},
    {!"Bobcat"},{!"Mr Whoopee"},{!"BF Injection"},{!"Hunter"},{!"Premier"},{!"Enforcer"},{!"Securicar"},
    {!"Banshee"},{!"Predator"},{!"Bus"},{!"Rhino"},{!"Barracks"},{!"Hotknife"},{!"Trailer 1"},{!"Previon"},
    {!"Coach"},{!"Cabbie"},{!"Stallion"},{!"Rumpo"},{!"RC Bandit"},{!"Romero"},{!"Packer"},{!"Monster"},
    {!"Admiral"},{!"Squalo"},{!"Seasparrow"},{!"Pizzaboy"},{!"Tram"},{!"Trailer 2"},{!"Turismo"},
    {!"Speeder"},{!"Reefer"},{!"Tropic"},{!"Flatbed"},{!"Yankee"},{!"Caddy"},{!"Solair"},{!"Berkley's RC Van"},
    {!"Skimmer"},{!"PCJ-600"},{!"Faggio"},{!"Freeway"},{!"RC Baron"},{!"RC Raider"},{!"Glendale"},{!"Oceanic"},
    {!"Sanchez"},{!"Sparrow"},{!"Patriot"},{!"Quad"},{!"Coastguard"},{!"Dinghy"},{!"Hermes"},{!"Sabre"},
    {!"Rustler"},{!"ZR-350"},{!"Walton"},{!"Regina"},{!"Comet"},{!"BMX"},{!"Burrito"},{!"Camper"},{!"Marquis"},
    {!"Baggage"},{!"Dozer"},{!"Maverick"},{!"News Chopper"},{!"Rancher"},{!"FBI Rancher"},{!"Virgo"},{!"Greenwood"},
    {!"Jetmax"},{!"Hotring"},{!"Sandking"},{!"Blista Compact"},{!"Police Maverick"},{!"Boxville"},{!"Benson"},
    {!"Mesa"},{!"RC Goblin"},{!"Hotring Racer A"},{!"Hotring Racer B"},{!"Bloodring Banger"},{!"Rancher"},
    {!"Super GT"},{!"Elegant"},{!"Journey"},{!"Bike"},{!"Mountain Bike"},{!"Beagle"},{!"Cropdust"},{!"Stunt"},
    {!"Tanker"}, {!"Roadtrain"},{!"Nebula"},{!"Majestic"},{!"Buccaneer"},{!"Shamal"},{!"Hydra"},{!"FCR-900"},
    {!"NRG-500"},{!"HPV1000"},{!"Cement Truck"},{!"Tow Truck"},{!"Fortune"},{!"Cadrona"},{!"FBI Truck"},
    {!"Willard"},{!"Forklift"},{!"Tractor"},{!"Combine"},{!"Feltzer"},{!"Remington"},{!"Slamvan"},
    {!"Blade"},{!"Freight"},{!"Streak"},{!"Vortex"},{!"Vincent"},{!"Bullet"},{!"Clover"},{!"Sadler"},
    {!"Firetruck LA"},{!"Hustler"},{!"Intruder"},{!"Primo"},{!"Cargobob"},{!"Tampa"},{!"Sunrise"},{!"Merit"},
    {!"Utility"},{!"Nevada"},{!"Yosemite"},{!"Windsor"},{!"Monster A"},{!"Monster B"},{!"Uranus"},{!"Jester"},
    {!"Sultan"},{!"Stratum"},{!"Elegy"},{!"Raindance"},{!"RC Tiger"},{!"Flash"},{!"Tahoma"},{!"Savanna"},
    {!"Bandito"},{!"Freight Flat"},{!"Streak Carriage"},{!"Kart"},{!"Mower"},{!"Duneride"},{!"Sweeper"},
    {!"Broadway"},{!"Tornado"},{!"AT-400"},{!"DFT-30"},{!"Huntley"},{!"Stafford"},{!"BF-400"},{!"Newsvan"},
    {!"Tug"},{!"Trailer 3"},{!"Emperor"},{!"Wayfarer"},{!"Euros"},{!"Hotdog"},{!"Club"},{!"Freight Carriage"},
    {!"Trailer 3"},{!"Andromada"},{!"Dodo"},{!"RC Cam"},{!"Launch"},{!"Police Car (LSPD)"},{!"Police Car (SFPD)"},
    {!"Police Car (LVPD)"},{!"Police Ranger"},{!"Picador"},{!"S.W.A.T. Van"},{!"Alpha"},{!"Phoenix"},{!"Glendale"},
    {!"Sadler"},{!"Luggage Trailer A"},{!"Luggage Trailer B"},{!"Stair Trailer"},{!"Boxville"},{!"Farm Plow"},
    {!"Utility Trailer"}
    };

    stock GetVehicleName(modelid)
    {
    static vehName[30];
    strunpack(vehName, VehicleNames[modelid - 400]);
    return vehName;
    }



    CMD:carinfo(playerid, params[]){
    if(!IsPlayerInAnyVehicle(playerid)) return SendClientMessage(playerid, -1, "Du bist in keinem Fahrzeug.");
    new veh = GetPlayerVehicleID(playerid);
    new id = getSlotID(veh);
    if(id == -1)return SendClientMessage(playerid,-1,"Dieses Fahrzeug ist nicht deins!");
    new str[300],headline[64];
    format(str,sizeof(str),"{FFFFFF}ID: %d\nFahrzeugname: %s\nFahrzeug Türen: %s{FFFFFF}\nFahrzeug Status: %s{FFFFFF}\nFahrzeug Verwahrung: %s\n{FFFFFF}Kennzeichen: %s{FFFFFF}",veh,GetVehicleName(sCarInfo[id][CarModelID]),
    (!sCarInfo[playerid][CarLock])?("{21DD00}Aufgeschlossen"):("{FF0000}Abgeschlossen"),
    (sCarInfo[playerid][CarAbgeschleppt])?("{FF0000}Abgeschleppt"):("{21DD00}Nicht abgeschleppt"),
    (sCarInfo[playerid][NeedRep])?("{FF0000}Benötigt Reparatur"):("{21DD00}Fahrtüchtig"),
    sCarInfo[id][CarSchildName]);
    format(headline,sizeof(headline),"Du hast %d Fahrzeuge.",CountKeys(playerid));
    ShowPlayerDialog(playerid,542,DIALOG_STYLE_MSGBOX,headline,str,"Bestätigen","");
    return 1;
    }


    Sollte so funktionieren

    Kannst du so machen nur wenn du schon ein define nutzt kannst du das auch als wert angeben bei der specifer abfolge



    sscanf(_result,"p<|>A<i>(0)["#MAX_CARKEYS"]", PlayerCarKeys[playerid]);


    du musst jedoch einen string beim speichern formatieren mit einem | als delimiter jedoch kannst du auch ein komma verwenden musst es jedoch bei
    dem specifer p anpassen würde so aussehen p<,>
    ein optionaler specifer (A) musst du nicht zwingend verwenden da der string sollte er einmal formatiert werden die 0 enthält. sollte das splitten nicht möglich sein
    so bleibt der wert der "Zeile" auf 0.


    eigentlich müsste es so passen und gewöhne dir das LIMIT 1 an bei MySQL Befehlen welche nur 1 Ergebnis liefern sollen, das optimiert die queries.


    Wenn du keine festebegrenzung haben möchtest musst du auf dynamischen Speicher zurückgreifen, das wäre mit PVars möglich
    http://wiki.sa-mp.com/wiki/GetPVarString


    oder mit Plugins
    wie dem MemoryAccess plugin siehe dazu auch mein ingame mapeditor.


    Jedoch muss das ganze nicht unendlich gehen ich geh mal davon aus das dein Spieler niemals mehr als 100 Schlüssel besitzt



    Du musst es auch nichtmal splitten da du variabeln so speichern kannst:

    new str[4];
    str[0] = 5;
    str[1] = 134;
    str[2] = 194;
    str[3] = 1043;


    das kannst du als string speichern und auslesen mit strfind sollte es auch möglich sein das wieder zu finden.

    Du hast ja wahrscheinlich ein 2D Array für die Fraktionsfahrzeuge und nutzt ein enum für die 2 dimension des arrays. Erweitere diese doch einfach mit den Namen des Spielers, so kannst
    du einfach noch den Namen des "Besitzers" setzen für das Auto, also neben der Fraktion.
    Es kommt jedoch drauf an wie viele Schlüssel der Leader vergeben kann für ein Fahrzeug sollte es nur einer sein so ist das eine ganz guter Ansatz.