Beiträge von Mann im Mond

    Um nicht nur ein Wort in einem string zu speichern, wie bei strtok, kannst du den Code unten verwenden. Der Text wird im string "result" gespeichert.
    new
    length = strlen(cmdtext);
    while ((idx < length) && (cmdtext[idx] <= ' '))
    {
    idx++;
    }
    new
    offset = idx,
    result[64];
    while ((idx < length) && ((idx - offset) < (sizeof(result) - 1)))
    {
    result[idx - offset] = cmdtext[idx];
    idx++;
    }
    result[idx - offset] = EOS;
    if(result[0] == 0) return 1; // Eingabe fehlt
    Einfacher und besser als strtok ist allerdings dcmd & sscanf, dort würde das Ganze (/pm Text) so aussehen:
    if(sscanf(params, "s", string)) return 1; // Fehlende Eingabe
    // Die Eingabe wird in string gespeichert


    Dein /sethealth Befehl so
    new
    health,
    giveplayerid,
    if(sscanf(params, "ud", giveplayerid, health)) return 1; // Fehlende Eingabe
    // Die Eingaben werden in giveplayerid und health gespeichert
    Außerdem brauchst du keinen Float beim /sethealth Befehl zu verwenden, ein einfacher Integer tuts auch

    mach
    SetTimer("TeamFarben", 1000,1);
    innerhalb von "OnGameModeInit", nicht außerhalb eines Callbacks...
    Außerdem benötigst du keinen Timer, der jede Sekunde abläuft, um eine Farbe eines Spielers zu setzen. Wenn du SetPlayeColor unter "OnPlayerSpawn" verwendest hat dies die Gleiche Wirkung, ohne, dass du einen widerholenden imermit einer Schleife benutzt...

    Dein probelm liegt wie oben schon beschrieben wahrscheinlich an einem leeren string, sowohl bei Weaponname, als auch bei string2, welchen du bei
    if (WaffeID[Waffe] == 0)
    {
    }
    nicht setzt, nur bei "else". Wenn du einfach die Waffen anzeigen lassen willst, die ein Spieler trägt, dann probier mal sowas:
    new
    string[100],
    weaponname[20],
    weapon,
    ammo;
    for(new slot = 0; slot < 15; slot++)
    {
    GetPlayerWeaponData(playerid, slot, weapon, ammo);
    if(weapon > 0 && weapon < 47 && ammo > 0)
    {
    GetWeaponName(weapon, weaponname, sizeof(weaponname));
    format(string, sizeof(string), "Slot: %d | Waffe: %d (%d) | Munition: %d", slot, weaponname, weapon, ammo);
    SendClientMessage(playerid, Weis, string);
    }
    }

    Hast du denn schon Häuser erstellt in deinem Script? Wie? Falls nicht wäre das der erste Schritt, der nächste Schritt wäre eine neue Variable anzulegen für den Spieler. In dieser wird dann die Hausid gespeichert, die der Spieler besitzt. Mit einem Timer (SetTimer ; auf 5 Minuten; wiederholend) wird dann mit Hilfe einer Schleife überprüft, welcher Spieler ein Haus besitzt und dieser bekommt dann 150$ hinzu mit GivePlayerMoney...

    Zitat


    wenn ein anderer spieler das haus kauft, dann bekommt der der das haus vorher hatte ***$ und der der das haus neu gekauft hat das geld was das haus kostet und die ***$ abgezogen.


    Hä?

    SendClientMessage(Empfänger, Farbe, Text);


    Du musst dann wenn dus so willst mit /call [Text], dann schon machen mit /call [Spieler] [Text]


    dcmd_call(playerid, params[])
    {
    new
    giveplayerid,
    sendername[MAX_PLAYER_NAME],
    string[128],
    text[100];
    GetPlayerName(playerid, sendername, sizeof(sendername));
    if(sscanf(params, "us", giveplayerid, text);
    {
    SendClientMessage(playerid, FARBE, "BENUTZUNG: /call [Spieler] [Text]");// Falsche Eingabe, Nachricht senden...
    }
    if(giveplayerid == INVALID_PLAYER_ID)
    {
    SendClientMessage(playerid, FARBE, "Spieler existiert nicht");
    }
    else
    {
    format(string, sizeof(string), "[Telefon] %s sagt: %s", sendername, text);
    SendClientMessage(giveplayerid, FARBE, string);
    SendClientMessage(playerid, FARBE, string);
    }
    }


    Wenn du nur /call [Spieler] machen willst, musst du in OnPlayerText überprüfen ob er telefoniert (Variable) und eine Nachricht an den anderen senden

    Eher nicht Tuner, du kannst GetPlayerMoney so nicht anwenden.
    if(strcmp(cmdtext, "/buycarlic", true) == 0)
    {
    if(GetPlayerMoney(playerid) < 5000)
    {
    SendClientMessage(playerid, COLOR_GELB, "Du hast nicht genügend Geld!");
    return 1;
    }
    if (PlayerInfo[playerid][pCarschein] == 1)
    {
    SendClientMessage(playerid, COLOR_GELB, "Du hast schon einen Führerschein!");
    return 1;
    }
    PlayerInfo[playerid][pCarschein] = 1;
    GivePlayerMoney(playerid, -5000);
    SendClientMessage(playerid, COLOR_GELB, "Du hast jetzt den Führerschein!");
    return 1;
    }

    Idx ist einfach eine Variable (integer), welche auch z. B. "test" heissen kann. Strtok arbeitet sich von Leerzeichen zu Leerzeichen und bleibt, wenn es auf ein Leerzeichen trifft, stehen und speichert diese Position in der Variable (in dem Fall idx). Wenn du nun erneut strtok anwendest, fängt strtok nicht wieder von vorne an zu suchen, sondern sucht ab dem letzen gefundenen Leerzeichen (ab idx) wieder bis zum nächsten Leerzeichen.


    EDIT: Beispieleingabe:

    Zitat

    /command 1 Doktor


    Der "/" hat die Position 0 (string[0]), das "c" die 1 usw. Wenn du nun strtok auf diese Eingabe loslässt (fängt er bei idx an zu suchen, da idx = 0 ist am Anfang fängt er vn vorne an), dann speichert er im string "/command" und in idx "8" (da bei der 8 das Leerzeichen ist). Wenn du nun erneut strtok auf die Eingabe loslässt (fängt er ab dem ersten Leerzeichen (idx = 8) an) dann speichert er in string "1" und in idx "10" (da dort wieder das Leerzeichen ist). Diese "1" musst du nun noch von einem string in einen Wert umwandeln mit strval(string). Wenn du strtok zum 3. Mal auf die Eingabe anwendest (fängt er ab dem 2. Leerzeichen (idx = 10) an zu suchen), dann speichert er in string "Doktor" und in idx "17"...


    _______


    Strval macht aus einem string eine Zahl und speuchert diese in einer Variable variable = strval(string);...

    Bei z.B. Schleifen durch alle Spieler ist es ratsam IsPlayerConnected zu überprüfen, damit nur Spieler die auch auf dem Server sind berücksichtigt werden
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(IsPlayerConnected(i))
    {
    // ...
    }
    }


    Oder auch bei Befehlen bei denen der Spieler einen anderen Spieler angeben soll (/kick [Spieler]) zum Überprüfen, ob der Spieler überhaupt exitiert...

    Wenn ich richtig gelesen habe, wollte er es mit strtok:
    // OnPlayerCommandText
    new
    string[128],
    idx;
    string = strtok(cmdtext, idx); // den Text (cmdtext) bis zum ersten Leerzeichen auslesen und in string speichern
    if(strcmp(string, "/command", true) == 0) // den string und den "Befehl" vergleichen, falls die beiden strings gleich sind gibt strcmp 0 aus
    {
    // der Command soll später so heissen /command [Zahl] [Wort]
    new
    number;
    string = strtok(cmdtext, idx); // den Text ab dem ersten Leerzeichen (ab idx) und bis zum 2. Leerzeichen auslesen und in string speichern
    if(string[0] == 0) // prüfen ob der string leer ist (1. Buchstabe)
    {
    // Keine Eingabe hinter /myhealth
    return 1;
    }
    number = strval(string); // aus dem string einen integer machen und diesen in number speichern
    string = strtok(cmdtext, idx); // den Text ab dem zweitren Leerzeichen (ab idx) und bis zum 3. Leerzeichen auslesen und in string speichern
    if(string[0] == 0) // prüfen ob der string leer ist (1. Buchstabe)
    {
    // Keine Eingabe hinter /myhealth [Zahl]
    return 1;
    }
    format(string, sizeof(string), "Du hast '/command %d %s' eingeben", number, string);
    /*
    Das kannst du immer so weiter machen.
    strtok merkt sich, wo es zuletzt ein Leerzeichen gefunden hat und speichert diese stelle in idx. Wenn du idx innerhalb vom OnPlayerCommandText
    wieder auf 0 setzt. fängt strtok an wieder von Anfang an zu suchen...
    */
    }

    Nein, sichtbar Scheiben hoch unter runterfahren kannst du nicht, du kannst lediglich eine /me Nachricht an die Spieler in der Nähe senden mit

    Zitat

    Dein Name kurbelt die Fensterscheiben hoch


    Ich denke du willst, wenn die Fensterscheiben oben sind, dass man nur innerhalb des Fahzeuges reden kann, wenn die Scheibe geöffnet ist man mit jedem, auch außerhalb reden kann. Dazu musst du einen Array erstellen:
    // -- Oben
    new
    bool:vWindow[MAX_VEHICLES];


    // -- beim Öffnen


    vWindow[GetPlayerVehicleID(playerid)] = true;
    // Eine Nachricht an Spieler in der Nähe


    // -- beim Schliessen


    vWindow[GetPlayerVehicleID(playerid)] = false;
    // Eine Nachricht an Spieler in der Nähe


    //-- bei deinem OnPlayerCommandText


    new
    carid = GetPlayervehicleID(playerid);
    if(vWindow[carid]) // geöffnet
    {
    // Text an Spieler in der Nähe
    }
    else
    {
    // Text an Spieler im Auto
    for(new i = 0; i < GetMaxPlayers(); i++)
    {
    if(IsPlayerConnected(i))
    {
    if(GetPlyerVehicleID(i) == carid)
    {
    // Nachricht an i senden
    }
    }
    }
    }

    Entweder strtok/strval oder sscanf, nicht beides gleichzeitig. Ich habe mal die falsche Stellen entfernt. Du musst den Code noch um die restlichen Waffen vervollständigen, damit er richtig funktioniert...
    dcmd_givegun(playerid, params[])
    {
    if(PlayerInfo[playerid][pJob] != 2)
    {
    SendClientMessage(playerid, COLOR_RED, "Du bist kein Waffenhändler");
    return 1;
    }
    new
    string[60], // Dein Output kann maximal 128 groß sein, nicht 256, in deinem Fall noch weniger
    giveplayerid,
    price,
    weapon,
    mats,
    ammo;
    if(sscanf(params, "uddd", giveplayerid, weapon, ammo, price))
    {
    SendClientMessage(playerid, COLOR_GREEN, "________________________________________________");
    SendClientMessage(playerid, COLOR_WHITE, "*** Waffen ***");
    SendClientMessage(playerid, COLOR_RED, "Verwendung: /givegun [ID] [WAFFEN ID] [AMMO] [PREIS]");
    SendClientMessage(playerid, COLOR_GRAD5, "Waffen: 1.flowers(25) 2.sdpistol(100) 3.eagle(200) 4.mp5(200) 5.shotgun(200)");
    SendClientMessage(playerid, COLOR_GRAD5, "Waffen: 6.ak47(600) 7.m4(600) 8.rifle(600)");
    SendClientMessage(playerid, COLOR_GREEN, "________________________________________________");
    }
    else if(giveplayerid == INVALID_PLAYER_ID)
    {
    SendClientMessage(playerid, COLOR_RED, "Dieser Spieler exitiert nicht");
    }
    else if(weapon < 1 | weapon > 8)
    {
    SendClientMessage(playerid, COLOR_RED, "Diese Waffe existiert nicht");
    }
    else
    {
    if(weapon == 1)
    {
    weapon = 14;
    mats = 25,
    }
    else if(weapon == 2)
    {
    weapon = WAFFENID;
    mats = MATS,
    }
    // hier immer so weiter
    if(PlayerInfo[playerid][pMats] < mats)
    {
    SendClientMessage(playerid, COLOR_RED, "Du hast so viele Materialien nicht");
    return 1;
    }
    GivePlayerWeapon(giveplayerid, weapon, price);
    GivePlayerMoney(giveplayerid, -price);
    GivePlayerMoney(playerid, price);
    format(string, sizeof(string), "Du hast eine %d mit %d Munition für $%d verkauft", weapon, ammo, price);
    SendClientMessage(playerid, COLOR_GREEN, string);
    format(string, sizeof(string), "Du hast eine %d mit %d Munition für $%d gekauft", weapon, ammo, price);
    SendClientMessage(giveplayerid, COLOR_GREEN, string);
    }
    return 1;
    }

    Erstelle Pickups anstatt den gelben Pfeilen (z.B. die berühmten "i"s) mit CreatePickup. Dann kannst du einen Befehl machen wie /enter in welche du mit Hilfe von PlayerToPoint überprüfst, wo sich der Spieler befindest und dann je nach Position die Position mit SetPlayerPos und den Innenraum des jeweiligen Gebäudes mit SetPlayerInterior änderst:


    Bsp.: Du willst den Spieler in das LSPD portenm (Koordinaten: 4, 5, 6 - Interior 7), wenn sich der Spieler bei 1, 2, 3 befindet (erfundene Koordinaten). Dann überprüft du, ob der Spieler bei 1, 2, 3 steht und portest ihn zu 4, 5, 6 und setzt das Interior auf 7...

    Extra in einem Timer es überprüfen lassen? Ziemlich unnütz


    Meine Lösung von weiter oben schon komplett:
    public OnPlayerStateChange(playerid, newstate, oldstate)
    {
    if(newstate == PLAYER_STATE_DRIVER)
    {
    if(PlayerInfo[playerid][pCarschein] == 0)
    {
    // ...
    RemovePlayerFromVehicle(playerid);
    }

    }
    return 1;
    }


    // Ich weiß nicht, obs nur mir so geht Jason, aber eingerückten Code kann ich besser lesen als uneingerückten

    Zitat

    das kann so gar nicht gehen, das musst du bei OnPlayerStateChange machen


    Warum solltest du bei OnPlayerEnterVehicle einen Spieler aus einem Auto schmeissen, in dem er noch gar nicht sitzen kann bzw. warum sollte man dort überprüfen, ob er in einem Auto sitzt.
    OnPlayerEnterVehicle wird aufgerufen, wenn man gerade die Taste ("Enter") drückt... Man kann zwar bei OnPlayerEnterVehicle schon dem Spieler verbieten in das Auto zu steigen (z.B. SetPlayerPos(playerid, x,y, z+1)), aber das dann nicht mit RemovePlayerFromVehicle.

    Wie Samp schon angedeutet hat. Bei /enter weisst du jedem deiner Restaurants eine eigene VirtualWorld zu und bei /exit überprüft du diese

    // /enter


    SetPlayerVirtualWorld(playerid, 1); // bei BSN1
    SetPlayerVirtualWorld(playerid, 2); // bei BSN2


    // /exit
    if(PlayerToPoint(... BSN Ausgang ...)
    {
    if(GetPlayerVirtualWorld(playerid) == 1)
    {
    // BSN 1
    }
    else
    {
    // BSN 2
    }
    }
    Musst du natürlich erweitern, je nachdem wie viele du hast