Beiträge von Glimmer

    Moin Community,


    da meine bisherige Lösung zu ein paar Problemen führte und Goldkiller mir empfohlen hat das über Arrays zu lösen, gab er mir folgendes Beispiel mit:
    enum e_TeamData {
    TD_iSpieler,
    TD_iKills
    }
    new g_TeamData[2][e_TeamData];


    stock Verteilen1(playerid)
    {
    // Aufpassen!
    // die Teamid fängt hier bei 0 an,nicht bei 1
    // Ist der Spieler in keinem Team,gibt es die konstante: NO_TEAM
    // SetPlayerTeam(playerid, NO_TEAM );
    new
    teamid;
    if( g_TeamData[0] > g_TeamData[1] ) {
    teamid = 1;
    }
    else if( g_TeamData[0] < g_TeamData[1] ) {
    teamid = 0;
    }
    else {
    new
    r = random(2);
    if( r == 0 ) {
    teamid = 0;
    }
    else {
    teamid = 1;
    }
    }
    g_TeamData[teamid][TD_iSpieler]++;
    SetPlayerTeam(playerid, teamid);
    SetPlayerHealth(playerid,0.0);
    // Man könnte jetzt alles Teamabhängig hier machen
    if(teamid == 0 ) {
    SetSpawnInfo(playerid,teamid,174,961.2678,2100.2549,1011.0256,7.5695,24,250,31,500,0,1);
    SetPlayerColor(playerid, 0x0073FF00);
    }
    else {
    SetSpawnInfo(playerid,teamid,185,959.1449,2167.9775,1011.0234,358.7257,24,250,31,500,0,1);
    SetPlayerColor(playerid, 0xFFE60000);
    }
    return 1;
    }

    Der Stock "Verteilen1" existierte schon vorher - nur eben mit anderem Inhalt.
    enum/variablen sind im Script ganz oben, wie üblich halt. Dennoch kommt beim compilieren folgender Fehler:

    Code
    error 033: array must be indexed (variable "g_TeamData")


    Ich erkenne beim besten Willen nicht wo eine falsche Definition vorliegt.
    Kann mir einer helfen? ^^



    Grüße

    Oder du durchläufst bei einem GMX einfach mit einer For-Schleife, siehe Beispiel, das wollte der Threadersteller doch haben? Dass die Spieler bei einem GMX gespeichert werden ;D

    Ja, siehe mein //Edit im letzten Beitrag. Damit habe ich mich auf deine Lösung bezogen.
    Aber: Was der "Spieler" (und ich) wollten ist eine Antwort darauf, warum dieser eine Wert bei einem Restart (über Befehl) auf 0 zurück gesetzt wird, wärend alle anderen Werte normal gespeichert werden; denn weiterhin tritt das Problem dabei bei Disconnects usw. NICHT auf - und weiterhin gibt es für den Server keine Veranlassung, bei einem per Befehl durchgeführten Restart diesen einen Wert zurück zu setzen!


    Die Methode, bei jedem GMX-Befehl separat sämtliche Werte zu speichern würde sicherlich funktionieren (oder auch nicht, wenns dann zurück gesetzt wird ^^), ist aber keine Antwort auf die Frage... *grins*

    Ist doch gleichgültig wie du diesen startest... er wird immer über die Befehlszeile
    SendRconCommand("gmx"); ausgeführt (oder eben als rcon-admin).


    Die Frage ist, WARUM der Wert in allen Fällen gespeichert wird, sich jedoch zurück setzt (also nicht nur einfach "nicht gespeichert"), wenn der Server über einen Befehl restartet wird.


    //Edit: Der Weg, bei einem Restart durch Befehl vorab alle Daten speichern zu lassen, bevor der eigentliche Restart durchgeführt wird, wäre sicher ein Weg welcher zur Lösung führt.

    Code
    for(new p = 1; p < MAX_PLAYERS; p++)


    Versuchs mal so.

    Dann wird jedoch die UserID 0 ausgelassen - woran es zudem deshalb nicht liegen kann, weil über das gleiche Verfahren auch die anderen Daten (erfolgreich) gespeichert werden.


    Ich schließe mich hiermit übrigens dem Problem an.
    Auch bei mir werden alle Daten gespeichert, außer einer (bei mir ist es der Skin). Ebenfalls nur dann, wenn ich den Server über Befehl (rcon) /gmx restarte.
    Bei einem einfachen Disconnect oder dem Beenden und erneuten Starten des Servers gibt es keinerlei Probleme.

    N'Abend,


    ich habe mich jetzt mal ran gemacht - unter der Woche hatte ich leider keine Zeit - und wollte das soweit umsetzen wie du das vorgeschlagen hast.
    Allerdings kommt beim Compilieren gleich die Meldung (natürlich 2x):

    Code
    error 033: array must be indexed (variable "g_TeamData")


    Wo liegt der Fehler? Der Array wurde doch ordnungsgemäß von dir definiert und auch nicht falsch verwendet?

    Hmm ja, das ist richtig. Allerdings muss man sich davon auch nicht irritieren lassen, selbst wenn (testweise) ein User auf unterschiedliche Weise einem Team zugeteilt wird - denn letzten Endes ist er immer nur in einem Team... und wird auch über alle Varianten hinweg auf "Team 0" gestellt, wenn er den DM-Modus verlässt ^^.
    Werd ich umstrukturieren.


    Heisst, alles etwas allgemeiner zu coden und nicht mit Gruppe1 / Gruppe2, sondern lieber direkt ein Array Gruppe[].

    Kannst du mir da ein Beispiel aufzeigen, was du genau meinst?
    Wie werden die Spieler in ein "Array" gelegt und wie frage ich ab in welchem "Array" dieser sich befindet?
    Zwei/drei Zeilen sollten als Beispiel reichen.


    Sry, vor ein paar Tagen das erste mal einen SAMP-Server installiert, so viel im Wiki und im Forum hier gelesen - ich bin schon ganz wirr, kann diesbezüglich kaum mehr einen sortierten Gedanken fassen. X-x



    Grüße

    Hi Goldkiller,
    vielen Dank schonmal für dein Bemühen, mir zu helfen. In manchen Fällen ist es irgendwie nicht leicht, mein Problem zu schildern - ich werde dir im Anschluss alle relevanten Code-Teile aufzeigen.
    Vorerst: Gruppe1 und Gruppe2 beinhaltet die Anzahl der jeweiligen Teammitglieder. Bei einem Teameinstieg wird die jeweilige Gruppe (je nachdem, ob Team1 oder Team2) um eins erhöht (Gruppe1++ bzw. Gruppe2++), bei Logout oder verlassen der DM-Runde um eins verringert.
    Die Variable Gruppe1Tod und Gruppe2Tod zählen die Tode, stirbt also ein User welcher im Team1 ist, wird Gruppe1Tod um eins erhöt. So kann ich bei jedem Todesfall überprüfen, ob bei einem der beiden Teams bereits alle verstorben sind (naemlich dann, wenn Gruppe1 gleich Gruppe1Tod ist) - und wenn ja, die nächste Runde starten lassen -> Countdown -> Türen werden geöffnet. Daher wird bei jedem Rundenstart Gruppe1Tod und Gruppe2Tod auf 0 zurück gestellt.
    Gruppe1Kills und Gruppe2Kills sind vorerst unbedeutend - möchte darin die Kills pro Team insgesamt zählen und per TextDraw einblenden lassen, aber das soll mit dem Problem nichts zu tun haben.


    Ich hoffe, das ist simpel genug erklärt ^^.


    So, jetzt mal alle relevanten Codestellen; gestartet wird aktuell über einen Befehl, /team:
    if (strcmp("/team", cmdtext, true, 10) == 0) // Team-Einstieg
    {
    if(IstSpielerInTeam(playerid, 0))
    {
    SetPlayerScore(playerid, 0);
    Verteilen1(playerid);
    return 1;
    }
    else
    {
    SendClientMessage(playerid,ROT,"Du spielst bereits! Verlasse die Runde mit /exit");
    return 1;
    }
    }

    Wenn der Spieler also noch nicht im DM-Modus spielt, werden seine Kills (Scores) resettet und die automatische Teamzuordnung wird gestartet:
    stock Verteilen1(playerid)
    {
    if(Gruppe1 > Gruppe2)
    {
    Gruppe[playerid] = 2;
    Gruppe2++;
    Gruppe2Tod++;
    SetPlayerTeam(playerid, 2);
    sSpieler[playerid][Team] = 2;
    SetSpawnInfo(playerid,2,185,959.1449,2167.9775,1011.0234,358.7257,24,250,31,500,0,1);
    SetPlayerColor(playerid, 0xFFE60000);
    SetPlayerHealth(playerid,0.0);
    }
    else if(Gruppe1 < Gruppe2)
    {
    Gruppe[playerid] = 1;
    Gruppe1++;
    Gruppe1Tod++;
    SetPlayerTeam(playerid, 1);
    sSpieler[playerid][Team] = 1;
    SetSpawnInfo(playerid,1,174,961.2678,2100.2549,1011.0256,7.5695,24,250,31,500,0,1);
    SetPlayerColor(playerid, 0x0073FF00);
    SetPlayerHealth(playerid,0.0);
    }
    else if(Gruppe1 == Gruppe2)
    {
    new r;
    r = random(3);
    if(r < 2)
    {
    Gruppe[playerid] = 1;
    Gruppe1++;
    Gruppe1Tod++;
    SetPlayerTeam(playerid, 1);
    sSpieler[playerid][Team] = 1;
    SetSpawnInfo(playerid,1,174,961.2678,2100.2549,1011.0256,7.5695,24,250,31,500,0,1);
    SetPlayerColor(playerid, 0x0073FF00);
    SetPlayerHealth(playerid,0.0);
    }
    else
    {
    Gruppe[playerid] = 2;
    Gruppe2++;
    Gruppe2Tod++;
    SetPlayerTeam(playerid, 2);
    sSpieler[playerid][Team] = 2;
    SetSpawnInfo(playerid,2,185,959.1449,2167.9775,1011.0234,358.7257,24,250,31,500,0,1);
    SetPlayerColor(playerid, 0xFFE60000);
    SetPlayerHealth(playerid,0.0);
    }
    }
    return 1;
    }

    Der Spieler wurde also einem Team zugeordnet, die Spieleranzahl des jeweiligen Teams um eins erhöht sowie auch die Tode des jeweiligen Teams erhöht (da dieser in der durch die Tür verschlossenen Spawnzone steht, muss also bis zum nächsten Countdown als tod gewertet werden).
    Mein OnPlayerSpawn sieht somit folgend aus:
    public OnPlayerSpawn(playerid)
    {
    if(IstSpielerInTeam(playerid,0)) //Spawn Zivi
    {
    SetPlayerPos(playerid,1107.5632,-1796.4484,16.5938);
    SetPlayerFacingAngle(playerid,90.8776);
    SetPlayerInterior(playerid,0);
    if(HatSpielerEinenSkin(playerid,0))
    {
    return 1;
    }
    else
    {
    SetPlayerSkin(playerid,sSpieler[playerid][Skin]);
    }
    return 1;
    }
    if(IstSpielerInTeam(playerid,1)) //Spawn TeamA1
    {
    SetPlayerPos(playerid,961.2678,2100.2549,1011.0256);
    SetPlayerFacingAngle(playerid,7.5695);
    SetPlayerInterior(playerid,1);
    SetPlayerColor(playerid, 0x0073FF00);
    SetPlayerTeam(playerid, 1);
    return 1;
    }
    if(IstSpielerInTeam(playerid,2)) //Spawn TeamA2
    {
    SetPlayerPos(playerid,959.1449,2167.9775,1011.0234);
    SetPlayerFacingAngle(playerid,358.7257);
    SetPlayerInterior(playerid,1);
    SetPlayerColor(playerid, 0xFFE60000);
    SetPlayerTeam(playerid, 2);
    return 1;
    }
    return 1;
    }


    Meine "alte" große Version von OnPlayerDeath dazu hast du ja bereits durch meinen Startbeitrag erhalten.
    Hilft dir das alles weiter? :D



    Grüße

    N'Abend Community,


    seit etwa vier bis fünf Tagen beschäftige ich mich erstmalig mit PAWN - mehr oder minder des Interesses wegen, ich habe nicht vor ein großes Projekt zu starten.
    Im Grunde will ich nichts weiter, als einen Übungsserver aufzubauen (um z.B. die Skills fuer DM-Aktionen aufzuwerten)... und habe mich an und für sich auch schon gut eingearbeitet. Registersystem steht, Adminsystem steht, DM-System steht halb, Auto/Tuning/Teleport-Funktionen in Form von Dialoge stehen, gemappte Objekte (~80) und aufgehende Türen stehen, InfoAnzeige innerhalb eines Deathmatch stehen halb.
    Allerdings habe ich nun einen Punkt erreicht, in dem ich das Problem nicht sehe, nicht erkenne und daher eure Hilfe benötige um weiter zu kommen.


    Weil ich derjenige bin, der Hilfe erwartet, will ich mein Problem und mein Ziel, das ich letzten Endes erreichen möchte, darlegen:
    Geplant sind unterschiedliche "Deathmatch"-Systeme, die sich in jeweils eigenen und extra ausgewählten Interiors abspielen - das soll hier jedoch keine Rolle spielen, gehen wir von EINEM Deathmatch-Modus aus.
    Der Spieler begibt sich (aktuell noch über einen Befehl) in den DM-Modus, in dem es zwei Teams gibt - es wird per (pseudo)Zufall entschieden, in welches Team er kommt sofern die Teams eine gleiche Spieleranzahl beherbergen, ansonsten steigt er automatisch im kleineren Team ein. Jedes Team hat automatisch seinen eigenen Skin sowie seine eigene Farbe (SetPlayerColor), nach jedem Tod (bzw. Spawn) werden die Waffen resettet und neu gegeben, bis dahin gibt es keine Probleme.
    Im DM-Interior gibt es zwei Spawnpunkte, einen für jedes Team und befindet sich auch beidemale hinter verschlossenen Türen. Auch das ist kein Problem.
    Etwas kniffelig wird es ab jetzt; Wenn der zweite Spieler spawnt, sein Team nur ihn besitzt und das gegnerische Team ebenfalls nur einen Spieler aufzuweisen hat, soll ein Countdown beginnen, nach diesem die Tore kurz geöffnet werden. Ebenfalls soll der Countdown beginnen und die Tore geöffnet werden, wenn unabhängig von der Teamgröße nur noch einer in beiden Teams am Leben ist.


    Bis auf ein paar seltsame Fehler hat das auch alles bereits funktioniert, aber eben mit kleinen Fehlern, die definitiv unter OnPlayerDeath zu finden sind. Da dieser Abschnitt bei mir das reinste Durcheinander war, auch viel zu (unnötig) groß, wollte ich mich daran machen, diesen Teil komplett neu zu schreiben, logisch nachvollziehend und skizzenhaft mit Stift und Papier bereits fertig gestellt.


    Vermutlich mag der eine oder andere jetzt denken, ja spinnt denn der, einen solchen Aufsatz zu schreiben mit seinen Zielen wenn es doch auch viel kürzer ginge - allerdings vermute ich, hier und da nochmal darauf zurück zu kommen, falls sich andere Problemchen die ich zu lösen hoffe nicht lösen lassen. ^^


    Mein OnPlayerDeath sieht aktuell wie folgt aus:

    public OnPlayerDeath(playerid, killerid, reason)
    {
    if(GetPlayerTeam(playerid) == 1 || GetPlayerTeam(playerid) == 2)
    {
    if(Gruppe1 == 0 || Gruppe2 == 0)
    {
    SendClientMessage(playerid,GELB,"Warte auf Gegner...");
    return 1;
    }
    if(Gruppe1 >= 1 && Gruppe2 >= 1)
    {
    if(Gruppe1 == Gruppe1Tod || Gruppe2 == Gruppe2Tod)
    {
    if(IstSpielerInTeam(killerid,1))
    {
    SetPlayerPos(killerid,961.2678,2100.2549,1011.0256);
    SetPlayerFacingAngle(killerid,7.5695);
    SetPlayerHealth(killerid,100.0);
    ResetPlayerWeapons(killerid);
    GivePlayerWeapon(killerid, 24, 250);
    GivePlayerWeapon(killerid, 31, 500);
    }
    if(IstSpielerInTeam(killerid,2))
    {
    SetPlayerPos(killerid,959.1449,2167.9775,1011.0234);
    SetPlayerFacingAngle(killerid,358.7257);
    SetPlayerHealth(killerid,100.0);
    ResetPlayerWeapons(killerid);
    GivePlayerWeapon(killerid, 24, 250);
    GivePlayerWeapon(killerid, 31, 500);
    }
    Gruppe1Tod = 0;
    Gruppe2Tod = 0;
    for(new i=0;i<MAX_PLAYERS;i++)
    {
    if(sSpieler[i][Team] == 1 || sSpieler[i][Team] == 2)
    {
    SendClientMessage(i,GELB,"Neue Runde wird gestartet in...");
    }
    }
    timecount = 7; // anpassen.
    timestop = SetTimer("Timer1",1000,true);
    return 1;
    }
    }
    }
    return 1;
    }

    Das Problem muss - warum, sehe ich nicht, hier liegen:


    if(Gruppe1 >= 1 && Gruppe2 >= 1)
    {
    if(Gruppe1 == Gruppe1Tod || Gruppe2 == Gruppe2Tod)


    Was ist an der zweiten if-Abfrage falsch?
    Ohne diese zweite Abfrage (wenn also bei beiden Teams mind. 1 Mitspieler vorhanden ist) läuft das durch, der Timer wird gestartet und somit die Tore geöffnet.
    Vorweg: Ich habe bereits einen Testbefehl eingebaut, welcher den Variablen Gruppe1, Gruppe1Tod, Gruppe2 und Gruppe2Tod den Wert 1 zuschreibt, um dort Unstimmigkeiten ausschließen zu können. Es liegt also nicht daran, dass die zweite if-Abfrage nicht erfüllt ist...


    Und der Vollständigkeit halber; mein altes OnPlayerDeath sah so aus:

    public OnPlayerDeath(playerid, killerid, reason)
    {
    if(GetPlayerTeam(killerid) != GetPlayerTeam(playerid))
    {
    SetPlayerScore(killerid, GetPlayerScore(killerid) + 1);
    new string[128];
    format(string, sizeof(string), "Kills: %d", GetPlayerScore(killerid));
    SendClientMessage(killerid,BLAU,string);
    if(IstSpielerInTeam(playerid,1))
    {
    if(IstSpielerInTeam(killerid,1) || IstSpielerInTeam(killerid,2))
    {
    Gruppe2Kills ++;
    new tod = GetPVarInt(playerid,"Tode");
    SetPVarInt(playerid,"Tode", tod + 1);
    for(new i=0;i<MAX_PLAYERS;i++)
    {
    if(sSpieler[i][Team] == 1 || sSpieler[i][Team] == 2)
    {
    new kname[MAX_PLAYER_NAME], oname[MAX_PLAYER_NAME], string2[128];
    GetPlayerName(killerid,kname,sizeof(kname));
    GetPlayerName(playerid,oname,sizeof(oname));
    format(string2, sizeof(string2), "{FFE600}%s {DCDCDC}tötete {0073FF}%s", kname, oname);
    SendClientMessage(i,GRAU,string2);
    }
    }
    }
    }
    if(IstSpielerInTeam(playerid,2))
    {
    if(IstSpielerInTeam(killerid,1) || IstSpielerInTeam(killerid,2))
    {
    Gruppe1Kills ++;
    new tod = GetPVarInt(playerid,"Tode");
    SetPVarInt(playerid,"Tode", tod + 1);
    for(new i=0;i<MAX_PLAYERS;i++)
    {
    if(sSpieler[i][Team] == 1 || sSpieler[i][Team] == 2)
    {
    new kname[MAX_PLAYER_NAME], oname[MAX_PLAYER_NAME], string2[128];
    GetPlayerName(killerid,kname,sizeof(kname));
    GetPlayerName(playerid,oname,sizeof(oname));
    format(string2, sizeof(string2), "{0073FF}%s {DCDCDC}tötete {FFE600}%s", kname, oname);
    SendClientMessage(i,GRAU,string2);
    }
    }
    }
    }
    }


    if(IstSpielerInTeam(playerid,1))
    {
    Gruppe1Tod++;
    if(Gruppe2 == 1)
    {
    Gruppe1Tod = 0;
    Gruppe2Tod = 0;
    Gruppe1Kills = 0;
    Gruppe2Kills = 0;
    SetPlayerPos(killerid,959.1449,2167.9775,1011.0234);
    SetPlayerFacingAngle(killerid,358.7257);
    SetPlayerHealth(killerid,100.0);
    ResetPlayerWeapons(killerid);
    GivePlayerWeapon(killerid, 24, 250);
    GivePlayerWeapon(killerid, 31, 500);
    for(new i=0;i<MAX_PLAYERS;i++)
    {
    if(sSpieler[i][Team] == 1 || sSpieler[i][Team] == 2)
    {
    SendClientMessage(i,GELB,"Neue Runde wird gestartet in...");
    }
    }
    timecount = 7; // anpassen.
    timestop = SetTimer("Timer1",1000,true);
    return 1;
    }
    if(Gruppe2 == 0)
    {
    SendClientMessage(playerid,GELB,"Warte auf Gegner...");
    return 1;
    }
    }
    if(IstSpielerInTeam(playerid,2))
    {
    Gruppe2Tod++;
    if(Gruppe1 == 1)
    {
    Gruppe1Tod = 0;
    Gruppe2Tod = 0;
    Gruppe1Kills = 0;
    Gruppe2Kills = 0;
    SetPlayerPos(killerid,961.2678,2100.2549,1011.0256);
    SetPlayerFacingAngle(killerid,7.5695);
    SetPlayerHealth(killerid,100.0);
    ResetPlayerWeapons(killerid);
    GivePlayerWeapon(killerid, 24, 250);
    GivePlayerWeapon(killerid, 31, 500);
    for(new i=0;i<MAX_PLAYERS;i++)
    {
    if(sSpieler[i][Team] == 1 || sSpieler[i][Team] == 2)
    {
    SendClientMessage(i,GELB,"Neue Runde wird gestartet in...");
    }
    }
    timecount = 7; // anpassen.
    timestop = SetTimer("Timer1",1000,true);
    return 1;
    }
    if(Gruppe1 == 0)
    {
    SendClientMessage(playerid,GELB,"Warte auf Gegner...");
    return 1;
    }
    }


    if(Gruppe1 == Gruppe1Tod || Gruppe2 == Gruppe2Tod)
    {
    if(IstSpielerInTeam(killerid,1))
    {
    SetPlayerPos(killerid,961.2678,2100.2549,1011.0256);
    SetPlayerFacingAngle(killerid,7.5695);
    SetPlayerHealth(killerid,100.0);
    ResetPlayerWeapons(killerid);
    GivePlayerWeapon(killerid, 24, 250);
    GivePlayerWeapon(killerid, 31, 500);
    }
    if(IstSpielerInTeam(killerid,2))
    {
    SetPlayerPos(killerid,959.1449,2167.9775,1011.0234);
    SetPlayerFacingAngle(killerid,358.7257);
    SetPlayerHealth(killerid,100.0);
    ResetPlayerWeapons(killerid);
    GivePlayerWeapon(killerid, 24, 250);
    GivePlayerWeapon(killerid, 31, 500);
    }
    Gruppe1Tod = 0;
    Gruppe2Tod = 0;
    for(new i=0;i<MAX_PLAYERS;i++)
    {
    if(sSpieler[i][Team] == 1 || sSpieler[i][Team] == 2)
    {
    SendClientMessage(i,GELB,"Neue Runde wird gestartet in...");
    }
    }
    timecount = 7; // anpassen.
    timestop = SetTimer("Timer1",1000,true);
    }
    return 1;
    }


    Hoffe, mir kann geholfen werden. :)



    Grüße