Benutzer-Werkzeuge

Webseiten-Werkzeuge


scripting:tutorials:level2:bandit_camps

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige ÜberarbeitungVorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
scripting:tutorials:level2:bandit_camps [2023/11/26 09:50] fritz_98scripting:tutorials:level2:bandit_camps [2024/05/20 13:03] (aktuell) fritz_98
Zeile 28: Zeile 28:
 ^ Key ^ Value-Typ ^ Bedeutung ^ ^ Key ^ Value-Typ ^ Bedeutung ^
 | **player** | Player Id | Spieler-Id des Spielers, dem die Armee gehören soll | | **player** | Player Id | Spieler-Id des Spielers, dem die Armee gehören soll |
-| **id** | Ganze Zahl (0 - 9) | Id der Armee. Es sollte pro Spieler-Id und Armee-Id maximal **eine** Armee geben. Somit ist die Anzahl der Armeen pro Spieler auf 10 beschränkt |+| **id** | Ganze Zahl (0 - 9) | Id der Armee. Es darf pro Spieler-Id und Armee-Id maximal **eine** Armee geben. Somit ist die Anzahl der Armeen pro Spieler auf 10 beschränkt |
 | **position** | Position (Table der Form ''{X = x, Y = y}'') | Defensive Position der Armee | | **position** | Position (Table der Form ''{X = x, Y = y}'') | Defensive Position der Armee |
 | **rodeLength** | Number | Radius um ''position'', innerhalb dessen sich die Armee bewegt | | **rodeLength** | Number | Radius um ''position'', innerhalb dessen sich die Armee bewegt |
Zeile 143: Zeile 143:
 =====Das Kampfverhalten===== =====Das Kampfverhalten=====
  
