Zeig mal dein Bincosystem her, meine magische Miesmuschel ist kaputt
@Mausibiba:
new player;
repeat:
player =random(MAX_PLAYERS);
if(!IsPlayerConnected(player))goto repeat;
//Hier deine Position abfragen und die des anderen Spielers setzen
Zeig mal dein Bincosystem her, meine magische Miesmuschel ist kaputt
@Mausibiba:
new player;
repeat:
player =random(MAX_PLAYERS);
if(!IsPlayerConnected(player))goto repeat;
//Hier deine Position abfragen und die des anderen Spielers setzen
benutz GetMaxPlayers();
@Mausibiba:
new player;
repeat:
player =random(MAX_PLAYERS);
if(!IsPlayerConnected(player))goto repeat;
Das ist sogenannter Spaghetti Code und eine sehr schlechte Möglichkeit dieses Problem zu lösen.
benutz GetMaxPlayers();
Dann würde das alles noch länger dauern, denn angenommen MAX_PLAYERS und GetMaxPlayers() würden den selben Wert haben, dann muss trotzdem immer wieder eine Funktion aufgerufen werden.
Besser zu lösen, wäre es mit einem Array:
/*
Oben im Skript am besten:
#undef MAX_PLAYERS
#define MAX_PLAYERS (ANZAHL_DER_MAXIMALEN_SPIELER)
*/
new bool:e_Player[MAX_PLAYERS char];
public OnPlayerConnect(playerid)
{
if(!IsPlayerNPC(playerid)) e_Player{playerid} = true; //für jeffry
return 1;
}
public OnPlayerDisconnect(playerid)
{
e_Player{playerid} = false;
return 1;
}
//Dann der Command
new tmp[MAX_PLAYERS],c,Float:p[3];
for(new i; i<MAX_PLAYERS; i++) if(e_Player{i} && i != playerid) tmp[code=c] = i,c++;
if(!c) return SendClientMessage(playerid,-1,"Es ist kein Spieler online, den du porten kannst!");
new p_random = tmp[random(c)];
GetPlayerPos(playerid,p[0],p[1],p[2]); //<< du fragst deine Position ab:
SetPlayerPos(p_random,p[0],p[1]+1.5,p[2]); //<<hier setzt du den random Spieler zu dir
mfg.
//Edit: Code
Das so zu machen ( Nemesus Jr: Fabi.StaR ist keine gute Idee. In einem Befehl mag es zwar funktionieren, da ja dann mindestens ein Spieler online ist, aber setzt man es in einen Timer und kein Spieler ist online, dann hat man eine Endlosschleife, was zur Folge hat, dass auch niemand mehr den Server betreten kann.
Außerdem kann es theoretisch sein, dass es sehr sehr viele Wiederholungen bei der Methode gibt, denn wenn nur ein Spieler online ist, man aber 500 Slots hat, besteht jedes mal nur eine Chance von 1 zu 499 Chance, dass der Wert getroffen wird. Bei 2000 Wiederholungen ist immer noch eine 2%'ige Chance, dass noch kein Spieler gefunden wurde (2000 ist zwar nicht viel, trotzdem sollte man keine theoretischen Lücken lassen).
Kaliber: Deine Methode wird auch nicht, bzw. nicht richtig, funktionieren, wenn nur ein/kein Spieler online ist, da ein random aus 0 keinen Sinn gibt.
Für @Mausibiba: ist es sicher am einfachsten und am leichtesten zu verstehen, eine Funktion zu verwenden, die einfach eine random ID ausgibt, ohne viel Code drum herum (fehleranfällig!).
stock GetRandomPlayer(playerid)
{
new onlinecount = 0, oID[MAX_PLAYERS];
for(new i=0; i<MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i) && !IsPlayerNPC(i) && i != playerid)
{
oID[onlinecount] = i;
onlinecount++;
}
}
if(onlinecount > 0) return oID[random(onlinecount)];
else return INVALID_PLAYER_ID;
}
Wäre dann ganz einfach zu verwenden:
new player1 = GetRandomPlayer(playerid);
if(player1 == INVALID_PLAYER_ID) return SendClientMessage(playerid, 0xFF0000FF, "Es ist kein Spieler außer dir online!");
SetPlayerPos(player1, x, y, z);
Kaliber: Deine Methode wird auch nicht, bzw. nicht richtig, funktionieren, wenn nur ein/kein Spieler online ist, da ein random aus 0 keinen Sinn gibt.
Doch...da wird nämlich kein Spieler geportet, da der Wert invalid ist
Wenn ihm das nicht passt kann man im übrigen ganz leicht abfragen ob c > 0 ist oder eben nicht
...oder man macht eine Funktion daraus, die nach dem selben Algorithmus funktioniert wie mein Beispiel..im Endeffekt egal, außer das mein Code schneller ist xD
Auf ein Array mit einem invaliden Index zuzugreifen ist dennoch keine gute Idee und ein schlechtes Beispiel, weil im schlechtesten Fall bricht der Code einfach ab und es kommt "Unknown Command.", was nicht wirklich schön ist. Mir ist klar, dass die Abfrage auf 0 fehlt, aber einem Anfänger ist das meistens nicht auf den ersten Blick klar.
Außerdem fehlt noch die Abfrage, ob der Spieler ein NPC ist, den kann man ja schlecht teleportieren.
Schneller ist der Code zwar, aber dafür fehleranfälliger. Wird beispielsweise OnPlayerDisconnect durch einen Fehler in einem Filterscript mal nicht ausgeführt (verursacht zum Beispiel durch ein zugreifen auf einen Array-Index mit einem invaliden Wert...), dann bleibt der Wert des Arrays für online Spieler auf true, was zur Folge haben kann, dass ein Spieler ausgewählt wird, der gar nicht online ist. Das ist zwar weit hergeholt, passiert aber dennoch Anfängern häufig. Da die Geschwindigkeit hier irrelevant ist (Nanosekunden) ist es wichtiger einen sicheren, unabhängigen Code zu haben.
C:\Users\tobialvarez\Desktop\samp03z_svr_R1_win32 (2)\gamemodes\GTA.pwn(1275) : warning 208: function with tag result used before definition, forcing reparse
stock SendSayChat(string[],playerid) //fehlerzeile
{
for(new i = 0;i < MAX_PLAYERS; i++)
{
if(GetDistanceBetweenPlayers(i,playerid) <= 15)
{
SendClientMessage(i,-1,string);
}
}
return 1;
}
Füge zum stock GetDistanceBetweenPlayers das hinzu:
forward Float:GetDistanceBetweenPlayers(/*hier die zwei Parameter, so wie sie im stock heißen*/);
Oder setze die GetDistanceBetweenPlayers unter die Includes hin. Beides geht.
Hab da ne Frage zu meinem Unban befehl.
Wenn ich jemanden unbanne funktioniert das aber ich bekomme auch die Message, dass der Befehl nicht existiert.
ocmd:unban(playerid,params[])
{
new name, grund[128], n1[128],query[1024];
if(sInfo[playerid][pEingeloggt] == 0) return SendClientMessage(playerid, GRAU, LOGINERROR);
if(sInfo[playerid][pAdmin] < 2) return SendClientMessage(playerid, GRAU, ADMERROR);
if(sscanf(params, "s[128]s[128]", name, grund)) return SendClientMessage(playerid, GRAU, "Verwende: /unban {FF9E00}<Spieler-Name> <Grund>");
format(query,sizeof(query), "UPDATE accounts SET Gebannt='0' WHERE Name='%s'", name);
mysql_function_query(mysql,query,false,"","");
format(n1,sizeof(n1), "%s hat %s den Zugang zum Server wieder gewehrt. Grund: %s", SpielerName(playerid), name, grund);
SendClientMessageToAll(ADMIN, n1);
return 1;
}
Der Chat:
Alles anzeigenSpoiler anzeigen Das so zu machen ( Nemesus Jr: Fabi.StaR ist keine gute Idee. In einem Befehl mag es zwar funktionieren, da ja dann mindestens ein Spieler online ist, aber setzt man es in einen Timer und kein Spieler ist online, dann hat man eine Endlosschleife, was zur Folge hat, dass auch niemand mehr den Server betreten kann.
Außerdem kann es theoretisch sein, dass es sehr sehr viele Wiederholungen bei der Methode gibt, denn wenn nur ein Spieler online ist, man aber 500 Slots hat, besteht jedes mal nur eine Chance von 1 zu 499 Chance, dass der Wert getroffen wird. Bei 2000 Wiederholungen ist immer noch eine 2%'ige Chance, dass noch kein Spieler gefunden wurde (2000 ist zwar nicht viel, trotzdem sollte man keine theoretischen Lücken lassen).
Kaliber: Deine Methode wird auch nicht, bzw. nicht richtig, funktionieren, wenn nur ein/kein Spieler online ist, da ein random aus 0 keinen Sinn gibt.
Für @Mausibiba: ist es sicher am einfachsten und am leichtesten zu verstehen, eine Funktion zu verwenden, die einfach eine random ID ausgibt, ohne viel Code drum herum (fehleranfällig!).
stock GetRandomPlayer(playerid)
{
new onlinecount = 0, oID[MAX_PLAYERS];
for(new i=0; i<max_players; i++)
{
if(IsPlayerConnected(i) && !IsPlayerNPC(i) && i != playerid)
{
oID[onlinecount] = i;
onlinecount++;
}
}
if(onlinecount > 0) return oID[random(onlinecount)];
else return INVALID_PLAYER_ID;
}
Wäre dann ganz einfach zu verwenden:
new player1 = GetRandomPlayer(playerid);
if(player1 == INVALID_PLAYER_ID) return SendClientMessage(playerid, 0xFF0000FF, "Es ist kein Spieler außer dir online!");
SetPlayerPos(player1, x, y, z);
CMD:random(playerid)
{
new player1 = GetRandomPlayer(playerid);
if(player1 == INVALID_PLAYER_ID) return SendClientMessage(playerid, 0xFF0000FF, "Es ist kein Spieler außer dir online!");
//SetPlayerPos(player1, 195.7658,-1436.2083,12.9808);
if(player1)
{
SetPlayerPos(player1, 195.7658,-1436.2083,12.9808);
}
else
{
SetPlayerPos(?, 195.7658,-1436.2083,12.9808);
}
return 1;
}
aber ich weiß nicht was ich dann bei "?" hin machen soll, und wäre es nicht einfacher dem Player eine variabel zu setzen und diese dann abzufragen?
Wie würdet ihr es machen und warum?
Danke im Voraus Mausibiba
@K3Ksii:
new name, grund[128], n1[128],query[1024];
zu:
new name[MAX_PLAYER_NAME], grund[64], n1[145],query[128];
@Mausibiba:
Das kannst, bzw. musst, du mit einer Schleife machen.
CMD:random(playerid)
{
new player1 = GetRandomPlayer(playerid);
if(player1 == INVALID_PLAYER_ID) return SendClientMessage(playerid, 0xFF0000FF, "Es ist kein Spieler außer dir online!");
//SetPlayerPos(player1, 195.7658,-1436.2083,12.9808);
for(new i=0; i<MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i) && !IsPlayerNPC(i))
{
if(i == player1)
{
SetPlayerPos(player1, 195.7658,-1436.2083,12.9808);
}
else
{
SetPlayerPos(i, 195.7658,-1436.2083,12.9808);
}
}
}
return 1;
}
PS: Gewöhne dir bitte ab, Vollzitate zu verwenden, das stört. Danke
Was ist der unterschied zwischen
SetPlayerTeam(playerid, test);
gTeam[playerid] = test;
PS: danke Jeffry
SetPlayerTeam ist eine Funktion
gTeam ist nur eine Variable für die Speicherung des Spielers im GF
Ich habe eine if Bedingung, wenn diese erfüllt ist, soll wenn:
1 Spieler in Team Test ist ein car spawnen mit ihm als Fahrer
2 Spieler in Team Test sind 2 cars (beide fahrer)
3 Spieler in Team Test sind 3 cars (alle fahrer)
usw.
sollten bereits alle Fahrzeuge einen Fahrer haben, sollen die Beifahrerplätze gefüllt werden, der reihe nach.
da ich das öfter brauche, wollte ich fragen ob man da eine Art array machen kann, sprich ich hab eine Liste in der 5 Autos sind,
und mit diesen Autos wird gearbeitet, also erst 5 Fahrer dann Beifahrer und falls dann noch Player in Team Test sind, sollen diese zu einer stelle geportet werden.
da ich bisher noch nicht mit arrays gearbeitet habe, habe ich keinen plan wie ich das angehen soll.
Ich habe es bereits geschafft den Spieler ein Auto zu spawnen und ihn auf den Fahrersitz zu setzen, jedoch weiß ich nicht wie ich das mache wenn mehr autos/player im team sind,
wegen der Reihenfolge und so
if(gTeam[playerid] == Test)
{
new vehicleid;
vehicleid = CreateVehicle(413,2038.8768,1415.6444,10.6058,180.7780,-1,-1,-1);
PutPlayerInVehicle(playerid, vehicleid, 0);
}
else...
PS: und ist es möglich das array dynamisch zu machen, sprich wenn 6 cars drinnen sind macht er es mit 6 und wenn 7 dann eben 7 cars
Wie kann ich ein Integer zu einem String machen?
Ungefair so? (ist aber falsch)
if(sInfo[playerid][pGeschlecht] == 1){
sInfo[playerid][pGeschlecht] = "Männlich";
} else if(sInfo[playerid][pGeschlecht] == 2){
sInfo[playerid][pGeschlecht] = "Weiblich";
}
Du kannst einen Integer nicht zu einem String machen.
Wenn, dann musst du das über eine andere Variable, die du als String (Array) deklariert hast.
Okay wie kann ich das dann mit einem Dialog machen?
Hier wird das Geschlecht gemacht:
if(dialogid == DIALOG_GESCHLECHT){
if(response){
sInfo[playerid][pGeschlecht] = 1;
ShowPlayerDialog(playerid,DIALOG_ALTER,1,"{FF9E00}Wähle dein Alter","Gebe nun dein Alter hier ein, mit welchem du auf dem Server spielen willst.\nDu kannst auch dein richtiges Alter angeben.","OK","");
} else {
sInfo[playerid][pGeschlecht] = 2;
ShowPlayerDialog(playerid,DIALOG_ALTER,1,"{FF9E00}Wähle dein Alter","Gebe nun dein Alter hier ein, mit welchem du auf dem Server spielen willst.\nDu kannst auch dein richtiges Alter angeben.","OK","");
}
return 1;
}
Du hattest schon den richtigen Ansatz.
format(player[..][geschlecht], Länge, "Text");