Ergebnis 1 bis 10 von 10

Thema: Reihenfolge der Spawns

  1. #1
    Erfahrener Benutzer Avatar von racer simon
    Registriert
    02.07.2010
    Alter
    22
    Beiträge
    297
    ManiaPlanet
    Challenger
    Login: racer_simon
    Nickname: Challenger
    Zone: World » Europe » Germany » Nordrhein-Westfalen » Düsseldorf
    Multiplayer: 7.866 (61.169 LP)
    Soloplayer: 12.298 (5.473 SP)
    Clan: Global Rebels
    TrackMania
    Challenger
    Login: racer_simon United
    Nickname: Challenger
    Zone: World » Germany » North Rhine-Westphalia » Düsseldorf
    Multiplayer: 46.775 (65.778 LP)
    Soloplayer: 12.811 (46.555 SP)
    Clan: Global Rebels
    Links: TM-Ladder

    Reihenfolge der Spawns

    Kurz vorweg: Es geht um die Gamemode-Programmierung mit Maniascript

    Jedes Team hat jeweils 3 Spawns. Ich unterteile nun eine Runde in 3 Phasen und in jeder Phase soll ein anderer Spawn genutzt werden.
    Ich habe mir überlegt, dass man diese Situation leicht mit den Variablen "Id" und "Order" aus der Klasse "CBlockSpawn" lösen kann.
    Dabei gibt die Id (1 oder 2) das Team an und Order (1 bis 3) gibt an, in welcher Phase der Spawn genutzt werden soll.
    Das Problem hierbei ist, dass die Funktionen, die die Spieler spawnen lassen, die Variable "Order" nicht berücksichtigen ( also nicht als Eingabeparameter haben ).
    Auch als ich mir das Melee-Script ( indem ja eigentlich die "Order"-Variable zum Einsatz kommen sollte ) angeschaut habe, bin ich nicht schlauer geworden.
    Dort werden alle Spawns in einer Liste gesammelt und die Spieler dann willkürlich über die Spawns verteilt.
    Dass das gezielte Spawnen möglich ist, zeigt der Spielmodus "Jailbreak" ja sehr gut.
    Allerdings habe ich keine Ahnung wie das funktionieren soll.

  2. #2
    Die Id des Spawns ist vom Typ Ident und dient zur genauen Identifizierung des Spawns. Dies ist keine Zahl (also kein 1 und 2!)
    Was du vielleicht meinst ist der Array-Index des Spawns in dem BlockSpawns-Array. (Also z.B. BlockSpawns[0] und BlockSpawns[1]!)
    Aber die sagen ja nichts über die Teamzugehörigkeit aus.
    Wieso nicht einfach so:
    Man muss im Editor 6 Spawns erstellen, denen man die Orders 1-6 zuweist. Order 1-3 = Team 1 Spawns, Order 4-6 = Team 2 Spawns... (Oder auch Order 1 = Team 1, Order 2 = Team 2 und die Reihenfolge der Spawns ist zufällig.)
    Jetzt kannst du im Script einen Algorithmus entwerfen, der jeweils den richtigen Spawn berechnet. (z.B. eine Variable hochzählen mit jeder Phase... )
    Und dann kannst du den Spawn einfach so beim Spawnen angeben:

    CSmMode
    ManiaScript:
    Void SpawnPlayer(CSmPlayer Player, Integer ClanNum, Integer Armor, CSmBlockSpawn BlockSpawn, Integer ActivationDate) {}

    Beispiel (für 1,2,3 = Team 1 | 4,5,6 = Team2)
    ManiaScript:
     
    // Global variables
    declare CSmBlockSpawn[Integer] BlockSpawnsRightOrder;
    declare Integer BlockSpawnIndex = 0;
     
    // Initialization
    foreach(BlockSpawn in BlockSpawns) {
        BlockSpawnsRightOrder[BlockSpawn.Order] = BlockSpawn;
    }
     
    // Methods
    Void CalculateSpawnIndex() {
        BlockSpawnIndex++;
        if(BlockSpawnIndex == (BlockSpawnsRightOrder.count / 2) + 1) {
            BlockSpawnIndex = 1;
        }
        return BlockSpawnIndex;
    }
     
    // Spawning
    declare Integer Clan = 1;
    declare Integer SpawnIndex = CalculateSpawnIndex() + (Clan - 1) * 3;
    SpawnPlayer(Players[0], 1, -1, AllBlockSpawns[SpawnIndex], Now);


    Das ist nur eine (ungetestete!) und evtl. nicht effiziente Idee, wie man es lösen kann.
    (In meinem Beispielcode sind bestimmt > 10 Leichtsinnsfehler drin.
    Geändert von ceptoplex (16.07.2012 um 16:12 Uhr)
    */

  3. #3
    Erfahrener Benutzer Avatar von racer simon
    Registriert
    02.07.2010
    Alter
    22
    Beiträge
    297
    ManiaPlanet
    Challenger
    Login: racer_simon
    Nickname: Challenger
    Zone: World » Europe » Germany » Nordrhein-Westfalen » Düsseldorf
    Multiplayer: 7.866 (61.169 LP)
    Soloplayer: 12.298 (5.473 SP)
    Clan: Global Rebels
    TrackMania
    Challenger
    Login: racer_simon United
    Nickname: Challenger
    Zone: World » Germany » North Rhine-Westphalia » Düsseldorf
    Multiplayer: 46.775 (65.778 LP)
    Soloplayer: 12.811 (46.555 SP)
    Clan: Global Rebels
    Links: TM-Ladder
    Ok, erstmal danke für deine Hilfe.
    Allerdings gibt es noch ein paar Sachen, die ich nicht so recht verstehe:
    Code:
    // Global variables
    declare CSmBlockSpawn[Integer] BlockSpawnsRightOrder; // Ist das jetzt ein Array oder eine Variable? Und die Klasse "CSmBlockSpawn" hab ich noch nie gesehen, ich denke du meinst "CBlockSpawn"declare Integer BlockSpawnIndex = 0;
     
    // Initialization
    foreach(BlockSpawn in BlockSpawns) {
        BlockSpawnsRightOrder[BlockSpawn.Order] = BlockSpawn[/COLOR];// ich versteh irgendwie nicht, welche Sinn die Variable/ das Array "BlockSpawnsRightOrder" hat
    } 
    // Methods
    Void CalculateSpawnIndex() {
        BlockSpawnIndex++;
        if(BlockSpawnIndex == (BlockSpawnsRightOrder.count / 2) + 1) {
            BlockSpawnIndex = 1;
        }
        return BlockSpawnIndex;
    }
     
    // Spawning
    declare Integer Clan = 1;
    declare Integer SpawnIndex = CalculateSpawnIndex() + (Clan - 1) * 3;
    SpawnPlayer(Players[0], 1, -1, AllBlockSpawns[SpawnIndex], Now);
    edit: Wie macht man den schönen Maniascript Code?
    Geändert von racer simon (16.07.2012 um 19:48 Uhr)

  4. #4
    Mit dem [script]-Tag kannst du ManiaScript Code einbinden.

    Zu den Fragen:

    a) Ja, ich meine CSmBlockSpawn ... den Typ den du meinst bezeichnet dasselbe, jedoch wurde da nochmal einiges umbenannt. So wie ich es verwende, ist es aktuell. Du solltest dir auch vielleicht mal eine aktuelle Dokumentation besorgen.
    Du solltest am besten tunlichst vermeiden, veraltete Typnamen zu verwenden, da es immer sein kann, dass die Entwickler des ManiaScripts es sich anders überlegen und die alten Bezeichnungen nicht nur als veraltet stehen lassen sondern ganz aus dem Syntax streichen, dann wär'st du mit deinem Skript aufgeschmissen.
    Und ja, es ist ein Array.

    b) Der Sinn des Arrays BlockSpawnsRightOrder ist der, dass die Spawns in diesem Array entsprechend der "Order" Variable, die man beim Editor jedem Spawn geben kann, angeordnet sind.
    Wenn ich den "normalen" Array BlockSpawns verwenden würde, könnte es sein, dass die Spawns in diesem Array nach der Zeit des Baus oder der Lage der Blöcke angeordnet sind, was ungünstig für mein System wäre. (Da ich davon ausgehe, dass Index 1-3 Team 1 gehört und Index 4-6 Team 2!)
    Das "[Integer]" bei der Arraydeklaration am Anfang bewirkt übrigens, dass ich die Elemente zu dem Array BlockSpawnsRightOrder nicht mit .add() hinzufügen muss, sondern konkrete Werte zuweisen kann. ( z.B. Array[Wert] = X; )

    Falls noch was unklar ist einfach weiter nachfragen, bin kein Ass in Erklärungen.
    */

  5. #5
    Erfahrener Benutzer Avatar von racer simon
    Registriert
    02.07.2010
    Alter
    22
    Beiträge
    297
    ManiaPlanet
    Challenger
    Login: racer_simon
    Nickname: Challenger
    Zone: World » Europe » Germany » Nordrhein-Westfalen » Düsseldorf
    Multiplayer: 7.866 (61.169 LP)
    Soloplayer: 12.298 (5.473 SP)
    Clan: Global Rebels
    TrackMania
    Challenger
    Login: racer_simon United
    Nickname: Challenger
    Zone: World » Germany » North Rhine-Westphalia » Düsseldorf
    Multiplayer: 46.775 (65.778 LP)
    Soloplayer: 12.811 (46.555 SP)
    Clan: Global Rebels
    Links: TM-Ladder
    Ok, ich verstehe immer noch nicht alles:
    ManiaScript:
     
    // Methods
    Void CalculateSpawnIndex() {
        BlockSpawnIndex++;
        if(BlockSpawnIndex == (BlockSpawnsRightOrder.count / 2) + 1) {  /*Ich nehme einfach mal an, dass die Funktion count die Elemente eines Arrays zählt; aber wieso rechnest du /2 +1? Beispielrechnung bei 6 Elementen im Array: (6/2)+1= 4
    also: if (1==4) ist falsch, also wird 1 zurückgegeben*/ 
            BlockSpawnIndex = 1;
        }
        return BlockSpawnIndex;
    }
     

    ManiaScript:
     
    // Spawning
    declare Integer Clan = 1;
    declare Integer SpawnIndex = CalculateSpawnIndex() + (Clan - 1) * 3; //1+(1-1)*3=3
    SpawnPlayer(Players[0], 1, -1, AllBlockSpawns[SpawnIndex], Now);//Wieso ist Armor auf -1?
     
    Geändert von racer simon (17.07.2012 um 10:12 Uhr)

  6. #6
    1.

    Ich will BlockSpawnIndex berechnen (der kann 1-3 sein).
    Um ehrlich zu sein will ich einfach nur immer eins dazuzählen, und mit der if-Überprüfung setze ich es bei dem Stand von 4 auf 1 zurück.
    Statt einer 4 hinzuschreiben, wollte ich das Ganze bei unterschiedlicher Spawnanzahl dynamisch halten und die 4 aus "(Spawns-Anzahl / 2) + 1" errechnen.
    Du hast geschrieben: "if(1==4) ist falsch, also wird 1 zurückgegeben". Das ist Quatsch.
    Sofern ich Programmiercode lesen kann habe ich in Syntax hingeschrieben: "if(1==4) => auf 1 zurücksetzen". (Weder zurückgeben, noch ein Nicht!)
    Spoiler: Uninteressantes Geschwafel, dient nicht zur Erklärung
    Dieser berechnet Wert (BlockSpawnIndex) gibt ab, welcher Spawn als nächstes dran ist. Mit dem "+ (Clan - 1) * 3" unten entscheide ich dann, ob ich den Spawn aus den Spawns mit den Indexen 1-3 oder den Indexen 4-6 auswähle. (Je nach Team...)
    Da 1-3 die Spawns des 1. Teams und 4-6 die Spawns des 2. Teams darstellen, ergibt die Formel "CalculateSpawnIndex() + (Clan - 1) * 3".

    2.

    Das mit der Armor = -1 hab ich glaub ich mal irgendwo im Nadeo Code gesehen und vermute, dass das irgendein Standardwert sein soll. (Unendlich Armor oder normale 2 Armor, keine Ahnung. Weiß auch ehrlich gesagt garnicht ob das funktioniert. ) Kannst da einfach nen ganz normalen Wert verwenden.
    Geändert von ceptoplex (17.07.2012 um 15:59 Uhr)
    */

  7. #7
    Erfahrener Benutzer Avatar von racer simon
    Registriert
    02.07.2010
    Alter
    22
    Beiträge
    297
    ManiaPlanet
    Challenger
    Login: racer_simon
    Nickname: Challenger
    Zone: World » Europe » Germany » Nordrhein-Westfalen » Düsseldorf
    Multiplayer: 7.866 (61.169 LP)
    Soloplayer: 12.298 (5.473 SP)
    Clan: Global Rebels
    TrackMania
    Challenger
    Login: racer_simon United
    Nickname: Challenger
    Zone: World » Germany » North Rhine-Westphalia » Düsseldorf
    Multiplayer: 46.775 (65.778 LP)
    Soloplayer: 12.811 (46.555 SP)
    Clan: Global Rebels
    Links: TM-Ladder
    So, ich hab in letzter Zeit mir deinen Code mal ein bisschen näher angeschaut, meinen Wünschen angepasst und in mein Script eingebaut.
    Hier erstmal mein angepasster Code:
    ManiaScript:
     
    // Deklaration
    declare CSmBlockSpawn[Integer] BlockSpawnsRightOrder;
    declare Integer BlockSpawnIndex = 0;
    declare Integer SpawnIndex = 0;
     
    // Spawns in die richtige Reihenfolge bringen
    foreach (BlockSpawn in BlockSpawns) {
        if (0 < BlockSpawn.Order && BlockSpawn.Order < 7) {
            BlockSpawnsRightOrder[BlockSpawn.Order] = BlockSpawn;
        }
    }
     
    // Das Spawnen an sich
    foreach(Player in Players) {
            BlockSpawnIndex = CalculateSpawnIndex(Player.RequestedClan, CurrentStage);
         if (Player.SpawnStatus != CSmPlayer::ESpawnStatus::NotSpawned) continue;                                   
         BalancedWeapons::SetPlayerWeapon(Player, True);            
         SM::SpawnPlayer(Player, Player.RequestedClan, BlockSpawnsRightOrder[BlockSpawnIndex], Now + RespawnTime);                
    }        
     
    // Die Funktion CalculateSpawnIndex
    Integer CalculateSpawnIndex(Integer CurrentClan, Integer CurrentStage) { // CurrentStage kann 1,2 oder 3 sein; mit Stage ist hier die Phase der Runde gemeint
        return CurrentStage + (CurrentClan * CurrentClan -1);
    }


    Beim Testen des Scripts hab ich sehr schnell gemerkt, dass die Spawns der ersten Stage funktionieren ( also in diesem Fall Spawn#1 und Spawn #4 ), die der zweiten aber nicht mehr. Man sieht die Map von oben, spawnt aber nicht und die Zeit läuft ab.
    Komischerweise wird aber kein Error ausgegeben.
    Ich weiß momentan einfach nicht weiter und ich hoffe, jemand kann mir helfen, dem Fehler auf die Schliche zu kommen.

    mfg Simon

  8. #8
    Wenn das oben dein gesamter Code ist, den du hast - funktioniert das natürlich kein zweites Mal.
    Du musst das dann schon auch richtig zusammenschneiden.
    Du brauchst u.a. eine Endlosschleife für die Runden, die nach jeder Runde wieder von vorne beginnt.
    Besser gesagt - wenn du Respawn wünscht - eigentlich dauernd aktiv ist.
    Es muss eine Endlosschleife geben (natürlich mit yield; - natürlich auch nicht Endlos, halt bis zum Matchende/Server-Shutdown etc.), die die ganze Zeit versucht, Players (die gestorben sind) zu respawnen.

    Die Respawn-Aktivität könnte z.B. dann irgendwie so aussehen:
    ManiaScript:
    Void SpawnPlayers() {
        foreach(Player in Players) {
            BlockSpawnIndex = CalculateSpawnIndex(Player.RequestedClan, CurrentStage);
            if (Player.SpawnStatus != CSmPlayer::ESpawnStatus::NotSpawned) {
                BalancedWeapons::SetPlayerWeapon(Player, True);            
                SM::SpawnPlayer(Player, Player.RequestedClan, BlockSpawnsRightOrder[BlockSpawnIndex], Now);
            }
        }
    }
     
    // Endlosschleife
     
    declare Boolean MatchEndRequested;
    while(!ServerShutdownRequested || MatchEndRequested) {
        yield;
        SpawnPlayers();
        // if(Win) {
        //     MatchEndRequested = True;
        // }
    }

    Da fällt mir auf ... wiso hast du eigentlich ein continue; oben bei der NotSpawned-Abfrage stehen?
    Das bedeutet ja, dass er einen Player nicht spawnt, wenn er noch nicht "nicht gespawnt" ist. Nicht nicht gespawnt bedeutet ja aber nicht "gespawnt", sondern kann auch ESpawnStatus::Spawning sein. In diesem Fall tritt folgendes Problem auf (Spawning dauert ein Weilchen):

    Was noch sein könnte ist, dass du eine Respawn-Time verwendest.
    Falls du das also alles schon richtig machst wie ich beschrieben hab (Endlosschleife etc.), ruft er die Spawn-Methode sehr schnell immer wieder auf.
    Wenn du jetzt eine Respawn-Time festlegst von z.B. 5 Sekunden, dann will er den Player in 5 Sekunden spawnen wollen.
    Jetzt ist dein Skript aber schneller, prüft wieder, ob der Player schon gespawnt wurde (was natürlich negativ ist) und setzt die Zeit auf Now + 5 Sekunden (immer so weiter, Player wird nie gespawnt!).
    Das könnte auch noch ein Grund sein...
    Sowas könnte man mit was ähnlichem wie ...
    ManiaScript:
    wait(Player.SpawnStatus == CSmPlayer::ESpawnStatus::Spawned);

    ...lösen, was aber hier bei 5 Sekunden nicht optimal ist, da da ja das Skript 5 Sekunden angehalten wird. Das müsste man also nochmals anders bauen.
    Auf jeden Fall wäre es schonmal ein Anfang, dein if/continue-Konstrukt durch sowas ähnliches wie das ...
    ManiaScript:
    if (Player.SpawnStatus != CSmPlayer::ESpawnStatus::NotSpawned) {
    // Spawn
    }

    ... zu ersetzen.

    Hab vielleicht jetzt zu wirr gelabert, einfach nochmal nachfragen, falls was unklar ist.
    Geändert von ceptoplex (27.07.2012 um 19:52 Uhr)
    */

  9. #9
    Erfahrener Benutzer Avatar von racer simon
    Registriert
    02.07.2010
    Alter
    22
    Beiträge
    297
    ManiaPlanet
    Challenger
    Login: racer_simon
    Nickname: Challenger
    Zone: World » Europe » Germany » Nordrhein-Westfalen » Düsseldorf
    Multiplayer: 7.866 (61.169 LP)
    Soloplayer: 12.298 (5.473 SP)
    Clan: Global Rebels
    TrackMania
    Challenger
    Login: racer_simon United
    Nickname: Challenger
    Zone: World » Germany » North Rhine-Westphalia » Düsseldorf
    Multiplayer: 46.775 (65.778 LP)
    Soloplayer: 12.811 (46.555 SP)
    Clan: Global Rebels
    Links: TM-Ladder
    Du hast jetzt nicht ernsthaft gedacht, dass da oben ist mein gesamter Code?!
    Natürlich läuft alles in mehreren Endlosschleifen.
    Na ja, auf jeden Fall ist interessant, was du zu folgender Codezeile geschrieben hast:
    ManiaScript:
     if (Player.SpawnStatus != CSmPlayer::ESpawnStatus::NotSpawned) continue;

    Ich glaube, mit deiner Vermutung liegts du gar nicht mal so falsch, aber widmen wir uns erstmal der Frage, warum der Code in meinem Script ist.
    Dazu muss man Folgendes wissen: Mein ganzes Script basiert auf dem Battle Script, d.h. , dass ich das Battle Script einfach kopiert habe und dann nach und nach umgebaut habe. Diese Codezeile ist ein Überbleibsel des Battle Scripts.
    Daher es bisher funktioniert hat, hab ich es einfach so gelassen.
    Zu deiner Vermutung: Ich werde das Script jetzt mal so umbauen, dass der von dir genannte Fehler nicht mehr auftauchen sollte.
    Vielleicht kann ich dir heute noch eine Rückmeldung geben.

    mfg Simon

  10. #10
    Hm ok ... tut mir Leid dass ich das vermutet habe, aber die Fehlerbeschreibung "man spawnt nur einmal" enthielt für mich zu wenige programmiertechnische und strukturelle Details, um einen konkreten Lösungsweg aufzuzeigen.
    (Weil der Ansatz ist ja richtig!)
    */

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •