Versuch Mal statt else "if(ooc = 0)"
[SAMMELTHREAD] Kleine Scripting Fragen
- Rafelder
- Unerledigt
Dein Problem konnte durch einen User gelöst werden? Bedank dich bei ihm indem du seinen Beitrag als Hilfreich markierst sowie einen Daumen oben dalässt
Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!
Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
-
-
Habs gelöst, hab new ooc oben bei den globalen rein gemacht und nicht im befehl
-
printf gibt immer aus dass die Pickupids 1, 2,3,4,5 sind, bei einer sizeof(GlobalActors) von 5, egal was ich als pickupid in die Funktion gebe
Das liegt daran, dass du pickupids nicht setzen kannst, sondern sie werden zugewiesen...
Wie vehicleids / objectids / actorids auch, werden vom Server erstellt

Aber schau nochmal in meinen Code...hab doch gezeigt wie du es machen musst

-
Guten Morgen,
kann mir jemand sagen, ob der Befehl so stimmt? Er soll vor /tv die Coords "speichern" und nach /tv wieder zu dieser Position zurück kehren, anstatt zu Spawnen
ocmd:tv(playerid,params[])
{
if(!IsPlayerGM(playerid,2)) return 1;
new pID,Float:X,Float:Y,Float:Z;
if(sscanf(params, "u", pID)) return SendClientMessage(playerid,FARBE_ROT," INFO: /tv [Playerid]");
GetPlayerPos(playerid,X,Y,Z);
if(!Beobachte[playerid])
{
new string[128];
TogglePlayerSpectating(playerid, 1);
PlayerSpectatePlayer(playerid, pID);
format(string, sizeof(string), "%s %s beobachtet nun den Spieler %s",GetGMRang(playerid),getPlayerName(playerid),getPlayerName(pID));
SendClientMessage(playerid, FARBE_ROT, string);
Beobachte[playerid] = true;
CMDLog(string);
}
else
{
TogglePlayerSpectating(playerid, 0);
SetCameraBehindPlayer(playerid);
Beobachte[playerid] = false;
SetPlayerPos(playerid,X,Y,Z);
}
return 1;
} -
Ist so richtig, sollte funktionieren.
-
Habe es mit der Pickupzuweisung so wie in deinem Vorschlag gemacht

Habe jedoch ein kleines Problem:
C
Alles anzeigenpublic OnPlayerPickUpPickup(playerid, pickupid) { for(new i;i<sizeof(GlobalActors);i++) { if(pickupid == ActorPickups[i]) { ShowMenuForPlayer(shopmenu,playerid); TogglePlayerControllable(playerid,false); } else { maxmoney = maxmoney -1; DestroyPickup(pickupid); GivePlayerMoney(playerid, 1000); printf("ID picked up: %d",maxmoney); break; } } return 1; }Ich versuche gerade irgendwie hinzukriegen, dass der else Teil ausgefuehrt wird, wenn das aufgesammelte Pickup keine Pickupid aus ActorPickups, aber natuehrlich klappt das nicht verneunftig.
Wie kann ich realisieren, dass else erst ausgefuehrt wird, wenn die For schleife durch ist, und die Bedingung darin nicht erfuellt ist?
-
Alles anzeigen
Habe es mit der Pickupzuweisung so wie in deinem Vorschlag gemacht

