[[http://www.siedler-games.de|{{:sg-link.jpg|}}]]
====== Armeen erstellen ======
===== Einführung =====
Um eine Armee zu erstellen, reicht es nicht aus, im Siedler5-Editor einfach die
Truppen auf die Karte zu setzen. Man würde die Soldaten zwar im Spiel sehen,
aber das wären nur nutzlose Teile, weil man sie weder befehligen noch sonst
etwas mit ihnen tun kann.
Eine Armee, egal ob für den menschlichen oder Computerspieler, muss immer im
Script erzeugt werden. Da jede Armee, genau wie jeder Spieler auch, eine
eindeutige ID haben muss, ist die Anzahl der nutzbaren Armeen (pro Spieler-ID)
begrenzt auf 10, da als ID nur die Ziffern von 0 bis 9 zulässig sind.
D.h. jeder Spieler kann maximal 10 Armeen haben.
===== Einfaches Beispiel =====
Hier wird eine einfache Armee erstellt, welche aus mehreren Trupps des gleichen
Soldatentyps besteht.
==== Mit Erläuterungen ====
function CreateArmyOne()
-- Erzeugt eine so genannte Tabelle, die alle für das Spiel benötigten Daten
-- über die Armee aufnimmt. Eine Armee sollte immer in eine globale Variable
-- gespeichert werden, um sie später auch noch außerhalb dieser Funktion
-- steuern zu können
armyOne = {
-- ID des Spielers, für den die Armee bestimmt ist
player = 2,
-- Eine zulässige und pro Armee einmalige(!) ID von 0 bis 9
id = 1,
-- strength gibt die durchschnittliche Stärke der Armee an.
-- Stärke bedeutet mit anderen Worten die Anzahl der Truppen
-- bzw. Hauptmänner
-- Der Wert wird u.a. als Richtlinie für die Funktionen IsWeak() und
-- IsVeryWeak() genutzt.
-- Es können maximal 8 Hauptmänner in einer Armee sein
-- Es ist zwar durchaus möglich, hier eine Zahl größer als 8 einzutragen,
-- allerdings werden nur maximal 8 Hauptmänner durch die KI kontrolliert.
-- Alle anderen stehen nur in der Gegend rum und verteidigen sich nur,
-- wenn sie angegriffen werden.
strength = 8,
-- Die Position, an der die Armee erzeugt werden soll (eine
-- XD_ScriptEntity, welche in diesem Fall den Namen "armyOne" trägt)
position = GetPosition("armyOne"),
-- Bestimmt den Aktionsradius,
-- innerhalb dessen die Armee selbständig angreift
rodeLength = 4000
}
-- ruft die Comfort-Function "SetupArmy" des Spieles auf,
-- um die Armee mit den Daten aus der Tabelle zu erzeugen
SetupArmy(armyOne)
-- Die Armee existiert nun, aber hat noch keine Truppen.
-- Also wird eine Tabelle erzeugt, in der festgelegt wird, welche und wie
-- viele Trupps zu der Armee gehören
-- ein Trupp ist ein Hauptmann und die entsprechende Anzahl Soldaten
local troopDescription = {
-- Anzahl der Soldaten pro Hauptmann
maxNumberOfSoldiers = 4,
-- Die Anzahl der Soldaten, bei der der Hauptmann zur nächsten Kaserne
-- geht und Soldaten auffüllt
minNumberOfSoldiers = 0,
-- Der Erfahrungsgrad, den die Armee bei der Erzeugung hat
-- LOW_EXPERIENCE,
-- MEDIUM_EXPERIENCE,
-- HIGH_EXPERIENCE,
-- VERYHIGH_EXPERIENCE
experiencePoints = LOW_EXPERIENCE,
-- Der Truppentyp.
-- Dies !!muss!! etwas mit "Leader" im Namen sein, sonst wird das Spiel
-- ohne Fehlermeldung abstürzen!
leaderType = Entities.PU_LeaderSword1
}
-- EnlargeArmy wird 8x aufgerufen, um der Armee 8 dieser Trupps hinzuzu-
-- fügen. Dadurch hat die Armee 8 Hauptmänner
for i = 1, 8 do
EnlargeArmy(armyOne, troopDescription)
end
-- Einen Job starten, der die Armee nun kontrolliert.
-- Das sollte immer gemacht werden, da es sonst vielleicht zu einigen
-- merkwürdigen Verhaltensweisen kommt
StartSimpleJob("ControlArmyOne")
end
function ControlArmyOne()
-- Armee-Befehle müssen nicht jede Sekunde erteilt werden:
-- Im Normalfall reicht es alle 10 Sekunden
-- Dafür sorgt diese if-Abfrage
if Counter.Tick2("ControlArmyOne", 10) then
-- Wenn die Armee besiegt wurde, muss sie auch nicht mehr kontrolliert
-- werden.
if IsDead(armyOne) then
-- Job beenden
return true
end
-- Verhalten der Armee bestimmen
-- hier: verteidigen
Defend(armyOne)
end
end
==== Ohne Erläuterungen ====
function CreateArmyOne()
armyOne = {
player = 2,
id = 1,
strength = 8,
position = GetPosition("armyOne"),
rodeLength = 4000
}
SetupArmy(armyOne)
local troopDescription = {
maxNumberOfSoldiers = 4,
minNumberOfSoldiers = 0,
experiencePoints = LOW_EXPERIENCE,
leaderType = Entities.PU_LeaderSword1
}
for i = 1, 8 do
EnlargeArmy(armyOne, troopDescription)
end
StartSimpleJob("ControlArmyOne")
end
function ControlArmyOne()
if Counter.Tick2("ControlArmyOne", 10) then
if IsDead(armyOne) then
return true
end
Defend(armyOne)
end
end
Wenn Ihr also die Zahl bei maxNumberOfSoldiers auf 8 ändert, werden pro
Hauptmann 8 statt 4 Soldaten erzeugt. Die oben stehende Funktion würde also nun
8 Hauptmänner mit je 4 Soldaten vom Typ Schwertkämpfer Stufe 1 mit niedriger
Erfahrungsstufe erzeugen.
===== Erweitertes Beispiel =====
Wenn jetzt in derselben Armee auch noch Bogenschützen und Lanzenträger vorhanden
sein sollen, muss nur der Teil mit der Beschreibungstabelle angepasst werden. Im
obigen Fall heißt die Tabelle troopDescription. Nun spricht nichts dagegen, der
Armee mehrere Tabellen mit jeweils verschiedenen Truppen zu übergeben.
function CreateArmyOne()
armyOne = {
player = 2,
id = 1,
strength = 8,
position = GetPosition("armyOne"),
rodeLength = 4000
}
SetupArmy(armyOne)
local troopDescription = {
maxNumberOfSoldiers = 4,
minNumberOfSoldiers = 0,
experiencePoints = MEDIUM_EXPERIENCE,
leaderType = Entities.PU_LeaderSword1
}
for i = 1, 8 do
EnlargeArmy(armyOne, troopDescription)
end
local troopDescription = {
maxNumberOfSoldiers = 6,
minNumberOfSoldiers = 0,
experiencePoints = LOW_EXPERIENCE,
leaderType = Entities.PU_LeaderBow1
}
for i = 1, 6 do
EnlargeArmy(armyOne, troopDescription)
end
local troopDescription = {
maxNumberOfSoldiers = 8,
minNumberOfSoldiers = 0,
experiencePoints = LOW_EXPERIENCE,
leaderType = Entities.PU_LeaderPoleArm3
}
for i = 1, 4 do
EnlargeArmy(armyOne, troopDescription)
end
StartSimpleJob("ControlArmyOne")
end
Also haben wir jetzt folgende Tabellen:
* troopDescription1 8 Trupps einfache Schwertkämpfer zu je 4 Soldaten mit mittlerer Erfahrung
* troopDescription2 6 Trupps einfache Bogenschützen zu je 6 Soldaten mit niedriger Erfahrung
* troopDescription3 4 Trupps verbesserte Lanzenträger zu je 8 Soldaten mit niedriger Erfahrung
===== Spezialfall: Truppen für den Spieler =====
Wenn dem Spieler Einheiten gegeben werden sollen, braucht man dazu keine Armee
erstellen. Der Spieler kann auch mit normalen Truppen umgehen, die keiner Armee
gehören.
In diesem Beispiel wird ein großer Trupp guter Bogenschützen, sowie drei kleine
Trupps mittelmäßiger Schwertkämpfer erstellt.
function CreateSupportTroops()
CreateMilitaryGroup(1, Entities.PU_LeaderBow4, 8, GetPosition("supporttroops"), "bows")
for i = 1, 3 do
CreateMilitaryGroup(1, Entities.PU_LeaderSword2, 4, GetPosition("supporttroops"))
end
end
Der Bogenschützentruppe wurde zusätzlich der Name "bows" gegeben. //Dies braucht
man nicht zu tun//, wenn man dieser Truppe keine anschliessenden Befehle
erteilen will. Mit dem Namen könnte man den Trupp beispielsweise vom Spawnpunkt
aus zum Hauptquartier des Spielers laufen lassen. Da die Truppen aber schon dem
Spieler gehören, kann dieser natürlich jederzeit andere Befehle erteilen.
Move("bows", "Player_HQ")
===== Potentielle Probleme =====
Mit der Handhabung von Armeen gibt es leider ein paar Probleme.
Diese werden hier aufgelistet.
==== IsDead direkt nach der Erstellung ====
Manchmal möchte man wissen, wann eine Armee vernichtet wurde, um daraufhin eine
Aktion auszulösen. Dazu wird ein Job gestartet, welcher IsDead( army ) abfragt.
Allerdings ist diese Bedingung //direkt// nach der Erstellung der Armee erfüllt,
da von der Erzeugung per Script, bis zum Erscheinen im Spiel, ein wenig Zeit
vergeht.
Hierzu gibt es einen modifizierten Abfragecode, der das Problem behebt.
Damit er korrekt funktioniert, muss er direkt nachdem die Armee erstellt wurde
als Job gestartet werden.
**Achtung: Wenn es nur darum geht, einen Job zu haben, der die Armee
kontrolliert, dann ist dieser Code __nicht__ nötig. Durch Counter.Tick2() wird
dieses Problem gar nicht erst auftreten, da der erste Befehl erst nach 10
Sekunden erteilt wird und die Armee bis dahin garantiert schon existiert!**
function IsDeadArmyOne()
if not armyOne.created then
armyOne.created = not IsDead(armyOne)
return false
end
if IsDead(armyOne) then
Message("armyOne ist besiegt")
return true
end
end
Dieser Code bewirkt, daß armyOne nicht als Dead gilt, solange sie noch nicht
erzeugt wurde.
==== KI benötigt ====
Armeen funktionieren nicht richtig, wenn kein KI Spieler für die entsprechende
SpielerID erstellt wurde. Wenn dieser KI-Spieler aber **kein** Gebäude besitzt,
stürzt das Spiel ab. Dieses Gebäude muss kein Spielergebäude sein, sondern kann
auch ein Zelt, ein Turm, ein Leuchtturm usw. sein. "Funktioniert nicht richtig"
bedeutet in diesem Fall, das sämtliche Armeen ohne KI sofort als tot erklärt
werden und deshalb jegliche Armee-Kontrolle unmöglich ist. Die Truppen stehen
zwar immer noch dort rum, tun aber nichts. In Verbindung mit einem
SpawnGenerator entstehen dann unendlich viele Soldaten, wodurch das Spiel früher
oder später hängen bleibt oder abstürzt.
Die KI wird übrigens mit der Funktion MapEditor_SetupAi() oder SetupPlayerAi()
aktiviert.
==== Automatische Bewegung durch die KI ====
**Wichtig:** Je nach "strength"-Wert, der beim Erstellen eines
[[computergegner_-_grundlagen|Computergegners]] (= KI) angegeben wurde, werden
für diese KI unterschiedlich viele Slots für Armeen erstellt. Armeen mit einer
der entsprechenden IDs werden von der KI kontrolliert; egal ob sie per Script
erstellt wurden oder die KI sie selbst ausgebildet hat.
Zur Vermeidung von Problemen sollten diese IDs für die Erstellung von Armeen per
Script **nicht verwendet werden**.
^ Stärke ^ Reservierte IDs ^
| 1 | 1 bis 2 |
| 2 | 1 bis 4 |
| 3 | 1 bis 6 |
Die KI erteilt Armeen mit einer anderen ID keine Befehle; diese können per
Skriptbefehlen kontrolliert werden.
Mehr dazu hier: http://www.siedler-portal.de/vb3/showthread.php?t=3896
===== Siehe auch =====
* [[reference:advance|Advance]]\\
* [[reference:defend|Defend]]\\
* [[reference:frontalattack|FrontalAttack]]\\
* [[reference:redeploy|Redeploy]]\\
* [[reference:retreat|Retreat]]\\
* [[reference:synchronize|Synchronize]]\\
\\
* [[reference:counter|Counterfunktionen]]\\
* [[tutorials:begleitende_armeen_erstellen|Begleitende Armee erstellen]]\\
* [[tutorials:advancedarmycontrolling|Steuerung von Armeen]]
* [[reference:setupaitroopspawngenerator|SetupAiTroopSpawnGenerator]]
* [[reference:tickoffensiveaicontroller|SetupAITroopSpawnGenerato mit TickOffensiveAIController]]
\\
\\
[[reference:functions-summary|Zur Befehlsreferenz-Übersicht]]
\\
[[:tutorials:index|Zur Tutorial-Übersicht]]