Dies ist eine alte Version des Dokuments!
Inhaltsverzeichnis
Orte erreichen, Gebäude bauen, Gegner besiegen
Für viele Typen von Quests, die in Siedler 5 üblich sind, existieren vorgefertigte Skripthilfen, um sie leichter implementieren zu können. Zu diesen Typen zählt das Erreichen eines gewissen Zielorts, die Zerstörung bestimmter Gegner oder das Errichten einiger Gebäude. Die dafür zur Verfügung stehenden Hilfsfunktionen werden im Folgenden nacheinander vorgestellt.
Wichtig: Die Funktionen, die wir vorstellen, prüfen nur die Erfüllung einer Quest! Einleitende oder abschließende Briefings, Questlogeinträge, NPCs, etc müssen gesondert definiert werden.
Orte erreichen: SetupExpedition
SetupExpedition(_QuestDescription)
prüft, ob eine bestimmte Entity oder eine Entity einer bestimmten Kategorie einen Bereich auf der Karte erreicht hat. _QuestDescription
ist ein Table mit den folgenden Parametern:
Key | Value-Typ | Bedeutung | Erforderlich? |
---|---|---|---|
EntityName | String oder Number | Skriptname oder Entity-Id der Entity, die den Bereich erreichen soll | Ja, wenn sonst nichts gegeben, sonst optional |
Heroes | Boolean | Irgendein Held muss den Bereich erreichen | Ja, wenn sonst nichts gegeben, sonst optional |
Leaders | Boolean | Irgendein Hauptmann muss den Bereich erreichen | Ja, wenn sonst nichts gegeben, sonst optional |
Serfs | Boolean | Irgendein Leibeigener muss den Bereich erreichen | Ja, wenn sonst nichts gegeben, sonst optional |
TargetName | String oder Number | Skriptname oder Entity-Id der Entity, die im Mittelpunkt des zu erreichenden Bereichs steht | Ja |
Distance | Number | Abstand zu TargetName , der für die Erfüllung der Bedingung unterschritten werden muss | Ja |
Callback | Funktion | Funktion, die aufgerufen wird, sobald der Bereich erreicht wurde | Ja |
Der zu erreichende Bereich wird demnach als Kreisfläche definiert. Mindestens einer von EntityName
, Heroes
, Leaders
oder Serfs
muss angegeben sein, damit die Quest erfüllbar wird.
In foldendem einfachen Beispiel soll Dario Helias in Crawford erreichen. Dazu müssen auf der Karte sowohl eine Entity mit dem Skriptnamen „Dario“ als auch eine Entity mit dem Skriptnamen „Helias“ existieren.
function CreateQuestFindHelias() QuestFindHelias = { EntityName = "Dario", TargetName = "Helias", Distance = 700, Callback = CallbackQuestFindHelias } SetupExpedition(QuestFindHelias) end function CallbackQuestFindHelias() -- diese Funktion wird ausgeführt, sobald Dario am Ziel ist end
Tipp: Du kannst deine gewünschte Distanz durch Platzieren eines XS_Ambient auf die Entity in TargetName
ermitteln. Das 100-fache der angegebenen Größe der Ambient-Entity entspricht genau der anzugebenden Distanz in SetupExpedition
.
Im obigen Beispiel definieren wir die _QuestDescription
als globales Table. Das ist nur notwendig, falls du die Quest später vorzeitig beenden willst.
Man kann die Bedingungen für einzelne Entities und Entity-Kategorien auch kombinieren. Beispielsweise soll entweder ein Bote namens „Hannes“ oder ein beliebiger Held den Bürgermeister „Mayor“ erreichen. Entities mit den entsprechenden Skriptnamen müssen auf der Karte existieren.
function CreateQuestReachMayor() local QuestDescription = { EntityName = "Hannes", Heroes = true, TargetName = "Mayor", Distance = 1000, Callback = CallbackQuestReachMayor } SetupExpedition(QuestDescription) end function CallbackQuestReachMayor() -- sobald der Bürgermeister erreicht wurde, wird diese Funktion ausgeführt end
Gegner besiegen: SetupDestroy
In Siedler 5 gibt es zahlreiche denkbare Bedingungen dafür, wann ein Gegner als besiegt gelten kann. Die Funktion SetupDestroy(_QuestDescription)
deckt die meisten davon ab. _QuestDescription
ist ein Table mit den folgenden Parametern, die in „Gruppen“ zusammengefasst sind und jeweils für eine andere Questbedingung stehen (alle Parameter innerhalb einer Gruppe müssen zusammen verwendet werden).
Gruppe | Key | Value-Typ | Bedeutung |
---|---|---|---|
Gruppe 1: Alle Gebäude in einem Gebiet zerstören | AreaPlayerID | Player Id | Spieler-Id, dessen Gebäude im Zielgebiet zerstört werden sollen |
AreaPos | String oder Number | Skriptname oder Entity-Id der Entity, die im Mittelpunkt des Zielgebiets steht | |
AreaSize | Number | Radius, in dessen Umkreis um AreaPos herum alle Gebäude von Spieler AreaPlayerID zerstört werden sollen |
|
Gruppe 2: Eine bestimmte Entity zerstören | Target | String oder Number | Skriptname oder Entity-Id der Entity, die zerstört werden soll |
Gruppe 3: Mehrere bestimmte Entities zerstören | Targets | Table | Liste mit Skriptnamen oder Entity-Ids aller Entities, die zerstört werden sollen |
Targets | String | Präfix eines Skriptnamens für mehrere Entities, deren Namen auf der Karte durchnummeriert sind. „Serf“ stände beispielsweise für „Serf1“, „Serf2“, „Serf3“, usw. - abhängig davon, wie viele durchnummerierte Entities existieren | |
Gruppe 4: Eine Armee ( link) zerstören | Army | Table | Army-Table der zu besiegenden Armee |
ArmyPos | String oder Number | Skriptname oder Entity-Id der Entity, zu deren Position die Armee beim Questaufruf geht (optional) | |
ArmyRange | Number | Radius der Armee nach dem Questaufruf (nur wenn ArmyPos angegeben) |
|
Immer notwendig | Callback | Funktion | Funktion, die aufgerufen wird, sobald alle Ziele zerstört wurden |
Armee-Tables werden erst in Ebene 3 ( link) behandelt, diesen Use Case lassen wir für die folgenden Beispiele also außen vor.
Im einfachsten aller Beispiele soll nur ein einzelner Banditenturm zerstört werden, dem wir den Skriptnamen „RobberyTower“
im Editor gegeben haben. Folgendermaßen kann seine Zerstörung ermittelt werden:
function CreateQuestDestroyRobberyTower() QuestDestroyRobberyTower = { Target = "RobberyTower", Callback = CallbackQuestDestroyRobberyTower } SetupDestroy(QuestDestroyRobberyTower) end function CallbackQuestDestroyRobberyTower() -- diese Funktion wird aufgerufen, sobald der Banditenturm zerstört wurde end
Hinweis: Im obigen Beispiel definieren wir die _QuestDescription
als globales Table. Das ist nur notwendig, falls du die Quest später vorzeitig beenden willst.
Die einzelnen Gruppen können auch kombiniert werden. Die Questbedingung ist genau dann erfüllt, wenn jede Bedingung der Gruppen erfüllt ist. Beispielsweise wollen wir in folgendem Beispiel ausdrücken, dass der Spieler alle Gebäude von Spieler 3
in einem Umkreis von 3000 Siedler-cm um die Entity „Player3Position“
zerstören muss. Außerdem haben wir einige PB_Beautification09
auf der Karte verteilt, deren Skriptnamen wir mit „Flower1“
, „Flower2“
, usw. durchnummeriert haben und die ebenfalls für die Quest zerstört werden müssen.
function CreateQuestDestroyPlayer3() local QuestDescription = { AreaPlayerID = 3, AreaPos = "Player3Position", AreaSize = 3000, Targets = "Flower", Callback = CallbackQuestDestroyPlayer3 } SetupDestroy(QuestDescription) end function CallbackQuestDestroyPlayer3() -- diese Funktion wird aufgerufen, wenn die Questbedingung erfüllt ist end
Tipp: Du kannst deinen gewünschten Radius durch Platzieren eines XS_Ambient auf die Entity in AreaPos
ermitteln. Das 100-fache der angegebenen Größe der Ambient-Entity entspricht genau dem anzugebenden Radius in SetupDestroy
.
Beachte, dass in diesem Beispiel die Blumen nicht notwendigerweise Spieler 3 gehören müssen! Die Angabe von AreaPlayerID
bezieht sich nur auf die Gebiets-Bedingung.
Gebäude errichten: SetupEstablish
In vielen Karten wird vom Spieler gefordert, bestimmte Gebäude zu errichten, meistens an einer vorgegebenen Position. SetupEstablish(_QuestDescription)
prüft, ob alle Gebäude nach Vorgabe errichtet wurden. _QuestDescription
ist ein Table mit den folgenden Parametern:
Key | Value-Typ | Bedeutung | Erforderlich? |
---|---|---|---|
Player | Player Id | Spieler-Id des Spielers, der die Gebäude errichten soll | Nein (wenn nicht angegeben, ist es der menschliche Spieler) |
AreaPos | String oder Number | Skriptname oder Entity-Id der Entity, die im Mittelpunkt des Zielgebiets steht | Nein (ohne Angabe ganze Karte) |
AreaSize | Number | Radius, in dessen Umkreis um AreaPos herum die Gebäude errichtet werden sollen | Nur, wenn AreaPos angegeben wurde |
EntityTypes | Table | Liste mit Entity-Typen der zu bauenden Gebäude und deren Anzahl | Ja |
Callback | Funktion | Funktion, die aufgerufen wird, sobald die Gebäude nach Vorgabe errichtet wurden | Ja |
Hinweis: Prinzipiell wurde im Code von SetupEstablish
auch der Parameter Any
implementiert, um nur eines der geforderten Gebäude für die Erfüllung der Quest notwendig zu machen. Diese Funktionalität ist allerdings an mehreren Stellen verbuggt und daher nicht zu gebrauchen.
In folgendem Beispiel soll Spieler 1 an der Position des Entities „CathedralTarget“
um Umkreis von 4000 Siedler-cm eine Kathedrale, ein großes Wohnhaus und einen Gutshof errichten:
function CreateQuestBuildCathedral() QuestBuildCathedral = { Player = 1, AreaPos = "CathedralTarget", AreaSize = 4000, EntityTypes = { {Entities.PB_Monastery3, 1}, -- Gebäudetyp und deren Anzahl {Entities.PB_Farm3, 1}, {Entities.PB_Residence3, 1} }, Callback = CallbackQuestBuildCathedral } SetupEstablish(QuestBuildCathedral) end function CallbackQuestBuildCathedral() -- diese Funktion wird automatisch nach Erfüllen der Quest aufgerufen end
Tipp: Du kannst deinen gewünschten Radius durch Platzieren eines XS_Ambient auf die Entity in AreaPos
ermitteln. Das 100-fache der angegebenen Größe der Ambient-Entity entspricht genau dem anzugebenden Radius in SetupEstablish
.
Im obigen Beispiel definieren wir die _QuestDescription
als globales Table. Das ist nur notwendig, falls du die Quest später vorzeitig beenden willst.
Wetter umstellen: SetupWeather
In der Kampagnenkarte „Norfolk“ des Hauptspiels erhält der Spieler die Aufgabe, den Winter zu beenden. Dieser Questtyp ist ebenfalls als Standardquest verfügbar und wird mit SetupWeather(_QuestDescription)
gestartet. _QuestDescription
ist ein Table mit den folgenden Parametern:
Key | Value-Typ | Bedeutung | Erforderlich? |
---|---|---|---|
WeatherStates | Table | Liste der gewünschten Weather states ( link), von denen einer eintreten muss, als Id | Ja |
Callback | Funktion | Funktion, die aufgerufen wird, sobald einer der WeatherStates eintritt | Ja |
Die erwarteten WeatherState-Ids sind 1
für Sommer, 2
für Regen und 3
für Winter. Um sich das besser lesbar zu machen, kann man sich auch ein globales Table definieren:
WeatherStates = { Summer = 1, Rain = 2, Winter = 3 }
Soll der Spieler beispielsweise wie in Norfolk den Winter beenden, könnte der SetupWeather
-Aufruf so aussehen:
function CreateQuestEndWinter() QuestEndWinter = { WeatherStates = { WeatherStates.Summer, WeatherStates.Rain }, -- Sowohl Sommer als auch Regen beenden den Winter Callback = CallbackQuestEndWinter } SetupWeather(QuestEndWinter) end function CallbackQuestEndWinter() -- diese Funktion wird automatisch aufgerufen, sobald der Winter zuende ist end
Im obigen Beispiel definieren wir die _QuestDescription
als globales Table. Das ist nur notwendig, falls du die Quest später vorzeitig beenden willst.
Damit die Quest funktioniert, ist es logischerweise wichtig, dass es zum Zeitpunkt des Aufrufs schneit. Falls der Winter nicht zu Beginn der Karte gestartet wird, sollte der Start der Quest auf den Wintereinbruch warten. Dazu kann ebenfalls SetupWeather
benutzt werden:
function CreateQuestWaitForWinter() local QuestDescription = { WeatherStates = { WeatherStates.Winter }, Callback = CallbackQuestWaitForWinter } SetupWeather(QuestDescription) end function CallbackQuestWaitForWinter() -- Beginne erst bei Wintereinbruch mit der "tatsächlichen" Spielerquest CreateQuestEndWinter() end