Habe jedoch ein kleines Problem:
C
Alles anzeigenpublic OnPlayerPickUpPickup(playerid, pickupid) { for(new i;i<sizeof(GlobalActors);i++) { if(pickupid == ActorPickups[i]) { ShowMenuForPlayer(shopmenu,playerid); TogglePlayerControllable(playerid,false); } else { maxmoney = maxmoney -1; DestroyPickup(pickupid); GivePlayerMoney(playerid, 1000); printf("ID picked up: %d",maxmoney); break; } } return 1; }Ich versuche gerade irgendwie hinzukriegen, dass der else Teil ausgefuehrt wird, wenn das aufgesammelte Pickup keine Pickupid aus ActorPickups, aber natuehrlich klappt das nicht verneunftig.
Wie kann ich realisieren, dass else erst ausgefuehrt wird, wenn die For schleife durch ist, und die Bedingung darin nicht erfuellt ist?
Probier es mal so:
public OnPlayerPickUpPickup(playerid, pickupid)
{
for(new i=0; i<sizeof(GlobalActors); i++)
{
if(pickupid != ActorPickups[i])continue;
ShowMenuForPlayer(shopmenu,playerid);
TogglePlayerControllable(playerid,false);
return 1;
}
maxmoney = maxmoney -1;
DestroyPickup(pickupid);
GivePlayerMoney(playerid, 1000);
printf("ID picked up: %d",maxmoney);
return 1;
} -
Danke dir, leider haut das auch irgendwie nicht hin:/
Nochmal alle Teile.
Auf den Counter via Globale Variable habe ich verzichtet da ich das in einer for schleife eh mit Iterator mache (oder ist das mein Fehler? :D)
Nochmal die Actor Funktion wo das PickUp generiert wird
C
Alles anzeigenstock CreateGlobalActor(actorid,modelid,Float:ax,Float:ay,Float:az,Float:angle,Float:distance,pickupid) { actorid = CreateActor(modelid,ax,ay,az,angle); new Float:x, Float:y, Float:z; GetActorPos(actorid, x, y, z); GetXYInFrontOfActor(actorid, x, y, distance); pickupid = CreatePickup(1210,2,x,y,z,-1); SetActorInvulnerable(actorid, true); printf("Actor created, pickupid %d",pickupid); return pickupid; }Wo es aufgesammelt wird
C
Alles anzeigenpublic OnPlayerPickUpPickup(playerid, pickupid) { for(new i=0; i<sizeof(GlobalActors); i++) { if(pickupid != ActorPickups[i])continue; ShowMenuForPlayer(shopmenu,playerid); TogglePlayerControllable(playerid,false); return 1; } maxmoney = maxmoney -1; DestroyPickup(pickupid); GivePlayerMoney(playerid, 1000); printf("ID picked up: %d",maxmoney); return 1; }
Und der FunktionsaufrufCfor(new g=0;g<sizeof(GlobalActors);g++) { CreateGlobalActor(g+1,274,GlobalActors[g][0],GlobalActors[g][1],GlobalActors[g][2],GlobalActors[g][3],3.0,ActorPickups[g]); SetActorInvulnerable(g+1, true); }Wenn ich alles richtig verstanden habe, muesste die Pickupid, beispielsweise bei der ersten Iteration bei g= 0 ActorPickups[0] uebergeben werden, und dann ActorPickups[0] = CreatePickup dann ausgefuehrt werden, oder?
Oder kann man keiene Werte aus Arrays in einer Funktion uebergeben?Weitere Frage:
Ich habe einen Command mit dem ein Spieler unsichtbar wird, und setze dann einen Timer von 60 Sekunden um ihn wieder sichtbar zu machen.
Problem ist: Ueber einen Timer kann ich ja keine Parameter an die Funktion uebergeben, wie kriege ich das dann realisiert? Muss ich vielleicht mit dem & Symbol arbeiten? Weil irgendwie muss die Funktion ja wissen bei welchem Spieler die 60 Sekunden abgelaufen sind.Macht es ausserdem irgendwo sinn in PAWN volatile einzusetzen? Ich habe mal in meine Arrays testweise volatile reingepackt, sehe aber keinen Unterschied.
Auch in der Dokumentation zu PAWN habe ich nix zu volatile gefunden, kenne das nur aus C daher weiss ich nicht was es in PAWN bringen sollte -
Wie wäre es, wenn du das ein bisschen übersichtlicher gestaltest.
Also, es würde funktionieren, wie Pr0x das gezeigt hat, aber nur unter der Vorraussetzung, dass du entweder ActorPickups oder MoneyPickups hast.
Falls noch eine weitere Art Pickup hinzukommt, wird das als money interpretiert...Also hier mal ein kleines Beispiel wie man sowas aufbauen könnte:
C
Alles anzeigen//Hier alle Pickuptypen enum { INVALID_PICKUP_TYPE, MONEY_TYPE, ACTOR_TYPE }; //Hier deine Pickup-Arrays: new money_pickups[100], actor_pickups[50]; //Dann der Callback public OnPlayerPickUpPickup(playerid, pickupid) { new index; switch(GetPickupType(pickupid,index)) { case INVALID_PICKUP_TYPE: { //Wenn es weder Money noch Actor ist...(also nicht definiert) } case MONEY_TYPE: { maxmoney -= 1; GivePlayerMoney(playerid, 1000); printf("ID picked up: %d",maxmoney); //Sehr wichtig, dass du auch das Pickup im Array clearst money_pickups[index]=-1; DestroyPickup(pickupid); } case ACTOR_TYPE: { ShowMenuForPlayer(shopmenu,playerid); TogglePlayerControllable(playerid,false); //Könntest z.B. mit actor_pickups[index] auf das im Array zugreifen } } return 1; } //Und dann die Funktion (ohne Makro) stock GetPickupType(pickupid, &index) { for(new i; i<sizeof(money_pickups); i++) { if(money_pickups[i] == pickupid) return index=i,MONEY_TYPE; } for(new i; i<sizeof(actor_pickups); i++) { if(actor_pickups[i] == pickupid) return index=i,ACTOR_TYPE; } return INVALID_PICKUP_TYPE; } /* Da das immer das selbe im Endeffekt ist, kann man das auch zusammenfassen mit einem Makro und sich so Schreibarbeit sparen: */ #define CheckForPickupType(%0,%1); for(new i; i<sizeof(%0); i++) if(%0[i] == pickupid) return index=i,%1; stock GetPickupType(pickupid, &index) { CheckForPickupType(money_pickups,MONEY_TYPE); CheckForPickupType(actor_pickups,ACTOR_TYPE); return INVALID_PICKUP_TYPE; }Nur so als Anregung bzw Idee, damit du es übersichtlicher hast
Musst halt auch schauen, dass du im Callback immer das Richtige Array verwendest, welches du unten angibst, da sich daran der Index anpasst
//Edit:
Parameter übergibst du mit SetTimerEx //Wiki Code buggt.lelvolatile existiert in Pawn nicht, da das alles in einer VM ausgeführt wird und nicht direkt auf der Hardware.
-
Wow klasse das funktioniert alles 1A
jetzt funktioniert mein Gamemode endlich und ich kann endlich die neue Version veroeffentlichen
Die enum Variante ist wirklich klasse!Mir ist jedoch aufgefallen, da mein Skript jetzt mit Makros vollgeballert wurde, bestimmt 600-700 Zeilen mit einem # inzwischen
dauert das Compilen leider ziemlich lange!Noch ne Frage zu dem OnPlayerPickUpPickup
Da wird ja letztendlich in dem Array gesucht wie ich das sehe, das kann ja bei 4000 MoneyPickups beispielsweise ziemlich lange dauern.
Damit es keinen Ueberlauf an Pickups gibt (ueber 4096) habe ich die so definiert, ist das richtig?Ist es eventuell weiterhin sinvoll oder moeglich, bei GetPickupType die binaere Suche anzuwenden? Zumindest hat sie ja eine geringere Laufzeit
Habe da an sowas gedacht was ich mal aus nem C Buch entnommen, und umgebaut habeC
Alles anzeigenstock binsearch(a[],key,l,r) { new k; while(r >=l) { k = (l+r)/2; if(key == a[k]) return k; if(key < a[k]) r = k=1; else l= k+1 } return 0; }Habe mir eventuell folgendes gedacht
C
Alles anzeigenstock GetPickupType(pickupid, &index) { for(new i; i<sizeof(MoneyPickups); i++) { if(binsearch(MoneyPickups,pickupid,0,sizeof(MoneyPickups)-1)) return index=i,MONEY_TYPE; } for(new i; i<sizeof(ActorPickups); i++) { if(binsearch(ActorPickups,pickupid,0,sizeof(ActorPickups)-1)) return index=i,ACTOR_TYPE; } return INVALID_PICKUP_TYPE; }//edit: vergiss meinen Code der ist mist

