dynamisch ist ein script, wenn mögichst viele änderungen während der laufzeit des scripts vorgenommen werden können, ohne dass ein erneutes compilen des scripts nötig ist.
außerdem sollte man veränderungen am script vornehmen können, ohne am script selbst etwas zu ändern (^^), sprich mögichst viele daten (koordinaten usw.) in dateien speichern.
(keine allgemein gültige definition, so würde ich es halt beschreiben).
Beiträge von Crank93
-
-
dazu musst du zunächst für jeden spieler ein textdraw erstellen:
//oben
new Text:MoneyDraw[MAX_PLAYERS];
//OnPlayerConnect
MoneyDraw[playerid]=TextDrawCreate(...) //koords einfügendamit kanst du dann über die playerid auf jedes textdraw einzeln zugreifen:
//geldanzeige für einen best. spieler äandern
TextDrawSetString(MoneyDraw[playerid], "<geld>"); -
new tmp[128]; -
hm, bei mir compiled es ohne errors, mach mal das array "tmp" größer.
-
//OnPlayerCommandText
new tmp[32], index;
tmp=strtok(cmdtext, index);
//
if(!strcmp(tmp,"/respawn", true))
{
tmp=strtok(cmdtext, index);
if(!strlen(tmp))
{
return SendClientMessage(playerid, COLOR, "USAGE: /respawn [id]");
}
new pID=strval(tmp);
if(!IsPlayerConnected(pID))
{
return SendClientMessage(playerid, COLOR, "Spieler nicht online!");
}
SpawnPlayer(pID);
return 1;
} -
schau dir nochmal genau an, was da eigentlich im callback "OnDialogResponse" steht.
du überprüfst lediglich, ob der inputtext jeweils mit dem ersten element aus den 2D-arrays "Wang" und "GPS" übereinstimmt. bei anderen begriffen passiert logischerweise nichts, wie auch, wenn die inputtexte garnicht mit den strings aus den arrays verglichen werden.ich würde es so machen:
//diese Suchbegriffe sollten ausreichen, sie sind in allen anderen enthalten
new Wang[][] = {
{"Wang"},
{"Auto"},
{"Cars"}
};
new GPS[][] = {
{"GPS"},
{"Navigation"}
};
if(dialogid == DIALOG_SASEARCH)
{
if(response)
{
for(new i=0; i<sizeof(Wang); i++) //durch die suchbegriffe schleifen
{
if(strfind(inputtext,Wang[i], true) != -1) //strfind hier deutlich besser als strcmp
{
return ShowPlayerDialog(playerid,DIALOG_WANGGEFUNDEN,DIALOG_STYLE_LIST,"Gefundene Seite:","www.WangCars.sa","Wählen","Schließen");
}
else if(strfind(inputtext,GPS[i], true) != -1)
{
return ShowPlayerDialog(playerid,DIALOG_GPSGEFUNDEN,DIALOG_STYLE_LIST,"Gefundene Seite:","www.GPS.sa","Wählen","Schließen");
}
}
}
return 1; -
public OnPlayerStateChange(playerid, newstate, oldstate) -
return 1;
beendet die funktion sofort an dieser stelle, also kann der code darunter nicht mehr erreicht werden. ("unreachable").
also nimm das raus und füge es am ende des callbacks ein. -
sehr informativ, ich denke mal, das wird einigen hier weiterhelfen.
-
so, da sich für jeden spieler ein spezifisches textdraw ergibt, hab ich den code etwas abgeändert.
//oben
new string[128];
//da der text vom jeweilgen spieler abhängt, musst du für jeden spieler einzeln ein textdraw erstellen, also:
new Text:td_PayDay[MAX_PLAYERS];
//OnPlayerConnect
td_PayDay[playerid]=TextDrawCreate(...);
//
//etwas abgeändert, da sich für jeden spieler ein anderer text ergibt
public UpdatePayday()
{
for(new i=0; i<MAX_PLAYERS; i++) //td für jeden spieler updaten
{
//erst formatieren
format(string, sizeof(string), "~w~Spielzeit seit Zahltag:~g~ %d Minuten", PlayerInfo[playerid][pPaydayZeit]);
TextDrawSetString(PayDay[i], string);
}
return 1;
}
//OnGameModeInit
SetTimer("UpdatePayday", 1000*60, true); -
man kann commands mit mehreren parametern (beliebig viele) auch ohne sscanf scripten (z. B. mit split oder strtok), nur um das mal klarzustellen.
sscanf ist aber meist die sicherere und elegantere lösung. -
"ds" bleibt so, das gibt das format der parameter an.
(d für dezimalzahl (ID) und s für string)
danach werden die parameter angegeben, die beim aufruf an "UpdateTextDraw" übergeben werden.
also für "ID" die ID des textdraws angeben und für "bla" eben den string, den du über das textdraw ausgeben willst.
/E:
hast du die funktion mit "forward" definert?
wenn ja, achte darauf, dass der ausdruck nach forward exakt mit der definition der funktion übereinstimmt. -
forward UpdateTextDraw(Text:ID, string[]);
public UpdateTextDraw(Text:ID, string[])
{
TextDrawSetString(ID, string);
return 1;
}
//irgendein callback
SetTimerEx("UpdateTextDraw", 1000*60, true, "ds", ID, "bla"); -
du kannst deinen thread selber schließen. solltest du auch machen, wenn das thema geklärt ist.
-
//oben
#define Nachricht(%0,%1,%2) SendClientMessage(%0,%1,%2) -
-
deine überlegung ist schon richtig, da du ja bei mehreren spielern mehrere timer erstellst, reicht eine einfache variable nicht mehr aus, um die verschiedenen timerIDs zu speichern.
(deshalb werden die timer auch machmal nicht beendet).
allerdings ist das script insgesamt nicht besonders gut, geht elegeanter:
//oben
#define BANK_ROB_SECONDS (90)// "/robbank"
//blabla
TogglePlayerControllable(playerid, 0);
SetTimerEx("EndBankRob", BANK_ROB_SECONDS*1000, false, "i", playerid);
//
public EndBankRob(playerid)
{
TogglePlayerControllable(playerid, 1);
new rand=random(2);
if(rand)
{
//erfolgreich...
}
else
{
//nicht erfolgreich...
}
return 1;
} -
//OnPlayerSpawn
PutPlayerInVehicle(playerid, RaceVehicles[playerid], 0); -
dann so:
new gang2=spieler[playerid][leader];
wenn ich das jetzt richtig verstanden habe
-
new gang2=spieler[id4][leader];