Beiträge von Goldkiller

    if(PlayerInfo[playerid][pAdmin] < 2000) //
    {


    }
    if(PlayerInfo[playerid][pAdmin] < 1500) //
    {


    }
    if(PlayerInfo[playerid][pAdmin] < 4) //
    {


    }
    if(PlayerInfo[playerid][pAdmin] < 3) //
    {


    }
    if(PlayerInfo[playerid][pAdmin] < 2) //
    {


    }
    if(PlayerInfo[playerid][pAdmin] < 1) //
    {


    }
    Du weisst aber schon,dass wenn etwas kleiner als 2000 ist,ist es auch kleiner als 1500.Ist es kleiner als 1500,ist es auch kleiner als 4.Ist es kleiner als 4,ist es auch kleiner als 3.Ist es kleiner als 3,ist es auch kleiner als 2.Ist es kleiner als 2,ist es auch kleiner als 1.
    Verstanden ?
    Du solltest von klein nach groß Abfragen und falls die Abfrage stimmt die weiteren nicht mehr ausführen lassen ( Beispielweise return ).
    Andere Möglichkeit wäre, zu prüfen,ob der Rang zwischen zwei Werten liegt.
    if( 1500 < PlayerInfo[playerid][pAdmin] <= 2000 ) {


    }
    if( 4 < PlayerInfo[playerid][pAdmin] <= 1500 ) {


    }

    Okay pass auf.

    Zitat

    Probieren geht über studieren. Ändert allerdings trotzdem nichts daran,dass du sowieso AddPlayerClass nicht unter OnPlayerRequestClass haben solltest.


    Mach wie es gesagt wurde.Das sollte deinen Vorstellungen entsprechen.

    Probieren geht über studieren. Ändert allerdings trotzdem nichts daran,dass du sowieso AddPlayerClass nicht unter OnPlayerRequestClass haben solltest.
    Deine Beschreibung trifft es sowieso nicht genau,verstehe nicht wovon du genau redest.


    //Edit: x(

    So wie es dort steht.
    Bei deinen switch-Statements playerid durch die Variable ersetzen, die du für die Schleife benutzt. Denn bei dir wird zur Zeit nur er Spieler überprüft,der es auch selber eingibt.

    Für gewöhnlich fügt man auch AddPlayerClass unter OnGameModeInit ein,nicht unter OnPlayerRequestClass. Denn die erstellten Klassen ( AddPlayerClass ) bilden die Grundlage für OnPlayerRequestClass. Das solltest du als erstes mal ändern.

    Uhuhu nice erklärt ;)
    Ich habe es nur nicht ganz verstanden. Aber naja, da ich mit Sitzplätzen im Moment nicht arbeite, brauch ich das wohl auch nicht so ^^


    Ich denke es geht auch nicht um den Sinn hinter der Funktion. Ich nehme an,dass ioRawr eher wissen wollte was dort konkret passiert und wieso es so überhaupt funktioniert. Allgemein sind Bit-Operationen sehr praktisch. Beispielsweise bei gPM nutz ich es um den Status von Nachrichten zu verwalten.Mit 1 Variable kann ich 3 Informationen Abfragen.
    enum ( <<= 1 ) {
    MessageStatus_Read = 1,
    MessageStatus_DEL_Sender, // del von sender ( postausgang )
    MessageStatus_DEL_Empfaenger // del von empfaenger ( posteingang )
    }


    Genug ausgeführt, schweife sonst zu sehr vom Thema ab. Sollte das vllt eher in ein Tutorual schreiben :wacko:

    Ich meine damit sowas wie hier: Link
    Wie arbeitet man damit richtig? Wo soll es benutzt werden?
    Ist es immer nützlich? Arbeitet das Programm schneller damit?


    Auf Frage von ioRawr, versuche ich mal den Code zu erklären.
    Es ist definitiv nichts für PAWN Anfänger bzw allg. Anfänger im Coding Bereich.


    Übrigens, in dem Code fehlt eine Zeile. "return model" muss noch eingefügt werden,sonst bringt die Funktion nichts.
    stock GetVehicleSeatCount(model)
    {
    static const
    scMaxPassengers[] =
    {
    0x10331113, 0x11311131, 0x11331313, 0x80133301, 0x1381F110, 0x10311103, 0x10001F10, 0x11113311, 0x13113311,
    0x31101100, 0x30001301, 0x11031311, 0x11111331, 0x10013111, 0x01131100, 0x11111110, 0x11100031, 0x11130221,
    0x33113311, 0x11111101, 0x33101133, 0x101001F0, 0x03133111, 0xFF11113F, 0x13330111, 0xFF131111, 0x0000FF3F
    };
    if (400 <= model <= 611)
    {
    model -= 400;
    model = (scMaxPassengers[model >>> 3] >>> ((model & 7) << 2)) & 0xF;
    if (model == 15)
    {
    return -1;
    }
    return model; // <---
    }
    else
    {
    return -1;
    }
    }

    Erstmal die Vorbereitung.Was haben wir eigentlich?
    Wir haben 611 - 400 Fahrzeuge.Sind also 211 Fahrzeuge, für die wir Werte speichern müssen.
    Es gibt kein Fahrzeug,dass mehr als 8 Sitzplätze hat ( Bus , 8 + Fahrer ). Damit wir die Zahl 8 in Binär darstellen können,
    müssen wir 4 bits verwenden.Denn 8 = 0b1000 . Die höchste Zahl die wir daher darstellen könnte wäre theoretisch 15 in diesem Fall.
    Ist aber sowieso nicht möglich,denn sonst hätten wir keine 8 als höchsten Wert für Sitzplätze genommen.
    Y_Less verwendet aber die 15 als Spezialfall,bedeutet, dass Fahrzeug bietet überhaupt keine Sitzmöglichkeit ( Weder Fahrer,noch
    Beifahrer ). Dazu später mehr.
    Bisher haben wir also herrausgefunden,dass wir eigentlich nur 4 bits benötigen pro Fahrzeug und das 211 mal. Macht Insgesamt 844 bits,
    um alle Informationen darzustellen.


    Da eine Variable ( Cell ) in PAWN 4 Byte hat ( 32 bits ) , können wir pro Variable also 8 ( 32 bits / 4 bits ) Sitzplätzwerte verwalten.
    Daraus resultiert,wir haben 8 Blöcke mit jeweils 4 bits pro Variable. Ich nenne diese einfach mal 4 bit-Block im weiteren Verlauf.


    Wie wir sehen,Y_Less hat 27 Variablen ( Code basiert allerdings auf einen Post von RyDeR` ) bzw ein Array mit einer
    Größe von 27.
    Genau genommen ist 211 / 8 = 26,375 . Wir können aber keine 0,375 Variablen erstellen, müssen daher aufrunden. Daher auch 27. Kann man
    auch überprüfen durch 26 * 32 bit , sind nur 832 bits.Wir vorher errechnet,wir brauchen aber 844 bits.


    Im ersten Schritt müssen wir herrausfinden, in welcher Variablen ( genau genommen, welcher Index ) der Wert für unser Fahrzeug
    steckt.
    Das geschiet hier:
    model -= 400;
    model >>> 3
    Da die Fahrzeuge erst bei 400, verschieben wir den Anfang zuerst. Wir verschieben alle ModelIDs um 400 nach unten.
    Sonst wären die ersten 400 Werte nutzlos ( 0 - 399 ) , da wir für diese keine Werte benötigen.Es gibt nämlich keine Fahrzeuge
    mit diesen ModelIDs.
    Gehen wir eine Zeile weiter ( model >>> 3 ).
    Ist in diesem Fall nichts Anderes als die Berechnung model / 8. Die 8 kommt von den 8 Sitzplatzwerten pro Variable.


    Angenommen für die modelid 411.
    411 -= 400;
    11 >>> 3 = 1
    Gut,wir wissen, dass der Wert für ModelID 411 in Index 1 steckt.


    Zitat

    400 - 407 ( 0 )
    408 - 415 ( 1 )
    416 = 423 ( 2 )
    424 = 431 ( 3 )
    ...


    scMaxPassengers[1] = 0x11311131 = 0b00010001001100010001000100110001 = 0001 0001 0011 0001 0001 0001 0011 0001
    Die Farben sind nur zur Verdeutlichung.Ich habe auch einfach mal den Block Fett markiert,den wir später suchen.




    Als nächstes müssen wir herrausfinden, in welchem der 4 bit-Blöcke der Wert steckt, den wir suchen.Das passiert hier:
    ((model & 7) // model & 0b111
    In unserem Fall würde es so aussehen:
    (( 11 & 7 ) // (( 0b1011 & 0b0111 )
    Das Ergebnis daraus ist 3 ( 0b1011 & 0b0111 ). Man hätte an dieser Stelle auch den Rest der Rechnung 11 durch 8 nehmen können.Ergibt ebenfalls
    3 und steht für "Wieviele 4 bit-Blöcke müssen wir verschieben,um den gesuchten an vorderster Position zu haben".
    In PAWN wäre es übrigens 11 % 8 ( = 3 ).


    Wir haben jetzt also den 4 bit-Block gefunden,den wir benötigen.Er ist in der Variable bei Index 1 und dort der vierte 4 bit-Block.
    Um an den vierten 4 bit-Block zu kommen,müssen wir den 4 bit-Block 3 Blöcke nach vorne schieben, bzw nach Rechts ( >> ).Das nennt sich Bit-Shiften.
    Denn wir beginnen hier bei den Blöcken bei 0 zu zählen.Der 1 4 bit-Block wird nämlich nicht ( also 0 mal ) geshiftet, ist nämlich schon an Vorderster Stelle.
    Der 2 4 bit-Block muss um 1 geshiftet werden,damit er an vorderster stelle steht.
    Der 3 " " " 2 geshiftet ","
    usw usf


    Jetzt sind wir bei folgendem Teil. Denn wir müssen zuerst Klammern berechnen.
    ((model & 7) << 2))
    Wir wissen ja, dass wir es um 3 4 bit-Blöcke verschieben müssen,damit der Gesuchte 4 bit-Block am Anfang steht. Da ein 4 bit-Block nun mal aus 4 Bits besteht,müssen wir alles um
    3 * 4 Bits verschieben. Das * 4 ist in diesem Fall << 2 , ist identisch .( << 1 wäre * 2 )
    Das würde Binäir so aussehen:

    Ausgang: 0001 0001 0011 0001 -> 0001 <- 0001 0011 0001
    Ergebnis: 0001 0011 0001 0001 0001 0011 0001 -> 0001 <- // Achtung , >> ist nicht >>> ! Macht in diesem Fall aber keinen Unterschied


    Jetzt haben wir den 4 bit-Block den wir benötigen an die vordersten 4 bits der Variablen verschoben. Damit wir auch nur diesen 4 bits bekommen,
    müssen wir jetzt & 0b111 machen.Dadurch fallen alle bits weg, die wir nicht benötigen.
    Für unseren Fall:
    0b0001 & 0b1111 = 0b0001 = 1.
    Damit wissen wir jetzt entgültig, dass wir 1 Sitzplatz für Fahrzeug 411 haben,neben dem Fahrersitz. Ein Spezialfall ist 15. Hätten wir jetzt also 15 als Lösung bekommen, wüssten wir, dass es eigentlich gar keine Sitzmöglichkeit für diese ModelID gibt. Es ist ein Sonderfall. 15 ist auch gleichzeitig der höchste Wert den wir mit 4 bits darstellen können ( Vorzeichenfrei ) .
    Man könnte auch anstatt die 15 eine eine Andere Zahl nehmen. Es wäre irgendeine Zahl zwischen 9 und 15 möglich,da wir ja wissen,dass kein Fahrzeug einen gültigen Wert über 8 hat.


    Was haben wir denn jetzt eigentlich davon ? Wir nutzen wenig Speicher, oder für einige Experten ... die AMX wird nicht so groß ( Was sowieso noch nie ein gute Kriterium war ).


    Ergebnis:
    Die oben gezeigte Variante verbraucht nur 27 * 4 byte , macht also 107 byte ( Technisch werden nur 211 ( Fahrzeuge ) * 4 ( bits ) 844 bits je benutzt).
    Würden wir einen Wert pro Variable benutzen, dann hätten 211 byte = 844 byte.
    Macht also 107 byte vs 844 byte. Um es mal in Prozent auszudrücken. Die oben gezeigte Variante belegt nur 12.6% von dem Speicher, den die normale Methode verbrauchen würde.Oder auch anders, die normale Methode ist um 788% Größer was den Speicherbedarf betrifft.



    Puh... so viel geschrieben, dachte das wird kürzer. Vorraussetzung dafür,dass man es versteht, sind Grundzüge des Binärsystems ( & ; << ; >> ). Sonst wird es mit dem verstehen sicherlich nicht auf anhieb klappen. Ich hoffe ich habe da jetzt nicht totalen Blödsinn geschrieben, so viele 0 und 1 ... :pinch:



    //Edit:
    Im übrigen verwende ich das ab und zu.Hier mal ein Beispiel, wie man Waffe + Munition in 1 Variable speichern kann.
    stock Class_CompressWeaponInfo(weaponid,ammo) {
    new
    info;
    info = ( ammo << 7 ) | weaponid;
    return info;
    }

    Solche Fehlermeldungen sind total sinnlos,wenn man nicht den Code dazu sieht.
    Hätte nicht gedacht,dass es so schwer sein sollte ein Tag für eine Variable zu erstellen.Denn es ist doch mehr als einfach,wenn du nur den Namen austauschen müsstest.


    Wie dem auch sei,es muss Text3D:haus_label sein.
    Text3D ist das Tag
    haus_label der Name der Variable.


    <Tag>:<Variable>

    Beispiel:
    Float:innen_x,
    Hier ist das tag "Float"


    haus_label
    Hier ist kein Tag.Du brauchst aber "Text3D" als tag.
    Übrigens steht auch bei der Funktion, was für ein tag zurückgegeben wird ( falls es eins gibt ).
    Text3D:Create3DTextLabel(text[], color, Float:X, Float:Y, Float:Z, Float:DrawDistance, virtualworld, testLOS=0);

    Ist in 1 Minute getan,aus dem Gamemode ein Filterscript zu machen. Jedenfalls sind jetzt die Präfixe falsch.

    Zitat

    .. sie als extra gameMode laufen lassen muss ...


    Man kann mehr als einen Gamemode gleichzeitig laufen lassen ? Denke eher nicht :\

    Outsch.
    main()
    {
    print("\n----------------------------------");
    print(" Paydaysystem by Sven");
    print("----------------------------------\n");
    }

    public OnGameModeInit() { ... }
    Filterscript oder Gamemode?

    listitem ist kein Array / String.
    Entweder du formatierst den String herkunft anders ( %d ), oder benutzt Dini_IntSet mit listitem.
    Natürlich nur,wenn du eine Zahl speichern willst und nicht den Text,der sich hinter dem listitem versteckt.

    Oder so :)
    if(Vehicle == (rentroller[1] || rentroller[2]))


    Das funktioniert niemals.
    Warum ? Splitten wir das:
    (rentroller[1] || rentroller[2])


    rentroller[1]
    rentroller[2]
    Sind beides eigene Statements, da mit ODER ( || ) verknüpft.Ist rentroller[1] oder rentroller[2] 0 , dann ist das Statement false.Wenn nicht,ist es für sich Wahr.Es ist zwar mit oder verknüpft, macht aber nichts. Ist eines der beiden wahr,ist das gesamte Statement ( rentroller[1] || rentroller[2]) ebenfalls wahr. Wenn nicht,ist es falsch.
    Heisst, das Gesamte Statement (rentroller[1] || rentroller[2]) ist entweder 0 ( falsch ) oder 1 ( wahr ).
    Funktioniert also nur in Ausnahmesitituationen, zb wenn rentroller[1] oder rentroller[2] Vehicleid 0 oder 1 ist. Zusätzlich muss dann auch Vehicle 0 oder 1 sein.


    //Edit:
    Um es nochmal zu verdeutlichen, wie der Ausgang immer sein würde.

    Vehicle == ( 1 / wahr )
    Vehicle == ( 0 / falsch )
    if(Vehicle == (rentroller[1] || rentroller[2]))

    Wenn du dir den Code mal genau anguckst ( zb bei OnPlayerExitVehicle ) , solltest du merken, dass nach einem return bei dir noch Code folgt.
    Nach einem return kann aber kein code mehr in der Funktion aufgerufen werden, daher ist alles nach dem return sinnlos bzw es wird nie aufgerufen. Denn das return beendet die Funktion ( kann man sich jedenfalls so vorstellen ).
    Ich zeig dir mal bei OnPlayerExitVehicle, wo die returns hin könnte ( oder du lässt sie weg ).


    public OnPlayerExitVehicle(playerid, vehicleid)
    {
    new Vehicle = GetPlayerVehicleID(playerid);
    if(Vehicle == rentroller[0])
    {
    SetVehicleToRespawn(GetPlayerVehicleID(playerid));
    return 1;
    }


    if(Vehicle == rentroller[1]) //hier
    {
    SetVehicleToRespawn(GetPlayerVehicleID(playerid));
    return 1;
    }


    if(Vehicle == rentroller[2]) //hier
    {
    SetVehicleToRespawn(GetPlayerVehicleID(playerid));
    return 1;
    }


    if(Vehicle == rentroller[3]) //hier
    {
    SetVehicleToRespawn(GetPlayerVehicleID(playerid));
    return 1;
    }
    if(Vehicle == rentroller[4]) //hier
    {
    SetVehicleToRespawn(GetPlayerVehicleID(playerid));
    }
    return 1;
    }

    Ich hab das gefühl,sobald du ein Fehler hast postest du direkt im Forum. Mal nachgeguckt,woran es liegen könnte?
    format(ALLESTRINGS, sizeof(ALLESTRINGS), "Admin: Support von %s :%s", SpielerName,inputtext);//HIER DIE ZEILE
    SpielerName ist bei dir bestimmt eine Funktion.

    Sieht eher so aus,als hätte er nur das Hud Icon der Deagle mit dem Icon der Pistole getauscht. Wenn man mal darauf achtet,wieviel schaden ein Treffer macht, sieht alles sehr nach Deagle aus.

    Wie du daraus ein stock machst ? Du solltest dir wahrscheinlich auch mal durchlesen,was dieses "stock" überhaupt bedeuet.

    stock IchMachDarausEinStock( welcher_parameter_waere_hier_am_logischsten ) {
    switch(GetPVarInt(playerid,"Fraktion"))
    {
    case 0:{}
    case 1:{SetPlayerPos(playerid,lspdspawn);SetPlayerColor(playerid,BLAU);GivePlayerWeapon(playerid,24,795);}
    case 2:{SetPlayerPos(playerid,mafiaspawn);GivePlayerWeapon(playerid,24,100);}
    case 3:{SetPlayerPos(playerid,medicspawn);SetPlayerColor(playerid,ROT);}
    case 4:{SetPlayerPos(playerid,armyspawn);SetPlayerColor(playerid,Grün);}
    }
    return 1;
    }


    Was würde denn anstatt welcher_parameter_waere_hier_am_logischsten am besten passen ? Der Parameter sollte natürlich auch in der Funktion vorkommen, und da sich alles auf einen bestimmten Spieler beziehnt nimmt man ... .