-
Wenn dein Hauptbestandteil aus money Pickups besteht, dann kannst du es smarter machen und brauchst diese gar nicht definieren.
Dann sind die MoneyPickups alle INVALID_PICKUP_TYPE, das funktioniert solange du alle anderen definierst

Dann suchst der nur in den anderen und wenn er es dort nicht findet, weiß er instant, dass es ein money pickup sein muss

Eine Binäre Suche funktioniert leider nur mit geordneten Arrays. Also wenn sie sortiert wären, würde das gehen..sind sie aber hier leider nicht, da ja in der Mitte zum beispeil ein Pickup verschwinden könnte...

//Edit:
Zitatbestimmt 600-700 Zeilen mit einem # inzwischen
Das sind aber ganz schön viele...da könntest du bestimmt etwas vereinfachen

-
Hallo Zusammen^^
ich habe folgendes Problem,
Mein Fraktionschat funktioniert nur in 1 Fraktion. Kann mir jemand sagen warum?
ocmd:f(playerid,params[])
{
new string[128];
if(IsPlayerInFraktion(playerid,0)) return 1;
if(sscanf(params, "s[128]", string)) return SendClientMessage(playerid,FARBE_ROT," INFO: /f (Fraktionschat) [Nachricht]");
new fID = sInfo[playerid][Fraktion];
format(string,sizeof(string), "**((%s: %s ))**", getPlayerName(playerid),string);
for(new i=0; i<MAX_PLAYERS; i++)
{
if(!IsPlayerConnected(i))return 1;
if(!IsPlayerInFraktion(i,fID))return 1;
SendClientMessage(i, FARBE_FUNK, string);
}
return 1;
} -
Alles anzeigen
Hallo Zusammen^^
ich habe folgendes Problem,
Mein Fraktionschat funktioniert nur in 1 Fraktion. Kann mir jemand sagen warum?
ocmd:f(playerid,params[]){new string[128];if(IsPlayerInFraktion(playerid,0)) return 1;if(sscanf(params, "s[128]", string)) return SendClientMessage(playerid,FARBE_ROT," INFO: /f (Fraktionschat) [Nachricht]");new fID = sInfo[playerid][Fraktion];format(string,sizeof(string), "**((%s: %s ))**", getPlayerName(playerid),string);for(new i=0; i<MAX_PLAYERS; i++){if(!IsPlayerConnected(i))return 1;if(!IsPlayerInFraktion(i,fID))return 1;SendClientMessage(i, FARBE_FUNK, string);}return 1;}
Wie sieht denn IsPlayInFraktion aus?
-
IsPlayerInFraktion(playerid,f_id)
{
if(sInfo[playerid][Fraktion]==f_id)return 1;
return 0;
}Wie sieht denn IsPlayInFraktion aus?
-
Danke Kaliber:

