[SAMMELTHREAD] Kleine Scripting Fragen

Dein Problem konnte durch einen User gelöst werden? Bedank dich bei ihm indem du seinen Beitrag als Hilfreich markierst sowie einen Daumen oben dalässt
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
  • Warum bringt das hier den Compiler zu crashen? :D




    C
    new ActorPickups[NUM_ACTORS];
    #if !defined NUM_WEAPONS
    #error NUM_WEAPONS must be defined!!!
    #endif
    new GeneralPickupInfo[MAX_PICKUPS][MAX_PICKUPS][MAX_PICKUPS];    
    new InfoPickups[sizeof(PlayerInfoPickups)];
    new MoneyPickups[MAX_PICKUPS-sizeof(ActorPickups)-sizeof(InfoPickups)-sizeof(GeneralPickupInfo)-1];

    MAX_PICKUPS ist auf 20000

  • 1000 habe ich auch mal probiert, mag er leider auch nicht :/


    Scheinbar bleibt dann nur der Weg ueber 2 separate Arrays was auch wieder doof ist


    1 fuer Pickup ID und 1 fuer Waffen ID und die Munition dazu


    Habe eventuell noch die Idee ein 2D Array zu machen, und WaffenID und Munition in der 2. Dimension als float zu speichern , WaffenID,Munition, und dann durch shiften beides zu trennen, und die Pickupid in der ersten Dimension in einen Float zu konvertieren, und beim Auslesen wieder in einen Int


    Wuerde die gerne wie folgt erzeugen




    Der Haken ist jedoch dass ich dann ein fettes Array brauche, am besten von der Groesse Pickups[MAX_PICKUPS][MAX_PICKUPS][MAX_PICKUPS], oder zumindest WeaponPickups[NUM_WEAPONS][NUM_WEAPONS][NUM_WEAPONS] wobei NUM_WEAPONS irgendwie bei 1000-5000 liegt


    Ich koennte natuehrlich die Munition dann festlegen wenn der Spieler das Pickup einsammelt, aber dann spare ich gerade mal eine Dimension ein, und bin immernoch bei 2

    3 Mal editiert, zuletzt von Sub Royal ()

  • 1000 habe ich auch mal probiert, mag er leider auch nicht

    Das ist viel zu viel.
    Überleg mal, das entspricht alleine schon 1000*1000*1000 einzelnen Variablen, sprich 1.000.000.000 (eine Milliarde!) Variablen. Dass das den Compiler sprengt dürfte klar sein.
    Bei 20000: 8.000.000.000.000 (8 Billionen!).




    WeaponPickups[PickupCounter[weapontype]][modelid][ammo]

    Warum nimmst du überhaupt die modelid und die ammo ins Array? Das macht wenig Sinn.
    Mache es doch so:
    new pickupid = CreateDynamicPickup(modelid,type,rx1,ry2,rz3,virtualworld);
    WeaponPickups[pickupid][wModel] = modelid;
    WeaponPickups[pickupid][wAmmo] = ammo;


    wModel und wAmmo kommen dann aus dem enum zu WeaponPickups (gleich wie bei PlayerInfo).

  • Vielen Dank^^ Das Problem beruht bei mir scheinbar auf dem falschen Verstaendnis von Arrays :D
    Habe mir das bisher immer wie ne Matrix vorgestellt



    Habe es dank des Beispiels geschafft


    C
    WeaponPickups[PickupCounter[weapontype]] = CreateDynamicPickup(modelid,type,rx1,ry2,rz3,virtualworld);
    		WeaponInfo[WeaponPickups[PickupCounter[weapontype]]][wModel] = modelid;
    		WeaponInfo[WeaponPickups[PickupCounter[weapontype]]][wAmmo] = random(1000)+10;

    Einmal editiert, zuletzt von Sub Royal ()

  • Nein, das ist falsch so.
    Du musst die pickupid als ersten Index nehmen, nur diese ist eindeutig. Außerdem hast du einen sofortigen Zugriff, ohne Schleife.


    PickupCounter[weapontype] kann ja für jeden "weapontype" die gleichen Werte wieder annehmen, somit besteht keine Eindeutigkeit.


    new pickupid = CreateDynamicPickup(modelid,type,rx1,ry2,rz3,virtualworld);
    WeaponInfo[pickupid][wModel] = modelid;
    WeaponInfo[pickupid][wAmmo] = random(1000)+10;



    Beim Pickup:
    if(WeaponInfo[pickupid][wModel] != 0) GivePlayerWeapon(playerid, WeaponInfo[pickupid][wModel], WeaponInfo[pickupid][wAmmo]);


    Mehr ist es nicht.

  • Ich stell mich grad doof an (wieder)



    dcmd_usedrugs(playerid,params[])
    {
    #pragma unused params
    if(sSpieler[playerid][Drogen] == 0) return SendClientMessage(playerid,Weiß,"Du hast keine Drogen!");
    if(sSpieler[playerid][Drogen] == 10) sSpieler[playerid][Drogen] = 9; SendClientMessage(playerid,Weiß,"Du hast 1g Drogen genommen und 10HP erhalten (9/10)"); GivePlayerHealth(playerid,10);
    if(sSpieler[playerid][Drogen] == 9) sSpieler[playerid][Drogen] = 8; SendClientMessage(playerid,Weiß,"Du hast 1g Drogen genommen und 10HP erhalten (8/10)"); GivePlayerHealth(playerid,10);
    if(sSpieler[playerid][Drogen] == 8) sSpieler[playerid][Drogen] = 7; SendClientMessage(playerid,Weiß,"Du hast 1g Drogen genommen und 10HP erhalten (7/10)"); GivePlayerHealth(playerid,10);
    if(sSpieler[playerid][Drogen] == 7) sSpieler[playerid][Drogen] = 6; SendClientMessage(playerid,Weiß,"Du hast 1g Drogen genommen und 10HP erhalten (6/10)"); GivePlayerHealth(playerid,10);
    if(sSpieler[playerid][Drogen] == 6) sSpieler[playerid][Drogen] = 5; SendClientMessage(playerid,Weiß,"Du hast 1g Drogen genommen und 10HP erhalten (5/10)"); GivePlayerHealth(playerid,10);
    if(sSpieler[playerid][Drogen] == 5) sSpieler[playerid][Drogen] = 4; SendClientMessage(playerid,Weiß,"Du hast 1g Drogen genommen und 10HP erhalten (4/10)"); GivePlayerHealth(playerid,10);
    if(sSpieler[playerid][Drogen] == 4) sSpieler[playerid][Drogen] = 3; SendClientMessage(playerid,Weiß,"Du hast 1g Drogen genommen und 10HP erhalten (3/10)"); GivePlayerHealth(playerid,10);
    if(sSpieler[playerid][Drogen] == 3) sSpieler[playerid][Drogen] = 2; SendClientMessage(playerid,Weiß,"Du hast 1g Drogen genommen und 10HP erhalten (2/10)"); GivePlayerHealth(playerid,10);
    if(sSpieler[playerid][Drogen] == 2) sSpieler[playerid][Drogen] = 1; SendClientMessage(playerid,Weiß,"Du hast 1g Drogen genommen und 10HP erhalten (1/10)"); GivePlayerHealth(playerid,10);
    if(sSpieler[playerid][Drogen] == 1) sSpieler[playerid][Drogen] = 0; SendClientMessage(playerid,Weiß,"Du hast 1g Drogen genommen und 10HP erhalten (0/10)"); GivePlayerHealth(playerid,10);
    return 1;
    }


    habs mit einem tut ausm englischen forum versucht, nur leider gibt er mir mit else if nur fehler aus.
    Der befehl funktioniert ansich, spammt aber alle abfragen nur durch.

  • Du darfst hinter einem if nur eine direkte Anweisung haben, mit Semikolon:
    if(sSpieler[playerid][Drogen] == 10) sSpieler[playerid][Drogen] = 9; SendClientMessage(playerid,Weiß,"Du hast 1g Drogen genommen und 10HP erhalten (9/10)"); GivePlayerHealth(playerid,10);


    Entweder (schlecht!):
    if(sSpieler[playerid][Drogen] == 10) sSpieler[playerid][Drogen] = 9, SendClientMessage(playerid,Weiß,"Du hast 1g Drogen genommen und 10HP erhalten (9/10)"), GivePlayerHealth(playerid,10);


    Oder (gut!):
    if(sSpieler[playerid][Drogen] == 10)
    {
    sSpieler[playerid][Drogen] = 9;
    SendClientMessage(playerid,Weiß,"Du hast 1g Drogen genommen und 10HP erhalten (9/10)");
    GivePlayerHealth(playerid,10);
    }



    Oder am besten direkt so:
    dcmd_usedrugs(playerid,params[])
    {
    #pragma unused params
    if(sSpieler[playerid][Drogen] <= 0) return SendClientMessage(playerid,Weiß,"Du hast keine Drogen!");
    sSpieler[playerid][Drogen]--;
    new str[145];
    format(str, sizeof(str), "Du hast 1g Drogen genommen und 10HP erhalten (%d/10)", sSpieler[playerid][Drogen]);
    SendClientMessage(playerid,Weiß, str);
    GivePlayerHealth(playerid,10);
    return 1;
    }

  • Danke Jeffry :D Ich glaube ich bin zu kompliziert.
    Musste das aufgrund meines komplexen Pickup Systems noch etwas umbauen.


    Das Problem mit der Eindeutigkeit habe ich auch erkannt.


    So sieht mein Pickup Teil jetzt aus






    Wobei es hier vielleicht sinvoll waere, die ganzen Faelle nicht 1000 mal hinzuschreiben, sondern fuer die Waffen vielleicht case 5..20: bla bla weil die Waffentypen in einem enum definiert sind


    Werde das erstmal so probieren :D PickupCounter[GENERIC_WEAPON] ist der Zaehler fuer die Pickups



    Hat jemand Tipps fuer das umbauen der HeapSort Funktion damit ich sie mit multidimensionalen arrays nutzen kann ?:D


    3 Mal editiert, zuletzt von Sub Royal ()

  • Vielen Dank!


    Ich habe mir das mal angeschaut, bin aber nicht so ganz ueberzeugt von der performance weil irgendwie bei dem quickSort Algorithmus von Slice der Worst Case nicht ausgeschlossen wurde .
    Habe deshalb versucht bei mir das Pivot Element aus dem Mittelwert von 2 Werten zu waehlen, um zu gewaehrleisten dass ich immer O(n log n) habe



    Habe das ganze nun gebaut bekommen, jedoch noch 1 Problem:


    Bekomme irgendwie nicht selten als WeaponInfo[pickupid][wModel] Nullen als Werte, eventuell durch meinen fehlerhaften Umgang mit random?


    Weiterhin sind die WeaponPickups da, funktionieren auch, jedoch bekomme ich z.B. wenn ich eine Katana einsammle, eine M4 :D
    Wo muss ich da nach dem Problem suchen? Vielleicht beim Sortieren?


    Bitte um Rat



    OnPlayerPickUpPickUp und dazugehoerige Funktion










    Jede 20ms wird eins generiert








    Die Funktion dazu


    Die dazugehoerigen enums



    Die Arrays

    C
    new ActorPickups[NUM_ACTORS];
    #if !defined NUM_WEAPONS
    #error NUM_WEAPONS must be defined!!!
    #endif
    new WeaponPickups[NUM_WEAPONS];
    new WeaponInfo[NUM_WEAPONS][VAL_INFO];
    new InfoPickups[sizeof(PlayerInfoPickups)];
    new MoneyPickups[MAX_PICKUPS-sizeof(ActorPickups)-sizeof(InfoPickups)-NUM_WEAPONS-1];






    Die Zuweisung der Munition geht auch bisher gut.
    Jedoch ist halt die Modelid des erstellen Pickups, nicht die Modelid des Pickups bei GetPickUpType, als wuerde da irgendwas durcheinander kommen


    Habe daher ueberlegt ob ich hier



    Unter OnPlayerPickUpPickup


    switch(WeaponInfo[pickupid][wModel])
    {


    statt der pickupid den Index nehmen muss den ich aus der Binaersuche rauskriege

    Einmal editiert, zuletzt von Sub Royal ()

  • Weiterhin sind die WeaponPickups da, funktionieren auch, jedoch bekomme ich z.B. wenn ich eine Katana einsammle, eine M4

    Du greifst beim OnPlayerPickUpDynamicPickup mit der pickupid auf das Array zu, dann mach das auch beim erstellen und lass diese Counter weg! Zum dritten mal!
    WeaponPickups[PickupCounter[GENERIC_WEAPON]] = CreateDynamicPickup(modelid,type,rx1,ry2,rz3,virtualworld);
    WeaponInfo[PickupCounter[GENERIC_WEAPON]][wModel] = modelid;
    WeaponInfo[PickupCounter[GENERIC_WEAPON]][wAmmo] = random(1000)+10;
    zu:
    new pickupid = CreateDynamicPickup(modelid,type,rx1,ry2,rz3,virtualworld);
    WeaponInfo[pickupid][wModel] = modelid;
    WeaponInfo[pickupid][wAmmo] = random(1000)+10;


    Nochmal sage ich das nicht.


    Zudem ist dein komplettes System so überkompliziert, da blickt man gar nicht mehr durch. Was sollen zum Beispiel die Sortierfunktionen für einen Zweck erfüllen?
    Die binarysearch Funktionen in GetPickupType haben ebenfalls keinen Sinn, da dein Index immer 0 ist. Ich verstehe auch nicht was das bezwecken soll.


    Das System an sich kannst du eigentlich komplett in die Tonne treten (sorry, aber ist so) und neu schreiben. Das geht wesentlich einfacher.


    -> Ein Array mit enum für die Pickups (enum: Model [Welche Waffe z.B.], Menge [für Geld und Ammo], Typ [ob Geldpickup(0), Waffenpickup(1), etc).
    -> Index ist die pickupid
    -> Eine Funktion, die die Model-ID zur Waffen-ID zurück gibt.
    -> Random Funktion für Position und Waffen-ID.


    Und wenns ein Geld Pickup sein soll, dann kann das ins gleiche Array. Jede Pickup-ID gibt es schließlich nur einmal, da hast du schon eine Eindeutigkeit.


    Mehr ist es nicht. Das kann man in 1 Stunde problemlos funktionsfähig schreiben.




    Zudem:
    Dieser Thread ist für kleine Fragen, nicht für elendslange Codes.
    Erstelle bitte einen separaten Thread für weitere Fragen.

  • Hey ich habe noch nie gelernt wie man bestimmte Koordinaten random verwendet, es wird mal Zeit für mich sowas zu verstehen.


    Ein Beispiel:


    Bei einem Beruf soll einer zufällig, von sagen wir mal 4 Checkpoints, ausgewählt werden und diese Koordinaten sind alle vorgegeben.
    Wie binde ich das nun in nem Code ein? Es wird über ein Befehl ausgelöst und trotzdem global im Script verwendet.


    Koords:
    X | Y | Z
    1 | 2 | 3
    3 | 2 | 1
    2 | 1 | 3
    3 | 1 | 2


    Bitte auch ein wenig mit Erklärung da ich sowas noch nicht gemacht habe!

    SA:MP in 2020?

  • Die 0 steht für die X Position im Array, die 1 für Y, die 2 für Z und die 3 für die Rotation. Da du keine Rotation benötigst, kannst du die weg lassen.


    SetPlayerCheckpoint(playerid, checkpoint[rand][0], checkpoint[rand][1], checkpoint[rand][2]);

  • Die 0 steht für die X Position im Array, die 1 für Y, die 2 für Z und die 3 für die Rotation. Da du keine Rotation benötigst, kannst du die weg lassen.


    SetPlayerCheckpoint(playerid, checkpoint[rand][0], checkpoint[rand][1], checkpoint[rand][2]);


    Vielen Dank ich bin echt froh, dass du hier in dem Forum unterwegs bist und so hilfsbereit bist ;)


    Die Breadfish Admins sollten dir mal eine "Sonderabzeichen" geben. Ich kann mich nur mit Worten bei dir bedanken, wie super nett du hier den Leuten hilfst und dann noch so aktiv!
    Mach weiter so ^^
    ______________________________________________________________________________________________________________________________________________________________________________
    Edit: Hey da wundert es mich nochmal wie ich dann z.B. in ner Funktion abrufe > IsPlayerInRangeOfPoint(playerid, Jede X, Jede Y, Jede Z) aus der Random funktion?
    Oder muss ich das alles einzeln machen? Ich hab da 17 verschiedene Koordinaten für Checkpoints

    SA:MP in 2020?

    Einmal editiert, zuletzt von Anti. ()

  • Oder muss ich das alles einzeln machen? Ich hab da 17 verschiedene Koordinaten für Checkpoints

    Das kannst du mit einer Schleife durch das Array erreichen:
    for(new i = 0; i < sizeof(checkpoint); i++)
    {
    if(IsPlayerInRangeOfPoint(playerid, 5.0, checkpoint[i][0], checkpoint[i][1], checkpoint[i][2]))
    {
    //Spieler in der Nähe von Checkpoint mit der ID "i"
    printf("Spieler %d ist in der Nähe von Checkpoint %d.", playerid, i);
    return 1;
    }
    }
    //Spieler bei keinem Checkpoint
    printf("Spieler %d ist bei keinem Checkpoint.", playerid);
    return 1;

  • Und wie würde ich das ganze mit z.B. mit globalen Codes machen?


    Ich hab da "Hacker" Funktion als Beruf wo man ganz schnell einen Zahlen Code eingeben muss um Geld zu bekommen. Im moment sieht es so aus:


    z1[playerid] = random(9)
    z2[playerid] = random(9)


    z3[playerid] = random(9)


    z4[playerid] = random(9)


    z5[playerid] = random(9)


    ... das ganze bis z12



    Und da es so ziemlich unschön aussieht und sehr viel Platz klaut und viel Mühe kostet, wie mach ich das besser?


    Am Ende sollte es einen Code generieren der z.B. so ist:



    %d%d%d%d - %d%d%d%d - %d%d%d%d



    Und der Spieler muss das in einem Dialog eingeben. Wie würde ich das mit einem Zahlen & Buchstaben Mix machen?

    SA:MP in 2020?