1. Heißt das, dass man immer static statt new nehmen soll?
Nein...da du ja nicht immer Speicherplatz reservieren willst...
Sondern nur dann, wenn es entweder um große Strings geht..die du oft nutzt...
oder kleine Strings die du sehr oft nutzt...
1. Heißt das, dass man immer static statt new nehmen soll?
Nein...da du ja nicht immer Speicherplatz reservieren willst...
Sondern nur dann, wenn es entweder um große Strings geht..die du oft nutzt...
oder kleine Strings die du sehr oft nutzt...
wie lasse ich jede Linie ausführen?
Was genau meinst du jetzt damit....
Unter OnDialogResponse...prüfst du über das listitem welche Route er ausgewählt hat..und lässt ihn darüber dann einen Checkpoint anzeigen...
Und einen Countdown kannst du z.B. so realisieren:
//Countdown-Starten
SetTimerEx(!"@countdown", 999, 0, !"i", playerid);
//Das hier als forward/public ansehen
@countdown(i);@countdown(i)
{
static x;
if(++x == 10)
{
GameTextForPlayer(i, "10~n~GoGoGo", 1000, 5);
//Hier dann machen..was passieren soll...
return 1;
}
new tmp[4];
valstr(tmp,x);
GameTextForPlayer(i, tmp, 1000, 5);
return SetTimerEx(!"@countdown", 999, 0, !"i", i);
}
Alles anzeigen
static oder new?
static, dadurch werden nicht permanent 2048 Cells (8192 Bytes = 8 KiloByte) pro Aufruf angefordert, sondern reserviert.
Das spart eine Menge Zeit ![]()
Wobei du eigentlich versuchen solltest alles zu packen.
Du musst doch nicht unbedingt format verwenden? ![]()
Verstehe nicht so genau...wieso du darauf zurückgreifen musst ![]()
Denn wenn du z.B. einen Namen adden willst geht das auch so:
new packed_name[MAX_PLAYER_NAME char];
strpack(packed_name, GetName(playerid));
//DialogString = !""; //Wichtig das dient als reset (aber da wir darunter schon was setzen, brauchen wir das nicht)
DialogString = !"Willkommen ";
strcat(DiaogString, packed_name);
strcat(DialogString, !" :)\nSchön, dass sie zu uns gefunden haben!");
Ist zwar ein bisschen umständlicher...aber du büßt nur minimale Performanz ein..und sparst dir 6 KiloByte von 8 ![]()
Und den verwende ich dann jetzt, richtig?
Einfach als ganz normalen String...
format(DialogString,sizeof(DialogString),"Haaaaaaaaaaaaaaalo\nHaaaaalo %s", GetName(playerid));
ShowPlayerDialog(playerid,0,0,"Caption", DialogString, "ok", "");
Wie gesagt, kannst das char weglassen, dann geht das klar ![]()
Also nur im strcat benutzen?
...das wäre am sichersten oder eine direkte zuweisung ![]()
Wie new test[] = !"Hi";
Du solltest das nicht global nutzen!
Da kann es zu Fehlern kommen...zwar meint man immer, Pawn ist in der VM Single-Threaded was auch so ist, allerdings können Callbacks sogut wie zeitgleich für Spieler ausgeführt werden.
Besser wäre zu versuchen, Strings zu packen oder einen großen statischen Speicherbereich im Callback zu allozieren.
//Ganz oben im OnDialogResponse
static DialogString[2048 char]; //Mit char wäre es am schönsten ^^ geht aber auch ohne xD
Nein format kannst du da nicht nutzen ![]()
[900 char] bedeutet, dass eine Cell (wo du hier 900 erstellst) nicht 4 Bytes groß ist, sondern nur 1 Byte ![]()
Wenn du format nutzen musst, dann musste normale Cells verwenden ![]()
Als erstes rate ich dir von dcmd ab...nutze ocmd/zcmd/ycmd/rcmd..iwas anderes außer dcmd ![]()
Als nächstes schreib den code mal so (return..immer klein):
dcmd_setfraktion(playerid,params[])
{
if(!IstSpielerAdmin(playerid, 5)) return SendClientMessage(playerid,ROT,"Du bist kein Admin!");
new pid, frakid;
if(sscanf(params,"ud",pid,frakid)) return SendClientMessage(playerid,GELB,"Verwendung : /setfraktion [ID][Fraktions ID]");
if(!IsPlayerConnected(pid)) return SendClientMessage(playerid,ROT,"Ungültiger Spieler");
if(IstSpielerInFraktion(pid,frakid) == frakid) return SendClientMessage(playerid,ROT,"Der Spieler ist bereits in der Fraktion");
sSpieler[pid][Fraktion] = frakid;
SendClientMessage(pid,BLAU,"Du bist nun in der Fraktion");
SendClientMessage(playerid,BLAU,"Du hast den Spieler in die Fraktion gepackt");
return 1;
}
Alles anzeigen
Jaa es heißt nicht /n sondern \n ![]()
Die Anderen Klappen kaum hab ich einen Langen Text spinnt es rum?
Jaa das liegt am Compiler
Du musst des zum Beispiel so machen:
new packer[900 char];
strcat(packer,!"Artikel 4: Fragen und Meldungen\n\nEs gibt zwei Methoden, um Fragen bzw. Anliegen an die Administration zu senden.");
strcat(packer,!"\n\nCheater,Buguser,sinnloses Deathmatsch und Dinge in die Richtung können direkt\n");
strcat(packer,!"per /a <Text> in den Admin-Chat gesendet werden,admit diese schnell bearbeitet werden.");
strcat(packer,!"\n\nBei anderen Anliegen wie z.B. bei Fragen wende dich bitte mit /sup <Frage>");
strcat(packer,!"\nan einen Communityhelfer,Suppoter oder Administrator.\n\n");
strcat(packer,!"Die Ticketanzahl ist aus scriptteschnischen Gründen limitiert, es kommt selten bis nie vor, dass du warten musst.");
strcat(packer,!"\nBitte gedulde dich, wenn du in dem Moment kein Ticket erstellen kannst, versuche es eventuell später noch einmal");
strcat(packer,!"\nund schreibe es nicht in den /a-Chat, da es sein kann, das du dafür gemutet wirst.\n\n");
strcat(packer,!"Formuliere dein Anliegen bitte direkt und nicht so: Frage, Hilfe und Sonstiges.\n");
strcat(packer,!"Das hilft unserem Team nicht, dir schnell zu helfen. Und dass sollte dir ja auch wichtig sein.");
ShowPlayerDialog(playerid, DIALOG_HELP4, DIALOG_STYLE_MSGBOX, !"Hilfe", packer, !"Schließen", !"");
Alles anzeigen
Das char packed den string, dadurch sparst du einfach Speicher ![]()
Dieses ! sagt einfach nur, dass der String gepackt werden soll ![]()
Kannst du auch ideal so bei Texten im Dialog verwenden ![]()
...ja dann prüf was passiert ![]()
Mach n print-Debug und schau..was aufgerufen wird..und so ![]()
Doch...das kannst du da einfach drunter klatchen..schau dir meinen code an..da unter die if-Abfrage kommt das alles mit dem IsPlayerConnected ![]()
In dem Fall musste kein if(listitem) checken, da wir die ID über den inputtext filtern und der je nach listitem angepasst ist ![]()
dini hat nichts mit PVars zu tun ._.
Das eine ist eine Speicherung, das andere ist quasi eine Speicherung im RAM und nicht im Stack wie bei einer Variable ![]()
Du machst quasi folgendes:
SetPVarInt(playerid, "lohn_id", pID);
Und dann öffnest du einen neuen Dialog und dort setzt du dann den lohn so:
new pID = GetPVarInt(playerid, "lohn_id"), lohn = strval(inputtext);
DeletePVar(playerid, "lohn_id"); //Wichtig! Hier Ram reinigen
//Und nun haste die pID = Der Spieler wo der Lohn gesetzt werden soll...lohn = der Betrag vom Lohn :)
Setze die ID in ein PVar und Frag die im neuen Dialog ab ![]()
Hier mal eine Variante:
if(listitem == 2)
{
new String[1500] = "ID\tName\tLohn";
for(new i=GetPlayerPoolSize(); i!=-1; i--)
{
if(!IsPlayerConnected(i) || SpielerInfo[i][Fraktion] != SpielerInfo[playerid][Fraktion]) continue;
format(String, sizeof(String),"%s\n%d\t%s\t%d$",String,i,SpielerName(i),SpielerInfo[i][Lohn]);
}
ShowPlayerDialog(playerid, FrakEinstell3, DIALOG_STYLE_TABLIST_HEADERS,"Lohn",String,"Ok","");
}
und dann so:
if(dialogid == FrakEinstell3)
{
if(!response) return 1;
new pID,tmp[3];
tmp[0] = inputtext[0];
if('0' <= inputtext[1] <= '9') tmp[1] = inputtext[1];
if('0' <= inputtext[2] <= '9') tmp[2] = inputtext[2];
pID = strval(tmp);
if(!IsPlayerConnected(pID)) return SCM(playerid,-1,"Nicht mehr on!");
//pID ist nun die ID die ausgewählt wurde..
}
Alles anzeigen
Hier schreibs mal so:
if(dialogid == FrakEinstell)
{
if(!response) return 1;
new pID = strval(inputtext);
if(!IsPlayerConnected(pID)) return SendClientMessage(playerid, Rot,"Spieler nicht verfügbar");
printf("%i PlayerID(Wird eingeladen)",pID); //Debug
if(SpielerInfo[pID][Fraktion] >= 1) return SendClientMessage(playerid, Rot,"Spieler ist bereits in einer Fraktion");
new string[200];
switch(SpielerInfo[playerid][Fraktion])
{
case 0: string ="Zivilisten";
case 1: string ="LSPD";
case 2: string ="Bundeswehr";
}
format(string, sizeof(string),"Leader %s hat dich zum Mitglieder der Fraktion %s gemacht",SpielerName(playerid),string);
SendClientMessage(pID, Gruen, string);
format(string, sizeof(string),"Du hast %s zum Mitglied deiner Fraktion gemacht",SpielerName(pID));
SendClientMessage(playerid, Gruen, string);
SpielerInfo[pID][Fraktion] = SpielerInfo[playerid][Fraktion];
return 1;
}
Alles anzeigen
Wenns nicht aufgerufen wird...ist die dialogid falsch ![]()
Nun also static kannst du unter 2 Bedingungen verwenden.
1. Wenn etwas konstant ist und du in einer Funktion oder einem Callback verwendest. Dadurch wird nicht neuer Speicher wieder angefordert (so wie es bei new ist) sondern das bleibt statisch im Speicher.
Zum Beispiel kannst du da auch einen Zähler machen:
Wenn du jetzt zum 1. Mal test() aufrufst, wird dir 0 ausgegeben..beim 2. mal 1 usw...
2. Du kannst static auch nutzen um einen Scope (zugriffs beschränkung / Sichtbarkeit) zu erzeugen...
In Includes zum Beispiel solltest du static nehmen, damit keine Variablennamen überschneidung mit dem Gamemmode stattfindet.
Das ! bei einem String packed diesen. Das bedeutet wenn man z.B. new string[5]; macht werden 5 Cells reserviert. Eine Cell hat 4 Bytes, also macht das 5 * 4 Bytes = 20 Bytes die man hier reserviert.
Bei einem packed String ist das new string[5 char]; und hier verbraucht die Cell nur einen Byte und nicht 4.
Das kann man generell auch in Funktionen nutzen (außer z.B. format) und dann spart man einfach speicher.
Dieses ! sagt einfach nur, dass der String gepackt werden soll.
Es gibt 2 Möglichkeiten Funktionen als public zu deklarieren.
Entweder über ein public oder über ein @.
Das ist das selbe nur weniger zu schreiben und das static sagt nur, dass das z.B. nicht von einer Include o.ä. aus aufgerufen werden kann...das verkleinert quasi (wie oben erwähnt) den Scope
Achso und das steht 2x da...weil das 1.mal vom Compiler als forward interpretiert wird ![]()
Mach es so:
new start,ende;
start = CreateObject(...); //Dein erstes Objekt
CreateObject(...); //Hier zwischen alle anderen Objekte
ende = CreateObject(...); //Dein letztes Objekt
Dann kannst du da so dadurch Loopen:
Hier auch eine Möglichkeit wie du es machen könntest:
public OnPlayerDisconnect(playerid, reason)
{
static const dc[3][] ={"(Timeout/Crash)","(Verlassen)","(Kick/Ban)"};
new Float:x, Float:y, Float:z, tmp[15 + MAX_PLAYER_NAME + 10], h,m,s;
gettime(h,m,s),GetPlayerPos(playerid, x, y, z);
GetPlayerName(playerid, tmp, MAX_PLAYER_NAME);
format(tmp,sizeof(tmp),"%s\n%s\n%02d:%02d:%02d", tmp, dc[reason], h,m,s);
SetTimerEx( !"@destroy_Logout",1000*30,0,!"ii",
CreatePickup(1275, 23, x, y, z, GetPlayerVirtualWorld(playerid)),
_:Create3DTextLabel(tmp, -1, x, y, z, 20.0, GetPlayerVirtualWorld(playerid), 1));
return 1;
}
static @destroy_Logout(a,Text3D:b);@destroy_Logout(a,Text3D:b)
{
DestroyPickup(a),Delete3DTextLabel(b);
return 1;
}
Alles anzeigen
Dann schenkst dir paar Variablen ![]()