-[[ s5lua_g:g_funktionen:tickoffensiveaicontroller |Offensivecontroller]]+Damit die Armee eben dieses Kampfverhalten ausführen kann, erweitern wird erneut das Armee-Table mit weiteren Parametern, die unser gewünschtes Kampfverhalten beschreiben. Nach dem Armee- und Spawner-Setup starten wir einen [[ scripting:tutorials:level1:simple_job|Simple Job]], in dem [[ scripting:tutorials:level2:countdowns|alle 10 Sekunden]] das Armee-Kampfverhalten aktualisiert wird. Das ist deshalb notwendig, weil die Armee regelmäßig auf die Aktionen des Spielers reagieren können muss. Ein einmaliger Aufruf eines Verteidigungs-Befehls beispielsweise würde deshalb nicht ausreichen.
  
 +Für das Armeeverhalten verwenden wir die Funktion ''TickOffensiveAIController''. Sie steuert die Armee nach folgender Logik: Wenn sie nicht volle Stärke besitzt (also weniger Hauptmänner als in ''strength'' angegeben) verteidigt sie einen kleinen Bereich um die angegebene ''position''. Bei voller Stärke vergrößert sich der Verteidigungsradius. Außerdem kann der Armee erlaubt werden, anzugreifen. Dazu muss mindestens eine Position angegeben werden, die die Armee angreifen kann.
 +Das Armee-Table wird um folgende Key-Value-Paare erweitert:
 +^Key^Value-Typ^Bedeutung^
 +|**outerDefenseRange**|Zahl|Der Radius des äußeren Verteidigungsrings. Wenn die Armee maximale Stärke hat, verteidigt sie die angegebene Position ''position'' in diesem Umkreis|
 +|**baseDefenseRange**|Zahl|Der Radius des inneren Verteidigungsrings. Die Armee verteidigt sich in diesem Umkreis an der Position ''position'', wenn sie weniger als ''retreatStrength'' Hauptmänner besitzt|
 +|**retreatStrength**|Integer < ''strength''|Wenn weniger als ''retreatStrength'' Hauptmänner in der Armee sind, zieht sie sich in die ''baseDefenseRange'' zurück|
 +|**AttackPos**|Table|Liste an Postionen, aus denen zufällig eine als Angriffsziel für die Armee gewählt wird|
 +|**AttackAllowed**|Boolean|Gibt an, ob die Armee angreifen darf. Falls **true**, wird sie bei voller Stärke eine der Positionen in ''AttackPos'' zufällig auswählen und angreifen|
 +|**pulse**|Boolean|Wenn **true**, darf die KI kurzzeitig ihren Verteidiungsring verlassen, falls sie volle Stärke hat. Dadurch kann sie schwieriger von außerhalb des Rings beschossen werden|
  
 +Für unser Beispiel machen wir folgende Angaben (unter der Voraussetzung, dass für Spieler 1 ein Hauptquartier namens ''"Player1"'' sowie ein neutrales Dorfzentrum namens ''"VillageCenter"'' auf der Karte existiert):
 +
 +<code lua>
 +function CreateArmyBandits()
 +    ArmyBandits = {
 +        player = 2,
 +        id = 0,
 +        position = GetPosition("ArmyBanditsSpawn"),
 +        rodeLength = 4000,
 +        beAgressive = true,
 +
 +        strength = 8,
 +        spawnTypes = {
 +            {Entities.CU_BanditLeaderSword1, 8},
 +            {Entities.CU_BanditLeaderBow1, 4},
 +            {Entities.CU_BanditLeaderSword1, 8},
 +            {Entities.PU_LeaderPoleArm1, 4}
 +        },
 +        endless = true,
 +        spawnPos = GetPosition("ArmyBanditsSpawn"),
 +        spawnGenerator = "ArmyBanditsTower",
 +        maxSpawnAmount = 2,
 +        respawnTime = 90,
 +        noEnemy = true,
 +        noEnemyDistance = 2000,
 +        
 +        -- die baseDefenseRange entspricht der Konsistenz zuliebe genau der rodeLength,
 +        -- die wir weiter oben angegeben haben
 +        baseDefenseRange = 4000,
 +        
 +        -- wenn die Armee volle Stärke hat, soll sie einen Umkreis von 6000 scm verteidigen...
 +        outerDefenseRange = 6000,
 +        
 +        -- ...und sich wieder zurückziehen, falls sie nur noch 3 oder weniger Hauptmänner besitzt
 +        retreatStrength = 3,
 +        
 +        -- Angriffe sind erlaubt
 +        AttackAllowed = true,
 +        
 +        -- Die Armee soll entweder das Hauptquartier vom Spieler oder die Position eines (neutralen)
 +        -- Dorfzentrums angreifen
 +        AttackPos = {
 +            GetPosition("Player1"),
 +            GetPosition("VillageCenter")
 +        },
 +        
 +        -- Die Truppen sollen außerdem für kurze Zeit außerhalb ihres Radius kämpfen dürfen
 +        pulse = true
 +    }
 +
 +    SetupArmy(ArmyBandits)
 +    SetupAITroopSpawnGenerator("ArmyBanditsSpawnGenerator", ArmyBandits)
 +    -- Den Armee-Kontrolljob findest du im Codebeispiel weiter unten
 +    StartSimpleJob("ControlArmyBandits")
 +end
 +</code>
 +
 +Der Kontrolljob ''ControlArmyBandits'' soll zwei Dinge erfüllen: Er soll zuerst prüfen, ob die Armee, die er steuert, überhaupt noch existiert. Falls sie das tut, soll das im Armee-Table definierte Kampfverhalten mittels ''TickOffensiveAIController'' ausgeführt werden. Andernfalls soll sich der Job selbst beenden.
 +
 +<code lua>
 +function ControlArmyBandits()
 +    -- Die Kontrollfunktion soll nur alle 10 Sekunden aufgerufen werden
 +    -- Dazu verwenden wir den Counter, der im letzten Kapitel vorgestellt wurde
 +    -- Es ist zwar möglich, die Kontrollfunktion jede Sekunde aufzurufen - das
 +    -- ist allerdings verschwendete Performance und lässt die Armee erratisch wirken,
 +    -- da sie u.U. jede Sekunde neue Befehle erhält
 +    if Counter.Tick2("ControlArmyBanditsCounter", 10) then
 + 
 +        -- Die Funktion IsAITroopGeneratorDead prüft, ob sowohl alle Truppen der Armee
 +        -- als auch ihr Spawngebäude zerstört wurde
 +        if IsAITroopGeneratorDead(ArmyBandits) then
 +            -- Falls ja, beende den Kontrolljob
 +            return true
 +        else
 +            -- Andernfalls führe das im Armee-Table definierte Verhalten aus
 +            TickOffensiveAIController(ArmyBandits)
 +        end
 +
 +    end
 + 
 +end
 +</code>
 +
 +----
 +
 +Die "technischen" Aspekte des Skriptens sind damit für diese Ebene abgeschlossen. Im nächsten Kapitel wollen wir die vielen Möglichkeiten, die man als Skripter zur Kommunikation mit dem Spieler hat, anschauen und einem Zweck zuordnen.
 +
 +[[ scripting:tutorials:level2:countdowns | Voriges Kapitel: Zähler und Zeitlimits ]] \\
 +[[ scripting:tutorials:level2:communication | Nächstes Kapitel: Effektive Kommunikation mit dem Spieler ]] \\
 +[[ scripting:tutorials:level2:bandit_camps | Zurück nach oben ]]
scripting/tutorials/level2/bandit_camps.txt · Zuletzt geändert: 2024/05/20 13:03 von fritz_98