Funktion nicht,nur ein define.
for(new i = 1 ; i < MAX_VEHICLES ; i++) { }
Beiträge von Goldkiller
-
-
Schau dir mal bitte die Grundlagen an.
public Updater()
{
//SetTimer("Updater",20000,1); <-- überflüssig,erstellt nur 1000 von Timern.
new zeit;
gettime(zeit);
if( ( zeit > 12 ) && ( zeit < 20 ) ) // *** - Diese Zeile mit Templer's austauschen,falls Andere Öffnugnszeiten
{
Update3DTextLabelText(Fschule1, 0x006300C5, "Fahrschule [GEÖFFNET]");
Update3DTextLabelText(Fschule2, 0x006300C5, "Fahrschule [GEÖFFNET]");
}
else
{
Update3DTextLabelText(Fschule1, 0x006300C5, "Fahrschule [GESCHLOSSEN]");
Update3DTextLabelText(Fschule2, 0x006300C5, "Fahrschule [GEÖFFNET]");
}
/*
Das kann man doch auch vereinfachen und beides oben einfügen,sofern die
Öffnungszeiten die selben sind
if( ( zeit > 0 ) && ( zeit < 12 ) && ( zeit > 20 ) && ( zeit < 0 ) )
{
Update3DTextLabelText(Fschule2, 0x006300C5, "Fahrschule [GEÖFFNET]");
}
else
{
Update3DTextLabelText(Fschule2, 0x006300C5, "Fahrschule [GESCHLOSSEN]");
}
*/
return 1;
}
Templer hat dir gezeigt,wie man die Öffnungszeiten zwischen 10Uhr - 14uhr , 17Uhr - 22Uhr und 01Uhr - 4Uhr hat. Vielleicht willst du diese ja so,dann müsstest du diese Zeile einfügen,dort wo Ich es im Quellcode markiert habe. -
if(zeit < 10 || zeit > 14|| zeit < 17 || zeit > 22 || zeit < 1 || zeit > 4 )
//
if(zeit > 10 || zeit < 14|| zeit > 17 || zeit < 22 || zeit > 1 || zeit < 4 )
Die sind ja mal völlig falsch.
Nehmen wir mal an wir haben 16Uhr.zeit < 10 - FALSE
zeit > 14 - TRUE
zeit < 17 - TRUE
zeit > 22 - FALSE
zeit < 1 - FALSE
zeit > 4 - TRUEDas hilft aber niemanden weiter o0.Denn egal bei welcher Uhrzeit,irgendwo wird TRUE rauskommen,was aber wohl nicht dein Ziel war.
Mach es doch lieber so.
if( ( Zeit > 12 ) && ( Zeit < 20 ) ) { // offen von 12uhr bis 20uhr
}
else { // geschlossen
}Abgesehen davon,erstellst du 1000 von Timern.
Entferne
SetTimer("Updater",20000,1); in deinem Public.Und wie NeoPhoenix gesagt hat, wäre Update3DTextLabel viel praktischer
-
Schau dir lieber nochmal printf() und format() an,denn %s ist der Platzhalter für Strings.
printf("Farbe: %d", farbe); -
Wie Templer gesagt hat,du kannst es mit strval() machen, falls du die Farbe auch als Integer abspeicherst.
-
Dann schreib mal weiter am PAWNO Buch.Wäre wirklich sehr hilfreich ein Buch für die PAWNO IDE.
Sorry,aber wenn du schon es so erscheinen lässt, als wäre PAWNO die Sprache, kann es nicht sehr professionel werden.
PAWN ist die Sprache,PAWNO eine IDE die beim SA:MP Server mitgeliefert wird. -
Weiss ja niemand wie du die Farbe gespeichert hast, von daher relativ schwer zu sagen.
Speicherst du die Farbe als String,Int oder vllt sogar Hex ( nicht sicher ob es das bei MYSQL gibt ) . -
Du brauchst dir keine weiteren Doppelaccount machen.
-
DINI hat kein Limit.Das einzige File-System was ein Limit hat ist SII,da es einen Cache benutzt,der nur für 100 Einträge ( Standartmäßig ) groß genug ist.
-
Niemand brauch hier PAWNO Grundlagen.PAWN ist die Sprache,PAWNO nur eine IDE,damit das mal klar ist
-
Ich wollte schon seit längerem mal das Tutorial erweitern um ZCMD, hab jetzt endlich mal Zeit dafür gefunden.
zcmd
ZCMD ist ein weiterer Weg seine Commands einfach und schnell zu scripten.Die Methode funktioniert um einiges anders als dcmd.Hier wird der eingegebene Text, der bei OnPlayerCommandText() übergeben wird nicht wie bei DCMD mit allen Befehlen verglichen die ihr unter OnPlayerCommandText() habt, sondern es wird versucht ein public Funktion aufzurufen,die den Namen des Commands hat.Diese Technik wurde zum ersten mal von Y_Less vorgestellt.Allerdings wurde sie kaum benutzt,lag wohl darans,dass
Y_Less diese Technik mehr oder weniger versteckt hatte in seinem YSI Include,welches relativ wenig genutzt wurde.
Viel später kam dann eine Russe Namens ZeeX auf die Idee diese Technik zu nutzen und stellte diese
im offiziellen SA:MP Forum vor.Seit der ersten Version wurde sie um einiges verändert und ist nun
neben DCMD die wohl meist genutzte Command-Technik.Alle darauf folgenden XYZ-Commands sind nur basierten auf ZCMD und auch nicht schneller / besser,deshalb empfehle
Ich beim Original zu bleiben.Die Version von ZeeX ist hier zu finden: [INC] zcmd 0.3.1 | Fast & Simple Command Processor (updated 30/10/2009)
Es ist generell kein großer Aufwand,die Commands von dcmd in zcmd umzuschreiben.Nehmen wir mal an,unser Befehl sieht so aus ( Bereits im Tutorial erstellt ).
public OnPlayerCommandText(playerid, cmdtext[])
{
dcmd(kick,4,cmdtext);
return 0;
}
dcmd_kick(playerid,params[]) {
new
sGrund[128],
pID;
if(sscanf(params, "dz",pID,sGrund)) {
return SendClientMessage(playerid,COLOR_RED,"USAGE: /kick [playerid] ([grund],optional)");
}
if(!IsPlayerConnected(pID)) {
return SendClientMessage(playerid,COLOR_RED,"Kein Spieler mit angegebener ID Online");
}
new
ThePlayer[MAX_PLAYER_NAME],
string[128];
GetPlayerName(pID,ThePlayer,sizeof(ThePlayer));
format(string,sizeof(string),"%s (ID %d) wurde vom Server gekickt,Grund: %s",ThePlayer,pID,sGrund[0] ? sGrund : "<Kein Grund>");
SendClientMessageToAll(COLOR_YELLOW,string);
Kick(pID);
return 1;
}
Wer dcmd verstanden hat, dem sollte klar sein, dass /kick der eigentliche Befehl ist.
Um es nun in ZCMD umzuschreiben,sollte man zuerst den Teil unter OnPlayerCommandText() löschen ( dcmd(kick,4,cmdtext); )Den DCMD selber muss man natürlich auch verändern.Sind aber auch nur kleine Veränderungen.
Aus dem
dcmd_kick(playerid,params[]) {
wird dabei :
COMMAND:kick(playerid,params[]) {
Viel muss man also nicht ändern.Man ersetz das dcmd_ aus dcmd_kick() durch COMMAND:.
Daraus wird dann also COMMAND:kick()Deshalb erhält man nun das folgende Script:
public OnPlayerCommandText(playerid, cmdtext[])
{
// dcmd(kick,4,cmdtext); - Brauchen wir nicht mehr
return 0;
}
COMMAND:kick(playerid,params[]) {
new
sGrund[128],
pID;
if(sscanf(params, "uz",pID,sGrund)) {
return SendClientMessage(playerid,COLOR_RED,"USAGE: /kick [playerid] ([grund],optional)");
}
if(!IsPlayerConnected(pID)) {
return SendClientMessage(playerid,COLOR_RED,"Kein Spieler mit angegebener ID Online");
}
new
ThePlayer[MAX_PLAYER_NAME],
string[128];
GetPlayerName(pID,ThePlayer,sizeof(ThePlayer));
format(string,sizeof(string),"%s (ID %d) wurde vom Server gekickt,Grund: %s",ThePlayer,pID,sGrund[0] ? sGrund : "<Kein Grund>");
SendClientMessageToAll(COLOR_YELLOW,string);
Kick(pID);
return 1;
}Man muss aber auch auf Kleinigkeiten im Script achten.Solltet ihr ZCMD in einem Filterscript benutzen,
solltet ihr sicher stellen,dass ihr im Kopf eures Scriptes, das Script als Filterscript definiert.
#define FILTERSCRIPT
Das ist deshalb nötig,da bei ZCMD einige Callbacks wichtig sind für das funktionieren des Technik.Wie das Ganze im Detail funktioniert sollte für die meisten unwichtig sein.Auch sollte man jetzt darauf achten,dass man nur mit isnull() überprüft ob der übergebene Text in
params[] leer ist.Die Funktion isnull() ist übrigens im ZCMD Include enthalten.
Bedeutet im Klartext,keine Abfragen mehr wie:if(!params[0]) { }
if(!strlen(params)) { }Stattdessen müsst ihr es jetzt so machen
if(isnull(params)) { }Falls ihr mehrere Commandhandler habt für eine Funktion, müsst ihr ebenfalls kleine Änderungen in eurem Script vor nehmen.
Nehmen wir an /test ist der eigentliche Command den wir auch über /testaufruf aufrufen sollen,sieht es so aus.COMMAND:testaufruf(playerid,params[]) {
cmd_test(playerid,params);
}
Dabei ist zu beachten,dass der zusätzliche Command-Handler ( testaufruf ) nach dem
Command im Script kommt, zu dem es weiterleiten soll.Heisst also:
COMMAND:test(playerid,params[]) {
printf("COMMAND:test(%d,%s)",playerid,params);
return 1;
}
COMMAND:testaufruf(playerid,params[]) {
return cmd_test(playerid,params);
}Ich selber benutze auch nur noch die ZCMD Methode.Im Endeffekt muss aber jeder für sich selber entscheiden welche Methode ihm am besten gefällt.
-
Ließ dir den Thread durch, da steht alles.
Zitatweil wenn z.B. pupsilon nicht angegeben wird, wird es zu 7 gemacht aber der Spieler wird's trotzdem angeben müssen.
Ganz klar Nein.
Der Spieler muss es nicht angeben,alle Platzhalter die Groß ( D ) geschrieben werden,sind Optional.Heisst also, sie brauchen nicht angegeben zu werden.ZitatAber ich denke meins wird funken, ich werds mal testen...
Tu dir keinen Zwang an :p -
Schau dir mal SSCANF 2.0 Plugin an.
Ich empfehle dir stark, dir die neue Anwendung der Platzhalter anzuschauen.
Damit ( falls Ich dich richtig verstanden habe ) , ist deine Sache leicht zu bewältigen.if(sscanf(params,"D(5)D(7)D(0)",ypsilon,pupsilon,rock)) { }
-
<< Zurück zu Teil 1 des Tutorials
Im ersten Teil des Tutorials haben wir bereits gelernt,wie wir mit DCMD umgehen.Durch DCMD ist der Command nun
bereits leichter gestaltet,doch das einfache durchsuchen des Befehls nach zusätzlichen Informationen wurde noch nicht
großartig erleichtert.
Dazu jetzt mehr in Teil 2.SSCANF
sscanf wurde von Alex "Y_Less" C. erstellt.Eine sehr bekannte Person für jeden der sich des öfteren im SA:MP Forum rumtreibt.
Zunächst einmal braucht ihr den sscanf - Code
sscanf code - SA-MP
Es gibt bereits ein SSCANF Plugin, womit die Performence gesteigert wurde sowie viele neue Verbesserung eingeführt wurden.
SSCANF Plugin
Ich rate jedoch sich nicht sofort mit dem Plugin zu beschäftigen, da es teilweise für Anfänger schwieriger sein kann,die neuen Platzhalter zu verstehen.Nun aber weiter im eigentlichem Tutorial
Viel umschreiben muss man jetzt nicht mehr vom Befehl wie wir in ihn Teil 1 geschrieben haben.
dcmd_kick(playerid,params[]) {
new
pID;
if(sscanf(params, "u",pID)) {
return SendClientMessage(playerid,COLOR_RED,"USAGE: /kick [playerid]");
}
if(!IsPlayerConnected(pID)) {
return SendClientMessage(playerid,COLOR_RED,"Kein Spieler mit angegebener ID Online");
}
Kick(pID);
SendClientMessage(playerid,COLOR_YELLOW,"Erfolgreich Spieler vom Server gekickt!");
return 1;
}
Jetzt müsste euch die Zeileif(sscanf(params, "u",pID)) {
auffallen.Diese Zeile spart euch nun das ganze getue mit strtok,strget oder Sonstigem.
sscanf brauch zwei Parameter.Der erste Paramter ist der String in dem gesucht werden soll nach etwas.Da wir dcmd benutzten ist es params.Der zweite Paramter ( "u" ) ist der Typ der Information.Es kann so ziemlich alles sein,was man brauch.String,Integer,Float,Hex,Char oder sogar ein Spieler.Dabei steht der Platzhalter "u" für einen Spieler,es kann sowohl der Name als auch die SpielerID angeben werden.Beides ist möglich.Alle Datentypes mit ihren Charakterkürzeln gibt es hier:
Fast Commands - SA-MP - Data typesJetzt gibt es aber noch weitere Paramter.Die Anzahl der weiteren Paramter sollte gleich zu der Anzahl sein wie die Anzahl an Datentypes die ihr im String sucht.
In unserem Beispiel handelt es sich um "u".Demnach brauchen wir einen weiteren Parameter, dabei handelt es sich um den Spieler an dem wir die Operation durchführen wollen.sscanf(params, "udd",pID,WeaponID,Ammo) // /giveweapon [playerid] [weaponid] [ammo]
sscanf(params, "s",sAnnounce) // /announce [text]
sscanf(params, "f",fGrav) // /gravity [Float:Anziehungskraft]Wird ein Spieler ( Name oder ID ) gefunden in params,wird er pID zugewiesen.Sehr praktisch wenn ihr mich fragt.Sollte jetzt gültiger Wert für den Spielrnamen oder die SpielerID im String params sein,wird sscanf irgendwas returnen nur nicht 0.
Nun wollen wir den Command etwas ausbreiten.Wir wollen einen Grund des Kicks als Grund mit angeben.Da der Grund für einen kick normalerweise ein Text ist,müssen wir jetzt als Datentype "s" oder "z".Da "z" ein Optionaler String ist,lassen wir den erst aus.Zu dem komm ich gleich ;).
Wir brauchen natürlich noch eine neue Variable (ein String) ,in der wir den Grund speichern.Demnach sieht es so aus mit einer kleinen Extra Nachricht:
dcmd_kick(playerid,params[]) {
new
sGrund[128],
pID;
if(sscanf(params, "us",pID,sGrund)) {
return SendClientMessage(playerid,COLOR_RED,"USAGE: /kick [playerid] [grund]");
}
if(!IsPlayerConnected(pID)) {
return SendClientMessage(playerid,COLOR_RED,"Kein Spieler mit angegebener ID Online");
}
new
ThePlayer[MAX_PLAYER_NAME],
string[128];
GetPlayerName(pID,ThePlayer,sizeof(ThePlayer));
format(string,sizeof(string),"%s (ID %d) wurde vom Server gekickt,Grund: %s",ThePlayer,pID,sGrund);
Kick(pID);
return 1;
}
Wenn das nicht einfach war.Keine große Veränderung der eigentlichen sscanfs-Zeile und schon ein neuer Parameter.
Wir können den Grund auch optional angeben,also:Es muss kein Grund als Kick angegeben werden,nur wenn man möchte.
Dafür gibt es einen extra Datentype,das ist "z".Achtung: Dies gilt nur für die PAWN Version SSCANF
In der Plugin Version von SSCANF sind die Platzhalter für einen Datentyp Anders!
http://forum.sa-mp.com/showthread.php?t=120356Also ändern wir erst einmal die sscanf Zeile:
if(sscanf(params, "uz",pID,sGrund)) {
Das tolle daran ist,wird kein Grund angegeben returnt sscanf nicht 0
dcmd_kick(playerid,params[]) {
new
sGrund[128],
pID;
if(sscanf(params, "uz",pID,sGrund)) {
return SendClientMessage(playerid,COLOR_RED,"USAGE: /kick [playerid] ([grund],optional)");
}
if(!IsPlayerConnected(pID)) {
return SendClientMessage(playerid,COLOR_RED,"Kein Spieler mit angegebener ID Online");
}
new
ThePlayer[MAX_PLAYER_NAME],
string[128];
GetPlayerName(pID,ThePlayer,sizeof(ThePlayer));
format(string,sizeof(string),"%s (ID %d) wurde vom Server gekickt,Grund: %s",ThePlayer,pID,sGrund[0] ? sGrund : "<Kein Grund>");
SendClientMessageToAll(COLOR_YELLOW,string);
Kick(pID);
return 1;
}
Was es mit dem sGrund[0] ? sGrund : "<Kein Grund>" auf sich hat möchte ich nicht genau erklären.Kurz gesagt,wenn das was vor dem "?" true ist (sGrund[0]) ,wird das nach dem "?" eingesetzt ( sGrund ),ansonsten das nach dem ":" ( "<Kein Grund>" ).Demnach,falls sGrund ein leerer string ist,also false,wird "<Kein Grund>" eingesetzt anstatt sGrund.Nun solltet ihr verstanden haben wie dcmd in Verbindung mit sscanf funktioniert.
Hier noch ein weiterer Beispiele:
public OnPlayerCommandText(playerid, cmdtext[])
{
dcmd(kick,4,cmdtext);
dcmd(sethealth,9,cmdtext);
dcmd(announce,8,cmdtext);
return 0;
}
dcmd_sethealth(playerid,params[])
{
new
pID,
Float:fHP;
if(sscanf(params, "uf",pID,fHP)) {
return SendClientMessage(playerid,COLOR_RED,"USAGE: /sethealth [playerid] [healthpoints]");}
if(!IsPlayerConnected(pID)) {
return SendClientMessage(playerid,COLOR_RED,"Kein Spieler mit angegebener ID Online");}
new
ThePlayer[MAX_PLAYER_NAME],
GivePlayer[MAX_PLAYER_NAME],
string[128];
GetPlayerName(pID,GivePlayer,sizeof(GivePlayer));
GetPlayerName(playerid,ThePlayer,sizeof(ThePlayer));
SetPlayerHealth(pID,fHP);
format(string,sizeof(string),"%s (ID %d) Healtpoints wurden von %s (ID %d) auf %.1f gesetzt!",GivePlayer,pID,ThePlayer,playerid,fHP);
SendClientMessageToAll(COLOR_YELLOW,string);
return 1;
}
dcmd_announce(playerid,params[]) {
new
sAnnounce[128];
if(sscanf(params, "s",sAnnounce)) {
return SendClientMessage(playerid,COLOR_RED,"USAGE: /announce [text]");
}
GameTextForAll(sAnnounce,3*1000,3);
return 1;
}
dcmd_kick(playerid,params[]) {
new
sGrund[128],
pID;
if(sscanf(params, "uz",pID,sGrund)) {
return SendClientMessage(playerid,COLOR_RED,"USAGE: /kick [playerid] ([grund],optional)");
}
if(!IsPlayerConnected(pID)) {
return SendClientMessage(playerid,COLOR_RED,"Kein Spieler mit angegebener ID Online");
}
new
ThePlayer[MAX_PLAYER_NAME],
string[128];
GetPlayerName(pID,ThePlayer,sizeof(ThePlayer));
format(string,sizeof(string),"%s (ID %d) wurde vom Server gekickt,Grund: %s",ThePlayer,pID,sGrund[0] ? sGrund : "<Kein Grund>");
SendClientMessageToAll(COLOR_YELLOW,string);
Kick(pID);
return 1;
}
Wer sich trotzdem nochmal zu sscanf schlau machen möchte,sollte diesen Link hier anklicken:
Fast Commands - SA:MP - sscanfIch hoffe mal das ganze ist verständlich erklärt und von nun an werden einige mehr in diesem Forum auf dcmd + sscanf umsteigen.
Goldkiller
//Edit ( 3.10.2010 ) : Parameter u wird nun für Spieler genutzt anstatt d
-
Ich will ja nicht für mein Tutorial werben,aber dazu hab Ich bereits vor langer Zeit eins geschrieben.
>> Klickdcmd(goto, 4, cmdtext);
Du hast die 4 nicht erklärt. -
So ist es richtig als DCMD Killer_Kater, trotzdem solltest du auch darauf achten wieviele Strings du erstellst.
new string1[256];
new string2[256];
new string3[256];
Es würde auch reichen
new str[128];
Danach
format(str,sizeof(str),"Du hast ID:%d %d WantedPunkte gegeben![Grund:%s]",pID,anzahl,grund);
SendClientMessage(playerid,COLOR_RED,str);
format(str,sizeof(str),"ID:%d %d hat dir %d WantedPunkte gegeben![Grund:%s]",playerid,anzahl,grund);
SendClientMessage(playerid,COLOR_RED,str);
format(str,sizeof(str),"HQ:%d hat %d %d WantedPunkte gegeben, weil %s",playerid,pID,anzahl,grund);
for(new i = 0; i < MAX_PLAYERS; i++)
{
if(IsACop(i))
{
SendClientMessage(i,COLOR_RED,str);
}
}[iP]Zabus,diese Grafik ist ja mal ein Witz.
http://www.kleiner-opa.de/pic/test.png
Mich würde ja mal dazu der Code interessieren, mit dem es getestet wurde oder die genauen Timings.Find ich persöhnlich immernoch lustig zu sehen wie jmd da betreitet es gäbe ZCMD nicht . -
Weiß jemand für mein Problem eine Lösung?
Ich schreibe es nochmal:Bekomme "array must be indexed (deletorname)"
new deletorname[MAX_PLAYER_NAME];
GetPlayerName(playerid, deletorname, sizeof(deletorname));
if(WebsiteData[1][SiteCreat] == deletorname) <<< In dieser Zeile kommt der Error
Sollte WebsiteData[1][SiteCreat] ein String sein,dann musst du mit strcmp() vergleichen.
if(!strcmp(WebsiteData[1][SiteCreat],deletorname,true)) { } -
Sehr gute Beschreibungen
Ich zitier mal:Zitat#pragma extra information
A "pragma" is a hook for a parser to specify additional settings, such as warnings or extra capabilities.
Common #pragmas are:align
amxlimit
amxram
codepage
ctrlchar
deprecated
dynamic
library
overlay
pack
rational
semicolon
tabsize
unused
Alle infos auch pawn-lang.pdf.Das Kapitel dazu ist "Directives". -
if(sscanf(cmdtext, "uds",pID,anzahl,grund)) {
cmdtext ist:
Zitat/st Peter 2 Ein Test
oderZitat/straftat Peter 2 Ein Test
Es wird nach 3 Parametern gesucht.
Das Problem ist,der erste Parameter wird von sscanf() als /straftat erkannt./straftat passt aber nicht in den u Platzhalter,der nur für Spielername / SpielerID gedacht ist.Deshalb wird pID auch zu INVALID_PLAYER_ID ( Intern durch sscanf() ).
Danach folgt das Peter als Integer gelesen werden soll. Peter ist aber keine Zahl,funktioniert als auch nicht es in anzahl zu speichern.
Folglich wird dann 2 Ein Test als String gelesen.Das klappt,trotzdem war das ja nicht die Idee hinter dem ganzen. -
Ist auch richtig so,dass kein Spieler gefunden wird.
if(sscanf(cmdtext, "uds",pID,anzahl,grund)) {
return SendClientMessage(playerid,COLOR_RED,"USAGE: /st [playerid][Anzahl an WantedPunkten][grund]");
}
Du darfst da auch nicht in cmdtext suchen.
Denn cmdtext wird vermutlich etwas sein wie :Zitat/strafttat Peter 2 Eine Testverwarnung
Deshalb mach lieber mal,auch wenn Ich dir lieber zu DCMD oder ZCMD raten würde.
//Removed//Edit:
Moment,bin gerade etwas verwirrt.cmd dürfte auch nicht funktionieren,denn cmd ist doch auch nur mit strtok ein Teil von cmdtext,eben "/straftat".new
_pos;
_pos = strfind(cmdtext," ");
if(sscanf(cmdtext[_pos], "uds",pID,anzahl,grund)) {
return SendClientMessage(playerid,COLOR_RED,"USAGE: /st [playerid][Anzahl an WantedPunkten][grund]");
}