So jetzt kommt meine vielleicht fuer heute letzte Frage

Ich werde tatsaechlich spaeter noch mehr Pickups hinzufuegen, deshalb habe ich das mit dem sortieren mal gemacht.
Bei dem Array mit den Actors ist das kein Problem, da aendert sich ja nix dran, und es funktioniert auch
Cstock GetPickupType(pickupid, &index) { new mres = binsearch(MoneyPickups,pickupid,0,sizeof(MoneyPickups)-1); HeapSort(MoneyPickups); if(MoneyPickups[mres] == pickupid) return index=mres,MONEY_TYPE; new ares = binsearch(ActorPickups,pickupid,0,sizeof(ActorPickups)-1); if(ActorPickups[ares] == pickupid) return index=ares,ACTOR_TYPE; return INVALID_PICKUP_TYPE; }C
Alles anzeigenpublic OnPlayerPickUpPickup(playerid, pickupid) { new index; switch(GetPickupType(pickupid,index)) { case INVALID_PICKUP_TYPE: { } case MONEY_TYPE: { maxmoney -= 1; GivePlayerMoney(playerid, 1000); printf("ID picked up: %d",maxmoney); MoneyPickups[index]=-1; DestroyPickup(pickupid); } case ACTOR_TYPE: { ShowMenuForPlayer(shopmenu,playerid); TogglePlayerControllable(playerid,false); } } return 1; }Mal angenommen ich will das Array sortieren damit das mit der binaersuche klappt, wo muesste ich das Sortieren dann ausfuehren also wo im Code?
Habe dazu eine super tolle HeapSort FunktionC
Alles anzeigenstock HeapSort (array [], n = sizeof (array)) { new i; for (i = n / 2; i > 0; --i) // Make heap SinkDown (array, i, n); for (i = n; i > 1; --i) { Swap (array [i - 1], array [0]); SinkDown (array, 1, i - 1); } } //---------------------------------------------------------- static stock SinkDown (array [], i, m) { new j; while (2 * i <= m) { j = 2 * i; if (j < m && array [j - 1] < array [j]) ++j; if (array [i - 1] < array [j - 1]) { Swap (array [i - 1], array [j - 1]); i = j; } else i = m; } } //---------------------------------------------------------- static stock Swap (&a, &b) { new s; s = a; a = b; b = s; } -
Quicksort wäre schneller als Heapsort

Und du müsstest genau dann das Array neu sortieren, wenn sich etwas ändert, also genau unter:
MoneyPickups[index]=-1;
-
Dann ist der letzte Eintrag ja nicht -1, sondern 3...
Nein der letzte Eintrag ist -1.
Die Frage ist nur was er genau vorhat, will er wirklich nur den letzten Wert(so wie es für mich klingt) oder will er den letzten Wert der nicht dem Standardwert entspricht(deine Schleife).
-
Nein der letzte Eintrag ist -1.
Die Frage ist nur was er genau vorhat, will er wirklich nur den letzten Wert(so wie es für mich klingt) oder will er den letzten Wert der nicht dem Standardwert entspricht(deine Schleife).Ja ich wollte nur den wirklich letzten Wert

Noch ne Frage
Meine binary suche ist irgendwie kaputt
returnt immer 0,kA warum, hat jemand eventuell zufaellig ne binaersuch Funktion auf Lager?Oder muss ich l un r eventuell anders festlegen?
Der fragliche Teil:
Codenew mres = binsearch(MoneyPickups,pickupid,MoneyPickups[0],MoneyPickups[sizeof(MoneyPickups)-1]); if(MoneyPickups[mres] == pickupid) return index=mres,MONEY_TYPE; printf("ID:%d mres: %d",pickupid,mres);
Es kommt immer zu return 0 aus meiner binsearch funktionCode
Alles anzeigenstock binsearch(a[],key,l,r) { new k; while(r >=l) { k = (l+r)/2; if(key == a[k]) { return k; } if(key < a[k]) { r = k-1; } else { l= k+1; } } return 0; }Habe als l das erste Element genommen also das am weitesten Links ist MoneyPickups[0] und das am weitesten rechts ist MoneyPickups[sizeof(MoneyPickups)-1]
-
Hier, mach es mal so:
C
Alles anzeigennew mres = binsearch(pickupid,MoneyPickups,sizeof(MoneyPickups)); if(mres != -1) return index=mres,MONEY_TYPE; printf("ID: %d mres: %d",pickupid,mres); //Funktion: stock binsearch(x, v[], n) { new low, high = n-1, mid; while(low < high) { mid = (low + high) / 2; if(x <= v[mid]) high = mid; else low = mid+1; } return (x == v[low]) ? low : -1; } -
Danke dir !
warum funktioniert deine binaersuche , jedoch meine nicht?
Habe ich da was falsch gemacht?Super dann werde ich mal folgendes einbauen
Cnew ares = binsearch(pickupid,ActorPickups,sizeof(ActorPickups)); if(ares != -1) return index=ares,ACTOR_TYPE; printf("ID: %d ares: %d",pickupid,ares); new mres = binsearch(pickupid,MoneyPickups,sizeof(MoneyPickups)); if(mres != -1) return index=mres,MONEY_TYPE; printf("ID: %d mres: %d",pickupid,mres);Vielen Dank nochmal! Zu Binaersuche im PAWN konnte mir leider im englischen Forum nicht geholfen werden
-
