scripting:tutorials:level2:setup_quest
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
Nächste Überarbeitung | Vorherige Überarbeitung | ||
scripting:tutorials:level2:setup_quest [2023/10/26 13:42] – angelegt fritz_98 | scripting:tutorials:level2:setup_quest [2023/11/11 14:07] (aktuell) – fritz_98 | ||
---|---|---|---|
Zeile 40: | Zeile 40: | ||
</ | </ | ||
- | **Tipp**: Du kannst deine gewünschte Distanz durch [[ scripting: | + | **Tipp**: Du kannst deine gewünschte Distanz durch [[ scripting: |
- | Im obigen Beispiel definieren wir die '' | + | Im obigen Beispiel definieren wir die '' |
Man kann die Bedingungen für einzelne Entities und Entity-Kategorien auch kombinieren. Beispielsweise soll entweder ein Bote namens " | Man kann die Bedingungen für einzelne Entities und Entity-Kategorien auch kombinieren. Beispielsweise soll entweder ein Bote namens " | ||
Zeile 100: | Zeile 100: | ||
</ | </ | ||
- | **Hinweis**: | + | **Hinweis**: |
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, | 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, | ||
Zeile 123: | Zeile 123: | ||
</ | </ | ||
- | **Tipp**: Du kannst deinen gewünschten Radius durch [[ scripting: | + | **Tipp**: Du kannst deinen gewünschten Radius durch [[ scripting: |
Beachte, dass in diesem Beispiel die Blumen nicht notwendigerweise Spieler 3 gehören müssen! Die Angabe von '' | Beachte, dass in diesem Beispiel die Blumen nicht notwendigerweise Spieler 3 gehören müssen! Die Angabe von '' | ||
Zeile 129: | Zeile 129: | ||
---- | ---- | ||
+ | ====Gebäude errichten: SetupEstablish==== | ||
+ | In vielen Karten wird vom Spieler gefordert, bestimmte Gebäude zu errichten, meistens an einer vorgegebenen Position. '' | ||
+ | |||
+ | ^ 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 '' | ||
+ | | **EntityTypes** | Table | [[scripting: | ||
+ | | **Callback** | Funktion | Funktion, die aufgerufen wird, sobald die Gebäude nach Vorgabe errichtet wurden | Ja | | ||
+ | |||
+ | **Hinweis**: | ||
+ | |||
+ | In folgendem Beispiel soll Spieler 1 an der Position des Entities ''" | ||
+ | <code lua> | ||
+ | function CreateQuestBuildCathedral() | ||
+ | QuestBuildCathedral = { | ||
+ | Player = 1, | ||
+ | AreaPos = " | ||
+ | AreaSize = 4000, | ||
+ | EntityTypes = { | ||
+ | {Entities.PB_Monastery3, | ||
+ | {Entities.PB_Farm3, | ||
+ | {Entities.PB_Residence3, | ||
+ | }, | ||
+ | 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 [[ scripting: | ||
+ | |||
+ | Im obigen Beispiel definieren wir die '' | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ====Wetter umstellen: SetupWeather==== | ||
+ | |||
+ | In der Kampagnenkarte " | ||
+ | |||
+ | ^ Key ^ Value-Typ ^ Bedeutung ^ Erforderlich? | ||
+ | | **WeatherStates** | Table | [[scripting: | ||
+ | | **Callback** | Funktion | Funktion, die aufgerufen wird, sobald einer der '' | ||
+ | |||
+ | Die erwarteten WeatherState-Ids sind '' | ||
+ | <code lua> | ||
+ | WeatherStates = { | ||
+ | Summer = 1, | ||
+ | Rain = 2, | ||
+ | Winter = 3 | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Soll der Spieler beispielsweise wie in Norfolk den Winter beenden, könnte der '' | ||
+ | <code lua> | ||
+ | function CreateQuestEndWinter() | ||
+ | QuestEndWinter = { | ||
+ | WeatherStates = { WeatherStates.Summer, | ||
+ | Callback = CallbackQuestEndWinter | ||
+ | } | ||
+ | | ||
+ | SetupWeather(QuestEndWinter) | ||
+ | end | ||
+ | |||
+ | function CallbackQuestEndWinter() | ||
+ | -- diese Funktion wird automatisch aufgerufen, sobald der Winter zuende ist | ||
+ | end | ||
+ | </ | ||
+ | |||
+ | Im obigen Beispiel definieren wir die '' | ||
+ | |||
+ | Damit die Quest funktioniert, | ||
+ | |||
+ | <code lua> | ||
+ | function CreateQuestWaitForWinter() | ||
+ | local QuestDescription = { | ||
+ | WeatherStates = { WeatherStates.Winter }, | ||
+ | Callback = CallbackQuestWaitForWinter | ||
+ | } | ||
+ | | ||
+ | SetupWeather(QuestDescription) | ||
+ | end | ||
+ | |||
+ | function CallbackQuestWaitForWinter() | ||
+ | -- Beginne erst bei Wintereinbruch mit der " | ||
+ | CreateQuestEndWinter() | ||
+ | end | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ====Quests abbrechen==== | ||
+ | |||
+ | Mit '' | ||
+ | |||
+ | Damit das funktioniert, | ||
+ | |||
+ | Wir nehmen das Beispiel zum Auffinden von Helias [[scripting: | ||
+ | |||
+ | <code lua> | ||
+ | function FirstMapAction() | ||
+ | -- Wir erstellen gleichzeitig die Quest, Helias zu finden und den Job, | ||
+ | -- der Helias Tod prüfen soll | ||
+ | CreateQuestFindHelias() | ||
+ | StartSimpleJob(" | ||
+ | end | ||
+ | |||
+ | function CheckHeliasDeath() | ||
+ | -- wenn Helias tot ist... | ||
+ | if IsDead(" | ||
+ | -- ...beende die Quest | ||
+ | DestroyQuest(QuestFindHelias) | ||
+ | -- Und beende die Quest nur 1 mal! Der Job wird nach Beenden der Quest ebenfalls | ||
+ | -- durch return true beendet | ||
+ | return true | ||
+ | end | ||
+ | end | ||
+ | |||
+ | -- Hierunter kommt der Beispielcode von oben. Wichtig ist, dass QuestFindHelias global definiert wird | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ====Zusätzliche Parameter==== | ||
+ | |||
+ | [[ scripting: | ||
+ | |||
+ | Eine Konsequenz daraus ist, dass im Quest-Table zusätzliche, | ||
+ | |||
+ | Folgende Quest soll umgesetzt werden: Der Spieler hat die Wahl, ob er für den Auftraggeber eine Garnision oder eine Schießanlage errichten möchte. Je nach gewähltem Gebäude soll er einen Trupp Langschwertkämpfer oder Armbrustschützen erhalten. Wenn er sich für eines der Gebäude entschieden und die zugehörige Belohnung erhalten hat, soll die jeweils andere Quest automatisch [[ scripting: | ||
+ | |||
+ | Für dieses Setup existiert eine '' | ||
+ | |||
+ | <code lua> | ||
+ | function FirstMapAction() | ||
+ | -- Beide Quests werden mit der gleichen Funktion, aber unterschiedlichen Parametern gestartet | ||
+ | -- Die Funktionen geben das Quest-Table zurück, damit sie in eine globale Variable gegeben werden können | ||
+ | -- Das ist notwendig, weil die jeweils nicht erfüllte Quests automatisch beendet werden soll | ||
+ | QuestBuildBarracks = CreateQuestBuildMilitaryBuilding(Entities.PB_Barracks2, | ||
+ | QuestBuildArchery = CreateQuestBuildMilitaryBuilding(Entities.PB_Archery2, | ||
+ | | ||
+ | -- Um anzugeben, welche Quest beendet werden soll, geben wir diese Information ebenfalls noch in die | ||
+ | -- Tables: | ||
+ | QuestBuildBarracks.RemoveQuest = QuestBuildArchery | ||
+ | QuestBuildArchery.RemoveQuest = QuestBuildBarracks | ||
+ | -- Im Callback brauchen wir also nur auf den Eintrag RemoveQuest zuzugriefen, | ||
+ | -- Quest beendet werden muss | ||
+ | end | ||
+ | |||
+ | function CreateQuestBuildMilitaryBuilding(_BuildingType, | ||
+ | -- Da die Funktion 2 mal aufgerufen wird, muss die Questbeschreibung innerhalb der | ||
+ | -- Funktion lokal sein. Sie wird mit return zurückgegeben und beim Aufruf in einer | ||
+ | -- globale Variable gespeichert | ||
+ | local QuestDescription = { | ||
+ | Player = 1, | ||
+ | AreaPos = " | ||
+ | AreaSize = 2000, | ||
+ | EntityTypes = { | ||
+ | -- Der Gebäudetyp wird aus dem Parameter geholt | ||
+ | {_BuildingType, | ||
+ | }, | ||
+ | -- Hier geben wir den Truppentyp der Belohnung für den Bau des Gebäudes an | ||
+ | -- Er wird vom Quest-Handling ignoriert, kann aber im Callback verwendet werden, | ||
+ | -- um die korrekte Belohnung zu spawnen | ||
+ | RewardType = _RewardType, | ||
+ | Callback = CallbackQuestBuildMilitaryBuilding | ||
+ | } | ||
+ | |||
+ | SetupEstablish(QuestDescription) | ||
+ | | ||
+ | -- Rückgabe der QuestDescription, | ||
+ | return QuestDescription | ||
+ | end | ||
+ | |||
+ | function CallbackQuestBuildMilitaryBuilding(_QuestDescription) | ||
+ | -- In dieser Funktion steht das Table _QuestDescription zur Verfügung, das genau dem Quest-Table | ||
+ | -- mitsamt unserer zusätzlichen Einträge entspricht | ||
+ | |||
+ | -- Die Funktion CreateMilitaryGroup erstellt einen kompletten Trupp Soldaten vom angegebenen Typ | ||
+ | -- Siehe die Comfort-Referenz oder den Artikel zu " | ||
+ | -- Für den Typ des Hauptmanns wählen wir den RewardType, der beim erstellen der Quest | ||
+ | -- abhängig von den Parametern festgelegt wurde | ||
+ | CreateMilitaryGroup(1, | ||
+ | -- Außerdem haben wir pro Quest angegeben, welche die jeweils andere Quest ist, die es nun zu | ||
+ | -- beenden gilt | ||
+ | DestroyQuest(_QuestDescription.RemoveQuest) | ||
+ | end | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ====Karawanen beschützen: | ||
+ | |||
+ | Diese Art der Quest kennst du vielleicht aus der Nebelreich-Kampagnenkarte " | ||
+ | |||
+ | Die Funktion '' | ||
+ | |||
+ | ^Key^Value-Typ^Bedeutung^ | ||
+ | | Unit | String | Präfix eines Skriptnamens für mehrere Entities, deren Namen auf der Karte durchnummeriert sind. „Trader“ stände beispielsweise für „Trader1“, | ||
+ | | Unit | Table (Liste) | Liste mit Skriptnamen oder Entity-Ids aller Entities, die der Karawane angehören sollen | | ||
+ | | Waypoint | Table (Liste) | Liste von Tables, die für jeden Wegpunkt den Namen einer Positions-Entity und die zugehörige Wartezeit angeben | | ||
+ | | Remove | nil | Wenn '' | ||
+ | | Callback | Funktion | Funktion, die aufgerufen wird, sobald alle Entities entweder am Zielort oder tot sind | | ||
+ | | ArrivedCallback | Funktion | Funktion, die jedes mal aufgerufen wird, sobald eine Entity am Zielort ankommt. Optionaler Parameter | | ||
+ | |||
+ | **Hinweis**: | ||
+ | |||
+ | Jedes mal, wenn ein Mitglied der Karawane den letzten Wegpunkt erreicht, wird außerdem eine Zählvariable im Quest-Table '' | ||
+ | |||
+ | Für folgendes Anwendungsbeispiel existieren auf der Karte einige '' | ||
+ | |||
+ | Außerdem werden wir uns die Möglichkeit [[ scripting: | ||
+ | |||
+ | <code lua> | ||
+ | function CreateQuestCaravan() | ||
+ | -- Die Händler existieren noch nicht, wir müssen sie also erst erstellen | ||
+ | for i = 1, 5 do | ||
+ | -- Skriptnamen werden beim Erstellen in der Schleife gleich durchnummeriert | ||
+ | CreateEntity(4, | ||
+ | end | ||
+ | | ||
+ | local QuestDescription = { | ||
+ | -- Alle 5 Händler sind gemeint - der gemeinsame Namenspräfix reicht | ||
+ | Unit = " | ||
+ | | ||
+ | -- Hier wird die Liste der Wegpunkte angegeben | ||
+ | -- Jeder Wegpunkt hat einen Namen (Skriptname der Entity, deren Position der Wegpunkt ist) | ||
+ | -- und eine Wartezeit | ||
+ | Waypoint = { | ||
+ | {Name = " | ||
+ | {Name = " | ||
+ | {Name = " | ||
+ | {Name = " | ||
+ | {Name = " | ||
+ | }, | ||
+ | | ||
+ | -- Jeder angekommene Händler soll direkt von der Map entfernt werden | ||
+ | Remove = true, | ||
+ | |||
+ | -- Dies ist ein eigener Parameter. Wir geben hier an, dass 3 der 5 Händler ankommen müssen | ||
+ | -- Diese Bedingung prüfen wir später im Callback | ||
+ | Necessary = 3, | ||
+ | | ||
+ | -- Zwei verschiedene Funktionen für zwei verschiedene Callbacks | ||
+ | -- Einmal die Funktion, die bei jedem angekommenen Händler ausgelöst wird | ||
+ | ArrivedCallback = CallbackArrivedQuestCaravan, | ||
+ | -- und die Funktion, die ausgelöst wird, sobald alle Händler angekommen oder tot sind | ||
+ | Callback = CallbackQuestCaravan, | ||
+ | } | ||
+ | | ||
+ | SetupCaravan(QuestDescription) | ||
+ | end | ||
+ | |||
+ | function CallbackArrivedQuestCaravan() | ||
+ | -- In diesem Callback lassen wir den Spieler lediglich wissen, dass einer der Händler angekommen ist | ||
+ | Message(" | ||
+ | end | ||
+ | |||
+ | function CallbackQuestCaravan(_QuestDescription) | ||
+ | -- Hier prüfen wir, ob genug Händler ihre Reise überlebt haben | ||
+ | -- Die Variable _QuestDescription.ArrivedCount wurde automatisch hochgezählt | ||
+ | if _QuestDescription.ArrivedCount >= _QuestDescription.Necessary then | ||
+ | Message(" | ||
+ | -- hier folgt alles Weitere nach dem erfolgreichen Erfüllen der Quest | ||
+ | else | ||
+ | Message(" | ||
+ | -- hier folgt alles nach dem Scheitern der Quest (z.B. neuer Versuch, etc) | ||
+ | end | ||
+ | end | ||
+ | </ | ||
+ | |||
+ | **Hinweis**: | ||
+ | |||
+ | ---- | ||
+ | |||
+ | NPCs geben Aufträge, deren Bedingungen nun geprüft werden können. Im nächsten Kapitel stellen wir einige Funktionen vor, mit denen der Spieler für seine Aktionen belohnt werden kann. | ||
+ | |||
+ | [[ scripting: | ||
+ | [[ scripting: | ||
+ | [[ scripting: |
scripting/tutorials/level2/setup_quest.1698327723.txt.gz · Zuletzt geändert: 2023/10/26 13:42 von fritz_98