warum ich soviel weitergeleitet werde
Zeig uns doch mal den Code, ohne den, können wir dir schlecht helfen.
warum ich soviel weitergeleitet werde
Zeig uns doch mal den Code, ohne den, können wir dir schlecht helfen.
Gibts eine einfache Möglichkeit wenn ich bspw pGeld = 20000 habe, dass ich es bei einer Übersicht für den Spieler mit einen Punkt anzeigen lassen (also ab den 1000er) also: 20.000 ohne das Geld System ändern zu müssen?
Hatte dafür mal eine Funktion geschrieben gehabt:
stock sMoney(geld)
{
new str[24],i;
valstr(str,geld),i=(geld > 0) ? strlen(str)-3 : strlen(str)-4;
for(; i>0; i-=3) strins(str,".",(geld > 0) ? i : i+1,24);
return str;
}
Nutzung einfach so:
format(string,sizeof(string),"Habe soviel Geld: %s$",sMoney(pGeld)); //Output: Habe soviel Geld: 20.000$
Hallo Brotfische,
oft sehe ich hier ein großes Missverständnis von Includes und Code-Trennungen.
Deshalb möchte ich hier noch einmal versuchen ein wenig mit diesen Fehlern aufzuräumen.
Was ist eigentlich ein Include?
Viele wissen dies nicht. Viele denken, das ist etwas ganz anderes als eine .pwn Datei, schließlich steht da ja .inc.
Allerdings ist das ein großes Missverständnis, denn im Endeffekt ist es identisch.
Die Endung soll nur symbolisieren, dass es sich um ein Include handelt und kein eigenständiges Skript.
Was ist der Unterschied?
Ein eigenständiges Skript wird kompiliert. Ein Include wird nicht kompiliert.
Wieso muss ein Include nicht kompiliert werden?
Ganz einfach, stellen wir uns mal folgende Situation vor:
//Im Gamemode
#include <a_samp>
#include <meinInclude>
main() {
print("%d",GetMyFunction());
}
//In der Datei - meinInclude.inc
stock GetMyFunction()
{
return 1;
}
Alles anzeigen
Kompilieren wir jetzt den Gamemode, sieht das nach dem pre-compile Prozess so aus:
//Hier würde alles stehen, was in a_samp steht.
stock GetMyFunction()
{
return 1;
}
main() {
print("%d",GetMyFunction());
}
Wir sehen also, es wird "einfach nur" (soo leicht ist das auch nicht, aber dazu später mehr) in die Datei kopiert.
Deshalb müssen wir Includes nicht kompilieren, da sie vom Gamemode kompiliert werden.
Und deshalb müssen wir in den Includes z.B. auch nicht mehr #include <a_samp> schreiben, da ja das schon im Gamemode steht und das somit auch für das Include gilt.
Was bringt das jetzt?
Das wurde ja schon oft gesagt, man kann nun viele Sachen auslagern.
Okay, aber was genau bedeutet das?
Logikfehler
Viele machen hier einen großen Logikfehler.
Da viele sich die Struktur ihres Gamemodes bei einem Godfather abschauen, verstehen sie oft nicht, wieso diese so schlecht ist.
Auf den Ersten Blick sieht das ja auch gut aus, ich meine, alle defines Oben, alle Variablen oben, alle Commands und publics in der Mitte und ganz unten alle "stock - Funktionen".
Ja cool, jetzt wo wir also Includes nutzen können, packen wir alle Variablen in ein Include, alle Commands, alle publics und alle "stock - Funktionen" und voila. Skript aufgeräumt xD
(No Joke, das machen sehr viele und sind fest von dieser Struktur überzeugt).
Wieso ist das aber schlecht?
Genau das versuche ich jetzt hiermit zu vermitteln, das ist NICHT der Sinn oder Vorteil eines Includes.
Da könnte man sich diesen ganzen Prozess gleich schenken.
Denn denken wir das weiter und es entsteht jetzt ein Fehler beim Haussystem.
Wie finden wir in so einem System den Fehler?
Ja Herzlichen Glückwunsch, jetzt sogar noch schlechter, da wir in 4 Dateien Suchen, alle Variablen dafür finden müssen, alle Funktionen, alle Befehle und überall in jedem public steht mal ein fitzelchen Code von dem System xD
Kein Wunder also, dass soviele Skripte verbuggt sind, wie will man da auch irgendwas finden.
Deshalb posten hier auch so viele Menschen 500 Zeilen Code und sagen, ja wo ist denn da der Fehler, bla bla funktioniert nicht.
Was wäre ein besserer Ansatz?
So, hier kommt jetzt das Wichtige.
Man packt ein einzelnes System in ein Include.
Und damit meine ich nicht nur den Hauptteil des Systems, sondern ALLES.
Und um noch einen drauf zu setzen, macht sowas:
//Include
static alleMeineVariablen;
static stock FunktionNurHier() { }
stock SetVar(x)
{
alleMeineVariablen = x;
}
CMD:fürDasInclude(playerid) {
}
Alles anzeigen
Hier sehen wir sehr viel static.
Das hat mehrere Gründe:
Denn wenn man dann einen Fehler hat, weiß man genau, wo man suchen muss.
Zusammenfassung
Weg von der Trennung von Bezeichnungen, wie new, public, stock...
Diese Trennung bringt rein gar nichts, man muss die LOGIK in einem Gamemode trennen.
Dafür eigenen sich Includes ideal.
Es sind im Endeffekt auch nur .pwn Dateien, die ihr mit Pawno schreiben könnt.
Und kompiliert, wird nur das Gamemode.
Zusätzliche Informationen:
Schneller & strukturierter skripten
Es ist auch nicht notwendig, dass ihr ein Selfmade anfangt und das dann konsequent macht (obwohl das ser sinnig wäre).
Ihr könnt auch anfangen neue Systeme, die ihr in ein GF implementiert, versucht so umzusetzen.
In diesem Sinne, ich hoffe ich sehe bald mehr Leute die das nutzen und schönere Fragen in der Scripting Base.
Mit freundlichen Grüßen
Euer Kalle
Ich hoffe mir kann jemand sagen wo das Problem ist, danke
Du erwartest jetzt, dass wir 525 Zeilen schlechten Code durcharbeiten, um dein Problem zu finden.
Wir wissen nicht, was für Werte die einzelnen Variablen haben, inwiefern OnPlayerDeath da eine entscheidende Rolle spielt etc pp.
Du solltest dir noch mal die Basics anschauen, wie du selbst print-Debugs machen kannst um eigenständig Fehler zu finden und eventuell crashdetect nutzen.
Zumal solltest du dir Tutorials anschauen, wie man Modular Skriptet bzw genrell mal schauen, wie man das in anderen Sprachen macht.
Den Code straight runter zu schreiben...sieht 1. Scheiße aus, 2. ist ineffizient und 3. Man findet nix mehr, genau deshalb stehst du jetzt vor deinem Problem.
Da sein?
Ja da hast du vollkommen recht, gar nicht auf den Code geachtet haha xD
Sinnvoller wäre eh sowas:
Wenn sie mit dem Thema zu tuen haben, einfach drunter.
Falls es sich um neue Themen handelt, eröffne einen neuen Thread.
Bitte nicht privat mit Problemen kommen, das ist nicht der Sinn eines Forums ![]()
Das unten schreib mal so:
stock const Float:Saveboxs[][3] = {
{-1834.7000000,327.5000000,16.7000000},
{-2932.1001000,453.8999900,3.6000000},
{-2942.3999000,1110.8000000,5.3000000},
{-1971.9000000,2601.7000000,48.8000000},
{-813.5999800,2345.8000000,119.8000000},
{-364.5000000,1593.4000000,76.5000000},
{-1356.4000000,2141.2000000,41.4000000},
{-792.0999800,2761.5000000,50.4000000},
{1564.4000000,2780.8999000,10.4000000},
{2627.0000000,2850.8999000,10.4000000},
{2613.2000000,718.5999800,10.4000000},
{2723.6001000,-1828.2000000,11.4000000},
{2471.6001000,-2697.7000000,2.6000000},
{1450.0000000,-2271.8999000,13.1000000},
{1120.4000000,-1886.5000000,36.3000000},
{707.7999900,-1472.7000000,5.0000000},
{1100.3000000,-665.4000200,109.7000000},
{1544.5000000,-1374.7000000,329.6000100},
{2112.2000000,-1500.5000000,10.0000000},
{2836.2000000,-1463.3000000,40.3000000},
{2840.1001000,-2395.8000000,20.0000000},
{2791.8999000,-2489.6001000,14.6000000},
{-1450.9000000,-217.8999900,13.7000000},
{-2508.0000000,-675.2000100,138.8999900},
{-2685.2000000,1428.9000000,6.6000000},
{-1688.6000000,1219.1000000,20.2000000},
{-1898.1000000,-127.0000000,22.8000000},
{-2229.3000000,138.8999900,34.9000000},
{-2053.7000000,309.7999900,41.5000000},
{-1724.2000000,543.7000100,33.5000000},
{-1797.7000000,372.5000000,0.1000000},
{1122.4000000,1463.7000000,5.4000000},
{1333.8000000,1250.2000000,10.4000000},
{1773.6000000,623.7000100,10.4000000},
{2439.3999000,-152.3999900,31.4000000},
{2114.2000000,-354.2999900,58.3000000},
{2243.6001000,1132.4000000,10.4000000},
{1990.1000000,1804.1000000,11.5000000},
{2561.5000000,2301.3999000,10.6000000},
{2119.7000000,1497.0000000,10.4000000}
};
ocmd:sb(playerid,params[])
{
ShowPlayerDialog(playerid,SBLISTE,DIALOG_STYLE_LIST,"Savebox - Liste","Box1,Box2,Box3,Box4,Box5,Box6,Box7,Box8,Box9,Box10,Box11,Box12,Box13,Box14,Box15,Box16,Box17,Box18,Box19,Box20,Box21,Box22,Box23,Box24,Box25,Box26,Box27,Box28,Box29,Box30,Box31,Box32,Box33,Box34,Box35,Box36,Box37,Box38,Box39,Box40","Wählen","");
return 1;
}
if(dialogid == SBLISTE)
{
if(!response) return 1;
GameTextForPlayer(playerid,"~w~ROUTE WIRD ~g~KALKULIERT",2000,4);
SetPlayerCheckpoint(playerid,Saveboxs[listitem][0],Saveboxs[listitem][1],Saveboxs[listitem][2], 5);
}
Alles anzeigen
Und das andere schreib so:
stock const Float:buddeln[][3] = {
{-152.4400,1846.9717,29.2687},//1
{-156.7346,1836.0719,35.8069},//2
{-159.3667,1819.4857,41.8780},//3
{-167.8414,1811.2115,47.8237},//4
{-170.0450,1801.4122,52.2505},//5
{-161.8423,1793.4242,53.3616},//6
{-158.1084,1784.1903,54.7704},//7
{-155.6175,1774.2726,55.9601},//8
{-161.5969,1759.1898,54.8455},//9
{-169.1723,1744.1102,54.3982},//10
{-179.5686,1728.7390,56.0567},//11
{-194.2571,1725.0474,57.2687},//12
{-211.9686,1723.6018,59.9577},//13
{-232.1001,1724.2982,65.5360},//14
{-249.9986,1729.4911,70.9397},//15
{-256.7750,1744.8335,79.7419},//16
{-263.5448,1757.6102,85.9440},//17
{-248.7828,1757.2014,91.1319},//18
{-236.3986,1762.3973,97.1517},//19
{-241.1614,1779.8954,98.7132},//20
{-158.1247,1657.6960,15.5781},//21
{-159.1710,1646.9923,17.1366},//22
{-161.2974,1631.9705,13.9626},//23
{-167.4120,1617.1793,16.0704},//24
{-179.3784,1609.5249,16.3702},//25
{-196.5753,1614.7747,18.1386},//26
{-208.7043,1622.6949,20.1674},//27
{-221.8707,1630.6270,23.0112},//28
{-224.7464,1643.3513,25.0204},//29
{-214.8419,1654.8787,24.1355},//30
{-217.1145,1666.9935,24.9542},//31
{-230.0202,1671.4265,28.5422},//32
{-240.1701,1680.7133,28.0925},//33
{-252.4414,1677.7377,27.4495},//34
{-264.8186,1666.5928,26.4511},//35
{-277.9287,1668.5056,27.4045},//36
{-287.5557,1678.8755,26.5148},//37
{-290.7267,1693.0597,28.3341},//38
{-300.0582,1705.0482,32.0989},//39
{-316.0493,1698.2067,34.0618}//40
};
stock GetPlayerCheckpoint(playerid)
{
for(new i; i<sizeof(buddeln); i++)
{
if(IsPlayerInRangeOfPoint(playerid,5.0,buddeln[i][0],buddeln[i][1],buddeln[i][2])) return i;
}
return -1;
}
ocmd:graben(playerid,params[])
{
if(sSpieler[playerid][Schaufel] < 1) return SendClientMessage(playerid,ROT,"Du hast keine Schaufeln mehr, kaufe dir neue im 24/7 Shop!");
if(IsPlayerInAnyVehicle(playerid)) return SendClientMessage(playerid,ROT,"Du sitz in/auf einem Fahrzeug!");
new cp = GetPlayerCheckpoint(playerid);
if(cp == -1) return SendClientMessage(playerid,GRAU,"Du bist nicht in der Nähe!");
switch(random(3))
{
case 0:
{
sSpieler[playerid][Schaufel] -= 1;
SendClientMessage(playerid,GOLD,"Du hast einen Goldbarren gefunden, du kannst ihn behalten, an andere Spieler verkaufen.");
SendClientMessage(playerid,GOLD,"oder auf dem Schwarzmarkt verkaufen.");
sSpieler[playerid][Goldbarre] += 1;
}
case 1:
{
sSpieler[playerid][Schaufel] -= 1;
SendClientMessage(playerid,HELLBLAU,"Leider hast du nichts gefunden, aber nicht aufgeben der Schatz wartet ;)");
}
case 2:
{
SendClientMessage(playerid,HELLBLAU,"Du hast eine Tasche gefunden, vielleicht ist was besonderes drin.");
SendClientMessage(playerid,HELLBLAU,"Mit /tasche kannst du sie öffnen.");
sSpieler[playerid][Schaufel] -= 1;
sSpieler[playerid][Tasche] += 1;
}
}
DisablePlayerCheckpoint(playerid);
return 1;
}
ocmd:bd(playerid,params[])
{
if(sSpieler[playerid][Schaufel] < 1) return SendClientMessage(playerid,ROT,"Du hast keine Schaufeln mehr, kaufe dir neue im 24/7 Shop!");
if(IsPlayerInAnyVehicle(playerid)) return SendClientMessage(playerid,ROT,"Du sitz in/auf einem Fahrzeug!");
new cp = random(40);
SetPlayerCheckpoint(playerid, buddeln[cp][0], buddeln[cp][1] ,buddeln[cp][2],5.0);
SendClientMessage(playerid,HELLBLAU,"Geh zum Checkpoint und tippe /graben ein. Viel Erfolg ;)");
return 1;
}
Alles anzeigen
Der Code ist ein richtig gutes Paradebeispiel dafür, wie man es nicht machen sollte haha xD
Das Problem ist, dass du alle 40 Safeboxen in eine Zeile schreibst und deswegen der crasht.
Nein, dann würde nur der Compiler crashen, er redet vom Server.
Crashdetect könnte hier definitiv helfen.
Deine Abfrage, ob er sich in einem Checkpoint befindet ist auch falsch, weil du nur prüfst ob er sich in einem zufälligen befindet.
Die Chance, dass der Befehl klappt steht damit bei 1/40 xD
Mit 2 einfachen Funktionen kannst du das realisieren:
stock CountCharsInString(const string[])
{
new c;
for(new i=strlen(string)-1; i!=-1; i--)
{
if((string[i] >= 'A' && string[i] <= 'Z') || (string[i] >= 'a' && string[i] <= 'z')) c++;
}
return c;
}
stock CountNumbersInString(const string[])
{
new c;
for(new i=strlen(string)-1; i!=-1; i--)
{
if(string[i] >= '0' && string[i] <= '9') c++;
}
return c;
}
Alles anzeigen
Und dann kannst du ja einfach abfragen:
Ich möchte gerne ein Filterscript erstellen, dass z.B. jeden Tag um 5 Uhr ein restart vom Server kommt
Also möglich ist das auch wirklich einfach durch ein Filterskript.
Falls du also noch irgendwas machen magst, bevor der Server Restartet, so könntest du das realisieren:
//Oben im Skript
new bool:variance;
//Unter OnFilterScriptInit
SetTimer("@restart", 1000*60, 1);
//Dann irgendwo
@restart();@restart()
{
new h,m,s;
gettime(h,m,s);
if(h == 5 && m <= 1 && !variance)
{
variance=true;
SendRconCommand("gmx");
}
else variance=false;
}
Alles anzeigen
Die variance Variable sorgt nur dafür, dass eine Timer Varianz miteinkalkuliert wird und so nicht 2x restartet.
Habe eine Funktion geschrieben zum Runden von Integern.
Kann man diese auch mit Bitwise Verknuepfungen und Shifts darstellen?
Kannst du mal Beispiele geben, was du als Input eingibst und als Output raushaben magst? ![]()
ohne komma zahlen in die Datenbank gespeichert
Wie hast denn GeschenkX etc definiert? Und wie benutzt du es?
und was genau steht in der Datenbank? xD
aber das klappt ja nicht.
Was genau klappt denn nicht?
Was genau passiert denn...was willst du haben?! xD
Bissl präziser
Muss ich eine Reihenfolge beachten? publics, ocmd Befehle, stocks, oder anders rum?
Nein, aber defines müssen nach oben.
Und was erwartest du jetzt von uns? ![]()
Eventuell hookst du irgendwo etwas...oder keine Ahnung...
Man kann dir so echt schlecht nur helfen ![]()
jetzt funktionieren meine Befehle nicht und es kommt immer unknown command.
Das liegt aber nicht an der Code Änderung.
Ja..lass mal Crashdetect laufen und schau in den Log ![]()
Kommt darauf an, wie groß dein Skript ist und wie effizient du mit dem Speicher umgehst, aber so wie ich deinen Code sehe, tust du das eben nicht.
Du kannst Variablen mehrfach verwenden:
public OnPlayerText(playerid, text[])
{
new message[128];
if(text[0] == '$')
{
if(iPAA(playerid,2))return rangniedrig;
if(!text[1]) return SCM(playerid, ROT,"$ [Text]"),0;
format(message, sizeof(message), "(([Adminchat] %s: %s ))", SpielerDaten[playerid][pName],text[1]);
return SAM(ROT,message),0;
}
if(text[0] == '§')
{
if(iPAA(playerid,1))return rangniedrig;
if(!text[1]) return SCM(playerid, ROT,"§ [Text]"),0;
format(message, sizeof(message), "(([Helferchat] %s: %s ))", SpielerDaten[playerid][pName],text[1]);
return SAM(HGREEN,message),0;
}
format(message, sizeof(message), "{969696}%s sagt: {FFFFFF}%s", SpielerDaten[playerid][pName], text);
return ProxDetector(7.0, playerid, message, WEISS,WEISS,WEISS,WEISS,WEISS),0;
}
Alles anzeigen
Dadurch kannst du dir also die ganzen anderen Variablen schenken.
...kann man nicht wirklich sehen.
Kommentiere doch mal sogut wie alles aus.
Dann compile und dann entkommentiere nach und nach und dann weißt du ja, an welcher Zeile es schließlich liegt.
Wie hast du denn rangniedrig definiert?
Das ist meine includes.inc
...und was steht im Gamemode und in den anderen Gamemmodes?
Hast du dort überall die selben Includes..rufen die sich alle endlos gegenseitig auf....