https://wiki.wesnoth.org/api.php?action=feedcontributions&user=Pa%C5%ADlo&feedformat=atomThe Battle for Wesnoth Wiki - User contributions [en]2024-03-28T23:16:55ZUser contributionsMediaWiki 1.31.16https://wiki.wesnoth.org/index.php?title=GermanTranslationErrors&diff=59428GermanTranslationErrors2018-04-16T19:40:34Z<p>Paŭlo: Szenrioeinstellungen</p>
<hr />
<div>Hier bitte die in der Übersetzung gefundenen Fehler eintragen.<br />
<br />
== Generelles ==<br />
<br />
Hinweis v. Espreon: Die Fertigkeit "feeding" ist im Deutschen - sehr spezifisch - als "Kanibalismus" übersetzt. Dies sei aber vielleicht zu spezifisch, und "fressen" sei generischer<br />
IRC: "And since ability names can pretty much go anywhere thanks to UMC,they ought to have names that are generic as possible"<br />
<br />
<br />
-------------------------<br />
Wesnoth 1.10.0<br />
<br />
:Ist es so richtig, dass auf der Landkarte von Wesnoth (die im Hauptmenü) das eine Gebirge "Erzgebierge" heißt? Müsste es nicht "Erzgebirge" heißen? Gruß Michieru<br />
<br />
:[Anmerkung: die "Heart Mountain" wurden im Deutschen zum Erzgebirge, da "Herzgebirge" sich in der Ork-Kampagne irgendwie nicht richtig angefühlt hatte. Änderungen sind natürlich, nach IRC-Diskussion, wie immer, möglich. Crommy, 22.06.2014]<br />
<br />
: Übrigens liest sich "Schwarzwasser Hafen" ein bisschen merkwürdig. Das klingt IMO so, als hätte es mal einen König "Schwarzwas" gegeben, der dort einen Hafen errichtet hat. Die Betonung liegt bei dieser Schreibweise auf "Haf-".<br />
<br />
: Wenn man "Schwarzwasserhafen" ohne Leerzeichen schreiben würde, dann liegt die Betonung auf "Schwarz-". Dies ist sowohl einfacher zu lesen, als auch grammatikalisch korrekter.<br />
: --[[User:Spixi|Spixi]] 21:07, 30 March 2012 (UTC)<br />
<br />
==Einstellungen-Dialog==<br />
Wesnoth 1.10.0<br />
<br />
Allgemein -> "Planungsmodus bei Start aktivieren" [http://img1.bildupload.com/e70d2099c321144bc357ebc5c8c0728d.jpg]<br />
<br />
Gruß Michieru<br />
<br />
<br />
[21:32:00] <Rhonda> Ja, war was in den allgemeinen Einstellungen.<br />
[21:32:11] <Rhonda> Das bei ES/MS die Bindestriche fehlen.<br />
<br />
== Statistics-Dialog ==<br />
Wesnoth 1.13.* (eingebaut [https://github.com/wesnoth/wesnoth/commit/20f8a62e7474#diff-5ef26b1f57b323b073e799e8426c330dR3086 jan 2017]):<br />
<br />
Der Button für die Szenarioeinstellungen heißt fälschlicherweise "Szenrioeinstellungen".<br />
<br />
== Lade-Dialog ==<br />
Wesnoth 1.12 / 1.13<br />
"Der Spielstand stammt aus einer alten Version ..."<br />
<br />
Tatsächlich wird der Dialog auch angezeigt wenn der Spielstand aus einer neueren Version stammt.<br />
<br />
==Hilfe==<br />
<br />
bei Geländearten -> Burg <br />
<br />
Ist: Elbische Burg<br />
<br />
Soll: Elfische Burg<br />
<br />
==Einheitenbeschreibungen==<br />
Die Attacke '''entangle''' ist auf zwei verschiedene Arten übersetzt.<br />
Zum einen als '''Efeumantel''' wenn die Elfen sie benutzen.<br />
In der Kampagne Defladors Memorien ist sie als '''Verstrickung''' übersetzt, und kann von einem Waldschrat benutzt werden.<br />
<br />
In 1.13 ist es nicht mehr möglich diese Attacke unterschiedlich zu übersetzen, die Übersetzung der Elfenattacke wird zum Standard. Soll es '''Verstrickung''' anstatt '''Efeumantel''' heißen?<br />
<br />
==Mehrspieler==<br />
Wesnoth 1.10.0<br />
<br />
Kartenbeschreibungen<br />
<br />
"Isars Kreuz" [http://img1.bildupload.com/9461bf044c3bc44ccd468510e673efba.jpg]<br />
"Freies Land" [http://img1.bildupload.com/ac9ed4edaaa8457bf327f4d5e7dd1c93.jpg]<br />
Gruß Michieru<br />
<br />
<br />
<br />
Fraktionen<br />
<br />
"Knalgan Alliance"<br />
<br />
IST: Knalgan Allianz<br />
<br />
SOLL: Knalga Allianz ?<br />
<br />
==Einführung==<br />
<br />
== Kampagnen ==<br />
<br />
=== Das Zepter des Feuers ===<br />
<br />
=== Die dunklen Künste ===<br />
<br />
=== Die Geschichte zweier Brüder ===<br />
<br />
=== Die Südwacht ===<br />
<br />
Rache hin oder her. Führt uns in diese'''m''' Wald und wir werden gegen die Untoten kämpfen!<br />
<br />
diesem -> diesen<br />
<br />
<br />
<br />
Halt, Ithelden. Ich bin mit diesen Menschen gereist und sie sind nicht diejenigen, die Mebrin entführten. Sie sind Verbüntede'''n'''.<br />
<br />
Verbünteden -> Verbündete<br />
<br />
=== Der Thronerbe ===<br />
<br />
=== Der Aufstieg Wesnoths ===<br />
Wesnoth 1.12 / 1.13:<br />
Die Level 2 und 3 Version der Verbannten des Wesfolks heißen beide "Wesfolk Adlige".<br />
<br />
=== Die Legende von Wesmere ===<br />
<br />
Auch in 1.12/1.13 noch vorhanden (z.T. etwas umgeschrieben)<br />
<br />
Kapitel 4 Stunde der Glorie:<br />
Kalenz<br />
IST: Ich verstehe nur zu gut was das bedeutet, Geliebter, auch wenn ich es nicht glauben mag. ....<br />
SOLL:Ich verstehe nur zu gut was das bedeutet, Geliebte, auch wenn ich es nicht glauben mag. ....<br />
<br />
Kapitel 5 Bürgerkrieg:<br />
Kalenz<br />
IST: "Die weite grüne Welt muss wissen, dass die Schlacht im Wald zu Wesmere hat seinen Preis, einen hohen Preis."<br />
SOLL:"Die weite grüne Welt muss wissen, dass die Schlacht im Wald zu Wesmere ihren Preis hat, einen hohen Preis."<br />
<br />
Ka'lian-Map: IST: "Ford von Alyas" SOLL: "Furt von Alyas"<br />
<br />
=== Ein Einmarsch der Orks ===<br />
<br />
=== Freiheit ===<br />
1.12 Mission "Ringen um Recht": "Auch dies wird nicht ewig wären, doch zur Zeit scheuen"<br />
IST: wären SOLL: währen (im Sinne "Ehrlich währt am Längsten"). <br />
<br />
Gruß Crommy<br />
<br />
=== Invasion der Finsternis ===<br />
<br />
=== Schwarzauges Sohn ===<br />
<br />
=== Unter brennenden Sonnen ===<br />
Wesnoth 1.12 / 1.13:<br />
<br />
<br />
"First Afternoon"<br />
<br />
IST: Erster Abend<br />
<br />
SOLL: Erster Nachmittag<br />
<br />
<br />
"Second Afternoon"<br />
<br />
IST: Zweiter Abend<br />
<br />
SOLL: Zweiter Nachmittag<br />
<br />
<br />
"First Dusk"<br />
<br />
IST: Erste Abenddämmerung<br />
<br />
evtl.: Erster Abend ?<br />
<br />
<br />
"Second Dusk"<br />
<br />
IST: Zweite Abenddämmerung<br />
<br />
evtl. Zweiter Abend ?<br />
<br />
=== Wiedergeburt des Nordens ===<br />
<br />
=== Der Hammer von Thursagan ===<br />
<br />
=== Delfadors Memoiren ===<br />
<br />
=== Stille Wasser ===<br />
<br />
"He had a chest in his tent, too. It is filled with gold!"<br />
<br />
Ist: "Jauche und Levkojen! Diese Goldkiste war in ihrer Höhle!"<br />
<br />
Soll: Höhle -> Zelt<br />
<br />
=== Steigt hinab in die Dunkelheit ===<br />
<br />
== Manpages ==<br />
<br />
-T number, --max-threads number<br />
<br />
sets the maximum number of worker threads that will be created. If set to 0 there will be no limit (default: 0).<br />
<br />
Dieser Option ist in der deutschen Übersetzung mit einem kleinen t gelistet. -t hat aber eine andere Funktion als -T.<br />
<br />
<br />
-l, --load Datei<br />
Lädt den Spielstand Datei aus dem Standard-Spielstand-Verzeichnis. Falls auch die -e oder --editor Option verwendet wurde, wird der Editor mit der Karte aus '''file''' geöffnet.<br />
Falls ein Verzeichnis angegeben wurde, wird der Editor mit einem Dialog zum Laden einer Karte aus eben diesem Verzeichnis gestartet.<br />
<br />
<br />
'''file''' -> aus der Datei<br />
<br />
== Siehe auch ==<br />
<br />
* [[GermanTranslation|Hauptseite für deutsche Übersetzung]]<br />
<br />
[[Category:Translations]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=History&diff=43064History2011-06-22T22:02:37Z<p>Paŭlo: fix double redirect</p>
<hr />
<div>#REDIRECT [[Timeline of Wesnoth]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=WSNPP&diff=40808WSNPP2011-03-14T16:24:01Z<p>Paŭlo: formatting more wiki-like.</p>
<hr />
<div>== Wesnoth Strategy for New or Professional Players ==<br />
<br />
Hello all and welcome to '''Wesnoth Strategy for New or Professional Players'''. We are the WSNPP and our aim is to provide Wesnoth players both new and old with guides to improve their gameplay to become one of the top players in Wesnoth.<br />
<br />
Also feel free to check out our Blog: "http://wsnpp.blogspot.com/"<br />
<br />
Moving along, we plan on sharing my ideas, thoughts, theories, etc through weekly guides for everyone. There will be at least 1 guide for PWP and NWP per week<br />
<br />
There will be two types of guides that we will be making:<br />
<br />
* NWP - New Wesnoth Player guides<br />
* PWP - Professional/Intermediate Wesnoth Player guides<br />
<br />
NOTE: With PWP guides we will assume you know most of the Wesnoth game mechanics.<br />
<br />
This will occur weekly and it will either be a NWP or PWP guide or both (depending on the time we have). Each guide will tackle different tactics, situations and the what to do and what not's and more. we will try to use diagrams or images to help you understand the explanation more and in some cases we might do videos in the future (This is still being discuessed).<br />
<br />
At any time feel free to add comment on my guides or add ideas and theories of your own. That said, we hope you all find our guides useful.<br />
<br />
Follow our blog for weekly updates.<br />
<br />
=== NWP Guides ===<br />
<br />
* '''Edition #1:''' [[Terrain you Pain]]<br />
* '''Edition #2:''' [[ZOC]]<br />
* '''Edition #3:''' [[Going Backwards]]<br />
* '''Edition #4:''' [[Basic Build Orders]]<br />
* '''Edition #5:''' [[Our love for villages]]<br />
<br />
=== PWP Guides ===<br />
<br />
* '''Edition #1:''' [[The Do's and Dont's of 2v2 Battles]]<br />
* '''Edition #2:''' [[Auxiliary Build Orders]]<br />
* '''Edition #3:''' [[Dynamic strategies; 1 plan failed, 100 more to go]]<br />
<br />
<br />
=== The Team ===<br />
<br />
* '''WSNPP Director: - Sarom'''<br />
* '''Guide Author: - Sarom'''<br />
* '''Art Director: - Zaine'''<br />
* '''FunChillWesnoth Podcasts - (yet to decide if we should do this)'''</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=Talk:WSNPP&diff=40807Talk:WSNPP2011-03-14T16:18:15Z<p>Paŭlo: use a prefix for page name?</p>
<hr />
<div>== Use a prefix for page-names ==<br />
<br />
I would propose to either use a prefix (like <code>WSNPP:</code>) for all the individual pages or even let all the pages be subpages of this page. This makes it clear from the page name that they are part of a series, and not some independent page (which would need more context to be useful by itself).<br />
<br />
Possible Variants:<br />
<br />
* [[WSNPP:Terrain you Pain]]<br />
* [[NWP:Terrain you Pain]] (and [[PWP:Auxiliary Build Orders]])<br />
* [[WSNPP/Terrain you Pain]] (but I'm not sure subpages are actually enabled in the main namespace)<br />
<br />
I would have done this myself, but it seems I don't have the right to move pages. If noone protests, I'll try to get a wiki admin to either do this or get me the rights. -- [[User:Paŭlo|Paŭlo]] 16:18, 14 March 2011 (UTC)</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=Fosdem2011&diff=40292Fosdem20112011-02-06T19:42:11Z<p>Paŭlo: /* Group Picture */ added small version of image inline</p>
<hr />
<div>== General information ==<br />
This page is meant to somehow coordinate the small Wesconf taking place at FOSDEM 2011. That is everyone attending should please list him/herself in the list of arrivals and stuff like this. FOSDEM 2011 will take place at the first weekend in Febuary 2011, on Saturday 5th and Sunday 6th.<br />
<br />
* Fosdem - http://fosdem.org/2011/<br />
<br />
== Schedule/Plans ==<br />
{| border="1" width="100%"<br />
|-<br />
! (nick)name(s)<br />
! Arrival<br />
! Departure<br />
! Accomodation<br />
|-<br />
| AI, mordante<br />
| Fri, 4th (at ULB ~15:00)<br />
| Sun, 6th<br />
| 2go4, booked by Ivanovic, 4-bed room<br />
|-<br />
| Boucman<br />
| Fri, 4th (midi station 17:33)<br />
| Sun, 6th<br />
| 2go4, booked<br />
|-<br />
| Crab_<br />
| Fri, 4th (airport arrival 18:45) <br />
| Tue, 8th<br />
| 2go4, booked<br />
|-<br />
| elias<br />
| Fri, 4th (airport arrival 12:15)<br />
| Sun, 6th<br />
| BestWestern, booked<br />
|-<br />
| fendrin<br />
| Fri, 4th (central station 14:30)<br />
| Sun, 6th<br />
| 2go4, booked by Ivanovic, 4-bed room<br />
|-<br />
| grzywacz<br />
| Fri, 4th (airport charleroi ETA 20:35)<br />
| Sun, 6th<br />
| 2go4, booked<br />
|-<br />
| Ivanovic & chrber<br />
| Fri, 4th, "afternoon" (~15:00 at "chokopolis")<br />
| Sun, 6th, leaving right from ULB campus<br />
| 2go4, booked by Ivanovic, 4-bed room<br />
|-<br />
| Sirp & Dragonking<br />
| Fri, 4th, (airport arrival 17:00)<br />
| Mo, 7th<br />
| Novotel Grand Palace<br />
|-<br />
| thespaceinvader<br />
| Fri, 4th, 1733 Bruxelles Midi<br />
| Sun, 6th, 1649 Bruxelles Midi<br />
| 2go4, booked<br />
|-<br />
| YogiHH<br />
| Fri, 4th, (~18:00 in town center)<br />
| Sun, 6th (?)<br />
| some hotel...<br />
|-<br />
|}<br />
<br />
For accomodations please keep in mind that parking in the center of Brussels is really problematic. It might make sense to drive to the University where FOSDEM takes place, park there and take the bus into the town center (where some of the hotels/hostels are).<br />
<br />
Possible hostels that we at least contacted over the last years (some of them might already be booked out by now!):<br />
* [http://www.chab.be/ CHAB]<br />
* [http://www.2go4.be/ 2go4] Note: groups bigger 6 are not allowed, so we can (officially) not form a complete Wesnoth group at this hostel, got to meet somewhere in town/at the university...<br />
* [http://www.jeugdherbergen.be/brusselE.htm Bruegel YH]<br />
<br />
On the official FOSDEM page [http://www.fosdem.org/2011/practical/accommodation some more possible hotels/hostels] are listed.<br />
<br />
== Maps ==<br />
* [http://tinyurl.com/3a65gr Bruegel YH]<br />
* [http://tinyurl.com/35br9c Brussels Central (Train Station) → Bruegel YH]<br />
* [http://tinyurl.com/37d9v4 Bruegel YH → Brussels Central (Train Station) → Novotel Grand Place]<br />
* [http://tinyurl.com/2mzns6 Novotel Grand Place]<br />
* [http://tinyurl.com/3dggg3 CrownePlaza (Europa)]<br />
* [http://tinyurl.com/36epxj FOSDEM]<br />
* [http://tinyurl.com/2w4bms Novotel Grand Place -> FOSDEM]<br />
<br />
== Transportation ==<br />
Information about how to reach the FOSDEM is listed at the [http://www.fosdem.org/2011/transportation official transportation subpage].<br />
<br />
Short version of how to get there for those that reside in Bruegel YH and Novotel Grand Place (basically town center):<br />
<br />
* Enter Bus 71 (Debrouckere - Central Station ("Gare Centrale") - Delta) somewhere at 'Central Station'<br />
* Leave the bus at "ULB" (crossroads Ave. Adolphe Buyl - Sq. Deveze)<br />
* Walk down Ave. Paul Heger on your right hand.<br />
<br />
== Wesnoth Hacking Room ==<br />
<br />
Wesnoth will not have a room of its own. Instead we will use one of the "general hacking rooms". So far it is not sure which room it will be, if we do it like the last three years, it will be room number 115 in the building AW1. Last year this was the smaller of the two hacking rooms and we had no real problem with conquering (and holding) the first row in this room. There were not too many power outlets, so this year at least Ivanovic will bring one multi-outlet power strip plus some extension cable (5m or something like this). Mordante will also bring a multi-outlet power strip and a 20m extension cable. There is no wired network, everything wireless (and sometimes rather/very unstable!). Beside this you should bring laptops since there are no computers available for hacking.<br />
<br />
Short version:<br />
AW1 - Room 115<br />
<br />
== Discussions and Results ==<br />
We usually discuss all sorts of things at FOSDEM, this section is basically a (really short) summary of things that were discussed including their results.<br />
<br />
===FOSDEM 2012===<br />
Basic question was if developers are interested in going to the next FOSDEM (the answer was a clear '''yes'''). Another question was if we should try to go for a complete dev room. The benefit of having a dev room would be that we had it just for us (plus people who are interested in listening to our stuff. In the room we should be holding talks (eg about stuff like "how to create artwork for an open game" (possibly including a live example about how it can be done) or "how to successfully start an open source game") but could also have discussions as well as hacking sessions. General agreement was that this step would make sense and that we might also consider talking to other orgs (gaming related ones!) if they are interested in this and want to join us to make it an "Open Source Gaming Dev" room with all the thing required for open games (since it is '''not''' about only having coders but also graphics, music/sounds, campaigns and story as well as translations.<br />
<br />
===GCI 2010/1011===<br />
We talked if we thought that GCI was a success for us and if we should consider trying to repeat it (if possible. In general the conclusion was that we were positively surprised by the contest. Both the quality of the work submitted as well as the tasks completed were really surprisingly good. We think that we should go for another round in case we do meet the requirements (this year it was required to participate in GSOC and it is not sure yet if we will be accepted there again). The general thing that we should change is that we should provide more coding and artwork related tasks. This is not of immediate concern since the next GCI won't start before GSOC is over, more likely it will start close to Christmas.<br />
<br />
===GSOC 2011===<br />
One question asked was if we wanted to participate in the new GSOC. The basic decision was that it would make sense to do so as long as we got projects as well as willing mentors. Some people already volunteered to consider being mentors and we still have some reasonable project ideas left from last year. One general comment was that we should make the projects a little smaller than they were so far. Besides we should shift our requirements to include more documentation, meaning that the ratio between code produced and documentation created shifts more to documentation.<br />
<br />
===Khalifate / New faction for mainline===<br />
We agreed that we do want to add the Khalifate to trunk as soon as possible. TSI reported that all the base frames should be basically done and we are just waiting for noy with the unit stats at the moment. Once we got those, the new faction "Khalifate" can be added to trunk. The current plan is to create a new era with the current setup named eg ''classic''. This would basically be the factions with the balancing used in default up to 1.9.4. The default era (still named ''default'') would have the Khalifate included. We do know that this will extremely unbalance the default era, but this way we make sure that the Khalifate will get testing from our users. Then we got about 9 month to find a usable balance till we start a new stable series.<br />
<br />
Users in IRC raised concerns regarding the balancing (mentioned above already, it won't be perfect at the start and has to improve over time, but requires lots of playtesting to do so), creation of the unit cfgs (should be done in about an hour, once we got the actual values!) as well as the Khalifate being too "real world" (are they really some "real world stuff"? Personally some Arabic/Mongolian themed stuff does fit nicely into a game like Wesnoth, too.<br />
<br />
Basic result of the discussion with the devs that were around at FOSEM was that it should be in trunk as soon as possible, so that it might be already available in the next dev release 1.9.5.<br />
<br />
===Licensing problems===<br />
On the mailing list the problem of Wesnoth licensing and possible incompatibility with web stores like eg the appstore from Apple for the iOS stuff (iphone, ipod touch and ipad) was brought up. The discussions on the mailing list were rather heated so it of course was a topic that we had to talk about during FOSDEM. The developers present felt that their prime concern is that the code is available freely, that it can be redistributed and recompiled. Generally we do think that the appstores that allow this are most likely compatible with the philosophy we have for Wesnoth. <br />
<br />
We also decided that the Wesnoth developers may officially endorse a port if we feel that it is basically done in a way that it is beneficial to the Wesnoth community. These are basically the important points:<br />
* They have to link back to wesnoth.org.<br />
* Their code has to be in a public repository.<br />
* If the port is redistributed for a fee, then a portion of the revenue has to be shared with the project.<br />
<br />
===Lord of Music===<br />
Lately we had the problem that we lost our Lord of Music ''West''. We still have another Lord of Music in the team who is still active in the forums: ''Tyler Johnson''. We plan to encourage him to take a more active role and communicate with us once something is ready for commit.<br />
<br />
===Multiplayer (campaign) UI===<br />
Fendrin brought up that the current GUI does suck for creating multiplayer campaign games. Several changes are required to make it work nicely. Fendrin and YogiHH worked on creating a proposal how stuff *could* be done. Here is a short list of problems and possible solutions:<br />
====Display of campaigns in scenario selection====<br />
Currently the interface does display the multiplayer campaign "Legend of Wesmere" at the very bottom of the list, even after some additional stuff like the test/benchmark scenarios. It would make sense to redesign the system to eg show tabs that allows differing between "simple scenarios" and "story based cooperative gameplay". The basic difference between those two is also that the information shown has to differ. For scenario you have tunable setting (village gold, starting gold, experience modifier, ...) while for a campaign you should rely on the author regarding the balancing.<br />
====Difficulty levels for MP campaigns====<br />
Currently all MP content has to be parsed before joining the server. This means all difficulty levels of a campaign would have to be parsed before you can even see it in the list. This somehow sucks. Sadly just loading (aka reparsing) the config after selecting it in the menu is currently not possible because you will end with a ping timeout.<br />
* Testing with a 300 second sleep didn't result in a timeout, so this may not be a big issue.<br />
<br />
====Split config cache for MP data====<br />
Currently all MP content has to be completely parsed before being able to join the MP server. This leads to several problems:<br />
* Once you download a new addon the *complete* cache has to be reparsed and redone. This leads to a huge (useless!) overhead.<br />
* It is not possible to do lazy loading.<br />
* Some addons do conflict. If they are all in one Cache, they simply create ugly problems.<br />
A possible fix for the problem would be splitting the cache into domains like it is done for singleplayer campaigns. This would eg lead to a new config file for a new faction, but the old config files would not change. With this approach we would have to probably create all config files before joining the server, too, but we would not just create one file but several. Then refreshing the cache would mean that only a fraction of the whole stuff is recreated. Which should speed stuff up when joining the mp server after getting new content.<br />
<br />
===Spritesheets===<br />
TSI brought up the matter of sprite sheets. We talked about how spritesheets are done in frogatto and that it might make sense to implement them in Wesnoth, too, but we first need someone to do it and it has to be done in concert with the artists to find the most usable way for them.<br />
<br />
===Wesnoth 1.10===<br />
So far there was no decision when to release the next stable release. Since we want to participate in GSOC and students are meant to directly commit their work to trunk and it has to be open for "new stuff". After GSOC we also need some time to fix bugs and polish new things, so the current idea is the next stable should be created around Christmas. In general we can not release 1.10 anytime close since it is not as stable as we would require it (just have a look at the amounts of bugs currently reported in the tracker!). So the next month should also be used for polishing as well as adding new stuff.<br />
<br />
== Group Picture ==<br />
<br />
http://forums.wesnoth.org/download/file.php?id=48633&t=1&t=1.jpg<br />
<br />
([http://forums.wesnoth.org/download/file.php?id=48633&mode=view Big version])<br />
Annotated for your convenience! - tsi<br />
<br />
== FOSDEM 2010 ==<br />
We were already at FOSDEM 2010, here something as reference:<br />
<br />
* [http://www.wesnoth.org/wiki/Fosdem2010 FOSDEM 2010 wiki page]<br />
<br />
<br />
<br />
== FOSDEM 2009 ==<br />
We were already at FOSDEM 2009, here something as reference:<br />
<br />
* [http://www.wesnoth.org/wiki/Fosdem2009 FOSDEM 2009 wiki page]<br />
<br />
== FOSDEM 2008 ==<br />
We were already at FOSDEM 2008, here something as reference:<br />
<br />
* [http://www.wesnoth.org/forum/viewtopic.php?p=283649#p283649 Forum topic (with group photo)]<br />
* [http://www.wesnoth.org/wiki/Fosdem2008 2008 wiki page]<br />
* [https://mail.gna.org/public/wesnoth-dev/2008-02/msg00078.html Summary of FOSDEM 2008 results]<br />
<br />
<br />
[[Category:Development]]<br />
[[Category:Wesconf]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=Template:WML_Tags&diff=40253Template:WML Tags2011-01-29T21:55:49Z<p>Paŭlo: if/else: links also to AnimationWML.</p>
<hr />
<div>{| class="gallery" style="width:225px;float: right;border: 1px solid #B48648; color:#B48648; font-size: 7pt;margin-left;10px;"<br />
|-<br />
|<br />
<span style="float: right;"><small class="editlink noprint plainlinksneverexpand">[{{SERVER}}{{localurl:Template:WML Tags|action=edit}} edit ]</small></span><br />
'''WML Tags'''<br />
<br />
|-<br />
|''A:'' <br />
[[AbilitiesWML|abilities]],<br />
[[CampaignWML|about]],<br />
[[AdvancedPreferenceWML|advanced_preference]],<br />
[[UnitTypeWML|advancefrom]],<br />
[[UnitTypeWML|advancement]],<br />
[[StatisticalScenarioWML|advances]],<br />
[[AiWML|ai]],<br />
[[DirectActionsWML#.5Ballow_recruit.5D|allow_recruit]],<br />
[[DirectActionsWML#.5Ballow_undo.5D|allow_undo]],<br />
[[ConditionalActionsWML#Meta_Condition_Tags|and]],<br />
[[InterfaceActionsWML|animate_unit]],<br />
[[AnimationWML|animation]],<br />
[[VariablesWML|array]],<br />
[[UnitTypeWML|attack]],<br />
[[AnimationWML|attack_filter]], <br />
[[StatisticalScenarioWML|attacks]],<br />
[[AiWML|avoid]];<br />
|-<br />
|''B:'' <br />
[[UnitTypeWML|base_unit]], [[BinaryPathWML|binary_path]], [[HelpWML|bold]], [[EditorWML|brush]];<br />
|-<br />
|''C:'' <br />
[[CampaignWML#The_.5Bcampaign.5D_tag|campaign]],<br />
[[DirectActionsWML#.5Bcapture_village.5D|capture_village]],<br />
[[ConditionalActionsWML#.5Bswitch.5D|case]],<br />
[[InterfaceActionsWML|chat]],<br />
[[ReplayWML|choose]],<br />
[[PersistenceWML|clear_global_variable]],<br />
[[InternalActionsWML|clear_variable]],<br />
[[InterfaceActionsWML|colour_adjust]],<br />
command([[InterfaceActionsWML|action]], [[ReplayWML|replay]]);<br />
|-<br />
|''D:'' <br />
[[AbilitiesWML|damage]],<br />
[[StatisticalScenarioWML|deaths]],<br />
[[AnimationWML|defend]],<br />
[[StatisticalScenarioWML|defends]],<br />
[[UnitTypeWML|defense]],<br />
[[InterfaceActionsWML|delay]],<br />
[[ReplayWML|destination]],<br />
[[DirectActionsWML#.5Bdisallow_recruit.5D|disallow_recruit]],<br />
[[ConditionalActionsWML#.5Bwhile.5D|do]];<br />
|-<br />
|''E:'' <br />
[[EditorWML|editor_group]],<br />
[[EditorWML|editor_music]], <br />
[[EditorWML|editor_times]],<br />
[[EditorWML|editor_tool_hint]],<br />
[[EffectWML|effect]],<br />
else ([[ConditionalActionsWML#.5Bif.5D|action]], [[AnimationWML#.5Bif.5D_and_.5Belse.5D|animation]]),<br />
[[DirectActionsWML#.5Bendlevel.5D|endlevel]],<br />
end_turn&nbsp;([[DirectActionsWML#.5Bend_turn.5D|action]], [[ReplayWML|replay]]),<br />
[[EraWML|era]],<br />
[[EventWML|event]],<br />
[[ThemeWML|expenses]];<br />
|-<br />
|''F:'' <br />
[[EventWML#.5Bfilter.5D|filter]],<br />
[[FilterWML|filter]],<br />
[[AnimationWML|filter_attack]],<br />
[[EventWML#.5Bfilter_attack.5D|filter_attack]],<br />
[[EventWML#.5Bfilter_condition.5D|filter_condition]],<br />
[[FilterWML|filter_location]],<br />
[[EventWML#.5Bfilter_second.5D|filter_second]],<br />
[[FilterWML|filter_second]],<br />
[[AnimationWML|filter_second_attack]],<br />
[[EventWML#.5Bfilter_second_attack.5D|filter_second_attack]],<br />
[[FilterWML#Filtering_Vision|filter_vision]],<br />
[[StandardUnitFilter|filter_wml]],<br />
[[InternalActionsWML|fire_event]],<br />
[[InterfaceActionsWML|floating_text]],<br />
[[HelpWML|format]],<br />
[[AnimationWML|frame]];<br />
|-<br />
|''G:'' <br />
[[GameConfigWML|game_config]],<br />
[[ScenarioWML|generator]],<br />
[[PersistenceWML|get_global_variable]],<br />
[[DirectActionsWML|gold]],<br />
[[ThemeWML|gold]];<br />
|-<br />
|''H:'' <br />
[[DirectActionsWML#.5Bharm_unit.5D|harm_unit]],<br />
[[ConditionalActionsWML#Condition_Tags|have_location]],<br />
[[ConditionalActionsWML#Condition_Tags|have_unit]],<br />
[[HelpWML|header]],<br />
[[DirectActionsWML#.5Bheal_unit.5D|heal_unit]],<br />
[[UnitsWML|hide_help]],<br />
[[InterfaceActionsWML|hide_unit]];<br />
|-<br />
|''I:'' <br />
if ([[ConditionalActionsWML#.5Bif.5D|action]], [[AnimationWML#.5Bif.5D_and_.5Belse.5D|animation]]),<br />
[[TimeWML|illuminated_time]],<br />
[[TerrainGraphicsWML|image]],<br />
[[HelpWML|img]],<br />
[[ThemeWML|income]],<br />
[[ReplayWML|init_side]],<br />
[[InternalActionsWML|insert_tag]],<br />
[[InterfaceActionsWML#.5Binspect.5D|inspect]],<br />
[[HelpWML|italic]],<br />
[[InterfaceActionsWML|item]];<br />
|-<br />
|''J:''<br />
[[HelpWML|jump]],<br />
[[InternalActionsWML|join]];<br />
|-<br />
|''K:'' <br />
[[DirectActionsWML#.5Bkill.5D|kill]],<br />
[[StatisticalScenarioWML|killed]];<br />
|-<br />
|''L:'' <br />
label&nbsp;([[InterfaceActionsWML|map]], [[ThemeWML|theme]]),<br />
[[LanguageWML|language]],<br />
[[AiWML|leader_goal]],<br />
[[LocaleWML|locale]],<br />
[[LuaWML|lua]];<br />
|-<br />
|''M:'' <br />
[[ThemeWML|main_map]],<br />
[[ThemeWML|menu]],<br />
[[InterfaceActionsWML|message]],<br />
[[ThemeWML|mini_map]],<br />
[[AnimationWML|missile_frame]],<br />
[[SingleUnitWML|modifications]],<br />
[[DirectActionsWML#.5Bmodify_side.5D|modify_side]],<br />
[[DirectActionsWML#.5Bmodify_turns.5D|modify_turns]],<br />
[[ReplayWML|move]],<br />
[[DirectActionsWML#.5Bmove_unit.5D|move_unit]],<br />
[[DirectActionsWML#.5Bmodify_ai.5D|modify_ai]],<br />
[[DirectActionsWML#.5Bmodify_unit.5D|modify_unit]],<br />
[[InterfaceActionsWML|move_unit_fake]],<br />
[[UnitTypeWML|movement costs]],<br />
[[UnitsWML|movetype]],<br />
[[ScenarioWML|multiplayer]],<br />
[[EraWML|multiplayer_side]],<br />
[[MusicListWML|music]];<br />
|-<br />
|''N:'' <br />
[[ConditionalActionsWML#Meta_Condition_Tags|not]],<br />
[[FilterWML|not]],<br />
[[ThemeWML|num_units]];<br />
|-<br />
|''O:'' <br />
[[DirectActionsWML#.5Bobject.5D|object]],<br />
[[InterfaceActionsWML|objectives]],<br />
[[InterfaceActionsWML|objective]],<br />
[[ThemeWML|observers]],<br />
[[InterfaceActionsWML|open_help]],<br />
[[InterfaceActionsWML|option]],<br />
[[ConditionalActionsWML#Meta_Condition_Tags|or]];<br />
|-<br />
|''P:'' <br />
[[ThemeWML|panel]], [[IntroWML|part]], [[DirectActionsWML#.5Bpetrify.5D|petrify]], [[DirectActionsWML#.5Bplace_shroud.5D|place_shroud]], [[ThemeWML|position]],<br />
[[InterfaceActionsWML|print]], [[AiWML|protect_location]], [[AiWML|protect_unit]];<br />
|-<br />
|''R:'' <br />
[[UnitsWML|race]], [[ReplayWML|random]], recall&nbsp;([[DirectActionsWML#.5Brecall.5D|action]], <br />
[[ReplayWML|replay]]), [[StatisticalScenarioWML|recalls]],<br />
[[ReplayWML|recruit]], [[StatisticalScenarioWML|recruits]], [[InterfaceActionsWML|redraw]],<br />
[[HelpWML|ref]], [[DirectActionsWML|remove_shroud]], [[InterfaceActionsWML|remove_unit_overlay]],<br />
[[InterfaceActionsWML|removeitem]], [[InterfaceActionsWML|remove_sound_source]], <br />
[[DirectActionsWML#.5Breplace_map.5D|replace_map]], [[DirectActionsWML#.5Breplace_schedule.5D|replace_schedule]], [[SavefileWML|replay]], [[SavefileWML|replay_start]],<br />
[[UnitTypeWML|resistance]], [[ThemeWML|resolution]], [[ReplayWML|results]], [[InternalActionsWML|role]];<br />
|-<br />
|''S:'' <br />
[[SavefileWML|save]], [[ScenarioWML|scenario]],<br />
[[InterfaceActionsWML|scroll]], [[InterfaceActionsWML|scroll_to]],<br />
[[InterfaceActionsWML|scroll_to_unit]], [[AnimationWML|secondary_attack_filter]], [[AnimationWML|secondary_unit_filter]], [[HelpWML|section]], [[InterfaceActionsWML|select_unit]], [[PersistenceWML|set_global_variable]],<br />
[[InterfaceActionsWML#.5Bset_menu_item.5D_.28SVN_trunk_only.29|set_menu_item]], [[DirectActionsWML#.5Bset_recruit.5D|set_recruit]],<br />
[[InternalActionsWML|set_variable]], [[InternalActionsWML|set_variables]], [[InterfaceActionsWML|show_objectives]],<br />
[[SideWML|side]], [[ThemeWML|side_playing]], [[SavefileWML|snapshot]],<br />
[[InterfaceActionsWML|sound]], [[InterfaceActionsWML|sound_source]], [[ReplayWML|source]], [[EventWML|special_filter]], [[EventWML|special_filter_second]],<br />
[[InternalActionsWML|split]],<br />
[[StatisticalScenarioWML#The_.5Bstatistics.5D_tag|statistics]],<br />
status([[SingleUnitWML|single unit]], [[ThemeWML|theme]]), [[InternalActionsWML#.5Bstore_gold.5D|store_gold]], [[InternalActionsWML#.5Bstore_locations.5D|store_locations]],<br />
[[InternalActionsWML#.5Bstore_map_dimensions.5D|store_map_dimensions]],<br />
[[InternalActionsWML#.5Bstore_side.5D|store_side]], [[InternalActionsWML#.5Bstore_starting_location.5D|store_starting_location]], [[InternalActionsWML#.5Bstore_time_of_day.5D|store_time_of_day]], [[InternalActionsWML#.5Bstore_unit.5D|store_unit]], [[InternalActionsWML#.5Bstore_villages.5D|store_villages]],[[IntroWML|story]],<br />
[[ConditionalActionsWML#.5Bswitch.5D|switch]];<br />
|-<br />
|''T:'' <br />
[[AiWML|target]],<br />
[[StatisticalScenarioWML#The_.5Bteam.5D_tag|team]],<br />
teleport ([[DirectActionsWML#.5Bteleport.5D|action]], [[AbilitiesWML|ability]]), [[AnimationWML|teleport_anim]],<br />
[[DirectActionsWML#.5Bterrain.5D|terrain]], [[TerrainGraphicsWML|terrain_graphics]], [[TerrainMaskWML|terrain_mask]], [[TerrainWML|terrain_type]], [[ScenarioWML#Test_scenario|test]],<br />
[[WesCamp|textdomain]], [[InterfaceActionsWML|text_input]], [[ThemeWML|theme]], [[ConditionalActionsWML#.5Bif.5D|then]],<br />
[[TerrainGraphicsWML|tile]], [[TimeWML|time]], time_area&nbsp;([[DirectActionsWML#.5Btime_area.5D|action]], [[ScenarioWML|scenario]]), <br />
[[ThemeWML|time_of_day]],<br />
[[HelpWML|topic]], [[HelpWML|toplevel]], [[SingleUnitWML|trait]], [[DirectActionsWML#.5Btunnel.5D|tunnel]] [[ThemeWML|turn]], [[ScenarioWML|tutorial]];<br />
|-<br />
|''U:'' <br />
[[InterfaceActionsWML|unhide_unit]], [[SingleUnitWML|unit]],<br />
[[ThemeWML|unit_abilities]], [[ThemeWML|unit_alignment]], [[ThemeWML|unit_description]], [[AnimationWML|unit_filter]], [[ThemeWML|unit_hp]], [[ThemeWML|unit_image]], [[ThemeWML|unit_level]], [[ThemeWML|unit_moves]],<br />
[[InterfaceActionsWML|unit_overlay]], [[ThemeWML|unit_profile]], [[ThemeWML|unit_status]],<br />
[[ThemeWML|unit_traits]], [[UnitTypeWML|unit_type]], [[ThemeWML|unit_weapons]], [[ThemeWML|unit_xp]],<br />
[[UnitsWML|units]], [[DirectActionsWML#.5Bunpetrify.5D|unpetrify]], [[DirectActionsWML#.5Bunstore_unit.5D|unstore_unit]], [[ThemeWML|upkeep]];<br />
|-<br />
| ''V:'' <br />
[[ConditionalActionsWML#Condition_Tags|variable]],<br />
[[VariablesWML|variables]],<br />
[[SideWML|village]],<br />
[[ThemeWML|villages]];<br />
|-<br />
| ''W:'' <br />
[[ConditionalActionsWML#.5Bwhile.5D|while]],<br />
[[InterfaceActionsWML|wml_message]];<br />
|}<br />
<br />
<noinclude>An box with all the WML tags, each linking to the page they are described in. This box should be included in each of the WML reference pages.</noinclude></div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ConditionalActionsWML&diff=40252ConditionalActionsWML2011-01-29T21:54:21Z<p>Paŭlo: /* [if] */ contrasting link to AnimationWML</p>
<hr />
<div>{{WML Tags}}<br />
<br />
Part of [[ActionWML]], Conditional Actions WML is used to describe container actions that create branching and flow control for WML. The [[#Conditional Actions|conditional actions]] act as gatekeepers, encapsulating other actions with [[#Condition Tags|conditions]] which must be met before an action can take place. These conditional actions also contain the actions which will take place if those conditions are met and, in some cases, what actions will take place if they are ''not'' met.<br />
<br />
== Conditional Actions ==<br />
<br />
These actions describe actions that should be executed only if certain conditions are met.<br />
<br />
=== [if] ===<br />
<br />
Executes actions only if the contained [[#Condition Tags|conditions]] are met.<br />
<br />
* [[#Condition Tags|Condition Tags]]: Conditions which must be met for the actions in the '''[then]''' tag to be executed.<br />
<br />
* '''[then]''': Contains [[ActionWML|actions]] which should be executed if all conditions evaluate as true ''or'' if any single '''[or]''' tag evaluates as true.<br />
<br />
* '''[else]''': Contains [[ActionWML|actions]] which should be executed if any condition evaluates as false ''and'' '''all''' of the '''[or]''' tags evaluate as false.<br />
<br />
<br />
'''Attention''': There are tags named [if] and [else] inside [animation] (see [[AnimationWML#.5Bif.5D_and_.5Belse.5D|AnimationWML]]), which have a different syntax.<br />
<br />
=== [switch] ===<br />
<br />
The '''[switch]''' tag is a special case because it does not use [[#Condition Tags|Condition Tags]] to control whether actions are performed. Instead, it executes different sets of actions based on the value of a variable.<br />
<br />
* '''variable''': The name of the variable to check.<br />
* '''[case]''': Case tag which forms a block containing:<br />
** '''value''': The value to test the variable's value against. <br />
This can be a comma separated list of values. {{DevFeature1.9}}<br />
** [[ActionWML|Action WML]]: Action WML to execute if the variable matches the value. (The rest of the '''[case]''' block after the '''value''' attribute.)<br />
* '''[else]''': Else tag which forms a block of [[ActionWML|Action WML]] to execute if no '''[case]''' block contains a '''value''' matching the value of the '''variable'''.<br />
<br />
Example usage:<br />
[switch]<br />
variable=foo<br />
[case]<br />
value="A"<br />
... WML if foo=A ...<br />
[/case]<br />
[case]<br />
value="B"<br />
... WML if foo=B ...<br />
[/case]<br />
[else]<br />
... WML if not foo=A nor foo=B ...<br />
[/else]<br />
[/switch]<br />
<br />
=== [while] ===<br />
<br />
Like the '''[if]''' tag, executes actions only if conditions described in the contained [[#Condition Tags|conditions]] are met. Additionally, the '''[while]''' tag ''continues'' to execute the actions until the contained [[#Condition Tags|conditions]] are no longer met. Executes a maximum of 1024 iterations per invocation.<br />
<br />
* [[#Condition Tags|Condition Tags]]: Conditions which must be met for the actions in the '''[do]''' tag to be executed.<br />
<br />
* '''[do]''': contains [[ActionWML|actions]] that should be executed repeatedly until some condition is false.<br />
<br />
The '''[while]''' tag is useful for iterating over an array.<br />
An array is a list of values.<br />
The ''number''th value in the array '''array''' is stored in the WML variable '''''array''[number]'''.<br />
Note that if '''number''' is the value of the variable '''variable''',<br />
the expression '''$''array''[$variable]''' will return the ''number''th value in ''array''.<br />
<br />
==== 'FOREACH' Macro ====<br />
This macro simplifies the use of a '''[while]''' tag to create a ''for-each'' iteration format. This is useful, for example, when you want to iterate over each row in a table. To use it, use the [http://www.wesnoth.org/macro-reference.xhtml#FOREACH FOREACH] and [http://www.wesnoth.org/macro-reference.xhtml#NEXT NEXT] macros.<br />
<br />
==== 'REPEAT' Macro ====<br />
This macro simplifies the use of a '''[while]''' tag to execute the same [[ActionWML|actions]] repeatedly for a specified number of times. To use it, use the [http://www.wesnoth.org/macro-reference.xhtml#REPEAT REPEAT] macro.<br />
<br />
=== [command] ===<br />
<br />
This tag is more of an Unconditional Action: when it is encountered, the [[ActionWML|actions]] in its content are simply executed once. In practice, this tag serves little purpose. However, it may be used to arrange actions together in logical groups, for example, with actions that are stored in an array and later inserted.<br />
(It is also used inside of [set_menu_item] and [option] of [[InterfaceActionWML]].)<br />
<br />
== Condition Tags ==<br />
<br />
===True Condition Tags===<br />
These tags describe conditions which must be met before an action can take place. Some or all of them are used in the various [[#Conditional Actions|Conditional Actions]].<br />
<br />
; [have_unit]<br />
: A unit with greater than zero hit points matching this filter exists.<br />
:* [[StandardUnitFilter]] '''*''': Selection criteria. Do not use a [filter] tag.<br />'''* Note:''' ''Does '''not''' check for matching units in the recall list!''<br />
:* '''count''': ''(Optional)'' If used, a number of units equal to the value must match the filter. Accepts a number, range, or comma separated range. If not used, the default value is "1-99999".<br />
:* '''search_recall_list''': ''(Optional)'' If 'yes', search through recall list too. (Default is 'no') {{DevFeature1.9}}<br />
<br />
; [have_location]<br />
: A location matching this filter exists.<br />
:* [[StandardLocationFilter]]: Selection criteria.<br />
:* '''count''': ''(Optional)'' If used, a number of locations equal to the value must match the filter. Accepts a number, range, or comma separated range. If not used, the default value is "1-99999".<br />
<br />
; [variable]<br />
: Test the value of a WML [[VariablesWML|variable]] against another value.<br />
:* '''name''': The name of the variable to test.<br />
:* ''<comparison>'': '''One''' of the following keys must be used to compare the value of the named variable, represented as ''$name'' below, against another value:<br />
:** '''contains''': ''$name'' contains this string value.<br />
:** '''equals''': ''$name'' is equal (string wise) to this value.<br />
:** '''not_equals''': ''$name'' is not equal (string wise) to this value.<br />
:** '''numerical_equals''': ''$name'' is equal (numerically) to this value. <br />
:** '''numerical_not_equals''': ''$name'' is not equal (numerically) to this value. '''*'''<br />'''*''' Using equals is faster. The point of numerical_equals and boolean_equals is not performance, it's representation. For instance, "1" and "1.0" are not equal as strings but they are equal as numbers; and "yes" and "on" are not equal as strings but they are equal as booleans. (This also explains why equals is faster: it is a straightforward comparison that doesn't try to understand what you have written.)<br />
:** '''greater_than''': ''$name'' is greater than this value.<br />
:** '''greater_than_equal_to''': ''$name'' is greater than or equal to this value.<br />
:** '''less_than''': ''$name'' is less than this value.<br />
:** '''less_than_equal_to''': ''$name'' is less than or equal to this value.<br />
:** '''boolean_equals''': ''$name'' has an equivalent boolean value. '''*'''<br />
:** '''boolean_not_equals''': ''$name'' does not have an equivalent boolean value. '''*'''<br />
====Boolean Values====<br />
'''*''' When values are evaluated as boolean values they are checked to see if they are ''false'' or ''true''.<br />These values are evaluated as ''false'': '''no''', '''false''', '''off''', '''0''', and '''0.0''' (and "'''uninitialized'''")<br />These values are evaluated as ''true'': '''yes''', '''true''', '''on''', '''1''', and '''0.1''' (and any other non-zero number)<br />
<br />
'''Warning:''' Usage of "off", "on", integers, and floating-point numbers, as booleans, is deprecated and should be avoided to ensure forward-compatibility of WML with future versions.<br />
<br />
=== Meta Condition Tags ===<br />
<br />
These tags aren't really conditions, themselves. Instead they are wrapped around condition tags to group them into multiple conditions that must all be met, lists of conditions that only one must be met, or conditions that must not be met. These are handled in order in any combination you can think of. One important thing to remember is if you are using '''[or]''' tags, the first conditional statement should ''not'' have an '''[or]''' tag wrapped around it.<br />
<br />
; [and]<br />
: A condition which must evaluate to true in addition to any others. Useful as a bracket for complex conditions, but not strictly necessary.<br />
:* [[#Condition Tags|Condition Tags]]: If these evaluate to true, the '''[and]''' tag evaluates to true.<br />
<br />
; [or]<br />
: A condition which, if it evaluates to true, is all that is necessary for the conditions to be met. In other words, if all other conditions are false, but one '''[or]''' condition is true, the conditions have been met for an [[:Category:ActionsWML|action]] to take place. (See [[AdvancedConditionalWML|Example]])<br />
:* [[#Condition Tags|Condition Tags]]: If these evaluate to true, the '''[or]''' tag evaluates to true. <br />
<br />
; [not]<br />
: A condition which reverses the evaluation of the contained condition(s).<br />
:* [[#Condition Tags|Condition Tags]]: If these evaluate to true, the '''[not]''' tag evaluates to false. If these evaluate to false, the '''[not]''' tag evaluates to true.<br />
<br />
== See Also ==<br />
* [[VariablesWML]]<br />
* [[InternalActionsWML]]<br />
* [[DirectActionsWML]]<br />
* [[InterfaceActionsWML]]<br />
* [[EventWML]]<br />
* [[ReferenceWML]]<br />
<br />
[[Category: WML Reference]]<br />
[[Category: ActionsWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=AnimationWML&diff=40251AnimationWML2011-01-29T21:46:56Z<p>Paŭlo: /* [if] and [else] */ contrasting link to ConditionalActionsWML</p>
<hr />
<div>{{WML Tags}}<br />
<br />
<br />
== Introduction ==<br />
<br />
This page covers unit animations. At any point in game, units are playing an animation. Even when the unit is standing, it is actually playing a single frame animation.<br />
<br />
This page will deal with the two problems of animations<br />
* How are animations Chosen<br />
* What exactly is drawn<br />
<br />
<br />
<br />
== How animations are drawn ==<br />
=== Animations ===<br />
Any unit has a huge set of animations to choose from. Animations are WML blocks in the unit type, enclosed in either the generic type '''[animation]''' or some more specific tags such as '''[attack_anim]''' '''[idle_anim]''' and the like. An animation is what a unit displays when a given event is triggered, and a certain set of conditions are met such as<br />
* unit is attacking<br />
* unit is idling<br />
* unit is attacking (event) and uses a melee weapon (condition)<br />
* unit is attacking (event) and uses a melee weapon (condition) and opponent can't retaliate (condition)<br />
<br />
events and conditions are described entirely in the [animation] block, and will be discussed in the animation choice section.<br />
<br />
=== Frames ===<br />
<br />
An animation is cut in frames. Frames are WML blocks that are contained either in '''[frame]''' WML blocks or in generic '''[xxx_frame]''' block. (the xxx part can be any string not starting with an underscore) the xxx part in the frame name is called the frame prefix. frames of the type '''[frame]''' are said to have an empty prefix<br />
<br />
A frame typically describes an image, where an how to render it. It can contain such things as<br />
* the image to display<br />
* how transparent should that image be<br />
* where to draw that image.<br />
<br />
At any given time, an animation will display one frame for each frame prefix it can find. I.e if your animation has both '''[frame]''' and '''[missile_frame]''' blocks, both will be displayed at the same time<br />
<br />
<br />
The frame with the empty prefix is special in many way. It is assumed to contain the image representing the unit itself, and as such the engine will heavily temper with it in multiple ways, such as providing a default image if none is available, or forcing the image to be green when the unit is poisoned<br />
<br />
=== Timing, Clock, Multiple animations ===<br />
When an animation is played it has an internal clock that is run. The step of this clock is the milisecond, and each frame is played for a given duration. Each animation also has a starting time which tells the animation engine at what value the animation clock should start<br />
<br />
This starting time is very important when multiple animations from different units are played synchronously Typically a fight involves a unit playing its defense animation while the opponent plays it's attack animation (and a third might play its leading animation, too). In that case all animations have a common clock, and are played concurrently.<br />
<br />
The convention is that the "important time" (usually the time of the hit) is at time 0. everything before should be at negative time, everything after at positive time. This is a WML convention that is not enforced by the engine<br />
<br />
In that case, it is very important that these animations (which can have different lengths) be synchronized. Fight animations are synchronized around the point of impact, so they all reach time 0 when the attack lands (or misses). This is accomplished through the use of the '''start_time''' key of the '''[animation]''' tag.<br />
<br />
Just like the '''[frame]''' tag can have a prefix, so can the '''start_time''' key. A '''start_time''' key without prefix will affect a '''[frame]''' tag without prefix, while a '''start_time''' key with a prefix will affect a '''[frame]''' tag with the same prefix.<br />
<br />
==== Example Syntax ====<br />
[attack_anim]<br />
[filter_attack]<br />
name=bow<br />
[/filter_attack]<br />
'''start_time'''=-350<br />
'''missile_start_time'''=-150<br />
[missile_frame]<br />
duration=150<br />
image="projectiles/missile-n.png"<br />
image_diagonal="projectiles/missile-ne.png"<br />
[/missile_frame]<br />
[if]<br />
hits=yes<br />
[frame]<br />
duration=350<br />
sound=bow.ogg<br />
[/frame]<br />
[/if]<br />
[else]<br />
hits=no<br />
[frame]<br />
duration=350<br />
sound=bow-miss.ogg<br />
[/frame]<br />
[/else]<br />
[/attack_anim]<br />
<br />
=== The content of a frame ===<br />
==== Syntax summary ====<br />
[frame]<br />
duration=<integer><br />
begin=<deprecated,integer><br />
end=<deprecated,integer><br />
image=<string><br />
image_diagonal=<string><br />
image_mod=<string><br />
sound=<string><br />
halo=<progressive string><br />
halo_x=<progressive int><br />
halo_y=<progressive int><br />
halo_mod=<string><br />
alpha=<progressive float><br />
offset=<progressive float><br />
blend_color=< red, green, blue ><br />
blend_ratio=<progressive float><br />
text=<string><br />
text_color=< red, green, blue ><br />
submerge=<progressive float><br />
x=<progressive int><br />
y=<progressive int><br />
directional_x=<dev feature 1.9,progressive int><br />
directional_y=<dev feature 1.9,progressive int><br />
layer=<progressive int><br />
auto_hflip=<dev feature 1.9, boolean><br />
auto_vflip=<dev feature 1.9, boolean><br />
primary=<dev feature 1.9, boolean><br />
[/frame]<br />
<br />
==== Progressive parameters ====<br />
<br />
Some parameters above are marked as ''progressive'' This means that you can specify that during the time the frame is displayed, the parameter should smoothly slide from one value to an other.<br />
<br />
A typical example would be a unit progressively fading out, becoming transparent<br />
<br />
To do that, you could use:<br />
<br />
alpha=1~0<br />
<br />
To make a frame, which is 900ms long, slide to transparent for 300ms, stay transparent for another 300ms and finally fade back to normal for 300ms, use:<br />
<br />
alpha=1~0:300,0:300,0~1:300<br />
<br />
you could also specify it like that<br />
<br />
alpha=1~0,0,0~1<br />
<br />
when a timing is missing, the engine will do its best to fill in in a fair way. <br />
<br />
a progressive string has a similar syntax<br />
<br />
halo=halo1.png:300,halo2.png:300,halo2.png:300<br />
<br />
==== Field Description ====<br />
<br />
** '''begin''': (deprecated) will be replaced by '''duration= <end - begin >'''<br />
** '''end''': (deprecated) see '''begin''' and also [[AnimationWML#Timing.2C_Clock.2C_Multiple_animations|Timing, Clock, Multiple animations]] section for coverage of '''start_time''' which combines with '''duration''' to replace '''begin=''' '''end='''.<br />
** '''duration''': how long the frame should be displayed. Use instead of '''begin=''' and '''end='''.<br />
** '''image''': the image to display during the frame.<br />
** '''image_diagonal''': the image to display when the attack occurs diagonally (directions ne,se,sw,nw).<br />
** '''image_mod''': a string modifications (see [[ImagePathFunctionWML]] ) that will be applied to all images<br />
** '''sound''': the sound to play when the frame begins. Can be a comma-separated list of sounds, in which case one of them is chosen randomly every time.<br />
** '''halo''': the halo to display at the time.<br />
** '''halo_x''': the position the halo is displayed in pixel relative to the unit's center.<br />
** '''halo_y''': the position the halo is displayed in pixel relative to the unit's center.<br />
** '''halo_mod''': a string modifications (see [[ImagePathFunctionWML]] ) that will be applied to all haloes<br />
** '''alpha''': transparency level to apply to the frame. This is a floating point progressive parameter ranging from 0.0 to 1.0.<br />
** '''offset''': the position of the image relative to the hex the unit is facing, 0.0 will display the unit in the center of the hex, 1.0 in the center of the faced hex, -1.0 at the center of the hex behind you. This is a progressive parameter.<br />
** '''blend_color''': a comma separated list of numbers representing a color in RGB (0-255) this color will be mixed to the frame to give it a tint.<br />
** '''blend_ratio''': this is a progressive parameter ranging from 0 to 1: 0 means no tint, 1 means target color only.<br />
** '''text''': if specified, floats a label with the given text above the unit (identical to the floating damage and healing numbers).<br />
** '''text_color''': the color of the above floating label.<br />
** '''submerge''': the part of the unit that should drawn with 50% opacity (for units in water)<br />
** '''x''': x offset applied to the frame<br />
** '''y''': y offset applied to the frame<br />
** '''directional_x''': x offset applied to the frame in the direction the unit is facing<br />
** '''directional_y''': y offset applied to the frame in the direction the unit is facing<br />
** '''layer''': layer used to draw the frame, see discussion bellow<br />
** '''auto_hflip''': should the image flip horizontally depending on sprite orientation<br />
** '''auto_vflip''': should the image flip vertically depending on sprite orientation<br />
** '''primary''': should the engine consider that frame as a primary frame (affected by visual effects like stone and poison)<br />
<br />
=== Drawing related animation content ===<br />
==== Syntax summary ====<br />
[animation]<br />
<animation choice related content><br />
[frame]<br />
<frame content><br />
[/frame]<br />
[frame]<br />
<frame content><br />
[/frame]<br />
start_time=<integer><br />
offset=<progressive float><br />
image_mod=<string><br />
blend_with=<r,g,b><br />
blend_ratio=<progressive float><br />
halo=<progressive_string><br />
halo_x=<progressive int><br />
halo_y=<progressive int><br />
halo_mod=<string><br />
submerge=<progressive float><br />
x=<progressive int><br />
y=<progressive int><br />
directional_x=<dev1.9,progressive int><br />
directional_y=<dev1.9,progressive int><br />
layer=<progressive int><br />
<br />
[xxx_frame]<br />
<frame content><br />
[/xxx_frame]<br />
xxx_start_time=<integer><br />
xxx_image_mod=<string><br />
xxx_offset=<progressive float><br />
xxx_blend_with=<r,g,b><br />
xxx_blend_ratio=<progressive float><br />
xxx_halo=<progressive_string><br />
xxx_halo_x=<progressive int><br />
xxx_halo_y=<progressive int><br />
xxx_halo_mod=<string><br />
xxx_submerge=<progressive float><br />
xxx_x=<progressive int><br />
xxx_y=<progressive int><br />
xxx_directional_x=<dev1.9,progressive int><br />
xxx_directional_y=<dev1.9,progressive int><br />
xxx_layer=<progressive int><br />
<br />
[/animation]<br />
<br />
==== Parameter handling ====<br />
All drawing related parameters in '''[animation]''' can be matched with a corresponding parameter in a '''[frame]''' block (or a '''[xxx_frame]''' block) The value provided in the animation will be used if no value is provided in the frame. <br />
<br />
The point of these two level of parameters is to easily be able to specify a parameter at the animation level and override it for a special case of frame.<br />
<br />
== How animations are chosen ==<br />
Within a unit decription block there are multiple animations. Each animation is meant to be played in a very special set of circumstances. We will discuss here how to tell the animation engine when a given animation should be played. <br />
<br />
Let's take an example. Suppose we have a unit which has the skirmisher ability. We have the folowing movement animations :<br />
* a normal walking animation<br />
* a swimming animation when the unit is in water<br />
* a tiptioeing animation when moving next to an ennemy unit<br />
<br />
Ok. most of the time it's easy to guess what animation should be. However if you are both in water and next to an ennemy unit, the animation to play is not obvious.<br />
<br />
To solve that question, each animation has a number of filtering criterias. The engine follow the following rules to select an animation<br />
* Start with all animations<br />
* Drop all animations with a criteria that fails on the current situation<br />
* Take the animations that have the most maching criterias<br />
* If there are more than one animation remaining, take an animation randomly<br />
* If all animations have been droped, the engine will provide a smart default.<br />
<br />
here is a pseudo-code explaination of this algorithm:<br />
<br />
foreach animation<br />
animation_score = 0<br />
foreach filter-criteria<br />
if <criteria-fails> <br />
animation_score = -1;<br />
break;<br />
elsif <criteria-matches> <br />
animation_score++<br />
endfor<br />
if animation_score > max_score<br />
<empty animation list><br />
max_score = animation_score;<br />
push(animation,animation_list);<br />
elsif animation_score = max_score<br />
push(animation,animation_list);<br />
endfor<br />
<choose an animation randomly from animation_list><br />
<br />
<br />
Note that all animations don't have all the filters...<br />
<br />
so, if we have a unit with<br />
# an animation for water terrain<br />
# an animation for SE on grassland<br />
# an animation with no criteria<br />
# an animation for N,NE,NW,S,SW,SE<br />
# an animation for NW<br />
<br />
* 3. will never be taken, because 4. will always trump it<br />
* on water going NW, it can be 1. 4. 5.<br />
* on water, any direction but NW, it will be 1. or 4.<br />
* on SE grassland it will be 2.<br />
* on other grasslands, it will be 4. (4. or 5. if NW)<br />
<br />
=== Generic animation filters available for all animations ===<br />
* '''apply_to''': a list of comma separated keywords describing what event should trigger the animation (movement, attack...) the complete list is given below<br />
* '''value''': a list of comma separated integer, the meaning depends on the triggering event. the meaning is given with the list of event<br />
* '''value_second''': a list of comma separated integer, the meaning depends on the triggering event. the meaning is given with the list of event<br />
* '''terrain''': a list of comma separated terrain letters, the animation will only be used on these terrains. See [[FilterWML#Filtering Terrains|Filtering Terrains]]. this has been replaced by '''terrain_type'''<br />
* '''terrain_type''': a list of comma separated terrain codes, the animation will only be used on matching terrains. See [[FilterWML#Filtering Terrains|Filtering Terrains]].<br />
* '''[filter]''': this will filter using a [[StandardUnitFilter|standard unit filter]] on the animated unit. Note that matching all criterias in the filter will only earn you one point for animation selection, but that you can have multiple '''[filter]''' blocks in an animation.<br />
* '''[filter_second]''': this will filter using a [[StandardUnitFilter|standard unit filter]] on the unit in the hex faced. Note that matching all criteria in the filter will only earn you one point for animation selection, but that you can have multiple '''[filter_second]''' blocks in an animation. Also note that if the faced hex is empty, the whole filter will fail.<br />
* '''direction''': a list of directions (n,ne,se,s,sw,nw), the animation will only be used when acting or moving in this direction (the attack direction for attack animations, moving direction for movement animations, direction of lead unit for leading animations, and so on).<br />
* '''frequency''': this integer value allows to easily tweak the matching frequency of animations. The filter will fail n-1 times out of n, randomly. Note that unlike every other filter, matching this filter won't give an extra point.<br />
* '''[filter_attack]''': a standard attack filter to match on the attacker's attack. See [[FilterWML#Filtering Weapons|Filtering Weapons]]. <br />
* '''[filter_second_attack]''': a standard attack filter to match on the defender's attack. See [[FilterWML#Filtering Weapons|Filtering Weapons]]. Also note that if the defender doesn't have any weapon to retaliate with, this filter will always fail. <br />
* '''hits''': filters attack animations based on whether the attack hits, misses or kills. Accepts a list of the following:<br />
** '''hit''': the attack hits, defender survives.<br />
** '''no''' or '''miss''': the attack misses.<br />
** '''kill''': the attack hits, defender dies.<br />
** '''yes''': is an alias of '''hit,kill'''.<br />
* '''swing''': a list of numbers representing the swing numbers this animation should match (numbered from 1). this has been replaced by value_second<br />
* '''base_score''': {{DevFeature1.9}} : a number that will always be added to the score. Use with caution<br />
<br />
=== Events triggering animations and default animations ===<br />
==== standing ====<br />
This animation is triggered whenever any other animation is finished, and is played in loop until another animation is triggered<br />
<br />
this is the default "standing image" for the unit<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no standing animation is set a single frame animation based on the enclosing unit's '''image=''' field is used<br />
==== selected ====<br />
This animation is triggered whenever the unit is selected<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="0.0~0.3:100,0.3~0.0:200" blend_color=255,255,255''<br />
==== recruited ====<br />
This animation is triggered whenever the unit is recruited or recalled<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''highlight=0~1:600''<br />
<br />
==== recruiting ====<br />
<br />
This animation is triggered for the leader when a unit is recruited or recalled<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
no default animation is needed<br />
<br />
note that is not triggered for WML triggered animations<br />
<br />
==== levelin ====<br />
This animation is triggered whenever the unit levels, before the unit is replaced by the new unit<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="1~0:600" blend_color=255,255,255''<br />
==== levelout ====<br />
This animation is triggered whenever the unit levels, after the unit is replaced by the new unit<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="0~1:600" blend_color=255,255,255''<br />
==== movement ====<br />
This animation is used whenever a unit moves. There are multiple things to consider when dealing with movement animation<br />
* unit stay ''exactly'' 150ms in each hex. so you typically want to have an offset of ''0~1:150,0~1:150,0~1:150,0~1:150,0~1:150'' or something similar<br />
* when a unit enters a hex, the current anim is tested again.<br />
** if the current animation is still valid (i.e it passes all its filter) it is kept, whatever the final score is<br />
** if it fails, a new movement anim is searched<br />
<br />
''value='' contains the number of steps already taken<br />
<br />
''value_second='' contains the number of steps left<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''offset="0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150"''<br />
<br />
==== pre_movement ====<br />
This animation is used before any unit movement<br />
<br />
''value='' is not used, and always contains 0 <br />
<br />
''value_second='' is not used, and always contains 0 <br />
<br />
==== post_movement ====<br />
This animation is used after any unit movement<br />
<br />
''value='' is not used, and always contains 0 <br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
==== pre_teleport ====<br />
This animation is triggered whenever the unit teleports, but before it has moved to the target hex<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="1~0:150" blend_color=255,255,255''<br />
==== post_teleport ====<br />
This animation is triggered whenever the unit teleports, but after it has moved to the target hex<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="0~1:150" blend_color=255,255,255''<br />
==== healing ====<br />
This animation is triggered when the unit has healing powers and uses them<br />
<br />
''value='' is the number of points healed<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
No default is provided by the engine<br />
==== healed ====<br />
This animation is triggered whenever the unit is healed for any reason<br />
<br />
''value='' is the number of points healed<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30" blend_color=255,255,255''<br />
and plays the sound ''heal.wav''<br />
==== poisoned ====<br />
This animation is triggered whenever the unit suffers poison dammage<br />
<br />
''value='' is the number of points lost<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30" blend_color=0,255,0''<br />
and plays the sound 'poison.ogg''<br />
==== defend ====<br />
This animation is triggered during a strike, of the unit receiving the blow<br />
<br />
''value='' is the number of point lost, if any<br />
<br />
''value_second='' is the number of the swing, starting from 1<br />
<br />
No default is provided by the engine<br />
==== attack ====<br />
This animation is triggered during a strike, of the unit giving the blow<br />
<br />
''value='' is the number of damage dealt, if any<br />
<br />
''value_second='' is the number of the swing, starting from 1<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''offset="0~0.6:150,0.6~0:150"'' for melee attacks<br />
No default is provided for range attacks<br />
==== leading ====<br />
This animation is triggered for units with the leading special ability, when the unit they are leading is attacking<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is the number of the swing, starting from 1<br />
<br />
No default is provided by the engine<br />
<br />
<br />
==== resistance ====<br />
This animation is triggered for units with the resistance special ability affecting neighbouring fights, when the unit they are helping is defending<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is the number of the swing, starting from 1<br />
<br />
No default is provided by the engine<br />
<br />
==== death ====<br />
This animation is triggered when a unit die.<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''highlight=1~0:600'' and plays the sound in ''die_sound='' of the enclosing unit<br />
==== victory ====<br />
This animation is triggered when a unit finishes a fight by killing the other unit<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
No default is provided by the engine<br />
==== idling ====<br />
This animation is called when the unit has been using its standing animation for a random duration.<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
No default is provided by the engine<br />
<br />
==== draw_weapon ====<br />
This animation is played before a fight<br />
<br />
''hit='' is set to HIT for the attacker and MISS for the defender<br />
<br />
No default is provided by the engine<br />
<br />
==== sheath_weapon ====<br />
This animation is played after a fight simultaneously for all surviving units<br />
<br />
No default is provided by the engine<br />
<br />
==== default ====<br />
<br />
This animation is never triggered, but is used as a base to create new animations<br />
<br />
''value='' is used depending of the type of animation it replaces<br />
<br />
''value_second='' is used depending of the type of animation it replaces<br />
<br />
A single animation made of the base frame is provided by the engine if no default animation is available<br />
<br />
==== extra animations ====<br />
Other values are never called by the engine. However they can be triggered by WML events allowing custom animations.<br />
<br />
Note that WML events can also trigger standard animations.<br />
''value='' is set from the WML event<br />
<br />
''value_second='' is set from the WML event<br />
<br />
== Shortcuts, tricks and quirks ==<br />
<br />
=== ''[if]'' and ''[else]'' ===<br />
<br />
Often, you need to do very slight variations in an animation (like a different sound depending on whether the unit hits or misses its attack), the '''[if]''' and '''[else]''' tags are meant to help you do that. ('''Attention:''' These do not have the same syntax as the action tag [if] and its subtag [else] in [[ConditionalActionsWML]].)<br />
<br />
Using these in an animation is equivalent to having multiple animations, one with the '''[if]''' block and one with each of the ''[else]'' blocks. Any filtering flags in these blocks will replace the toplevel filters. You can have multiple '''[if]''' blocks in an animation, but you can't nest an '''[if]''' inside another. These should be written directly inside the '''[animation]''' block. The following example would make the '''[frame]''' inside the '''[if]''' be played when the attack misses, and the '''[frame]''' inside the '''[else]''' be played when the attack hits (producing a different sound):<br />
<br />
[if]<br />
hits=no<br />
[frame]<br />
begin=-100<br />
end=100<br />
image="units/dwarves/lord-attack.png"<br />
sound={SOUND_LIST:MISS}<br />
[/frame]<br />
[/if]<br />
[else]<br />
hits=yes<br />
[frame]<br />
begin=-100<br />
end=100<br />
image="units/dwarves/lord-attack.png"<br />
sound=axe.ogg<br />
[/frame]<br />
[/else]<br />
<br />
note that this is very close to preprocessing and should be considered as such, especially with regard to scoring and animation selection<br />
<br />
=== Simplified animation blocks ===<br />
To simplify the most common animation cases, you can use different blocks instead of the generic '''[animation]''' block. These are also here for backward compatibility, but are not deprecated and fully supported<br />
<br />
some of these use extra tags which are translated in the normal ''value='' tag<br />
<br />
some of these define '''[xxx_frame]''' blocks where the frame prefix starts with an underscore. This is not allowed in normal WML (prefix starting with underscore is reserved for the engine internal use). It is here for clarity purpose<br />
<br />
* '''[leading_anim]''' is an animation with the following parameters automatically set<br />
apply_to=leading<br />
* '''[recruit_anim]''' is an animation with the following parameters automatically set<br />
apply_to=recruited<br />
* '''[recruiting_anim]''' is an animation with the following parameters automatically set<br />
apply_to=recruiting<br />
* '''[standing_anim]''' is an animation with the following parameters automatically set<br />
apply_to=standing,default<br />
note for 1.4 :''default'' doesn't exist in 1.4, but the semantic is the same.<br />
<br />
i.e: the animation will be used to build default animations<br />
* '''[idle_anim]''' is an animation with the following parameters automatically set<br />
apply_to=idling<br />
* '''[levelin_anim]''' is an animation with the following parameters automatically set<br />
apply_to=levelin<br />
* '''[levelout_anim]''' is an animation with the following parameters automatically set<br />
apply_to=levelout<br />
* '''[healing_anim]''' is an animation with the following parameters automatically set<br />
apply_to=healing<br />
value=<damage= value><br />
* '''[healed_anim]''' is an animation with the following parameters automatically set<br />
apply_to=healed<br />
value=<healing= value><br />
[_healed_sound_frame]<br />
sound=heal.wav<br />
[/_healed_sound_frame]<br />
* '''[poison_anim]''' is an animation with the following parameters automatically set<br />
apply_to=poisoned<br />
value=<damage= value><br />
[_poison_sound_frame]<br />
sound=poison.ogg<br />
[/_poison_sound_frame]<br />
* '''[movement_anim]''' is an animation with the following parameters automatically set<br />
apply_to=movement<br />
offset="0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150"<br />
* '''[pre_movement_anim]''' is an animation with the following parameters automatically set<br />
apply_to=pre_movement<br />
* '''[post_movement_anim]''' is an animation with the following parameters automatically set<br />
apply_to=post_movement<br />
* '''[draw_weapon_anim]''' is an animation with the following parameters automatically set<br />
apply_to=draw_weapon<br />
* '''[sheath_weapon_anim]''' is an animation with the following parameters automatically set<br />
apply_to=sheath_weapon_movement<br />
* '''[defend]''' is an animation with the following parameters automatically set<br />
apply_to=defend<br />
value=<damage= value><br />
<WML content><br />
[frame]<br />
blend_with=255,0,0<br />
blend_ratio="0.5:50,0.0:50"<br />
[/frame]<br />
<br />
there are some subtil change compared to what is described above to avoid the red flash when value=0, but it should work as expected as far as WML author are concerned<br />
<br />
* '''[attack_anim]''' is an animation with the following parameters automatically set<br />
if the animation contains a missile frame<br />
<br />
apply_to=attack<br />
missile_offset="0~0.8"<br />
<br />
else<br />
<br />
apply_to=attack<br />
offset="0~0.6,0.6~0"<br />
<br />
* '''[death]''' is an animation with the following parameters automatically set<br />
apply_to=death<br />
[_death_sound_frame]<br />
sound=<die_sound= of the enclosing [unit] tag><br />
[/_death_sound_frame]<br />
* '''[victory_anim]''' is an animation with the following parameters automatically set<br />
apply_to=victory<br />
* '''[extra_anim]''' is an animation with the following parameters automatically set<br />
apply_to=<flag= value of the anim><br />
* '''[teleport_anim]''' will be cut into two at the clock-time 0<br />
everything before zero becomes an animation with the following parameters automatically set<br />
apply_to=pre_teleport<br />
everything after zero becomes an animation with the following parameters automatically set<br />
apply_to=post_teleport<br />
<br />
== Layering ==<br />
The ''layer'' progressive parameter allows the animation writer to choose in what order the animation should be drawn.<br />
<br />
this value must be between 0 and 100<br />
<br />
* the back of haloes is drawn with a value of 10<br />
* when unspecified, a animation is drawn with a value of 40<br />
* terrain elements that are supposed to go in front of units (castles) are drawn with a value of 50<br />
* orbs and status bars are drawn on layer 80<br />
* when unspecified missile frames are drawn on layer 90<br />
<br />
by changing these values, it is easy to have the unit display the way you want<br />
<br />
== Optimization ==<br />
<br />
there is a special flag that goes into the animation block (not the frame) <br />
<br />
* ''offscreen'' a boolean saying if the unit's animation should be played when the unit is offscreen. You want the animation to play offscreen if the animation contains some usefull sound effects.This attribute defaults to true (play offscreen) except for standing and idle animations where it defaults to false<br />
<br />
== See Also ==<br />
<br />
* [[UnitTypeWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=AnimationWML&diff=40250AnimationWML2011-01-29T21:42:08Z<p>Paŭlo: /* Generic animation filters available for all animations */ links to specific sections of FilterWML, and StandardUnitFilter</p>
<hr />
<div>{{WML Tags}}<br />
<br />
<br />
== Introduction ==<br />
<br />
This page covers unit animations. At any point in game, units are playing an animation. Even when the unit is standing, it is actually playing a single frame animation.<br />
<br />
This page will deal with the two problems of animations<br />
* How are animations Chosen<br />
* What exactly is drawn<br />
<br />
<br />
<br />
== How animations are drawn ==<br />
=== Animations ===<br />
Any unit has a huge set of animations to choose from. Animations are WML blocks in the unit type, enclosed in either the generic type '''[animation]''' or some more specific tags such as '''[attack_anim]''' '''[idle_anim]''' and the like. An animation is what a unit displays when a given event is triggered, and a certain set of conditions are met such as<br />
* unit is attacking<br />
* unit is idling<br />
* unit is attacking (event) and uses a melee weapon (condition)<br />
* unit is attacking (event) and uses a melee weapon (condition) and opponent can't retaliate (condition)<br />
<br />
events and conditions are described entirely in the [animation] block, and will be discussed in the animation choice section.<br />
<br />
=== Frames ===<br />
<br />
An animation is cut in frames. Frames are WML blocks that are contained either in '''[frame]''' WML blocks or in generic '''[xxx_frame]''' block. (the xxx part can be any string not starting with an underscore) the xxx part in the frame name is called the frame prefix. frames of the type '''[frame]''' are said to have an empty prefix<br />
<br />
A frame typically describes an image, where an how to render it. It can contain such things as<br />
* the image to display<br />
* how transparent should that image be<br />
* where to draw that image.<br />
<br />
At any given time, an animation will display one frame for each frame prefix it can find. I.e if your animation has both '''[frame]''' and '''[missile_frame]''' blocks, both will be displayed at the same time<br />
<br />
<br />
The frame with the empty prefix is special in many way. It is assumed to contain the image representing the unit itself, and as such the engine will heavily temper with it in multiple ways, such as providing a default image if none is available, or forcing the image to be green when the unit is poisoned<br />
<br />
=== Timing, Clock, Multiple animations ===<br />
When an animation is played it has an internal clock that is run. The step of this clock is the milisecond, and each frame is played for a given duration. Each animation also has a starting time which tells the animation engine at what value the animation clock should start<br />
<br />
This starting time is very important when multiple animations from different units are played synchronously Typically a fight involves a unit playing its defense animation while the opponent plays it's attack animation (and a third might play its leading animation, too). In that case all animations have a common clock, and are played concurrently.<br />
<br />
The convention is that the "important time" (usually the time of the hit) is at time 0. everything before should be at negative time, everything after at positive time. This is a WML convention that is not enforced by the engine<br />
<br />
In that case, it is very important that these animations (which can have different lengths) be synchronized. Fight animations are synchronized around the point of impact, so they all reach time 0 when the attack lands (or misses). This is accomplished through the use of the '''start_time''' key of the '''[animation]''' tag.<br />
<br />
Just like the '''[frame]''' tag can have a prefix, so can the '''start_time''' key. A '''start_time''' key without prefix will affect a '''[frame]''' tag without prefix, while a '''start_time''' key with a prefix will affect a '''[frame]''' tag with the same prefix.<br />
<br />
==== Example Syntax ====<br />
[attack_anim]<br />
[filter_attack]<br />
name=bow<br />
[/filter_attack]<br />
'''start_time'''=-350<br />
'''missile_start_time'''=-150<br />
[missile_frame]<br />
duration=150<br />
image="projectiles/missile-n.png"<br />
image_diagonal="projectiles/missile-ne.png"<br />
[/missile_frame]<br />
[if]<br />
hits=yes<br />
[frame]<br />
duration=350<br />
sound=bow.ogg<br />
[/frame]<br />
[/if]<br />
[else]<br />
hits=no<br />
[frame]<br />
duration=350<br />
sound=bow-miss.ogg<br />
[/frame]<br />
[/else]<br />
[/attack_anim]<br />
<br />
=== The content of a frame ===<br />
==== Syntax summary ====<br />
[frame]<br />
duration=<integer><br />
begin=<deprecated,integer><br />
end=<deprecated,integer><br />
image=<string><br />
image_diagonal=<string><br />
image_mod=<string><br />
sound=<string><br />
halo=<progressive string><br />
halo_x=<progressive int><br />
halo_y=<progressive int><br />
halo_mod=<string><br />
alpha=<progressive float><br />
offset=<progressive float><br />
blend_color=< red, green, blue ><br />
blend_ratio=<progressive float><br />
text=<string><br />
text_color=< red, green, blue ><br />
submerge=<progressive float><br />
x=<progressive int><br />
y=<progressive int><br />
directional_x=<dev feature 1.9,progressive int><br />
directional_y=<dev feature 1.9,progressive int><br />
layer=<progressive int><br />
auto_hflip=<dev feature 1.9, boolean><br />
auto_vflip=<dev feature 1.9, boolean><br />
primary=<dev feature 1.9, boolean><br />
[/frame]<br />
<br />
==== Progressive parameters ====<br />
<br />
Some parameters above are marked as ''progressive'' This means that you can specify that during the time the frame is displayed, the parameter should smoothly slide from one value to an other.<br />
<br />
A typical example would be a unit progressively fading out, becoming transparent<br />
<br />
To do that, you could use:<br />
<br />
alpha=1~0<br />
<br />
To make a frame, which is 900ms long, slide to transparent for 300ms, stay transparent for another 300ms and finally fade back to normal for 300ms, use:<br />
<br />
alpha=1~0:300,0:300,0~1:300<br />
<br />
you could also specify it like that<br />
<br />
alpha=1~0,0,0~1<br />
<br />
when a timing is missing, the engine will do its best to fill in in a fair way. <br />
<br />
a progressive string has a similar syntax<br />
<br />
halo=halo1.png:300,halo2.png:300,halo2.png:300<br />
<br />
==== Field Description ====<br />
<br />
** '''begin''': (deprecated) will be replaced by '''duration= <end - begin >'''<br />
** '''end''': (deprecated) see '''begin''' and also [[AnimationWML#Timing.2C_Clock.2C_Multiple_animations|Timing, Clock, Multiple animations]] section for coverage of '''start_time''' which combines with '''duration''' to replace '''begin=''' '''end='''.<br />
** '''duration''': how long the frame should be displayed. Use instead of '''begin=''' and '''end='''.<br />
** '''image''': the image to display during the frame.<br />
** '''image_diagonal''': the image to display when the attack occurs diagonally (directions ne,se,sw,nw).<br />
** '''image_mod''': a string modifications (see [[ImagePathFunctionWML]] ) that will be applied to all images<br />
** '''sound''': the sound to play when the frame begins. Can be a comma-separated list of sounds, in which case one of them is chosen randomly every time.<br />
** '''halo''': the halo to display at the time.<br />
** '''halo_x''': the position the halo is displayed in pixel relative to the unit's center.<br />
** '''halo_y''': the position the halo is displayed in pixel relative to the unit's center.<br />
** '''halo_mod''': a string modifications (see [[ImagePathFunctionWML]] ) that will be applied to all haloes<br />
** '''alpha''': transparency level to apply to the frame. This is a floating point progressive parameter ranging from 0.0 to 1.0.<br />
** '''offset''': the position of the image relative to the hex the unit is facing, 0.0 will display the unit in the center of the hex, 1.0 in the center of the faced hex, -1.0 at the center of the hex behind you. This is a progressive parameter.<br />
** '''blend_color''': a comma separated list of numbers representing a color in RGB (0-255) this color will be mixed to the frame to give it a tint.<br />
** '''blend_ratio''': this is a progressive parameter ranging from 0 to 1: 0 means no tint, 1 means target color only.<br />
** '''text''': if specified, floats a label with the given text above the unit (identical to the floating damage and healing numbers).<br />
** '''text_color''': the color of the above floating label.<br />
** '''submerge''': the part of the unit that should drawn with 50% opacity (for units in water)<br />
** '''x''': x offset applied to the frame<br />
** '''y''': y offset applied to the frame<br />
** '''directional_x''': x offset applied to the frame in the direction the unit is facing<br />
** '''directional_y''': y offset applied to the frame in the direction the unit is facing<br />
** '''layer''': layer used to draw the frame, see discussion bellow<br />
** '''auto_hflip''': should the image flip horizontally depending on sprite orientation<br />
** '''auto_vflip''': should the image flip vertically depending on sprite orientation<br />
** '''primary''': should the engine consider that frame as a primary frame (affected by visual effects like stone and poison)<br />
<br />
=== Drawing related animation content ===<br />
==== Syntax summary ====<br />
[animation]<br />
<animation choice related content><br />
[frame]<br />
<frame content><br />
[/frame]<br />
[frame]<br />
<frame content><br />
[/frame]<br />
start_time=<integer><br />
offset=<progressive float><br />
image_mod=<string><br />
blend_with=<r,g,b><br />
blend_ratio=<progressive float><br />
halo=<progressive_string><br />
halo_x=<progressive int><br />
halo_y=<progressive int><br />
halo_mod=<string><br />
submerge=<progressive float><br />
x=<progressive int><br />
y=<progressive int><br />
directional_x=<dev1.9,progressive int><br />
directional_y=<dev1.9,progressive int><br />
layer=<progressive int><br />
<br />
[xxx_frame]<br />
<frame content><br />
[/xxx_frame]<br />
xxx_start_time=<integer><br />
xxx_image_mod=<string><br />
xxx_offset=<progressive float><br />
xxx_blend_with=<r,g,b><br />
xxx_blend_ratio=<progressive float><br />
xxx_halo=<progressive_string><br />
xxx_halo_x=<progressive int><br />
xxx_halo_y=<progressive int><br />
xxx_halo_mod=<string><br />
xxx_submerge=<progressive float><br />
xxx_x=<progressive int><br />
xxx_y=<progressive int><br />
xxx_directional_x=<dev1.9,progressive int><br />
xxx_directional_y=<dev1.9,progressive int><br />
xxx_layer=<progressive int><br />
<br />
[/animation]<br />
<br />
==== Parameter handling ====<br />
All drawing related parameters in '''[animation]''' can be matched with a corresponding parameter in a '''[frame]''' block (or a '''[xxx_frame]''' block) The value provided in the animation will be used if no value is provided in the frame. <br />
<br />
The point of these two level of parameters is to easily be able to specify a parameter at the animation level and override it for a special case of frame.<br />
<br />
== How animations are chosen ==<br />
Within a unit decription block there are multiple animations. Each animation is meant to be played in a very special set of circumstances. We will discuss here how to tell the animation engine when a given animation should be played. <br />
<br />
Let's take an example. Suppose we have a unit which has the skirmisher ability. We have the folowing movement animations :<br />
* a normal walking animation<br />
* a swimming animation when the unit is in water<br />
* a tiptioeing animation when moving next to an ennemy unit<br />
<br />
Ok. most of the time it's easy to guess what animation should be. However if you are both in water and next to an ennemy unit, the animation to play is not obvious.<br />
<br />
To solve that question, each animation has a number of filtering criterias. The engine follow the following rules to select an animation<br />
* Start with all animations<br />
* Drop all animations with a criteria that fails on the current situation<br />
* Take the animations that have the most maching criterias<br />
* If there are more than one animation remaining, take an animation randomly<br />
* If all animations have been droped, the engine will provide a smart default.<br />
<br />
here is a pseudo-code explaination of this algorithm:<br />
<br />
foreach animation<br />
animation_score = 0<br />
foreach filter-criteria<br />
if <criteria-fails> <br />
animation_score = -1;<br />
break;<br />
elsif <criteria-matches> <br />
animation_score++<br />
endfor<br />
if animation_score > max_score<br />
<empty animation list><br />
max_score = animation_score;<br />
push(animation,animation_list);<br />
elsif animation_score = max_score<br />
push(animation,animation_list);<br />
endfor<br />
<choose an animation randomly from animation_list><br />
<br />
<br />
Note that all animations don't have all the filters...<br />
<br />
so, if we have a unit with<br />
# an animation for water terrain<br />
# an animation for SE on grassland<br />
# an animation with no criteria<br />
# an animation for N,NE,NW,S,SW,SE<br />
# an animation for NW<br />
<br />
* 3. will never be taken, because 4. will always trump it<br />
* on water going NW, it can be 1. 4. 5.<br />
* on water, any direction but NW, it will be 1. or 4.<br />
* on SE grassland it will be 2.<br />
* on other grasslands, it will be 4. (4. or 5. if NW)<br />
<br />
=== Generic animation filters available for all animations ===<br />
* '''apply_to''': a list of comma separated keywords describing what event should trigger the animation (movement, attack...) the complete list is given below<br />
* '''value''': a list of comma separated integer, the meaning depends on the triggering event. the meaning is given with the list of event<br />
* '''value_second''': a list of comma separated integer, the meaning depends on the triggering event. the meaning is given with the list of event<br />
* '''terrain''': a list of comma separated terrain letters, the animation will only be used on these terrains. See [[FilterWML#Filtering Terrains|Filtering Terrains]]. this has been replaced by '''terrain_type'''<br />
* '''terrain_type''': a list of comma separated terrain codes, the animation will only be used on matching terrains. See [[FilterWML#Filtering Terrains|Filtering Terrains]].<br />
* '''[filter]''': this will filter using a [[StandardUnitFilter|standard unit filter]] on the animated unit. Note that matching all criterias in the filter will only earn you one point for animation selection, but that you can have multiple '''[filter]''' blocks in an animation.<br />
* '''[filter_second]''': this will filter using a [[StandardUnitFilter|standard unit filter]] on the unit in the hex faced. Note that matching all criteria in the filter will only earn you one point for animation selection, but that you can have multiple '''[filter_second]''' blocks in an animation. Also note that if the faced hex is empty, the whole filter will fail.<br />
* '''direction''': a list of directions (n,ne,se,s,sw,nw), the animation will only be used when acting or moving in this direction (the attack direction for attack animations, moving direction for movement animations, direction of lead unit for leading animations, and so on).<br />
* '''frequency''': this integer value allows to easily tweak the matching frequency of animations. The filter will fail n-1 times out of n, randomly. Note that unlike every other filter, matching this filter won't give an extra point.<br />
* '''[filter_attack]''': a standard attack filter to match on the attacker's attack. See [[FilterWML#Filtering Weapons|Filtering Weapons]]. <br />
* '''[filter_second_attack]''': a standard attack filter to match on the defender's attack. See [[FilterWML#Filtering Weapons|Filtering Weapons]]. Also note that if the defender doesn't have any weapon to retaliate with, this filter will always fail. <br />
* '''hits''': filters attack animations based on whether the attack hits, misses or kills. Accepts a list of the following:<br />
** '''hit''': the attack hits, defender survives.<br />
** '''no''' or '''miss''': the attack misses.<br />
** '''kill''': the attack hits, defender dies.<br />
** '''yes''': is an alias of '''hit,kill'''.<br />
* '''swing''': a list of numbers representing the swing numbers this animation should match (numbered from 1). this has been replaced by value_second<br />
* '''base_score''': {{DevFeature1.9}} : a number that will always be added to the score. Use with caution<br />
<br />
=== Events triggering animations and default animations ===<br />
==== standing ====<br />
This animation is triggered whenever any other animation is finished, and is played in loop until another animation is triggered<br />
<br />
this is the default "standing image" for the unit<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no standing animation is set a single frame animation based on the enclosing unit's '''image=''' field is used<br />
==== selected ====<br />
This animation is triggered whenever the unit is selected<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="0.0~0.3:100,0.3~0.0:200" blend_color=255,255,255''<br />
==== recruited ====<br />
This animation is triggered whenever the unit is recruited or recalled<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''highlight=0~1:600''<br />
<br />
==== recruiting ====<br />
<br />
This animation is triggered for the leader when a unit is recruited or recalled<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
no default animation is needed<br />
<br />
note that is not triggered for WML triggered animations<br />
<br />
==== levelin ====<br />
This animation is triggered whenever the unit levels, before the unit is replaced by the new unit<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="1~0:600" blend_color=255,255,255''<br />
==== levelout ====<br />
This animation is triggered whenever the unit levels, after the unit is replaced by the new unit<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="0~1:600" blend_color=255,255,255''<br />
==== movement ====<br />
This animation is used whenever a unit moves. There are multiple things to consider when dealing with movement animation<br />
* unit stay ''exactly'' 150ms in each hex. so you typically want to have an offset of ''0~1:150,0~1:150,0~1:150,0~1:150,0~1:150'' or something similar<br />
* when a unit enters a hex, the current anim is tested again.<br />
** if the current animation is still valid (i.e it passes all its filter) it is kept, whatever the final score is<br />
** if it fails, a new movement anim is searched<br />
<br />
''value='' contains the number of steps already taken<br />
<br />
''value_second='' contains the number of steps left<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''offset="0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150"''<br />
<br />
==== pre_movement ====<br />
This animation is used before any unit movement<br />
<br />
''value='' is not used, and always contains 0 <br />
<br />
''value_second='' is not used, and always contains 0 <br />
<br />
==== post_movement ====<br />
This animation is used after any unit movement<br />
<br />
''value='' is not used, and always contains 0 <br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
==== pre_teleport ====<br />
This animation is triggered whenever the unit teleports, but before it has moved to the target hex<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="1~0:150" blend_color=255,255,255''<br />
==== post_teleport ====<br />
This animation is triggered whenever the unit teleports, but after it has moved to the target hex<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="0~1:150" blend_color=255,255,255''<br />
==== healing ====<br />
This animation is triggered when the unit has healing powers and uses them<br />
<br />
''value='' is the number of points healed<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
No default is provided by the engine<br />
==== healed ====<br />
This animation is triggered whenever the unit is healed for any reason<br />
<br />
''value='' is the number of points healed<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30" blend_color=255,255,255''<br />
and plays the sound ''heal.wav''<br />
==== poisoned ====<br />
This animation is triggered whenever the unit suffers poison dammage<br />
<br />
''value='' is the number of points lost<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''blend_with="0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30" blend_color=0,255,0''<br />
and plays the sound 'poison.ogg''<br />
==== defend ====<br />
This animation is triggered during a strike, of the unit receiving the blow<br />
<br />
''value='' is the number of point lost, if any<br />
<br />
''value_second='' is the number of the swing, starting from 1<br />
<br />
No default is provided by the engine<br />
==== attack ====<br />
This animation is triggered during a strike, of the unit giving the blow<br />
<br />
''value='' is the number of damage dealt, if any<br />
<br />
''value_second='' is the number of the swing, starting from 1<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''offset="0~0.6:150,0.6~0:150"'' for melee attacks<br />
No default is provided for range attacks<br />
==== leading ====<br />
This animation is triggered for units with the leading special ability, when the unit they are leading is attacking<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is the number of the swing, starting from 1<br />
<br />
No default is provided by the engine<br />
<br />
<br />
==== resistance ====<br />
This animation is triggered for units with the resistance special ability affecting neighbouring fights, when the unit they are helping is defending<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is the number of the swing, starting from 1<br />
<br />
No default is provided by the engine<br />
<br />
==== death ====<br />
This animation is triggered when a unit die.<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
if no animation is available, the default uses the standing animation(s) with ''highlight=1~0:600'' and plays the sound in ''die_sound='' of the enclosing unit<br />
==== victory ====<br />
This animation is triggered when a unit finishes a fight by killing the other unit<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
No default is provided by the engine<br />
==== idling ====<br />
This animation is called when the unit has been using its standing animation for a random duration.<br />
<br />
''value='' is not used, and always contains 0<br />
<br />
''value_second='' is not used, and always contains 0<br />
<br />
No default is provided by the engine<br />
<br />
==== draw_weapon ====<br />
This animation is played before a fight<br />
<br />
''hit='' is set to HIT for the attacker and MISS for the defender<br />
<br />
No default is provided by the engine<br />
<br />
==== sheath_weapon ====<br />
This animation is played after a fight simultaneously for all surviving units<br />
<br />
No default is provided by the engine<br />
<br />
==== default ====<br />
<br />
This animation is never triggered, but is used as a base to create new animations<br />
<br />
''value='' is used depending of the type of animation it replaces<br />
<br />
''value_second='' is used depending of the type of animation it replaces<br />
<br />
A single animation made of the base frame is provided by the engine if no default animation is available<br />
<br />
==== extra animations ====<br />
Other values are never called by the engine. However they can be triggered by WML events allowing custom animations.<br />
<br />
Note that WML events can also trigger standard animations.<br />
''value='' is set from the WML event<br />
<br />
''value_second='' is set from the WML event<br />
<br />
== Shortcuts, tricks and quirks ==<br />
<br />
=== ''[if]'' and ''[else]'' ===<br />
<br />
Often, you need to do very slight variations in an animation (like a different sound depending on whether the unit hits or misses its attack), the '''[if]''' and '''[else]''' tags are meant to help you do that. <br />
<br />
Using these in an animation is equivalent to having multiple animations, one with the '''[if]''' block and one with each of the ''[else]'' blocks. Any filtering flags in these blocks will replace the toplevel filters. You can have multiple '''[if]''' blocks in an animation, but you can't nest an '''[if]''' inside another. These should be written directly inside the '''[animation]''' block. The following example would make the '''[frame]''' inside the '''[if]''' be played when the attack misses, and the '''[frame]''' inside the '''[else]''' be played when the attack hits (producing a different sound):<br />
<br />
[if]<br />
hits=no<br />
[frame]<br />
begin=-100<br />
end=100<br />
image="units/dwarves/lord-attack.png"<br />
sound={SOUND_LIST:MISS}<br />
[/frame]<br />
[/if]<br />
[else]<br />
hits=yes<br />
[frame]<br />
begin=-100<br />
end=100<br />
image="units/dwarves/lord-attack.png"<br />
sound=axe.ogg<br />
[/frame]<br />
[/else]<br />
<br />
note that this is very close to preprocessing and should be considered as such, especially with regard to scoring and animation selection<br />
<br />
=== Simplified animation blocks ===<br />
To simplify the most common animation cases, you can use different blocks instead of the generic '''[animation]''' block. These are also here for backward compatibility, but are not deprecated and fully supported<br />
<br />
some of these use extra tags which are translated in the normal ''value='' tag<br />
<br />
some of these define '''[xxx_frame]''' blocks where the frame prefix starts with an underscore. This is not allowed in normal WML (prefix starting with underscore is reserved for the engine internal use). It is here for clarity purpose<br />
<br />
* '''[leading_anim]''' is an animation with the following parameters automatically set<br />
apply_to=leading<br />
* '''[recruit_anim]''' is an animation with the following parameters automatically set<br />
apply_to=recruited<br />
* '''[recruiting_anim]''' is an animation with the following parameters automatically set<br />
apply_to=recruiting<br />
* '''[standing_anim]''' is an animation with the following parameters automatically set<br />
apply_to=standing,default<br />
note for 1.4 :''default'' doesn't exist in 1.4, but the semantic is the same.<br />
<br />
i.e: the animation will be used to build default animations<br />
* '''[idle_anim]''' is an animation with the following parameters automatically set<br />
apply_to=idling<br />
* '''[levelin_anim]''' is an animation with the following parameters automatically set<br />
apply_to=levelin<br />
* '''[levelout_anim]''' is an animation with the following parameters automatically set<br />
apply_to=levelout<br />
* '''[healing_anim]''' is an animation with the following parameters automatically set<br />
apply_to=healing<br />
value=<damage= value><br />
* '''[healed_anim]''' is an animation with the following parameters automatically set<br />
apply_to=healed<br />
value=<healing= value><br />
[_healed_sound_frame]<br />
sound=heal.wav<br />
[/_healed_sound_frame]<br />
* '''[poison_anim]''' is an animation with the following parameters automatically set<br />
apply_to=poisoned<br />
value=<damage= value><br />
[_poison_sound_frame]<br />
sound=poison.ogg<br />
[/_poison_sound_frame]<br />
* '''[movement_anim]''' is an animation with the following parameters automatically set<br />
apply_to=movement<br />
offset="0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150,0~1:150"<br />
* '''[pre_movement_anim]''' is an animation with the following parameters automatically set<br />
apply_to=pre_movement<br />
* '''[post_movement_anim]''' is an animation with the following parameters automatically set<br />
apply_to=post_movement<br />
* '''[draw_weapon_anim]''' is an animation with the following parameters automatically set<br />
apply_to=draw_weapon<br />
* '''[sheath_weapon_anim]''' is an animation with the following parameters automatically set<br />
apply_to=sheath_weapon_movement<br />
* '''[defend]''' is an animation with the following parameters automatically set<br />
apply_to=defend<br />
value=<damage= value><br />
<WML content><br />
[frame]<br />
blend_with=255,0,0<br />
blend_ratio="0.5:50,0.0:50"<br />
[/frame]<br />
<br />
there are some subtil change compared to what is described above to avoid the red flash when value=0, but it should work as expected as far as WML author are concerned<br />
<br />
* '''[attack_anim]''' is an animation with the following parameters automatically set<br />
if the animation contains a missile frame<br />
<br />
apply_to=attack<br />
missile_offset="0~0.8"<br />
<br />
else<br />
<br />
apply_to=attack<br />
offset="0~0.6,0.6~0"<br />
<br />
* '''[death]''' is an animation with the following parameters automatically set<br />
apply_to=death<br />
[_death_sound_frame]<br />
sound=<die_sound= of the enclosing [unit] tag><br />
[/_death_sound_frame]<br />
* '''[victory_anim]''' is an animation with the following parameters automatically set<br />
apply_to=victory<br />
* '''[extra_anim]''' is an animation with the following parameters automatically set<br />
apply_to=<flag= value of the anim><br />
* '''[teleport_anim]''' will be cut into two at the clock-time 0<br />
everything before zero becomes an animation with the following parameters automatically set<br />
apply_to=pre_teleport<br />
everything after zero becomes an animation with the following parameters automatically set<br />
apply_to=post_teleport<br />
<br />
== Layering ==<br />
The ''layer'' progressive parameter allows the animation writer to choose in what order the animation should be drawn.<br />
<br />
this value must be between 0 and 100<br />
<br />
* the back of haloes is drawn with a value of 10<br />
* when unspecified, a animation is drawn with a value of 40<br />
* terrain elements that are supposed to go in front of units (castles) are drawn with a value of 50<br />
* orbs and status bars are drawn on layer 80<br />
* when unspecified missile frames are drawn on layer 90<br />
<br />
by changing these values, it is easy to have the unit display the way you want<br />
<br />
== Optimization ==<br />
<br />
there is a special flag that goes into the animation block (not the frame) <br />
<br />
* ''offscreen'' a boolean saying if the unit's animation should be played when the unit is offscreen. You want the animation to play offscreen if the animation contains some usefull sound effects.This attribute defaults to true (play offscreen) except for standing and idle animations where it defaults to false<br />
<br />
== See Also ==<br />
<br />
* [[UnitTypeWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=WML_Abilities&diff=40222WML Abilities2011-01-24T11:33:28Z<p>Paŭlo: Undo revision 40221 by Paŭlo (Talk) (misread the sentence.)</p>
<hr />
<div>Remember that you must include the WML ability code in every scenario where you intend them to work. Or include them in the unit file inside the [unit_type] tag.<br />
<br />
Some abilities require macros from [[WML_Utilities|Utilities]]. <br />
<br />
<br />
<br />
=== Knockback ===<br />
<br />
When a unit is hit with a knockback attack, it is immediately pushed back one hex away from the attacker. Units cannot be knocked back into an occupied hex, out of villages or onto terrain they normally could not move to. Only works on offense.<br />
<br />
Use this to display the special correctly on the attacks you want:<br />
#define WEAPON_SPECIAL_KNOCKBACK<br />
[dummy]<br />
id=knockback<br />
name= _ "knockback"<br />
female_name= _ "female^knockback"<br />
description=_ "Knockback:<br />
When a unit is hit with a knockback attack, it is immediately pushed back one hex away from the attacker. Units cannot be knocked back into an occupied hex, out of villages or onto terrain they normally could not move to. Only works on offense."<br />
[/dummy]<br />
#enddef<br />
<br />
And insert this event to your [scenario], [multiplayer], [unit_type] or [era]:<br />
[event]<br />
name=attacker hits<br />
first_time_only=no<br />
<br />
[filter_attack]<br />
special=knockback<br />
[/filter_attack]<br />
<br />
[filter_second]<br />
[not]<br />
[filter_location]<br />
terrain=*^V*<br />
[/filter_location]<br />
[/not]<br />
[/filter_second]<br />
<br />
[if]<br />
[variable]<br />
name=second_unit.hitpoints<br />
greater_than=0<br />
[/variable]<br />
<br />
[then]<br />
[if]<br />
[have_unit]<br />
x,y=$x1,$y1<br />
[filter_adjacent]<br />
x,y=$x2,$y2<br />
adjacent=n<br />
[/filter_adjacent]<br />
[/have_unit]<br />
[then]<br />
{VARIABLE knockback_direction n}<br />
[/then]<br />
[else]<br />
[if]<br />
[have_unit]<br />
x,y=$x1,$y1<br />
[filter_adjacent]<br />
x,y=$x2,$y2<br />
adjacent=ne<br />
[/filter_adjacent]<br />
[/have_unit]<br />
[then]<br />
{VARIABLE knockback_direction ne}<br />
[/then]<br />
[else]<br />
[if]<br />
[have_unit]<br />
x,y=$x1,$y1<br />
[filter_adjacent]<br />
x,y=$x2,$y2<br />
adjacent=se<br />
[/filter_adjacent]<br />
[/have_unit]<br />
[then]<br />
{VARIABLE knockback_direction se}<br />
[/then]<br />
[else]<br />
[if]<br />
[have_unit]<br />
x,y=$x1,$y1<br />
[filter_adjacent]<br />
x,y=$x2,$y2<br />
adjacent=s<br />
[/filter_adjacent]<br />
[/have_unit]<br />
[then]<br />
{VARIABLE knockback_direction s}<br />
[/then]<br />
[else]<br />
[if]<br />
[have_unit]<br />
x,y=$x1,$y1<br />
[filter_adjacent]<br />
x,y=$x2,$y2<br />
adjacent=sw<br />
[/filter_adjacent]<br />
[/have_unit]<br />
[then]<br />
{VARIABLE knockback_direction sw}<br />
[/then]<br />
[else]<br />
[if]<br />
[have_unit]<br />
x,y=$x1,$y1<br />
[filter_adjacent]<br />
x,y=$x2,$y2<br />
adjacent=nw<br />
[/filter_adjacent]<br />
[/have_unit]<br />
[then]<br />
{VARIABLE knockback_direction nw}<br />
[/then]<br />
[/if]<br />
[/else]<br />
[/if]<br />
[/else]<br />
[/if]<br />
[/else]<br />
[/if]<br />
[/else]<br />
[/if]<br />
[/else]<br />
[/if]<br />
<br />
[store_locations]<br />
[not]<br />
[filter]<br />
[/filter]<br />
[/not]<br />
<br />
[filter_adjacent_location]<br />
x,y=$x2,$y2<br />
adjacent=-$knockback_direction<br />
[/filter_adjacent_location]<br />
<br />
variable=knockback_target_hex<br />
[/store_locations]<br />
<br />
[if]<br />
[variable]<br />
name=knockback_target_hex.length<br />
greater_than=0<br />
[/variable]<br />
<br />
[then]<br />
[teleport]<br />
[filter]<br />
x,y=$x2,$y2<br />
[/filter]<br />
<br />
x,y=$knockback_target_hex.x,$knockback_target_hex.y<br />
ignore_passability=no<br />
[/teleport]<br />
<br />
[if]<br />
[have_unit]<br />
x,y=$knockback_target_hex.x,$knockback_target_hex.y<br />
[/have_unit]<br />
<br />
[then]<br />
[sound]<br />
name=fist.ogg<br />
[/sound]<br />
<br />
# the knockbacked unit doesn't seem to receive experience by default,<br />
# so we need to add it manually<br />
[store_unit]<br />
[filter]<br />
x,y=$knockback_target_hex.x,$knockback_target_hex.y<br />
[/filter]<br />
<br />
kill=yes<br />
variable=knockbacked<br />
[/store_unit]<br />
<br />
{VARIABLE_OP knockbacked.experience add $unit.level}<br />
<br />
[unstore_unit]<br />
variable=knockbacked<br />
text= _ "knockback"<br />
{COLOR_HARM}<br />
advance=true<br />
[/unstore_unit]<br />
<br />
{CLEAR_VARIABLE knockbacked}<br />
[/then]<br />
[/if]<br />
[/then]<br />
[/if]<br />
<br />
{CLEAR_VARIABLE knockback_direction,knockback_target_hex}<br />
[/then]<br />
[/if]<br />
[/event]<br />
<br />
<br />
=== Charm ===<br />
<br />
When a unit is hit with a ''charm'' attack, it instantly jumps to the attacker's side, and returns to it's original side at the beginning of that side's turn. A charmed unit has 1 movement point and can attack.<br />
<br />
Example that makes all Troll Whelps have charm on their attack:<br />
<br />
{CHARM (type=Troll Whelp) fist}<br />
<br />
#define CHARM FILTER WEAPON<br />
[event]<br />
name=attacker_hits<br />
first_time_only=no<br />
<br />
[filter]<br />
{FILTER}<br />
[/filter]<br />
<br />
[special_filter]<br />
weapon={WEAPON}<br />
[/special_filter]<br />
<br />
{STORE_UNIT_VAR x,y=$x1,$y1 side charmer_side}<br />
{STORE_UNIT_VAR x,y=$x2,$y2 side charmed_side}<br />
<br />
{IF_VAR charmer_side not_equals $charmed_side (<br />
[then]<br />
{MODIFY_UNIT x,y=$x2,$y2 variables.real_side $charmed_side}<br />
{MODIFY_UNIT x,y=$x2,$y2 side $charmer_side}<br />
{MODIFY_UNIT x,y=$x2,$y2 moves 1}<br />
{MODIFY_UNIT x,y=$x2,$y2 attacks_left 1}<br />
<br />
{VARIABLE_OP varname format "side_$charmed_side|_units_charmed"}<br />
{VARIABLE $varname yes}<br />
<br />
{CLEAR_VARIABLE varname}<br />
[/then]<br />
)}<br />
<br />
{CLEAR_VARIABLE charmer_side}<br />
{CLEAR_VARIABLE charmed_side}<br />
[/event]<br />
<br />
[event]<br />
name=side turn<br />
first_time_only=no<br />
<br />
{VARIABLE_OP this_side_charmed to_variable "side_$side_number|_units_charmed"}<br />
<br />
{IF_VAR this_side_charmed equals yes (<br />
[then]<br />
[store_unit]<br />
[filter]<br />
[not]<br />
side=$side_number<br />
[/not]<br />
[/filter]<br />
<br />
variable=possibly_charmed<br />
kill=no<br />
[/store_unit]<br />
<br />
{FOREACH possibly_charmed i}<br />
{VARIABLE_OP real_side format "0$possibly_charmed[$i].variables.real_side"}<br />
<br />
{IF_VAR real_side not_equals "0" (<br />
[then]<br />
{IF_VAR side_number equals $possibly_charmed[$i].variables.real_side (<br />
[then]<br />
{CLEAR_VARIABLE possibly_charmed[$i].variables.real_side}<br />
{VARIABLE possibly_charmed[$i].side $side_number}<br />
<br />
[unstore_unit]<br />
variable=possibly_charmed[$i]<br />
find_vacant=no<br />
[/unstore_unit]<br />
[/then]<br />
)}<br />
[/then]<br />
)}<br />
{NEXT i}<br />
<br />
{CLEAR_VARIABLE possibly_charmed}<br />
[/then]<br />
)}<br />
[/event]<br />
#enddef<br />
<br />
=== Bloodlust ===<br />
<br />
Bloodlust is a very simple ability. If a unit that has bloodlust kills an enemy unit when attacking, it may attack again, provided that there are more enemy units adjacent to it.<br />
<br />
This would give the bloodlust ability to all Dwarvish Ulfserkers (making them insanely powerful):<br />
<br />
{BLOODLUST (type=Dwarvish Ulfserker)}<br />
<br />
#define BLOODLUST FILTER<br />
[event]<br />
name=die<br />
first_time_only=no<br />
<br />
[filter_second]<br />
{FILTER}<br />
[/filter_second]<br />
<br />
{MODIFY_UNIT x,y=$x2,$y2 moves 0}<br />
{MODIFY_UNIT x,y=$x2,$y2 attacks_left 1}<br />
[/event]<br />
#enddef<br />
<br />
=== Pickpocket ===<br />
<br />
This special could also be called loot. When a unit with this attack special sucessfully hits an enemy unit, it gains a certain amount of gold.<br />
<br />
To do this, use this code:<br />
<br />
<code>#define WEAPON_SPECIAL_PICKPOCKET<br /><br />
# Canned definition of the pickpocket ability to be included in a<br /><br />
# [specials] clause.<br />
# dummy weapon special used to describe the effect to the user<br />
# and filter on special's id<br />
[dummy]<br />
id=weapon_pickpocket<br />
name= _ "pickpocket"<br />
name_inactive= _ "pickpocket"<br />
description= _ "pickpocket :<br />
Gain money for attacking your foe. Each strike scores you one gold."<br />
description_inactive= _ "pickpocket :<br />
Gain money for attacking your foe. Each strike scores you one gold."<br />
apply_to=opponent<br />
[/dummy]<br />
[/specials]<br />
[/attack]<br />
# event that creates a "pickpocket has worked" variable<br />
# and sets it to "yes" if the attacker hits at least once.<br />
[event]<br />
name=attacker_hits<br />
first_time_only=no <br />
[filter_attack]<br />
special=weapon_pickpocket<br />
[/filter_attack] <br />
[store_unit]<br />
[filter]<br />
x,y=$x1,$y1<br />
[/filter]<br />
variable=unit_att_with_pickpocket<br />
mode=append<br />
[/store_unit]<br />
[set_variable]<br />
name=unit_att_with_pickpocket.variables.pickpocket_has_worked<br />
value=yes<br />
[/set_variable]<br />
[unstore_unit]<br />
variable=unit_att_with_pickpocket<br />
[/unstore_unit] <br />
{CLEAR_VARIABLE unit_att_with_pickpocket}<br />
[/event]<br />
[event]<br />
name=attacker_hits<br />
first_time_only=no <br />
[filter_attack]<br />
special=weapon_pickpocket<br />
[/filter_attack] <br />
[store_unit]<br />
[filter]<br />
x,y=$x1,$y1<br />
[/filter]<br />
variable=pickpocketer<br />
mode=append<br />
[/store_unit] <br />
[store_unit]<br />
[filter]<br />
x,y=$x2,$y2<br />
[/filter]<br />
variable=pickpocketed<br />
mode=append<br />
[/store_unit] <br />
[if]<br />
[variable]<br />
name=pickpocketer.variables.pickpocket_has_worked<br />
equals=yes<br />
[/variable]<br />
[then]<br />
[gold]<br />
side=$side_number<br />
amount=2<br />
[/gold]<br />
[unstore_unit]<br />
variable=pickpocketed<br />
text="!"<br />
{COLOR_HEAL}<br />
[/unstore_unit]<br />
[/then]<br />
[/if] <br />
{CLEAR_VARIABLE pickpocketer}<br />
{CLEAR_VARIABLE pickpocketed}<br />
[/event]<br />
[+attack]<br />
[+specials]<br />
#enddef</code><br />
<br />
It can be placed after the [unit_type] tag, or in its own .cfg file.<br />
<br />
<br />
<br />
<br />
To change the amount of gold given per hit, change<br />
<code>[gold]<br />
side=$side_number<br />
amount='''X'''<br />
[/gold]</code><br />
Where '''X''' is the amount of gold you want.<br />
<br />
<br />
<br />
<br />
If you want the gold to be constant, given at the end of the turn if at least one of the attack hits, instead of '''X''' amount of gold per hit, change<br />
<code>[event]<br />
'''name=attacker_hits'''<br />
first_time_only=no</code><br />
<br />
to<br />
<br />
<code>[event]<br />
'''name=attack_end'''<br />
first_time_only=no</code><br />
<br />
===Soultaker===<br />
<br />
Any unit with this ability will gain an additional point of damage per strike every time it kills an enemy. Coder(s) unknown, made for Melon's Youkai faction (http://www.wesnoth.org/forum/viewtopic.php?f=19&t=20100).<br />
<br />
To give a unit the ability, place the following in any .cfg file loaded by the campaign or era:<br />
<br />
#define ABILITY_SOULTAKER<br />
[dummy]<br />
id=soultaker<br />
name= _ "soultaker"<br />
description=_ "Soultaker:<br />
This unit gains an additional point added to its maximum damage whenever it kills a living unit."<br />
[/dummy]<br />
<br />
[/abilities]<br />
[event]<br />
name=die<br />
first_time_only=no<br />
[filter]<br />
[not]<br />
[wml_filter]<br />
[status]<br />
not_living="yes"<br />
[/status]<br />
[/wml_filter]<br />
[/not]<br />
[/filter]<br />
<br />
[filter_second]<br />
ability=soultaker<br />
[/filter_second]<br />
<br />
[unstore_unit]<br />
variable=second_unit<br />
{COLOR_HEAL}<br />
text= _ "+1 damage"<br />
find_vacant=no<br />
[/unstore_unit]<br />
<br />
[object]<br />
silent=yes<br />
duration=forever<br />
[filter]<br />
x,y=$x2,$y2<br />
[/filter]<br />
<br />
[effect]<br />
apply_to=attack<br />
range=melee<br />
increase_damage=1<br />
increase=1<br />
[/effect]<br />
[/object]<br />
[/event]<br />
<br />
[+abilities]<br />
#enddef<br />
<br />
And the following in the unit's [abilities] tag:<br />
<br />
{ABILITY_SOULTAKER}<br />
<br />
===Charm (Type 2)===<br />
<br />
An attack special. If the attack hits, and the target is level 0 or 1, the target is converted to the attacker's side. However, if it misses, the attacker is converted to the defender's side. Maintainer is krotop, using 1.6.x syntax (and compatible with 1.7.x], made for Melon's Youkai faction (http://www.wesnoth.org/forum/viewtopic.php?f=21&t=22539)<br />
<br />
<br />
#define WEAPON_SPECIAL_CHARM<br />
# Canned definition of the Charm ability to be included in a<br />
# [specials] clause.<br />
<br />
<br />
# dummy weapon special used to describe the effect to the user<br />
# and filter on special's id<br />
[dummy]<br />
id=weapon_charm<br />
name= _ "charm"<br />
name_inactive= _ "charm"<br />
description= _ "Charm : <br />
Turns a living level 1 or level 0 unit to your side. Beware if all of your attacks miss, the charm user turns to the defender side, even if it is your leader. You can not charm an ennemy leader or a non-living creature." <br />
description_inactive= _ "Charm : <br />
Turns a living level 1 or level 0 unit to your side. Beware if all of your attacks miss, the charm user turns to the defender side, even if it is your leader. You can not charm an ennemy leader or a non-living creature." <br />
apply_to=opponent<br />
[/dummy]<br />
<br />
[/specials]<br />
[/attack]<br />
<br />
# event that creates a variable at the beginning of the fight to check if the attacker hit at least once by the end.<br />
[event]<br />
name=attack<br />
first_time_only=no<br />
<br />
[filter_attack]<br />
special=weapon_charm<br />
[/filter_attack]<br />
<br />
[store_unit]<br />
[filter]<br />
x,y=$x1,$y1<br />
[/filter]<br />
variable=unit_att_with_charm<br />
mode=append<br />
[/store_unit] <br />
[set_variable]<br />
name=unit_att_with_charm.variables.charm_has_worked<br />
value=no<br />
[/set_variable] <br />
[unstore_unit]<br />
variable=unit_att_with_charm<br />
[/unstore_unit]<br />
<br />
{CLEAR_VARIABLE unit_att_with_charm}<br />
[/event]<br />
<br />
<br />
# event that creates a "charm has worked" variable<br />
# and sets it to "yes" if the attacker hits at least once.<br />
[event]<br />
name=attacker_hits<br />
first_time_only=no<br />
<br />
[filter_attack]<br />
special=weapon_charm<br />
[/filter_attack]<br />
<br />
[store_unit]<br />
[filter]<br />
x,y=$x1,$y1<br />
[/filter]<br />
variable=unit_att_with_charm<br />
mode=append<br />
[/store_unit]<br />
[set_variable]<br />
name=unit_att_with_charm.variables.charm_has_worked<br />
value=yes<br />
[/set_variable]<br />
[unstore_unit]<br />
variable=unit_att_with_charm<br />
[/unstore_unit]<br />
<br />
{CLEAR_VARIABLE unit_att_with_charm}<br />
[/event]<br />
<br />
<br />
# event that shifts a unit to the other side<br />
# if the defending unit<br />
# - was not lvl1 or lvl0 <br />
# - and was not a recruiting unit <br />
# - and was a not a "non-living" creature<br />
# then :<br />
# -> if the attacker missed all attacks, it goes to the defender side.<br />
# -> if the attacker hit once at least, the defender goes to the attacker side.<br />
[event]<br />
name=attack_end<br />
first_time_only=no<br />
<br />
[filter_attack]<br />
special=weapon_charm<br />
[/filter_attack]<br />
[filter_second]<br />
canrecruit=no<br />
[and]<br />
level=0<br />
[or]<br />
level=1<br />
[/or]<br />
[/and]<br />
[and]<br />
[not]<br />
[filter_wml]<br />
[status]<br />
not_living=yes<br />
[/status]<br />
[/filter_wml]<br />
[/not]<br />
[/and]<br />
[/filter_second]<br />
<br />
[store_unit]<br />
[filter]<br />
x,y=$x1,$y1<br />
[/filter]<br />
variable=charmer<br />
mode=append<br />
[/store_unit]<br />
<br />
[store_unit]<br />
[filter]<br />
x,y=$x2,$y2<br />
[/filter]<br />
variable=charmed<br />
mode=append<br />
[/store_unit]<br />
<br />
[if]<br />
[variable]<br />
name=charmer.variables.charm_has_worked<br />
equals=no<br />
[/variable]<br />
[then]<br />
[set_variable]<br />
name=charmer.side<br />
value=$charmed.side<br />
[/set_variable]<br />
[unstore_unit]<br />
variable=charmer<br />
text="Charm failed!"<br />
{COLOR_HARM}<br />
[/unstore_unit]<br />
[/then]<br />
[else]<br />
[set_variable]<br />
name=charmed.side<br />
value=$charmer.side<br />
[/set_variable]<br />
[unstore_unit]<br />
variable=charmed<br />
text="Charmed!"<br />
{COLOR_HEAL}<br />
[/unstore_unit]<br />
[/else]<br />
[/if]<br />
<br />
{CLEAR_VARIABLE charmer}<br />
{CLEAR_VARIABLE charmed}<br />
[/event]<br />
<br />
[+attack]<br />
[+specials]<br />
<br />
#enddef<br />
<br />
== Works ==<br />
<br />
Unit with ability ''works'' will produce 1 gold per turn.<br />
<br />
Put this macro into you code before the last piece of code.<br />
<pre><br />
#define ABILITY_WORKS<br />
[leadership]<br />
value=0<br />
id=peasant_works<br />
cumulative=no<br />
name="works"<br />
description= _ "Works:<br />
This unit produces 1 gold per turn."<br />
[/leadership]<br />
#enddef<br />
</pre><br />
<br />
Put this event into your code.<br />
<pre><br />
[event]<br />
name=side turn<br />
first_time_only=no<br />
[store_unit]<br />
[filter]<br />
#your filter here... for example type=Peasant<br />
[/filter]<br />
variable=worker<br />
kill=no<br />
[/store_unit]<br />
<br />
{FOREACH worker i}<br />
<br />
[gold]<br />
side=$side_number <br />
amount=1<br />
[/gold] <br />
[unstore_unit]<br />
variable=worker[$i]<br />
text="1"<br />
red,green,blue=255,255,0 <br />
[/unstore_unit]<br />
<br />
{NEXT i}<br />
<br />
{CLEAR_VARIABLE worker}<br />
[/event]<br />
</pre><br />
<br />
And give the unit the ability like this<br />
<pre><br />
[object]<br />
silent=yes<br />
[effect]<br />
apply_to=new_ability<br />
[abilities]<br />
{ABILITY_WORKS}<br />
[/abilities]<br />
[/effect]<br />
[/object]<br />
</pre><br />
<br />
<br />
== Mind Flay ==<br />
<br />
The weapon special gives an attacker 1 point of exp taken from a defender for each hit. This will violate minimum experience (i.e. defender can go below 0). <br />
<br />
Give this special to the attack(s) you want it to have. <br />
#define WEAPON_SPECIAL_MIND_FLAY<br />
[mindflay]<br />
id=mind_flay<br />
name="Mind Flay"<br />
description="When used offensively, each hit of the mind flay attack takes 1 point of experience from the defender and gives it to the attacker."<br />
[/mindflay]<br />
#enddef<br />
<br />
Include these events into your scenario.<br />
[event]<br />
name=attack<br />
first_time_only=no<br />
[special_filter]<br />
weapon=mind flay<br />
[/special_filter]<br />
{VARIABLE hit_number 0}<br />
[/event]<br />
[event]<br />
name=attacker_hits<br />
first_time_only=no<br />
[special_filter]<br />
weapon=mind flay<br />
[/special_filter]<br />
{VARIABLE_OP hit_number add 1}<br />
[/event]<br />
[event]<br />
name=attack_end<br />
first_time_only=no<br />
[special_filter]<br />
weapon=mind flay<br />
[/special_filter]<br />
{VARIABLE_OP second_unit.experience add -$hit_number}<br />
{VARIABLE_OP unit.experience add $hit_number}<br />
[unstore_unit]<br />
variable=unit<br />
find_vacant=no<br />
text=$hit_number<br />
blue=255<br />
[/unstore_unit]<br />
[unstore_unit]<br />
variable=second_unit<br />
find_vacant=no<br />
[/unstore_unit]<br />
{CLEAR_VARIABLE hit_number}<br />
[/event]<br />
<br />
Note: In dev version substitute "name=" instead of "weapon=".<br />
<br />
== Initiative ==<br />
<br />
Initiative is an aura ability. Much like Leadership, it effects adjacent allies but not the unit itself.<br />
<br />
#define AURA_INITIATIVE TYPE<br />
[dummy]<br />
id=initiative<br />
name= _ "initiative"<br />
description= _ "Initiative:<br />
Adjacent allies are granted Firststrike with all weapons."<br />
[/dummy]<br />
[/abilities]<br />
[event]<br />
name=attack<br />
first_time_only=no<br />
<br />
[filter]<br />
[filter_adjacent]<br />
type={TYPE}<br />
is_enemy=no<br />
[/filter_adjacent]<br />
[/filter]<br />
<br />
{FOREACH unit.attack i}<br />
{VARIABLE unit.attack[$i].specials.firststrike.id "firststrike"}<br />
{NEXT i}<br />
<br />
[unstore_unit]<br />
variable=unit<br />
[/unstore_unit]<br />
[/event]<br />
[event]<br />
name=attack<br />
first_time_only=no<br />
<br />
[filter_second]<br />
[filter_adjacent]<br />
type={TYPE}<br />
is_enemy=no<br />
[/filter_adjacent]<br />
[/filter_second]<br />
<br />
{FOREACH second_unit.attack i}<br />
{VARIABLE second_unit.attack[$i].specials.firststrike.id "firststrike"}<br />
{NEXT i}<br />
<br />
[unstore_unit]<br />
variable=second_unit<br />
[/unstore_unit]<br />
[/event]<br />
[event]<br />
name=attack_end<br />
first_time_only=no<br />
<br />
[filter]<br />
[wml_filter]<br />
[attack]<br />
[specials]<br />
[firststrike]<br />
id=firststrike<br />
[/firststrike]<br />
[/specials]<br />
[/attack]<br />
[/wml_filter]<br />
[/filter]<br />
<br />
{FOREACH unit.attack i}<br />
{CLEAR_VARIABLE unit.attack[$i].specials.firststrike}<br />
{NEXT i}<br />
<br />
[unstore_unit]<br />
variable=unit<br />
[/unstore_unit]<br />
[/event]<br />
[event]<br />
name=attack_end<br />
first_time_only=no<br />
<br />
[filter_second]<br />
[wml_filter]<br />
[attack]<br />
[specials]<br />
[firststrike]<br />
id=firststrike<br />
[/firststrike]<br />
[/specials]<br />
[/attack]<br />
[/wml_filter]<br />
[/filter_second]<br />
<br />
{FOREACH second_unit.attack i}<br />
{CLEAR_VARIABLE second_unit.attack[$i].specials.firststrike}<br />
{NEXT i}<br />
<br />
[unstore_unit]<br />
variable=second_unit<br />
[/unstore_unit]<br />
[/event]<br />
[+abilities]<br />
#enddef<br />
<br />
A WML filter may be added instead of the type if you want some units of that type to not have the ability.<br />
<br />
== Blitz ==<br />
<br />
Blitz is an aura ability. Much like Leadership, it effects adjacent allies but not the unit itself.<br />
<br />
#define AURA_BLITZ TYPE<br />
[dummy]<br />
id=blitz <br />
name= _ "blitz"<br />
description= _ "Blitz:<br />
Allies that start their turn adjacent to this unit are granted Skirmisher for that turn."<br />
[/dummy]<br />
[/abilities]<br />
[event]<br />
name=side turn<br />
first_time_only=no<br />
<br />
[store_unit]<br />
[filter]<br />
<br />
[wml_filter]<br />
blitzed=1<br />
[/wml_filter]<br />
[/filter]<br />
variable=blitz_refresh<br />
[/store_unit]<br />
<br />
{FOREACH blitz_refresh i}<br />
{CLEAR_VARIABLE blitz_refresh[$i].abilities.skirmisher}<br />
{VARIABLE blitz_refresh[$i].blitzed 0}<br />
[unstore_unit]<br />
variable=blitz_refresh[$i]<br />
[/unstore_unit]<br />
{NEXT i}<br />
<br />
[store_unit]<br />
[filter]<br />
side=$side_number<br />
[filter_adjacent]<br />
type={TYPE}<br />
is_enemy=no<br />
[/filter_adjacent]<br />
[/filter]<br />
variable=blitzed<br />
[/store_unit]<br />
<br />
{FOREACH blitzed i}<br />
[if]<br />
[variable]<br />
name=blitzed[$i].abilities.skirmisher.id<br />
not_equals="skirmisher"<br />
[/variable]<br />
[then]<br />
{VARIABLE blitzed[$i].blitzed 1}<br />
{VARIABLE blitzed[$i].abilities.skirmisher.id skirmisher}<br />
{VARIABLE blitzed[$i].abilities.skirmisher.name "skirmisher"}<br />
{VARIABLE blitzed[$i].abilities.skirmisher.description "Skirmisher:<br />
This unit is skilled in moving past enemies quickly, and ignores all enemy Zones of Control."}<br />
[unstore_unit]<br />
variable=blitzed[$i]<br />
[/unstore_unit]<br />
[/then]<br />
[/if]<br />
{NEXT i}<br />
[/event]<br />
[+abilities]<br />
#enddef<br />
<br />
A WML filter may be added instead of the type if you want some units of that type to not have the ability.<br />
<br />
== See Also ==<br />
<br />
* [[UsefulWMLFragments]]<br />
* [[ReferenceWML]]<br />
<br />
[[Category: UsefulWMLFragments]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=WML_Abilities&diff=40221WML Abilities2011-01-24T11:32:09Z<p>Paŭlo: /* Initiative */ Leadership => firststrike</p>
<hr />
<div>Remember that you must include the WML ability code in every scenario where you intend them to work. Or include them in the unit file inside the [unit_type] tag.<br />
<br />
Some abilities require macros from [[WML_Utilities|Utilities]]. <br />
<br />
<br />
<br />
=== Knockback ===<br />
<br />
When a unit is hit with a knockback attack, it is immediately pushed back one hex away from the attacker. Units cannot be knocked back into an occupied hex, out of villages or onto terrain they normally could not move to. Only works on offense.<br />
<br />
Use this to display the special correctly on the attacks you want:<br />
#define WEAPON_SPECIAL_KNOCKBACK<br />
[dummy]<br />
id=knockback<br />
name= _ "knockback"<br />
female_name= _ "female^knockback"<br />
description=_ "Knockback:<br />
When a unit is hit with a knockback attack, it is immediately pushed back one hex away from the attacker. Units cannot be knocked back into an occupied hex, out of villages or onto terrain they normally could not move to. Only works on offense."<br />
[/dummy]<br />
#enddef<br />
<br />
And insert this event to your [scenario], [multiplayer], [unit_type] or [era]:<br />
[event]<br />
name=attacker hits<br />
first_time_only=no<br />
<br />
[filter_attack]<br />
special=knockback<br />
[/filter_attack]<br />
<br />
[filter_second]<br />
[not]<br />
[filter_location]<br />
terrain=*^V*<br />
[/filter_location]<br />
[/not]<br />
[/filter_second]<br />
<br />
[if]<br />
[variable]<br />
name=second_unit.hitpoints<br />
greater_than=0<br />
[/variable]<br />
<br />
[then]<br />
[if]<br />
[have_unit]<br />
x,y=$x1,$y1<br />
[filter_adjacent]<br />
x,y=$x2,$y2<br />
adjacent=n<br />
[/filter_adjacent]<br />
[/have_unit]<br />
[then]<br />
{VARIABLE knockback_direction n}<br />
[/then]<br />
[else]<br />
[if]<br />
[have_unit]<br />
x,y=$x1,$y1<br />
[filter_adjacent]<br />
x,y=$x2,$y2<br />
adjacent=ne<br />
[/filter_adjacent]<br />
[/have_unit]<br />
[then]<br />
{VARIABLE knockback_direction ne}<br />
[/then]<br />
[else]<br />
[if]<br />
[have_unit]<br />
x,y=$x1,$y1<br />
[filter_adjacent]<br />
x,y=$x2,$y2<br />
adjacent=se<br />
[/filter_adjacent]<br />
[/have_unit]<br />
[then]<br />
{VARIABLE knockback_direction se}<br />
[/then]<br />
[else]<br />
[if]<br />
[have_unit]<br />
x,y=$x1,$y1<br />
[filter_adjacent]<br />
x,y=$x2,$y2<br />
adjacent=s<br />
[/filter_adjacent]<br />
[/have_unit]<br />
[then]<br />
{VARIABLE knockback_direction s}<br />
[/then]<br />
[else]<br />
[if]<br />
[have_unit]<br />
x,y=$x1,$y1<br />
[filter_adjacent]<br />
x,y=$x2,$y2<br />
adjacent=sw<br />
[/filter_adjacent]<br />
[/have_unit]<br />
[then]<br />
{VARIABLE knockback_direction sw}<br />
[/then]<br />
[else]<br />
[if]<br />
[have_unit]<br />
x,y=$x1,$y1<br />
[filter_adjacent]<br />
x,y=$x2,$y2<br />
adjacent=nw<br />
[/filter_adjacent]<br />
[/have_unit]<br />
[then]<br />
{VARIABLE knockback_direction nw}<br />
[/then]<br />
[/if]<br />
[/else]<br />
[/if]<br />
[/else]<br />
[/if]<br />
[/else]<br />
[/if]<br />
[/else]<br />
[/if]<br />
[/else]<br />
[/if]<br />
<br />
[store_locations]<br />
[not]<br />
[filter]<br />
[/filter]<br />
[/not]<br />
<br />
[filter_adjacent_location]<br />
x,y=$x2,$y2<br />
adjacent=-$knockback_direction<br />
[/filter_adjacent_location]<br />
<br />
variable=knockback_target_hex<br />
[/store_locations]<br />
<br />
[if]<br />
[variable]<br />
name=knockback_target_hex.length<br />
greater_than=0<br />
[/variable]<br />
<br />
[then]<br />
[teleport]<br />
[filter]<br />
x,y=$x2,$y2<br />
[/filter]<br />
<br />
x,y=$knockback_target_hex.x,$knockback_target_hex.y<br />
ignore_passability=no<br />
[/teleport]<br />
<br />
[if]<br />
[have_unit]<br />
x,y=$knockback_target_hex.x,$knockback_target_hex.y<br />
[/have_unit]<br />
<br />
[then]<br />
[sound]<br />
name=fist.ogg<br />
[/sound]<br />
<br />
# the knockbacked unit doesn't seem to receive experience by default,<br />
# so we need to add it manually<br />
[store_unit]<br />
[filter]<br />
x,y=$knockback_target_hex.x,$knockback_target_hex.y<br />
[/filter]<br />
<br />
kill=yes<br />
variable=knockbacked<br />
[/store_unit]<br />
<br />
{VARIABLE_OP knockbacked.experience add $unit.level}<br />
<br />
[unstore_unit]<br />
variable=knockbacked<br />
text= _ "knockback"<br />
{COLOR_HARM}<br />
advance=true<br />
[/unstore_unit]<br />
<br />
{CLEAR_VARIABLE knockbacked}<br />
[/then]<br />
[/if]<br />
[/then]<br />
[/if]<br />
<br />
{CLEAR_VARIABLE knockback_direction,knockback_target_hex}<br />
[/then]<br />
[/if]<br />
[/event]<br />
<br />
<br />
=== Charm ===<br />
<br />
When a unit is hit with a ''charm'' attack, it instantly jumps to the attacker's side, and returns to it's original side at the beginning of that side's turn. A charmed unit has 1 movement point and can attack.<br />
<br />
Example that makes all Troll Whelps have charm on their attack:<br />
<br />
{CHARM (type=Troll Whelp) fist}<br />
<br />
#define CHARM FILTER WEAPON<br />
[event]<br />
name=attacker_hits<br />
first_time_only=no<br />
<br />
[filter]<br />
{FILTER}<br />
[/filter]<br />
<br />
[special_filter]<br />
weapon={WEAPON}<br />
[/special_filter]<br />
<br />
{STORE_UNIT_VAR x,y=$x1,$y1 side charmer_side}<br />
{STORE_UNIT_VAR x,y=$x2,$y2 side charmed_side}<br />
<br />
{IF_VAR charmer_side not_equals $charmed_side (<br />
[then]<br />
{MODIFY_UNIT x,y=$x2,$y2 variables.real_side $charmed_side}<br />
{MODIFY_UNIT x,y=$x2,$y2 side $charmer_side}<br />
{MODIFY_UNIT x,y=$x2,$y2 moves 1}<br />
{MODIFY_UNIT x,y=$x2,$y2 attacks_left 1}<br />
<br />
{VARIABLE_OP varname format "side_$charmed_side|_units_charmed"}<br />
{VARIABLE $varname yes}<br />
<br />
{CLEAR_VARIABLE varname}<br />
[/then]<br />
)}<br />
<br />
{CLEAR_VARIABLE charmer_side}<br />
{CLEAR_VARIABLE charmed_side}<br />
[/event]<br />
<br />
[event]<br />
name=side turn<br />
first_time_only=no<br />
<br />
{VARIABLE_OP this_side_charmed to_variable "side_$side_number|_units_charmed"}<br />
<br />
{IF_VAR this_side_charmed equals yes (<br />
[then]<br />
[store_unit]<br />
[filter]<br />
[not]<br />
side=$side_number<br />
[/not]<br />
[/filter]<br />
<br />
variable=possibly_charmed<br />
kill=no<br />
[/store_unit]<br />
<br />
{FOREACH possibly_charmed i}<br />
{VARIABLE_OP real_side format "0$possibly_charmed[$i].variables.real_side"}<br />
<br />
{IF_VAR real_side not_equals "0" (<br />
[then]<br />
{IF_VAR side_number equals $possibly_charmed[$i].variables.real_side (<br />
[then]<br />
{CLEAR_VARIABLE possibly_charmed[$i].variables.real_side}<br />
{VARIABLE possibly_charmed[$i].side $side_number}<br />
<br />
[unstore_unit]<br />
variable=possibly_charmed[$i]<br />
find_vacant=no<br />
[/unstore_unit]<br />
[/then]<br />
)}<br />
[/then]<br />
)}<br />
{NEXT i}<br />
<br />
{CLEAR_VARIABLE possibly_charmed}<br />
[/then]<br />
)}<br />
[/event]<br />
#enddef<br />
<br />
=== Bloodlust ===<br />
<br />
Bloodlust is a very simple ability. If a unit that has bloodlust kills an enemy unit when attacking, it may attack again, provided that there are more enemy units adjacent to it.<br />
<br />
This would give the bloodlust ability to all Dwarvish Ulfserkers (making them insanely powerful):<br />
<br />
{BLOODLUST (type=Dwarvish Ulfserker)}<br />
<br />
#define BLOODLUST FILTER<br />
[event]<br />
name=die<br />
first_time_only=no<br />
<br />
[filter_second]<br />
{FILTER}<br />
[/filter_second]<br />
<br />
{MODIFY_UNIT x,y=$x2,$y2 moves 0}<br />
{MODIFY_UNIT x,y=$x2,$y2 attacks_left 1}<br />
[/event]<br />
#enddef<br />
<br />
=== Pickpocket ===<br />
<br />
This special could also be called loot. When a unit with this attack special sucessfully hits an enemy unit, it gains a certain amount of gold.<br />
<br />
To do this, use this code:<br />
<br />
<code>#define WEAPON_SPECIAL_PICKPOCKET<br /><br />
# Canned definition of the pickpocket ability to be included in a<br /><br />
# [specials] clause.<br />
# dummy weapon special used to describe the effect to the user<br />
# and filter on special's id<br />
[dummy]<br />
id=weapon_pickpocket<br />
name= _ "pickpocket"<br />
name_inactive= _ "pickpocket"<br />
description= _ "pickpocket :<br />
Gain money for attacking your foe. Each strike scores you one gold."<br />
description_inactive= _ "pickpocket :<br />
Gain money for attacking your foe. Each strike scores you one gold."<br />
apply_to=opponent<br />
[/dummy]<br />
[/specials]<br />
[/attack]<br />
# event that creates a "pickpocket has worked" variable<br />
# and sets it to "yes" if the attacker hits at least once.<br />
[event]<br />
name=attacker_hits<br />
first_time_only=no <br />
[filter_attack]<br />
special=weapon_pickpocket<br />
[/filter_attack] <br />
[store_unit]<br />
[filter]<br />
x,y=$x1,$y1<br />
[/filter]<br />
variable=unit_att_with_pickpocket<br />
mode=append<br />
[/store_unit]<br />
[set_variable]<br />
name=unit_att_with_pickpocket.variables.pickpocket_has_worked<br />
value=yes<br />
[/set_variable]<br />
[unstore_unit]<br />
variable=unit_att_with_pickpocket<br />
[/unstore_unit] <br />
{CLEAR_VARIABLE unit_att_with_pickpocket}<br />
[/event]<br />
[event]<br />
name=attacker_hits<br />
first_time_only=no <br />
[filter_attack]<br />
special=weapon_pickpocket<br />
[/filter_attack] <br />
[store_unit]<br />
[filter]<br />
x,y=$x1,$y1<br />
[/filter]<br />
variable=pickpocketer<br />
mode=append<br />
[/store_unit] <br />
[store_unit]<br />
[filter]<br />
x,y=$x2,$y2<br />
[/filter]<br />
variable=pickpocketed<br />
mode=append<br />
[/store_unit] <br />
[if]<br />
[variable]<br />
name=pickpocketer.variables.pickpocket_has_worked<br />
equals=yes<br />
[/variable]<br />
[then]<br />
[gold]<br />
side=$side_number<br />
amount=2<br />
[/gold]<br />
[unstore_unit]<br />
variable=pickpocketed<br />
text="!"<br />
{COLOR_HEAL}<br />
[/unstore_unit]<br />
[/then]<br />
[/if] <br />
{CLEAR_VARIABLE pickpocketer}<br />
{CLEAR_VARIABLE pickpocketed}<br />
[/event]<br />
[+attack]<br />
[+specials]<br />
#enddef</code><br />
<br />
It can be placed after the [unit_type] tag, or in its own .cfg file.<br />
<br />
<br />
<br />
<br />
To change the amount of gold given per hit, change<br />
<code>[gold]<br />
side=$side_number<br />
amount='''X'''<br />
[/gold]</code><br />
Where '''X''' is the amount of gold you want.<br />
<br />
<br />
<br />
<br />
If you want the gold to be constant, given at the end of the turn if at least one of the attack hits, instead of '''X''' amount of gold per hit, change<br />
<code>[event]<br />
'''name=attacker_hits'''<br />
first_time_only=no</code><br />
<br />
to<br />
<br />
<code>[event]<br />
'''name=attack_end'''<br />
first_time_only=no</code><br />
<br />
===Soultaker===<br />
<br />
Any unit with this ability will gain an additional point of damage per strike every time it kills an enemy. Coder(s) unknown, made for Melon's Youkai faction (http://www.wesnoth.org/forum/viewtopic.php?f=19&t=20100).<br />
<br />
To give a unit the ability, place the following in any .cfg file loaded by the campaign or era:<br />
<br />
#define ABILITY_SOULTAKER<br />
[dummy]<br />
id=soultaker<br />
name= _ "soultaker"<br />
description=_ "Soultaker:<br />
This unit gains an additional point added to its maximum damage whenever it kills a living unit."<br />
[/dummy]<br />
<br />
[/abilities]<br />
[event]<br />
name=die<br />
first_time_only=no<br />
[filter]<br />
[not]<br />
[wml_filter]<br />
[status]<br />
not_living="yes"<br />
[/status]<br />
[/wml_filter]<br />
[/not]<br />
[/filter]<br />
<br />
[filter_second]<br />
ability=soultaker<br />
[/filter_second]<br />
<br />
[unstore_unit]<br />
variable=second_unit<br />
{COLOR_HEAL}<br />
text= _ "+1 damage"<br />
find_vacant=no<br />
[/unstore_unit]<br />
<br />
[object]<br />
silent=yes<br />
duration=forever<br />
[filter]<br />
x,y=$x2,$y2<br />
[/filter]<br />
<br />
[effect]<br />
apply_to=attack<br />
range=melee<br />
increase_damage=1<br />
increase=1<br />
[/effect]<br />
[/object]<br />
[/event]<br />
<br />
[+abilities]<br />
#enddef<br />
<br />
And the following in the unit's [abilities] tag:<br />
<br />
{ABILITY_SOULTAKER}<br />
<br />
===Charm (Type 2)===<br />
<br />
An attack special. If the attack hits, and the target is level 0 or 1, the target is converted to the attacker's side. However, if it misses, the attacker is converted to the defender's side. Maintainer is krotop, using 1.6.x syntax (and compatible with 1.7.x], made for Melon's Youkai faction (http://www.wesnoth.org/forum/viewtopic.php?f=21&t=22539)<br />
<br />
<br />
#define WEAPON_SPECIAL_CHARM<br />
# Canned definition of the Charm ability to be included in a<br />
# [specials] clause.<br />
<br />
<br />
# dummy weapon special used to describe the effect to the user<br />
# and filter on special's id<br />
[dummy]<br />
id=weapon_charm<br />
name= _ "charm"<br />
name_inactive= _ "charm"<br />
description= _ "Charm : <br />
Turns a living level 1 or level 0 unit to your side. Beware if all of your attacks miss, the charm user turns to the defender side, even if it is your leader. You can not charm an ennemy leader or a non-living creature." <br />
description_inactive= _ "Charm : <br />
Turns a living level 1 or level 0 unit to your side. Beware if all of your attacks miss, the charm user turns to the defender side, even if it is your leader. You can not charm an ennemy leader or a non-living creature." <br />
apply_to=opponent<br />
[/dummy]<br />
<br />
[/specials]<br />
[/attack]<br />
<br />
# event that creates a variable at the beginning of the fight to check if the attacker hit at least once by the end.<br />
[event]<br />
name=attack<br />
first_time_only=no<br />
<br />
[filter_attack]<br />
special=weapon_charm<br />
[/filter_attack]<br />
<br />
[store_unit]<br />
[filter]<br />
x,y=$x1,$y1<br />
[/filter]<br />
variable=unit_att_with_charm<br />
mode=append<br />
[/store_unit] <br />
[set_variable]<br />
name=unit_att_with_charm.variables.charm_has_worked<br />
value=no<br />
[/set_variable] <br />
[unstore_unit]<br />
variable=unit_att_with_charm<br />
[/unstore_unit]<br />
<br />
{CLEAR_VARIABLE unit_att_with_charm}<br />
[/event]<br />
<br />
<br />
# event that creates a "charm has worked" variable<br />
# and sets it to "yes" if the attacker hits at least once.<br />
[event]<br />
name=attacker_hits<br />
first_time_only=no<br />
<br />
[filter_attack]<br />
special=weapon_charm<br />
[/filter_attack]<br />
<br />
[store_unit]<br />
[filter]<br />
x,y=$x1,$y1<br />
[/filter]<br />
variable=unit_att_with_charm<br />
mode=append<br />
[/store_unit]<br />
[set_variable]<br />
name=unit_att_with_charm.variables.charm_has_worked<br />
value=yes<br />
[/set_variable]<br />
[unstore_unit]<br />
variable=unit_att_with_charm<br />
[/unstore_unit]<br />
<br />
{CLEAR_VARIABLE unit_att_with_charm}<br />
[/event]<br />
<br />
<br />
# event that shifts a unit to the other side<br />
# if the defending unit<br />
# - was not lvl1 or lvl0 <br />
# - and was not a recruiting unit <br />
# - and was a not a "non-living" creature<br />
# then :<br />
# -> if the attacker missed all attacks, it goes to the defender side.<br />
# -> if the attacker hit once at least, the defender goes to the attacker side.<br />
[event]<br />
name=attack_end<br />
first_time_only=no<br />
<br />
[filter_attack]<br />
special=weapon_charm<br />
[/filter_attack]<br />
[filter_second]<br />
canrecruit=no<br />
[and]<br />
level=0<br />
[or]<br />
level=1<br />
[/or]<br />
[/and]<br />
[and]<br />
[not]<br />
[filter_wml]<br />
[status]<br />
not_living=yes<br />
[/status]<br />
[/filter_wml]<br />
[/not]<br />
[/and]<br />
[/filter_second]<br />
<br />
[store_unit]<br />
[filter]<br />
x,y=$x1,$y1<br />
[/filter]<br />
variable=charmer<br />
mode=append<br />
[/store_unit]<br />
<br />
[store_unit]<br />
[filter]<br />
x,y=$x2,$y2<br />
[/filter]<br />
variable=charmed<br />
mode=append<br />
[/store_unit]<br />
<br />
[if]<br />
[variable]<br />
name=charmer.variables.charm_has_worked<br />
equals=no<br />
[/variable]<br />
[then]<br />
[set_variable]<br />
name=charmer.side<br />
value=$charmed.side<br />
[/set_variable]<br />
[unstore_unit]<br />
variable=charmer<br />
text="Charm failed!"<br />
{COLOR_HARM}<br />
[/unstore_unit]<br />
[/then]<br />
[else]<br />
[set_variable]<br />
name=charmed.side<br />
value=$charmer.side<br />
[/set_variable]<br />
[unstore_unit]<br />
variable=charmed<br />
text="Charmed!"<br />
{COLOR_HEAL}<br />
[/unstore_unit]<br />
[/else]<br />
[/if]<br />
<br />
{CLEAR_VARIABLE charmer}<br />
{CLEAR_VARIABLE charmed}<br />
[/event]<br />
<br />
[+attack]<br />
[+specials]<br />
<br />
#enddef<br />
<br />
== Works ==<br />
<br />
Unit with ability ''works'' will produce 1 gold per turn.<br />
<br />
Put this macro into you code before the last piece of code.<br />
<pre><br />
#define ABILITY_WORKS<br />
[leadership]<br />
value=0<br />
id=peasant_works<br />
cumulative=no<br />
name="works"<br />
description= _ "Works:<br />
This unit produces 1 gold per turn."<br />
[/leadership]<br />
#enddef<br />
</pre><br />
<br />
Put this event into your code.<br />
<pre><br />
[event]<br />
name=side turn<br />
first_time_only=no<br />
[store_unit]<br />
[filter]<br />
#your filter here... for example type=Peasant<br />
[/filter]<br />
variable=worker<br />
kill=no<br />
[/store_unit]<br />
<br />
{FOREACH worker i}<br />
<br />
[gold]<br />
side=$side_number <br />
amount=1<br />
[/gold] <br />
[unstore_unit]<br />
variable=worker[$i]<br />
text="1"<br />
red,green,blue=255,255,0 <br />
[/unstore_unit]<br />
<br />
{NEXT i}<br />
<br />
{CLEAR_VARIABLE worker}<br />
[/event]<br />
</pre><br />
<br />
And give the unit the ability like this<br />
<pre><br />
[object]<br />
silent=yes<br />
[effect]<br />
apply_to=new_ability<br />
[abilities]<br />
{ABILITY_WORKS}<br />
[/abilities]<br />
[/effect]<br />
[/object]<br />
</pre><br />
<br />
<br />
== Mind Flay ==<br />
<br />
The weapon special gives an attacker 1 point of exp taken from a defender for each hit. This will violate minimum experience (i.e. defender can go below 0). <br />
<br />
Give this special to the attack(s) you want it to have. <br />
#define WEAPON_SPECIAL_MIND_FLAY<br />
[mindflay]<br />
id=mind_flay<br />
name="Mind Flay"<br />
description="When used offensively, each hit of the mind flay attack takes 1 point of experience from the defender and gives it to the attacker."<br />
[/mindflay]<br />
#enddef<br />
<br />
Include these events into your scenario.<br />
[event]<br />
name=attack<br />
first_time_only=no<br />
[special_filter]<br />
weapon=mind flay<br />
[/special_filter]<br />
{VARIABLE hit_number 0}<br />
[/event]<br />
[event]<br />
name=attacker_hits<br />
first_time_only=no<br />
[special_filter]<br />
weapon=mind flay<br />
[/special_filter]<br />
{VARIABLE_OP hit_number add 1}<br />
[/event]<br />
[event]<br />
name=attack_end<br />
first_time_only=no<br />
[special_filter]<br />
weapon=mind flay<br />
[/special_filter]<br />
{VARIABLE_OP second_unit.experience add -$hit_number}<br />
{VARIABLE_OP unit.experience add $hit_number}<br />
[unstore_unit]<br />
variable=unit<br />
find_vacant=no<br />
text=$hit_number<br />
blue=255<br />
[/unstore_unit]<br />
[unstore_unit]<br />
variable=second_unit<br />
find_vacant=no<br />
[/unstore_unit]<br />
{CLEAR_VARIABLE hit_number}<br />
[/event]<br />
<br />
Note: In dev version substitute "name=" instead of "weapon=".<br />
<br />
== Initiative ==<br />
<br />
Initiative is an aura ability. Much like Firststrike, it effects adjacent allies but not the unit itself.<br />
<br />
#define AURA_INITIATIVE TYPE<br />
[dummy]<br />
id=initiative<br />
name= _ "initiative"<br />
description= _ "Initiative:<br />
Adjacent allies are granted Firststrike with all weapons."<br />
[/dummy]<br />
[/abilities]<br />
[event]<br />
name=attack<br />
first_time_only=no<br />
<br />
[filter]<br />
[filter_adjacent]<br />
type={TYPE}<br />
is_enemy=no<br />
[/filter_adjacent]<br />
[/filter]<br />
<br />
{FOREACH unit.attack i}<br />
{VARIABLE unit.attack[$i].specials.firststrike.id "firststrike"}<br />
{NEXT i}<br />
<br />
[unstore_unit]<br />
variable=unit<br />
[/unstore_unit]<br />
[/event]<br />
[event]<br />
name=attack<br />
first_time_only=no<br />
<br />
[filter_second]<br />
[filter_adjacent]<br />
type={TYPE}<br />
is_enemy=no<br />
[/filter_adjacent]<br />
[/filter_second]<br />
<br />
{FOREACH second_unit.attack i}<br />
{VARIABLE second_unit.attack[$i].specials.firststrike.id "firststrike"}<br />
{NEXT i}<br />
<br />
[unstore_unit]<br />
variable=second_unit<br />
[/unstore_unit]<br />
[/event]<br />
[event]<br />
name=attack_end<br />
first_time_only=no<br />
<br />
[filter]<br />
[wml_filter]<br />
[attack]<br />
[specials]<br />
[firststrike]<br />
id=firststrike<br />
[/firststrike]<br />
[/specials]<br />
[/attack]<br />
[/wml_filter]<br />
[/filter]<br />
<br />
{FOREACH unit.attack i}<br />
{CLEAR_VARIABLE unit.attack[$i].specials.firststrike}<br />
{NEXT i}<br />
<br />
[unstore_unit]<br />
variable=unit<br />
[/unstore_unit]<br />
[/event]<br />
[event]<br />
name=attack_end<br />
first_time_only=no<br />
<br />
[filter_second]<br />
[wml_filter]<br />
[attack]<br />
[specials]<br />
[firststrike]<br />
id=firststrike<br />
[/firststrike]<br />
[/specials]<br />
[/attack]<br />
[/wml_filter]<br />
[/filter_second]<br />
<br />
{FOREACH second_unit.attack i}<br />
{CLEAR_VARIABLE second_unit.attack[$i].specials.firststrike}<br />
{NEXT i}<br />
<br />
[unstore_unit]<br />
variable=second_unit<br />
[/unstore_unit]<br />
[/event]<br />
[+abilities]<br />
#enddef<br />
<br />
A WML filter may be added instead of the type if you want some units of that type to not have the ability.<br />
<br />
== Blitz ==<br />
<br />
Blitz is an aura ability. Much like Leadership, it effects adjacent allies but not the unit itself.<br />
<br />
#define AURA_BLITZ TYPE<br />
[dummy]<br />
id=blitz <br />
name= _ "blitz"<br />
description= _ "Blitz:<br />
Allies that start their turn adjacent to this unit are granted Skirmisher for that turn."<br />
[/dummy]<br />
[/abilities]<br />
[event]<br />
name=side turn<br />
first_time_only=no<br />
<br />
[store_unit]<br />
[filter]<br />
<br />
[wml_filter]<br />
blitzed=1<br />
[/wml_filter]<br />
[/filter]<br />
variable=blitz_refresh<br />
[/store_unit]<br />
<br />
{FOREACH blitz_refresh i}<br />
{CLEAR_VARIABLE blitz_refresh[$i].abilities.skirmisher}<br />
{VARIABLE blitz_refresh[$i].blitzed 0}<br />
[unstore_unit]<br />
variable=blitz_refresh[$i]<br />
[/unstore_unit]<br />
{NEXT i}<br />
<br />
[store_unit]<br />
[filter]<br />
side=$side_number<br />
[filter_adjacent]<br />
type={TYPE}<br />
is_enemy=no<br />
[/filter_adjacent]<br />
[/filter]<br />
variable=blitzed<br />
[/store_unit]<br />
<br />
{FOREACH blitzed i}<br />
[if]<br />
[variable]<br />
name=blitzed[$i].abilities.skirmisher.id<br />
not_equals="skirmisher"<br />
[/variable]<br />
[then]<br />
{VARIABLE blitzed[$i].blitzed 1}<br />
{VARIABLE blitzed[$i].abilities.skirmisher.id skirmisher}<br />
{VARIABLE blitzed[$i].abilities.skirmisher.name "skirmisher"}<br />
{VARIABLE blitzed[$i].abilities.skirmisher.description "Skirmisher:<br />
This unit is skilled in moving past enemies quickly, and ignores all enemy Zones of Control."}<br />
[unstore_unit]<br />
variable=blitzed[$i]<br />
[/unstore_unit]<br />
[/then]<br />
[/if]<br />
{NEXT i}<br />
[/event]<br />
[+abilities]<br />
#enddef<br />
<br />
A WML filter may be added instead of the type if you want some units of that type to not have the ability.<br />
<br />
== See Also ==<br />
<br />
* [[UsefulWMLFragments]]<br />
* [[ReferenceWML]]<br />
<br />
[[Category: UsefulWMLFragments]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=InternalActionsWML&diff=40184InternalActionsWML2011-01-19T16:41:06Z<p>Paŭlo: /* [store_unit] */ order of units (see http://forums.wesnoth.org/viewtopic.php?p=475434#p475434 )</p>
<hr />
<div>{{WML Tags}}<br />
<br />
Part of [[ActionWML]], Internal actions are actions that WML uses internally that do not directly affect game play (or, at least, are not readily apparent to the player). For example, storing a variable is an internal action.<br />
<br />
== Variable Actions ==<br />
<br />
These actions are focused, in one way or another, on [[VariablesWML|variables]]. Creating them, modifying them, capturing game data to them, you name it, these actions are all about the variables.<br />
<br />
=== [set_variable] ===<br />
<br />
The '''[set_variable]''' tag is used to create and manipulate WML variables. The [http://www.wesnoth.org/macro-reference.xhtml#VARIABLE VARIABLE] macro is a quick syntactic shortcut for simple variable creation and the [http://www.wesnoth.org/macro-reference.xhtml#VARIABLE_OP VARIABLE_OP] macro is a quick syntactic shortcut for performing simple mathematical operations on variables.<br />
<br />
* '''name''': the name of the variable to manipulate<br />
<br />
* '''value''': set the variable to the given value (can be numeric or string).Use literal for no substitution. (see [[VariablesWML]])<br />
<br />
* '''literal''': set the variable to the given value (can be numeric or string). This does not interpret any dollars signs.<br />
<br />
* '''format''': This attribute will be deprecated from 1.7 on. Same behaviour as value.<br />
<br />
* '''to_variable''': set the variable to the value of the given variable, e.g. 'to_variable=temp' would be equivalent to 'value=$temp'.<br />
<br />
* '''add''': add the given amount to the variable. To subtract, add a negative number.<br />
<br />
* '''sub''' {{DevFeature}}: subtract the given amount from the variable.<br />
<br />
* '''multiply''': multiply the variable by the given number. To divide, multiply by the inverse eg: 4/2 = 4 * 1/2 = 4 * 0.5. To negate, multiply by -1. Floating point values are not rounded.<br />
<br />
* '''divide''': divide the variable by the given number. The result is an integer. Floating point results are not rounded. If both variables are integers, [http://en.wikipedia.org/wiki/Division_(mathematics)#Division_of_integers Integer division] is used.<br />
<br />
* '''modulo''': returns the remainder of a division.<br />
<br />
* '''random''': the variable will be randomly set.<br>You may provide a comma separated list of possibilities, e.g. 'random=Bob,Bill,Bella'.<br>You may provide a range of numbers (integers), e.g. 'random=3..5'.<br>You may combine these, e.g. 'random=100,1..9', in which case there would be 1/10th chance of getting 100, just like for each of 1 to 9. {{DevFeature1.9}} random is deprecated, use rand instead.<br />
<br />
* '''rand''': does the same as random, but has better MP support. See [[BuildingMultiplayerExamples]] for more info on the MP case. '''It is highly recommended that you use this feature for randomization.'''<br />
<br />
* '''time=stamp''': Retrieves a timestamp in milliseconds since wesnoth was started, can be used as timing aid. Don't try to use this as random value in MP since it will cause an OOS.<br />
<br />
* '''string_length''': Retrieves the length in characters of the string passed as this attribute's value; such string is parsed and variable substitution applied automatically (see [[VariablesWML]] for details).<br />
<br />
* '''[join]''' joins an array of strings to create a textual list<br />
** '''variable''': name of the array<br />
** '''key''': the key of each array element(array[$i].foo) in which the strings are stored<br />
** '''separator''': separator to connect the elements<br />
** '''remove_empty''': whether to ignore empty elements<br />
<br />
* '''ipart''': Assigns the integer part (the part to the left of the comma) of the referenced variable.<br />
<br />
* '''fpart''': Assigns the decimal part (the part to the right of the comma) of the referenced variable.<br />
<br />
* '''round''': Rounds the variable to the specified number of digits of precision. Negative precision works as expected (rounding 19517 to -2 = 19500). Special values:<br />
**'''ceil''': Rounds upward to the nearest integer.<br />
**'''floor''': Rounds down to the nearest integer.<br />
<br />
=== [set_variables] ===<br />
<br />
Manipulates a WML array or container<br />
<br />
* '''name''': the name of the array or container to manipulate<br />
<br />
* '''mode''': one of the following values:<br />
** ''replace'': will clean the array '''name''' and replace it with given data<br />
** ''append'': will append given data to the current array<br />
** ''merge'': will merge in the given data into '''name'''<br />
** ''insert'': will insert the given data at the index specified in the '''name''' attribute, such as name=my_array[1]. The default index is zero, which will insert to the front of the array. '''Note:''' if an invalid index is used, empty containers will be created before the insertion is performed. In other words, do not attempt to insert at an index greater than (or equal to) the array's current length. This limitation may be removed in future versions.<br />
<br />
* '''to_variable''': data will be set to the given array<br />
<br />
* '''[value]''': the WML inside the [value] tags will be stored in data, variables will be interpolated directly, use $| in order to escape the $ sign, you can store arrays of WML by supplying multiple [value] tags. ([[#Using_.5Bset_variables.5D_to_Create_Arrays_of_WML|See Example]])<br />
<br />
* '''[literal]''': same as '''[value]''', but variables will not be substituted, '''[literal]''' and '''[value]''' can not be used in the same [set_variables] tag, i.e. you can not create arrays by piling a mix of '''[value]''' and '''[literal]''' tags<br />
<br />
*'''[split]''' splits a textual list into an array which will then be set to data<br />
** '''list''': textual list to split<br />
** '''key''': the key of each array element(array[$i].foo) in which the strings are stored<br />
** '''separator''': separator to separate the elements<br />
** '''remove_empty''': whether to ignore empty elements<br />
<br />
=== Capturing Game Data ===<br />
<br />
These actions capture different bits of game data and store them to variables so they can be examined and/or manipulated.<br />
<br />
==== [store_gold] ====<br />
<br />
Stores a side's gold into a variable.<br />
<br />
* '''side''': (default=1) the side for which the gold should be stored<br />
<br />
* '''variable''': (default='gold') the name of the variable to store the gold in<br />
<br />
==== [store_locations] ====<br />
<br />
Stores a series of locations that pass certain criteria into an array. Each member of the array has members 'x' and 'y' (the position) and 'terrain' (the terrain type) and 'owner_side' (villages only). The array will include any unreachable border hexes, if applicable.<br />
<br />
* [[StandardLocationFilter]]: a location or location range which specifies the locations to store. You must specify this or no locations will be stored.<br />
<br />
* '''variable''': the name of the variable (array) into which to store the locations.<br />
<br />
==== [store_reachable_locations] {{DevFeature1.9}} ====<br />
<br />
Stores locations reachable by the given units. Can store either the movement, attack or vision ranges.<br />
<br />
* '''[filter]''': a [[StandardUnitFilter]]. The locations reachable by any of the matching units will be stored.<br />
* '''[filter_location]''': (optional) a [[StandardLocationFilter]]. Only locations which also match this filter will be stored.<br />
* '''range''': possible values ''movement'' (default), ''attack'', ''vision''. If ''movement'', stores the locations within the movement range of the unit, taking Zone of Control into account. If ''attack'', stores the attack range (movement range + 1 hex). If ''vision'', stores the vision range (movement range ignoring Zone of Control + 1 hex).<br />
* '''moves''': possible values ''current'' (default), ''max''. Specifies whether to use the current or maximum movement points when calculating the range.<br />
* '''viewing_side''': (optional) the side whose vision to use when calculating the reach. This only has meaning in the presence of fog, shroud, or units with the ambush ability. If left out, then fog, shroud and ambushers are ignored and the real reach of the units is stored.<br />
* '''variable''': the name of the variable (array) into which to store the locations.<br />
<br />
==== [store_map_dimensions] ====<br />
<br />
Stores the map dimensions in a variable.<br />
<br />
* '''variable''': the name of the variable where the values will be saved into. If it is skipped, a variable 'map_size' is used, and its contents overridden, if they existed already. The result is a container variable, with members ''width'' and ''height''.<br />
<br />
==== [store_side] ====<br />
<br />
Stores information about a certain side in a variable. The variable will contain the member variables 'name', 'team_name', 'gold' and 'income', 'fog', 'shroud', 'hidden', 'user_team_name', 'colour' (becomes 'color' in 1.9+), 'controller', 'village_gold' and 'recruit'.<br />
<br />
* '''side''': the side whose information should be stored<br />
<br />
* '''variable''': the name of the variable to store the information in<br />
<br />
==== [store_starting_location] ====<br />
<br />
Stores the starting location of a side's leader in a variable. The variable is a composite type which will have members 'x', 'y', 'terrain' (the terrain type for a starting location is always 'K' unless it has been changed) and 'owner_side' (villages only)<br />
<br />
* '''side''': the side whose starting location is to be stored<br />
<br />
* '''variable''': (default='location'): the name of the variable to store the location in<br />
<br />
==== [store_time_of_day] ====<br />
<br />
Stores time of day information from the current scenario into a WML variable container.<br />
<br />
* '''variable''': (default='time_of_day') name of the container on which to store the information. The container will be filled with the same attributes found on [[TimeWML]].<br />
<br />
* '''turn''': (defaults to the current turn number) changes the turn number for which time of day information should be retrieved.<br />
<br />
==== [store_unit] ====<br />
<br />
Stores details about units into a [[VariablesWML#Container|container]] variable. When a unit is stored, all keys and tags in the unit definition may be manipulated, including some others, with [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]]. A sample list of these tags and keys can be found [[InternalActionsWMLUnitTags|here]]. If you have a doubt about what keys are valid or what the valid value range is for each key, code a [store_unit] event, save the game, and examine what keys are in the file (or just examine the '''[unit]''' tag(s) in any save file).<br />
<br />
Common usage is to manipulate a unit by using '''[store_unit]''' to store it into a variable, followed by manipulation of the variable, and then [[DirectActionsWML|[unstore_unit]]] to re-create the unit with the modified variables.<br />
<br />
''Note: stored units also exist on the field, and modifying the stored variable will not automatically change the stats of the units. You need to use [unstore_unit]. See also [[DirectActionsWML|[unstore_unit]]] and [http://www.wesnoth.org/macro-reference.xhtml#FOREACH FOREACH].''<br />
<br />
* '''[filter]''' with a [[StandardUnitFilter]] as argument. All units matching this filter will be stored. If there are multiple units, they will be stored into an array of variables. The units will be stored in order of their internal ''underlying_id'' attribute, which is usually in creation order (but you normally should not depend on the order).<br />
<br />
* '''variable''': the name of the variable into which to store the unit(s)<br />
<br />
* '''mode''': defaults to ''always_clear'', which clears the variable, whether or not a match is found. If mode is set to ''replace'', the variable will only be cleared if a match is found. If mode is set to ''append'', the variable will not be cleared.<br />
<br />
* '''kill''': if 'yes' the units that are stored will be removed from play. This is useful for instance to remove access to a player's recall list, with the intent to restore the recall list later.<br />
<br />
==== [store_villages] ====<br />
<br />
Stores a series of locations of villages that pass certain criteria into an array. Each member of the array has members 'x' and 'y' (the position) and 'terrain' (the terrain type) and 'owner_side'.<br />
<br />
* '''owner_side''': a side number. If present, only villages owned by this side will be choosen. If owner_side=0, store the unowned villages. <br />
<br />
* '''variable''': the name of the variable (array) into which to store the locations<br />
<br />
* '''terrain''': a series of terrain characters. (See [[TerrainLettersWML]] for possible values.) If present, villages will only be chosen if the terrain code of the terrain type of that location is listed. You may give a comma separated list of terrains.<br />
<br />
=== [clear_variable] ===<br />
<br />
This will delete the given variable or array. This is good to use to clean up the set of variables -- e.g. a well-behaved scenario will delete any variables that shouldn't be kept for the next scenario before the end of the scenario.<br> Tags and variables of stored units can also be cleared, meaning that [trait]s and [object]s, for example, can be removed.<br />
<br />
* '''name''': the name of the variable to clear, multiple comma-separated variable names can be given.<br />
<br />
== Other Internal Actions ==<br />
<br />
Believe it or not, there are some internal actions that are not focused primarily on variables. They are all grouped here.<br />
<br />
=== [fire_event] ===<br />
<br />
Trigger a WML event<br />
<br />
* '''name''': the name of event to trigger<br />
<br />
* '''[primary_unit]''': ''(Optional)'' Primary unit for the event. Will never match on a recall list unit. The first unit matching the filter will be chosen.<br />
**[[StandardUnitFilter]] as argument. Do not use a [filter] tag.<br />
<br />
* '''[secondary_unit]''': ''(Optional)'' Same as '''[primary_unit]''' except for the secondary unit.<br />
**[[StandardUnitFilter]] as argument. Do not use a [filter] tag.<br />
<br />
* '''[primary_attack]''': Information passed to the primary attack filter and $weapon variable on the new event.<br />
<br />
* '''[secondary_attack]''': Information passed to the second attack filter and $second_weapon variable on the new event.<br />
<br />
=== [insert_tag] ===<br />
<br />
Inserts a variable as WML. In other words, the value of the passed [[VariablesWML#Container|container variable]] will be injected into the game as if they had been written out in WML form. ([[#.5Binsert_tag.5D_Example|See Example]]).<br />
<br />
Tag insertion is a special case in that it can be used in places where other ActionWML cannot be used. The basic rule is that anywhere that $variable syntax works, tag insertion will also work. In practice this means pretty much everywhere except directly within top-level scenario tags.<br />
<br />
*'''name''': The ["name"] to be given to the tag. This must be a tag which would be valid at the place where [insert_tag] is used, for anything to happen. (For example, if used as ActionWML, it should be a [[ActionWML]] tag name, and it may be a recognized subtag such as "option" when used within a [message]).<br />
<br />
*'''variable''': Name of the container variable which will have its value inserted into the tag.<br />
<br />
=== [role] ===<br />
<br />
Tries to find a unit to assign a role to.<br>This is useful if you want to choose a non-major character to say some things during the game. Once a role is assigned, you can use '''role=''' in a unit filter to identify the unit with that role (See [[FilterWML]]).<br>However, there is no guarantee that roles will ever be assigned. You can use '''[have_unit]''' (see [[ConditionalActionsWML#Condition_Tags|Condition Tags]]) to see whether a role was assigned. This tag uses a [[StandardUnitFilter]] (without [filter]) with the modification to order the search by type, mark only the first unit found with the role, and the role attribute is not used in the search. If for some reason you want to search for units that have or don't have existing roles, you can use one or more [not] filters. The will check recall lists in addition to units on the map. In normal use, you will probably want to include a ''side'' attribute to force the unit to be on a particular side.<br />
<br />
* '''role''': the value to store as the unit's role. This role is not used in the [[StandardUnitFilter]] when doing the search for the unit to assign this role to.<br />
<br />
* '''type''': a comma-separated list of possible types the unit can be. If any types are given, then units will be searched by type in the order listed. If no type is given, then no particular order with respect to type is guaranteed.<br />
<br />
== Examples ==<br />
<br />
=== Using [set_variables] to Create Arrays of WML ===<br />
<br />
[set_variables]<br />
name=arr<br />
mode=replace<br />
[value]<br />
foo=bar<br />
[/value]<br />
[value]<br />
foo=more<br />
[/value]<br />
[/set_variables]<br />
{DEBUG_MSG $arr[0].foo}<br />
{DEBUG_MSG $arr[1].foo}<br />
<br />
This will produce two output messages, first one saying '''bar''' and next one saying '''more'''.<br />
<br />
=== [insert_tag] Example ===<br />
<br />
[event]<br />
name=moveto<br />
<br />
[set_variable]<br />
name=temp.speaker<br />
value=Konrad<br />
[/set_variable]<br />
<br />
[set_variable]<br />
name=temp.message<br />
value= _ "Yo Kalenz!"<br />
[/set_variable] <br />
<br />
[insert_tag]<br />
name=message<br />
variable=temp<br />
[/insert_tag]<br />
[/event]<br />
<br />
This is effectively identical to:<br />
<br />
[event]<br />
name=moveto<br />
<br />
[message]<br />
speaker=Konrad<br />
message= _ "Yo Kalenz!"<br />
[/message]<br />
[/event]<br />
<br />
== See Also ==<br />
* [[VariablesWML]]<br />
* [[ActionWML]]<br />
** [[ConditionalWML]]<br />
** [[DirectActionsWML]]<br />
** [[InterfaceActionsWML]]<br />
* [[EventWML]]<br />
* [[ReferenceWML]]<br />
<br />
[[Category: WML Reference]]<br />
[[Category: ActionsWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=InternalActionsWML&diff=40100InternalActionsWML2011-01-15T22:33:08Z<p>Paŭlo: /* [insert_tag] */ reworded the "should be a valid tag name". Hope it still fits.</p>
<hr />
<div>{{WML Tags}}<br />
<br />
Part of [[ActionWML]], Internal actions are actions that WML uses internally that do not directly affect game play (or, at least, are not readily apparent to the player). For example, storing a variable is an internal action.<br />
<br />
== Variable Actions ==<br />
<br />
These actions are focused, in one way or another, on [[VariablesWML|variables]]. Creating them, modifying them, capturing game data to them, you name it, these actions are all about the variables.<br />
<br />
=== [set_variable] ===<br />
<br />
The '''[set_variable]''' tag is used to create and manipulate WML variables. The [http://www.wesnoth.org/macro-reference.xhtml#VARIABLE VARIABLE] macro is a quick syntactic shortcut for simple variable creation and the [http://www.wesnoth.org/macro-reference.xhtml#VARIABLE_OP VARIABLE_OP] macro is a quick syntactic shortcut for performing simple mathematical operations on variables.<br />
<br />
* '''name''': the name of the variable to manipulate<br />
<br />
* '''value''': set the variable to the given value (can be numeric or string).Use literal for no substitution. (see [[VariablesWML]])<br />
<br />
* '''literal''': set the variable to the given value (can be numeric or string). This does not interpret any dollars signs.<br />
<br />
* '''format''': This attribute will be deprecated from 1.7 on. Same behaviour as value.<br />
<br />
* '''to_variable''': set the variable to the value of the given variable, e.g. 'to_variable=temp' would be equivalent to 'value=$temp'.<br />
<br />
* '''add''': add the given amount to the variable. To subtract, add a negative number.<br />
<br />
* '''sub''' {{DevFeature}}: subtract the given amount from the variable.<br />
<br />
* '''multiply''': multiply the variable by the given number. To divide, multiply by the inverse eg: 4/2 = 4 * 1/2 = 4 * 0.5. To negate, multiply by -1. Floating point values are not rounded.<br />
<br />
* '''divide''': divide the variable by the given number. The result is an integer. Floating point results are not rounded. If both variables are integers, [http://en.wikipedia.org/wiki/Division_(mathematics)#Division_of_integers Integer division] is used.<br />
<br />
* '''modulo''': returns the remainder of a division.<br />
<br />
* '''random''': the variable will be randomly set.<br>You may provide a comma separated list of possibilities, e.g. 'random=Bob,Bill,Bella'.<br>You may provide a range of numbers (integers), e.g. 'random=3..5'.<br>You may combine these, e.g. 'random=100,1..9', in which case there would be 1/10th chance of getting 100, just like for each of 1 to 9. {{DevFeature1.9}} random is deprecated, use rand instead.<br />
<br />
* '''rand''': does the same as random, but has better MP support. See [[BuildingMultiplayerExamples]] for more info on the MP case. '''It is highly recommended that you use this feature for randomization.'''<br />
<br />
* '''time=stamp''': Retrieves a timestamp in milliseconds since wesnoth was started, can be used as timing aid. Don't try to use this as random value in MP since it will cause an OOS.<br />
<br />
* '''string_length''': Retrieves the length in characters of the string passed as this attribute's value; such string is parsed and variable substitution applied automatically (see [[VariablesWML]] for details).<br />
<br />
* '''[join]''' joins an array of strings to create a textual list<br />
** '''variable''': name of the array<br />
** '''key''': the key of each array element(array[$i].foo) in which the strings are stored<br />
** '''separator''': separator to connect the elements<br />
** '''remove_empty''': whether to ignore empty elements<br />
<br />
* '''ipart''': Assigns the integer part (the part to the left of the comma) of the referenced variable.<br />
<br />
* '''fpart''': Assigns the decimal part (the part to the right of the comma) of the referenced variable.<br />
<br />
* '''round''': Rounds the variable to the specified number of digits of precision. Negative precision works as expected (rounding 19517 to -2 = 19500). Special values:<br />
**'''ceil''': Rounds upward to the nearest integer.<br />
**'''floor''': Rounds down to the nearest integer.<br />
<br />
=== [set_variables] ===<br />
<br />
Manipulates a WML array or container<br />
<br />
* '''name''': the name of the array or container to manipulate<br />
<br />
* '''mode''': one of the following values:<br />
** ''replace'': will clean the array '''name''' and replace it with given data<br />
** ''append'': will append given data to the current array<br />
** ''merge'': will merge in the given data into '''name'''<br />
** ''insert'': will insert the given data at the index specified in the '''name''' attribute, such as name=my_array[1]. The default index is zero, which will insert to the front of the array. '''Note:''' if an invalid index is used, empty containers will be created before the insertion is performed. In other words, do not attempt to insert at an index greater than (or equal to) the array's current length. This limitation may be removed in future versions.<br />
<br />
* '''to_variable''': data will be set to the given array<br />
<br />
* '''[value]''': the WML inside the [value] tags will be stored in data, variables will be interpolated directly, use $| in order to escape the $ sign, you can store arrays of WML by supplying multiple [value] tags. ([[#Using_.5Bset_variables.5D_to_Create_Arrays_of_WML|See Example]])<br />
<br />
* '''[literal]''': same as '''[value]''', but variables will not be substituted, '''[literal]''' and '''[value]''' can not be used in the same [set_variables] tag, i.e. you can not create arrays by piling a mix of '''[value]''' and '''[literal]''' tags<br />
<br />
*'''[split]''' splits a textual list into an array which will then be set to data<br />
** '''list''': textual list to split<br />
** '''key''': the key of each array element(array[$i].foo) in which the strings are stored<br />
** '''separator''': separator to separate the elements<br />
** '''remove_empty''': whether to ignore empty elements<br />
<br />
=== Capturing Game Data ===<br />
<br />
These actions capture different bits of game data and store them to variables so they can be examined and/or manipulated.<br />
<br />
==== [store_gold] ====<br />
<br />
Stores a side's gold into a variable.<br />
<br />
* '''side''': (default=1) the side for which the gold should be stored<br />
<br />
* '''variable''': (default='gold') the name of the variable to store the gold in<br />
<br />
==== [store_locations] ====<br />
<br />
Stores a series of locations that pass certain criteria into an array. Each member of the array has members 'x' and 'y' (the position) and 'terrain' (the terrain type) and 'owner_side' (villages only). The array will include any unreachable border hexes, if applicable.<br />
<br />
* [[StandardLocationFilter]]: a location or location range which specifies the locations to store. You must specify this or no locations will be stored.<br />
<br />
* '''variable''': the name of the variable (array) into which to store the locations.<br />
<br />
==== [store_reachable_locations] {{DevFeature1.9}} ====<br />
<br />
Stores locations reachable by the given units. Can store either the movement, attack or vision ranges.<br />
<br />
* '''[filter]''': a [[StandardUnitFilter]]. The locations reachable by any of the matching units will be stored.<br />
* '''[filter_location]''': (optional) a [[StandardLocationFilter]]. Only locations which also match this filter will be stored.<br />
* '''range''': possible values ''movement'' (default), ''attack'', ''vision''. If ''movement'', stores the locations within the movement range of the unit, taking Zone of Control into account. If ''attack'', stores the attack range (movement range + 1 hex). If ''vision'', stores the vision range (movement range ignoring Zone of Control + 1 hex).<br />
* '''moves''': possible values ''current'' (default), ''max''. Specifies whether to use the current or maximum movement points when calculating the range.<br />
* '''viewing_side''': (optional) the side whose vision to use when calculating the reach. This only has meaning in the presence of fog, shroud, or units with the ambush ability. If left out, then fog, shroud and ambushers are ignored and the real reach of the units is stored.<br />
* '''variable''': the name of the variable (array) into which to store the locations.<br />
<br />
==== [store_map_dimensions] ====<br />
<br />
Stores the map dimensions in a variable.<br />
<br />
* '''variable''': the name of the variable where the values will be saved into. If it is skipped, a variable 'map_size' is used, and its contents overridden, if they existed already. The result is a container variable, with members ''width'' and ''height''.<br />
<br />
==== [store_side] ====<br />
<br />
Stores information about a certain side in a variable. The variable will contain the member variables 'name', 'team_name', 'gold' and 'income', 'fog', 'shroud', 'hidden', 'user_team_name', 'colour' (becomes 'color' in 1.9+), 'controller', 'village_gold' and 'recruit'.<br />
<br />
* '''side''': the side whose information should be stored<br />
<br />
* '''variable''': the name of the variable to store the information in<br />
<br />
==== [store_starting_location] ====<br />
<br />
Stores the starting location of a side's leader in a variable. The variable is a composite type which will have members 'x', 'y', 'terrain' (the terrain type for a starting location is always 'K' unless it has been changed) and 'owner_side' (villages only)<br />
<br />
* '''side''': the side whose starting location is to be stored<br />
<br />
* '''variable''': (default='location'): the name of the variable to store the location in<br />
<br />
==== [store_time_of_day] ====<br />
<br />
Stores time of day information from the current scenario into a WML variable container.<br />
<br />
* '''variable''': (default='time_of_day') name of the container on which to store the information. The container will be filled with the same attributes found on [[TimeWML]].<br />
<br />
* '''turn''': (defaults to the current turn number) changes the turn number for which time of day information should be retrieved.<br />
<br />
==== [store_unit] ====<br />
<br />
Stores details about units into a [[VariablesWML#Container|container]] variable. When a unit is stored, all keys and tags in the unit definition may be manipulated, including some others, with [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]]. A sample list of these tags and keys can be found [[InternalActionsWMLUnitTags|here]]. If you have a doubt about what keys are valid or what the valid value range is for each key, code a [store_unit] event, save the game, and examine what keys are in the file (or just examine the '''[unit]''' tag(s) in any save file).<br />
<br />
Common usage is to manipulate a unit by using '''[store_unit]''' to store it into a variable, followed by manipulation of the variable, and then [[DirectActionsWML|[unstore_unit]]] to re-create the unit with the modified variables.<br />
<br />
''Note: stored units also exist on the field, and modifying the stored variable will not automatically change the stats of the units. You need to use [unstore_unit]. See also [[DirectActionsWML|[unstore_unit]]] and [http://www.wesnoth.org/macro-reference.xhtml#FOREACH FOREACH].''<br />
<br />
* '''[filter]''' with a [[StandardUnitFilter]] as argument. All units matching this filter will be stored. If there are multiple units, they will be stored into an array of variables.<br />
<br />
* '''variable''': the name of the variable into which to store the unit(s)<br />
<br />
* '''mode''': defaults to ''always_clear'', which clears the variable, whether or not a match is found. If mode is set to ''replace'', the variable will only be cleared if a match is found. If mode is set to ''append'', the variable will not be cleared.<br />
<br />
* '''kill''': if 'yes' the units that are stored will be removed from play. This is useful for instance to remove access to a player's recall list, with the intent to restore the recall list later.<br />
<br />
==== [store_villages] ====<br />
<br />
Stores a series of locations of villages that pass certain criteria into an array. Each member of the array has members 'x' and 'y' (the position) and 'terrain' (the terrain type) and 'owner_side'.<br />
<br />
* '''owner_side''': a side number. If present, only villages owned by this side will be choosen. If owner_side=0, store the unowned villages. <br />
<br />
* '''variable''': the name of the variable (array) into which to store the locations<br />
<br />
* '''terrain''': a series of terrain characters. (See [[TerrainLettersWML]] for possible values.) If present, villages will only be chosen if the terrain code of the terrain type of that location is listed. You may give a comma separated list of terrains.<br />
<br />
=== [clear_variable] ===<br />
<br />
This will delete the given variable or array. This is good to use to clean up the set of variables -- e.g. a well-behaved scenario will delete any variables that shouldn't be kept for the next scenario before the end of the scenario.<br> Tags and variables of stored units can also be cleared, meaning that [trait]s and [object]s, for example, can be removed.<br />
<br />
* '''name''': the name of the variable to clear, multiple comma-separated variable names can be given.<br />
<br />
== Other Internal Actions ==<br />
<br />
Believe it or not, there are some internal actions that are not focused primarily on variables. They are all grouped here.<br />
<br />
=== [fire_event] ===<br />
<br />
Trigger a WML event<br />
<br />
* '''name''': the name of event to trigger<br />
<br />
* '''[primary_unit]''': ''(Optional)'' Primary unit for the event. Will never match on a recall list unit. The first unit matching the filter will be chosen.<br />
**[[StandardUnitFilter]] as argument. Do not use a [filter] tag.<br />
<br />
* '''[secondary_unit]''': ''(Optional)'' Same as '''[primary_unit]''' except for the secondary unit.<br />
**[[StandardUnitFilter]] as argument. Do not use a [filter] tag.<br />
<br />
* '''[primary_attack]''': Information passed to the primary attack filter and $weapon variable on the new event.<br />
<br />
* '''[secondary_attack]''': Information passed to the second attack filter and $second_weapon variable on the new event.<br />
<br />
=== [insert_tag] ===<br />
<br />
Inserts a variable as WML. In other words, the value of the passed [[VariablesWML#Container|container variable]] will be injected into the game as if they had been written out in WML form. ([[#.5Binsert_tag.5D_Example|See Example]]).<br />
<br />
Tag insertion is a special case in that it can be used in places where other ActionWML cannot be used. The basic rule is that anywhere that $variable syntax works, tag insertion will also work. In practice this means pretty much everywhere except directly within top-level scenario tags.<br />
<br />
*'''name''': The ["name"] to be given to the tag. This must be a tag which would be valid at the place where [insert_tag] is used, for anything to happen. (For example, if used as ActionWML, it should be a [[ActionWML]] tag name, and it may be a recognized subtag such as "option" when used within a [message]).<br />
<br />
*'''variable''': Name of the container variable which will have its value inserted into the tag.<br />
<br />
=== [role] ===<br />
<br />
Tries to find a unit to assign a role to.<br>This is useful if you want to choose a non-major character to say some things during the game. Once a role is assigned, you can use '''role=''' in a unit filter to identify the unit with that role (See [[FilterWML]]).<br>However, there is no guarantee that roles will ever be assigned. You can use '''[have_unit]''' (see [[ConditionalActionsWML#Condition_Tags|Condition Tags]]) to see whether a role was assigned. This tag uses a [[StandardUnitFilter]] (without [filter]) with the modification to order the search by type, mark only the first unit found with the role, and the role attribute is not used in the search. If for some reason you want to search for units that have or don't have existing roles, you can use one or more [not] filters. The will check recall lists in addition to units on the map. In normal use, you will probably want to include a ''side'' attribute to force the unit to be on a particular side.<br />
<br />
* '''role''': the value to store as the unit's role. This role is not used in the [[StandardUnitFilter]] when doing the search for the unit to assign this role to.<br />
<br />
* '''type''': a comma-separated list of possible types the unit can be. If any types are given, then units will be searched by type in the order listed. If no type is given, then no particular order with respect to type is guaranteed.<br />
<br />
== Examples ==<br />
<br />
=== Using [set_variables] to Create Arrays of WML ===<br />
<br />
[set_variables]<br />
name=arr<br />
mode=replace<br />
[value]<br />
foo=bar<br />
[/value]<br />
[value]<br />
foo=more<br />
[/value]<br />
[/set_variables]<br />
{DEBUG_MSG $arr[0].foo}<br />
{DEBUG_MSG $arr[1].foo}<br />
<br />
This will produce two output messages, first one saying '''bar''' and next one saying '''more'''.<br />
<br />
=== [insert_tag] Example ===<br />
<br />
[event]<br />
name=moveto<br />
<br />
[set_variable]<br />
name=temp.speaker<br />
value=Konrad<br />
[/set_variable]<br />
<br />
[set_variable]<br />
name=temp.message<br />
value= _ "Yo Kalenz!"<br />
[/set_variable] <br />
<br />
[insert_tag]<br />
name=message<br />
variable=temp<br />
[/insert_tag]<br />
[/event]<br />
<br />
This is effectively identical to:<br />
<br />
[event]<br />
name=moveto<br />
<br />
[message]<br />
speaker=Konrad<br />
message= _ "Yo Kalenz!"<br />
[/message]<br />
[/event]<br />
<br />
== See Also ==<br />
* [[VariablesWML]]<br />
* [[ActionWML]]<br />
** [[ConditionalWML]]<br />
** [[DirectActionsWML]]<br />
** [[InterfaceActionsWML]]<br />
* [[EventWML]]<br />
* [[ReferenceWML]]<br />
<br />
[[Category: WML Reference]]<br />
[[Category: ActionsWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=HelpWML&diff=40098HelpWML2011-01-15T22:25:54Z<p>Paŭlo: /* Help System Topic Markup */ clarified a bit more.</p>
<hr />
<div>{{WML Tags}}<br />
== The toplevel [help] tag ==<br />
<br />
The [help] tag describes the Wesnoth help system.<br />
Each of the three subtags [toplevel], [section] and [topic] describe an element of the help system.<br />
<br />
* '''[toplevel]''': The toplevel tag denotes sections and topics that should be shown immediately when the "Help" button is clicked on (see the "help" action, [[ThemeWML]]). The sections referenced within this tag are read recursively, including all subsections.<br />
** '''sections''': a list of IDs of the sections to include recursively.<br />
** '''topics''': a list of IDs of the topics to show as not being included in a section; i.e. top-level topics.<br />
* '''[section]''': The section tag describes a section in the help browser. A section contains subsections and/or topics.<br />
** '''id''': is the unique ID for this section.<br />
** '''title''': (translatable) is the title of the section. It is displayed in the left menu.<br />
** '''sections''': is a list of IDs of the sections that should be this section's subsections.<br />
** '''topics''': is a list of IDs of the topics that should be included in this section. Topics will be included in the order listed unless sorting is requested.<br />
** '''generator''': provides the name of a function that will generate a list of topics and include them in this section. These topics will be included after topics listed on the '''topics''' key unless ''sort_topics'' is ''yes''.<br />
** '''sort_topics''': specifies whether or not to list the topics sorted by title or in the order listed on the '''topics''' key. '''yes''' indicates fixed and generated topics should be sorted together by title. '''no''' indicates that topics should appear in the order listed with fixed topics appearing before generated topics. '''generated''' indicates that fixed topics should not be sorted and will be followed by generated topics sorted by the generator. The default is '''generated'''.<br />
* '''[topic]''': The topic tag describes one topic, i.e, one help page. The keys that are meaningful in the topic tag:<br />
** '''id''': is the unique ID for this topic.<br />
** '''title''': (translatable) is the title of the topic. It is displayed in the left menu and as a header in the text area.<br />
** '''text''': (translatable) is the contents of the topics. May contain markup described below.<br />
<br />
== Help System Topic Markup ==<br />
<br />
The markup that is allowed in the text key within a topic tag is in a WML-like markup language with angle brackets.<br />
<br />
It consists of plain text, interrupted with markup tags. Between paired start and end tags (like '''<jump> ... </jump>''') you can give keys and values like in WML, separated by spaces instead of newlines. For values containing spaces, surround them with single quotes. The "text content" of a tag, if any, is usually given by a ''text'' key. You can't nest tags within another tag.<br />
<br />
The following key/tags are accepted inside '''text''':<br />
* '''<ref>''': creates a cross reference to another topic, a cross reference will not show up if the topic it refers to is not visible.<br />
** '''dst''': the ID of the topic to reference.<br />
** '''text''': the text to display as a link to '''dst'''; i.e. when '''text''' is clicked on the page '''dst''' will be linked to.<br />
** '''force''': shows the cross reference even though the referred topic is not shown.<br />
* '''<jump>''': when this text is selected, the input position along the X axis is moved. Can be used for example to create columns of things. A jump is ignored if it would bring the input position to an invalid position.<br />
** '''to''': the X coordinate of the text area to jump to. If it can't be done on the current row, the input position is moved down one line.<br />
** '''amount''': the number of pixels to jump forward<br />
* '''<img>''': insert an image in the topic<br />
** '''src''': the path to the image relative to the '''images/''' directory.<br />
** '''align''': the position of the image with respect to the page. Values are '''here''', '''left''', '''middle''', and '''right'''.<br />
** '''float''': whether the image should float(have text filled in around it) or not (be seen as included in a line).<br />
* '''<format>''': describes a group of text in a different format. Can be used to describe different colors and font sizes.<br />
** '''bold''': whether the text should be displayed in bold('''bold''').<br />
** '''italic''': whether the text should be displayed in italics(''italics'').<br />
** '''color''': the color of the text. Only a few colors are currently supported: '''white'''(default), '''green''', '''red''', '''yellow''', and '''black'''.<br />
** '''font_size''': the height of the text in pixels. Default 9(?)<br />
** '''text''': the text to be displayed using this format.<br />
* '''<italic>''': a shortcut to '''<format>''' which inputs only the '''text''' key. Uses the attribute '''italic=yes'''<br />
* '''<bold>''': like <italic>, but uses '''bold=yes'''<br />
* '''<header>''': like <italic>, but uses both the attributes '''bold=yes''' and '''font_size=13'''(?)<br />
<br />
Example:<br />
[help]<br />
[toplevel]<br />
sections=introduction,gameplay<br />
topics=about<br />
[/toplevel]<br />
[section]<br />
id=gameplay<br />
sections=combat<br />
topics=income_and_upkeep,time_of_day,terrain,victory_and_defeat<br />
[/section]<br />
[topic]<br />
id=terrain<br />
title=Terrain<br />
text="<ref>dst=income_and_upkeep text='Link to Income and Upkeep topic'</ref>"<br />
[/topic]<br />
[topic]<br />
id=victory_and_defeat<br />
title= _ "Victory and Defeat"<br />
text= _ "Pay careful attention to the <bold>text='Objectives'</bold> pop-up<br />
box at the beginning of each scenario. Usually you will achieve<br />
victory by killing all enemy leaders, and only be defeated by having<br />
your leader killed. But scenarios may have other victory objectives<br />
— getting your leader to a designated point, say, or rescuing someone,<br />
or solving a puzzle, or holding out against a siege until a certain<br />
number of turns have elapsed." + _"<br />
<br />
When you win a scenario, the map grays over and the<br />
<bold>text='End Turn'</bold> button changes to<br />
<bold>text='End Scenario'</bold>. You can now do things like changing<br />
your save options or (if you are in a multiplayer game) chatting with<br />
other players before pressing that button to advance."<br />
<br />
[/topic]<br />
[/help]<br />
<br />
== See Also ==<br />
<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=Talk:HelpWML&diff=40097Talk:HelpWML2011-01-15T22:20:16Z<p>Paŭlo: why I changed the "XML" bits in the article.</p>
<hr />
<div>== Help system topic markup - XML ==<br />
<br />
This was written here:<br />
: ''The markup that is allowed in the text key within a topic tag is in XML, a markup language similar to WML. Note that this is the only time that markup language is used as a value. ''<br />
In fact, the used language may have been looking like XML to someone who never really used XML, but it certainly is not XML. XML has its attributes (keys and values) inside the start tag, not between the start and end tag. (Also, XML is hierarchical, while this is only one-level, as it looks.)<br />
<br />
The example<br />
text="<ref>dst=income_and_upkeep text='Link to Income and Upkeep topic'</ref>"<br />
would have looked in XML (as the inner language) like one of these:<br />
text="<ref dst='income_and_upkeep' text='Link to Income and Upkeep topic'></ref>"<br />
text="<ref dst='income_and_upkeep' text='Link to Income and Upkeep topic' />"<br />
text="<ref dst='income_and_upkeep'>Link to Income and Upkeep topic</ref>"<br />
<br />
Thus I changed the description of this language, also throwing away this "you have to convert from WML to XML", as our current wiki seems not to have any problems with angled brackets. I hope it is better understandable now.<br />
-- [[User:Paŭlo|Paŭlo]] 22:20, 15 January 2011 (UTC)</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=HelpWML&diff=40096HelpWML2011-01-15T22:10:52Z<p>Paŭlo: /* Help System Topic Markup */ better description (I hope), one more topic example (from current trunk help.cfg)</p>
<hr />
<div>{{WML Tags}}<br />
== The toplevel [help] tag ==<br />
<br />
The [help] tag describes the Wesnoth help system.<br />
Each of the three subtags [toplevel], [section] and [topic] describe an element of the help system.<br />
<br />
* '''[toplevel]''': The toplevel tag denotes sections and topics that should be shown immediately when the "Help" button is clicked on (see the "help" action, [[ThemeWML]]). The sections referenced within this tag are read recursively, including all subsections.<br />
** '''sections''': a list of IDs of the sections to include recursively.<br />
** '''topics''': a list of IDs of the topics to show as not being included in a section; i.e. top-level topics.<br />
* '''[section]''': The section tag describes a section in the help browser. A section contains subsections and/or topics.<br />
** '''id''': is the unique ID for this section.<br />
** '''title''': (translatable) is the title of the section. It is displayed in the left menu.<br />
** '''sections''': is a list of IDs of the sections that should be this section's subsections.<br />
** '''topics''': is a list of IDs of the topics that should be included in this section. Topics will be included in the order listed unless sorting is requested.<br />
** '''generator''': provides the name of a function that will generate a list of topics and include them in this section. These topics will be included after topics listed on the '''topics''' key unless ''sort_topics'' is ''yes''.<br />
** '''sort_topics''': specifies whether or not to list the topics sorted by title or in the order listed on the '''topics''' key. '''yes''' indicates fixed and generated topics should be sorted together by title. '''no''' indicates that topics should appear in the order listed with fixed topics appearing before generated topics. '''generated''' indicates that fixed topics should not be sorted and will be followed by generated topics sorted by the generator. The default is '''generated'''.<br />
* '''[topic]''': The topic tag describes one topic, i.e, one help page. The keys that are meaningful in the topic tag:<br />
** '''id''': is the unique ID for this topic.<br />
** '''title''': (translatable) is the title of the topic. It is displayed in the left menu and as a header in the text area.<br />
** '''text''': (translatable) is the contents of the topics. May contain markup described below.<br />
<br />
== Help System Topic Markup ==<br />
<br />
The markup that is allowed in the text key within a topic tag is in a WML-like markup language with angle brackets.<br />
<br />
It consists of plain text, interrupted with markup tags. Between the tags you can give keys and values like in WML, separated by spaces instead of newlines. For values containing spaces, surround them with single quotes.<br />
<br />
The following key/tags are accepted inside '''text''':<br />
* '''<ref>''': creates a cross reference to another topic, a cross reference will not show up if the topic it refers to is not visible.<br />
** '''dst''': the ID of the topic to reference.<br />
** '''text''': the text to display as a link to '''dst'''; i.e. when '''text''' is clicked on the page '''dst''' will be linked to.<br />
** '''force''': shows the cross reference even though the referred topic is not shown.<br />
* '''<jump>''': when this text is selected, the input position along the X axis is moved. Can be used for example to create columns of things. A jump is ignored if it would bring the input position to an invalid position.<br />
** '''to''': the X coordinate of the text area to jump to. If it can't be done on the current row, the input position is moved down one line.<br />
** '''amount''': the number of pixels to jump forward<br />
* '''<img>''': insert an image in the topic<br />
** '''src''': the path to the image relative to the '''images/''' directory.<br />
** '''align''': the position of the image with respect to the page. Values are '''here''', '''left''', '''middle''', and '''right'''.<br />
** '''float''': whether the image should float(have text filled in around it) or not (be seen as included in a line).<br />
* '''<format>''': describes a group of text in a different format. Can be used to describe different colors and font sizes.<br />
** '''bold''': whether the text should be displayed in bold('''bold''').<br />
** '''italic''': whether the text should be displayed in italics(''italics'').<br />
** '''color''': the color of the text. Only a few colors are currently supported: '''white'''(default), '''green''', '''red''', '''yellow''', and '''black'''.<br />
** '''font_size''': the height of the text in pixels. Default 9(?)<br />
** '''text''': the text to be displayed using this format.<br />
* '''<italic>''': a shortcut to '''<format>''' which inputs only the '''text''' key. Uses the attribute '''italic=yes'''<br />
* '''<bold>''': like <italic>, but uses '''bold=yes'''<br />
* '''<header>''': like <italic>, but uses both the attributes '''bold=yes''' and '''font_size=13'''(?)<br />
<br />
Example:<br />
[help]<br />
[toplevel]<br />
sections=introduction,gameplay<br />
topics=about<br />
[/toplevel]<br />
[section]<br />
id=gameplay<br />
sections=combat<br />
topics=income_and_upkeep,time_of_day,terrain,victory_and_defeat<br />
[/section]<br />
[topic]<br />
id=terrain<br />
title=Terrain<br />
text="<ref>dst=income_and_upkeep text='Link to Income and Upkeep topic'</ref>"<br />
[/topic]<br />
[topic]<br />
id=victory_and_defeat<br />
title= _ "Victory and Defeat"<br />
text= _ "Pay careful attention to the <bold>text='Objectives'</bold> pop-up<br />
box at the beginning of each scenario. Usually you will achieve<br />
victory by killing all enemy leaders, and only be defeated by having<br />
your leader killed. But scenarios may have other victory objectives<br />
— getting your leader to a designated point, say, or rescuing someone,<br />
or solving a puzzle, or holding out against a siege until a certain<br />
number of turns have elapsed." + _"<br />
<br />
When you win a scenario, the map grays over and the<br />
<bold>text='End Turn'</bold> button changes to<br />
<bold>text='End Scenario'</bold>. You can now do things like changing<br />
your save options or (if you are in a multiplayer game) chatting with<br />
other players before pressing that button to advance."<br />
<br />
[/topic]<br />
[/help]<br />
<br />
== See Also ==<br />
<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=InterfaceActionsWML&diff=40094InterfaceActionsWML2011-01-15T21:43:11Z<p>Paŭlo: /* Other interface tags */ use subsections instead a simple enumeration, to enable linking to individual tags.</p>
<hr />
<div>{{WML Tags}}<br />
== Interface actions ==<br />
<br />
Part of [[ActionWML]], interface actions are actions that do not have a direct effect on gameplay;<br />
instead, they show something to the player. The main interface tags<br />
are '''[message]''' and '''[objectives]''', but several other tags affect<br />
the interface also.<br />
<br />
== [inspect] ==<br />
This user interface action only works in debug mode. It displays the gamestate inspector dialog (the same one which can be brought up with '':inspect'' ), which can be used to inspect the values of WML variables, AI configuration, recall lists, and more.<br />
<br />
* '''name''': optional attribute to specify the name of this gamestate inspector dialog. It is just a label to help differentiate between different invocations of gamestate inspector dialog.<br />
<br />
== [message] ==<br />
The most commonly used interface action is [message], which displays a message to the user in a dialog box. It can also be used to take input from the user.<br />
<br />
The following key/tags are accepted for [message]:<br />
* [[StandardUnitFilter]]: The unit whose profile and name are displayed. Do not use a [filter] tag. If no unit matching this filter is found, the message is not displayed (The unit has probably been killed).<br>'''[message]''' elements should be constructed so that it is either guaranteed that a certain unit is alive, or so that dialog flows smoothly even if the message isn't displayed.<br />
<br />
* '''speaker''': an alternative to standard unit filter. You may specify as the value of the speaker attribute a unit id or any of the following special values:<br />
** '''narrator''': the dialog box is displayed without a caption for the unit speaking or a unit image<br />
** '''unit''': the primary unit for the event is speaking<br />
** '''second_unit''': the secondary unit for the event is speaking<br />
<br />
* '''message''': (translatable) the text to display to the right of the image. ''message'' is sometimes multiple lines; if it is, be sure to use quotes(''' ' ''' or ''' " ''')<br />
* '''[show_if]''': if present then this message will only be displayed if the conditional statement in this tag is passed (see [[ConditionalActionsWML#Condition_Tags|ConditionalActionsWML]])<br />
* '''side_for''': (default: all sides) comma-separated list of sides for who message is shown.<br />
* '''image''': (default: profile image of speaker) the image to display next to the message.<br />
* '''caption''': (default: name of speaker) the caption to display beside the image. Name to be displayed. Note: use a translation mark to avoid wmllint errors.<br />
* '''scroll''': {{DevFeature1.9}} Boolean specifying whether the game view should scroll to the speaking unit. Defaults to ''yes''.<br />
* '''duration''': (default: 10) the minimum number of frames for this message to be displayed. (A frame lasts about 30 milliseconds.) During this time any dialog decisions will be disregarded.<br />
* '''sound''': a sound effect (wav file) to play as the message is displayed. This can be a comma-separated list, from which one will be randomly chosen.<br />
* '''[option]''': No '''[option]''' elements have to be used. If '''[option]''' elements are present, then each option will be displayed in a menu for the user to select one option.<br />
** '''message''': (translatable) the text displayed for the option (see [[DescriptionWML]])<br />
** '''[show_if]''': if present then this option will only be displayed if the conditional statement in this tag is passed (see [[InternalActionsWML]])<br />
** '''[command]''': an element containing actions which are executed if the option is selected.<br />
* '''[text_input]''': there can be only one [text_input] tag. this adds a text input field to the message.<br />
** '''variable''': the variable that the user's input will be written to<br />
** '''label''': a text label to the left of the input field<br />
** '''max_length''': the maximum number of characters that may be typed into the field<br />
** '''text''': text that is written into the field in the beginning<br />
* Check [[EventWML#Multiplayer_safety]] to find out in which events you can safely use '''[option]''' and '''[text_input]''' without causing OOS.<br />
<br />
=== Formatting ===<br />
In 1.8, [http://library.gnome.org/devel/pango/unstable/PangoMarkupFormat.html Pango markup formatting codes] have been adopted for '''[message]'''. These can also be used in unit names (user_description), objectives, and such. Note that you'll probably want to use a single quote ' instead of a double quote " as double quotes cannot be escaped, otherwise the string will appear fragmented and you may also encounter errors. Running wmllint on your campaign will up-convert it, warning you about unusual cases you must fix by hand.<br />
<br />
For example, if you wanted to write "You are victorious!" in large, italic, gold letters, you might write it this way:<br />
<br />
<nowiki><span color='#BCB088' size='large' font-style='italic'>You are victorious!</span></nowiki><br />
<br />
<br />
These are the codes taken from the Pango markup formatting guide:<br />
<br />
*'''font''', '''font_desc''': A font description string, such as "Sans Italic 12".<br />
*'''font_family''', '''face''': A font family name.<br />
*'''font_size''', '''size''': Font size in 1024ths of a point, or one of the absolute sizes 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', or one of the relative sizes 'smaller' or 'larger'.<br />
*'''font_style''', '''style''': One of 'normal', 'oblique', 'italic'.<br />
*'''font_weight''', '''weight''': One of 'ultralight', 'light', 'normal', 'bold', 'ultrabold', 'heavy', or a numeric weight.<br />
*'''font_variant''', '''variant''': One of 'normal' or 'smallcaps'.<br />
*'''font_stretch''', '''stretch''': One of 'ultracondensed', 'extracondensed', 'condensed', 'semicondensed', 'normal', 'semiexpanded', 'expanded', 'extraexpanded', 'ultraexpanded'.<br />
*'''foreground''', '''fgcolor''', '''color''': An RGB color specification such as '#00FF00' or a color name such as 'red'.<br />
*'''background, bgcolor''': An RGB color specification such as '#00FF00' or a color name such as 'red'.<br />
*'''underline''': One of 'none', 'single', 'double', 'low', 'error'.<br />
*'''underline_color''': The color of underlines; an RGB color specification such as '#00FF00' or a color name such as 'red'.<br />
*'''rise''': Vertical displacement, in 10000ths of an em. Can be negative for subscript, positive for superscript.<br />
*'''strikethrough''': 'true' or 'false' whether to strike through the text.<br />
*'''strikethrough_color''': The color of strikethrough lines; an RGB color specification such as '#00FF00' or a color name such as 'red'<br />
*'''fallback''': 'true' or 'false' whether to enable fallback. If disabled, then characters will only be used from the closest matching font on the system. No fallback will be done to other fonts on the system that might contain the characters in the text. Fallback is enabled by default. Most applications should not disable fallback.<br />
*'''letter_spacing''': Inter-letter spacing in 1024ths of a point.<br />
*'''gravity''': One of 'south', 'east', 'north', 'west', 'auto'.<br />
*'''gravity_hint''': One of 'natural', 'strong', 'line'.<br />
<br />
<br />
In 1.6, Wesnoth uses older text formatting options<br />
* A tilde (~) as the first character causes the line to be boldfaced.<br />
* An at symbol (@) as the first character causes the line to be green, as done with victory conditions.<br />
* A pound symbol (#) as the first character causes the line to be red, as done with defeat conditions.<br />
* An asterisk (*) as the first character causes the line to be bigger.<br />
* A backquote (`) as the first character causes the line to be smaller.<br />
* If used, the caption key text is boldfaced.<br />
* An RGB colour code in the beginning causes the line to be the given colour. This can still be preceded by the above characters. Example: ''message=_"<255,0,0>Red!"''<br />
<br />
== [objectives] ==<br />
The other tag used for plot development is '''[objectives]'''.<br />
The '''[objectives]''' tag overwrites any previously set objectives,<br />
and displays text which should describe the objectives of the scenario.<br />
Scenario objectives are displayed on the player's first turn after the tag is used,<br />
or as part of the event if it triggers during that player's turn.<br />
Objectives can also be accessed at any time in a scenario using the<br />
"Scenario Objectives" game menu option, making this tag useful for<br />
scenario-specific information that the player may need to refer to during play.<br />
<br />
This tag renders the ''objectives'' attribute of [scenario] obsolete (see ''objectives'', [[ScenarioWML]]).<br />
Instead of using ''objectives'', use '''[objectives]''' to set scenario objectives inside a prestart event.<br />
It can also be used to overwrite the starting objectives mid-scenario.<br />
<br />
Attributes of '''[objectives]''':<br />
* '''side''': Default '0'. The side to set the objectives for. A value of 0 sets objectives for all sides.<br />
* '''summary''': Displayed first in the objectives text, this should describe the basic objective for the overall scenario. Can be omitted.<br />
* '''note''': Displayed last in the objectives text, this is sometimes used for hints or additional information. Can be omitted.<br />
* '''victory_string''': Default ' _ "Victory:"', this text precedes the victory objectives.<br />
* '''defeat_string''': Default ' _ "Defeat:"', this text precedes the defeat objectives.<br />
* '''gold_carryover_string''' {{DevFeature1.9}}: Default ' _ "Gold carryover:"', this text precedes the gold carryover information.<br />
* '''notes_string''' {{DevFeature1.9}}: Default ' _ "Notes:"', this text precedes the notes.<br />
* '''silent''': Default: not present. If set to "yes", the objectives are silently changed. Else, they will be shown to the user when appropriate.<br />
<br />
Tags of '''[objectives]''':<br />
* '''[objective]''': describes a win or loss condition. Most scenarios have multiple win or loss conditions, so use a separate [objective] subtag for each line; this helps with translations.<br />
** '''description''': text for the specific win or loss condition.<br />
** '''condition''': The color and placement of the text. Values are 'win'(colored green, placed after ''victory_string'') and 'lose'(colored red, placed after ''defeat_string'')<br />
** '''show_turn_counter''' {{DevFeature1.9}}: If set to yes, displays the number of turns remaining in the scenario. Default is no.<br />
** '''[show_if]''': A condition that disables the objective if it doesn't hold. Conditional objectives are refreshed at '''[show_objectives]''' time only. {{DevFeature}}<br />
* '''[gold_carryover]''' {{DevFeature1.9}}: describes how the gold carryover works in this scenario. This is intended to be a more convenient way of displaying carryover information than using the note= key in [objectives].<br />
** '''bonus''' (boolean): whether an early finish bonus is granted. If omitted, early finish bonus is not mentioned.<br />
** '''carryover_percentage''': the amount of carryover gold. If omitted, the amount is not mentioned.<br />
* '''[note]''' {{DevFeature1.9}}: describes a note, usually used for hints or additional information. This is an easier way of adding several notes than concatenating them together into a single string to use with the ''note='' key.<br />
** '''description''': the text of the note.<br />
<br />
=== Macros ===<br />
There are a few predefined macros for Objectives that you can use to shorten the code: [http://www.wesnoth.org/macro-reference.xhtml#SET_OBJECTIVES SET_OBJECTIVES], [http://www.wesnoth.org/macro-reference.xhtml#VICTORY_CONDITION VICTORY_CONDITION], and [http://www.wesnoth.org/macro-reference.xhtml#DEFEAT_CONDITION DEFEAT_CONDITION]. Follow the links for each one to see complete syntax and example usage.<br />
<br />
== [set_menu_item] ==<br />
This tag is used to add a custom option in the right-click context menu which can then be used to trigger arbitrary WML commands.<br />
<br />
'''Note:''' Due to limitations in portable devices where there are no scroll bars for context menus, there is a hard-coded limit of 7 custom WML menu items. If you really need to have more than 7 menu items, try combining some of them in a submenu.<br />
<br />
* '''id''': the unique id for this menu item. If a menu item with this id already exists, it allows you to set specific changes to that item.<br />
* '''description''': the in-game text that will appear for this item in the menu.<br />
* '''image''': the image to display next to this item.<br />
* '''needs_select''': if ''yes'' (default ''no''), then the latest select event (see [[EventWML]]) that triggered before this menu item was chosen will be transmitted over the network before this menu item action will be. This only has any effect in networked multiplayer, and is intended to allow more elaborate menu item behaviour there without causing out of sync errors. If you don't know what this means, just leave it false.<br />
* '''[show_if]''': If present, the menu item will only be available if the conditional statement (see [[InternalActionsWML]]) within evaluates to true. When this is evaluated, the WML variables ''$x1'' and ''$y1'' will point to the location on which the context menu was invoked, so it's possible to for example only enable the option on empty hexes or on a particular unit.<br />
* '''[filter_location]''': contains a location filter similar to the one found inside Single Unit Filters (see [[FilterWML]]). The menu item will only be available on matching locations.<br />
* '''[command]''': contains the WML actions to be executed when the menu item is selected. Again, the WML variables ''$x1'' and ''$y1'' will point to the location on which the context menu was invoked on.<br />
<br />
== Other interface tags ==<br />
<br />
The following tags are also action tags:<br />
=== [item] ===<br />
Makes a graphical item appear on a certain hex. Note this only places the graphics for an item. It does not make the item do anything. Use a moveto event to make moving onto the item do something. <tt>''('''Hint:''' There are a number of predefined items that are used in various campaigns that you can make use of. You can find [http://www.wesnoth.org/macro-reference.xhtml#file:items.cfg a list of them] if you look into the items.cfg file in the wesnoth install directory (under /data/core/macros))''</tt><br />
* '''x''', '''y''': the location to place the item.<br />
* '''image''': the image (in ''images/'' as .png) to place on the hex.<br />
* '''halo''': an image to place centered on the hex. Use this instead of ''image'' if the image is bigger than the hex or if you want to animate an image. ''Example (where the integer after the colon is the duration of each frame): halo=scenery/fire1.png:100,scenery/fire2.png:100,scenery/fire3.png:100,scenery/fire4.png:100,scenery/fire5.png:100,scenery/fire6.png:100,scenery/fire7.png:100,scenery/fire8.png:100''<br />
* '''team_name''': name of the team for which the item is to be displayed (hidden for others). For multiple teams just put all the names in one string, for example separated by commas.<br />
* '''visible_in_fog''': whether the item should be visible through fog or not. Default yes.<br />
=== [removeitem] ===<br />
Removes any graphical items on a given hex. (In version 1.9.2, this was renamed to '''[remove_item]''')<br />
* '''x''', '''y''': the hex to remove items off<br />
* '''image''' if specified, only removes the given image item (This image name must include any [[ImagePathFunctionWML|image path functions]] appended to the original image name.)<br />
=== [print] ===<br />
Displays a message across the screen. The message will disappear after a certain time.<br />
* '''text''': (translatable) the text to display.<br />
* '''size''': (default=12) the pointsize of the font to use<br />
* '''duration''': (default=50) the length of time to display the text for. This is measured in the number of 'frames'. A frame in Wesnoth is usually displayed for around 30ms.<br />
* '''red''', '''green''', '''blue''': (default=0,0,0) the color to display the text in. Values vary from 0-255.<br />
=== [move_unit_fake] ===<br />
Moves an image of a unit along a certain path on the map. The path does not need to be a continuous list of adjacent hexes, so for example only the start and end points can be given, in which case the straightest line between those points will be calculated and used.<br />
* '''type''': the type of the unit whose image to use<br />
* '''x''': a comma-separated list of x locations to move along<br />
* '''y''': a comma-separated list of y locations to move along (x and y values are matched pairs)<br />
* '''side''': the side of the fake unit, used for team-coloring the fake unit<br />
* '''gender''': the gender of the fake unit. Example: gender=female<br />
* '''variation''': the variation of the fake unit. Example: variation=undead<br />
* '''image_mods''': {{DevFeature1.9}} [[ImagePathFunctionWML|image path functions]] sequence to be applied on the fake unit.<br />
=== [move_units_fake] ===<br />
{{DevFeature1.9}} moves multiple images of units along paths on the map. These units are moved in lockstep.<br />
* '''[fake_unit]''': A fake unit to move<br />
** '''type''': the type of unit whose image to use<br />
** '''x''': a comma-separated list of x locations to move along<br />
** '''y''': a comma-separated list of y locations to move along (x and y values are matched pairs)<br />
** '''side''': the side of the fake unit, used for team-coloring the fake unit<br />
** '''skip_steps''': the number of steps to skip before this unit starts moving<br />
=== [hide_unit] ===<br />
Temporarily prevents the engine from displaying the given unit. The unit does not become invisible, as it would be with the '''[hides]''' ability; it is still the same plain unit, but without an image. Useful in conjunction with '''[move_unit_fake]''': to move a leader unit into position on-screen. Until 1.8 each '''[hide_unit]''' tag only hides one unit.<br />
* '''x''', '''y''': location of the unit to be hidden. (NOT a standard unit filter! Just x and y.)<br />
* {{DevFeature1.9}}: '''[hide_unit]''' accepts a [[StandardUnitFilter]] as argument and can disable several units at once.<br />
<br />
=== [unhide_unit] ===<br />
Stops the currently hidden units from being hidden.<br />
* {{DevFeature1.9}}: '''[unhide_unit]''' accepts a [[StandardUnitFilter]] as argument.<br />
=== [scroll] ===<br />
Scroll a certain number of pixels in a given direction. Useful for earthquake/shaking effects.<br />
* '''x''', '''y''': the number of pixels to scroll along the x and y axis<br />
=== '''[scroll_to]''' ===<br />
Scroll to a given hex<br />
* '''x''', '''y''': the hex to scroll to<br />
* '''check_fogged''': whether to scroll even to locations covered in fog or shroud. Possible values ''true'' (don't scroll to fog) and ''false'' (scroll even to fog), with ''false'' as the default.<br />
=== [scroll_to_unit] ===<br />
Scroll to a given unit<br />
* [[StandardUnitFilter]]<br />
* '''check_fogged''': whether to scroll even to locations covered in fog or shroud. Possible values ''true'' (don't scroll to fog) and ''false'' (scroll even to fog), with ''false'' as the default.<br />
=== [select_unit] ===<br />
{{DevFeature1.9}} Selects a given unit.<br />
* [[StandardUnitFilter]]<br />
* '''fire_event''': whether a ''select'' event should be triggered or not (def. ''no'').<br />
* '''highlight''': whether the unit's current hex should be highlighted (def. ''yes'').<br />
=== [sound]===<br />
Plays a sound<br />
* '''name''': the filename of the sound to play (in ''sounds/'' as .wav or .ogg)<br />
* '''repeat''': repeats the sound for a specified additional number of times (default=0)<br />
=== [sound_source] ===<br />
Creates a sound source. "Sound sources" is a general name for a mechanism which makes possible for map elements to emit sounds according to some rules, where "map elements" can be specific locations or terrain types. For now, only sound sources tied to locations are supported.<br />
* '''id''': a unique identification key of the sound source<br />
* '''sounds''': a list of comma separated, randomly played sounds associated with the sound source<br />
* '''delay''': a numerical value (in milliseconds) of the minimal delay between two playbacks of the source's sound if the source remains visible on the screen; if one scrolls out and back in, the source will be considered as ready to play<br />
* '''chance''': a percentage (a value from 0 to 100) describing the chance of the source being activated every second after the delay has passed or when the source's location appears on the screen (note that it cannot play more than one file at the same time)<br />
* '''check_fogged''': possible values "true" and "false" - if true the source will not play if its locations are fogged<br />
* '''check_shrouded''': {{DevFeature}} possible values "true" and "false" - if true the source will not play if its locations are shrouded<br />
* '''x,y''': similar to x,y as found in a [[StandardLocationFilter]], these are the locations associated with the sound source<br />
* '''fade_range''' (default = 3): distance in hexes that determines a "circular" area around the one specified by '''full_range''' where sound volume fades out linearly<br />
* '''full_range''' (default = 14): distance in hexes that determines a "circular" area where source plays with full volume, relative to screen center<br />
* '''loop''': number of times a sound sample should be looped if it stays visible. -1 means infinite (~65000)<br />
<br />
=== [remove_sound_source] ===<br />
Removes a previously defined sound source.<br />
* '''id''': the identification key of the sound source to remove<br />
<br />
=== [music]===<br />
Switches to playing different music<br />
* '''name''': the filename of the music to play (in ''music/'' as .ogg)<br />
* see [[MusicListWML]] for the correct syntax<br />
===[volume]===<br />
{{DevFeature1.9}} Changes the game volume to a percent of the preferences volume for the game being played. Values can go from 0 to 100: <br />
* '''music''': Changes the music volume.<br />
* '''sound''': Changes the sound volume.<br />
=== [colour_adjust]===<br />
Tints the color of the screen. {{DevFeature1.9}}: now named '''[color_adjust]'''.<br />
* '''red''', '''green''', '''blue''': values from -255 to 255, the amount to tint by for each color<br />
=== [delay] ===<br />
Pauses the game.<br />
* '''time''': the time to pause in milliseconds<br />
=== [redraw] ===<br />
Redraws the screen (this normally isn't done during events, although some of the other interface actions cause the screen or parts of it to be redrawn).<br />
* '''side''': if used, recalculates fog and shroud for that side. Useful if you for example spawn friendly units in the middle of an event and want the shroud to update accordingly (otherwise units that spawn inside fog would remain invisible for the duration of the event, since the fog would not automatically get cleared around them).<br />
=== [unit_overlay] ===<br />
Sets an image that will be drawn over a particular unit, and follow it around<br />
* '''x''', '''y''': the location of the unit to overlay on<br />
* '''image''': the image to place on the unit<br />
* {{DevFeature1.9}}: '''[unit_overlay]''' accepts a [[StandardUnitFilter]] as argument<br />
=== [remove_unit_overlay] ===<br />
removes a particular overlayed image from a unit<br />
* '''x''', '''y''': the location of the unit to remove an overlay from<br />
* '''image''': the image to remove from the unit<br />
* {{DevFeature1.9}}: '''[remove_unit_overlay]''' accepts a [[StandardUnitFilter]] as argument<br />
=== [animate_unit] ===<br />
Uses an animation of a unit to animate it on screen (if the unit has the corresponding animation).<br />
* '''flag''': The key to find the custom animation in the unit description (see the '''[extra_anim]''' description in [[AnimationWML]]). Standard animations can be triggered with the following keywords: ''leading recruited standing idling levelin levelout healing healed poisoned movement defend attack death victory pre_teleport post_teleport''<br />
* '''[filter]''' with a [[StandardUnitFilter]] as argument, see [[FilterWML]]. By default, the unit at the event location will be animated. You can use this tag to choose any other unit to animate.<br />
* '''[primary_attack]''': If this tag is not present, the filter for animation will be triggered with no attack. If it is here, all attacks from the unit will be filtered, and a matching one will be used to filter the animation. Takes a weapon filter as argument, see [[FilterWML]].<br />
* '''[secondary_attack]''': Similar to '''[primary_attack]'''. May be needed to trigger a defense animation correctly, if there are more than one animations available for the defending unit.<br />
* '''hits''': yes/no/hit/miss/kill: which according variation of a attack/defense animation shall be chosen (required)<br />
* '''text''': a text to hover during the animation <br />
* '''red''': red value for the text color (0-255)<br />
* '''green''': green value for the text color<br />
* '''blue''': blue value for the text color<br />
* '''with_bars''': yes/no: whether to display the status bars during the animation (e.g. the hitpoint bar)<br />
* '''[animate]''': a sub block with the same syntax as '''[animate_unit]''' except that the '''[filter]''' block is mandatory to find the unit. This block will find and animate another unit simultaneously.<br />
* '''[facing]''': a [[StandardLocationFilter]] specifying what direction the unit should be facing when animated<br />
=== [label] ===<br />
Places a label on the map.<br />
* '''x''', '''y''': the location of the label<br />
* '''text''': what the label should say<br />
* '''team_name''': if specified, the label will only be visible to the given team.<br />
* '''colour''': color of the label. The format is r,g,b; r, g and b are numbers between 0 and 255. {{DevFeature1.9}}: now named '''color'''.<br />
* '''visible_in_fog''': whether the label should be visible through fog or not. Default yes.<br />
* '''visible_in_shroud''': whether the label should be visible through shroud or not. Default no.<br />
* '''immutable''': whether this label is protected from being removed or changed by players. Default yes. {{DevFeature1.9}}<br />
=== [floating_text]===<br />
{{DevFeature1.9}} Floats text (similar to the damage and healing numbers) on the given locations.<br />
* [[StandardLocationFilter]]: the text will be floated on all matching locations simultaneously.<br />
* '''text''': the text to display.<br />
=== [deprecated_message] ===<br />
Shows a deprecated message in the message area, this feature is only intended to be used to warn about deprecated macros in mainline. The message is not translatable.<br />
* '''message''': the message to show.<br />
=== [wml_message] ===<br />
Outputs a message to Wesnoth's console output. Intended for campaign designers to output silent text to the console, without annoying the player; then, that text might contain information useful for later bug-reporting. The log domain for it is '''wml''', and the '''debug/dbg''' log level is available for use with the '''logger''' attribute. Depending on the current log level ('''error''' by default), which may be changed with the in-game :log command, or the --log-<level>=wml command line switch, the messages are echoed to the in-game chat.<br />
* '''message''': the message to show.<br />
* '''logger''': the Wesnoth engine output logger that should catch the text; this might be 'err' (the errors log level), 'warn'/'wrn' (the warnings log level) or anything else (the information log level). Not all information will be displayed depending on the log level chosen when starting Wesnoth.<br />
=== [open_help] ===<br />
Opens the in-game help.<br />
* '''topic''': the id of the topic to open<br />
=== [show_objectives] ===<br />
{{DevFeature}} refreshes the objectives defined by [objectives] and its [show_if] tags, and displays them. (It is also called whenever the user explicitly asks for the objectives; this matters only if the tag was overridden by a [[LuaWML#register_wml_action|Lua]] script.)<br />
* '''side''': the side to show the objectives. If not set, all sides are used.<br />
=== [chat] ===<br />
Displays a message in the chat area. {{DevFeature1.9}}<br />
* '''speaker''': A string for the name of the sender of the message.<br />
* '''message''': The message that should be displayed<br />
* '''side''': A comma separated list of sides to show the message to. If the same machine controls multiple sides that are in this list, then the message will only be displayed once. If left blank the message will be send to all sides.<br />
<br />
== Useful Macros ==<br />
There are some predefined macros that you find useful for interface actions. You can find a complete list along with a detailed explanation of how they work [http://www.wesnoth.org/macro-reference.xhtml here].<br />
* '''{FLOATING_TEXT}''' Float some text over a unit similar to the damage numbers.<br />
* '''{HIGHLIGHT_UNIT}''' Highlight a unit on the map. Use this to show important units<br />
* '''{HIGHLIGHT_IMAGE}''' Places and highlights an image on the map. Use this to show important items or locations<br />
* '''{SET_IMAGE}''' Places an image on the map which has no other function.<br />
* '''{QUAKE <soundfile>}''' Creates a tremor like screenshake and plays <soundfile>. ('''{TREMOR}''' is a deprecated version, equivalent to '''{QUAKE (rumble.ogg)}''')<br />
* '''{FLASH_WHITE}''' Flash the screen white momentarily. You can also replace WHITE with RED, BLUE or GREEN for a different colour.<br />
<br />
== See Also ==<br />
* [[DirectActionsWML]]<br />
* [[InternalActionsWML]]<br />
* [[EventWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]<br />
[[Category: ActionsWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ReferenceWML&diff=40041ReferenceWML2011-01-11T19:44:32Z<p>Paŭlo: /* WML toplevel tags */ terrain -> terrain_type</p>
<hr />
<div>{{WML Tags}}<br />
== The Wesnoth Markup Language ==<br />
<br />
The Wesnoth Markup Language (WML) is used to code almost everything in Wesnoth, including scenarios, units, savefiles, and the user interface layout. WML files are simple, human-readable text files, usually with the .cfg extension, with similarities to INI files and XML. A major feature in WML are macros, which are alike those found in the C language and similarily are handled by a preprocessor. Implementation-wise, WML files are handled mainly by the ''config'' class (and ''simple_wml'' in [[wesnothd]]).<br />
<br />
This page is a collection of pointers to different common WML structures. See [[AlphabeticalWML]] for a quick listing of all WML tags. The more comprehensive [[BuildingScenariosIndex]] lists tags and keys.<br />
<br />
See [[BuildingScenarios]], [[BuildingCampaigns]] and [[BuildingUnits]]<br />
for a tutorial style overview.<br />
<br />
<br />
<br />
''Note: this reference may contain slight inaccuracies, might not list all existing keys and tags or might contain some deprecated syntax. If you find that this reference doesn't give you the answer to how to implement some feature in WML, the most reliable way is to look at the WML code of existing units and campaigns that have done so.''<br />
<br />
== How WML works ==<br />
<br />
* [[SyntaxWML]] the language syntax.<br />
** [[VariablesWML]] how to use WML variables<br />
* [[PreprocessorRef]] the WML preprocessor syntax<br />
** [[UtilWML]] utility macros defined in utils.cfg<br />
<br />
== WML toplevel tags ==<br />
<br />
* [[GameConfigWML]] the top level '''[game_config]''' tag<br />
* [[UnitsWML]] the top level '''[units]''' tag<br />
** [[UnitTypeWML]] how to describe a unit type<br />
** [[AnimationWML]] how to animate units<br />
* [[CampaignWML]] the top level '''[campaign]''' tag<br />
* [[ScenarioWML]] the top level tags '''[scenario]''', '''[multiplayer]''', '''[test]''', and '''[tutorial]'''<br />
** [[EventWML]] how to describe an event<br />
** [[SideWML]] how to describe a side<br />
** [[MapGeneratorWML]] the random map generator<br />
** [[TimeWML]] how to describe a day<br />
** [[IntroWML]] how to describe the intro screen<br />
* [[SavefileWML]] a description of the format of savegames<br />
** [[ReplayWML]] a description of the format of player actions such as moving a unit<br />
** [[StatisticalScenarioWML]] used to generate statistics of a savegame<br />
* [[PblWML]] a description of the format of server-uploadable campaigns<br />
* [[EraWML]] the top level '''[era]''' tag<br />
* [[TerrainWML]] the top level '''[terrain_type]''' tag<br />
* [[TerrainGraphicsWML]], the top level '''[terrain_graphics]''' tag<br />
* [[ThemeWML]] the top level '''[theme]''' tag<br />
* [[LanguageWML]] the top level '''[language]''' tag<br />
* [[LocaleWML]] the top level '''[locale]''' tag<br />
* [[HelpWML]] the top level '''[help]''' tag<br />
* [[BinaryPathWML]] the top level '''[binary_path]''' tag<br />
* [[FontsWML]] the top level '''[fonts]''' tag<br />
<br />
== Other WML tags ==<br />
<br />
* [[EventWML]] how to describe an event<br />
** [[FilterWML]] the construct to filter on units, locations, and weapons<br />
** [[ActionWML]] to describe the actions which occur when the event is fired<br />
*** [[ConditionalActionsWML]] actions that encapsulate conditional filters and the actions to execute if the conditions are met<br />
*** [[DirectActionsWML]] actions that directly affect gameplay: for example creating a unit<br />
**** [[SingleUnitWML]] how to describe a unit<br />
*** [[InternalActionsWML]] actions that WML uses internally: for example storing a variable<br />
*** [[InterfaceActionsWML]] actions that do not affect gameplay: for example displaying a message<br />
*** [[LuaWML]] how to code actions with the Lua language<br />
* [[AiWML]] how to describe parameters for AI<br />
* [[EffectWML]] the construct to modify a unit<br />
* [[AbilitiesWML]] a list of the different abilities a unit or weapon can have<br />
* [[DescriptionWML]] the structure of WML coded menus like the difficulty chooser of campaigns<br />
* [[EditorWML]] tags controlling the post-1.4 editor's behavior<br />
<br />
== Predefined macros == <br />
<br />
Wesnoth ships with a library of predefined macros you should find useful in writing your own WML. You can find a description of all such macros [http://www.wesnoth.org/macro-reference.html here].<br />
<br />
== Other ==<br />
<br />
* [[ReferenceWMLSyntax]] how this wiki and the pages it links to should be formatted<br />
* [[ConventionsWML]] how to make your WML more readable<br />
* [[UsefulWMLFragments]] Various pieces of WML for various purposes. If you have some WML you're proud of that you think others can use, add it here.<br />
* [[CommandMode]] commands are not strictly speaking part of WML, these could be a little hard to find so there's a link here.<br />
* [[MultiplayerServerWML]] is used when communicating with the multiplayer server.<br />
* [[CampaignServerWML]] is used when managing contributed campaigns on the campaign server.<br />
* [[ImagePathFunctionWML]] is used when applying the team-color function to images.<br />
* [[BinaryWML]] how WML is sent over the network<br />
<br />
== See Also ==<br />
<br />
* [[BuildingMaps]] the text-based format for Wesnoth maps<br />
* [[TerrainCodesWML]] a list of all terrains<br />
* [[MultiHexTutorial]] a description of the multi-hex tiling system<br />
* [[IGNFileFormat]] a description of the ignore file format<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=Template:WML_Tags&diff=40040Template:WML Tags2011-01-11T19:43:55Z<p>Paŭlo: terrain -> terrain_type</p>
<hr />
<div>{| class="gallery" style="width:225px;float: right;border: 1px solid #B48648; color:#B48648; font-size: 7pt;margin-left;10px;"<br />
|-<br />
|<br />
<span style="float: right;"><small class="editlink noprint plainlinksneverexpand">[{{SERVER}}{{localurl:Template:WML Tags|action=edit}} edit ]</small></span><br />
'''WML Tags'''<br />
<br />
|-<br />
|''A:'' <br />
[[AbilitiesWML|abilities]],<br />
[[CampaignWML|about]],<br />
[[AdvancedPreferenceWML|advanced_preference]],<br />
[[UnitTypeWML|advancefrom]],<br />
[[UnitTypeWML|advancement]],<br />
[[StatisticalScenarioWML|advances]],<br />
[[AiWML|ai]],<br />
[[DirectActionsWML#.5Ballow_recruit.5D|allow_recruit]],<br />
[[DirectActionsWML#.5Ballow_undo.5D|allow_undo]],<br />
[[ConditionalActionsWML#Meta_Condition_Tags|and]],<br />
[[InterfaceActionsWML|animate_unit]],<br />
[[AnimationWML|animation]],<br />
[[VariablesWML|array]],<br />
[[UnitTypeWML|attack]],<br />
[[AnimationWML|attack_filter]], <br />
[[StatisticalScenarioWML|attacks]],<br />
[[AiWML|avoid]];<br />
|-<br />
|''B:'' <br />
[[UnitTypeWML|base_unit]], [[BinaryPathWML|binary_path]], [[HelpWML|bold]], [[EditorWML|brush]];<br />
|-<br />
|''C:'' <br />
[[CampaignWML#The_.5Bcampaign.5D_tag|campaign]],<br />
[[DirectActionsWML#.5Bcapture_village.5D|capture_village]],<br />
[[ConditionalActionsWML#.5Bswitch.5D|case]],<br />
[[InterfaceActionsWML|chat]],<br />
[[ReplayWML|choose]],<br />
[[PersistenceWML|clear_global_variable]],<br />
[[InternalActionsWML|clear_variable]],<br />
[[InterfaceActionsWML|colour_adjust]],<br />
command([[InterfaceActionsWML|action]], [[ReplayWML|replay]]);<br />
|-<br />
|''D:'' <br />
[[AbilitiesWML|damage]],<br />
[[StatisticalScenarioWML|deaths]],<br />
[[AnimationWML|defend]],<br />
[[StatisticalScenarioWML|defends]],<br />
[[UnitTypeWML|defense]],<br />
[[InterfaceActionsWML|delay]],<br />
[[ReplayWML|destination]],<br />
[[DirectActionsWML#.5Bdisallow_recruit.5D|disallow_recruit]],<br />
[[ConditionalActionsWML#.5Bwhile.5D|do]];<br />
|-<br />
|''E:'' <br />
[[EditorWML|editor_group]],<br />
[[EditorWML|editor_music]], <br />
[[EditorWML|editor_times]],<br />
[[EditorWML|editor_tool_hint]],<br />
[[EffectWML|effect]],<br />
[[ConditionalActionsWML#Conditional_Actions|else]],<br />
[[DirectActionsWML#.5Bendlevel.5D|endlevel]],<br />
end_turn&nbsp;([[DirectActionsWML#.5Bend_turn.5D|action]], [[ReplayWML|replay]]),<br />
[[EraWML|era]],<br />
[[EventWML|event]],<br />
[[ThemeWML|expenses]];<br />
|-<br />
|''F:'' <br />
[[EventWML#.5Bfilter.5D|filter]],<br />
[[FilterWML|filter]],<br />
[[AnimationWML|filter_attack]],<br />
[[EventWML#.5Bfilter_attack.5D|filter_attack]],<br />
[[EventWML#.5Bfilter_condition.5D|filter_condition]],<br />
[[FilterWML|filter_location]],<br />
[[EventWML#.5Bfilter_second.5D|filter_second]],<br />
[[FilterWML|filter_second]],<br />
[[AnimationWML|filter_second_attack]],<br />
[[EventWML#.5Bfilter_second_attack.5D|filter_second_attack]],<br />
[[FilterWML#Filtering_Vision|filter_vision]],<br />
[[StandardUnitFilter|filter_wml]],<br />
[[InternalActionsWML|fire_event]],<br />
[[InterfaceActionsWML|floating_text]],<br />
[[HelpWML|format]],<br />
[[AnimationWML|frame]];<br />
|-<br />
|''G:'' <br />
[[GameConfigWML|game_config]],<br />
[[ScenarioWML|generator]],<br />
[[PersistenceWML|get_global_variable]],<br />
[[DirectActionsWML|gold]],<br />
[[ThemeWML|gold]];<br />
|-<br />
|''H:'' <br />
[[DirectActionsWML#.5Bharm_unit.5D|harm_unit]],<br />
[[ConditionalActionsWML#Condition_Tags|have_location]],<br />
[[ConditionalActionsWML#Condition_Tags|have_unit]],<br />
[[HelpWML|header]],<br />
[[DirectActionsWML#.5Bheal_unit.5D|heal_unit]],<br />
[[UnitsWML|hide_help]],<br />
[[InterfaceActionsWML|hide_unit]];<br />
|-<br />
|''I:'' <br />
[[ConditionalActionsWML#.5Bif.5D|if]],<br />
[[TimeWML|illuminated_time]],<br />
[[TerrainGraphicsWML|image]],<br />
[[HelpWML|img]],<br />
[[ThemeWML|income]],<br />
[[ReplayWML|init_side]],<br />
[[InternalActionsWML|insert_tag]],<br />
[[InterfaceActionsWML#.5Binspect.5D|inspect]],<br />
[[HelpWML|italic]],<br />
[[InterfaceActionsWML|item]];<br />
|-<br />
|''J:''<br />
[[HelpWML|jump]],<br />
[[InternalActionsWML|join]];<br />
|-<br />
|''K:'' <br />
[[DirectActionsWML#.5Bkill.5D|kill]],<br />
[[StatisticalScenarioWML|killed]];<br />
|-<br />
|''L:'' <br />
label&nbsp;([[InterfaceActionsWML|map]], [[ThemeWML|theme]]),<br />
[[LanguageWML|language]],<br />
[[AiWML|leader_goal]],<br />
[[LocaleWML|locale]],<br />
[[LuaWML|lua]];<br />
|-<br />
|''M:'' <br />
[[ThemeWML|main_map]],<br />
[[ThemeWML|menu]],<br />
[[InterfaceActionsWML|message]],<br />
[[ThemeWML|mini_map]],<br />
[[AnimationWML|missile_frame]],<br />
[[SingleUnitWML|modifications]],<br />
[[DirectActionsWML#.5Bmodify_side.5D|modify_side]],<br />
[[DirectActionsWML#.5Bmodify_turns.5D|modify_turns]],<br />
[[ReplayWML|move]],<br />
[[DirectActionsWML#.5Bmove_unit.5D|move_unit]],<br />
[[DirectActionsWML#.5Bmodify_ai.5D|modify_ai]],<br />
[[DirectActionsWML#.5Bmodify_unit.5D|modify_unit]],<br />
[[InterfaceActionsWML|move_unit_fake]],<br />
[[UnitTypeWML|movement costs]],<br />
[[UnitsWML|movetype]],<br />
[[ScenarioWML|multiplayer]],<br />
[[EraWML|multiplayer_side]],<br />
[[MusicListWML|music]];<br />
|-<br />
|''N:'' <br />
[[ConditionalActionsWML#Meta_Condition_Tags|not]],<br />
[[FilterWML|not]],<br />
[[ThemeWML|num_units]];<br />
|-<br />
|''O:'' <br />
[[DirectActionsWML#.5Bobject.5D|object]],<br />
[[InterfaceActionsWML|objectives]],<br />
[[InterfaceActionsWML|objective]],<br />
[[ThemeWML|observers]],<br />
[[InterfaceActionsWML|open_help]],<br />
[[InterfaceActionsWML|option]],<br />
[[ConditionalActionsWML#Meta_Condition_Tags|or]];<br />
|-<br />
|''P:'' <br />
[[ThemeWML|panel]], [[IntroWML|part]], [[DirectActionsWML#.5Bpetrify.5D|petrify]], [[DirectActionsWML#.5Bplace_shroud.5D|place_shroud]], [[ThemeWML|position]],<br />
[[InterfaceActionsWML|print]], [[AiWML|protect_location]], [[AiWML|protect_unit]];<br />
|-<br />
|''R:'' <br />
[[UnitsWML|race]], [[ReplayWML|random]], recall&nbsp;([[DirectActionsWML#.5Brecall.5D|action]], <br />
[[ReplayWML|replay]]), [[StatisticalScenarioWML|recalls]],<br />
[[ReplayWML|recruit]], [[StatisticalScenarioWML|recruits]], [[InterfaceActionsWML|redraw]],<br />
[[HelpWML|ref]], [[DirectActionsWML|remove_shroud]], [[InterfaceActionsWML|remove_unit_overlay]],<br />
[[InterfaceActionsWML|removeitem]], [[InterfaceActionsWML|remove_sound_source]], <br />
[[DirectActionsWML#.5Breplace_map.5D|replace_map]], [[DirectActionsWML#.5Breplace_schedule.5D|replace_schedule]], [[SavefileWML|replay]], [[SavefileWML|replay_start]],<br />
[[UnitTypeWML|resistance]], [[ThemeWML|resolution]], [[ReplayWML|results]], [[InternalActionsWML|role]];<br />
|-<br />
|''S:'' <br />
[[SavefileWML|save]], [[ScenarioWML|scenario]],<br />
[[InterfaceActionsWML|scroll]], [[InterfaceActionsWML|scroll_to]],<br />
[[InterfaceActionsWML|scroll_to_unit]], [[AnimationWML|secondary_attack_filter]], [[AnimationWML|secondary_unit_filter]], [[HelpWML|section]], [[InterfaceActionsWML|select_unit]], [[PersistenceWML|set_global_variable]],<br />
[[InterfaceActionsWML#.5Bset_menu_item.5D_.28SVN_trunk_only.29|set_menu_item]], [[DirectActionsWML#.5Bset_recruit.5D|set_recruit]],<br />
[[InternalActionsWML|set_variable]], [[InternalActionsWML|set_variables]], [[InterfaceActionsWML|show_objectives]],<br />
[[SideWML|side]], [[ThemeWML|side_playing]], [[SavefileWML|snapshot]],<br />
[[InterfaceActionsWML|sound]], [[InterfaceActionsWML|sound_source]], [[ReplayWML|source]], [[EventWML|special_filter]], [[EventWML|special_filter_second]],<br />
[[InternalActionsWML|split]],<br />
[[StatisticalScenarioWML#The_.5Bstatistics.5D_tag|statistics]],<br />
status([[SingleUnitWML|single unit]], [[ThemeWML|theme]]), [[InternalActionsWML#.5Bstore_gold.5D|store_gold]], [[InternalActionsWML#.5Bstore_locations.5D|store_locations]],<br />
[[InternalActionsWML#.5Bstore_map_dimensions.5D|store_map_dimensions]],<br />
[[InternalActionsWML#.5Bstore_side.5D|store_side]], [[InternalActionsWML#.5Bstore_starting_location.5D|store_starting_location]], [[InternalActionsWML#.5Bstore_time_of_day.5D|store_time_of_day]], [[InternalActionsWML#.5Bstore_unit.5D|store_unit]], [[InternalActionsWML#.5Bstore_villages.5D|store_villages]],[[IntroWML|story]],<br />
[[ConditionalActionsWML#.5Bswitch.5D|switch]];<br />
|-<br />
|''T:'' <br />
[[AiWML|target]],<br />
[[StatisticalScenarioWML#The_.5Bteam.5D_tag|team]],<br />
teleport ([[DirectActionsWML#.5Bteleport.5D|action]], [[AbilitiesWML|ability]]), [[AnimationWML|teleport_anim]],<br />
[[DirectActionsWML#.5Bterrain.5D|terrain]], [[TerrainGraphicsWML|terrain_graphics]], [[TerrainMaskWML|terrain_mask]], [[TerrainWML|terrain_type]], [[ScenarioWML#Test_scenario|test]],<br />
[[WesCamp|textdomain]], [[InterfaceActionsWML|text_input]], [[ThemeWML|theme]], [[ConditionalActionsWML#.5Bif.5D|then]],<br />
[[TerrainGraphicsWML|tile]], [[TimeWML|time]], time_area&nbsp;([[DirectActionsWML#.5Btime_area.5D|action]], [[ScenarioWML|scenario]]), <br />
[[ThemeWML|time_of_day]],<br />
[[HelpWML|topic]], [[HelpWML|toplevel]], [[SingleUnitWML|trait]], [[DirectActionsWML#.5Btunnel.5D|tunnel]] [[ThemeWML|turn]], [[ScenarioWML|tutorial]];<br />
|-<br />
|''U:'' <br />
[[InterfaceActionsWML|unhide_unit]], [[SingleUnitWML|unit]],<br />
[[ThemeWML|unit_abilities]], [[ThemeWML|unit_alignment]], [[ThemeWML|unit_description]], [[AnimationWML|unit_filter]], [[ThemeWML|unit_hp]], [[ThemeWML|unit_image]], [[ThemeWML|unit_level]], [[ThemeWML|unit_moves]],<br />
[[InterfaceActionsWML|unit_overlay]], [[ThemeWML|unit_profile]], [[ThemeWML|unit_status]],<br />
[[ThemeWML|unit_traits]], [[UnitTypeWML|unit_type]], [[ThemeWML|unit_weapons]], [[ThemeWML|unit_xp]],<br />
[[UnitsWML|units]], [[DirectActionsWML#.5Bunpetrify.5D|unpetrify]], [[DirectActionsWML#.5Bunstore_unit.5D|unstore_unit]], [[ThemeWML|upkeep]];<br />
|-<br />
| ''V:'' <br />
[[ConditionalActionsWML#Condition_Tags|variable]],<br />
[[VariablesWML|variables]],<br />
[[SideWML|village]],<br />
[[ThemeWML|villages]];<br />
|-<br />
| ''W:'' <br />
[[ConditionalActionsWML#.5Bwhile.5D|while]],<br />
[[InterfaceActionsWML|wml_message]];<br />
|}<br />
<br />
<noinclude>An box with all the WML tags, each linking to the page they are described in. This box should be included in each of the WML reference pages.</noinclude></div>Paŭlohttps://wiki.wesnoth.org/index.php?title=TerrainWML&diff=40039TerrainWML2011-01-11T19:42:23Z<p>Paŭlo: /* the toplevel [terrain] tag */ renamed to terrain_type</p>
<hr />
<div>{{WML Tags}}<br />
== the toplevel [terrain_type] tag ==<br />
<br />
Note: {{DevFeature}} Before 1.7, this was '''[terrain]'''.<br />
<br />
The [terrain_type] tag describes a terrain in WML.<br />
Terrains are usually described in the terrain.cfg file<br />
<br />
the [terrain_type] tag has the following keys and subtags<br />
* '''symbol_image''': an image used for this terrain in the minimap<br />
* '''editor_image''': an image used for this terrain in the map editor; if not defined uses symbol_image<br />
* '''name''': the name of the terrain, a translatable string used for the display of terrain type in the game and the map editor<br />
* '''description''': {{DevFeature}} the detailed description of the terrain, a translatable string used for the display of terrain type in the game and the map editor. If this is not present, the game and editor will fall back to the '''name''' attribute. The difference is that the name tends to describe the game effect of the terrain type (e.g., "Forest") but the description attribute also carries information about visual subtype (e.g. "Summer Deciduous Forest").<br />
* '''string''': this is the string that represents the terrain in maps and scenarios<br />
* '''unit_height_adjust''': how much the unit graphic should be moved up or down when on that terrain<br />
* '''submerge''': float, between 0 and 1: specifies how much of the unit graphic should be submerged by the terrain<br />
* '''light''': signed value: this will modify local light level on that hex by that amount for gameplay<br />
* '''heals''': signed value: this value is the amount of HP a unit on this terrain will be healed at the start of every turn. (If set to true a unit on that terrain will be healed 8 HP at the start of every turn, this notation is deprecated and support might be removed at some point.)<br />
* '''gives_income''': if set to true, this terrain will give income every turn when flagged, as if it were a village<br />
* '''recruit_onto''': if set to true, it is possible to recruit or recall on that terrain<br />
* '''recruit_from''': if set to true it is possible to recruit when a unit that can recruit is on that terrain<br />
* '''aliasof''': comma separated string representing terrains that this terrain will be an alias of. This is a list of characters, with the + and - signs having special meanings. the string is read left to right taking the best value. when a minus sign is encountered, it starts taking the worst instead. the plus sign reverts it back to the best (note after a + or - a comma is also required. In order to include a + sign the entire line must be placed between double quotes.)<br />
* '''def_alias''': like ''aliasof'' but overides it for defense calculation only<br />
* '''mvt_alias''': like ''aliasof'' but overides it for movement calculation only<br />
* '''income_description''': for terrains with ''gives_income'' and owned by nobody this text is shown in the terrain description in the top bar before the brackets. This tag is optional, if not supplied Wesnoth will assume the terrain is a village and sets an appropriate message.<br />
* '''income_description_ally''': like ''income_description'' but if owned by an ally<br />
* '''income_description_enemy''': like ''income_description'' but if owned by an enemy<br />
* '''income_description_own''': like ''income_description'' but if owned by yourself<br />
* '''editor_group''': a comma separated list of editor_group ids to which this terrain belongs.<br />
* '''hidden''': (boolean) if set to 'yes', makes this terrain not appear in the map editor palettes.<br />
<br />
== See Also ==<br />
<br />
* [[ReferenceWML]]<br />
* [[TerrainCodesWML]]<br />
* [[EditorGroupWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ActionWML&diff=40034ActionWML2011-01-11T13:20:57Z<p>Paŭlo: /* Where ActionWML can be used */ grammar</p>
<hr />
<div>'''ActionWML''' is a summarizing term for all '''WML actions''' which can be used in events and some other places.<br />
<br />
== Types of ActionWML ==<br />
<br />
When a tag permits ActionWML as content, this means that it permits a sequence of any of the following tags:<br />
<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
* conditional actions ([[ConditionalActionsWML]]) which contain other actions, which then are (maybe) executed ([if], [switch], [while], [command])<br />
* [event] (see [[EventWML#Nested Events|EventWML]]) which creates a new event handler<br />
** note: [event] can also be a subtag of [unit], [era] and [scenario], where it would not be counted as ActionWML (but has nearly the same syntax).<br />
* [lua] ([[LuaWML]]) which contains Lua code to be executed, and<br />
* all tags created from lua with [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] (if they don't fit in one of the categories above)<br />
<br />
When the ActionWML is executed, all its action tags are executed in order.<br />
<br />
== Where ActionWML can be used ==<br />
<br />
ActionWML can be used:<br />
* inside an [event], to define a event handler (see [[EventWML]]),<br />
* inside a [then] or [else] of an [if] tag (see [[ConditionalActionsWML]]),<br />
* inside a [case] or [else] of a [switch] tag (see [[ConditionalActionsWML]]),<br />
* inside the [do] of a [while] tag (see [[ConditionalActionsWML]]),<br />
* inside a [command] tag (in [option] or [set_menu_item] or directly as ActionWML) (see [[InterfaceActionsWML]]),<br />
* in certain Lua-created tags (if the registered WML action handler interprets the content as ActionWML).<br />
<br />
<br />
On most other places ActionWML code will either be ignored, give error messages or be interpreted differently (there may be some tags which are both ActionWML and have similar or different meanings in other places, like [event]).<br />
<br />
<br />
[[Category:ActionsWML]]<br />
[[Category:WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=Talk:ActionsWML&diff=40033Talk:ActionsWML2011-01-11T13:19:59Z<p>Paŭlo: comment about new page.</p>
<hr />
<div>== Recreation of redirect ==<br />
The page was deleted before (Feb 2008, by [[User:Esr|Esr]]) with the comment "Redirect page with no inward links".<br />
<br />
I just recreated it as a redirect to the new page [[ActionWML]], since arguably '''ActionsWML''' may be a more logical name. I still don't plan on creating any inward links, but before deleting again, please consider this. -- [[User:Paŭlo|Paŭlo]] 13:19, 11 January 2011 (UTC)</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ActionsWML&diff=40032ActionsWML2011-01-11T13:15:39Z<p>Paŭlo: new: redirect to ActionWML</p>
<hr />
<div>#REDIRECT [[ActionWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=Category:ActionsWML&diff=40030Category:ActionsWML2011-01-10T21:18:51Z<p>Paŭlo: + category WML reference</p>
<hr />
<div>Pages in this category all relate to the various types of actions that can be coded in WML.<br />
<br />
[[Category:WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ActionWML&diff=40029ActionWML2011-01-10T21:18:07Z<p>Paŭlo: + category WML Reference ... but now I really finish.</p>
<hr />
<div>'''ActionWML''' is a summarizing term for all '''WML actions''' which can be used in events and some other places.<br />
<br />
== Types of ActionWML ==<br />
<br />
When a tag permits ActionWML as content, this means that it permits a sequence of any of the following tags:<br />
<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
* conditional actions ([[ConditionalActionsWML]]) which contain other actions, which then are (maybe) executed ([if], [switch], [while], [command])<br />
* [event] (see [[EventWML#Nested Events|EventWML]]) which creates a new event handler<br />
** note: [event] can also be a subtag of [unit], [era] and [scenario], where it would not be counted as ActionWML (but has nearly the same syntax).<br />
* [lua] ([[LuaWML]]) which contains Lua code to be executed, and<br />
* all tags created from lua with [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] (if they don't fit in one of the categories above)<br />
<br />
When the ActionWML is executed, all its action tags are executed in order.<br />
<br />
== Where ActionWML can be used ==<br />
<br />
ActionWML can be used:<br />
* inside an [event], to define a event handler (see [[EventWML]]),<br />
* inside a [then] or [else] of an [if] tag (see [[ConditionalActionsWML]]),<br />
* inside a [case] or [else} of a [switch] tag (see [[ConditionalActionsWML]]),<br />
* inside the [do] of a [while] tag (see [[ConditionalActionsWML]]),<br />
* inside a [command] tag (in [option] or [set_menu_item] or directly as ActionWML) (see [[InterfaceActionsWML]]),<br />
* in certain Lua-created tags (if the registered WML action handler interprets the content as ActionWML).<br />
<br />
<br />
On most other places ActionWML code will either be ignored, give error messages or interpreted differently (there may be some tags which are both ActionWML and have similar or different meanings in other places, like [event]).<br />
<br />
<br />
[[Category:ActionsWML]]<br />
[[Category:WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=SingleUnitWML&diff=40028SingleUnitWML2011-01-10T21:04:30Z<p>Paŭlo: /* How to describe a single unit */ where to use</p>
<hr />
<div>{{WML Tags}}<br />
== How to describe a single unit ==<br />
<br />
This tag, '''[unit]''', describes a single unit on the map, for example Konrad.<br />
It is different from the [unit_type] in [units], which describes a class of units. However it takes many of the same keys and thus can generally override the inherited properties from the associated [unit_type].<br />
<br />
[unit] can be used inside [side] ([[SideWML]]) for units present at start of the scenario, or as [[DirectActionsWML]] for units created during the game. (It is also used in save-files.)<br />
<br />
The following keys are recognized:<br />
* '''type''': the ID of the unit's unit type. See [[UnitTypeWML]].<br />
<br />
* '''side''': the side that the unit is on. It has to be an existing side, even if the unit is created in a variable.<br />
<br />
* '''gender''': can be set to male or female to designate the gender of the unit. Default is male, but if the unit has only a female variant it will be female.<br />
<br />
* '''x''', '''y''': the location of the unit. By default ( see '''placement''') if a location isn't provided and the side the unit will belong to has a recall list, the unit will be created on the recall list.<br />
<br />
* '''placement''': How the unit should be placed: can be one value or a comma-separated list of values. Default value is 'map,leader' for a leader given directly in [side], "" otherwise. By default, 'map,recall' is implicitly appended to the end of the list.<br />
** '''map''': If x,y are explicitly given and point to a valid on-map location - try to place the unit at the nearest free location to there, never overwriting existing units. Successful if x,y are given and a valid on-map vacant location near it can be found.<br />
** '''leader''': Try to place unit near the leader, if leader is not present or is in recall list - try to place unit near the start location for this side. Successful if a valid on-map vacant location can be found near leader or near start location.<br />
** '''recall''': Place unit on recall list. Always successful. <br />
** '''map_overwrite''': If x,y are explicitly given and point to a valid on-map location - try to place unit at this location, if there was a unit there - overwriting it, without firing events. <br />
<br />
* '''to_variable''': creates the unit into the given variable instead of placing it on the map.<br />
<br />
* '''id''': a unique identifier for the unit. This is not displayed to the player, but is to be used only for identifying and filtering for units. If not specified or when a unit is normally recruited, a random one will be generated for the unit to ensure that each unit has a unique ''id'' attribute. In older versions, the '''description''' attribute specified a unique ID.<br />
<br />
* '''name''': the user-visible name of the unit. Note that the player may use the "rename unit" action to change this.<br />
<br />
* '''generate_name''': (default=yes) will generate a new name if there isn't one specifed for the unit, as if the unit were a freshly-recruited one<br />
<br />
* '''unrenamable''': if 'yes', the user-visible name of the unit cannot be changed by the player (which is only possible when the unit is on the player's side anyway).<br />
<br />
* '''traits_description''': the description of the unit's traits which is displayed. However if it is not specified explicitly, the unit's actual traits' names will be used instead, so it is normally not necessary to set this.<br />
<br />
* '''random_traits''': "no" will prevent random trait generation for units. You should only need to set this for placed nonleaders in multiplayer games or if you want to give a unit less traits than it would normally get for its unit type. When generating traits for a unit, first traits the unit has already been given are excluded. Then "musthave" traits (undead, mechanical) for the unit type are given. Then for leaders ('''canrecruit=yes''') traits that are not available to "any" (currently that's all of them to avoid a multiplayer OOS issue, but later will be restricted based on multiplayer play balance issues) are removed from consideration. Then traits are added randomly until the maximum allowed for the unit type is reached or there are no more available traits. Random traits can now be used in MP games but only when spawned in an event, so not for leaders and other units in the [side] definition.<br />
<br />
* '''random_gender''': "yes" will cause the gender of the unit with male and female variations to be male 50% of the time, female 50% of the time. If the unit has only one gender variant it will always be given the correct one.<br />
<br />
* '''canrecruit''': a special key for leaders.<br />
** '''no''': default. Unit cannot recruit.<br />
** '''yes''': unit can recruit.<br />
: Normally when a team controls no units with '''canrecruit=yes''', that team loses. However, even if your team has lost you continue to play with whatever units you still have until the scenario is over. Usually scenarios end when only one team is left with a leader that can recruit, but special victory conditions can be set up in campaigns. Normally you want to set the leader of a side with '''canrecruit=yes'''. If you don't want the leader to recruit, it is usually better to just not give him any unit types to recruit, than to make a special victory condition. Units with '''canrecruit=yes''' are exempt from upkeep costs. So that leaders do not need to be given the ''loyal'' trait.<br />
: More than one unit with '''canrecruit=yes''' for the same side (see [[SideWML]]) are allowed in single player, if the side is human-controlled.<br />
<br />
* '''variation''': the variation of itself the unit should be created as.<br />
<br />
* '''upkeep''': the amount of upkeep the unit costs.<br />
** '''loyal''' no upkeep cost. Can be changed by the effect 'loyal' (see [[EffectWML]])<br />
** '''full''': unit costs ''level'' upkeep (see [[UnitTypeWML]]).<br />
** An integer can be used to set the upkeep cost to that number.<br />
** The default is "full".<br />
** Leaders (units with '''canrecruit=yes''') never pay upkeep no matter what upkeep is set to.<br />
** Normally you don't want to muck with this value. If you want to give a side units without upkeep costs, give those units the 'loyal' trait.<br />
<br />
* '''overlays''': a list of images that are overlayed on the unit.<br />
<br />
* '''goto_x''':, '''goto_y''': UI settings that control courses. Default is 0,0 i.e. the unit is not on a course.<br />
<br />
* '''hitpoints''': the HP of the unit. Default is the max HP for ''type''.<br />
<br />
* '''experience''': the XP of the unit. Default is 0.<br />
<br />
* '''moves''': number of movement points the unit has left. Default is the movement for its unit type.<br />
<br />
* '''resting''': whether the unit has not moved yet this turn. Used to decide whether to give a unit rest healing.<br />
<br />
* '''role''': used in standard unit filter ([[FilterWML]]). Can be set using [role] (see [[InternalActionsWML]]).<br />
<br />
* '''ai_special''': causes the unit to act differently.<br />
** "guardian" the unit will not move, except to attack something in the turn it moves (so, it only can move if an enemy unit gets within range of it).<br />
<br />
* '''facing''': which way the unit is facing (this only affects how the unit is displayed).<br />
** Possible values are '''se''', '''s''', '''sw''', '''nw''', '''n''', '''ne'''. Using '''sw''' is preferred for a "reversed" facing (looking to the left) and '''se''' for a normal (looking to the right) facing.<br />
<br />
* '''profile''': sets a portrait image for this unit. If the unit type already has a portrait set, this is used instead for this unit. When the unit advances, if the value of profile is different from the unit-type portrait, that value is preserved. If the profile field is empty or the same as the unit-type portrait, the level-advance changes the unit portrait to the default for the new level and type. See [[UnitTypeWML]] for the rules used for locating files.<br />
** "unit_image" if given instead of a filename, uses the unit's base image as the portrait (in the same manner that unit types without portraits do by default).<br />
<br />
* '''small_profile''': {{DevFeature1.9}} sets a small portrait image for this unit. See the '''profile''' attribute above for advancement and special values. As with [[UnitTypeWML]], the location heuristic of the '''profile''' attribute is disabled when the '''small_profile''' attribute is provided.<br />
<br />
* '''animate''': if ''yes'', fades the unit in like when it's recruited/recalled.<br />
<br />
* '''[status]''' the status of the unit. This affects different features of the unit, for example whether the unit loses health each turn. Default for all keys is 'off', but this can be changed by the scenario or by special abilities (see [[AbilitiesWML]]). The status of a unit is displayed on the Status Table; each status modification ''statusmod'' is represented by the image '''misc/statusmod.png'''.<br />
** '''poisoned''': if 'yes', the unit loses 8 HP each turn. See also ''heals'', ''cures'', [[AbilitiesWML]].<br />
** '''slowed''': if 'yes', the unit has 50% of its normal movement and does half damage. When the controller of the unit's turn is over, ''slowed'' is set to 'off' <br />
** '''petrified''': if 'yes', the unit cannot move, attack, or be attacked.<br />
** '''uncovered''': if 'yes', the unit has performed an action (e.g. attacking) that causes it to no longer be hidden until the next turn.<br />
** '''guardian''': this is set to 'yes' by ai_special=guardian and clearing it will allow the unit to act normally again.<br />
** '''healable''': if set to 'no', the unit cannot be healed. {{DevFeature1.9}} ''healable'' is deprecated, use ''unhealable'' instead.<br />
** '''unhealable''': {{DevFeature1.9}} if set to 'yes', the unit cannot be healed.<br />
<br />
* '''[variables]''' a set of variables that will be stored when this unit is stored (See [store_unit], [[InternalActionsWML]]). The attribute '''variable'''='''value''' means that when the unit is stored in the array ''unit'', the variable '''unit'''.variables.''variable'' will have the value ''value'' (See [[VariablesWML]]).<br />
<br />
* '''[modifications]''' changes that have been made to the unit.<br />
** '''[trait]''' a trait the unit has. Same format as [trait], [[UnitsWML]].<br />
** '''[object]''' an object the unit has. Same format as [object], [[DirectActionsWML]].<br />
<br />
* '''unit_description''': overrides the unit type description for this unit. You will probably want to set up a ''post_advance'' [[EventWML|event]] to override the default description after promotions. Or better, use an object with a profile [[EffectWML|effect(s)]] to filter on unit type and change the unit description and/or portrait.<br />
<br />
* '''[event]''' The event is copied from the contents of the created unit to the scenario. Everything valid in [scenario][event]s is valid in [unit][event]s. warning: Contrarily to [unit_type][event]s, a [unit] tag performs variable substitution before creating the unit. This can be worked around by using $|variable_name syntax. note: [unit][event] does currently (1.8.3, 1.9.0-svn) not work.<br />
<br />
== See Also ==<br />
<br />
* [[UnitTypeWML]]<br />
* [[ReferenceWML]]<br />
<br />
[[Category:WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ReferenceWML&diff=40027ReferenceWML2011-01-10T21:02:45Z<p>Paŭlo: /* Other WML tags */ orthography, SingleUnitWML as part of DirectActionsWML</p>
<hr />
<div>{{WML Tags}}<br />
== The Wesnoth Markup Language ==<br />
<br />
The Wesnoth Markup Language (WML) is used to code almost everything in Wesnoth, including scenarios, units, savefiles, and the user interface layout. WML files are simple, human-readable text files, usually with the .cfg extension, with similarities to INI files and XML. A major feature in WML are macros, which are alike those found in the C language and similarily are handled by a preprocessor. Implementation-wise, WML files are handled mainly by the ''config'' class (and ''simple_wml'' in [[wesnothd]]).<br />
<br />
This page is a collection of pointers to different common WML structures. See [[AlphabeticalWML]] for a quick listing of all WML tags. The more comprehensive [[BuildingScenariosIndex]] lists tags and keys.<br />
<br />
See [[BuildingScenarios]], [[BuildingCampaigns]] and [[BuildingUnits]]<br />
for a tutorial style overview.<br />
<br />
<br />
<br />
''Note: this reference may contain slight inaccuracies, might not list all existing keys and tags or might contain some deprecated syntax. If you find that this reference doesn't give you the answer to how to implement some feature in WML, the most reliable way is to look at the WML code of existing units and campaigns that have done so.''<br />
<br />
== How WML works ==<br />
<br />
* [[SyntaxWML]] the language syntax.<br />
** [[VariablesWML]] how to use WML variables<br />
* [[PreprocessorRef]] the WML preprocessor syntax<br />
** [[UtilWML]] utility macros defined in utils.cfg<br />
<br />
== WML toplevel tags ==<br />
<br />
* [[GameConfigWML]] the top level '''[game_config]''' tag<br />
* [[UnitsWML]] the top level '''[units]''' tag<br />
** [[UnitTypeWML]] how to describe a unit type<br />
** [[AnimationWML]] how to animate units<br />
* [[CampaignWML]] the top level '''[campaign]''' tag<br />
* [[ScenarioWML]] the top level tags '''[scenario]''', '''[multiplayer]''', '''[test]''', and '''[tutorial]'''<br />
** [[EventWML]] how to describe an event<br />
** [[SideWML]] how to describe a side<br />
** [[MapGeneratorWML]] the random map generator<br />
** [[TimeWML]] how to describe a day<br />
** [[IntroWML]] how to describe the intro screen<br />
* [[SavefileWML]] a description of the format of savegames<br />
** [[ReplayWML]] a description of the format of player actions such as moving a unit<br />
** [[StatisticalScenarioWML]] used to generate statistics of a savegame<br />
* [[PblWML]] a description of the format of server-uploadable campaigns<br />
* [[EraWML]] the top level '''[era]''' tag<br />
* [[TerrainWML]] the top level '''[terrain]''' tag<br />
* [[TerrainGraphicsWML]], the top level '''[terrain_graphics]''' tag<br />
* [[ThemeWML]] the top level '''[theme]''' tag<br />
* [[LanguageWML]] the top level '''[language]''' tag<br />
* [[LocaleWML]] the top level '''[locale]''' tag<br />
* [[HelpWML]] the top level '''[help]''' tag<br />
* [[BinaryPathWML]] the top level '''[binary_path]''' tag<br />
* [[FontsWML]] the top level '''[fonts]''' tag<br />
<br />
== Other WML tags ==<br />
<br />
* [[EventWML]] how to describe an event<br />
** [[FilterWML]] the construct to filter on units, locations, and weapons<br />
** [[ActionWML]] to describe the actions which occur when the event is fired<br />
*** [[ConditionalActionsWML]] actions that encapsulate conditional filters and the actions to execute if the conditions are met<br />
*** [[DirectActionsWML]] actions that directly affect gameplay: for example creating a unit<br />
**** [[SingleUnitWML]] how to describe a unit<br />
*** [[InternalActionsWML]] actions that WML uses internally: for example storing a variable<br />
*** [[InterfaceActionsWML]] actions that do not affect gameplay: for example displaying a message<br />
*** [[LuaWML]] how to code actions with the Lua language<br />
* [[AiWML]] how to describe parameters for AI<br />
* [[EffectWML]] the construct to modify a unit<br />
* [[AbilitiesWML]] a list of the different abilities a unit or weapon can have<br />
* [[DescriptionWML]] the structure of WML coded menus like the difficulty chooser of campaigns<br />
* [[EditorWML]] tags controlling the post-1.4 editor's behavior<br />
<br />
== Predefined macros == <br />
<br />
Wesnoth ships with a library of predefined macros you should find useful in writing your own WML. You can find a description of all such macros [http://www.wesnoth.org/macro-reference.html here].<br />
<br />
== Other ==<br />
<br />
* [[ReferenceWMLSyntax]] how this wiki and the pages it links to should be formatted<br />
* [[ConventionsWML]] how to make your WML more readable<br />
* [[UsefulWMLFragments]] Various pieces of WML for various purposes. If you have some WML you're proud of that you think others can use, add it here.<br />
* [[CommandMode]] commands are not strictly speaking part of WML, these could be a little hard to find so there's a link here.<br />
* [[MultiplayerServerWML]] is used when communicating with the multiplayer server.<br />
* [[CampaignServerWML]] is used when managing contributed campaigns on the campaign server.<br />
* [[ImagePathFunctionWML]] is used when applying the team-color function to images.<br />
* [[BinaryWML]] how WML is sent over the network<br />
<br />
== See Also ==<br />
<br />
* [[BuildingMaps]] the text-based format for Wesnoth maps<br />
* [[TerrainCodesWML]] a list of all terrains<br />
* [[MultiHexTutorial]] a description of the multi-hex tiling system<br />
* [[IGNFileFormat]] a description of the ignore file format<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=LuaWML/Events&diff=40026LuaWML/Events2011-01-10T20:31:37Z<p>Paŭlo: /* wesnoth.register_wml_action */ link to ActionWML</p>
<hr />
<div>This page describes the [[LuaWML]] functions and helpers for interacting with events and action handlers.<br />
<br />
==== wesnoth.fire ====<br />
<br />
Fires a [[ActionWML|WML action]]. Argument 1 is the name of the action. Argument 2 is the WML table describing the action. Note: WML variables are substituted.<br />
<br />
wesnoth.fire("message", { speaker="narrator", message=_ "Hello World!" })<br />
<br />
==== wesnoth.register_wml_action ====<br />
<br />
Registers the second argument as a handler for the given action tag. When the game encounters this tag when executing [[ActionWML]] (for example in an event), it fires the action handler and passes the content of the WML object as the first argument. Thus, this function creates new types of [[ActionWML]].<br />
<br />
<br />
If the registered function raises an error with a message starting with ''~wml:'', it will not be displayed as a Lua error with a backtrace but as a standard WML error. (See also [[#helper.wml_error]].) The following script defines a [freeze_unit] tag that sets to 0 the move points of the unit with the given id.<br />
<br />
wesnoth.register_wml_action("freeze_unit",<br />
function(cfg)<br />
local unit_id = cfg.id or error("~wml:[freeze_unit] expects an id= attribute.", 0)<br />
helper.modify_unit({ id = unit_id }, { moves = 0 })<br />
end<br />
)<br />
<br />
# The new tag can now be used in plain WML code.<br />
[freeze_unit]<br />
id=Delfador<br />
[/freeze_unit]<br />
<br />
The function returns the previous action handler. Its metatable appears as '''"wml action handler"'''. This handler can be called to delegate part of the action, if needed. For instance, the following script modifies the [[InterfaceActionsWML#Other interface tags|[print]]] tag so that messages are displayed with a bigger font.<br />
<br />
local old_print_handler<br />
old_print_handler = wesnoth.register_wml_action("print",<br />
function(cfg)<br />
-- Do not perform variable substitution.<br />
local new_cfg = cfg.__literal<br />
-- Modify the size field and call the previous handler.<br />
new_cfg.size = (cfg.size or 12) + 10<br />
old_print_handler(cfg)<br />
end<br />
)<br />
<br />
Note that the data coming from the WML tag are stored in a read-only object and variable substitution happens on the fly when accessing attributes and children. The metatable of this proxy object appears as '''"wml object"'''. See [[LuaWML#Encoding WML objects into Lua tables]] for more details.<br />
<br />
If the name of a tag starts as ''filter'', it is ignored when the actions of an event are executed. These names are indeed reserved for event filtering, e.g. [filter], [filter_weapon], and so on. It is therefore useless to define action tags with such names.<br />
<br />
==== wesnoth.wml_actions ====<br />
<br />
{{DevFeature1.9}}<br />
<br />
This is not a function but an associative table indexed by WML action names. It contains functions performing the corresponding actions. Using these functions is similar to calling [[#wesnoth.fire]], while setting entries of the table is similar to calling [[#wesnoth.register_wml_action]].<br />
<br />
function wesnoth.wml_actions.freeze_unit(cfg)<br />
local unit_id = cfg.id or helper.wml_error "[freeze_unit] expects an id= attribute."<br />
helper.modify_unit({ id = unit_id }, { moves = 0 })<br />
end<br />
<br />
Note: When calling an action handler directly through its function stored in ''wesnoth.wml_actions'', the engine is not involved. As a consequence, whether variable substitution will happen is up to the handler. In particular, if the argument is a plain table, the caller should have substituted WML variables beforehand to be on the safe side. Moreover, table arguments might be modified by the action handler, so they should usually not be reused for consecutive calls. If variable substitution should happen and/or table content should be preserved, one can call [[#wesnoth.tovconfig]] and pass its result to the handler. Calling [[#wesnoth.fire]] is another possibility.<br />
<br />
==== wesnoth.game_events ====<br />
<br />
{{DevFeature1.9}}<br />
<br />
This is not a function but an associative table indexed by engine action names. It contains function hooks the engine calls whenever it performs a particular action.<br />
<br />
* '''on_save''': function called when the engine (auto)saves a scenario file; it should return a WML table and the children of this table are added to the savefile.<br />
* '''on_load''': function called when the engine loads a scenario file; its argument is a WML table that contains all the children of the savefile that the engine did not handle.<br />
* '''on_event''': function called before each WML event is executed; its argument is the event name; other event arguments can be recovered from [[LuaWML:Misc#wesnoth.current|wesnoth.current.event_context]].<br />
<br />
The ''on_save'' and ''on_load'' hooks can be used to manipulate data that are neither meant to be forwarded to the next level nor substituted on the fly. (For either of these two purposes, WML variables are the best choice.) For instance, toplevel tags like [item], [event], [time_area], and so on, could typically be handled by such hooks.<br />
<br />
-- some value that survives save/load cycles, but that is not forwarded to the next level<br />
local level_local_data = 0<br />
<br />
local old_on_load = wesnoth.game_event.on_load<br />
function wesnoth.game_event.on_load(cfg)<br />
for i = 1,#cfg do<br />
if cfg[i][1] == "my_data" then<br />
-- recover the value stored in the savefile<br />
level_local_data = cfg[i][2].value<br />
-- erase the child, since it has been handled<br />
table.remove(cfg, i)<br />
break<br />
end<br />
end<br />
-- call the previous hook, in case there are still some containers in the savefile<br />
old_on_load(cfg)<br />
end<br />
<br />
local old_on_save = wesnoth.game_events.on_save<br />
function wesnoth.game_events.on_save()<br />
-- call the previous hook, in case it had some containers to store<br />
local cfg = old_on_save()<br />
-- add our own container to them<br />
table.insert(cfg, { "my_data", { value = level_local_data } })<br />
-- tell the engine to store them in the savefile<br />
return cfg<br />
end<br />
<br />
Note: since the ''on_load'' hook is called very early in the scenario, it cannot be set inside a [lua] tag in an [event], not even a ''preload'' one. It has to be set inside a [lua] tag outside or at [scenario] level.<br />
<br />
==== wesnoth.fire_event ====<br />
<br />
Fires all the WML events with the given name. Optional parameters allow passing two locations and two tables. These parameters will be matched against the [filter], [filter_second], [filter_attack], and [filter_second_attack] of any event handler, and are used to fill the WML variables "unit", "second_unit", "weapon", and "second_weapon". These parameters can also be read through ''current.event_context''. The function returns a boolean indicating whether the game state was modified.<br />
<br />
wesnoth.fire_event("explosion", 17, 42, { damage = "fire" })<br />
<br />
==== wesnoth.eval_conditional ====<br />
<br />
Returns true if the conditional described by the WML table passes. Note: WML variables are substituted.<br />
<br />
local result = wesnoth.eval_conditional {<br />
{ "have_unit", { id = "hero" } },<br />
{ "variable", { name = "counter", numerical_equals = "$old_counter" } }<br />
}<br />
<br />
==== wesnoth.tovconfig ====<br />
<br />
Converts a WML table into a proxy object which performs variable substitution on the fly.<br />
<br />
wesnoth.set_variable("varname", "to_be_deleted")<br />
wesnoth.wml_actions.clear_variable { name = "to_be_deleted" } -- correct<br />
wesnoth.wml_actions.clear_variable { name = "$varname" } -- error: try to delete a variable literally called "$varname"<br />
wesnoth.wml_actions.clear_variable(wesnoth.tovconfig { name = "$varname" }) -- correct: "$varname" is replaced by "to_be_deleted" at the right time<br />
<br />
==== helper.set_wml_action_metatable ====<br />
<br />
Sets the metable of a table so that it can be used to fire WML actions. Returns the table. The fields of the table are then simple wrappers around a call to [[#wesnoth.fire]].<br />
<br />
local W = helper.set_wml_action_metatable {}<br />
W.message { speaker = "narrator", message = "?" }<br />
<br />
==== helper.wml_error ====<br />
<br />
Interrupts the current execution and displays a chat message that looks like a WML error.<br />
<br />
local names = cfg.name or helper.wml_error("[clear_variable] missing required name= attribute.")<br />
<br />
==== helper.literal ====<br />
<br />
{{DevFeature1.9}}<br />
<br />
Returns the ''__literal'' field of its argument if it is a userdata, the argument itself otherwise. This function is meant to be called when a WML action handler can be called indifferently from WML (hence receiving a userdata) or from Lua (hence possibly receiving a table).<br />
<br />
function wml_actions.display_literal_value(cfg)<br />
cfg = helper.literal(cfg)<br />
wesnoth.message(tostring(cfg.value)) <br />
end<br />
<br />
Note: when the argument is a plain table, the function returns it as is. In particular, modifying the fields of the returned table causes the original table to be modified too.<br />
<br />
==== helper.parsed ====<br />
<br />
{{DevFeature1.9}}<br />
<br />
Returns the ''__parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].<br />
<br />
==== helper.shallow_literal ====<br />
<br />
{{DevFeature1.9}}<br />
<br />
Returns the ''__shallow_literal'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].<br />
<br />
==== helper.shallow_parsed ====<br />
<br />
{{DevFeature1.9}}<br />
<br />
Returns the ''__shallow_parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=LuaWML/Events&diff=40025LuaWML/Events2011-01-10T20:27:39Z<p>Paŭlo: /* wesnoth.fire */ link to ActionWML</p>
<hr />
<div>This page describes the [[LuaWML]] functions and helpers for interacting with events and action handlers.<br />
<br />
==== wesnoth.fire ====<br />
<br />
Fires a [[ActionWML|WML action]]. Argument 1 is the name of the action. Argument 2 is the WML table describing the action. Note: WML variables are substituted.<br />
<br />
wesnoth.fire("message", { speaker="narrator", message=_ "Hello World!" })<br />
<br />
==== wesnoth.register_wml_action ====<br />
<br />
Registers the second argument as a handler for the given action tag. When the game encounters this tag an event, it fires the action handler and passes the content of the WML object as the first argument. If the registered function raises an error with a message starting with ''~wml:'', it will not be displayed as a Lua error with a backtrace but as a standard WML error. (See also [[#helper.wml_error]].) The following script defines a [freeze_unit] tag that sets to 0 the move points of the unit with the given id.<br />
<br />
wesnoth.register_wml_action("freeze_unit",<br />
function(cfg)<br />
local unit_id = cfg.id or error("~wml:[freeze_unit] expects an id= attribute.", 0)<br />
helper.modify_unit({ id = unit_id }, { moves = 0 })<br />
end<br />
)<br />
<br />
# The new tag can now be used in plain WML code.<br />
[freeze_unit]<br />
id=Delfador<br />
[/freeze_unit]<br />
<br />
The function returns the previous action handler. Its metatable appears as '''"wml action handler"'''. This handler can be called to delegate part of the action, if needed. For instance, the following script modifies the [[InterfaceActionsWML#Other interface tags|[print]]] tag so that messages are displayed with a bigger font.<br />
<br />
local old_print_handler<br />
old_print_handler = wesnoth.register_wml_action("print",<br />
function(cfg)<br />
-- Do not perform variable substitution.<br />
local new_cfg = cfg.__literal<br />
-- Modify the size field and call the previous handler.<br />
new_cfg.size = (cfg.size or 12) + 10<br />
old_print_handler(cfg)<br />
end<br />
)<br />
<br />
Note that the data coming from the WML tag are stored in a read-only object and variable substitution happens on the fly when accessing attributes and children. The metatable of this proxy object appears as '''"wml object"'''. See [[LuaWML#Encoding WML objects into Lua tables]] for more details.<br />
<br />
If the name of a tag starts as ''filter'', it is ignored when the actions of an event are executed. These names are indeed reserved for event filtering, e.g. [filter], [filter_weapon], and so on. It is therefore useless to define action tags with such names.<br />
<br />
==== wesnoth.wml_actions ====<br />
<br />
{{DevFeature1.9}}<br />
<br />
This is not a function but an associative table indexed by WML action names. It contains functions performing the corresponding actions. Using these functions is similar to calling [[#wesnoth.fire]], while setting entries of the table is similar to calling [[#wesnoth.register_wml_action]].<br />
<br />
function wesnoth.wml_actions.freeze_unit(cfg)<br />
local unit_id = cfg.id or helper.wml_error "[freeze_unit] expects an id= attribute."<br />
helper.modify_unit({ id = unit_id }, { moves = 0 })<br />
end<br />
<br />
Note: When calling an action handler directly through its function stored in ''wesnoth.wml_actions'', the engine is not involved. As a consequence, whether variable substitution will happen is up to the handler. In particular, if the argument is a plain table, the caller should have substituted WML variables beforehand to be on the safe side. Moreover, table arguments might be modified by the action handler, so they should usually not be reused for consecutive calls. If variable substitution should happen and/or table content should be preserved, one can call [[#wesnoth.tovconfig]] and pass its result to the handler. Calling [[#wesnoth.fire]] is another possibility.<br />
<br />
==== wesnoth.game_events ====<br />
<br />
{{DevFeature1.9}}<br />
<br />
This is not a function but an associative table indexed by engine action names. It contains function hooks the engine calls whenever it performs a particular action.<br />
<br />
* '''on_save''': function called when the engine (auto)saves a scenario file; it should return a WML table and the children of this table are added to the savefile.<br />
* '''on_load''': function called when the engine loads a scenario file; its argument is a WML table that contains all the children of the savefile that the engine did not handle.<br />
* '''on_event''': function called before each WML event is executed; its argument is the event name; other event arguments can be recovered from [[LuaWML:Misc#wesnoth.current|wesnoth.current.event_context]].<br />
<br />
The ''on_save'' and ''on_load'' hooks can be used to manipulate data that are neither meant to be forwarded to the next level nor substituted on the fly. (For either of these two purposes, WML variables are the best choice.) For instance, toplevel tags like [item], [event], [time_area], and so on, could typically be handled by such hooks.<br />
<br />
-- some value that survives save/load cycles, but that is not forwarded to the next level<br />
local level_local_data = 0<br />
<br />
local old_on_load = wesnoth.game_event.on_load<br />
function wesnoth.game_event.on_load(cfg)<br />
for i = 1,#cfg do<br />
if cfg[i][1] == "my_data" then<br />
-- recover the value stored in the savefile<br />
level_local_data = cfg[i][2].value<br />
-- erase the child, since it has been handled<br />
table.remove(cfg, i)<br />
break<br />
end<br />
end<br />
-- call the previous hook, in case there are still some containers in the savefile<br />
old_on_load(cfg)<br />
end<br />
<br />
local old_on_save = wesnoth.game_events.on_save<br />
function wesnoth.game_events.on_save()<br />
-- call the previous hook, in case it had some containers to store<br />
local cfg = old_on_save()<br />
-- add our own container to them<br />
table.insert(cfg, { "my_data", { value = level_local_data } })<br />
-- tell the engine to store them in the savefile<br />
return cfg<br />
end<br />
<br />
Note: since the ''on_load'' hook is called very early in the scenario, it cannot be set inside a [lua] tag in an [event], not even a ''preload'' one. It has to be set inside a [lua] tag outside or at [scenario] level.<br />
<br />
==== wesnoth.fire_event ====<br />
<br />
Fires all the WML events with the given name. Optional parameters allow passing two locations and two tables. These parameters will be matched against the [filter], [filter_second], [filter_attack], and [filter_second_attack] of any event handler, and are used to fill the WML variables "unit", "second_unit", "weapon", and "second_weapon". These parameters can also be read through ''current.event_context''. The function returns a boolean indicating whether the game state was modified.<br />
<br />
wesnoth.fire_event("explosion", 17, 42, { damage = "fire" })<br />
<br />
==== wesnoth.eval_conditional ====<br />
<br />
Returns true if the conditional described by the WML table passes. Note: WML variables are substituted.<br />
<br />
local result = wesnoth.eval_conditional {<br />
{ "have_unit", { id = "hero" } },<br />
{ "variable", { name = "counter", numerical_equals = "$old_counter" } }<br />
}<br />
<br />
==== wesnoth.tovconfig ====<br />
<br />
Converts a WML table into a proxy object which performs variable substitution on the fly.<br />
<br />
wesnoth.set_variable("varname", "to_be_deleted")<br />
wesnoth.wml_actions.clear_variable { name = "to_be_deleted" } -- correct<br />
wesnoth.wml_actions.clear_variable { name = "$varname" } -- error: try to delete a variable literally called "$varname"<br />
wesnoth.wml_actions.clear_variable(wesnoth.tovconfig { name = "$varname" }) -- correct: "$varname" is replaced by "to_be_deleted" at the right time<br />
<br />
==== helper.set_wml_action_metatable ====<br />
<br />
Sets the metable of a table so that it can be used to fire WML actions. Returns the table. The fields of the table are then simple wrappers around a call to [[#wesnoth.fire]].<br />
<br />
local W = helper.set_wml_action_metatable {}<br />
W.message { speaker = "narrator", message = "?" }<br />
<br />
==== helper.wml_error ====<br />
<br />
Interrupts the current execution and displays a chat message that looks like a WML error.<br />
<br />
local names = cfg.name or helper.wml_error("[clear_variable] missing required name= attribute.")<br />
<br />
==== helper.literal ====<br />
<br />
{{DevFeature1.9}}<br />
<br />
Returns the ''__literal'' field of its argument if it is a userdata, the argument itself otherwise. This function is meant to be called when a WML action handler can be called indifferently from WML (hence receiving a userdata) or from Lua (hence possibly receiving a table).<br />
<br />
function wml_actions.display_literal_value(cfg)<br />
cfg = helper.literal(cfg)<br />
wesnoth.message(tostring(cfg.value)) <br />
end<br />
<br />
Note: when the argument is a plain table, the function returns it as is. In particular, modifying the fields of the returned table causes the original table to be modified too.<br />
<br />
==== helper.parsed ====<br />
<br />
{{DevFeature1.9}}<br />
<br />
Returns the ''__parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].<br />
<br />
==== helper.shallow_literal ====<br />
<br />
{{DevFeature1.9}}<br />
<br />
Returns the ''__shallow_literal'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].<br />
<br />
==== helper.shallow_parsed ====<br />
<br />
{{DevFeature1.9}}<br />
<br />
Returns the ''__shallow_parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ActionWML&diff=40024ActionWML2011-01-10T20:26:47Z<p>Paŭlo: added "sequence of".</p>
<hr />
<div>'''ActionWML''' is a summarizing term for all '''WML actions''' which can be used in events and some other places.<br />
<br />
== Types of ActionWML ==<br />
<br />
When a tag permits ActionWML as content, this means that it permits a sequence of any of the following tags:<br />
<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
* conditional actions ([[ConditionalActionsWML]]) which contain other actions, which then are (maybe) executed ([if], [switch], [while], [command])<br />
* [event] (see [[EventWML#Nested Events|EventWML]]) which creates a new event handler<br />
** note: [event] can also be a subtag of [unit], [era] and [scenario], where it would not be counted as ActionWML (but has nearly the same syntax).<br />
* [lua] ([[LuaWML]]) which contains Lua code to be executed, and<br />
* all tags created from lua with [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] (if they don't fit in one of the categories above)<br />
<br />
When the ActionWML is executed, all its action tags are executed in order.<br />
<br />
== Where ActionWML can be used ==<br />
<br />
ActionWML can be used:<br />
* inside an [event], to define a event handler (see [[EventWML]]),<br />
* inside a [then] or [else] of an [if] tag (see [[ConditionalActionsWML]]),<br />
* inside a [case] or [else} of a [switch] tag (see [[ConditionalActionsWML]]),<br />
* inside the [do] of a [while] tag (see [[ConditionalActionsWML]]),<br />
* inside a [command] tag (in [option] or [set_menu_item] or directly as ActionWML) (see [[InterfaceActionsWML]]),<br />
* in certain Lua-created tags (if the registered WML action handler interprets the content as ActionWML).<br />
<br />
<br />
On most other places ActionWML code will either be ignored, give error messages or interpreted differently (there may be some tags which are both ActionWML and have similar or different meanings in other places, like [event]).<br />
<br />
<br />
[[Category:ActionsWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=MusicListWML&diff=40023MusicListWML2011-01-10T20:19:33Z<p>Paŭlo: /* the [music] tag */ link to ActionWML</p>
<hr />
<div>{{WML Tags}}<br />
== the [music] tag ==<br />
<br />
This tag is a subtag of [scenario] and also part of [[ActionWML]], which is used to describe a music track to play. You can repeat this tag as many times as you like; if you set the ''append'' tag to ''yes'' they will form a playlist from which tracks will be selected at random.<br />
<br />
Tags describe the music track:<br />
* ''name'' specifies the music file, relative to '"music/"'. This is compulsory.<br />
* ''append=yes'' specifies this is to be added to the current playlist. Without this, the current playlist is replaced by this track. (Note: if the same track is appended multiple times in a row, it will only play once before moving on to the next (different) track)<br />
* ''play_once=yes'' immediately switch to playing this track, but then return to the play list, which is unchanged.<br />
* ''immediate=yes'' immediately switch to playing this track. Without this, the song will play when the entire [event] is over or the current song ends. This exists to force music changes '''during''' dialog exchange or other [event] which take significant time.<br />
* ''ms_before'' (optional) specifies how many milliseconds to delay before playing this track. Currently this does not apply when the scenario first starts, or with ''play_once'' or ''immediate''.<br />
* ''ms_after'' (optional) specifies how many milliseconds to delay after playing this track.<br />
<br />
For a list of music tracks you can use in your scenario, see [[Available Music]].<br />
<br />
=== Example ===<br />
This creates a new playlist with three entries in it. The second track is always preceeded by 1/2 a second of silence.<br />
[music]<br />
name=background-music-1.ogg<br />
[/music]<br />
[music]<br />
name=background-music-2.ogg<br />
ms_before=500<br />
append=yes<br />
[/music]<br />
[music]<br />
name=background-music-3.ogg<br />
append=yes<br />
[/music]<br />
<br />
<br />
<br />
[[Category: WML Reference]]<br />
[[Category:Music]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=InterfaceActionsWML&diff=40022InterfaceActionsWML2011-01-10T20:10:53Z<p>Paŭlo: /* Interface actions */ link to ActionWML</p>
<hr />
<div>{{WML Tags}}<br />
== Interface actions ==<br />
<br />
Part of [[ActionWML]], interface actions are actions that do not have a direct effect on gameplay;<br />
instead, they show something to the player. The main interface tags<br />
are '''[message]''' and '''[objectives]''', but several other tags affect<br />
the interface also.<br />
<br />
== [inspect] ==<br />
This user interface action only works in debug mode. It displays the gamestate inspector dialog (the same one which can be brought up with '':inspect'' ), which can be used to inspect the values of WML variables, AI configuration, recall lists, and more.<br />
<br />
* '''name''': optional attribute to specify the name of this gamestate inspector dialog. It is just a label to help differentiate between different invocations of gamestate inspector dialog.<br />
<br />
== [message] ==<br />
The most commonly used interface action is [message], which displays a message to the user in a dialog box. It can also be used to take input from the user.<br />
<br />
The following key/tags are accepted for [message]:<br />
* [[StandardUnitFilter]]: The unit whose profile and name are displayed. Do not use a [filter] tag. If no unit matching this filter is found, the message is not displayed (The unit has probably been killed).<br>'''[message]''' elements should be constructed so that it is either guaranteed that a certain unit is alive, or so that dialog flows smoothly even if the message isn't displayed.<br />
<br />
* '''speaker''': an alternative to standard unit filter. You may specify as the value of the speaker attribute a unit id or any of the following special values:<br />
** '''narrator''': the dialog box is displayed without a caption for the unit speaking or a unit image<br />
** '''unit''': the primary unit for the event is speaking<br />
** '''second_unit''': the secondary unit for the event is speaking<br />
<br />
* '''message''': (translatable) the text to display to the right of the image. ''message'' is sometimes multiple lines; if it is, be sure to use quotes(''' ' ''' or ''' " ''')<br />
* '''[show_if]''': if present then this message will only be displayed if the conditional statement in this tag is passed (see [[ConditionalActionsWML#Condition_Tags|ConditionalActionsWML]])<br />
* '''side_for''': (default: all sides) comma-separated list of sides for who message is shown.<br />
* '''image''': (default: profile image of speaker) the image to display next to the message.<br />
* '''caption''': (default: name of speaker) the caption to display beside the image. Name to be displayed. Note: use a translation mark to avoid wmllint errors.<br />
* '''scroll''': {{DevFeature1.9}} Boolean specifying whether the game view should scroll to the speaking unit. Defaults to ''yes''.<br />
* '''duration''': (default: 10) the minimum number of frames for this message to be displayed. (A frame lasts about 30 milliseconds.) During this time any dialog decisions will be disregarded.<br />
* '''sound''': a sound effect (wav file) to play as the message is displayed. This can be a comma-separated list, from which one will be randomly chosen.<br />
* '''[option]''': No '''[option]''' elements have to be used. If '''[option]''' elements are present, then each option will be displayed in a menu for the user to select one option.<br />
** '''message''': (translatable) the text displayed for the option (see [[DescriptionWML]])<br />
** '''[show_if]''': if present then this option will only be displayed if the conditional statement in this tag is passed (see [[InternalActionsWML]])<br />
** '''[command]''': an element containing actions which are executed if the option is selected.<br />
* '''[text_input]''': there can be only one [text_input] tag. this adds a text input field to the message.<br />
** '''variable''': the variable that the user's input will be written to<br />
** '''label''': a text label to the left of the input field<br />
** '''max_length''': the maximum number of characters that may be typed into the field<br />
** '''text''': text that is written into the field in the beginning<br />
* Check [[EventWML#Multiplayer_safety]] to find out in which events you can safely use '''[option]''' and '''[text_input]''' without causing OOS.<br />
<br />
=== Formatting ===<br />
In 1.8, [http://library.gnome.org/devel/pango/unstable/PangoMarkupFormat.html Pango markup formatting codes] have been adopted for '''[message]'''. These can also be used in unit names (user_description), objectives, and such. Note that you'll probably want to use a single quote ' instead of a double quote " as double quotes cannot be escaped, otherwise the string will appear fragmented and you may also encounter errors. Running wmllint on your campaign will up-convert it, warning you about unusual cases you must fix by hand.<br />
<br />
For example, if you wanted to write "You are victorious!" in large, italic, gold letters, you might write it this way:<br />
<br />
<nowiki><span color='#BCB088' size='large' font-style='italic'>You are victorious!</span></nowiki><br />
<br />
<br />
These are the codes taken from the Pango markup formatting guide:<br />
<br />
*'''font''', '''font_desc''': A font description string, such as "Sans Italic 12".<br />
*'''font_family''', '''face''': A font family name.<br />
*'''font_size''', '''size''': Font size in 1024ths of a point, or one of the absolute sizes 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', or one of the relative sizes 'smaller' or 'larger'.<br />
*'''font_style''', '''style''': One of 'normal', 'oblique', 'italic'.<br />
*'''font_weight''', '''weight''': One of 'ultralight', 'light', 'normal', 'bold', 'ultrabold', 'heavy', or a numeric weight.<br />
*'''font_variant''', '''variant''': One of 'normal' or 'smallcaps'.<br />
*'''font_stretch''', '''stretch''': One of 'ultracondensed', 'extracondensed', 'condensed', 'semicondensed', 'normal', 'semiexpanded', 'expanded', 'extraexpanded', 'ultraexpanded'.<br />
*'''foreground''', '''fgcolor''', '''color''': An RGB color specification such as '#00FF00' or a color name such as 'red'.<br />
*'''background, bgcolor''': An RGB color specification such as '#00FF00' or a color name such as 'red'.<br />
*'''underline''': One of 'none', 'single', 'double', 'low', 'error'.<br />
*'''underline_color''': The color of underlines; an RGB color specification such as '#00FF00' or a color name such as 'red'.<br />
*'''rise''': Vertical displacement, in 10000ths of an em. Can be negative for subscript, positive for superscript.<br />
*'''strikethrough''': 'true' or 'false' whether to strike through the text.<br />
*'''strikethrough_color''': The color of strikethrough lines; an RGB color specification such as '#00FF00' or a color name such as 'red'<br />
*'''fallback''': 'true' or 'false' whether to enable fallback. If disabled, then characters will only be used from the closest matching font on the system. No fallback will be done to other fonts on the system that might contain the characters in the text. Fallback is enabled by default. Most applications should not disable fallback.<br />
*'''letter_spacing''': Inter-letter spacing in 1024ths of a point.<br />
*'''gravity''': One of 'south', 'east', 'north', 'west', 'auto'.<br />
*'''gravity_hint''': One of 'natural', 'strong', 'line'.<br />
<br />
<br />
In 1.6, Wesnoth uses older text formatting options<br />
* A tilde (~) as the first character causes the line to be boldfaced.<br />
* An at symbol (@) as the first character causes the line to be green, as done with victory conditions.<br />
* A pound symbol (#) as the first character causes the line to be red, as done with defeat conditions.<br />
* An asterisk (*) as the first character causes the line to be bigger.<br />
* A backquote (`) as the first character causes the line to be smaller.<br />
* If used, the caption key text is boldfaced.<br />
* An RGB colour code in the beginning causes the line to be the given colour. This can still be preceded by the above characters. Example: ''message=_"<255,0,0>Red!"''<br />
<br />
== [objectives] ==<br />
The other tag used for plot development is '''[objectives]'''.<br />
The '''[objectives]''' tag overwrites any previously set objectives,<br />
and displays text which should describe the objectives of the scenario.<br />
Scenario objectives are displayed on the player's first turn after the tag is used,<br />
or as part of the event if it triggers during that player's turn.<br />
Objectives can also be accessed at any time in a scenario using the<br />
"Scenario Objectives" game menu option, making this tag useful for<br />
scenario-specific information that the player may need to refer to during play.<br />
<br />
This tag renders the ''objectives'' attribute of [scenario] obsolete (see ''objectives'', [[ScenarioWML]]).<br />
Instead of using ''objectives'', use '''[objectives]''' to set scenario objectives inside a prestart event.<br />
It can also be used to overwrite the starting objectives mid-scenario.<br />
<br />
Attributes of '''[objectives]''':<br />
* '''side''': Default '0'. The side to set the objectives for. A value of 0 sets objectives for all sides.<br />
* '''summary''': Displayed first in the objectives text, this should describe the basic objective for the overall scenario. Can be omitted.<br />
* '''note''': Displayed last in the objectives text, this is sometimes used for hints or additional information. Can be omitted.<br />
* '''victory_string''': Default ' _ "Victory:"', this text precedes the victory objectives.<br />
* '''defeat_string''': Default ' _ "Defeat:"', this text precedes the defeat objectives.<br />
* '''gold_carryover_string''' {{DevFeature1.9}}: Default ' _ "Gold carryover:"', this text precedes the gold carryover information.<br />
* '''notes_string''' {{DevFeature1.9}}: Default ' _ "Notes:"', this text precedes the notes.<br />
* '''silent''': Default: not present. If set to "yes", the objectives are silently changed. Else, they will be shown to the user when appropriate.<br />
<br />
Tags of '''[objectives]''':<br />
* '''[objective]''': describes a win or loss condition. Most scenarios have multiple win or loss conditions, so use a separate [objective] subtag for each line; this helps with translations.<br />
** '''description''': text for the specific win or loss condition.<br />
** '''condition''': The color and placement of the text. Values are 'win'(colored green, placed after ''victory_string'') and 'lose'(colored red, placed after ''defeat_string'')<br />
** '''show_turn_counter''' {{DevFeature1.9}}: If set to yes, displays the number of turns remaining in the scenario. Default is no.<br />
** '''[show_if]''': A condition that disables the objective if it doesn't hold. Conditional objectives are refreshed at '''[show_objectives]''' time only. {{DevFeature}}<br />
* '''[gold_carryover]''' {{DevFeature1.9}}: describes how the gold carryover works in this scenario. This is intended to be a more convenient way of displaying carryover information than using the note= key in [objectives].<br />
** '''bonus''' (boolean): whether an early finish bonus is granted. If omitted, early finish bonus is not mentioned.<br />
** '''carryover_percentage''': the amount of carryover gold. If omitted, the amount is not mentioned.<br />
* '''[note]''' {{DevFeature1.9}}: describes a note, usually used for hints or additional information. This is an easier way of adding several notes than concatenating them together into a single string to use with the ''note='' key.<br />
** '''description''': the text of the note.<br />
<br />
=== Macros ===<br />
There are a few predefined macros for Objectives that you can use to shorten the code: [http://www.wesnoth.org/macro-reference.xhtml#SET_OBJECTIVES SET_OBJECTIVES], [http://www.wesnoth.org/macro-reference.xhtml#VICTORY_CONDITION VICTORY_CONDITION], and [http://www.wesnoth.org/macro-reference.xhtml#DEFEAT_CONDITION DEFEAT_CONDITION]. Follow the links for each one to see complete syntax and example usage.<br />
<br />
== [set_menu_item] ==<br />
This tag is used to add a custom option in the right-click context menu which can then be used to trigger arbitrary WML commands.<br />
<br />
'''Note:''' Due to limitations in portable devices where there are no scroll bars for context menus, there is a hard-coded limit of 7 custom WML menu items. If you really need to have more than 7 menu items, try combining some of them in a submenu.<br />
<br />
* '''id''': the unique id for this menu item. If a menu item with this id already exists, it allows you to set specific changes to that item.<br />
* '''description''': the in-game text that will appear for this item in the menu.<br />
* '''image''': the image to display next to this item.<br />
* '''needs_select''': if ''yes'' (default ''no''), then the latest select event (see [[EventWML]]) that triggered before this menu item was chosen will be transmitted over the network before this menu item action will be. This only has any effect in networked multiplayer, and is intended to allow more elaborate menu item behaviour there without causing out of sync errors. If you don't know what this means, just leave it false.<br />
* '''[show_if]''': If present, the menu item will only be available if the conditional statement (see [[InternalActionsWML]]) within evaluates to true. When this is evaluated, the WML variables ''$x1'' and ''$y1'' will point to the location on which the context menu was invoked, so it's possible to for example only enable the option on empty hexes or on a particular unit.<br />
* '''[filter_location]''': contains a location filter similar to the one found inside Single Unit Filters (see [[FilterWML]]). The menu item will only be available on matching locations.<br />
* '''[command]''': contains the WML actions to be executed when the menu item is selected. Again, the WML variables ''$x1'' and ''$y1'' will point to the location on which the context menu was invoked on.<br />
<br />
== Other interface tags ==<br />
<br />
The following tags are also action tags:<br />
* '''[item]''': makes a graphical item appear on a certain hex. Note this only places the graphics for an item. It does not make the item do anything. Use a moveto event to make moving onto the item do something. <tt>''('''Hint:''' There are a number of predefined items that are used in various campaigns that you can make use of. You can find [http://www.wesnoth.org/macro-reference.xhtml#file:items.cfg a list of them] if you look into the items.cfg file in the wesnoth install directory (under /data/core/macros))''</tt><br />
** '''x''', '''y''': the location to place the item.<br />
** '''image''': the image (in ''images/'' as .png) to place on the hex.<br />
** '''halo''': an image to place centered on the hex. Use this instead of ''image'' if the image is bigger than the hex or if you want to animate an image. ''Example (where the integer after the colon is the duration of each frame): halo=scenery/fire1.png:100,scenery/fire2.png:100,scenery/fire3.png:100,scenery/fire4.png:100,scenery/fire5.png:100,scenery/fire6.png:100,scenery/fire7.png:100,scenery/fire8.png:100''<br />
** '''team_name''': name of the team for which the item is to be displayed (hidden for others). For multiple teams just put all the names in one string, for example separated by commas.<br />
** '''visible_in_fog''': whether the item should be visible through fog or not. Default yes.<br />
* '''[removeitem]''': removes any graphical items on a given hex. (In version 1.9.2, this was renamed to '''[remove_item]''')<br />
** '''x''', '''y''': the hex to remove items off<br />
** '''image''' if specified, only removes the given image item (This image name must include any [[ImagePathFunctionWML|image path functions]] appended to the original image name.)<br />
* '''[print]''': displays a message across the screen. The message will disappear after a certain time.<br />
** '''text''': (translatable) the text to display.<br />
** '''size''': (default=12) the pointsize of the font to use<br />
** '''duration''': (default=50) the length of time to display the text for. This is measured in the number of 'frames'. A frame in Wesnoth is usually displayed for around 30ms.<br />
** '''red''', '''green''', '''blue''': (default=0,0,0) the color to display the text in. Values vary from 0-255.<br />
* '''[move_unit_fake]''': moves an image of a unit along a certain path on the map. The path does not need to be a continuous list of adjacent hexes, so for example only the start and end points can be given, in which case the straightest line between those points will be calculated and used.<br />
** '''type''': the type of the unit whose image to use<br />
** '''x''': a comma-separated list of x locations to move along<br />
** '''y''': a comma-separated list of y locations to move along (x and y values are matched pairs)<br />
** '''side''': the side of the fake unit, used for team-coloring the fake unit<br />
** '''gender''': the gender of the fake unit. Example: gender=female<br />
** '''variation''': the variation of the fake unit. Example: variation=undead<br />
** '''image_mods''': {{DevFeature1.9}} [[ImagePathFunctionWML|image path functions]] sequence to be applied on the fake unit.<br />
* '''[move_units_fake]''': {{DevFeature1.9}} moves multiple images of units along paths on the map. These units are moved in lockstep.<br />
** '''[fake_unit]''': A fake unit to move<br />
*** '''type''': the type of unit whose image to use<br />
*** '''x''': a comma-separated list of x locations to move along<br />
*** '''y''': a comma-separated list of y locations to move along (x and y values are matched pairs)<br />
*** '''side''': the side of the fake unit, used for team-coloring the fake unit<br />
*** '''skip_steps''': the number of steps to skip before this unit starts moving<br />
* '''[hide_unit]''': temporarily prevents the engine from displaying the given unit. The unit does not become invisible, as it would be with the '''[hides]''' ability; it is still the same plain unit, but without an image. Useful in conjunction with '''[move_unit_fake]''': to move a leader unit into position on-screen. Each '''[hide_unit]''' tag only hides one unit.<br />
** '''x''', '''y''': location of the unit to be hidden. (NOT a standard unit filter! Just x and y.)<br />
** {{DevFeature1.9}}: '''[hide_unit]''' accepts a [[StandardUnitFilter]] as argument and can disable several units at once.<br />
* '''[unhide_unit]''': stops the currently hidden units from being hidden.<br />
** {{DevFeature1.9}}: '''[unhide_unit]''' accepts a [[StandardUnitFilter]] as argument.<br />
* '''[scroll]''': Scroll a certain number of pixels in a given direction. Useful for earthquake/shaking effects.<br />
** '''x''', '''y''': the number of pixels to scroll along the x and y axis<br />
* '''[scroll_to]''': Scroll to a given hex<br />
** '''x''', '''y''': the hex to scroll to<br />
** '''check_fogged''': whether to scroll even to locations covered in fog or shroud. Possible values ''true'' (don't scroll to fog) and ''false'' (scroll even to fog), with ''false'' as the default.<br />
* '''[scroll_to_unit]''' Scroll to a given unit<br />
** [[StandardUnitFilter]]<br />
** '''check_fogged''': whether to scroll even to locations covered in fog or shroud. Possible values ''true'' (don't scroll to fog) and ''false'' (scroll even to fog), with ''false'' as the default.<br />
* '''[select_unit]''': {{DevFeature1.9}} Selects a given unit<br />
** [[StandardUnitFilter]]<br />
** '''fire_event''': whether a ''select'' event should be triggered or not (def. ''no'').<br />
** '''highlight''': whether the unit's current hex should be highlighted (def. ''yes'').<br />
* '''[sound]''': Plays a sound<br />
** '''name''': the filename of the sound to play (in ''sounds/'' as .wav or .ogg)<br />
** '''repeat''': repeats the sound for a specified additional number of times (default=0)<br />
* '''[sound_source]''': Creates a sound source. "Sound sources" is a general name for a mechanism which makes possible for map elements to emit sounds according to some rules, where "map elements" can be specific locations or terrain types. For now, only sound sources tied to locations are supported.<br />
** '''id''': a unique identification key of the sound source<br />
** '''sounds''': a list of comma separated, randomly played sounds associated with the sound source<br />
** '''delay''': a numerical value (in milliseconds) of the minimal delay between two playbacks of the source's sound if the source remains visible on the screen; if one scrolls out and back in, the source will be considered as ready to play<br />
** '''chance''': a percentage (a value from 0 to 100) describing the chance of the source being activated every second after the delay has passed or when the source's location appears on the screen (note that it cannot play more than one file at the same time)<br />
** '''check_fogged''': possible values "true" and "false" - if true the source will not play if its locations are fogged<br />
** '''check_shrouded''': {{DevFeature}} possible values "true" and "false" - if true the source will not play if its locations are shrouded<br />
** '''x,y''': similar to x,y as found in a [[StandardLocationFilter]], these are the locations associated with the sound source<br />
** '''fade_range''' (default = 3): distance in hexes that determines a "circular" area around the one specified by '''full_range''' where sound volume fades out linearly<br />
** '''full_range''' (default = 14): distance in hexes that determines a "circular" area where source plays with full volume, relative to screen center<br />
** '''loop''': number of times a sound sample should be looped if it stays visible. -1 means infinite (~65000)<br />
* '''[remove_sound_source]''': Removes a previously defined sound source.<br />
** '''id''': the identification key of the sound source to remove<br />
* '''[music]''': Switches to playing different music<br />
** '''name''': the filename of the music to play (in ''music/'' as .ogg)<br />
** see [[MusicListWML]] for the correct syntax<br />
* '''[volume]''': {{DevFeature1.9}} Changes the game volume to a percent of the preferences volume for the game being played. Values can go from 0 to 100: <br />
** '''music''': Changes the music volume.<br />
** '''sound''': Changes the sound volume.<br />
* '''[colour_adjust]''': tints the color of the screen. {{DevFeature1.9}}: now named '''[color_adjust]'''.<br />
** '''red''', '''green''', '''blue''': values from -255 to 255, the amount to tint by for each color<br />
* '''[delay]''': pauses the game<br />
** '''time''': the time to pause in milliseconds<br />
* '''[redraw]''': redraws the screen (this normally isn't done during events, although some of the other interface actions cause the screen or parts of it to be redrawn).<br />
** '''side''': if used, recalculates fog and shroud for that side. Useful if you for example spawn friendly units in the middle of an event and want the shroud to update accordingly (otherwise units that spawn inside fog would remain invisible for the duration of the event, since the fog would not automatically get cleared around them).<br />
* '''[unit_overlay]''': sets an image that will be drawn over a particular unit, and follow it around<br />
** '''x''', '''y''': the location of the unit to overlay on<br />
** '''image''': the image to place on the unit<br />
** {{DevFeature1.9}}: '''[unit_overlay]''' accepts a [[StandardUnitFilter]] as argument<br />
* '''[remove_unit_overlay]''': removes a particular overlayed image from a unit<br />
** '''x''', '''y''': the location of the unit to remove an overlay from<br />
** '''image''': the image to remove from the unit<br />
** {{DevFeature1.9}}: '''[remove_unit_overlay]''' accepts a [[StandardUnitFilter]] as argument<br />
* '''[animate_unit]''': Uses an animation of a unit to animate it on screen (if the unit has the corresponding animation).<br />
** '''flag''': The key to find the custom animation in the unit description (see the '''[extra_anim]''' description in [[AnimationWML]]). Standard animations can be triggered with the following keywords: ''leading recruited standing idling levelin levelout healing healed poisoned movement defend attack death victory pre_teleport post_teleport''<br />
** '''[filter]''' with a [[StandardUnitFilter]] as argument, see [[FilterWML]]. By default, the unit at the event location will be animated. You can use this tag to choose any other unit to animate.<br />
** '''[primary_attack]''': If this tag is not present, the filter for animation will be triggered with no attack. If it is here, all attacks from the unit will be filtered, and a matching one will be used to filter the animation. Takes a weapon filter as argument, see [[FilterWML]].<br />
** '''[secondary_attack]''': Similar to '''[primary_attack]'''. May be needed to trigger a defense animation correctly, if there are more than one animations available for the defending unit.<br />
** '''hits''': yes/no/hit/miss/kill: which according variation of a attack/defense animation shall be chosen (required)<br />
** '''text''': a text to hover during the animation <br />
** '''red''': red value for the text color (0-255)<br />
** '''green''': green value for the text color<br />
** '''blue''': blue value for the text color<br />
** '''with_bars''': yes/no: whether to display the status bars during the animation (e.g. the hitpoint bar)<br />
** '''[animate]''': a sub block with the same syntax as '''[animate_unit]''' except that the '''[filter]''' block is mandatory to find the unit. This block will find and animate another unit simultaneously.<br />
** '''[facing]''': a [[StandardLocationFilter]] specifying what direction the unit should be facing when animated<br />
* '''[label]''' places a label on the map.<br />
** '''x''', '''y''': the location of the label<br />
** '''text''': what the label should say<br />
** '''team_name''': if specified, the label will only be visible to the given team.<br />
** '''colour''': color of the label. The format is r,g,b; r, g and b are numbers between 0 and 255. {{DevFeature1.9}}: now named '''color'''.<br />
** '''visible_in_fog''': whether the label should be visible through fog or not. Default yes.<br />
** '''visible_in_shroud''': whether the label should be visible through shroud or not. Default no.<br />
** '''immutable''': whether this label is protected from being removed or changed by players. Default yes. {{DevFeature1.9}}<br />
* '''[floating_text]''': {{DevFeature1.9}} floats text (similar to the damage and healing numbers) on the given locations.<br />
** [[StandardLocationFilter]]: the text will be floated on all matching locations simultaneously.<br />
** '''text''': the text to display.<br />
* '''[deprecated_message]''' shows a deprecated message in the message area, this feature is only intended to be used to warn about deprecated macros in mainline. The message is not translatable.<br />
** '''message''': the message to show.<br />
* '''[wml_message]''' outputs a message to Wesnoth's console output. Intended for campaign designers to output silent text to the console, without annoying the player; then, that text might contain information useful for later bug-reporting. The log domain for it is '''wml''', and the '''debug/dbg''' log level is available for use with the '''logger''' attribute. Depending on the current log level ('''error''' by default), which may be changed with the in-game :log command, or the --log-<level>=wml command line switch, the messages are echoed to the in-game chat.<br />
** '''message''': the message to show.<br />
** '''logger''': the Wesnoth engine output logger that should catch the text; this might be 'err' (the errors log level), 'warn'/'wrn' (the warnings log level) or anything else (the information log level). Not all information will be displayed depending on the log level chosen when starting Wesnoth.<br />
* '''[open_help]''' opens the in-game help.<br />
** '''topic''': the id of the topic to open<br />
* '''[show_objectives]''': {{DevFeature}} refreshes the objectives defined by [objectives] and its [show_if] tags, and displays them. (It is also called whenever the user explicitly asks for the objectives; this matters only if the tag was overridden by a [[LuaWML#register_wml_action|Lua]] script.)<br />
** '''side''': the side to show the objectives. If not set, all sides are used.<br />
* '''[chat]''' displays a message in the chat area. {{DevFeature1.9}}<br />
** '''speaker''': A string for the name of the sender of the message.<br />
** '''message''': The message that should be displayed<br />
** '''side''': A comma separated list of sides to show the message to. If the same machine controls multiple sides that are in this list, then the message will only be displayed once. If left blank the message will be send to all sides.<br />
<br />
== Useful Macros ==<br />
There are some predefined macros that you find useful for interface actions. You can find a complete list along with a detailed explanation of how they work [http://www.wesnoth.org/macro-reference.xhtml here].<br />
* '''{FLOATING_TEXT}''' Float some text over a unit similar to the damage numbers.<br />
* '''{HIGHLIGHT_UNIT}''' Highlight a unit on the map. Use this to show important units<br />
* '''{HIGHLIGHT_IMAGE}''' Places and highlights an image on the map. Use this to show important items or locations<br />
* '''{SET_IMAGE}''' Places an image on the map which has no other function.<br />
* '''{QUAKE <soundfile>}''' Creates a tremor like screenshake and plays <soundfile>. ('''{TREMOR}''' is a deprecated version, equivalent to '''{QUAKE (rumble.ogg)}''')<br />
* '''{FLASH_WHITE}''' Flash the screen white momentarily. You can also replace WHITE with RED, BLUE or GREEN for a different colour.<br />
<br />
== See Also ==<br />
* [[DirectActionsWML]]<br />
* [[InternalActionsWML]]<br />
* [[EventWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]<br />
[[Category: ActionsWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=InternalActionsWML&diff=40021InternalActionsWML2011-01-10T20:06:19Z<p>Paŭlo: /* [insert_tag] */ mention "container", ActionWML.</p>
<hr />
<div>{{WML Tags}}<br />
<br />
Part of [[ActionWML]], Internal actions are actions that WML uses internally that do not directly affect game play (or, at least, are not readily apparent to the player). For example, storing a variable is an internal action.<br />
<br />
== Variable Actions ==<br />
<br />
These actions are focused, in one way or another, on [[VariablesWML|variables]]. Creating them, modifying them, capturing game data to them, you name it, these actions are all about the variables.<br />
<br />
=== [set_variable] ===<br />
<br />
The '''[set_variable]''' tag is used to create and manipulate WML variables. The [http://www.wesnoth.org/macro-reference.xhtml#VARIABLE VARIABLE] macro is a quick syntactic shortcut for simple variable creation and the [http://www.wesnoth.org/macro-reference.xhtml#VARIABLE_OP VARIABLE_OP] macro is a quick syntactic shortcut for performing simple mathematical operations on variables.<br />
<br />
* '''name''': the name of the variable to manipulate<br />
<br />
* '''value''': set the variable to the given value (can be numeric or string).Use literal for no substitution. (see [[VariablesWML]])<br />
<br />
* '''literal''': set the variable to the given value (can be numeric or string). This does not interpret any dollars signs.<br />
<br />
* '''format''': This attribute will be deprecated from 1.7 on. Same behaviour as value.<br />
<br />
* '''to_variable''': set the variable to the value of the given variable, e.g. 'to_variable=temp' would be equivalent to 'value=$temp'.<br />
<br />
* '''add''': add the given amount to the variable. To subtract, add a negative number.<br />
<br />
* '''sub''' {{DevFeature}}: subtract the given amount from the variable.<br />
<br />
* '''multiply''': multiply the variable by the given number. To divide, multiply by the inverse eg: 4/2 = 4 * 1/2 = 4 * 0.5. To negate, multiply by -1. Floating point values are not rounded.<br />
<br />
* '''divide''': divide the variable by the given number. The result is an integer. Floating point results are not rounded. If both variables are integers, [http://en.wikipedia.org/wiki/Division_(mathematics)#Division_of_integers Integer division] is used.<br />
<br />
* '''modulo''': returns the remainder of a division.<br />
<br />
* '''random''': the variable will be randomly set.<br>You may provide a comma separated list of possibilities, e.g. 'random=Bob,Bill,Bella'.<br>You may provide a range of numbers (integers), e.g. 'random=3..5'.<br>You may combine these, e.g. 'random=100,1..9', in which case there would be 1/10th chance of getting 100, just like for each of 1 to 9. {{DevFeature1.9}} random is deprecated, use rand instead.<br />
<br />
* '''rand''': does the same as random, but has better MP support. See [[BuildingMultiplayerExamples]] for more info on the MP case. '''It is highly recommended that you use this feature for randomization.'''<br />
<br />
* '''time=stamp''': Retrieves a timestamp in milliseconds since wesnoth was started, can be used as timing aid. Don't try to use this as random value in MP since it will cause an OOS.<br />
<br />
* '''string_length''': Retrieves the length in characters of the string passed as this attribute's value; such string is parsed and variable substitution applied automatically (see [[VariablesWML]] for details).<br />
<br />
* '''[join]''' joins an array of strings to create a textual list<br />
** '''variable''': name of the array<br />
** '''key''': the key of each array element(array[$i].foo) in which the strings are stored<br />
** '''separator''': separator to connect the elements<br />
** '''remove_empty''': whether to ignore empty elements<br />
<br />
* '''ipart''': Assigns the integer part (the part to the left of the comma) of the referenced variable.<br />
<br />
* '''fpart''': Assigns the decimal part (the part to the right of the comma) of the referenced variable.<br />
<br />
* '''round''': Rounds the variable to the specified number of digits of precision. Negative precision works as expected (rounding 19517 to -2 = 19500). Special values:<br />
**'''ceil''': Rounds upward to the nearest integer.<br />
**'''floor''': Rounds down to the nearest integer.<br />
<br />
=== [set_variables] ===<br />
<br />
Manipulates a WML array or container<br />
<br />
* '''name''': the name of the array or container to manipulate<br />
<br />
* '''mode''': one of the following values:<br />
** ''replace'': will clean the array '''name''' and replace it with given data<br />
** ''append'': will append given data to the current array<br />
** ''merge'': will merge in the given data into '''name'''<br />
** ''insert'': will insert the given data at the index specified in the '''name''' attribute, such as name=my_array[1]. The default index is zero, which will insert to the front of the array. '''Note:''' if an invalid index is used, empty containers will be created before the insertion is performed. In other words, do not attempt to insert at an index greater than (or equal to) the array's current length. This limitation may be removed in future versions.<br />
<br />
* '''to_variable''': data will be set to the given array<br />
<br />
* '''[value]''': the WML inside the [value] tags will be stored in data, variables will be interpolated directly, use $| in order to escape the $ sign, you can store arrays of WML by supplying multiple [value] tags. ([[#Using_.5Bset_variables.5D_to_Create_Arrays_of_WML|See Example]])<br />
<br />
* '''[literal]''': same as '''[value]''', but variables will not be substituted, '''[literal]''' and '''[value]''' can not be used in the same [set_variables] tag, i.e. you can not create arrays by piling a mix of '''[value]''' and '''[literal]''' tags<br />
<br />
*'''[split]''' splits a textual list into an array which will then be set to data<br />
** '''list''': textual list to split<br />
** '''key''': the key of each array element(array[$i].foo) in which the strings are stored<br />
** '''separator''': separator to separate the elements<br />
** '''remove_empty''': whether to ignore empty elements<br />
<br />
=== Capturing Game Data ===<br />
<br />
These actions capture different bits of game data and store them to variables so they can be examined and/or manipulated.<br />
<br />
==== [store_gold] ====<br />
<br />
Stores a side's gold into a variable.<br />
<br />
* '''side''': (default=1) the side for which the gold should be stored<br />
<br />
* '''variable''': (default='gold') the name of the variable to store the gold in<br />
<br />
==== [store_locations] ====<br />
<br />
Stores a series of locations that pass certain criteria into an array. Each member of the array has members 'x' and 'y' (the position) and 'terrain' (the terrain type) and 'owner_side' (villages only). The array will include any unreachable border hexes, if applicable.<br />
<br />
* [[StandardLocationFilter]]: a location or location range which specifies the locations to store. You must specify this or no locations will be stored.<br />
<br />
* '''variable''': the name of the variable (array) into which to store the locations.<br />
<br />
==== [store_reachable_locations] {{DevFeature1.9}} ====<br />
<br />
Stores locations reachable by the given units. Can store either the movement, attack or vision ranges.<br />
<br />
* '''[filter]''': a [[StandardUnitFilter]]. The locations reachable by any of the matching units will be stored.<br />
* '''[filter_location]''': (optional) a [[StandardLocationFilter]]. Only locations which also match this filter will be stored.<br />
* '''range''': possible values ''movement'' (default), ''attack'', ''vision''. If ''movement'', stores the locations within the movement range of the unit, taking Zone of Control into account. If ''attack'', stores the attack range (movement range + 1 hex). If ''vision'', stores the vision range (movement range ignoring Zone of Control + 1 hex).<br />
* '''moves''': possible values ''current'' (default), ''max''. Specifies whether to use the current or maximum movement points when calculating the range.<br />
* '''viewing_side''': (optional) the side whose vision to use when calculating the reach. This only has meaning in the presence of fog, shroud, or units with the ambush ability. If left out, then fog, shroud and ambushers are ignored and the real reach of the units is stored.<br />
* '''variable''': the name of the variable (array) into which to store the locations.<br />
<br />
==== [store_map_dimensions] ====<br />
<br />
Stores the map dimensions in a variable.<br />
<br />
* '''variable''': the name of the variable where the values will be saved into. If it is skipped, a variable 'map_size' is used, and its contents overridden, if they existed already. The result is a container variable, with members ''width'' and ''height''.<br />
<br />
==== [store_side] ====<br />
<br />
Stores information about a certain side in a variable. The variable will contain the member variables 'name', 'team_name', 'gold' and 'income', 'fog', 'shroud', 'hidden', 'user_team_name', 'colour' (becomes 'color' in 1.9+), 'controller', 'village_gold' and 'recruit'.<br />
<br />
* '''side''': the side whose information should be stored<br />
<br />
* '''variable''': the name of the variable to store the information in<br />
<br />
==== [store_starting_location] ====<br />
<br />
Stores the starting location of a side's leader in a variable. The variable is a composite type which will have members 'x', 'y', 'terrain' (the terrain type for a starting location is always 'K' unless it has been changed) and 'owner_side' (villages only)<br />
<br />
* '''side''': the side whose starting location is to be stored<br />
<br />
* '''variable''': (default='location'): the name of the variable to store the location in<br />
<br />
==== [store_time_of_day] ====<br />
<br />
Stores time of day information from the current scenario into a WML variable container.<br />
<br />
* '''variable''': (default='time_of_day') name of the container on which to store the information. The container will be filled with the same attributes found on [[TimeWML]].<br />
<br />
* '''turn''': (defaults to the current turn number) changes the turn number for which time of day information should be retrieved.<br />
<br />
==== [store_unit] ====<br />
<br />
Stores details about units into a [[VariablesWML#Container|container]] variable. When a unit is stored, all keys and tags in the unit definition may be manipulated, including some others, with [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]]. A sample list of these tags and keys can be found [[InternalActionsWMLUnitTags|here]]. If you have a doubt about what keys are valid or what the valid value range is for each key, code a [store_unit] event, save the game, and examine what keys are in the file (or just examine the '''[unit]''' tag(s) in any save file).<br />
<br />
Common usage is to manipulate a unit by using '''[store_unit]''' to store it into a variable, followed by manipulation of the variable, and then [[DirectActionsWML|[unstore_unit]]] to re-create the unit with the modified variables.<br />
<br />
''Note: stored units also exist on the field, and modifying the stored variable will not automatically change the stats of the units. You need to use [unstore_unit]. See also [[DirectActionsWML|[unstore_unit]]] and [http://www.wesnoth.org/macro-reference.xhtml#FOREACH FOREACH].''<br />
<br />
* '''[filter]''' with a [[StandardUnitFilter]] as argument. All units matching this filter will be stored. If there are multiple units, they will be stored into an array of variables.<br />
<br />
* '''variable''': the name of the variable into which to store the unit(s)<br />
<br />
* '''mode''': defaults to ''always_clear'', which clears the variable, whether or not a match is found. If mode is set to ''replace'', the variable will only be cleared if a match is found. If mode is set to ''append'', the variable will not be cleared.<br />
<br />
* '''kill''': if 'yes' the units that are stored will be removed from play. This is useful for instance to remove access to a player's recall list, with the intent to restore the recall list later.<br />
<br />
==== [store_villages] ====<br />
<br />
Stores a series of locations of villages that pass certain criteria into an array. Each member of the array has members 'x' and 'y' (the position) and 'terrain' (the terrain type) and 'owner_side'.<br />
<br />
* '''owner_side''': a side number. If present, only villages owned by this side will be choosen. If owner_side=0, store the unowned villages. <br />
<br />
* '''variable''': the name of the variable (array) into which to store the locations<br />
<br />
* '''terrain''': a series of terrain characters. (See [[TerrainLettersWML]] for possible values.) If present, villages will only be chosen if the terrain code of the terrain type of that location is listed. You may give a comma separated list of terrains.<br />
<br />
=== [clear_variable] ===<br />
<br />
This will delete the given variable or array. This is good to use to clean up the set of variables -- e.g. a well-behaved scenario will delete any variables that shouldn't be kept for the next scenario before the end of the scenario.<br> Tags and variables of stored units can also be cleared, meaning that [trait]s and [object]s, for example, can be removed.<br />
<br />
* '''name''': the name of the variable to clear, multiple comma-separated variable names can be given.<br />
<br />
== Other Internal Actions ==<br />
<br />
Believe it or not, there are some internal actions that are not focused primarily on variables. They are all grouped here.<br />
<br />
=== [fire_event] ===<br />
<br />
Trigger a WML event<br />
<br />
* '''name''': the name of event to trigger<br />
<br />
* '''[primary_unit]''': ''(Optional)'' Primary unit for the event. Will never match on a recall list unit. The first unit matching the filter will be chosen.<br />
**[[StandardUnitFilter]] as argument. Do not use a [filter] tag.<br />
<br />
* '''[secondary_unit]''': ''(Optional)'' Same as '''[primary_unit]''' except for the secondary unit.<br />
**[[StandardUnitFilter]] as argument. Do not use a [filter] tag.<br />
<br />
* '''[primary_attack]''': Information passed to the primary attack filter and $weapon variable on the new event.<br />
<br />
* '''[secondary_attack]''': Information passed to the second attack filter and $second_weapon variable on the new event.<br />
<br />
=== [insert_tag] ===<br />
<br />
Inserts a variable as WML. In other words, the value of the passed [[VariableWML#Container|container variable]] will be injected into the game as if they had been written out in WML form. ([[#.5Binsert_tag.5D_Example|See Example]])<br />
<br />
*'''name''': The ["name"] to be given to the tag. This must be a valid [[ActionWML]] tag name for anything to happen.<br />
<br />
*'''variable''': Name of the container variable which will have its value inserted into the tag.<br />
<br />
=== [role] ===<br />
<br />
Tries to find a unit to assign a role to.<br>This is useful if you want to choose a non-major character to say some things during the game. Once a role is assigned, you can use '''role=''' in a unit filter to identify the unit with that role (See [[FilterWML]]).<br>However, there is no guarantee that roles will ever be assigned. You can use '''[have_unit]''' (see [[ConditionalActionsWML#Condition_Tags|Condition Tags]]) to see whether a role was assigned. This tag uses a [[StandardUnitFilter]] (without [filter]) with the modification to order the search by type, mark only the first unit found with the role, and the role attribute is not used in the search. If for some reason you want to search for units that have or don't have existing roles, you can use one or more [not] filters. The will check recall lists in addition to units on the map. In normal use, you will probably want to include a ''side'' attribute to force the unit to be on a particular side.<br />
<br />
* '''role''': the value to store as the unit's role. This role is not used in the [[StandardUnitFilter]] when doing the search for the unit to assign this role to.<br />
<br />
* '''type''': a comma-separated list of possible types the unit can be. If any types are given, then units will be searched by type in the order listed. If no type is given, then no particular order with respect to type is guaranteed.<br />
<br />
== Examples ==<br />
<br />
=== Using [set_variables] to Create Arrays of WML ===<br />
<br />
[set_variables]<br />
name=arr<br />
mode=replace<br />
[value]<br />
foo=bar<br />
[/value]<br />
[value]<br />
foo=more<br />
[/value]<br />
[/set_variables]<br />
{DEBUG_MSG $arr[0].foo}<br />
{DEBUG_MSG $arr[1].foo}<br />
<br />
This will produce two output messages, first one saying '''bar''' and next one saying '''more'''.<br />
<br />
=== [insert_tag] Example ===<br />
<br />
[event]<br />
name=moveto<br />
<br />
[set_variable]<br />
name=temp.speaker<br />
value=Konrad<br />
[/set_variable]<br />
<br />
[set_variable]<br />
name=temp.message<br />
value= _ "Yo Kalenz!"<br />
[/set_variable] <br />
<br />
[insert_tag]<br />
name=message<br />
variable=temp<br />
[/insert_tag]<br />
[/event]<br />
<br />
This is effectively identical to:<br />
<br />
[event]<br />
name=moveto<br />
<br />
[message]<br />
speaker=Konrad<br />
message= _ "Yo Kalenz!"<br />
[/message]<br />
[/event]<br />
<br />
== See Also ==<br />
* [[VariablesWML]]<br />
* [[ActionWML]]<br />
** [[ConditionalWML]]<br />
** [[DirectActionsWML]]<br />
** [[InterfaceActionsWML]]<br />
* [[EventWML]]<br />
* [[ReferenceWML]]<br />
<br />
[[Category: WML Reference]]<br />
[[Category: ActionsWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=InternalActionsWML&diff=40020InternalActionsWML2011-01-10T20:02:55Z<p>Paŭlo: /* See Also */ link to ActionWML</p>
<hr />
<div>{{WML Tags}}<br />
<br />
Part of [[ActionWML]], Internal actions are actions that WML uses internally that do not directly affect game play (or, at least, are not readily apparent to the player). For example, storing a variable is an internal action.<br />
<br />
== Variable Actions ==<br />
<br />
These actions are focused, in one way or another, on [[VariablesWML|variables]]. Creating them, modifying them, capturing game data to them, you name it, these actions are all about the variables.<br />
<br />
=== [set_variable] ===<br />
<br />
The '''[set_variable]''' tag is used to create and manipulate WML variables. The [http://www.wesnoth.org/macro-reference.xhtml#VARIABLE VARIABLE] macro is a quick syntactic shortcut for simple variable creation and the [http://www.wesnoth.org/macro-reference.xhtml#VARIABLE_OP VARIABLE_OP] macro is a quick syntactic shortcut for performing simple mathematical operations on variables.<br />
<br />
* '''name''': the name of the variable to manipulate<br />
<br />
* '''value''': set the variable to the given value (can be numeric or string).Use literal for no substitution. (see [[VariablesWML]])<br />
<br />
* '''literal''': set the variable to the given value (can be numeric or string). This does not interpret any dollars signs.<br />
<br />
* '''format''': This attribute will be deprecated from 1.7 on. Same behaviour as value.<br />
<br />
* '''to_variable''': set the variable to the value of the given variable, e.g. 'to_variable=temp' would be equivalent to 'value=$temp'.<br />
<br />
* '''add''': add the given amount to the variable. To subtract, add a negative number.<br />
<br />
* '''sub''' {{DevFeature}}: subtract the given amount from the variable.<br />
<br />
* '''multiply''': multiply the variable by the given number. To divide, multiply by the inverse eg: 4/2 = 4 * 1/2 = 4 * 0.5. To negate, multiply by -1. Floating point values are not rounded.<br />
<br />
* '''divide''': divide the variable by the given number. The result is an integer. Floating point results are not rounded. If both variables are integers, [http://en.wikipedia.org/wiki/Division_(mathematics)#Division_of_integers Integer division] is used.<br />
<br />
* '''modulo''': returns the remainder of a division.<br />
<br />
* '''random''': the variable will be randomly set.<br>You may provide a comma separated list of possibilities, e.g. 'random=Bob,Bill,Bella'.<br>You may provide a range of numbers (integers), e.g. 'random=3..5'.<br>You may combine these, e.g. 'random=100,1..9', in which case there would be 1/10th chance of getting 100, just like for each of 1 to 9. {{DevFeature1.9}} random is deprecated, use rand instead.<br />
<br />
* '''rand''': does the same as random, but has better MP support. See [[BuildingMultiplayerExamples]] for more info on the MP case. '''It is highly recommended that you use this feature for randomization.'''<br />
<br />
* '''time=stamp''': Retrieves a timestamp in milliseconds since wesnoth was started, can be used as timing aid. Don't try to use this as random value in MP since it will cause an OOS.<br />
<br />
* '''string_length''': Retrieves the length in characters of the string passed as this attribute's value; such string is parsed and variable substitution applied automatically (see [[VariablesWML]] for details).<br />
<br />
* '''[join]''' joins an array of strings to create a textual list<br />
** '''variable''': name of the array<br />
** '''key''': the key of each array element(array[$i].foo) in which the strings are stored<br />
** '''separator''': separator to connect the elements<br />
** '''remove_empty''': whether to ignore empty elements<br />
<br />
* '''ipart''': Assigns the integer part (the part to the left of the comma) of the referenced variable.<br />
<br />
* '''fpart''': Assigns the decimal part (the part to the right of the comma) of the referenced variable.<br />
<br />
* '''round''': Rounds the variable to the specified number of digits of precision. Negative precision works as expected (rounding 19517 to -2 = 19500). Special values:<br />
**'''ceil''': Rounds upward to the nearest integer.<br />
**'''floor''': Rounds down to the nearest integer.<br />
<br />
=== [set_variables] ===<br />
<br />
Manipulates a WML array or container<br />
<br />
* '''name''': the name of the array or container to manipulate<br />
<br />
* '''mode''': one of the following values:<br />
** ''replace'': will clean the array '''name''' and replace it with given data<br />
** ''append'': will append given data to the current array<br />
** ''merge'': will merge in the given data into '''name'''<br />
** ''insert'': will insert the given data at the index specified in the '''name''' attribute, such as name=my_array[1]. The default index is zero, which will insert to the front of the array. '''Note:''' if an invalid index is used, empty containers will be created before the insertion is performed. In other words, do not attempt to insert at an index greater than (or equal to) the array's current length. This limitation may be removed in future versions.<br />
<br />
* '''to_variable''': data will be set to the given array<br />
<br />
* '''[value]''': the WML inside the [value] tags will be stored in data, variables will be interpolated directly, use $| in order to escape the $ sign, you can store arrays of WML by supplying multiple [value] tags. ([[#Using_.5Bset_variables.5D_to_Create_Arrays_of_WML|See Example]])<br />
<br />
* '''[literal]''': same as '''[value]''', but variables will not be substituted, '''[literal]''' and '''[value]''' can not be used in the same [set_variables] tag, i.e. you can not create arrays by piling a mix of '''[value]''' and '''[literal]''' tags<br />
<br />
*'''[split]''' splits a textual list into an array which will then be set to data<br />
** '''list''': textual list to split<br />
** '''key''': the key of each array element(array[$i].foo) in which the strings are stored<br />
** '''separator''': separator to separate the elements<br />
** '''remove_empty''': whether to ignore empty elements<br />
<br />
=== Capturing Game Data ===<br />
<br />
These actions capture different bits of game data and store them to variables so they can be examined and/or manipulated.<br />
<br />
==== [store_gold] ====<br />
<br />
Stores a side's gold into a variable.<br />
<br />
* '''side''': (default=1) the side for which the gold should be stored<br />
<br />
* '''variable''': (default='gold') the name of the variable to store the gold in<br />
<br />
==== [store_locations] ====<br />
<br />
Stores a series of locations that pass certain criteria into an array. Each member of the array has members 'x' and 'y' (the position) and 'terrain' (the terrain type) and 'owner_side' (villages only). The array will include any unreachable border hexes, if applicable.<br />
<br />
* [[StandardLocationFilter]]: a location or location range which specifies the locations to store. You must specify this or no locations will be stored.<br />
<br />
* '''variable''': the name of the variable (array) into which to store the locations.<br />
<br />
==== [store_reachable_locations] {{DevFeature1.9}} ====<br />
<br />
Stores locations reachable by the given units. Can store either the movement, attack or vision ranges.<br />
<br />
* '''[filter]''': a [[StandardUnitFilter]]. The locations reachable by any of the matching units will be stored.<br />
* '''[filter_location]''': (optional) a [[StandardLocationFilter]]. Only locations which also match this filter will be stored.<br />
* '''range''': possible values ''movement'' (default), ''attack'', ''vision''. If ''movement'', stores the locations within the movement range of the unit, taking Zone of Control into account. If ''attack'', stores the attack range (movement range + 1 hex). If ''vision'', stores the vision range (movement range ignoring Zone of Control + 1 hex).<br />
* '''moves''': possible values ''current'' (default), ''max''. Specifies whether to use the current or maximum movement points when calculating the range.<br />
* '''viewing_side''': (optional) the side whose vision to use when calculating the reach. This only has meaning in the presence of fog, shroud, or units with the ambush ability. If left out, then fog, shroud and ambushers are ignored and the real reach of the units is stored.<br />
* '''variable''': the name of the variable (array) into which to store the locations.<br />
<br />
==== [store_map_dimensions] ====<br />
<br />
Stores the map dimensions in a variable.<br />
<br />
* '''variable''': the name of the variable where the values will be saved into. If it is skipped, a variable 'map_size' is used, and its contents overridden, if they existed already. The result is a container variable, with members ''width'' and ''height''.<br />
<br />
==== [store_side] ====<br />
<br />
Stores information about a certain side in a variable. The variable will contain the member variables 'name', 'team_name', 'gold' and 'income', 'fog', 'shroud', 'hidden', 'user_team_name', 'colour' (becomes 'color' in 1.9+), 'controller', 'village_gold' and 'recruit'.<br />
<br />
* '''side''': the side whose information should be stored<br />
<br />
* '''variable''': the name of the variable to store the information in<br />
<br />
==== [store_starting_location] ====<br />
<br />
Stores the starting location of a side's leader in a variable. The variable is a composite type which will have members 'x', 'y', 'terrain' (the terrain type for a starting location is always 'K' unless it has been changed) and 'owner_side' (villages only)<br />
<br />
* '''side''': the side whose starting location is to be stored<br />
<br />
* '''variable''': (default='location'): the name of the variable to store the location in<br />
<br />
==== [store_time_of_day] ====<br />
<br />
Stores time of day information from the current scenario into a WML variable container.<br />
<br />
* '''variable''': (default='time_of_day') name of the container on which to store the information. The container will be filled with the same attributes found on [[TimeWML]].<br />
<br />
* '''turn''': (defaults to the current turn number) changes the turn number for which time of day information should be retrieved.<br />
<br />
==== [store_unit] ====<br />
<br />
Stores details about units into a [[VariablesWML#Container|container]] variable. When a unit is stored, all keys and tags in the unit definition may be manipulated, including some others, with [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]]. A sample list of these tags and keys can be found [[InternalActionsWMLUnitTags|here]]. If you have a doubt about what keys are valid or what the valid value range is for each key, code a [store_unit] event, save the game, and examine what keys are in the file (or just examine the '''[unit]''' tag(s) in any save file).<br />
<br />
Common usage is to manipulate a unit by using '''[store_unit]''' to store it into a variable, followed by manipulation of the variable, and then [[DirectActionsWML|[unstore_unit]]] to re-create the unit with the modified variables.<br />
<br />
''Note: stored units also exist on the field, and modifying the stored variable will not automatically change the stats of the units. You need to use [unstore_unit]. See also [[DirectActionsWML|[unstore_unit]]] and [http://www.wesnoth.org/macro-reference.xhtml#FOREACH FOREACH].''<br />
<br />
* '''[filter]''' with a [[StandardUnitFilter]] as argument. All units matching this filter will be stored. If there are multiple units, they will be stored into an array of variables.<br />
<br />
* '''variable''': the name of the variable into which to store the unit(s)<br />
<br />
* '''mode''': defaults to ''always_clear'', which clears the variable, whether or not a match is found. If mode is set to ''replace'', the variable will only be cleared if a match is found. If mode is set to ''append'', the variable will not be cleared.<br />
<br />
* '''kill''': if 'yes' the units that are stored will be removed from play. This is useful for instance to remove access to a player's recall list, with the intent to restore the recall list later.<br />
<br />
==== [store_villages] ====<br />
<br />
Stores a series of locations of villages that pass certain criteria into an array. Each member of the array has members 'x' and 'y' (the position) and 'terrain' (the terrain type) and 'owner_side'.<br />
<br />
* '''owner_side''': a side number. If present, only villages owned by this side will be choosen. If owner_side=0, store the unowned villages. <br />
<br />
* '''variable''': the name of the variable (array) into which to store the locations<br />
<br />
* '''terrain''': a series of terrain characters. (See [[TerrainLettersWML]] for possible values.) If present, villages will only be chosen if the terrain code of the terrain type of that location is listed. You may give a comma separated list of terrains.<br />
<br />
=== [clear_variable] ===<br />
<br />
This will delete the given variable or array. This is good to use to clean up the set of variables -- e.g. a well-behaved scenario will delete any variables that shouldn't be kept for the next scenario before the end of the scenario.<br> Tags and variables of stored units can also be cleared, meaning that [trait]s and [object]s, for example, can be removed.<br />
<br />
* '''name''': the name of the variable to clear, multiple comma-separated variable names can be given.<br />
<br />
== Other Internal Actions ==<br />
<br />
Believe it or not, there are some internal actions that are not focused primarily on variables. They are all grouped here.<br />
<br />
=== [fire_event] ===<br />
<br />
Trigger a WML event<br />
<br />
* '''name''': the name of event to trigger<br />
<br />
* '''[primary_unit]''': ''(Optional)'' Primary unit for the event. Will never match on a recall list unit. The first unit matching the filter will be chosen.<br />
**[[StandardUnitFilter]] as argument. Do not use a [filter] tag.<br />
<br />
* '''[secondary_unit]''': ''(Optional)'' Same as '''[primary_unit]''' except for the secondary unit.<br />
**[[StandardUnitFilter]] as argument. Do not use a [filter] tag.<br />
<br />
* '''[primary_attack]''': Information passed to the primary attack filter and $weapon variable on the new event.<br />
<br />
* '''[secondary_attack]''': Information passed to the second attack filter and $second_weapon variable on the new event.<br />
<br />
=== [insert_tag] ===<br />
<br />
Inserts a variable as WML. In other words, the value of the passed variable will be injected into the game as if they had been written out in WML form. ([[#.5Binsert_tag.5D_Example|See Example]])<br />
<br />
*'''name''': The ["name"] to be given to the tag. This must be a valid WML tag name for anything to happen.<br />
<br />
*'''variable''': Name of the variable which will have its value inserted into the tag.<br />
<br />
=== [role] ===<br />
<br />
Tries to find a unit to assign a role to.<br>This is useful if you want to choose a non-major character to say some things during the game. Once a role is assigned, you can use '''role=''' in a unit filter to identify the unit with that role (See [[FilterWML]]).<br>However, there is no guarantee that roles will ever be assigned. You can use '''[have_unit]''' (see [[ConditionalActionsWML#Condition_Tags|Condition Tags]]) to see whether a role was assigned. This tag uses a [[StandardUnitFilter]] (without [filter]) with the modification to order the search by type, mark only the first unit found with the role, and the role attribute is not used in the search. If for some reason you want to search for units that have or don't have existing roles, you can use one or more [not] filters. The will check recall lists in addition to units on the map. In normal use, you will probably want to include a ''side'' attribute to force the unit to be on a particular side.<br />
<br />
* '''role''': the value to store as the unit's role. This role is not used in the [[StandardUnitFilter]] when doing the search for the unit to assign this role to.<br />
<br />
* '''type''': a comma-separated list of possible types the unit can be. If any types are given, then units will be searched by type in the order listed. If no type is given, then no particular order with respect to type is guaranteed.<br />
<br />
== Examples ==<br />
<br />
=== Using [set_variables] to Create Arrays of WML ===<br />
<br />
[set_variables]<br />
name=arr<br />
mode=replace<br />
[value]<br />
foo=bar<br />
[/value]<br />
[value]<br />
foo=more<br />
[/value]<br />
[/set_variables]<br />
{DEBUG_MSG $arr[0].foo}<br />
{DEBUG_MSG $arr[1].foo}<br />
<br />
This will produce two output messages, first one saying '''bar''' and next one saying '''more'''.<br />
<br />
=== [insert_tag] Example ===<br />
<br />
[event]<br />
name=moveto<br />
<br />
[set_variable]<br />
name=temp.speaker<br />
value=Konrad<br />
[/set_variable]<br />
<br />
[set_variable]<br />
name=temp.message<br />
value= _ "Yo Kalenz!"<br />
[/set_variable] <br />
<br />
[insert_tag]<br />
name=message<br />
variable=temp<br />
[/insert_tag]<br />
[/event]<br />
<br />
This is effectively identical to:<br />
<br />
[event]<br />
name=moveto<br />
<br />
[message]<br />
speaker=Konrad<br />
message= _ "Yo Kalenz!"<br />
[/message]<br />
[/event]<br />
<br />
== See Also ==<br />
* [[VariablesWML]]<br />
* [[ActionWML]]<br />
** [[ConditionalWML]]<br />
** [[DirectActionsWML]]<br />
** [[InterfaceActionsWML]]<br />
* [[EventWML]]<br />
* [[ReferenceWML]]<br />
<br />
[[Category: WML Reference]]<br />
[[Category: ActionsWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=InternalActionsWML&diff=40019InternalActionsWML2011-01-10T19:54:48Z<p>Paŭlo: link to ActionWML.</p>
<hr />
<div>{{WML Tags}}<br />
<br />
Part of [[ActionWML]], Internal actions are actions that WML uses internally that do not directly affect game play (or, at least, are not readily apparent to the player). For example, storing a variable is an internal action.<br />
<br />
== Variable Actions ==<br />
<br />
These actions are focused, in one way or another, on [[VariablesWML|variables]]. Creating them, modifying them, capturing game data to them, you name it, these actions are all about the variables.<br />
<br />
=== [set_variable] ===<br />
<br />
The '''[set_variable]''' tag is used to create and manipulate WML variables. The [http://www.wesnoth.org/macro-reference.xhtml#VARIABLE VARIABLE] macro is a quick syntactic shortcut for simple variable creation and the [http://www.wesnoth.org/macro-reference.xhtml#VARIABLE_OP VARIABLE_OP] macro is a quick syntactic shortcut for performing simple mathematical operations on variables.<br />
<br />
* '''name''': the name of the variable to manipulate<br />
<br />
* '''value''': set the variable to the given value (can be numeric or string).Use literal for no substitution. (see [[VariablesWML]])<br />
<br />
* '''literal''': set the variable to the given value (can be numeric or string). This does not interpret any dollars signs.<br />
<br />
* '''format''': This attribute will be deprecated from 1.7 on. Same behaviour as value.<br />
<br />
* '''to_variable''': set the variable to the value of the given variable, e.g. 'to_variable=temp' would be equivalent to 'value=$temp'.<br />
<br />
* '''add''': add the given amount to the variable. To subtract, add a negative number.<br />
<br />
* '''sub''' {{DevFeature}}: subtract the given amount from the variable.<br />
<br />
* '''multiply''': multiply the variable by the given number. To divide, multiply by the inverse eg: 4/2 = 4 * 1/2 = 4 * 0.5. To negate, multiply by -1. Floating point values are not rounded.<br />
<br />
* '''divide''': divide the variable by the given number. The result is an integer. Floating point results are not rounded. If both variables are integers, [http://en.wikipedia.org/wiki/Division_(mathematics)#Division_of_integers Integer division] is used.<br />
<br />
* '''modulo''': returns the remainder of a division.<br />
<br />
* '''random''': the variable will be randomly set.<br>You may provide a comma separated list of possibilities, e.g. 'random=Bob,Bill,Bella'.<br>You may provide a range of numbers (integers), e.g. 'random=3..5'.<br>You may combine these, e.g. 'random=100,1..9', in which case there would be 1/10th chance of getting 100, just like for each of 1 to 9. {{DevFeature1.9}} random is deprecated, use rand instead.<br />
<br />
* '''rand''': does the same as random, but has better MP support. See [[BuildingMultiplayerExamples]] for more info on the MP case. '''It is highly recommended that you use this feature for randomization.'''<br />
<br />
* '''time=stamp''': Retrieves a timestamp in milliseconds since wesnoth was started, can be used as timing aid. Don't try to use this as random value in MP since it will cause an OOS.<br />
<br />
* '''string_length''': Retrieves the length in characters of the string passed as this attribute's value; such string is parsed and variable substitution applied automatically (see [[VariablesWML]] for details).<br />
<br />
* '''[join]''' joins an array of strings to create a textual list<br />
** '''variable''': name of the array<br />
** '''key''': the key of each array element(array[$i].foo) in which the strings are stored<br />
** '''separator''': separator to connect the elements<br />
** '''remove_empty''': whether to ignore empty elements<br />
<br />
* '''ipart''': Assigns the integer part (the part to the left of the comma) of the referenced variable.<br />
<br />
* '''fpart''': Assigns the decimal part (the part to the right of the comma) of the referenced variable.<br />
<br />
* '''round''': Rounds the variable to the specified number of digits of precision. Negative precision works as expected (rounding 19517 to -2 = 19500). Special values:<br />
**'''ceil''': Rounds upward to the nearest integer.<br />
**'''floor''': Rounds down to the nearest integer.<br />
<br />
=== [set_variables] ===<br />
<br />
Manipulates a WML array or container<br />
<br />
* '''name''': the name of the array or container to manipulate<br />
<br />
* '''mode''': one of the following values:<br />
** ''replace'': will clean the array '''name''' and replace it with given data<br />
** ''append'': will append given data to the current array<br />
** ''merge'': will merge in the given data into '''name'''<br />
** ''insert'': will insert the given data at the index specified in the '''name''' attribute, such as name=my_array[1]. The default index is zero, which will insert to the front of the array. '''Note:''' if an invalid index is used, empty containers will be created before the insertion is performed. In other words, do not attempt to insert at an index greater than (or equal to) the array's current length. This limitation may be removed in future versions.<br />
<br />
* '''to_variable''': data will be set to the given array<br />
<br />
* '''[value]''': the WML inside the [value] tags will be stored in data, variables will be interpolated directly, use $| in order to escape the $ sign, you can store arrays of WML by supplying multiple [value] tags. ([[#Using_.5Bset_variables.5D_to_Create_Arrays_of_WML|See Example]])<br />
<br />
* '''[literal]''': same as '''[value]''', but variables will not be substituted, '''[literal]''' and '''[value]''' can not be used in the same [set_variables] tag, i.e. you can not create arrays by piling a mix of '''[value]''' and '''[literal]''' tags<br />
<br />
*'''[split]''' splits a textual list into an array which will then be set to data<br />
** '''list''': textual list to split<br />
** '''key''': the key of each array element(array[$i].foo) in which the strings are stored<br />
** '''separator''': separator to separate the elements<br />
** '''remove_empty''': whether to ignore empty elements<br />
<br />
=== Capturing Game Data ===<br />
<br />
These actions capture different bits of game data and store them to variables so they can be examined and/or manipulated.<br />
<br />
==== [store_gold] ====<br />
<br />
Stores a side's gold into a variable.<br />
<br />
* '''side''': (default=1) the side for which the gold should be stored<br />
<br />
* '''variable''': (default='gold') the name of the variable to store the gold in<br />
<br />
==== [store_locations] ====<br />
<br />
Stores a series of locations that pass certain criteria into an array. Each member of the array has members 'x' and 'y' (the position) and 'terrain' (the terrain type) and 'owner_side' (villages only). The array will include any unreachable border hexes, if applicable.<br />
<br />
* [[StandardLocationFilter]]: a location or location range which specifies the locations to store. You must specify this or no locations will be stored.<br />
<br />
* '''variable''': the name of the variable (array) into which to store the locations.<br />
<br />
==== [store_reachable_locations] {{DevFeature1.9}} ====<br />
<br />
Stores locations reachable by the given units. Can store either the movement, attack or vision ranges.<br />
<br />
* '''[filter]''': a [[StandardUnitFilter]]. The locations reachable by any of the matching units will be stored.<br />
* '''[filter_location]''': (optional) a [[StandardLocationFilter]]. Only locations which also match this filter will be stored.<br />
* '''range''': possible values ''movement'' (default), ''attack'', ''vision''. If ''movement'', stores the locations within the movement range of the unit, taking Zone of Control into account. If ''attack'', stores the attack range (movement range + 1 hex). If ''vision'', stores the vision range (movement range ignoring Zone of Control + 1 hex).<br />
* '''moves''': possible values ''current'' (default), ''max''. Specifies whether to use the current or maximum movement points when calculating the range.<br />
* '''viewing_side''': (optional) the side whose vision to use when calculating the reach. This only has meaning in the presence of fog, shroud, or units with the ambush ability. If left out, then fog, shroud and ambushers are ignored and the real reach of the units is stored.<br />
* '''variable''': the name of the variable (array) into which to store the locations.<br />
<br />
==== [store_map_dimensions] ====<br />
<br />
Stores the map dimensions in a variable.<br />
<br />
* '''variable''': the name of the variable where the values will be saved into. If it is skipped, a variable 'map_size' is used, and its contents overridden, if they existed already. The result is a container variable, with members ''width'' and ''height''.<br />
<br />
==== [store_side] ====<br />
<br />
Stores information about a certain side in a variable. The variable will contain the member variables 'name', 'team_name', 'gold' and 'income', 'fog', 'shroud', 'hidden', 'user_team_name', 'colour' (becomes 'color' in 1.9+), 'controller', 'village_gold' and 'recruit'.<br />
<br />
* '''side''': the side whose information should be stored<br />
<br />
* '''variable''': the name of the variable to store the information in<br />
<br />
==== [store_starting_location] ====<br />
<br />
Stores the starting location of a side's leader in a variable. The variable is a composite type which will have members 'x', 'y', 'terrain' (the terrain type for a starting location is always 'K' unless it has been changed) and 'owner_side' (villages only)<br />
<br />
* '''side''': the side whose starting location is to be stored<br />
<br />
* '''variable''': (default='location'): the name of the variable to store the location in<br />
<br />
==== [store_time_of_day] ====<br />
<br />
Stores time of day information from the current scenario into a WML variable container.<br />
<br />
* '''variable''': (default='time_of_day') name of the container on which to store the information. The container will be filled with the same attributes found on [[TimeWML]].<br />
<br />
* '''turn''': (defaults to the current turn number) changes the turn number for which time of day information should be retrieved.<br />
<br />
==== [store_unit] ====<br />
<br />
Stores details about units into a [[VariablesWML#Container|container]] variable. When a unit is stored, all keys and tags in the unit definition may be manipulated, including some others, with [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]]. A sample list of these tags and keys can be found [[InternalActionsWMLUnitTags|here]]. If you have a doubt about what keys are valid or what the valid value range is for each key, code a [store_unit] event, save the game, and examine what keys are in the file (or just examine the '''[unit]''' tag(s) in any save file).<br />
<br />
Common usage is to manipulate a unit by using '''[store_unit]''' to store it into a variable, followed by manipulation of the variable, and then [[DirectActionsWML|[unstore_unit]]] to re-create the unit with the modified variables.<br />
<br />
''Note: stored units also exist on the field, and modifying the stored variable will not automatically change the stats of the units. You need to use [unstore_unit]. See also [[DirectActionsWML|[unstore_unit]]] and [http://www.wesnoth.org/macro-reference.xhtml#FOREACH FOREACH].''<br />
<br />
* '''[filter]''' with a [[StandardUnitFilter]] as argument. All units matching this filter will be stored. If there are multiple units, they will be stored into an array of variables.<br />
<br />
* '''variable''': the name of the variable into which to store the unit(s)<br />
<br />
* '''mode''': defaults to ''always_clear'', which clears the variable, whether or not a match is found. If mode is set to ''replace'', the variable will only be cleared if a match is found. If mode is set to ''append'', the variable will not be cleared.<br />
<br />
* '''kill''': if 'yes' the units that are stored will be removed from play. This is useful for instance to remove access to a player's recall list, with the intent to restore the recall list later.<br />
<br />
==== [store_villages] ====<br />
<br />
Stores a series of locations of villages that pass certain criteria into an array. Each member of the array has members 'x' and 'y' (the position) and 'terrain' (the terrain type) and 'owner_side'.<br />
<br />
* '''owner_side''': a side number. If present, only villages owned by this side will be choosen. If owner_side=0, store the unowned villages. <br />
<br />
* '''variable''': the name of the variable (array) into which to store the locations<br />
<br />
* '''terrain''': a series of terrain characters. (See [[TerrainLettersWML]] for possible values.) If present, villages will only be chosen if the terrain code of the terrain type of that location is listed. You may give a comma separated list of terrains.<br />
<br />
=== [clear_variable] ===<br />
<br />
This will delete the given variable or array. This is good to use to clean up the set of variables -- e.g. a well-behaved scenario will delete any variables that shouldn't be kept for the next scenario before the end of the scenario.<br> Tags and variables of stored units can also be cleared, meaning that [trait]s and [object]s, for example, can be removed.<br />
<br />
* '''name''': the name of the variable to clear, multiple comma-separated variable names can be given.<br />
<br />
== Other Internal Actions ==<br />
<br />
Believe it or not, there are some internal actions that are not focused primarily on variables. They are all grouped here.<br />
<br />
=== [fire_event] ===<br />
<br />
Trigger a WML event<br />
<br />
* '''name''': the name of event to trigger<br />
<br />
* '''[primary_unit]''': ''(Optional)'' Primary unit for the event. Will never match on a recall list unit. The first unit matching the filter will be chosen.<br />
**[[StandardUnitFilter]] as argument. Do not use a [filter] tag.<br />
<br />
* '''[secondary_unit]''': ''(Optional)'' Same as '''[primary_unit]''' except for the secondary unit.<br />
**[[StandardUnitFilter]] as argument. Do not use a [filter] tag.<br />
<br />
* '''[primary_attack]''': Information passed to the primary attack filter and $weapon variable on the new event.<br />
<br />
* '''[secondary_attack]''': Information passed to the second attack filter and $second_weapon variable on the new event.<br />
<br />
=== [insert_tag] ===<br />
<br />
Inserts a variable as WML. In other words, the value of the passed variable will be injected into the game as if they had been written out in WML form. ([[#.5Binsert_tag.5D_Example|See Example]])<br />
<br />
*'''name''': The ["name"] to be given to the tag. This must be a valid WML tag name for anything to happen.<br />
<br />
*'''variable''': Name of the variable which will have its value inserted into the tag.<br />
<br />
=== [role] ===<br />
<br />
Tries to find a unit to assign a role to.<br>This is useful if you want to choose a non-major character to say some things during the game. Once a role is assigned, you can use '''role=''' in a unit filter to identify the unit with that role (See [[FilterWML]]).<br>However, there is no guarantee that roles will ever be assigned. You can use '''[have_unit]''' (see [[ConditionalActionsWML#Condition_Tags|Condition Tags]]) to see whether a role was assigned. This tag uses a [[StandardUnitFilter]] (without [filter]) with the modification to order the search by type, mark only the first unit found with the role, and the role attribute is not used in the search. If for some reason you want to search for units that have or don't have existing roles, you can use one or more [not] filters. The will check recall lists in addition to units on the map. In normal use, you will probably want to include a ''side'' attribute to force the unit to be on a particular side.<br />
<br />
* '''role''': the value to store as the unit's role. This role is not used in the [[StandardUnitFilter]] when doing the search for the unit to assign this role to.<br />
<br />
* '''type''': a comma-separated list of possible types the unit can be. If any types are given, then units will be searched by type in the order listed. If no type is given, then no particular order with respect to type is guaranteed.<br />
<br />
== Examples ==<br />
<br />
=== Using [set_variables] to Create Arrays of WML ===<br />
<br />
[set_variables]<br />
name=arr<br />
mode=replace<br />
[value]<br />
foo=bar<br />
[/value]<br />
[value]<br />
foo=more<br />
[/value]<br />
[/set_variables]<br />
{DEBUG_MSG $arr[0].foo}<br />
{DEBUG_MSG $arr[1].foo}<br />
<br />
This will produce two output messages, first one saying '''bar''' and next one saying '''more'''.<br />
<br />
=== [insert_tag] Example ===<br />
<br />
[event]<br />
name=moveto<br />
<br />
[set_variable]<br />
name=temp.speaker<br />
value=Konrad<br />
[/set_variable]<br />
<br />
[set_variable]<br />
name=temp.message<br />
value= _ "Yo Kalenz!"<br />
[/set_variable] <br />
<br />
[insert_tag]<br />
name=message<br />
variable=temp<br />
[/insert_tag]<br />
[/event]<br />
<br />
This is effectively identical to:<br />
<br />
[event]<br />
name=moveto<br />
<br />
[message]<br />
speaker=Konrad<br />
message= _ "Yo Kalenz!"<br />
[/message]<br />
[/event]<br />
<br />
== See Also ==<br />
* [[VariablesWML]]<br />
* [[ConditionalWML]]<br />
* [[DirectActionsWML]]<br />
* [[InterfaceActionsWML]]<br />
* [[EventWML]]<br />
* [[ReferenceWML]]<br />
<br />
[[Category: WML Reference]]<br />
[[Category: ActionsWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ActionWML&diff=40018ActionWML2011-01-10T19:53:41Z<p>Paŭlo: /* Where ActionWML can be used */ ah, mixed [variable] and {VARIABLE}.</p>
<hr />
<div>'''ActionWML''' is a summarizing term for all '''WML actions''' which can be used in events and some other places.<br />
<br />
== Types of ActionWML ==<br />
<br />
When a tag permits ActionWML, this means that it permits all of the following:<br />
<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
* conditional actions ([[ConditionalActionsWML]]) which contain other actions, which then are (maybe) executed ([if], [switch], [while], [command])<br />
* [event] (see [[EventWML#Nested Events|EventWML]]) which creates a new event handler<br />
** note: [event] can also be a subtag of [unit], [era] and [scenario], where it would not be counted as ActionWML (but has the same syntax).<br />
* [lua] ([[LuaWML]]) which contains Lua code to be executed, and<br />
* all tags created from lua with [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] (if they don't fit in one of the categories above)<br />
<br />
<br />
== Where ActionWML can be used ==<br />
<br />
ActionWML can be used<br />
* inside an [event], to define a event handler (see [[EventWML]]),<br />
* inside a [then] or [else] of an [if] tag (see [[ConditionalActionsWML]]),<br />
* inside a [case] or [else} of a [switch] tag (see [[ConditionalActionsWML]]),<br />
* inside the [do] of a [while] tag (see [[ConditionalActionsWML]]),<br />
* inside a [command] tag (in [option] or [set_menu_item] or directly as ActionWML) (see [[InterfaceActionsWML]]),<br />
* in certain Lua-created tags (if the registered WML action handler interprets the content as ActionWML).<br />
<br />
<br />
On most other places ActionWML code will either be ignored, give error messages or interpreted differently (there may be some tags which are both ActionWML and have similar or different meanings in other places, like [event]).<br />
<br />
<br />
[[Category:ActionsWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ConditionalActionsWML&diff=40017ConditionalActionsWML2011-01-10T19:50:51Z<p>Paŭlo: /* Conditional Actions */ links to ActionWML instead of Category:ActionsWML</p>
<hr />
<div>{{WML Tags}}<br />
<br />
Part of [[ActionWML]], Conditional Actions WML is used to describe container actions that create branching and flow control for WML. The [[#Conditional Actions|conditional actions]] act as gatekeepers, encapsulating other actions with [[#Condition Tags|conditions]] which must be met before an action can take place. These conditional actions also contain the actions which will take place if those conditions are met and, in some cases, what actions will take place if they are ''not'' met.<br />
<br />
== Conditional Actions ==<br />
<br />
These actions describe actions that should be executed only if certain conditions are met.<br />
<br />
=== [if] ===<br />
<br />
Executes actions only if the contained [[#Condition Tags|conditions]] are met.<br />
<br />
* [[#Condition Tags|Condition Tags]]: Conditions which must be met for the actions in the '''[then]''' tag to be executed.<br />
<br />
* '''[then]''': Contains [[ActionWML|actions]] which should be executed if all conditions evaluate as true ''or'' if any single '''[or]''' tag evaluates as true.<br />
<br />
* '''[else]''': Contains [[ActionWML|actions]] which should be executed if any condition evaluates as false ''and'' '''all''' of the '''[or]''' tags evaluate as false.<br />
<br />
=== [switch] ===<br />
<br />
The '''[switch]''' tag is a special case because it does not use [[#Condition Tags|Condition Tags]] to control whether actions are performed. Instead, it executes different sets of actions based on the value of a variable.<br />
<br />
* '''variable''': The name of the variable to check.<br />
* '''[case]''': Case tag which forms a block containing:<br />
** '''value''': The value to test the variable's value against. <br />
This can be a comma separated list of values. {{DevFeature1.9}}<br />
** [[ActionWML|Action WML]]: Action WML to execute if the variable matches the value. (The rest of the '''[case]''' block after the '''value''' attribute.)<br />
* '''[else]''': Else tag which forms a block of [[ActionWML|Action WML]] to execute if no '''[case]''' block contains a '''value''' matching the value of the '''variable'''.<br />
<br />
Example usage:<br />
[switch]<br />
variable=foo<br />
[case]<br />
value="A"<br />
... WML if foo=A ...<br />
[/case]<br />
[case]<br />
value="B"<br />
... WML if foo=B ...<br />
[/case]<br />
[else]<br />
... WML if not foo=A nor foo=B ...<br />
[/else]<br />
[/switch]<br />
<br />
=== [while] ===<br />
<br />
Like the '''[if]''' tag, executes actions only if conditions described in the contained [[#Condition Tags|conditions]] are met. Additionally, the '''[while]''' tag ''continues'' to execute the actions until the contained [[#Condition Tags|conditions]] are no longer met. Executes a maximum of 1024 iterations per invocation.<br />
<br />
* [[#Condition Tags|Condition Tags]]: Conditions which must be met for the actions in the '''[do]''' tag to be executed.<br />
<br />
* '''[do]''': contains [[ActionWML|actions]] that should be executed repeatedly until some condition is false.<br />
<br />
The '''[while]''' tag is useful for iterating over an array.<br />
An array is a list of values.<br />
The ''number''th value in the array '''array''' is stored in the WML variable '''''array''[number]'''.<br />
Note that if '''number''' is the value of the variable '''variable''',<br />
the expression '''$''array''[$variable]''' will return the ''number''th value in ''array''.<br />
<br />
==== 'FOREACH' Macro ====<br />
This macro simplifies the use of a '''[while]''' tag to create a ''for-each'' iteration format. This is useful, for example, when you want to iterate over each row in a table. To use it, use the [http://www.wesnoth.org/macro-reference.xhtml#FOREACH FOREACH] and [http://www.wesnoth.org/macro-reference.xhtml#NEXT NEXT] macros.<br />
<br />
==== 'REPEAT' Macro ====<br />
This macro simplifies the use of a '''[while]''' tag to execute the same [[ActionWML|actions]] repeatedly for a specified number of times. To use it, use the [http://www.wesnoth.org/macro-reference.xhtml#REPEAT REPEAT] macro.<br />
<br />
=== [command] ===<br />
<br />
This tag is more of an Unconditional Action: when it is encountered, the [[ActionWML|actions]] in its content are simply executed once. In practice, this tag serves little purpose. However, it may be used to arrange actions together in logical groups, for example, with actions that are stored in an array and later inserted.<br />
(It is also used inside of [set_menu_item] and [option] of [[InterfaceActionWML]].)<br />
<br />
== Condition Tags ==<br />
<br />
===True Condition Tags===<br />
These tags describe conditions which must be met before an action can take place. Some or all of them are used in the various [[#Conditional Actions|Conditional Actions]].<br />
<br />
; [have_unit]<br />
: A unit with greater than zero hit points matching this filter exists.<br />
:* [[StandardUnitFilter]] '''*''': Selection criteria. Do not use a [filter] tag.<br />'''* Note:''' ''Does '''not''' check for matching units in the recall list!''<br />
:* '''count''': ''(Optional)'' If used, a number of units equal to the value must match the filter. Accepts a number, range, or comma separated range. If not used, the default value is "1-99999".<br />
:* '''search_recall_list''': ''(Optional)'' If 'yes', search through recall list too. (Default is 'no') {{DevFeature1.9}}<br />
<br />
; [have_location]<br />
: A location matching this filter exists.<br />
:* [[StandardLocationFilter]]: Selection criteria.<br />
:* '''count''': ''(Optional)'' If used, a number of locations equal to the value must match the filter. Accepts a number, range, or comma separated range. If not used, the default value is "1-99999".<br />
<br />
; [variable]<br />
: Test the value of a WML [[VariablesWML|variable]] against another value.<br />
:* '''name''': The name of the variable to test.<br />
:* ''<comparison>'': '''One''' of the following keys must be used to compare the value of the named variable, represented as ''$name'' below, against another value:<br />
:** '''contains''': ''$name'' contains this string value.<br />
:** '''equals''': ''$name'' is equal (string wise) to this value.<br />
:** '''not_equals''': ''$name'' is not equal (string wise) to this value.<br />
:** '''numerical_equals''': ''$name'' is equal (numerically) to this value. <br />
:** '''numerical_not_equals''': ''$name'' is not equal (numerically) to this value. '''*'''<br />'''*''' Using equals is faster. The point of numerical_equals and boolean_equals is not performance, it's representation. For instance, "1" and "1.0" are not equal as strings but they are equal as numbers; and "yes" and "on" are not equal as strings but they are equal as booleans. (This also explains why equals is faster: it is a straightforward comparison that doesn't try to understand what you have written.)<br />
:** '''greater_than''': ''$name'' is greater than this value.<br />
:** '''greater_than_equal_to''': ''$name'' is greater than or equal to this value.<br />
:** '''less_than''': ''$name'' is less than this value.<br />
:** '''less_than_equal_to''': ''$name'' is less than or equal to this value.<br />
:** '''boolean_equals''': ''$name'' has an equivalent boolean value. '''*'''<br />
:** '''boolean_not_equals''': ''$name'' does not have an equivalent boolean value. '''*'''<br />
====Boolean Values====<br />
'''*''' When values are evaluated as boolean values they are checked to see if they are ''false'' or ''true''.<br />These values are evaluated as ''false'': '''no''', '''false''', '''off''', '''0''', and '''0.0''' (and "'''uninitialized'''")<br />These values are evaluated as ''true'': '''yes''', '''true''', '''on''', '''1''', and '''0.1''' (and any other non-zero number)<br />
<br />
'''Warning:''' Usage of "off", "on", integers, and floating-point numbers, as booleans, is deprecated and should be avoided to ensure forward-compatibility of WML with future versions.<br />
<br />
=== Meta Condition Tags ===<br />
<br />
These tags aren't really conditions, themselves. Instead they are wrapped around condition tags to group them into multiple conditions that must all be met, lists of conditions that only one must be met, or conditions that must not be met. These are handled in order in any combination you can think of. One important thing to remember is if you are using '''[or]''' tags, the first conditional statement should ''not'' have an '''[or]''' tag wrapped around it.<br />
<br />
; [and]<br />
: A condition which must evaluate to true in addition to any others. Useful as a bracket for complex conditions, but not strictly necessary.<br />
:* [[#Condition Tags|Condition Tags]]: If these evaluate to true, the '''[and]''' tag evaluates to true.<br />
<br />
; [or]<br />
: A condition which, if it evaluates to true, is all that is necessary for the conditions to be met. In other words, if all other conditions are false, but one '''[or]''' condition is true, the conditions have been met for an [[:Category:ActionsWML|action]] to take place. (See [[AdvancedConditionalWML|Example]])<br />
:* [[#Condition Tags|Condition Tags]]: If these evaluate to true, the '''[or]''' tag evaluates to true. <br />
<br />
; [not]<br />
: A condition which reverses the evaluation of the contained condition(s).<br />
:* [[#Condition Tags|Condition Tags]]: If these evaluate to true, the '''[not]''' tag evaluates to false. If these evaluate to false, the '''[not]''' tag evaluates to true.<br />
<br />
== See Also ==<br />
* [[VariablesWML]]<br />
* [[InternalActionsWML]]<br />
* [[DirectActionsWML]]<br />
* [[InterfaceActionsWML]]<br />
* [[EventWML]]<br />
* [[ReferenceWML]]<br />
<br />
[[Category: WML Reference]]<br />
[[Category: ActionsWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ActionWML&diff=40016ActionWML2011-01-10T19:44:39Z<p>Paŭlo: + Category:ActionsWML</p>
<hr />
<div>'''ActionWML''' is a summarizing term for all '''WML actions''' which can be used in events and some other places.<br />
<br />
== Types of ActionWML ==<br />
<br />
When a tag permits ActionWML, this means that it permits all of the following:<br />
<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
* conditional actions ([[ConditionalActionsWML]]) which contain other actions, which then are (maybe) executed ([if], [switch], [while], [command])<br />
* [event] (see [[EventWML#Nested Events|EventWML]]) which creates a new event handler<br />
** note: [event] can also be a subtag of [unit], [era] and [scenario], where it would not be counted as ActionWML (but has the same syntax).<br />
* [lua] ([[LuaWML]]) which contains Lua code to be executed, and<br />
* all tags created from lua with [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] (if they don't fit in one of the categories above)<br />
<br />
<br />
== Where ActionWML can be used ==<br />
<br />
ActionWML can be used<br />
* inside an [event], to define a event handler (see [[EventWML]]),<br />
* inside a [then] or [else] of an [if] tag (see [[ConditionalActionsWML]]),<br />
* inside a [case] or [else} of a [switch] tag (see [[ConditionalActionsWML]]),<br />
* inside the [do] of a [while] tag (see [[ConditionalActionsWML]]),<br />
* inside a [command] tag (in [option] or [set_menu_item] or directly as ActionWML) (see [[InterfaceActionsWML]]),<br />
* in certain Lua-created tags (if the registered WML action handler interprets the content as ActionWML).<br />
<br />
<br />
On most other places ActionWML code will either be ignored, give error messages or interpreted differently (there are some tags which are ActionWML and have other meanings in other places, like [event] or [variable]).<br />
<br />
<br />
[[Category:ActionsWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ConditionalActionsWML&diff=40015ConditionalActionsWML2011-01-10T19:43:19Z<p>Paŭlo: + Link to ActionWML</p>
<hr />
<div>{{WML Tags}}<br />
<br />
Part of [[ActionWML]], Conditional Actions WML is used to describe container actions that create branching and flow control for WML. The [[#Conditional Actions|conditional actions]] act as gatekeepers, encapsulating other actions with [[#Condition Tags|conditions]] which must be met before an action can take place. These conditional actions also contain the actions which will take place if those conditions are met and, in some cases, what actions will take place if they are ''not'' met.<br />
<br />
== Conditional Actions ==<br />
<br />
These actions describe actions that should be executed only if certain conditions are met.<br />
<br />
=== [if] ===<br />
<br />
Executes actions only if the contained [[#Condition Tags|conditions]] are met.<br />
<br />
* [[#Condition Tags|Condition Tags]]: Conditions which must be met for the actions in the '''[then]''' tag to be executed.<br />
<br />
* '''[then]''': Contains [[:Category:ActionsWML|actions]] which should be executed if all conditions evaluate as true ''or'' if any single '''[or]''' tag evaluates as true.<br />
<br />
* '''[else]''': Contains [[:Category:ActionsWML|actions]] which should be executed if any condition evaluates as false ''and'' '''all''' of the '''[or]''' tags evaluate as false.<br />
<br />
=== [switch] ===<br />
<br />
The '''[switch]''' tag is a special case because it does not use [[#Condition Tags|Condition Tags]] to control whether actions are performed. Instead, it executes different sets of actions based on the value of a variable.<br />
<br />
* '''variable''': The name of the variable to check.<br />
* '''[case]''': Case tag which forms a block containing:<br />
** '''value''': The value to test the variable's value against. <br />
This can be a comma separated list of values. {{DevFeature1.9}}<br />
** [[:Category:ActionsWML|Action WML]]: Action WML to execute if the variable matches the value. (The rest of the '''[case]''' block after the '''value''' attribute.)<br />
* '''[else]''': Else tag which forms a block of [[:Category:ActionsWML|Action WML]] to execute if no '''[case]''' block contains a '''value''' matching the value of the '''variable'''.<br />
<br />
Example usage:<br />
[switch]<br />
variable=foo<br />
[case]<br />
value="A"<br />
... WML if foo=A ...<br />
[/case]<br />
[case]<br />
value="B"<br />
... WML if foo=B ...<br />
[/case]<br />
[else]<br />
... WML if not foo=A nor foo=B ...<br />
[/else]<br />
[/switch]<br />
<br />
=== [while] ===<br />
<br />
Like the '''[if]''' tag, executes actions only if conditions described in the contained [[#Condition Tags|conditions]] are met. Additionally, the '''[while]''' tag ''continues'' to execute the actions until the contained [[#Condition Tags|conditions]] are no longer met. Executes a maximum of 1024 iterations per invocation.<br />
<br />
* [[#Condition Tags|Condition Tags]]: Conditions which must be met for the actions in the '''[do]''' tag to be executed.<br />
<br />
* '''[do]''': contains [[:Category:ActionsWML|actions]] that should be executed repeatedly until some condition is false.<br />
<br />
The '''[while]''' tag is useful for iterating over an array.<br />
An array is a list of values.<br />
The ''number''th value in the array '''array''' is stored in the WML variable '''''array''[number]'''.<br />
Note that if '''number''' is the value of the variable '''variable''',<br />
the expression '''$''array''[$variable]''' will return the ''number''th value in ''array''.<br />
<br />
==== 'FOREACH' Macro ====<br />
This macro simplifies the use of a '''[while]''' tag to create a ''for-each'' iteration format. This is useful, for example, when you want to iterate over each row in a table. To use it, use the [http://www.wesnoth.org/macro-reference.xhtml#FOREACH FOREACH] and [http://www.wesnoth.org/macro-reference.xhtml#NEXT NEXT] macros.<br />
<br />
==== 'REPEAT' Macro ====<br />
This macro simplifies the use of a '''[while]''' tag to execute the same [[:Category:ActionsWML|actions]] repeatedly for a specified number of times. To use it, use the [http://www.wesnoth.org/macro-reference.xhtml#REPEAT REPEAT] macro.<br />
<br />
=== [command] ===<br />
<br />
This tag is more of an Unconditional Action: when it is encountered, the contents are simply executed once. In practice, this tag serves little purpose. However, it may be used to arrange actions together in logical groups, for example, with actions that are stored in an array and later inserted.<br />
<br />
== Condition Tags ==<br />
<br />
===True Condition Tags===<br />
These tags describe conditions which must be met before an action can take place. Some or all of them are used in the various [[#Conditional Actions|Conditional Actions]].<br />
<br />
; [have_unit]<br />
: A unit with greater than zero hit points matching this filter exists.<br />
:* [[StandardUnitFilter]] '''*''': Selection criteria. Do not use a [filter] tag.<br />'''* Note:''' ''Does '''not''' check for matching units in the recall list!''<br />
:* '''count''': ''(Optional)'' If used, a number of units equal to the value must match the filter. Accepts a number, range, or comma separated range. If not used, the default value is "1-99999".<br />
:* '''search_recall_list''': ''(Optional)'' If 'yes', search through recall list too. (Default is 'no') {{DevFeature1.9}}<br />
<br />
; [have_location]<br />
: A location matching this filter exists.<br />
:* [[StandardLocationFilter]]: Selection criteria.<br />
:* '''count''': ''(Optional)'' If used, a number of locations equal to the value must match the filter. Accepts a number, range, or comma separated range. If not used, the default value is "1-99999".<br />
<br />
; [variable]<br />
: Test the value of a WML [[VariablesWML|variable]] against another value.<br />
:* '''name''': The name of the variable to test.<br />
:* ''<comparison>'': '''One''' of the following keys must be used to compare the value of the named variable, represented as ''$name'' below, against another value:<br />
:** '''contains''': ''$name'' contains this string value.<br />
:** '''equals''': ''$name'' is equal (string wise) to this value.<br />
:** '''not_equals''': ''$name'' is not equal (string wise) to this value.<br />
:** '''numerical_equals''': ''$name'' is equal (numerically) to this value. <br />
:** '''numerical_not_equals''': ''$name'' is not equal (numerically) to this value. '''*'''<br />'''*''' Using equals is faster. The point of numerical_equals and boolean_equals is not performance, it's representation. For instance, "1" and "1.0" are not equal as strings but they are equal as numbers; and "yes" and "on" are not equal as strings but they are equal as booleans. (This also explains why equals is faster: it is a straightforward comparison that doesn't try to understand what you have written.)<br />
:** '''greater_than''': ''$name'' is greater than this value.<br />
:** '''greater_than_equal_to''': ''$name'' is greater than or equal to this value.<br />
:** '''less_than''': ''$name'' is less than this value.<br />
:** '''less_than_equal_to''': ''$name'' is less than or equal to this value.<br />
:** '''boolean_equals''': ''$name'' has an equivalent boolean value. '''*'''<br />
:** '''boolean_not_equals''': ''$name'' does not have an equivalent boolean value. '''*'''<br />
====Boolean Values====<br />
'''*''' When values are evaluated as boolean values they are checked to see if they are ''false'' or ''true''.<br />These values are evaluated as ''false'': '''no''', '''false''', '''off''', '''0''', and '''0.0''' (and "'''uninitialized'''")<br />These values are evaluated as ''true'': '''yes''', '''true''', '''on''', '''1''', and '''0.1''' (and any other non-zero number)<br />
<br />
'''Warning:''' Usage of "off", "on", integers, and floating-point numbers, as booleans, is deprecated and should be avoided to ensure forward-compatibility of WML with future versions.<br />
<br />
=== Meta Condition Tags ===<br />
<br />
These tags aren't really conditions, themselves. Instead they are wrapped around condition tags to group them into multiple conditions that must all be met, lists of conditions that only one must be met, or conditions that must not be met. These are handled in order in any combination you can think of. One important thing to remember is if you are using '''[or]''' tags, the first conditional statement should ''not'' have an '''[or]''' tag wrapped around it.<br />
<br />
; [and]<br />
: A condition which must evaluate to true in addition to any others. Useful as a bracket for complex conditions, but not strictly necessary.<br />
:* [[#Condition Tags|Condition Tags]]: If these evaluate to true, the '''[and]''' tag evaluates to true.<br />
<br />
; [or]<br />
: A condition which, if it evaluates to true, is all that is necessary for the conditions to be met. In other words, if all other conditions are false, but one '''[or]''' condition is true, the conditions have been met for an [[:Category:ActionsWML|action]] to take place. (See [[AdvancedConditionalWML|Example]])<br />
:* [[#Condition Tags|Condition Tags]]: If these evaluate to true, the '''[or]''' tag evaluates to true. <br />
<br />
; [not]<br />
: A condition which reverses the evaluation of the contained condition(s).<br />
:* [[#Condition Tags|Condition Tags]]: If these evaluate to true, the '''[not]''' tag evaluates to false. If these evaluate to false, the '''[not]''' tag evaluates to true.<br />
<br />
== See Also ==<br />
* [[VariablesWML]]<br />
* [[InternalActionsWML]]<br />
* [[DirectActionsWML]]<br />
* [[InterfaceActionsWML]]<br />
* [[EventWML]]<br />
* [[ReferenceWML]]<br />
<br />
[[Category: WML Reference]]<br />
[[Category: ActionsWML]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ReferenceWML&diff=40014ReferenceWML2011-01-10T19:41:17Z<p>Paŭlo: /* Other WML tags */ + Link to ActionWML</p>
<hr />
<div>{{WML Tags}}<br />
== The Wesnoth Markup Language ==<br />
<br />
The Wesnoth Markup Language (WML) is used to code almost everything in Wesnoth, including scenarios, units, savefiles, and the user interface layout. WML files are simple, human-readable text files, usually with the .cfg extension, with similarities to INI files and XML. A major feature in WML are macros, which are alike those found in the C language and similarily are handled by a preprocessor. Implementation-wise, WML files are handled mainly by the ''config'' class (and ''simple_wml'' in [[wesnothd]]).<br />
<br />
This page is a collection of pointers to different common WML structures. See [[AlphabeticalWML]] for a quick listing of all WML tags. The more comprehensive [[BuildingScenariosIndex]] lists tags and keys.<br />
<br />
See [[BuildingScenarios]], [[BuildingCampaigns]] and [[BuildingUnits]]<br />
for a tutorial style overview.<br />
<br />
<br />
<br />
''Note: this reference may contain slight inaccuracies, might not list all existing keys and tags or might contain some deprecated syntax. If you find that this reference doesn't give you the answer to how to implement some feature in WML, the most reliable way is to look at the WML code of existing units and campaigns that have done so.''<br />
<br />
== How WML works ==<br />
<br />
* [[SyntaxWML]] the language syntax.<br />
** [[VariablesWML]] how to use WML variables<br />
* [[PreprocessorRef]] the WML preprocessor syntax<br />
** [[UtilWML]] utility macros defined in utils.cfg<br />
<br />
== WML toplevel tags ==<br />
<br />
* [[GameConfigWML]] the top level '''[game_config]''' tag<br />
* [[UnitsWML]] the top level '''[units]''' tag<br />
** [[UnitTypeWML]] how to describe a unit type<br />
** [[AnimationWML]] how to animate units<br />
* [[CampaignWML]] the top level '''[campaign]''' tag<br />
* [[ScenarioWML]] the top level tags '''[scenario]''', '''[multiplayer]''', '''[test]''', and '''[tutorial]'''<br />
** [[EventWML]] how to describe an event<br />
** [[SideWML]] how to describe a side<br />
** [[MapGeneratorWML]] the random map generator<br />
** [[TimeWML]] how to describe a day<br />
** [[IntroWML]] how to describe the intro screen<br />
* [[SavefileWML]] a description of the format of savegames<br />
** [[ReplayWML]] a description of the format of player actions such as moving a unit<br />
** [[StatisticalScenarioWML]] used to generate statistics of a savegame<br />
* [[PblWML]] a description of the format of server-uploadable campaigns<br />
* [[EraWML]] the top level '''[era]''' tag<br />
* [[TerrainWML]] the top level '''[terrain]''' tag<br />
* [[TerrainGraphicsWML]], the top level '''[terrain_graphics]''' tag<br />
* [[ThemeWML]] the top level '''[theme]''' tag<br />
* [[LanguageWML]] the top level '''[language]''' tag<br />
* [[LocaleWML]] the top level '''[locale]''' tag<br />
* [[HelpWML]] the top level '''[help]''' tag<br />
* [[BinaryPathWML]] the top level '''[binary_path]''' tag<br />
* [[FontsWML]] the top level '''[fonts]''' tag<br />
<br />
== Other WML tags ==<br />
<br />
* [[EventWML]] how to describe an event<br />
** [[FilterWML]] the construct to filter on units, locations, and weapons<br />
** [[ActionWML]] to describe the actions which occur when the event is fired<br />
*** [[ConditionalActionsWML]] actions that encapsulate conditional filters and the actions to execute if the conditions are met<br />
*** [[DirectActionsWML]] actions that directly affect gameplay: for example creating a unit<br />
*** [[InternalActionsWML]] actions that WML uses internally: for example storing a variable<br />
*** [[InterfaceActionsWML]] actions that do not affect gameplay: for example displaying a message<br />
*** [[LuaWML]] how to code actions with the Lua language<br />
* [[SingleUnitWML]] how to describe a unit<br />
* [[AiWML]] how to describe parameters for AI<br />
* [[EffectWML]] the construct to modify a unit<br />
* [[AbilitiesWML]] a list of the different abilities a unit or weapon can have<br />
* [[DescriptionWML]] the structure of WML coded menus like the difficulty chooser of campaigns<br />
* [[EditorWML]] tags controllin the post-1.4 editor's behavior<br />
<br />
== Predefined macros == <br />
<br />
Wesnoth ships with a library of predefined macros you should find useful in writing your own WML. You can find a description of all such macros [http://www.wesnoth.org/macro-reference.html here].<br />
<br />
== Other ==<br />
<br />
* [[ReferenceWMLSyntax]] how this wiki and the pages it links to should be formatted<br />
* [[ConventionsWML]] how to make your WML more readable<br />
* [[UsefulWMLFragments]] Various pieces of WML for various purposes. If you have some WML you're proud of that you think others can use, add it here.<br />
* [[CommandMode]] commands are not strictly speaking part of WML, these could be a little hard to find so there's a link here.<br />
* [[MultiplayerServerWML]] is used when communicating with the multiplayer server.<br />
* [[CampaignServerWML]] is used when managing contributed campaigns on the campaign server.<br />
* [[ImagePathFunctionWML]] is used when applying the team-color function to images.<br />
* [[BinaryWML]] how WML is sent over the network<br />
<br />
== See Also ==<br />
<br />
* [[BuildingMaps]] the text-based format for Wesnoth maps<br />
* [[TerrainCodesWML]] a list of all terrains<br />
* [[MultiHexTutorial]] a description of the multi-hex tiling system<br />
* [[IGNFileFormat]] a description of the ignore file format<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=LuaWML&diff=40013LuaWML2011-01-10T19:39:34Z<p>Paŭlo: /* The [lua] tag */ link to ActionWML</p>
<hr />
<div>{{WML Tags}}<br />
<br />
== The '''[lua]''' tag ==<br />
<br />
This tag is a part of [[ActionWML]], thus can be used inside [event] and at other places where [[ActionWML]] can be used. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.<br />
<br />
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.<br />
<br />
[lua]<br />
code = << wesnoth.message "Hello World!" >><br />
[/lua]<br />
<br />
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:<br />
<br />
:lua local u = wesnoth.get_units({ id = "Konrad" })[1]; u.moves = 5<br />
<br />
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable "'''...'''".<br />
<br />
[lua]<br />
code = << local t = ...; wesnoth.message(tostring(t.text)) >><br />
[args]<br />
text = _ "Hello world!"<br />
[/args]<br />
[/lua]<br />
<br />
== Global environment ==<br />
<br />
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.<br />
<br />
[event]<br />
name = preload<br />
first_time_only = no<br />
[lua]<br />
code = <<<br />
function narrator(t)<br />
-- Behave like the [message] tag.<br />
wesnoth.fire("message",<br />
{ speaker = "narrator", message = t.sentence })<br />
end<br />
>><br />
[/lua]<br />
[/event]<br />
<br />
[event]<br />
name = turn 1<br />
[lua]<br />
code = << narrator(...) >><br />
[args]<br />
sentence = _ "Hello world!"<br />
[/args]<br />
[/lua]<br />
[lua]<br />
code = << narrator(...) >><br />
[args]<br />
sentence = _ "How are you today?"<br />
[/args]<br />
[/lua]<br />
[/event]<br />
<br />
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.<br />
<br />
[event]<br />
name = preload<br />
first_time_only = no<br />
[lua]<br />
code = <<<br />
-- The function is now local, since its name does not have to be<br />
-- visible outside this Lua scripts.<br />
local function handler(t)<br />
-- Behave like the [message] tag.<br />
wesnoth.fire("message",<br />
{ speaker = "narrator", message = t.sentence })<br />
end<br />
-- Create a new tag named [narrator].<br />
wesnoth.register_wml_action("narrator", handler)<br />
>><br />
[/lua]<br />
[/event]<br />
<br />
[event]<br />
name = turn 1<br />
[narrator]<br />
sentence = _ "Hello world!"<br />
[/narrator]<br />
[narrator]<br />
sentence = _ "How are you today?"<br />
[/narrator]<br />
[/event]<br />
<br />
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.<br />
<br />
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].<br />
<br />
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any.<br />
<br />
== Examples ==<br />
<br />
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.<br />
<br />
# General catch for them moving to the wrong place.<br />
[event]<br />
name=moveto<br />
first_time_only=no<br />
[allow_undo][/allow_undo]<br />
[filter]<br />
side=1<br />
[/filter]<br />
<br />
[if]<br />
[variable]<br />
name=target_hex.is_set<br />
equals=yes<br />
[/variable]<br />
[then]<br />
[if]<br />
[variable]<br />
name=x1<br />
equals=$target_hex.x<br />
[/variable]<br />
[variable]<br />
name=y1<br />
equals=$target_hex.y<br />
[/variable]<br />
[then]<br />
[/then]<br />
[else]<br />
[redraw][/redraw]<br />
[message]<br />
speaker=narrator<br />
message=_ "*Oops!<br />
You moved to the wrong place! After this message, you can press 'u' to undo, then try again." +<br />
_ "<br />
*Left click or press spacebar to continue..."<br />
[/message]<br />
[/else]<br />
[/if]<br />
[/then]<br />
[/if]<br />
[/event]<br />
<br />
A Lua script that performs the same action is presented below.<br />
<br />
[event]<br />
name=moveto<br />
first_time_only=no<br />
[allow_undo][/allow_undo]<br />
[filter]<br />
side=1<br />
[/filter]<br />
<br />
[lua]<br />
code = <<<br />
local event_data = wesnoth.current.event_context<br />
if target_hex.is_set and<br />
(event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)<br />
then<br />
W.redraw()<br />
narrator_says(_ "*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.")<br />
end<br />
>><br />
[/lua]<br />
[/event]<br />
<br />
Here is a more detailed explanation of the Lua code. Its first line<br />
<br />
local event_data = wesnoth.current.event_context<br />
<br />
puts the event data into the ''event_data'' local variable. Since it is a ''moveto'' event, the ''event_data'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.<br />
<br />
The next two lines then test<br />
<br />
if target_hex.is_set and<br />
(event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)<br />
<br />
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.<br />
<br />
[event]<br />
name=preload<br />
first_time_only=no<br />
[lua]<br />
code = <<<br />
H = wesnoth.require "lua/helper.lua"<br />
-- skipping some other initializations<br />
-- ...<br />
H.set_wml_var_metatable(_G)<br />
>><br />
[/lua]<br />
[/event]<br />
<br />
Without a prelude redirecting ''_G'', the conditional would have been written<br />
<br />
if wesnoth.get_variable("target_hex.is_set") and<br />
(event_data.x1 ~= wesnoth.get_variable("target_hex.x") or event_data.y1 ~= wesnoth.get_variable("target_hex.y")<br />
<br />
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.<br />
<br />
W.redraw()<br />
<br />
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.<br />
<br />
W = H.set_wml_action_metatable {}<br />
<br />
Without this shortcut, the first statement would have been written<br />
<br />
wesnoth.fire("redraw")<br />
<br />
Finally the script displays a message by<br />
<br />
narrator_says(_ "*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.")<br />
<br />
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is<br />
<br />
function narrator_says(m)<br />
W.message { speaker="narrator",<br />
message = m .. _ "\n*Left click or press spacebar to continue..." }<br />
end<br />
<br />
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:<br />
<br />
_ = wesnoth.textdomain "wesnoth-tutorial"<br />
<br />
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].<br />
<br />
== Interface to the engine and helper functions ==<br />
<br />
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked "read-only" are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.<br />
<br />
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].<br />
<br />
helper = wesnoth.require "lua/helper.lua"<br />
<br />
=== WML variables ===<br />
<br />
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]<br />
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]<br />
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]<br />
* [[LuaWML:Variables#helper.get_child|helper.get_child]]<br />
* [[LuaWML:Variables#helper.child_range|helper.child_range]]<br />
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]<br />
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]<br />
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]<br />
<br />
=== Events and WML actions ===<br />
<br />
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]<br />
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]<br />
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}<br />
* [[LuaWML:Events#wesnoth.game_events|wesnoth.game_events]] {{DevFeature1.9}}<br />
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]<br />
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]<br />
* [[LuaWML:Events#wesnoth.tovconfig|wesnoth.tovconfig]] {{DevFeature1.9}}<br />
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]<br />
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]<br />
* [[LuaWML:Events#helper.literal|helper.literal]] {{DevFeature1.9}}<br />
* [[LuaWML:Events#helper.parsed|helper.parsed]] {{DevFeature1.9}}<br />
* [[LuaWML:Events#helper.shallow_literal|helper.shallow_literal]] {{DevFeature1.9}}<br />
* [[LuaWML:Events#helper.shallow_parsed|helper.shallow_parsed]] {{DevFeature1.9}}<br />
<br />
=== User interface ===<br />
<br />
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]<br />
* [[LuaWML:Display#wesnoth.clear_messages|wesnoth.clear_messages]] {{DevFeature1.9}}<br />
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]<br />
* [[LuaWML:Display#wesnoth.delay|wesnoth.delay]] {{DevFeature1.9}}<br />
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]<br />
* [[LuaWML:Display#wesnoth.hilight_hex|wesnoth.hilight_hex]] {{DevFeature1.9}}<br />
* [[LuaWML:Display#wesnoth.select_hex|wesnoth.select_hex]] {{DevFeature1.9}}<br />
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}<br />
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}<br />
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}<br />
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}<br />
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}<br />
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}<br />
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}<br />
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}<br />
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]<br />
<br />
=== Map and terrains ===<br />
<br />
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]<br />
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]<br />
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]<br />
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]<br />
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]<br />
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]] {{DevFeature1.9}}<br />
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]] {{DevFeature1.9}}<br />
* [[LuaWML:Tiles#wesnoth.add_tile_overlay|wesnoth.add_tile_overlay]] {{DevFeature1.9}}<br />
* [[LuaWML:Tiles#wesnoth.remove_tile_overlay|wesnoth.remove_tile_overlay]] {{DevFeature1.9}}<br />
* [[LuaWML:Tiles#items.place_image|items.place_image]] {{DevFeature1.9}}<br />
* [[LuaWML:Tiles#items.place_halo|items.place_halo]] {{DevFeature1.9}}<br />
* [[LuaWML:Tiles#items.remove|items.remove]] {{DevFeature1.9}}<br />
<br />
=== Units ===<br />
<br />
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]<br />
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}<br />
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}<br />
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]<br />
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}<br />
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}<br />
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]<br />
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]<br />
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}<br />
* [[LuaWML:Units#wesnoth.add_modification|wesnoth.add_modification]] {{DevFeature1.9}}<br />
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]<br />
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]<br />
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]<br />
* [[LuaWML:Units#wesnoth.unit_ability|wesnoth.unit_ability]] {{DevFeature1.9}}<br />
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]<br />
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]<br />
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}<br />
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]<br />
<br />
=== Sides ===<br />
<br />
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]<br />
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}<br />
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]<br />
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]<br />
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}<br />
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]<br />
<br />
=== Pathfinder ===<br />
<br />
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]<br />
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]<br />
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]<br />
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]<br />
* [[LuaWML:Pathfinder#helper.adjacent_tiles|helper.adjacent_tiles]] {{DevFeature1.9}}<br />
<br />
=== Lua files ===<br />
<br />
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]<br />
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]<br />
<br />
=== Location sets ===<br />
<br />
* [[LuaWML:Location_set#location_set.create|location_set.create]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set.of_pairs|location_set.of_pairs]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set.of_wml_var|location_set.of_wml_var]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:empty|location_set:empty]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:size|location_set:size]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:clear|location_set:clear]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:get|location_set:get]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:insert|location_set:insert]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:remove|location_set:remove]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:of_pairs|location_set:of_pairs]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:of_wml_var|location_set:of_wml_var]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:to_pairs|location_set:to_pairs]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:to_stable_pairs|location_set:to_stable_pairs]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:to_wml_var|location_set:to_wml_var]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:union|location_set:union]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:inter|location_set:inter]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:iter|location_set:iter]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:stable_iter|location_set:stable_iter]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:filter|location_set:filter]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:union_merge|location_set:union_merge]] {{DevFeature1.9}}<br />
* [[LuaWML:Location_set#location_set:inter_merge|location_set:inter_merge]] {{DevFeature1.9}}<br />
<br />
=== Miscellaneous ===<br />
<br />
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]<br />
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]<br />
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]] {{DevFeature1.9}}<br />
* [[LuaWML:Misc#wesnoth.get_image_size|wesnoth.get_image_size]] {{DevFeature1.9}}<br />
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]<br />
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]<br />
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]<br />
* [[LuaWML:Misc#helper.rand|helper.rand]] {{DevFeature1.9}}<br />
<br />
== Encoding WML objects into Lua tables ==<br />
<br />
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.<br />
<br />
Scalar fields are transformed into WML attributes. For instance, the following Lua table<br />
<br />
{<br />
a_bool = true,<br />
an_int = 42,<br />
a_float = 1.25,<br />
a_string = "scout",<br />
a_translation = _ "Hello World!"<br />
}<br />
<br />
is equivalent to the content of the following WML object<br />
<br />
[dummy]<br />
a_bool = "yes"<br />
an_int = "42"<br />
a_float = "1.25"<br />
a_string = "scout"<br />
a_translation = _ "Hello World!"<br />
[/dummy]<br />
<br />
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. This means that for every subtag appearing in the wml code there is an additional table "layer" in the corresponding WML table of the form {[1] = "tag_name", [2] = {}} which is equivalent to {"tag_name", {}}. [1] etc are the unnamed fields (as opposed to wml attributes). The table under [2] in this subtable then holds the wml attributes from inside the wml subtag. So every subtag other than the toplevel tag corresponds to two nested tables each. For instance, the following Lua table<br />
<br />
{<br />
foo = 42,<br />
{ "bar", { v = 1, w = 2 } },<br />
{ "foo", { x = false } },<br />
{ "bar", { y = "foo" } },<br />
{ "foobar", { z = 5, { "barfoo", {} } } }<br />
}<br />
<br />
is equivalent to the content of the following WML object<br />
<br />
[dummy]<br />
foo = 42<br />
[bar]<br />
v = 1<br />
w = 2<br />
[/bar]<br />
[foo]<br />
x = no<br />
[/foo]<br />
[bar]<br />
y = foo<br />
[bar]<br />
[foobar]<br />
z = 5<br />
[barfoo]<br />
[/barfoo]<br />
[/foobar]<br />
[/dummy]<br />
<br />
Both tables above are also equivalent to this WML table, where all unnamed fields are displayed:<br />
{<br />
foo = 42,<br />
[1] = { [1] = "bar", [2] = { v = 1, w = 2 } },<br />
[2] = { [1] = "foo", [2] = { x = false } },<br />
[3] = { [1] = "bar", [2] = { y = "foo" } },<br />
[4] = { [1] = "foobar", [2] = { z = 5, [1] = { [1] = "barfoo", [2] = {} } } }<br />
}<br />
<br />
So assuming ''cfg'' contains the above WML object, the following accesses are possible:<br />
<br />
a_int = cfg.foo -- "dummy.foo", 42<br />
a_string = cfg[3][2].y -- "dummy.bar[1].y", "foo"<br />
a_table = cfg[4][2] -- "dummy.foobar", { z = 5, { "barfoo", {} } }<br />
<br />
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.<br />
<br />
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.<br />
<br />
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.<br />
<br />
local old_event_handler<br />
old_event_handler = register_wml_action("event",<br />
function(cfg)<br />
-- Get the plain text from the user.<br />
local new_cfg = cfg.__literal<br />
-- The expression below is equivalent to cfg.__parsed.first_time_only,<br />
-- only faster. It is needed, since the first_time_only attribute may<br />
-- reference variables.<br />
local first = cfg.first_time_only<br />
-- Modify the default behavior of first_time_only.<br />
if first == nil then first = false end<br />
new_cfg.first_time_only = first<br />
-- Call the engine handler.<br />
old_event_handler(new_cfg)<br />
end<br />
)<br />
<br />
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:<br />
<br />
function get_child(cfg, name)<br />
for i = 1, #cfg do<br />
local v = cfg[i]<br />
if v[1] == name then return v[2] end<br />
end<br />
end<br />
<br />
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:<br />
<br />
if getmetatable(cfg) == "wml object" then cfg = cfg.__parsed end<br />
<br />
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.<br />
<br />
== Skeleton of a preload event ==<br />
<br />
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.<br />
<br />
[event]<br />
name=preload<br />
first_time_only=no<br />
[lua]<br />
code = <<<br />
H = wesnoth.require "lua/helper.lua"<br />
W = H.set_wml_action_metatable {}<br />
_ = wesnoth.textdomain "my-campaign"<br />
<br />
-- Define your global constants here.<br />
-- ...<br />
<br />
H.set_wml_var_metatable(_G)<br />
<br />
-- Define your global functions here.<br />
-- ...<br />
>><br />
[/lua]<br />
[/event]<br />
<br />
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:<br />
<br />
[event]<br />
name=preload<br />
first_time_only=no<br />
[lua]<br />
code = << wesnoth.dofile "~add-ons/Whatever/file.lua" >><br />
[/lua]<br />
[/event]<br />
<br />
== Remarks ==<br />
<br />
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.<br />
<br />
function random(min, max)<br />
if not max then min, max = 1, min end<br />
wesnoth.fire("set_variable", { name = "LUA_random", rand = string.format("%d..%d", min, max) })<br />
local res = wesnoth.get_variable "LUA_random"<br />
wesnoth.set_variable "LUA_random"<br />
return res<br />
end</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=EventWML&diff=40012EventWML2011-01-10T19:35:37Z<p>Paŭlo: /* The [event] Tag */ link to ActionWML</p>
<hr />
<div>{{WML Tags}}<br />
== The [event] Tag ==<br />
<br />
This tag is a subtag of the [scenario], [unit_type] and [era] tags which is used to describe a set of [[ActionWML|actions]] which trigger at a certain point in a scenario. When used in a [scenario] tag (also includes [multiplayer], [tutorial] and [test]), the event only occurs in that scenario. When used in a [unit_type] tag, the event will occur in all scenarios in which a unit of that type appears in (only after such a unit appears during the scenario, however). When used in an [era], the event will occur in any scenario which is played using that era.<br />
<br />
This tag has keys and child tags that control when and if the event actions will be triggered. Most important of these is the '''name''' key. Without it, no error will be raised but the event will never fire. Therefore, from a practical standpoint, it can be considered mandatory. All of the others can be used or not and the event actions will fire either way.<br />
<br />
'''Lexicon side note:''' ''The word "event" in the [event] tag itself may be considered an abbreviation of the word "event handler" because it is technically not a game "event" but an event '''handler''' for the game events fired with the given 'name'. However, this distinction is usually unimportant in most discussions and the event handlers are therefore simply referred to as "events" in this documentation.''<br />
<br />
=== The 'name' Key (Mandatory) ===<br />
<br />
Usage:<br />
name=<value><br />
<br />
This key defines which game event or trigger your [event] tag will be handling. This 'name' key should not be confused with a descriptive comment; it is rather a precise value which must match the predefined game event's name to be valid.<br />
<br />
'''Lexicon side note:''' ''It is not uncommon to refer to these values as the 'trigger' for an event and, furthermore, to call an event by its 'trigger' name. For example, in an event containing '''name=moveto''', a person might refer to the event as a ''''moveto''' event' and/or refer to the ''''moveto''' trigger' in the event or even talk about the 'event trigger' when referring to the '''moveto''' value of the 'name' key in that event. Some or all of this usage can, in fact, be found throughout this page.''<br />
<br />
The '''name''' key can accept a list of comma separated values describing when the event will be triggered.* These values may be either predefined event types or custom event names not matching any predefined type.<br />
<br />
For example:<br />
<br />
name=attacker misses,defender misses<br />
<br />
''* Note that unless you use [[#first_time_only|first_time_only=no]], the event will fire only once, '''not''' once for each listed type.''<br />
<br />
==== Predefined 'name' Key Values ====<br />
<br />
All predefined event types are listed here along with a description of when this value will cause the event to be triggered. Any value ''not'' listed here is a custom event name which can be triggered only by a '''[fire_event]''' tag somewhere else. Spaces in event names can be interchanged with underscores (for example, '''name=new turn''' and '''name=new_turn''' are equivalent).<br />
<br />
; preload<br />
: Triggers before a scenario 'prestarts' and when loading a savegame -- before anything is shown on the screen at all. Can be used to set up the [[LuaWML|Lua]] environment: loading libraries, defining helper functions, etc.<br />
: '''Note:''' Unlike prestart and start, the preload event '''must be able to fire more than once!''' This is because it is triggered each time a savegame is loaded in addition to the initial time when it loads before the scenario 'prestart'. This means that it is effectively ''mandatory'' to have the [[#first_time_only|first_time_only=no]] key value in a preload event. <br />
<br />
; prestart<br />
: Triggers before a scenario 'starts' -- before anything is shown on the screen at all. Can be used to set up things like village ownership. For things displayed on-screen such as character dialog, use '''start''' instead.<br />
: '''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
; start<br />
: Triggers after the map is shown but before the scenario begins -- before players can 'do' anything.<br />
: '''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
; new turn<br />
: Triggers at the start of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. Before any events of this type trigger, the value of the WML variable '''turn_number''' is set to the number of the turn that is beginning.<br />
<br />
; turn end {{DevFeature1.9}}<br />
: Triggers at the end of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. The WML variable '''side_number''' will contain the side that ended their turn.<br />
<br />
; turn ''X'' end {{DevFeature1.9}}<br />
: Triggers at the end of turn ''X''.<br />
<br />
; side turn<br />
: Triggers when a side is about to start its turn. Before events of this type trigger, the value of the WML variable '''side_number''' is set to the number of the side of the player about to take their turn. This is before any healing takes place for that side, before calculating income, and before restoring unit movement and status.<br />
<br />
; ai turn<br />
: Triggered just before the AI is invoked for a side. This is called after ''side turn'', and thus the WML variable '''side_number''' still holds the number of this side. Note that this event might be called several times per turn in case that fallbacks to human or droiding is involved. I.e. it happens at the middle of turn of human side 1 if the human player droids his side. It happens after the selection of ai to play the turn but before AI is told that new turn has come.<br />
: '''Note:''' ''This event currently breaks replays since it is not explicitly saved in a replay and there is no AI involved in replays...''<br />
<br />
; turn refresh<br />
: Like '''side turn''', triggers just before a side is taking control but '''after''' healing, calculating income, and restoring unit movement and status.<br />
<br />
; turn ''X''<br />
: Triggers at the start of turn ''X''. It's the first side initialization event. <br />
:Side initialization events go in the order of: <br />
: 1) '''turn ''X''''' <br />
:2) '''new turn''' <br />
:3) '''side turn''' <br />
:4) '''side ''X'' turn''' <br />
:5) '''side turn ''X''''' <br />
:6) '''side ''X'' turn ''Y''''' <br />
:7) '''turn refresh''' <br />
:8) '''side ''X'' turn refresh''' <br />
:9) '''turn ''X'' refresh''' <br />
:10) '''side ''X'' turn ''Y'' refresh'''<br />
<br />
; side ''X'' turn ''Y''<br />
: This event triggers at the start of turn ''Y'' of side X {{DevFeature}}<br />
<br />
; side ''X'' turn<br />
: This event triggers at the start of any turn of side X {{DevFeature}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side turn ''X''<br />
: This event triggers at the start of any side on turn X {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side X turn Y refresh<br />
: This event triggers at the turn refresh for side X on turn Y {{DevFeature1.9}}<br />
<br />
; side ''X'' turn refresh<br />
: This event triggers at the turn refresh for side X {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; turn ''X'' refresh<br />
: This event triggers for any side at the refresh of turn X. {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side turn end {{DevFeature1.9}}<br />
: Triggers after a side ends its turn. Like side turn, there are also some variations for specific combinations of side number and turn number. Here is the order in which the turn end events trigger:<br />
:1) '''side turn end''' <br />
:2) '''side ''X'' turn end''' <br />
:3) '''side turn ''X'' end''' <br />
:4) '''side ''X'' turn ''Y'' end''' <br />
:5) '''turn end''' <br />
:6) '''turn ''X'' end''' <br />
<br />
; time over<br />
: Triggers on turn ''turns''. (''turns'' is specified in [scenario])<br />
<br />
; enemies defeated<br />
: Triggers when all units with '''canrecruit=yes''' (that is, all leaders) not allied with side 1 are killed.<br />
<br />
; victory<br />
: In this scenario, any tag of the form '''[endlevel] result=victory [/endlevel]''' will be automatically preceded by all actions in this tag. It helps debugging if the victory event allows you to safely advance to any of the possible next maps after using the ":n" command. Scenarios where key units are picked up before the victory, or where some action chosen earlier determines which map to advance to, make it hard to quickly test scenarios in a campaign. (See also: [endlevel], [[DirectActionsWML]])<br />
<br />
; defeat<br />
: In this scenario, any tag of the form '''[endlevel] result=defeat [/endlevel]''' will be automatically preceded by all actions in this tag. (See also [endlevel], [[DirectActionsWML]])<br />
<br />
<br />
Filters (except [filter_condition] which is for all sorts of events) can be applied to the following event triggers (see [[FilterWML]]; see also below). The actions specified in the event tag will be executed only if the filter returns true. <br />
These event triggers are all actions by units ('''moveto''', '''attack''') or things that happen to units ('''recruit''', '''advance'''). When one of these events is triggered, the position of the active unit (referred to as the '''primary unit''') is stored in the variables '''x1''' and '''y1''' and the position of any unit that primary unit does something to is stored in the variables '''x2''' and '''y2''' (this unit is referred to as the '''secondary unit''' below). '' These units are also automatically stored in the variables 'unit' and 'second_unit' as if they had been stored using the '''[store_unit]''' tag. see [[SingleUnitWML]]<br />
<br />
; moveto<br />
: Triggers after the primary unit moves. Typically this is used when the primary unit gets to a particular location and a filter for the location of the primary unit is included; remember that this is the location that the primary unit lands on, not the location it started on or any location it travels on.<br />''An '''[allow_undo]''' tag anywhere within a moveto event will cancel any lack of undo functionality the event would have caused. Note that undo functionality will only move the unit back to its former location; it will not undo other changes to the game caused by the event. Thus it is up to the scenario designer to use this tag correctly.'' {{DevFeature}} $x2 and $y2 refer to the hex the unit came from.<br />
<br />
; sighted<br />
: '''important: "sighted" events are very buggy in general, especially if "delay shroud updates" is set to "yes". Avoid using them despite of them being (still) used a lot in mainline.''' {{DevFeature1.9}}: It is currently tested whether the introduction of the "whiteboard" feature is accepted, making it possible to remove the "delay shroud updates" option which could in return make this event stable again.<br />
: A '''sighted''' event is triggered when a fog or shroud is lifted from the primary ''unit''. This can happen when a ''second_unit'' moves to a nearby location and discovers the primary ''unit''. Alternatively, the ''second_unit'' might emerge "out of the mist" and be discovered simultaneously by all members of the enemy side: in this case, the ''second_unit'' is not set. (This is part of the sighted event's bugs.)<br />
<br />
: '''Note:''' The sighted event is ''only'' triggered when a unit moves from one location to another. When the player moves to attack an enemy unit and, in the process, removes the fog/shroud over an enemy unit, the sighted event does ''not'' fire. This makes the sighted event unreliable: It may or may not fire, depending on the user actions. (This may be part of the sighted event's bugs.)<br />
<br />
: '''Alternatives:''' It is sometimes possible to replace a sighted event by a moveto event with a [[StandardLocationFilter|location filter]] matching a nearby location. A [[FilterWML#Filtering_Vision|filter_vision]] filter may be useful in some cases.<br />
<br />
; attack<br />
: Triggers when the primary unit attacks the secondary unit.<br />
<br />
; attack end<br />
: Similar to '''attack''', but is triggered ''after'' the fight instead of before. Note that if either unit is killed during the fight, this event triggers before any '''die''' events.<br />
<br />
; attacker hits<br />
: Triggers when the the primary unit (the attacker) hits the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the attacker.<br />
<br />
; attacker misses<br />
: Same as ''attacker hits'', but is triggered when the attacker misses.<br />
<br />
; defender hits<br />
: Triggers when the primary unit (the attacker) is hit in retaliation by the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the defender.<br />
<br />
; defender misses<br />
: Same as ''defender hits'', but is triggered when the defender misses.<br />
<br />
; stone<br />
: Triggers when the primary unit is hit by an attack with the 'stones' ability (See ''stones'', [[AbilitiesWML]]) by the secondary unit (the unit with the 'stones' ability). In {{DevFeature}}, this event name is changed to "petrified".<br />
<br />
; last breath<br />
: Triggers when the primary unit is killed by the secondary unit, but before the death animation is triggered. Use this instead of name=die when you want the primary unit to make a final [message]. <br />
<br />
; die<br />
: Triggers when the primary unit is killed by the secondary unit. ''Note: The primary unit is not removed from the game until the end of this event. The primary unit can still be manipulated, will block other units from taking its hex, and will still be found by standard unit filters (except [have_unit]). To prevent this behavior, you can use [kill] to remove the unit immediately. However, this will stop any (still unfired) other events that also match the unit from firing afterwards, so use with caution.'' If you want to the primary unit to make a final [message], use name=last_breath, see above.<br />
<br />
; capture<br />
: Triggers when the primary unit captures a village. The village may have been previously neutral, or previously owned by another side; merely moving into your own villages does not constitute a capture.<br />
<br />
; recruit<br />
: Triggers when the primary unit is recruited. (That is, when a unit is recruited it will trigger this event and this event's filter will filter that unit.).<br />
<br />
; prerecruit<br />
: Triggers when the primary unit is recruited but before it is displayed.<br />
<br />
; recall<br />
: Triggers after a unit is recalled.<br />
<br />
; prerecall<br />
: Triggers when a unit is recalled but before it is displayed.<br />
<br />
; advance<br />
: Triggers just before the primary unit is going to advance to another unit.<br />
<br />
; post advance<br />
: Triggers just after the primary unit has advanced to another unit.<br />
<br />
; select<br />
: Triggers when the primary unit is selected. Also triggers when ending a move, as the game keeps the moving unit selected by selecting it again at the end of movement. ''Note: in networked multiplayer, these events are only executed by the client on which the event is triggered, leading to out of sync errors if you modify the game state in the event.''<br />
<br />
; menu item ''X''<br />
: Triggers when a WML menu item with id=''X'' is selected. ''Note: if the menu item has a [command], this event may be executed before or after the command; there is no guarantee.''<br />
<br />
==== Custom events ====<br />
<br />
An event with a custom name may be invoked using the [[InternalActionsWML#.5Bfire_event.5D|[fire_event]]] tag. Normally you'll use such custom events as named subroutines to be called by events with predefined types. One common case of this, for example, is that more than one '''sighted''' events might fire the same custom event that changes the scenario objectives.<br />
<br />
=== Optional Keys and Tags ===<br />
<br />
These keys and tags are more complex ways to filter when an event should trigger:<br />
<br />
==== first_time_only ====<br />
: Whether the event should be removed from the scenario after it is triggered. This key takes a [[ConditionalActionsWML#Boolean_Values|boolean]]; for example:<br />
: ''first_time_only=yes''<br />
:: Default behavior if key is omitted. The event will trigger the first time it can and never again.<br />
: ''first_time_only=no''<br />
:: The event will trigger every time the criteria are met instead of only the first time.<br />
<br />
==== [filter] ====<br />
: The event will only trigger if the primary unit matches this filter.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_second] ====<br />
: Like [filter], but for the secondary unit.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_attack] ====<br />
: Can be used to set additional filtering criteria for the primary unit and the secondary unit that are not generally available in a standard unit filter. Can be used in events ''attack'', ''attacker hits'', ''attacker misses'', ''defender hits'', ''defender misses'' and ''attack end''. For more information and other filter keys, see [[FilterWML]].<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_second_attack] ====<br />
: Like [filter_attack], but for the secondary unit.<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_condition] ====<br />
: {{DevFeature1.9}}<br />
: This tag makes sense inside any sort of event - even those that don't have units, or custom events,... The event will only trigger if this condition evaluates to true.<br />
:* True Condition Tags and Meta Condition Tags as described in [[ConditionalActionsWML]].<br />
: note: This tag is meant to be used when the firing of an event shall be based on variables/conditions which cannot be retrieved from the filtered units.<br />
<br />
==== delayed_variable_substitution ====<br />
: This key is only relevant inside of a [[#Delayed Variable Substitution|nested event]] and controls when variable substitution will occur in those special case actions.<br />
<br />
=== Actions triggered by [event] ===<br />
<br />
After the trigger conditions have been met, all [[ActionWML|action tags]] within the [event] tag are executed in the order they are written in.<br />
<br />
There are 3 main types of actions:<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
<br />
More details in [[ActionWML]].<br />
<br />
Several actions use standard filters to find out which units<br />
to execute the command on. These are denoted by the phrases<br />
"standard unit filter" and "standard location filter".<br />
<br />
=== Nested Events ===<br />
<br />
There is one special type of action: event creation. By placing an '''[event]''' tag inside another '''[event]''' tag, the nested event is spawned (created) when the parent (outer) event is encountered (when executing the contents of the parent event).<br />
<br />
([[#Nested Event Example|See Examples]])<br />
<br />
==== Delayed Variable Substitution ====<br />
<br />
Variable substitution for a nested event can happen either when it is spawned by the parent event or when it is triggered itself. This is controlled with the key '''delayed_variable_substitution''' which is used in the nested event.<br />
<br />
If this key is set to ''yes'', the variables in the nested event will contain values from the turn in which the ''nested'' event was triggered. ''This is the default behavior if the key is omitted.'' If set to ''no'', the variables in the nested event are set at the time the ''parent'' event is triggered.<br />
<br />
This behavior can be fine tuned with a special syntax when referencing variables. Instead of the normal '''$variable''' syntax, use '''$|variable''' to cause a variable to contain values relevant to the turn in which the nested event was triggered even when '''delayed_variable_substitution''' is set to ''no''. In this way you can have a mix of variables relevant to the parent and nested event trigger times.<br />
<br />
([[#Delayed Variable Substitution Example|See Examples]])<br />
<br />
== Multiplayer safety ==<br />
<br />
In multiplayer it is only safe to use WML that might require synchronization with other players because of input or random numbers (like [message] with input or options or [unstore_unit] where a unit might advance) in the following events. This is because in these cases WML needs data from other players to work right and/or do the same thing for all players. This data is only available after a network synchronization.<br />
<br />
List of synchronized events:<br />
* moveto<br />
* sighted <br />
* attack<br />
* attack_end <br />
* attacker hits <br />
* attacker misses <br />
* defender hits<br />
* defender misses <br />
* stone<br />
* last breath <br />
* menu item X<br />
* die<br />
* capture <br />
* recruit<br />
* prerecruit <br />
* recall <br />
* prerecall <br />
* advance <br />
* post_advance <br />
getting message options (etc) from the following events is not synchronized, except in the development version (1.9+svn):<br />
* new turn <br />
* side turn <br />
* turn X <br />
* side X turn <br />
* side X turn Y <br />
* turn refresh <br />
<br />
There is also the possibility of events that are normally synchronized when fired by the engine but can be non-synchronized when fired by WML tags from non-synchronized event. So when you are using them you must be extra careful. For example [unstore_unit] may trigger a unit advancement that will fire ''advance'' and ''post advance'' events.<br />
<br />
== A Trap for the Unwary ==<br />
<br />
You need to beware of using macros to generate events. If you include a macro expanding to an event definition twice, the event will be executed twice (not once) each time the trigger condition fires. Consider this code:<br />
<br />
#define DOUBLE<br />
[event]<br />
name=multiply_by_2<br />
{VARIABLE_OP 2_becomes_4 multiply 2}<br />
[/event]<br />
#enddef<br />
<br />
{DOUBLE}<br />
{DOUBLE}<br />
<br />
{VARIABLE 2_becomes_4 2}<br />
<br />
[fire_event]<br />
name=multiply_by_2<br />
[/fire_event]<br />
<br />
{DEBUG_MSG "$2_becomes_4 should be 4"}<br />
<br />
After it executes, the debug message will reveal that the variable has been set to 8, not 4.<br />
<br />
== Miscellaneous Notes and Examples ==<br />
<br />
=== Primary/Secondary Unit Speaker Example ===<br />
<br />
In events, the primary unit can be referred to as '''unit''' and the secondary unit can be referred to as '''second_unit''' in [message] tags using the '''speaker''' key. For example:<br />
<br />
[event]<br />
name=die<br />
[message]<br />
speaker='''second_unit'''<br />
message= _ "Hahaha! I finally killed you!"<br />
[/message]<br />
<br />
[message]<br />
speaker='''unit'''<br />
message= _ "It's not over yet! I'll come back to haunt you!"<br />
[/message]<br />
[/event]<br />
<br />
=== Nested Event Example ===<br />
<br />
An event is created for a portal that opens on turn 10. The parent (or 'outer') event executes on turn 10 at which point the nested moveto event is created. This nested event executes when a player steps on a certain spot.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
# moving to 5,8 will trigger this event only on turn 10 and after<br />
[/event]<br />
[/event]<br />
<br />
An equivalent way of doing this would be to create a single moveto event with an '''[if]''' statement to check for turn number but using nested '''[event]''' tags is a convenient shortcut to accomplish this task without resorting to '''[if]''' statements.<br />
<br />
=== Delayed Variable Substitution Example ===<br />
<br />
This code will display a message showing the turn number on which the nested ''moveto'' event happens.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=yes<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
Since this is the default behavior for the '''delayed_variable_substitution''' key, the following example is identical.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
The following code will always display "Turn 10" when the nested ''moveto'' event happens. This is because the variable substitution is done when the parent event is triggered and spawns the nested event, ''not'' when the nested event is triggered.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
Finally, the following example is identical to the first two in that it will display a message showing the turn number on which the nested ''moveto'' event happens, despite the fact that the '''delayed_variable_substitution''' key is set to ''no''. This is because the special '''$|variable''' syntax is used.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $|turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
=== Multiple Nested Events ===<br />
<br />
Every delayed_variable_substitution=no causes a variable substitution run on the subevent where it occurs at the spawn time of this event and on all following subevents. For any specific event, variable substitution happens at least one time when the event is executed. For each delayed=no key appearing in itself or in an event of an "older" generation, which is not the toplevel event, an additional variable substitution run is made.<br />
[event]# parent<br />
name=turn 2<br />
#delayed_variable_substitution=no # In the parent event, delayed= has no effect.<br />
<br />
[event]# child<br />
name=turn 3<br />
delayed_variable_substitution=no # Causes variable substitution in the child, grandchild and great-grandchild event<br />
# at execution time of the parent event = spawn time of the child event.<br />
<br />
[event]# grandchild<br />
name=turn 4<br />
delayed_variable_substitution=yes # no variable substitution in the grandchild and great-grandchild event<br />
# at execution time of the child event = spawn time of the grandchild event<br />
<br />
[event]# great-grandchild<br />
name=turn 5<br />
{DEBUG_MSG $turn_number}# output: 2 - value from the variable substitution at execution time of the parent event,<br />
# caused by delayed=no in the child event<br />
<br />
{DEBUG_MSG $||turn_number}# output: "$turn_number"<br />
# Each variable substitution transforms a "$|" to a "$" (except when no | left).<br />
<br />
{DEBUG_MSG $|turn_number}# output: 5 - from the variable substitution at execution time<br />
# of the great-grandchild event<br />
[/event]<br />
[/event]<br />
[/event]<br />
[/event]<br />
<br />
== See Also ==<br />
<br />
* [[DirectActionsWML]]<br />
* [[InternalActionsWML]]<br />
* [[InterfaceActionsWML]]<br />
* [[FilterWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=EventWML&diff=40011EventWML2011-01-10T19:33:50Z<p>Paŭlo: /* Actions triggered by [event] */ link to ActionWML</p>
<hr />
<div>{{WML Tags}}<br />
== The [event] Tag ==<br />
<br />
This tag is a subtag of the [scenario], [unit_type] and [era] tags which is used to describe a set of actions which trigger at a certain point in a scenario. When used in a [scenario] tag (also includes [multiplayer], [tutorial] and [test]), the event only occurs in that scenario. When used in a [unit_type] tag, the event will occur in all scenarios in which a unit of that type appears in (only after such a unit appears during the scenario, however). When used in an [era], the event will occur in any scenario which is played using that era.<br />
<br />
This tag has keys and child tags that control when and if the event actions will be triggered. Most important of these is the '''name''' key. Without it, no error will be raised but the event will never fire. Therefore, from a practical standpoint, it can be considered mandatory. All of the others can be used or not and the event actions will fire either way.<br />
<br />
'''Lexicon side note:''' ''The word "event" in the [event] tag itself may be considered an abbreviation of the word "event handler" because it is technically not a game "event" but an event '''handler''' for the game events fired with the given 'name'. However, this distinction is usually unimportant in most discussions and the event handlers are therefore simply referred to as "events" in this documentation.''<br />
<br />
=== The 'name' Key (Mandatory) ===<br />
<br />
Usage:<br />
name=<value><br />
<br />
This key defines which game event or trigger your [event] tag will be handling. This 'name' key should not be confused with a descriptive comment; it is rather a precise value which must match the predefined game event's name to be valid.<br />
<br />
'''Lexicon side note:''' ''It is not uncommon to refer to these values as the 'trigger' for an event and, furthermore, to call an event by its 'trigger' name. For example, in an event containing '''name=moveto''', a person might refer to the event as a ''''moveto''' event' and/or refer to the ''''moveto''' trigger' in the event or even talk about the 'event trigger' when referring to the '''moveto''' value of the 'name' key in that event. Some or all of this usage can, in fact, be found throughout this page.''<br />
<br />
The '''name''' key can accept a list of comma separated values describing when the event will be triggered.* These values may be either predefined event types or custom event names not matching any predefined type.<br />
<br />
For example:<br />
<br />
name=attacker misses,defender misses<br />
<br />
''* Note that unless you use [[#first_time_only|first_time_only=no]], the event will fire only once, '''not''' once for each listed type.''<br />
<br />
==== Predefined 'name' Key Values ====<br />
<br />
All predefined event types are listed here along with a description of when this value will cause the event to be triggered. Any value ''not'' listed here is a custom event name which can be triggered only by a '''[fire_event]''' tag somewhere else. Spaces in event names can be interchanged with underscores (for example, '''name=new turn''' and '''name=new_turn''' are equivalent).<br />
<br />
; preload<br />
: Triggers before a scenario 'prestarts' and when loading a savegame -- before anything is shown on the screen at all. Can be used to set up the [[LuaWML|Lua]] environment: loading libraries, defining helper functions, etc.<br />
: '''Note:''' Unlike prestart and start, the preload event '''must be able to fire more than once!''' This is because it is triggered each time a savegame is loaded in addition to the initial time when it loads before the scenario 'prestart'. This means that it is effectively ''mandatory'' to have the [[#first_time_only|first_time_only=no]] key value in a preload event. <br />
<br />
; prestart<br />
: Triggers before a scenario 'starts' -- before anything is shown on the screen at all. Can be used to set up things like village ownership. For things displayed on-screen such as character dialog, use '''start''' instead.<br />
: '''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
; start<br />
: Triggers after the map is shown but before the scenario begins -- before players can 'do' anything.<br />
: '''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
; new turn<br />
: Triggers at the start of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. Before any events of this type trigger, the value of the WML variable '''turn_number''' is set to the number of the turn that is beginning.<br />
<br />
; turn end {{DevFeature1.9}}<br />
: Triggers at the end of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. The WML variable '''side_number''' will contain the side that ended their turn.<br />
<br />
; turn ''X'' end {{DevFeature1.9}}<br />
: Triggers at the end of turn ''X''.<br />
<br />
; side turn<br />
: Triggers when a side is about to start its turn. Before events of this type trigger, the value of the WML variable '''side_number''' is set to the number of the side of the player about to take their turn. This is before any healing takes place for that side, before calculating income, and before restoring unit movement and status.<br />
<br />
; ai turn<br />
: Triggered just before the AI is invoked for a side. This is called after ''side turn'', and thus the WML variable '''side_number''' still holds the number of this side. Note that this event might be called several times per turn in case that fallbacks to human or droiding is involved. I.e. it happens at the middle of turn of human side 1 if the human player droids his side. It happens after the selection of ai to play the turn but before AI is told that new turn has come.<br />
: '''Note:''' ''This event currently breaks replays since it is not explicitly saved in a replay and there is no AI involved in replays...''<br />
<br />
; turn refresh<br />
: Like '''side turn''', triggers just before a side is taking control but '''after''' healing, calculating income, and restoring unit movement and status.<br />
<br />
; turn ''X''<br />
: Triggers at the start of turn ''X''. It's the first side initialization event. <br />
:Side initialization events go in the order of: <br />
: 1) '''turn ''X''''' <br />
:2) '''new turn''' <br />
:3) '''side turn''' <br />
:4) '''side ''X'' turn''' <br />
:5) '''side turn ''X''''' <br />
:6) '''side ''X'' turn ''Y''''' <br />
:7) '''turn refresh''' <br />
:8) '''side ''X'' turn refresh''' <br />
:9) '''turn ''X'' refresh''' <br />
:10) '''side ''X'' turn ''Y'' refresh'''<br />
<br />
; side ''X'' turn ''Y''<br />
: This event triggers at the start of turn ''Y'' of side X {{DevFeature}}<br />
<br />
; side ''X'' turn<br />
: This event triggers at the start of any turn of side X {{DevFeature}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side turn ''X''<br />
: This event triggers at the start of any side on turn X {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side X turn Y refresh<br />
: This event triggers at the turn refresh for side X on turn Y {{DevFeature1.9}}<br />
<br />
; side ''X'' turn refresh<br />
: This event triggers at the turn refresh for side X {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; turn ''X'' refresh<br />
: This event triggers for any side at the refresh of turn X. {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side turn end {{DevFeature1.9}}<br />
: Triggers after a side ends its turn. Like side turn, there are also some variations for specific combinations of side number and turn number. Here is the order in which the turn end events trigger:<br />
:1) '''side turn end''' <br />
:2) '''side ''X'' turn end''' <br />
:3) '''side turn ''X'' end''' <br />
:4) '''side ''X'' turn ''Y'' end''' <br />
:5) '''turn end''' <br />
:6) '''turn ''X'' end''' <br />
<br />
; time over<br />
: Triggers on turn ''turns''. (''turns'' is specified in [scenario])<br />
<br />
; enemies defeated<br />
: Triggers when all units with '''canrecruit=yes''' (that is, all leaders) not allied with side 1 are killed.<br />
<br />
; victory<br />
: In this scenario, any tag of the form '''[endlevel] result=victory [/endlevel]''' will be automatically preceded by all actions in this tag. It helps debugging if the victory event allows you to safely advance to any of the possible next maps after using the ":n" command. Scenarios where key units are picked up before the victory, or where some action chosen earlier determines which map to advance to, make it hard to quickly test scenarios in a campaign. (See also: [endlevel], [[DirectActionsWML]])<br />
<br />
; defeat<br />
: In this scenario, any tag of the form '''[endlevel] result=defeat [/endlevel]''' will be automatically preceded by all actions in this tag. (See also [endlevel], [[DirectActionsWML]])<br />
<br />
<br />
Filters (except [filter_condition] which is for all sorts of events) can be applied to the following event triggers (see [[FilterWML]]; see also below). The actions specified in the event tag will be executed only if the filter returns true. <br />
These event triggers are all actions by units ('''moveto''', '''attack''') or things that happen to units ('''recruit''', '''advance'''). When one of these events is triggered, the position of the active unit (referred to as the '''primary unit''') is stored in the variables '''x1''' and '''y1''' and the position of any unit that primary unit does something to is stored in the variables '''x2''' and '''y2''' (this unit is referred to as the '''secondary unit''' below). '' These units are also automatically stored in the variables 'unit' and 'second_unit' as if they had been stored using the '''[store_unit]''' tag. see [[SingleUnitWML]]<br />
<br />
; moveto<br />
: Triggers after the primary unit moves. Typically this is used when the primary unit gets to a particular location and a filter for the location of the primary unit is included; remember that this is the location that the primary unit lands on, not the location it started on or any location it travels on.<br />''An '''[allow_undo]''' tag anywhere within a moveto event will cancel any lack of undo functionality the event would have caused. Note that undo functionality will only move the unit back to its former location; it will not undo other changes to the game caused by the event. Thus it is up to the scenario designer to use this tag correctly.'' {{DevFeature}} $x2 and $y2 refer to the hex the unit came from.<br />
<br />
; sighted<br />
: '''important: "sighted" events are very buggy in general, especially if "delay shroud updates" is set to "yes". Avoid using them despite of them being (still) used a lot in mainline.''' {{DevFeature1.9}}: It is currently tested whether the introduction of the "whiteboard" feature is accepted, making it possible to remove the "delay shroud updates" option which could in return make this event stable again.<br />
: A '''sighted''' event is triggered when a fog or shroud is lifted from the primary ''unit''. This can happen when a ''second_unit'' moves to a nearby location and discovers the primary ''unit''. Alternatively, the ''second_unit'' might emerge "out of the mist" and be discovered simultaneously by all members of the enemy side: in this case, the ''second_unit'' is not set. (This is part of the sighted event's bugs.)<br />
<br />
: '''Note:''' The sighted event is ''only'' triggered when a unit moves from one location to another. When the player moves to attack an enemy unit and, in the process, removes the fog/shroud over an enemy unit, the sighted event does ''not'' fire. This makes the sighted event unreliable: It may or may not fire, depending on the user actions. (This may be part of the sighted event's bugs.)<br />
<br />
: '''Alternatives:''' It is sometimes possible to replace a sighted event by a moveto event with a [[StandardLocationFilter|location filter]] matching a nearby location. A [[FilterWML#Filtering_Vision|filter_vision]] filter may be useful in some cases.<br />
<br />
; attack<br />
: Triggers when the primary unit attacks the secondary unit.<br />
<br />
; attack end<br />
: Similar to '''attack''', but is triggered ''after'' the fight instead of before. Note that if either unit is killed during the fight, this event triggers before any '''die''' events.<br />
<br />
; attacker hits<br />
: Triggers when the the primary unit (the attacker) hits the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the attacker.<br />
<br />
; attacker misses<br />
: Same as ''attacker hits'', but is triggered when the attacker misses.<br />
<br />
; defender hits<br />
: Triggers when the primary unit (the attacker) is hit in retaliation by the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the defender.<br />
<br />
; defender misses<br />
: Same as ''defender hits'', but is triggered when the defender misses.<br />
<br />
; stone<br />
: Triggers when the primary unit is hit by an attack with the 'stones' ability (See ''stones'', [[AbilitiesWML]]) by the secondary unit (the unit with the 'stones' ability). In {{DevFeature}}, this event name is changed to "petrified".<br />
<br />
; last breath<br />
: Triggers when the primary unit is killed by the secondary unit, but before the death animation is triggered. Use this instead of name=die when you want the primary unit to make a final [message]. <br />
<br />
; die<br />
: Triggers when the primary unit is killed by the secondary unit. ''Note: The primary unit is not removed from the game until the end of this event. The primary unit can still be manipulated, will block other units from taking its hex, and will still be found by standard unit filters (except [have_unit]). To prevent this behavior, you can use [kill] to remove the unit immediately. However, this will stop any (still unfired) other events that also match the unit from firing afterwards, so use with caution.'' If you want to the primary unit to make a final [message], use name=last_breath, see above.<br />
<br />
; capture<br />
: Triggers when the primary unit captures a village. The village may have been previously neutral, or previously owned by another side; merely moving into your own villages does not constitute a capture.<br />
<br />
; recruit<br />
: Triggers when the primary unit is recruited. (That is, when a unit is recruited it will trigger this event and this event's filter will filter that unit.).<br />
<br />
; prerecruit<br />
: Triggers when the primary unit is recruited but before it is displayed.<br />
<br />
; recall<br />
: Triggers after a unit is recalled.<br />
<br />
; prerecall<br />
: Triggers when a unit is recalled but before it is displayed.<br />
<br />
; advance<br />
: Triggers just before the primary unit is going to advance to another unit.<br />
<br />
; post advance<br />
: Triggers just after the primary unit has advanced to another unit.<br />
<br />
; select<br />
: Triggers when the primary unit is selected. Also triggers when ending a move, as the game keeps the moving unit selected by selecting it again at the end of movement. ''Note: in networked multiplayer, these events are only executed by the client on which the event is triggered, leading to out of sync errors if you modify the game state in the event.''<br />
<br />
; menu item ''X''<br />
: Triggers when a WML menu item with id=''X'' is selected. ''Note: if the menu item has a [command], this event may be executed before or after the command; there is no guarantee.''<br />
<br />
==== Custom events ====<br />
<br />
An event with a custom name may be invoked using the [[InternalActionsWML#.5Bfire_event.5D|[fire_event]]] tag. Normally you'll use such custom events as named subroutines to be called by events with predefined types. One common case of this, for example, is that more than one '''sighted''' events might fire the same custom event that changes the scenario objectives.<br />
<br />
=== Optional Keys and Tags ===<br />
<br />
These keys and tags are more complex ways to filter when an event should trigger:<br />
<br />
==== first_time_only ====<br />
: Whether the event should be removed from the scenario after it is triggered. This key takes a [[ConditionalActionsWML#Boolean_Values|boolean]]; for example:<br />
: ''first_time_only=yes''<br />
:: Default behavior if key is omitted. The event will trigger the first time it can and never again.<br />
: ''first_time_only=no''<br />
:: The event will trigger every time the criteria are met instead of only the first time.<br />
<br />
==== [filter] ====<br />
: The event will only trigger if the primary unit matches this filter.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_second] ====<br />
: Like [filter], but for the secondary unit.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_attack] ====<br />
: Can be used to set additional filtering criteria for the primary unit and the secondary unit that are not generally available in a standard unit filter. Can be used in events ''attack'', ''attacker hits'', ''attacker misses'', ''defender hits'', ''defender misses'' and ''attack end''. For more information and other filter keys, see [[FilterWML]].<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_second_attack] ====<br />
: Like [filter_attack], but for the secondary unit.<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_condition] ====<br />
: {{DevFeature1.9}}<br />
: This tag makes sense inside any sort of event - even those that don't have units, or custom events,... The event will only trigger if this condition evaluates to true.<br />
:* True Condition Tags and Meta Condition Tags as described in [[ConditionalActionsWML]].<br />
: note: This tag is meant to be used when the firing of an event shall be based on variables/conditions which cannot be retrieved from the filtered units.<br />
<br />
==== delayed_variable_substitution ====<br />
: This key is only relevant inside of a [[#Delayed Variable Substitution|nested event]] and controls when variable substitution will occur in those special case actions.<br />
<br />
=== Actions triggered by [event] ===<br />
<br />
After the trigger conditions have been met, all [[ActionWML|action tags]] within the [event] tag are executed in the order they are written in.<br />
<br />
There are 3 main types of actions:<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
<br />
More details in [[ActionWML]].<br />
<br />
Several actions use standard filters to find out which units<br />
to execute the command on. These are denoted by the phrases<br />
"standard unit filter" and "standard location filter".<br />
<br />
=== Nested Events ===<br />
<br />
There is one special type of action: event creation. By placing an '''[event]''' tag inside another '''[event]''' tag, the nested event is spawned (created) when the parent (outer) event is encountered (when executing the contents of the parent event).<br />
<br />
([[#Nested Event Example|See Examples]])<br />
<br />
==== Delayed Variable Substitution ====<br />
<br />
Variable substitution for a nested event can happen either when it is spawned by the parent event or when it is triggered itself. This is controlled with the key '''delayed_variable_substitution''' which is used in the nested event.<br />
<br />
If this key is set to ''yes'', the variables in the nested event will contain values from the turn in which the ''nested'' event was triggered. ''This is the default behavior if the key is omitted.'' If set to ''no'', the variables in the nested event are set at the time the ''parent'' event is triggered.<br />
<br />
This behavior can be fine tuned with a special syntax when referencing variables. Instead of the normal '''$variable''' syntax, use '''$|variable''' to cause a variable to contain values relevant to the turn in which the nested event was triggered even when '''delayed_variable_substitution''' is set to ''no''. In this way you can have a mix of variables relevant to the parent and nested event trigger times.<br />
<br />
([[#Delayed Variable Substitution Example|See Examples]])<br />
<br />
== Multiplayer safety ==<br />
<br />
In multiplayer it is only safe to use WML that might require synchronization with other players because of input or random numbers (like [message] with input or options or [unstore_unit] where a unit might advance) in the following events. This is because in these cases WML needs data from other players to work right and/or do the same thing for all players. This data is only available after a network synchronization.<br />
<br />
List of synchronized events:<br />
* moveto<br />
* sighted <br />
* attack<br />
* attack_end <br />
* attacker hits <br />
* attacker misses <br />
* defender hits<br />
* defender misses <br />
* stone<br />
* last breath <br />
* menu item X<br />
* die<br />
* capture <br />
* recruit<br />
* prerecruit <br />
* recall <br />
* prerecall <br />
* advance <br />
* post_advance <br />
getting message options (etc) from the following events is not synchronized, except in the development version (1.9+svn):<br />
* new turn <br />
* side turn <br />
* turn X <br />
* side X turn <br />
* side X turn Y <br />
* turn refresh <br />
<br />
There is also the possibility of events that are normally synchronized when fired by the engine but can be non-synchronized when fired by WML tags from non-synchronized event. So when you are using them you must be extra careful. For example [unstore_unit] may trigger a unit advancement that will fire ''advance'' and ''post advance'' events.<br />
<br />
== A Trap for the Unwary ==<br />
<br />
You need to beware of using macros to generate events. If you include a macro expanding to an event definition twice, the event will be executed twice (not once) each time the trigger condition fires. Consider this code:<br />
<br />
#define DOUBLE<br />
[event]<br />
name=multiply_by_2<br />
{VARIABLE_OP 2_becomes_4 multiply 2}<br />
[/event]<br />
#enddef<br />
<br />
{DOUBLE}<br />
{DOUBLE}<br />
<br />
{VARIABLE 2_becomes_4 2}<br />
<br />
[fire_event]<br />
name=multiply_by_2<br />
[/fire_event]<br />
<br />
{DEBUG_MSG "$2_becomes_4 should be 4"}<br />
<br />
After it executes, the debug message will reveal that the variable has been set to 8, not 4.<br />
<br />
== Miscellaneous Notes and Examples ==<br />
<br />
=== Primary/Secondary Unit Speaker Example ===<br />
<br />
In events, the primary unit can be referred to as '''unit''' and the secondary unit can be referred to as '''second_unit''' in [message] tags using the '''speaker''' key. For example:<br />
<br />
[event]<br />
name=die<br />
[message]<br />
speaker='''second_unit'''<br />
message= _ "Hahaha! I finally killed you!"<br />
[/message]<br />
<br />
[message]<br />
speaker='''unit'''<br />
message= _ "It's not over yet! I'll come back to haunt you!"<br />
[/message]<br />
[/event]<br />
<br />
=== Nested Event Example ===<br />
<br />
An event is created for a portal that opens on turn 10. The parent (or 'outer') event executes on turn 10 at which point the nested moveto event is created. This nested event executes when a player steps on a certain spot.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
# moving to 5,8 will trigger this event only on turn 10 and after<br />
[/event]<br />
[/event]<br />
<br />
An equivalent way of doing this would be to create a single moveto event with an '''[if]''' statement to check for turn number but using nested '''[event]''' tags is a convenient shortcut to accomplish this task without resorting to '''[if]''' statements.<br />
<br />
=== Delayed Variable Substitution Example ===<br />
<br />
This code will display a message showing the turn number on which the nested ''moveto'' event happens.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=yes<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
Since this is the default behavior for the '''delayed_variable_substitution''' key, the following example is identical.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
The following code will always display "Turn 10" when the nested ''moveto'' event happens. This is because the variable substitution is done when the parent event is triggered and spawns the nested event, ''not'' when the nested event is triggered.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
Finally, the following example is identical to the first two in that it will display a message showing the turn number on which the nested ''moveto'' event happens, despite the fact that the '''delayed_variable_substitution''' key is set to ''no''. This is because the special '''$|variable''' syntax is used.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $|turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
=== Multiple Nested Events ===<br />
<br />
Every delayed_variable_substitution=no causes a variable substitution run on the subevent where it occurs at the spawn time of this event and on all following subevents. For any specific event, variable substitution happens at least one time when the event is executed. For each delayed=no key appearing in itself or in an event of an "older" generation, which is not the toplevel event, an additional variable substitution run is made.<br />
[event]# parent<br />
name=turn 2<br />
#delayed_variable_substitution=no # In the parent event, delayed= has no effect.<br />
<br />
[event]# child<br />
name=turn 3<br />
delayed_variable_substitution=no # Causes variable substitution in the child, grandchild and great-grandchild event<br />
# at execution time of the parent event = spawn time of the child event.<br />
<br />
[event]# grandchild<br />
name=turn 4<br />
delayed_variable_substitution=yes # no variable substitution in the grandchild and great-grandchild event<br />
# at execution time of the child event = spawn time of the grandchild event<br />
<br />
[event]# great-grandchild<br />
name=turn 5<br />
{DEBUG_MSG $turn_number}# output: 2 - value from the variable substitution at execution time of the parent event,<br />
# caused by delayed=no in the child event<br />
<br />
{DEBUG_MSG $||turn_number}# output: "$turn_number"<br />
# Each variable substitution transforms a "$|" to a "$" (except when no | left).<br />
<br />
{DEBUG_MSG $|turn_number}# output: 5 - from the variable substitution at execution time<br />
# of the great-grandchild event<br />
[/event]<br />
[/event]<br />
[/event]<br />
[/event]<br />
<br />
== See Also ==<br />
<br />
* [[DirectActionsWML]]<br />
* [[InternalActionsWML]]<br />
* [[InterfaceActionsWML]]<br />
* [[FilterWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ActionWML&diff=40010ActionWML2011-01-10T19:31:46Z<p>Paŭlo: formatting, some additions.</p>
<hr />
<div>'''ActionWML''' is a summarizing term for all '''WML actions''' which can be used in events and some other places.<br />
<br />
== Types of ActionWML ==<br />
<br />
When a tag permits ActionWML, this means that it permits all of the following:<br />
<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
* conditional actions ([[ConditionalActionsWML]]) which contain other actions, which then are (maybe) executed ([if], [switch], [while], [command])<br />
* [event] (see [[EventWML#Nested Events|EventWML]]) which creates a new event handler<br />
** note: [event] can also be a subtag of [unit], [era] and [scenario], where it would not be counted as ActionWML (but has the same syntax).<br />
* [lua] ([[LuaWML]]) which contains Lua code to be executed, and<br />
* all tags created from lua with [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] (if they don't fit in one of the categories above)<br />
<br />
<br />
== Where ActionWML can be used ==<br />
<br />
ActionWML can be used<br />
* inside an [event], to define a event handler (see [[EventWML]]),<br />
* inside a [then] or [else] of an [if] tag (see [[ConditionalActionsWML]]),<br />
* inside a [case] or [else} of a [switch] tag (see [[ConditionalActionsWML]]),<br />
* inside the [do] of a [while] tag (see [[ConditionalActionsWML]]),<br />
* inside a [command] tag (in [option] or [set_menu_item] or directly as ActionWML) (see [[InterfaceActionsWML]]),<br />
* in certain Lua-created tags (if the registered WML action handler interprets the content as ActionWML).<br />
<br />
<br />
On most other places ActionWML code will either be ignored, give error messages or interpreted differently (there are some tags which are ActionWML and have other meanings in other places, like [event] or [variable]).</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ActionWML&diff=40009ActionWML2011-01-10T19:23:32Z<p>Paŭlo: new page: ActionWML (to bundle information from other places).</p>
<hr />
<div>'''ActionWML''' is a summarizing term for all '''WML actions''' which can be used in events and some other places.<br />
<br />
== Types of ActionWML ==<br />
<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
<br />
<br />
* conditional actions ([[ConditionalActionsWML]]) which contain other actions, which then are executed on certain conditions<br />
* [event] (see [[EventWML#Nested Events|EventWML]]) which creates a new event handler<br />
* [lua] ([[LuaWML]]) which contains Lua code to be executed, and<br />
* all tags created from lua with [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] (if they don't fit in one of the categories above)<br />
<br />
<br />
== Where ActionWML can be used ==<br />
<br />
ActionWML can be used<br />
* inside an [event], to define a event handler (see [[EventWML]])<br />
* inside a [then] or [else] of an [if] tag (see [[ConditionalActionsWML]]).<br />
* inside a [case] or [else} of a [switch] tag (see [[ConditionalActionsWML]]).<br />
* inside the [do] of a [while] tag (see [[ConditionalActionsWML]]).<br />
* inside a [command] tag (in [option] or [set_menu_item] or directly as ActionWML) (see [[InterfaceActionsWML]]).<br />
* in certain Lua-created tags (if the registered WML action handler interprets the content as ActionWML)</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=EventWML&diff=39953EventWML2011-01-05T22:43:11Z<p>Paŭlo: /* [event] */ - removed section</p>
<hr />
<div>{{WML Tags}}<br />
== The [event] Tag ==<br />
<br />
This tag is a subtag of the [scenario], [unit_type] and [era] tags which is used to describe a set of actions which trigger at a certain point in a scenario. When used in a [scenario] tag (also includes [multiplayer], [tutorial] and [test]), the event only occurs in that scenario. When used in a [unit_type] tag, the event will occur in all scenarios in which a unit of that type appears in (only after such a unit appears during the scenario, however). When used in an [era], the event will occur in any scenario which is played using that era.<br />
<br />
This tag has keys and child tags that control when and if the event actions will be triggered. Most important of these is the '''name''' key. Without it, no error will be raised but the event will never fire. Therefore, from a practical standpoint, it can be considered mandatory. All of the others can be used or not and the event actions will fire either way.<br />
<br />
'''Lexicon side note:''' ''The word "event" in the [event] tag itself may be considered an abbreviation of the word "event handler" because it is technically not a game "event" but an event '''handler''' for the game events fired with the given 'name'. However, this distinction is usually unimportant in most discussions and the event handlers are therefore simply referred to as "events" in this documentation.''<br />
<br />
=== The 'name' Key (Mandatory) ===<br />
<br />
Usage:<br />
name=<value><br />
<br />
This key defines which game event or trigger your [event] tag will be handling. This 'name' key should not be confused with a descriptive comment; it is rather a precise value which must match the predefined game event's name to be valid.<br />
<br />
'''Lexicon side note:''' ''It is not uncommon to refer to these values as the 'trigger' for an event and, furthermore, to call an event by its 'trigger' name. For example, in an event containing '''name=moveto''', a person might refer to the event as a ''''moveto''' event' and/or refer to the ''''moveto''' trigger' in the event or even talk about the 'event trigger' when referring to the '''moveto''' value of the 'name' key in that event. Some or all of this usage can, in fact, be found throughout this page.''<br />
<br />
The '''name''' key can accept a list of comma separated values describing when the event will be triggered.* These values may be either predefined event types or custom event names not matching any predefined type.<br />
<br />
For example:<br />
<br />
name=attacker misses,defender misses<br />
<br />
''* Note that unless you use [[#first_time_only|first_time_only=no]], the event will fire only once, '''not''' once for each listed type.''<br />
<br />
==== Predefined 'name' Key Values ====<br />
<br />
All predefined event types are listed here along with a description of when this value will cause the event to be triggered. Any value ''not'' listed here is a custom event name which can be triggered only by a '''[fire_event]''' tag somewhere else. Spaces in event names can be interchanged with underscores (for example, '''name=new turn''' and '''name=new_turn''' are equivalent).<br />
<br />
; preload<br />
: Triggers before a scenario 'prestarts' and when loading a savegame -- before anything is shown on the screen at all. Can be used to set up the [[LuaWML|Lua]] environment: loading libraries, defining helper functions, etc.<br />
: '''Note:''' Unlike prestart and start, the preload event '''must be able to fire more than once!''' This is because it is triggered each time a savegame is loaded in addition to the initial time when it loads before the scenario 'prestart'. This means that it is effectively ''mandatory'' to have the [[#first_time_only|first_time_only=no]] key value in a preload event. <br />
<br />
; prestart<br />
: Triggers before a scenario 'starts' -- before anything is shown on the screen at all. Can be used to set up things like village ownership. For things displayed on-screen such as character dialog, use '''start''' instead.<br />
: '''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
; start<br />
: Triggers after the map is shown but before the scenario begins -- before players can 'do' anything.<br />
: '''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
; new turn<br />
: Triggers at the start of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. Before any events of this type trigger, the value of the WML variable '''turn_number''' is set to the number of the turn that is beginning.<br />
<br />
; turn end {{DevFeature1.9}}<br />
: Triggers at the end of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. The WML variable '''side_number''' will contain the side that ended their turn.<br />
<br />
; turn ''X'' end {{DevFeature1.9}}<br />
: Triggers at the end of turn ''X''.<br />
<br />
; side turn<br />
: Triggers when a side is about to start its turn. Before events of this type trigger, the value of the WML variable '''side_number''' is set to the number of the side of the player about to take their turn. This is before any healing takes place for that side, before calculating income, and before restoring unit movement and status.<br />
<br />
; ai turn<br />
: Triggered just before the AI is invoked for a side. This is called after ''side turn'', and thus the WML variable '''side_number''' still holds the number of this side. Note that this event might be called several times per turn in case that fallbacks to human or droiding is involved. I.e. it happens at the middle of turn of human side 1 if the human player droids his side. It happens after the selection of ai to play the turn but before AI is told that new turn has come.<br />
: '''Note:''' ''This event currently breaks replays since it is not explicitly saved in a replay and there is no AI involved in replays...''<br />
<br />
; turn refresh<br />
: Like '''side turn''', triggers just before a side is taking control but '''after''' healing, calculating income, and restoring unit movement and status.<br />
<br />
; turn ''X''<br />
: Triggers at the start of turn ''X''. It's the first side initialization event. <br />
:Side initialization events go in the order of: <br />
: 1) '''turn ''X''''' <br />
:2) '''new turn''' <br />
:3) '''side turn''' <br />
:4) '''side ''X'' turn''' <br />
:5) '''side turn ''X''''' <br />
:6) '''side ''X'' turn ''Y''''' <br />
:7) '''turn refresh''' <br />
:8) '''side ''X'' turn refresh''' <br />
:9) '''turn ''X'' refresh''' <br />
:10) '''side ''X'' turn ''Y'' refresh'''<br />
<br />
; side ''X'' turn ''Y''<br />
: This event triggers at the start of turn ''Y'' of side X {{DevFeature}}<br />
<br />
; side ''X'' turn<br />
: This event triggers at the start of any turn of side X {{DevFeature}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side turn ''X''<br />
: This event triggers at the start of any side on turn X {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side X turn Y refresh<br />
: This event triggers at the turn refresh for side X on turn Y {{DevFeature1.9}}<br />
<br />
; side ''X'' turn refresh<br />
: This event triggers at the turn refresh for side X {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; turn ''X'' refresh<br />
: This event triggers for any side at the refresh of turn X. {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side turn end {{DevFeature1.9}}<br />
: Triggers after a side ends its turn. Like side turn, there are also some variations for specific combinations of side number and turn number. Here is the order in which the turn end events trigger:<br />
:1) '''side turn end''' <br />
:2) '''side ''X'' turn end''' <br />
:3) '''side turn ''X'' end''' <br />
:4) '''side ''X'' turn ''Y'' end''' <br />
:5) '''turn end''' <br />
:6) '''turn ''X'' end''' <br />
<br />
; time over<br />
: Triggers on turn ''turns''. (''turns'' is specified in [scenario])<br />
<br />
; enemies defeated<br />
: Triggers when all units with '''canrecruit=yes''' (that is, all leaders) not allied with side 1 are killed.<br />
<br />
; victory<br />
: In this scenario, any tag of the form '''[endlevel] result=victory [/endlevel]''' will be automatically preceded by all actions in this tag. It helps debugging if the victory event allows you to safely advance to any of the possible next maps after using the ":n" command. Scenarios where key units are picked up before the victory, or where some action chosen earlier determines which map to advance to, make it hard to quickly test scenarios in a campaign. (See also: [endlevel], [[DirectActionsWML]])<br />
<br />
; defeat<br />
: In this scenario, any tag of the form '''[endlevel] result=defeat [/endlevel]''' will be automatically preceded by all actions in this tag. (See also [endlevel], [[DirectActionsWML]])<br />
<br />
<br />
Filters (except [filter_condition] which is for all sorts of events) can be applied to the following event triggers (see [[FilterWML]]; see also below). The actions specified in the event tag will be executed only if the filter returns true. <br />
These event triggers are all actions by units ('''moveto''', '''attack''') or things that happen to units ('''recruit''', '''advance'''). When one of these events is triggered, the position of the active unit (referred to as the '''primary unit''') is stored in the variables '''x1''' and '''y1''' and the position of any unit that primary unit does something to is stored in the variables '''x2''' and '''y2''' (this unit is referred to as the '''secondary unit''' below). '' These units are also automatically stored in the variables 'unit' and 'second_unit' as if they had been stored using the '''[store_unit]''' tag. see [[SingleUnitWML]]<br />
<br />
; moveto<br />
: Triggers after the primary unit moves. Typically this is used when the primary unit gets to a particular location and a filter for the location of the primary unit is included; remember that this is the location that the primary unit lands on, not the location it started on or any location it travels on.<br />''An '''[allow_undo]''' tag anywhere within a moveto event will cancel any lack of undo functionality the event would have caused. Note that undo functionality will only move the unit back to its former location; it will not undo other changes to the game caused by the event. Thus it is up to the scenario designer to use this tag correctly.'' {{DevFeature}} $x2 and $y2 refer to the hex the unit came from.<br />
<br />
; sighted<br />
: '''important: "sighted" events are very buggy in general, especially if "delay shroud updates" is set to "yes". Avoid using them despite of them being (still) used a lot in mainline.''' {{DevFeature1.9}}: It is currently tested whether the introduction of the "whiteboard" feature is accepted, making it possible to remove the "delay shroud updates" option which could in return make this event stable again.<br />
: A '''sighted''' event is triggered when a fog or shroud is lifted from the primary ''unit''. This can happen when a ''second_unit'' moves to a nearby location and discovers the primary ''unit''. Alternatively, the ''second_unit'' might emerge "out of the mist" and be discovered simultaneously by all members of the enemy side: in this case, the ''second_unit'' is not set. (This is part of the sighted event's bugs.)<br />
<br />
: '''Note:''' The sighted event is ''only'' triggered when a unit moves from one location to another. When the player moves to attack an enemy unit and, in the process, removes the fog/shroud over an enemy unit, the sighted event does ''not'' fire. This makes the sighted event unreliable: It may or may not fire, depending on the user actions. (This may be part of the sighted event's bugs.)<br />
<br />
: '''Alternatives:''' It is sometimes possible to replace a sighted event by a moveto event with a [[StandardLocationFilter|location filter]] matching a nearby location. A [[FilterWML#Filtering_Vision|filter_vision]] filter may be useful in some cases.<br />
<br />
; attack<br />
: Triggers when the primary unit attacks the secondary unit.<br />
<br />
; attack end<br />
: Similar to '''attack''', but is triggered ''after'' the fight instead of before. Note that if either unit is killed during the fight, this event triggers before any '''die''' events.<br />
<br />
; attacker hits<br />
: Triggers when the the primary unit (the attacker) hits the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the attacker.<br />
<br />
; attacker misses<br />
: Same as ''attacker hits'', but is triggered when the attacker misses.<br />
<br />
; defender hits<br />
: Triggers when the primary unit (the attacker) is hit in retaliation by the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the defender.<br />
<br />
; defender misses<br />
: Same as ''defender hits'', but is triggered when the defender misses.<br />
<br />
; stone<br />
: Triggers when the primary unit is hit by an attack with the 'stones' ability (See ''stones'', [[AbilitiesWML]]) by the secondary unit (the unit with the 'stones' ability). In {{DevFeature}}, this event name is changed to "petrified".<br />
<br />
; last breath<br />
: Triggers when the primary unit is killed by the secondary unit, but before the death animation is triggered. Use this instead of name=die when you want the primary unit to make a final [message]. <br />
<br />
; die<br />
: Triggers when the primary unit is killed by the secondary unit. ''Note: The primary unit is not removed from the game until the end of this event. The primary unit can still be manipulated, will block other units from taking its hex, and will still be found by standard unit filters (except [have_unit]). To prevent this behavior, you can use [kill] to remove the unit immediately. However, this will stop any (still unfired) other events that also match the unit from firing afterwards, so use with caution.'' If you want to the primary unit to make a final [message], use name=last_breath, see above.<br />
<br />
; capture<br />
: Triggers when the primary unit captures a village. The village may have been previously neutral, or previously owned by another side; merely moving into your own villages does not constitute a capture.<br />
<br />
; recruit<br />
: Triggers when the primary unit is recruited. (That is, when a unit is recruited it will trigger this event and this event's filter will filter that unit.).<br />
<br />
; prerecruit<br />
: Triggers when the primary unit is recruited but before it is displayed.<br />
<br />
; recall<br />
: Triggers after a unit is recalled.<br />
<br />
; prerecall<br />
: Triggers when a unit is recalled but before it is displayed.<br />
<br />
; advance<br />
: Triggers just before the primary unit is going to advance to another unit.<br />
<br />
; post advance<br />
: Triggers just after the primary unit has advanced to another unit.<br />
<br />
; select<br />
: Triggers when the primary unit is selected. Also triggers when ending a move, as the game keeps the moving unit selected by selecting it again at the end of movement. ''Note: in networked multiplayer, these events are only executed by the client on which the event is triggered, leading to out of sync errors if you modify the game state in the event.''<br />
<br />
; menu item ''X''<br />
: Triggers when a WML menu item with id=''X'' is selected. ''Note: if the menu item has a [command], this event may be executed before or after the command; there is no guarantee.''<br />
<br />
==== Custom events ====<br />
<br />
An event with a custom name may be invoked using the [[InternalActionsWML#.5Bfire_event.5D|[fire_event]]] tag. Normally you'll use such custom events as named subroutines to be called by events with predefined types. One common case of this, for example, is that more than one '''sighted''' events might fire the same custom event that changes the scenario objectives.<br />
<br />
=== Optional Keys and Tags ===<br />
<br />
These keys and tags are more complex ways to filter when an event should trigger:<br />
<br />
==== first_time_only ====<br />
: Whether the event should be removed from the scenario after it is triggered. This key takes a [[ConditionalActionsWML#Boolean_Values|boolean]]; for example:<br />
: ''first_time_only=yes''<br />
:: Default behavior if key is omitted. The event will trigger the first time it can and never again.<br />
: ''first_time_only=no''<br />
:: The event will trigger every time the criteria are met instead of only the first time.<br />
<br />
==== [filter] ====<br />
: The event will only trigger if the primary unit matches this filter.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_second] ====<br />
: Like [filter], but for the secondary unit.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_attack] ====<br />
: Can be used to set additional filtering criteria for the primary unit and the secondary unit that are not generally available in a standard unit filter. Can be used in events ''attack'', ''attacker hits'', ''attacker misses'', ''defender hits'', ''defender misses'' and ''attack end''. For more information and other filter keys, see [[FilterWML]].<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_second_attack] ====<br />
: Like [filter_attack], but for the secondary unit.<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_condition] ====<br />
: {{DevFeature1.9}}<br />
: This tag makes sense inside any sort of event - even those that don't have units, or custom events,... The event will only trigger if this condition evaluates to true.<br />
:* True Condition Tags and Meta Condition Tags as described in [[ConditionalActionsWML]].<br />
: note: This tag is meant to be used when the firing of an event shall be based on variables/conditions which cannot be retrieved from the filtered units.<br />
<br />
==== delayed_variable_substitution ====<br />
: This key is only relevant inside of a [[#Delayed Variable Substitution|nested event]] and controls when variable substitution will occur in those special case actions.<br />
<br />
=== Actions triggered by [event] ===<br />
<br />
After the trigger conditions have been met, all action tags within the [event] tag are executed in the order they are written in.<br />
<br />
There are 3 main types of actions:<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
<br />
and (outside of these categories) additionally<br />
* conditional actions ([[ConditionalActionsWML]]) which contain other actions, which then are executed on certain conditions<br />
* [event] (see [[#Nested Events|below]]) which creates a new event handler<br />
* [lua] ([[LuaWML]]) which contains Lua code to be executed, and<br />
* all tags created from lua with [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] (if they don't fit in one of the categories above)<br />
<br />
Several actions use standard filters to find out which units<br />
to execute the command on. These are denoted by the phrases<br />
"standard unit filter" and "standard location filter".<br />
<br />
=== Nested Events ===<br />
<br />
There is one special type of action: event creation. By placing an '''[event]''' tag inside another '''[event]''' tag, the nested event is spawned (created) when the parent (outer) event is encountered (when executing the contents of the parent event).<br />
<br />
([[#Nested Event Example|See Examples]])<br />
<br />
==== Delayed Variable Substitution ====<br />
<br />
Variable substitution for a nested event can happen either when it is spawned by the parent event or when it is triggered itself. This is controlled with the key '''delayed_variable_substitution''' which is used in the nested event.<br />
<br />
If this key is set to ''yes'', the variables in the nested event will contain values from the turn in which the ''nested'' event was triggered. ''This is the default behavior if the key is omitted.'' If set to ''no'', the variables in the nested event are set at the time the ''parent'' event is triggered.<br />
<br />
This behavior can be fine tuned with a special syntax when referencing variables. Instead of the normal '''$variable''' syntax, use '''$|variable''' to cause a variable to contain values relevant to the turn in which the nested event was triggered even when '''delayed_variable_substitution''' is set to ''no''. In this way you can have a mix of variables relevant to the parent and nested event trigger times.<br />
<br />
([[#Delayed Variable Substitution Example|See Examples]])<br />
<br />
== Multiplayer safety ==<br />
<br />
In multiplayer it is only safe to use WML that might require synchronization with other players because of input or random numbers (like [message] with input or options or [unstore_unit] where a unit might advance) in the following events. This is because in these cases WML needs data from other players to work right and/or do the same thing for all players. This data is only available after a network synchronization.<br />
<br />
List of synchronized events:<br />
* moveto<br />
* sighted <br />
* attack<br />
* attack_end <br />
* attacker hits <br />
* attacker misses <br />
* defender hits<br />
* defender misses <br />
* stone<br />
* last breath <br />
* menu item X<br />
* die<br />
* capture <br />
* recruit<br />
* prerecruit <br />
* recall <br />
* prerecall <br />
* advance <br />
* post_advance <br />
getting message options (etc) from the following events is not synchronized, except in the development version (1.9+svn):<br />
* new turn <br />
* side turn <br />
* turn X <br />
* side X turn <br />
* side X turn Y <br />
* turn refresh <br />
<br />
There is also the possibility of events that are normally synchronized when fired by the engine but can be non-synchronized when fired by WML tags from non-synchronized event. So when you are using them you must be extra careful. For example [unstore_unit] may trigger a unit advancement that will fire ''advance'' and ''post advance'' events.<br />
<br />
== A Trap for the Unwary ==<br />
<br />
You need to beware of using macros to generate events. If you include a macro expanding to an event definition twice, the event will be executed twice (not once) each time the trigger condition fires. Consider this code:<br />
<br />
#define DOUBLE<br />
[event]<br />
name=multiply_by_2<br />
{VARIABLE_OP 2_becomes_4 multiply 2}<br />
[/event]<br />
#enddef<br />
<br />
{DOUBLE}<br />
{DOUBLE}<br />
<br />
{VARIABLE 2_becomes_4 2}<br />
<br />
[fire_event]<br />
name=multiply_by_2<br />
[/fire_event]<br />
<br />
{DEBUG_MSG "$2_becomes_4 should be 4"}<br />
<br />
After it executes, the debug message will reveal that the variable has been set to 8, not 4.<br />
<br />
== Miscellaneous Notes and Examples ==<br />
<br />
=== Primary/Secondary Unit Speaker Example ===<br />
<br />
In events, the primary unit can be referred to as '''unit''' and the secondary unit can be referred to as '''second_unit''' in [message] tags using the '''speaker''' key. For example:<br />
<br />
[event]<br />
name=die<br />
[message]<br />
speaker='''second_unit'''<br />
message= _ "Hahaha! I finally killed you!"<br />
[/message]<br />
<br />
[message]<br />
speaker='''unit'''<br />
message= _ "It's not over yet! I'll come back to haunt you!"<br />
[/message]<br />
[/event]<br />
<br />
=== Nested Event Example ===<br />
<br />
An event is created for a portal that opens on turn 10. The parent (or 'outer') event executes on turn 10 at which point the nested moveto event is created. This nested event executes when a player steps on a certain spot.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
# moving to 5,8 will trigger this event only on turn 10 and after<br />
[/event]<br />
[/event]<br />
<br />
An equivalent way of doing this would be to create a single moveto event with an '''[if]''' statement to check for turn number but using nested '''[event]''' tags is a convenient shortcut to accomplish this task without resorting to '''[if]''' statements.<br />
<br />
=== Delayed Variable Substitution Example ===<br />
<br />
This code will display a message showing the turn number on which the nested ''moveto'' event happens.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=yes<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
Since this is the default behavior for the '''delayed_variable_substitution''' key, the following example is identical.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
The following code will always display "Turn 10" when the nested ''moveto'' event happens. This is because the variable substitution is done when the parent event is triggered and spawns the nested event, ''not'' when the nested event is triggered.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
Finally, the following example is identical to the first two in that it will display a message showing the turn number on which the nested ''moveto'' event happens, despite the fact that the '''delayed_variable_substitution''' key is set to ''no''. This is because the special '''$|variable''' syntax is used.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $|turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
=== Multiple Nested Events ===<br />
<br />
Every delayed_variable_substitution=no causes a variable substitution run on the subevent where it occurs at the spawn time of this event and on all following subevents. For any specific event, variable substitution happens at least one time when the event is executed. For each delayed=no key appearing in itself or in an event of an "older" generation, which is not the toplevel event, an additional variable substitution run is made.<br />
[event]# parent<br />
name=turn 2<br />
#delayed_variable_substitution=no # In the parent event, delayed= has no effect.<br />
<br />
[event]# child<br />
name=turn 3<br />
delayed_variable_substitution=no # Causes variable substitution in the child, grandchild and great-grandchild event<br />
# at execution time of the parent event = spawn time of the child event.<br />
<br />
[event]# grandchild<br />
name=turn 4<br />
delayed_variable_substitution=yes # no variable substitution in the grandchild and great-grandchild event<br />
# at execution time of the child event = spawn time of the grandchild event<br />
<br />
[event]# great-grandchild<br />
name=turn 5<br />
{DEBUG_MSG $turn_number}# output: 2 - value from the variable substitution at execution time of the parent event,<br />
# caused by delayed=no in the child event<br />
<br />
{DEBUG_MSG $||turn_number}# output: "$turn_number"<br />
# Each variable substitution transforms a "$|" to a "$" (except when no | left).<br />
<br />
{DEBUG_MSG $|turn_number}# output: 5 - from the variable substitution at execution time<br />
# of the great-grandchild event<br />
[/event]<br />
[/event]<br />
[/event]<br />
[/event]<br />
<br />
== See Also ==<br />
<br />
* [[DirectActionsWML]]<br />
* [[InternalActionsWML]]<br />
* [[InterfaceActionsWML]]<br />
* [[FilterWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=EventWML&diff=39952EventWML2011-01-05T22:37:10Z<p>Paŭlo: /* Actions triggered by [event] */ added [lua]+co</p>
<hr />
<div>{{WML Tags}}<br />
== The [event] Tag ==<br />
<br />
This tag is a subtag of the [scenario], [unit_type] and [era] tags which is used to describe a set of actions which trigger at a certain point in a scenario. When used in a [scenario] tag (also includes [multiplayer], [tutorial] and [test]), the event only occurs in that scenario. When used in a [unit_type] tag, the event will occur in all scenarios in which a unit of that type appears in (only after such a unit appears during the scenario, however). When used in an [era], the event will occur in any scenario which is played using that era.<br />
<br />
This tag has keys and child tags that control when and if the event actions will be triggered. Most important of these is the '''name''' key. Without it, no error will be raised but the event will never fire. Therefore, from a practical standpoint, it can be considered mandatory. All of the others can be used or not and the event actions will fire either way.<br />
<br />
'''Lexicon side note:''' ''The word "event" in the [event] tag itself may be considered an abbreviation of the word "event handler" because it is technically not a game "event" but an event '''handler''' for the game events fired with the given 'name'. However, this distinction is usually unimportant in most discussions and the event handlers are therefore simply referred to as "events" in this documentation.''<br />
<br />
=== The 'name' Key (Mandatory) ===<br />
<br />
Usage:<br />
name=<value><br />
<br />
This key defines which game event or trigger your [event] tag will be handling. This 'name' key should not be confused with a descriptive comment; it is rather a precise value which must match the predefined game event's name to be valid.<br />
<br />
'''Lexicon side note:''' ''It is not uncommon to refer to these values as the 'trigger' for an event and, furthermore, to call an event by its 'trigger' name. For example, in an event containing '''name=moveto''', a person might refer to the event as a ''''moveto''' event' and/or refer to the ''''moveto''' trigger' in the event or even talk about the 'event trigger' when referring to the '''moveto''' value of the 'name' key in that event. Some or all of this usage can, in fact, be found throughout this page.''<br />
<br />
The '''name''' key can accept a list of comma separated values describing when the event will be triggered.* These values may be either predefined event types or custom event names not matching any predefined type.<br />
<br />
For example:<br />
<br />
name=attacker misses,defender misses<br />
<br />
''* Note that unless you use [[#first_time_only|first_time_only=no]], the event will fire only once, '''not''' once for each listed type.''<br />
<br />
==== Predefined 'name' Key Values ====<br />
<br />
All predefined event types are listed here along with a description of when this value will cause the event to be triggered. Any value ''not'' listed here is a custom event name which can be triggered only by a '''[fire_event]''' tag somewhere else. Spaces in event names can be interchanged with underscores (for example, '''name=new turn''' and '''name=new_turn''' are equivalent).<br />
<br />
; preload<br />
: Triggers before a scenario 'prestarts' and when loading a savegame -- before anything is shown on the screen at all. Can be used to set up the [[LuaWML|Lua]] environment: loading libraries, defining helper functions, etc.<br />
: '''Note:''' Unlike prestart and start, the preload event '''must be able to fire more than once!''' This is because it is triggered each time a savegame is loaded in addition to the initial time when it loads before the scenario 'prestart'. This means that it is effectively ''mandatory'' to have the [[#first_time_only|first_time_only=no]] key value in a preload event. <br />
<br />
; prestart<br />
: Triggers before a scenario 'starts' -- before anything is shown on the screen at all. Can be used to set up things like village ownership. For things displayed on-screen such as character dialog, use '''start''' instead.<br />
: '''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
; start<br />
: Triggers after the map is shown but before the scenario begins -- before players can 'do' anything.<br />
: '''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
; new turn<br />
: Triggers at the start of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. Before any events of this type trigger, the value of the WML variable '''turn_number''' is set to the number of the turn that is beginning.<br />
<br />
; turn end {{DevFeature1.9}}<br />
: Triggers at the end of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. The WML variable '''side_number''' will contain the side that ended their turn.<br />
<br />
; turn ''X'' end {{DevFeature1.9}}<br />
: Triggers at the end of turn ''X''.<br />
<br />
; side turn<br />
: Triggers when a side is about to start its turn. Before events of this type trigger, the value of the WML variable '''side_number''' is set to the number of the side of the player about to take their turn. This is before any healing takes place for that side, before calculating income, and before restoring unit movement and status.<br />
<br />
; ai turn<br />
: Triggered just before the AI is invoked for a side. This is called after ''side turn'', and thus the WML variable '''side_number''' still holds the number of this side. Note that this event might be called several times per turn in case that fallbacks to human or droiding is involved. I.e. it happens at the middle of turn of human side 1 if the human player droids his side. It happens after the selection of ai to play the turn but before AI is told that new turn has come.<br />
: '''Note:''' ''This event currently breaks replays since it is not explicitly saved in a replay and there is no AI involved in replays...''<br />
<br />
; turn refresh<br />
: Like '''side turn''', triggers just before a side is taking control but '''after''' healing, calculating income, and restoring unit movement and status.<br />
<br />
; turn ''X''<br />
: Triggers at the start of turn ''X''. It's the first side initialization event. <br />
:Side initialization events go in the order of: <br />
: 1) '''turn ''X''''' <br />
:2) '''new turn''' <br />
:3) '''side turn''' <br />
:4) '''side ''X'' turn''' <br />
:5) '''side turn ''X''''' <br />
:6) '''side ''X'' turn ''Y''''' <br />
:7) '''turn refresh''' <br />
:8) '''side ''X'' turn refresh''' <br />
:9) '''turn ''X'' refresh''' <br />
:10) '''side ''X'' turn ''Y'' refresh'''<br />
<br />
; side ''X'' turn ''Y''<br />
: This event triggers at the start of turn ''Y'' of side X {{DevFeature}}<br />
<br />
; side ''X'' turn<br />
: This event triggers at the start of any turn of side X {{DevFeature}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side turn ''X''<br />
: This event triggers at the start of any side on turn X {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side X turn Y refresh<br />
: This event triggers at the turn refresh for side X on turn Y {{DevFeature1.9}}<br />
<br />
; side ''X'' turn refresh<br />
: This event triggers at the turn refresh for side X {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; turn ''X'' refresh<br />
: This event triggers for any side at the refresh of turn X. {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side turn end {{DevFeature1.9}}<br />
: Triggers after a side ends its turn. Like side turn, there are also some variations for specific combinations of side number and turn number. Here is the order in which the turn end events trigger:<br />
:1) '''side turn end''' <br />
:2) '''side ''X'' turn end''' <br />
:3) '''side turn ''X'' end''' <br />
:4) '''side ''X'' turn ''Y'' end''' <br />
:5) '''turn end''' <br />
:6) '''turn ''X'' end''' <br />
<br />
; time over<br />
: Triggers on turn ''turns''. (''turns'' is specified in [scenario])<br />
<br />
; enemies defeated<br />
: Triggers when all units with '''canrecruit=yes''' (that is, all leaders) not allied with side 1 are killed.<br />
<br />
; victory<br />
: In this scenario, any tag of the form '''[endlevel] result=victory [/endlevel]''' will be automatically preceded by all actions in this tag. It helps debugging if the victory event allows you to safely advance to any of the possible next maps after using the ":n" command. Scenarios where key units are picked up before the victory, or where some action chosen earlier determines which map to advance to, make it hard to quickly test scenarios in a campaign. (See also: [endlevel], [[DirectActionsWML]])<br />
<br />
; defeat<br />
: In this scenario, any tag of the form '''[endlevel] result=defeat [/endlevel]''' will be automatically preceded by all actions in this tag. (See also [endlevel], [[DirectActionsWML]])<br />
<br />
<br />
Filters (except [filter_condition] which is for all sorts of events) can be applied to the following event triggers (see [[FilterWML]]; see also below). The actions specified in the event tag will be executed only if the filter returns true. <br />
These event triggers are all actions by units ('''moveto''', '''attack''') or things that happen to units ('''recruit''', '''advance'''). When one of these events is triggered, the position of the active unit (referred to as the '''primary unit''') is stored in the variables '''x1''' and '''y1''' and the position of any unit that primary unit does something to is stored in the variables '''x2''' and '''y2''' (this unit is referred to as the '''secondary unit''' below). '' These units are also automatically stored in the variables 'unit' and 'second_unit' as if they had been stored using the '''[store_unit]''' tag. see [[SingleUnitWML]]<br />
<br />
; moveto<br />
: Triggers after the primary unit moves. Typically this is used when the primary unit gets to a particular location and a filter for the location of the primary unit is included; remember that this is the location that the primary unit lands on, not the location it started on or any location it travels on.<br />''An '''[allow_undo]''' tag anywhere within a moveto event will cancel any lack of undo functionality the event would have caused. Note that undo functionality will only move the unit back to its former location; it will not undo other changes to the game caused by the event. Thus it is up to the scenario designer to use this tag correctly.'' {{DevFeature}} $x2 and $y2 refer to the hex the unit came from.<br />
<br />
; sighted<br />
: '''important: "sighted" events are very buggy in general, especially if "delay shroud updates" is set to "yes". Avoid using them despite of them being (still) used a lot in mainline.''' {{DevFeature1.9}}: It is currently tested whether the introduction of the "whiteboard" feature is accepted, making it possible to remove the "delay shroud updates" option which could in return make this event stable again.<br />
: A '''sighted''' event is triggered when a fog or shroud is lifted from the primary ''unit''. This can happen when a ''second_unit'' moves to a nearby location and discovers the primary ''unit''. Alternatively, the ''second_unit'' might emerge "out of the mist" and be discovered simultaneously by all members of the enemy side: in this case, the ''second_unit'' is not set. (This is part of the sighted event's bugs.)<br />
<br />
: '''Note:''' The sighted event is ''only'' triggered when a unit moves from one location to another. When the player moves to attack an enemy unit and, in the process, removes the fog/shroud over an enemy unit, the sighted event does ''not'' fire. This makes the sighted event unreliable: It may or may not fire, depending on the user actions. (This may be part of the sighted event's bugs.)<br />
<br />
: '''Alternatives:''' It is sometimes possible to replace a sighted event by a moveto event with a [[StandardLocationFilter|location filter]] matching a nearby location. A [[FilterWML#Filtering_Vision|filter_vision]] filter may be useful in some cases.<br />
<br />
; attack<br />
: Triggers when the primary unit attacks the secondary unit.<br />
<br />
; attack end<br />
: Similar to '''attack''', but is triggered ''after'' the fight instead of before. Note that if either unit is killed during the fight, this event triggers before any '''die''' events.<br />
<br />
; attacker hits<br />
: Triggers when the the primary unit (the attacker) hits the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the attacker.<br />
<br />
; attacker misses<br />
: Same as ''attacker hits'', but is triggered when the attacker misses.<br />
<br />
; defender hits<br />
: Triggers when the primary unit (the attacker) is hit in retaliation by the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the defender.<br />
<br />
; defender misses<br />
: Same as ''defender hits'', but is triggered when the defender misses.<br />
<br />
; stone<br />
: Triggers when the primary unit is hit by an attack with the 'stones' ability (See ''stones'', [[AbilitiesWML]]) by the secondary unit (the unit with the 'stones' ability). In {{DevFeature}}, this event name is changed to "petrified".<br />
<br />
; last breath<br />
: Triggers when the primary unit is killed by the secondary unit, but before the death animation is triggered. Use this instead of name=die when you want the primary unit to make a final [message]. <br />
<br />
; die<br />
: Triggers when the primary unit is killed by the secondary unit. ''Note: The primary unit is not removed from the game until the end of this event. The primary unit can still be manipulated, will block other units from taking its hex, and will still be found by standard unit filters (except [have_unit]). To prevent this behavior, you can use [kill] to remove the unit immediately. However, this will stop any (still unfired) other events that also match the unit from firing afterwards, so use with caution.'' If you want to the primary unit to make a final [message], use name=last_breath, see above.<br />
<br />
; capture<br />
: Triggers when the primary unit captures a village. The village may have been previously neutral, or previously owned by another side; merely moving into your own villages does not constitute a capture.<br />
<br />
; recruit<br />
: Triggers when the primary unit is recruited. (That is, when a unit is recruited it will trigger this event and this event's filter will filter that unit.).<br />
<br />
; prerecruit<br />
: Triggers when the primary unit is recruited but before it is displayed.<br />
<br />
; recall<br />
: Triggers after a unit is recalled.<br />
<br />
; prerecall<br />
: Triggers when a unit is recalled but before it is displayed.<br />
<br />
; advance<br />
: Triggers just before the primary unit is going to advance to another unit.<br />
<br />
; post advance<br />
: Triggers just after the primary unit has advanced to another unit.<br />
<br />
; select<br />
: Triggers when the primary unit is selected. Also triggers when ending a move, as the game keeps the moving unit selected by selecting it again at the end of movement. ''Note: in networked multiplayer, these events are only executed by the client on which the event is triggered, leading to out of sync errors if you modify the game state in the event.''<br />
<br />
; menu item ''X''<br />
: Triggers when a WML menu item with id=''X'' is selected. ''Note: if the menu item has a [command], this event may be executed before or after the command; there is no guarantee.''<br />
<br />
==== Custom events ====<br />
<br />
An event with a custom name may be invoked using the [[InternalActionsWML#.5Bfire_event.5D|[fire_event]]] tag. Normally you'll use such custom events as named subroutines to be called by events with predefined types. One common case of this, for example, is that more than one '''sighted''' events might fire the same custom event that changes the scenario objectives.<br />
<br />
=== Optional Keys and Tags ===<br />
<br />
These keys and tags are more complex ways to filter when an event should trigger:<br />
<br />
==== first_time_only ====<br />
: Whether the event should be removed from the scenario after it is triggered. This key takes a [[ConditionalActionsWML#Boolean_Values|boolean]]; for example:<br />
: ''first_time_only=yes''<br />
:: Default behavior if key is omitted. The event will trigger the first time it can and never again.<br />
: ''first_time_only=no''<br />
:: The event will trigger every time the criteria are met instead of only the first time.<br />
<br />
==== [filter] ====<br />
: The event will only trigger if the primary unit matches this filter.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_second] ====<br />
: Like [filter], but for the secondary unit.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_attack] ====<br />
: Can be used to set additional filtering criteria for the primary unit and the secondary unit that are not generally available in a standard unit filter. Can be used in events ''attack'', ''attacker hits'', ''attacker misses'', ''defender hits'', ''defender misses'' and ''attack end''. For more information and other filter keys, see [[FilterWML]].<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_second_attack] ====<br />
: Like [filter_attack], but for the secondary unit.<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_condition] ====<br />
: {{DevFeature1.9}}<br />
: This tag makes sense inside any sort of event - even those that don't have units, or custom events,... The event will only trigger if this condition evaluates to true.<br />
:* True Condition Tags and Meta Condition Tags as described in [[ConditionalActionsWML]].<br />
: note: This tag is meant to be used when the firing of an event shall be based on variables/conditions which cannot be retrieved from the filtered units.<br />
<br />
==== [event] ====<br />
: A special case 'action', the [event] tag may be used to create a [[#Nested Events|nested event]].<br />
<br />
==== delayed_variable_substitution ====<br />
: This key is only relevant inside of a [[#Delayed Variable Substitution|nested event]] and controls when variable substitution will occur in those special case actions.<br />
<br />
=== Actions triggered by [event] ===<br />
<br />
After the trigger conditions have been met, all action tags within the [event] tag are executed in the order they are written in.<br />
<br />
There are 3 main types of actions:<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
<br />
and (outside of these categories) additionally<br />
* conditional actions ([[ConditionalActionsWML]]) which contain other actions, which then are executed on certain conditions<br />
* [event] (see [[#Nested Events|below]]) which creates a new event handler<br />
* [lua] ([[LuaWML]]) which contains Lua code to be executed, and<br />
* all tags created from lua with [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] (if they don't fit in one of the categories above)<br />
<br />
Several actions use standard filters to find out which units<br />
to execute the command on. These are denoted by the phrases<br />
"standard unit filter" and "standard location filter".<br />
<br />
=== Nested Events ===<br />
<br />
There is one special type of action: event creation. By placing an '''[event]''' tag inside another '''[event]''' tag, the nested event is spawned (created) when the parent (outer) event is encountered (when executing the contents of the parent event).<br />
<br />
([[#Nested Event Example|See Examples]])<br />
<br />
==== Delayed Variable Substitution ====<br />
<br />
Variable substitution for a nested event can happen either when it is spawned by the parent event or when it is triggered itself. This is controlled with the key '''delayed_variable_substitution''' which is used in the nested event.<br />
<br />
If this key is set to ''yes'', the variables in the nested event will contain values from the turn in which the ''nested'' event was triggered. ''This is the default behavior if the key is omitted.'' If set to ''no'', the variables in the nested event are set at the time the ''parent'' event is triggered.<br />
<br />
This behavior can be fine tuned with a special syntax when referencing variables. Instead of the normal '''$variable''' syntax, use '''$|variable''' to cause a variable to contain values relevant to the turn in which the nested event was triggered even when '''delayed_variable_substitution''' is set to ''no''. In this way you can have a mix of variables relevant to the parent and nested event trigger times.<br />
<br />
([[#Delayed Variable Substitution Example|See Examples]])<br />
<br />
== Multiplayer safety ==<br />
<br />
In multiplayer it is only safe to use WML that might require synchronization with other players because of input or random numbers (like [message] with input or options or [unstore_unit] where a unit might advance) in the following events. This is because in these cases WML needs data from other players to work right and/or do the same thing for all players. This data is only available after a network synchronization.<br />
<br />
List of synchronized events:<br />
* moveto<br />
* sighted <br />
* attack<br />
* attack_end <br />
* attacker hits <br />
* attacker misses <br />
* defender hits<br />
* defender misses <br />
* stone<br />
* last breath <br />
* menu item X<br />
* die<br />
* capture <br />
* recruit<br />
* prerecruit <br />
* recall <br />
* prerecall <br />
* advance <br />
* post_advance <br />
getting message options (etc) from the following events is not synchronized, except in the development version (1.9+svn):<br />
* new turn <br />
* side turn <br />
* turn X <br />
* side X turn <br />
* side X turn Y <br />
* turn refresh <br />
<br />
There is also the possibility of events that are normally synchronized when fired by the engine but can be non-synchronized when fired by WML tags from non-synchronized event. So when you are using them you must be extra careful. For example [unstore_unit] may trigger a unit advancement that will fire ''advance'' and ''post advance'' events.<br />
<br />
== A Trap for the Unwary ==<br />
<br />
You need to beware of using macros to generate events. If you include a macro expanding to an event definition twice, the event will be executed twice (not once) each time the trigger condition fires. Consider this code:<br />
<br />
#define DOUBLE<br />
[event]<br />
name=multiply_by_2<br />
{VARIABLE_OP 2_becomes_4 multiply 2}<br />
[/event]<br />
#enddef<br />
<br />
{DOUBLE}<br />
{DOUBLE}<br />
<br />
{VARIABLE 2_becomes_4 2}<br />
<br />
[fire_event]<br />
name=multiply_by_2<br />
[/fire_event]<br />
<br />
{DEBUG_MSG "$2_becomes_4 should be 4"}<br />
<br />
After it executes, the debug message will reveal that the variable has been set to 8, not 4.<br />
<br />
== Miscellaneous Notes and Examples ==<br />
<br />
=== Primary/Secondary Unit Speaker Example ===<br />
<br />
In events, the primary unit can be referred to as '''unit''' and the secondary unit can be referred to as '''second_unit''' in [message] tags using the '''speaker''' key. For example:<br />
<br />
[event]<br />
name=die<br />
[message]<br />
speaker='''second_unit'''<br />
message= _ "Hahaha! I finally killed you!"<br />
[/message]<br />
<br />
[message]<br />
speaker='''unit'''<br />
message= _ "It's not over yet! I'll come back to haunt you!"<br />
[/message]<br />
[/event]<br />
<br />
=== Nested Event Example ===<br />
<br />
An event is created for a portal that opens on turn 10. The parent (or 'outer') event executes on turn 10 at which point the nested moveto event is created. This nested event executes when a player steps on a certain spot.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
# moving to 5,8 will trigger this event only on turn 10 and after<br />
[/event]<br />
[/event]<br />
<br />
An equivalent way of doing this would be to create a single moveto event with an '''[if]''' statement to check for turn number but using nested '''[event]''' tags is a convenient shortcut to accomplish this task without resorting to '''[if]''' statements.<br />
<br />
=== Delayed Variable Substitution Example ===<br />
<br />
This code will display a message showing the turn number on which the nested ''moveto'' event happens.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=yes<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
Since this is the default behavior for the '''delayed_variable_substitution''' key, the following example is identical.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
The following code will always display "Turn 10" when the nested ''moveto'' event happens. This is because the variable substitution is done when the parent event is triggered and spawns the nested event, ''not'' when the nested event is triggered.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
Finally, the following example is identical to the first two in that it will display a message showing the turn number on which the nested ''moveto'' event happens, despite the fact that the '''delayed_variable_substitution''' key is set to ''no''. This is because the special '''$|variable''' syntax is used.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $|turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
=== Multiple Nested Events ===<br />
<br />
Every delayed_variable_substitution=no causes a variable substitution run on the subevent where it occurs at the spawn time of this event and on all following subevents. For any specific event, variable substitution happens at least one time when the event is executed. For each delayed=no key appearing in itself or in an event of an "older" generation, which is not the toplevel event, an additional variable substitution run is made.<br />
[event]# parent<br />
name=turn 2<br />
#delayed_variable_substitution=no # In the parent event, delayed= has no effect.<br />
<br />
[event]# child<br />
name=turn 3<br />
delayed_variable_substitution=no # Causes variable substitution in the child, grandchild and great-grandchild event<br />
# at execution time of the parent event = spawn time of the child event.<br />
<br />
[event]# grandchild<br />
name=turn 4<br />
delayed_variable_substitution=yes # no variable substitution in the grandchild and great-grandchild event<br />
# at execution time of the child event = spawn time of the grandchild event<br />
<br />
[event]# great-grandchild<br />
name=turn 5<br />
{DEBUG_MSG $turn_number}# output: 2 - value from the variable substitution at execution time of the parent event,<br />
# caused by delayed=no in the child event<br />
<br />
{DEBUG_MSG $||turn_number}# output: "$turn_number"<br />
# Each variable substitution transforms a "$|" to a "$" (except when no | left).<br />
<br />
{DEBUG_MSG $|turn_number}# output: 5 - from the variable substitution at execution time<br />
# of the great-grandchild event<br />
[/event]<br />
[/event]<br />
[/event]<br />
[/event]<br />
<br />
== See Also ==<br />
<br />
* [[DirectActionsWML]]<br />
* [[InternalActionsWML]]<br />
* [[InterfaceActionsWML]]<br />
* [[FilterWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=EventWML&diff=39951EventWML2011-01-05T22:06:59Z<p>Paŭlo: /* Actions triggered by [event] */</p>
<hr />
<div>{{WML Tags}}<br />
== The [event] Tag ==<br />
<br />
This tag is a subtag of the [scenario], [unit_type] and [era] tags which is used to describe a set of actions which trigger at a certain point in a scenario. When used in a [scenario] tag (also includes [multiplayer], [tutorial] and [test]), the event only occurs in that scenario. When used in a [unit_type] tag, the event will occur in all scenarios in which a unit of that type appears in (only after such a unit appears during the scenario, however). When used in an [era], the event will occur in any scenario which is played using that era.<br />
<br />
This tag has keys and child tags that control when and if the event actions will be triggered. Most important of these is the '''name''' key. Without it, no error will be raised but the event will never fire. Therefore, from a practical standpoint, it can be considered mandatory. All of the others can be used or not and the event actions will fire either way.<br />
<br />
'''Lexicon side note:''' ''The word "event" in the [event] tag itself may be considered an abbreviation of the word "event handler" because it is technically not a game "event" but an event '''handler''' for the game events fired with the given 'name'. However, this distinction is usually unimportant in most discussions and the event handlers are therefore simply referred to as "events" in this documentation.''<br />
<br />
=== The 'name' Key (Mandatory) ===<br />
<br />
Usage:<br />
name=<value><br />
<br />
This key defines which game event or trigger your [event] tag will be handling. This 'name' key should not be confused with a descriptive comment; it is rather a precise value which must match the predefined game event's name to be valid.<br />
<br />
'''Lexicon side note:''' ''It is not uncommon to refer to these values as the 'trigger' for an event and, furthermore, to call an event by its 'trigger' name. For example, in an event containing '''name=moveto''', a person might refer to the event as a ''''moveto''' event' and/or refer to the ''''moveto''' trigger' in the event or even talk about the 'event trigger' when referring to the '''moveto''' value of the 'name' key in that event. Some or all of this usage can, in fact, be found throughout this page.''<br />
<br />
The '''name''' key can accept a list of comma separated values describing when the event will be triggered.* These values may be either predefined event types or custom event names not matching any predefined type.<br />
<br />
For example:<br />
<br />
name=attacker misses,defender misses<br />
<br />
''* Note that unless you use [[#first_time_only|first_time_only=no]], the event will fire only once, '''not''' once for each listed type.''<br />
<br />
==== Predefined 'name' Key Values ====<br />
<br />
All predefined event types are listed here along with a description of when this value will cause the event to be triggered. Any value ''not'' listed here is a custom event name which can be triggered only by a '''[fire_event]''' tag somewhere else. Spaces in event names can be interchanged with underscores (for example, '''name=new turn''' and '''name=new_turn''' are equivalent).<br />
<br />
; preload<br />
: Triggers before a scenario 'prestarts' and when loading a savegame -- before anything is shown on the screen at all. Can be used to set up the [[LuaWML|Lua]] environment: loading libraries, defining helper functions, etc.<br />
: '''Note:''' Unlike prestart and start, the preload event '''must be able to fire more than once!''' This is because it is triggered each time a savegame is loaded in addition to the initial time when it loads before the scenario 'prestart'. This means that it is effectively ''mandatory'' to have the [[#first_time_only|first_time_only=no]] key value in a preload event. <br />
<br />
; prestart<br />
: Triggers before a scenario 'starts' -- before anything is shown on the screen at all. Can be used to set up things like village ownership. For things displayed on-screen such as character dialog, use '''start''' instead.<br />
: '''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
; start<br />
: Triggers after the map is shown but before the scenario begins -- before players can 'do' anything.<br />
: '''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
; new turn<br />
: Triggers at the start of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. Before any events of this type trigger, the value of the WML variable '''turn_number''' is set to the number of the turn that is beginning.<br />
<br />
; turn end {{DevFeature1.9}}<br />
: Triggers at the end of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. The WML variable '''side_number''' will contain the side that ended their turn.<br />
<br />
; turn ''X'' end {{DevFeature1.9}}<br />
: Triggers at the end of turn ''X''.<br />
<br />
; side turn<br />
: Triggers when a side is about to start its turn. Before events of this type trigger, the value of the WML variable '''side_number''' is set to the number of the side of the player about to take their turn. This is before any healing takes place for that side, before calculating income, and before restoring unit movement and status.<br />
<br />
; ai turn<br />
: Triggered just before the AI is invoked for a side. This is called after ''side turn'', and thus the WML variable '''side_number''' still holds the number of this side. Note that this event might be called several times per turn in case that fallbacks to human or droiding is involved. I.e. it happens at the middle of turn of human side 1 if the human player droids his side. It happens after the selection of ai to play the turn but before AI is told that new turn has come.<br />
: '''Note:''' ''This event currently breaks replays since it is not explicitly saved in a replay and there is no AI involved in replays...''<br />
<br />
; turn refresh<br />
: Like '''side turn''', triggers just before a side is taking control but '''after''' healing, calculating income, and restoring unit movement and status.<br />
<br />
; turn ''X''<br />
: Triggers at the start of turn ''X''. It's the first side initialization event. <br />
:Side initialization events go in the order of: <br />
: 1) '''turn ''X''''' <br />
:2) '''new turn''' <br />
:3) '''side turn''' <br />
:4) '''side ''X'' turn''' <br />
:5) '''side turn ''X''''' <br />
:6) '''side ''X'' turn ''Y''''' <br />
:7) '''turn refresh''' <br />
:8) '''side ''X'' turn refresh''' <br />
:9) '''turn ''X'' refresh''' <br />
:10) '''side ''X'' turn ''Y'' refresh'''<br />
<br />
; side ''X'' turn ''Y''<br />
: This event triggers at the start of turn ''Y'' of side X {{DevFeature}}<br />
<br />
; side ''X'' turn<br />
: This event triggers at the start of any turn of side X {{DevFeature}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side turn ''X''<br />
: This event triggers at the start of any side on turn X {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side X turn Y refresh<br />
: This event triggers at the turn refresh for side X on turn Y {{DevFeature1.9}}<br />
<br />
; side ''X'' turn refresh<br />
: This event triggers at the turn refresh for side X {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; turn ''X'' refresh<br />
: This event triggers for any side at the refresh of turn X. {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side turn end {{DevFeature1.9}}<br />
: Triggers after a side ends its turn. Like side turn, there are also some variations for specific combinations of side number and turn number. Here is the order in which the turn end events trigger:<br />
:1) '''side turn end''' <br />
:2) '''side ''X'' turn end''' <br />
:3) '''side turn ''X'' end''' <br />
:4) '''side ''X'' turn ''Y'' end''' <br />
:5) '''turn end''' <br />
:6) '''turn ''X'' end''' <br />
<br />
; time over<br />
: Triggers on turn ''turns''. (''turns'' is specified in [scenario])<br />
<br />
; enemies defeated<br />
: Triggers when all units with '''canrecruit=yes''' (that is, all leaders) not allied with side 1 are killed.<br />
<br />
; victory<br />
: In this scenario, any tag of the form '''[endlevel] result=victory [/endlevel]''' will be automatically preceded by all actions in this tag. It helps debugging if the victory event allows you to safely advance to any of the possible next maps after using the ":n" command. Scenarios where key units are picked up before the victory, or where some action chosen earlier determines which map to advance to, make it hard to quickly test scenarios in a campaign. (See also: [endlevel], [[DirectActionsWML]])<br />
<br />
; defeat<br />
: In this scenario, any tag of the form '''[endlevel] result=defeat [/endlevel]''' will be automatically preceded by all actions in this tag. (See also [endlevel], [[DirectActionsWML]])<br />
<br />
<br />
Filters (except [filter_condition] which is for all sorts of events) can be applied to the following event triggers (see [[FilterWML]]; see also below). The actions specified in the event tag will be executed only if the filter returns true. <br />
These event triggers are all actions by units ('''moveto''', '''attack''') or things that happen to units ('''recruit''', '''advance'''). When one of these events is triggered, the position of the active unit (referred to as the '''primary unit''') is stored in the variables '''x1''' and '''y1''' and the position of any unit that primary unit does something to is stored in the variables '''x2''' and '''y2''' (this unit is referred to as the '''secondary unit''' below). '' These units are also automatically stored in the variables 'unit' and 'second_unit' as if they had been stored using the '''[store_unit]''' tag. see [[SingleUnitWML]]<br />
<br />
; moveto<br />
: Triggers after the primary unit moves. Typically this is used when the primary unit gets to a particular location and a filter for the location of the primary unit is included; remember that this is the location that the primary unit lands on, not the location it started on or any location it travels on.<br />''An '''[allow_undo]''' tag anywhere within a moveto event will cancel any lack of undo functionality the event would have caused. Note that undo functionality will only move the unit back to its former location; it will not undo other changes to the game caused by the event. Thus it is up to the scenario designer to use this tag correctly.'' {{DevFeature}} $x2 and $y2 refer to the hex the unit came from.<br />
<br />
; sighted<br />
: '''important: "sighted" events are very buggy in general, especially if "delay shroud updates" is set to "yes". Avoid using them despite of them being (still) used a lot in mainline.''' {{DevFeature1.9}}: It is currently tested whether the introduction of the "whiteboard" feature is accepted, making it possible to remove the "delay shroud updates" option which could in return make this event stable again.<br />
: A '''sighted''' event is triggered when a fog or shroud is lifted from the primary ''unit''. This can happen when a ''second_unit'' moves to a nearby location and discovers the primary ''unit''. Alternatively, the ''second_unit'' might emerge "out of the mist" and be discovered simultaneously by all members of the enemy side: in this case, the ''second_unit'' is not set. (This is part of the sighted event's bugs.)<br />
<br />
: '''Note:''' The sighted event is ''only'' triggered when a unit moves from one location to another. When the player moves to attack an enemy unit and, in the process, removes the fog/shroud over an enemy unit, the sighted event does ''not'' fire. This makes the sighted event unreliable: It may or may not fire, depending on the user actions. (This may be part of the sighted event's bugs.)<br />
<br />
: '''Alternatives:''' It is sometimes possible to replace a sighted event by a moveto event with a [[StandardLocationFilter|location filter]] matching a nearby location. A [[FilterWML#Filtering_Vision|filter_vision]] filter may be useful in some cases.<br />
<br />
; attack<br />
: Triggers when the primary unit attacks the secondary unit.<br />
<br />
; attack end<br />
: Similar to '''attack''', but is triggered ''after'' the fight instead of before. Note that if either unit is killed during the fight, this event triggers before any '''die''' events.<br />
<br />
; attacker hits<br />
: Triggers when the the primary unit (the attacker) hits the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the attacker.<br />
<br />
; attacker misses<br />
: Same as ''attacker hits'', but is triggered when the attacker misses.<br />
<br />
; defender hits<br />
: Triggers when the primary unit (the attacker) is hit in retaliation by the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the defender.<br />
<br />
; defender misses<br />
: Same as ''defender hits'', but is triggered when the defender misses.<br />
<br />
; stone<br />
: Triggers when the primary unit is hit by an attack with the 'stones' ability (See ''stones'', [[AbilitiesWML]]) by the secondary unit (the unit with the 'stones' ability). In {{DevFeature}}, this event name is changed to "petrified".<br />
<br />
; last breath<br />
: Triggers when the primary unit is killed by the secondary unit, but before the death animation is triggered. Use this instead of name=die when you want the primary unit to make a final [message]. <br />
<br />
; die<br />
: Triggers when the primary unit is killed by the secondary unit. ''Note: The primary unit is not removed from the game until the end of this event. The primary unit can still be manipulated, will block other units from taking its hex, and will still be found by standard unit filters (except [have_unit]). To prevent this behavior, you can use [kill] to remove the unit immediately. However, this will stop any (still unfired) other events that also match the unit from firing afterwards, so use with caution.'' If you want to the primary unit to make a final [message], use name=last_breath, see above.<br />
<br />
; capture<br />
: Triggers when the primary unit captures a village. The village may have been previously neutral, or previously owned by another side; merely moving into your own villages does not constitute a capture.<br />
<br />
; recruit<br />
: Triggers when the primary unit is recruited. (That is, when a unit is recruited it will trigger this event and this event's filter will filter that unit.).<br />
<br />
; prerecruit<br />
: Triggers when the primary unit is recruited but before it is displayed.<br />
<br />
; recall<br />
: Triggers after a unit is recalled.<br />
<br />
; prerecall<br />
: Triggers when a unit is recalled but before it is displayed.<br />
<br />
; advance<br />
: Triggers just before the primary unit is going to advance to another unit.<br />
<br />
; post advance<br />
: Triggers just after the primary unit has advanced to another unit.<br />
<br />
; select<br />
: Triggers when the primary unit is selected. Also triggers when ending a move, as the game keeps the moving unit selected by selecting it again at the end of movement. ''Note: in networked multiplayer, these events are only executed by the client on which the event is triggered, leading to out of sync errors if you modify the game state in the event.''<br />
<br />
; menu item ''X''<br />
: Triggers when a WML menu item with id=''X'' is selected. ''Note: if the menu item has a [command], this event may be executed before or after the command; there is no guarantee.''<br />
<br />
==== Custom events ====<br />
<br />
An event with a custom name may be invoked using the [[InternalActionsWML#.5Bfire_event.5D|[fire_event]]] tag. Normally you'll use such custom events as named subroutines to be called by events with predefined types. One common case of this, for example, is that more than one '''sighted''' events might fire the same custom event that changes the scenario objectives.<br />
<br />
=== Optional Keys and Tags ===<br />
<br />
These keys and tags are more complex ways to filter when an event should trigger:<br />
<br />
==== first_time_only ====<br />
: Whether the event should be removed from the scenario after it is triggered. This key takes a [[ConditionalActionsWML#Boolean_Values|boolean]]; for example:<br />
: ''first_time_only=yes''<br />
:: Default behavior if key is omitted. The event will trigger the first time it can and never again.<br />
: ''first_time_only=no''<br />
:: The event will trigger every time the criteria are met instead of only the first time.<br />
<br />
==== [filter] ====<br />
: The event will only trigger if the primary unit matches this filter.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_second] ====<br />
: Like [filter], but for the secondary unit.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_attack] ====<br />
: Can be used to set additional filtering criteria for the primary unit and the secondary unit that are not generally available in a standard unit filter. Can be used in events ''attack'', ''attacker hits'', ''attacker misses'', ''defender hits'', ''defender misses'' and ''attack end''. For more information and other filter keys, see [[FilterWML]].<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_second_attack] ====<br />
: Like [filter_attack], but for the secondary unit.<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_condition] ====<br />
: {{DevFeature1.9}}<br />
: This tag makes sense inside any sort of event - even those that don't have units, or custom events,... The event will only trigger if this condition evaluates to true.<br />
:* True Condition Tags and Meta Condition Tags as described in [[ConditionalActionsWML]].<br />
: note: This tag is meant to be used when the firing of an event shall be based on variables/conditions which cannot be retrieved from the filtered units.<br />
<br />
==== [event] ====<br />
: A special case 'action', the [event] tag may be used to create a [[#Nested Events|nested event]].<br />
<br />
==== delayed_variable_substitution ====<br />
: This key is only relevant inside of a [[#Delayed Variable Substitution|nested event]] and controls when variable substitution will occur in those special case actions.<br />
<br />
=== Actions triggered by [event] ===<br />
<br />
After the trigger conditions have been met, all action tags within the [event] tag are executed in the order they are written in.<br />
<br />
There are 3 main types of actions:<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
<br />
and additionally<br />
* conditional actions ([[ConditionalActionsWML]]) contain other actions, which are executed on certain conditions<br />
* [[#Nested Events|nested events]]<br />
<br />
Several actions use standard filters to find out which units<br />
to execute the command on. These are denoted by the phrases<br />
"standard unit filter" and "standard location filter".<br />
<br />
=== Nested Events ===<br />
<br />
There is one special type of action: event creation. By placing an '''[event]''' tag inside another '''[event]''' tag, the nested event is spawned (created) when the parent (outer) event is encountered (when executing the contents of the parent event).<br />
<br />
([[#Nested Event Example|See Examples]])<br />
<br />
==== Delayed Variable Substitution ====<br />
<br />
Variable substitution for a nested event can happen either when it is spawned by the parent event or when it is triggered itself. This is controlled with the key '''delayed_variable_substitution''' which is used in the nested event.<br />
<br />
If this key is set to ''yes'', the variables in the nested event will contain values from the turn in which the ''nested'' event was triggered. ''This is the default behavior if the key is omitted.'' If set to ''no'', the variables in the nested event are set at the time the ''parent'' event is triggered.<br />
<br />
This behavior can be fine tuned with a special syntax when referencing variables. Instead of the normal '''$variable''' syntax, use '''$|variable''' to cause a variable to contain values relevant to the turn in which the nested event was triggered even when '''delayed_variable_substitution''' is set to ''no''. In this way you can have a mix of variables relevant to the parent and nested event trigger times.<br />
<br />
([[#Delayed Variable Substitution Example|See Examples]])<br />
<br />
== Multiplayer safety ==<br />
<br />
In multiplayer it is only safe to use WML that might require synchronization with other players because of input or random numbers (like [message] with input or options or [unstore_unit] where a unit might advance) in the following events. This is because in these cases WML needs data from other players to work right and/or do the same thing for all players. This data is only available after a network synchronization.<br />
<br />
List of synchronized events:<br />
* moveto<br />
* sighted <br />
* attack<br />
* attack_end <br />
* attacker hits <br />
* attacker misses <br />
* defender hits<br />
* defender misses <br />
* stone<br />
* last breath <br />
* menu item X<br />
* die<br />
* capture <br />
* recruit<br />
* prerecruit <br />
* recall <br />
* prerecall <br />
* advance <br />
* post_advance <br />
getting message options (etc) from the following events is not synchronized, except in the development version (1.9+svn):<br />
* new turn <br />
* side turn <br />
* turn X <br />
* side X turn <br />
* side X turn Y <br />
* turn refresh <br />
<br />
There is also the possibility of events that are normally synchronized when fired by the engine but can be non-synchronized when fired by WML tags from non-synchronized event. So when you are using them you must be extra careful. For example [unstore_unit] may trigger a unit advancement that will fire ''advance'' and ''post advance'' events.<br />
<br />
== A Trap for the Unwary ==<br />
<br />
You need to beware of using macros to generate events. If you include a macro expanding to an event definition twice, the event will be executed twice (not once) each time the trigger condition fires. Consider this code:<br />
<br />
#define DOUBLE<br />
[event]<br />
name=multiply_by_2<br />
{VARIABLE_OP 2_becomes_4 multiply 2}<br />
[/event]<br />
#enddef<br />
<br />
{DOUBLE}<br />
{DOUBLE}<br />
<br />
{VARIABLE 2_becomes_4 2}<br />
<br />
[fire_event]<br />
name=multiply_by_2<br />
[/fire_event]<br />
<br />
{DEBUG_MSG "$2_becomes_4 should be 4"}<br />
<br />
After it executes, the debug message will reveal that the variable has been set to 8, not 4.<br />
<br />
== Miscellaneous Notes and Examples ==<br />
<br />
=== Primary/Secondary Unit Speaker Example ===<br />
<br />
In events, the primary unit can be referred to as '''unit''' and the secondary unit can be referred to as '''second_unit''' in [message] tags using the '''speaker''' key. For example:<br />
<br />
[event]<br />
name=die<br />
[message]<br />
speaker='''second_unit'''<br />
message= _ "Hahaha! I finally killed you!"<br />
[/message]<br />
<br />
[message]<br />
speaker='''unit'''<br />
message= _ "It's not over yet! I'll come back to haunt you!"<br />
[/message]<br />
[/event]<br />
<br />
=== Nested Event Example ===<br />
<br />
An event is created for a portal that opens on turn 10. The parent (or 'outer') event executes on turn 10 at which point the nested moveto event is created. This nested event executes when a player steps on a certain spot.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
# moving to 5,8 will trigger this event only on turn 10 and after<br />
[/event]<br />
[/event]<br />
<br />
An equivalent way of doing this would be to create a single moveto event with an '''[if]''' statement to check for turn number but using nested '''[event]''' tags is a convenient shortcut to accomplish this task without resorting to '''[if]''' statements.<br />
<br />
=== Delayed Variable Substitution Example ===<br />
<br />
This code will display a message showing the turn number on which the nested ''moveto'' event happens.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=yes<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
Since this is the default behavior for the '''delayed_variable_substitution''' key, the following example is identical.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
The following code will always display "Turn 10" when the nested ''moveto'' event happens. This is because the variable substitution is done when the parent event is triggered and spawns the nested event, ''not'' when the nested event is triggered.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
Finally, the following example is identical to the first two in that it will display a message showing the turn number on which the nested ''moveto'' event happens, despite the fact that the '''delayed_variable_substitution''' key is set to ''no''. This is because the special '''$|variable''' syntax is used.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $|turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
=== Multiple Nested Events ===<br />
<br />
Every delayed_variable_substitution=no causes a variable substitution run on the subevent where it occurs at the spawn time of this event and on all following subevents. For any specific event, variable substitution happens at least one time when the event is executed. For each delayed=no key appearing in itself or in an event of an "older" generation, which is not the toplevel event, an additional variable substitution run is made.<br />
[event]# parent<br />
name=turn 2<br />
#delayed_variable_substitution=no # In the parent event, delayed= has no effect.<br />
<br />
[event]# child<br />
name=turn 3<br />
delayed_variable_substitution=no # Causes variable substitution in the child, grandchild and great-grandchild event<br />
# at execution time of the parent event = spawn time of the child event.<br />
<br />
[event]# grandchild<br />
name=turn 4<br />
delayed_variable_substitution=yes # no variable substitution in the grandchild and great-grandchild event<br />
# at execution time of the child event = spawn time of the grandchild event<br />
<br />
[event]# great-grandchild<br />
name=turn 5<br />
{DEBUG_MSG $turn_number}# output: 2 - value from the variable substitution at execution time of the parent event,<br />
# caused by delayed=no in the child event<br />
<br />
{DEBUG_MSG $||turn_number}# output: "$turn_number"<br />
# Each variable substitution transforms a "$|" to a "$" (except when no | left).<br />
<br />
{DEBUG_MSG $|turn_number}# output: 5 - from the variable substitution at execution time<br />
# of the great-grandchild event<br />
[/event]<br />
[/event]<br />
[/event]<br />
[/event]<br />
<br />
== See Also ==<br />
<br />
* [[DirectActionsWML]]<br />
* [[InternalActionsWML]]<br />
* [[InterfaceActionsWML]]<br />
* [[FilterWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=EventWML&diff=39950EventWML2011-01-05T22:05:42Z<p>Paŭlo: /* Actions triggered by [event] */ added conditional + nested</p>
<hr />
<div>{{WML Tags}}<br />
== The [event] Tag ==<br />
<br />
This tag is a subtag of the [scenario], [unit_type] and [era] tags which is used to describe a set of actions which trigger at a certain point in a scenario. When used in a [scenario] tag (also includes [multiplayer], [tutorial] and [test]), the event only occurs in that scenario. When used in a [unit_type] tag, the event will occur in all scenarios in which a unit of that type appears in (only after such a unit appears during the scenario, however). When used in an [era], the event will occur in any scenario which is played using that era.<br />
<br />
This tag has keys and child tags that control when and if the event actions will be triggered. Most important of these is the '''name''' key. Without it, no error will be raised but the event will never fire. Therefore, from a practical standpoint, it can be considered mandatory. All of the others can be used or not and the event actions will fire either way.<br />
<br />
'''Lexicon side note:''' ''The word "event" in the [event] tag itself may be considered an abbreviation of the word "event handler" because it is technically not a game "event" but an event '''handler''' for the game events fired with the given 'name'. However, this distinction is usually unimportant in most discussions and the event handlers are therefore simply referred to as "events" in this documentation.''<br />
<br />
=== The 'name' Key (Mandatory) ===<br />
<br />
Usage:<br />
name=<value><br />
<br />
This key defines which game event or trigger your [event] tag will be handling. This 'name' key should not be confused with a descriptive comment; it is rather a precise value which must match the predefined game event's name to be valid.<br />
<br />
'''Lexicon side note:''' ''It is not uncommon to refer to these values as the 'trigger' for an event and, furthermore, to call an event by its 'trigger' name. For example, in an event containing '''name=moveto''', a person might refer to the event as a ''''moveto''' event' and/or refer to the ''''moveto''' trigger' in the event or even talk about the 'event trigger' when referring to the '''moveto''' value of the 'name' key in that event. Some or all of this usage can, in fact, be found throughout this page.''<br />
<br />
The '''name''' key can accept a list of comma separated values describing when the event will be triggered.* These values may be either predefined event types or custom event names not matching any predefined type.<br />
<br />
For example:<br />
<br />
name=attacker misses,defender misses<br />
<br />
''* Note that unless you use [[#first_time_only|first_time_only=no]], the event will fire only once, '''not''' once for each listed type.''<br />
<br />
==== Predefined 'name' Key Values ====<br />
<br />
All predefined event types are listed here along with a description of when this value will cause the event to be triggered. Any value ''not'' listed here is a custom event name which can be triggered only by a '''[fire_event]''' tag somewhere else. Spaces in event names can be interchanged with underscores (for example, '''name=new turn''' and '''name=new_turn''' are equivalent).<br />
<br />
; preload<br />
: Triggers before a scenario 'prestarts' and when loading a savegame -- before anything is shown on the screen at all. Can be used to set up the [[LuaWML|Lua]] environment: loading libraries, defining helper functions, etc.<br />
: '''Note:''' Unlike prestart and start, the preload event '''must be able to fire more than once!''' This is because it is triggered each time a savegame is loaded in addition to the initial time when it loads before the scenario 'prestart'. This means that it is effectively ''mandatory'' to have the [[#first_time_only|first_time_only=no]] key value in a preload event. <br />
<br />
; prestart<br />
: Triggers before a scenario 'starts' -- before anything is shown on the screen at all. Can be used to set up things like village ownership. For things displayed on-screen such as character dialog, use '''start''' instead.<br />
: '''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
; start<br />
: Triggers after the map is shown but before the scenario begins -- before players can 'do' anything.<br />
: '''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''<br />
<br />
; new turn<br />
: Triggers at the start of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. Before any events of this type trigger, the value of the WML variable '''turn_number''' is set to the number of the turn that is beginning.<br />
<br />
; turn end {{DevFeature1.9}}<br />
: Triggers at the end of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. The WML variable '''side_number''' will contain the side that ended their turn.<br />
<br />
; turn ''X'' end {{DevFeature1.9}}<br />
: Triggers at the end of turn ''X''.<br />
<br />
; side turn<br />
: Triggers when a side is about to start its turn. Before events of this type trigger, the value of the WML variable '''side_number''' is set to the number of the side of the player about to take their turn. This is before any healing takes place for that side, before calculating income, and before restoring unit movement and status.<br />
<br />
; ai turn<br />
: Triggered just before the AI is invoked for a side. This is called after ''side turn'', and thus the WML variable '''side_number''' still holds the number of this side. Note that this event might be called several times per turn in case that fallbacks to human or droiding is involved. I.e. it happens at the middle of turn of human side 1 if the human player droids his side. It happens after the selection of ai to play the turn but before AI is told that new turn has come.<br />
: '''Note:''' ''This event currently breaks replays since it is not explicitly saved in a replay and there is no AI involved in replays...''<br />
<br />
; turn refresh<br />
: Like '''side turn''', triggers just before a side is taking control but '''after''' healing, calculating income, and restoring unit movement and status.<br />
<br />
; turn ''X''<br />
: Triggers at the start of turn ''X''. It's the first side initialization event. <br />
:Side initialization events go in the order of: <br />
: 1) '''turn ''X''''' <br />
:2) '''new turn''' <br />
:3) '''side turn''' <br />
:4) '''side ''X'' turn''' <br />
:5) '''side turn ''X''''' <br />
:6) '''side ''X'' turn ''Y''''' <br />
:7) '''turn refresh''' <br />
:8) '''side ''X'' turn refresh''' <br />
:9) '''turn ''X'' refresh''' <br />
:10) '''side ''X'' turn ''Y'' refresh'''<br />
<br />
; side ''X'' turn ''Y''<br />
: This event triggers at the start of turn ''Y'' of side X {{DevFeature}}<br />
<br />
; side ''X'' turn<br />
: This event triggers at the start of any turn of side X {{DevFeature}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side turn ''X''<br />
: This event triggers at the start of any side on turn X {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side X turn Y refresh<br />
: This event triggers at the turn refresh for side X on turn Y {{DevFeature1.9}}<br />
<br />
; side ''X'' turn refresh<br />
: This event triggers at the turn refresh for side X {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; turn ''X'' refresh<br />
: This event triggers for any side at the refresh of turn X. {{DevFeature1.9}}<br />
: '''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''<br />
<br />
; side turn end {{DevFeature1.9}}<br />
: Triggers after a side ends its turn. Like side turn, there are also some variations for specific combinations of side number and turn number. Here is the order in which the turn end events trigger:<br />
:1) '''side turn end''' <br />
:2) '''side ''X'' turn end''' <br />
:3) '''side turn ''X'' end''' <br />
:4) '''side ''X'' turn ''Y'' end''' <br />
:5) '''turn end''' <br />
:6) '''turn ''X'' end''' <br />
<br />
; time over<br />
: Triggers on turn ''turns''. (''turns'' is specified in [scenario])<br />
<br />
; enemies defeated<br />
: Triggers when all units with '''canrecruit=yes''' (that is, all leaders) not allied with side 1 are killed.<br />
<br />
; victory<br />
: In this scenario, any tag of the form '''[endlevel] result=victory [/endlevel]''' will be automatically preceded by all actions in this tag. It helps debugging if the victory event allows you to safely advance to any of the possible next maps after using the ":n" command. Scenarios where key units are picked up before the victory, or where some action chosen earlier determines which map to advance to, make it hard to quickly test scenarios in a campaign. (See also: [endlevel], [[DirectActionsWML]])<br />
<br />
; defeat<br />
: In this scenario, any tag of the form '''[endlevel] result=defeat [/endlevel]''' will be automatically preceded by all actions in this tag. (See also [endlevel], [[DirectActionsWML]])<br />
<br />
<br />
Filters (except [filter_condition] which is for all sorts of events) can be applied to the following event triggers (see [[FilterWML]]; see also below). The actions specified in the event tag will be executed only if the filter returns true. <br />
These event triggers are all actions by units ('''moveto''', '''attack''') or things that happen to units ('''recruit''', '''advance'''). When one of these events is triggered, the position of the active unit (referred to as the '''primary unit''') is stored in the variables '''x1''' and '''y1''' and the position of any unit that primary unit does something to is stored in the variables '''x2''' and '''y2''' (this unit is referred to as the '''secondary unit''' below). '' These units are also automatically stored in the variables 'unit' and 'second_unit' as if they had been stored using the '''[store_unit]''' tag. see [[SingleUnitWML]]<br />
<br />
; moveto<br />
: Triggers after the primary unit moves. Typically this is used when the primary unit gets to a particular location and a filter for the location of the primary unit is included; remember that this is the location that the primary unit lands on, not the location it started on or any location it travels on.<br />''An '''[allow_undo]''' tag anywhere within a moveto event will cancel any lack of undo functionality the event would have caused. Note that undo functionality will only move the unit back to its former location; it will not undo other changes to the game caused by the event. Thus it is up to the scenario designer to use this tag correctly.'' {{DevFeature}} $x2 and $y2 refer to the hex the unit came from.<br />
<br />
; sighted<br />
: '''important: "sighted" events are very buggy in general, especially if "delay shroud updates" is set to "yes". Avoid using them despite of them being (still) used a lot in mainline.''' {{DevFeature1.9}}: It is currently tested whether the introduction of the "whiteboard" feature is accepted, making it possible to remove the "delay shroud updates" option which could in return make this event stable again.<br />
: A '''sighted''' event is triggered when a fog or shroud is lifted from the primary ''unit''. This can happen when a ''second_unit'' moves to a nearby location and discovers the primary ''unit''. Alternatively, the ''second_unit'' might emerge "out of the mist" and be discovered simultaneously by all members of the enemy side: in this case, the ''second_unit'' is not set. (This is part of the sighted event's bugs.)<br />
<br />
: '''Note:''' The sighted event is ''only'' triggered when a unit moves from one location to another. When the player moves to attack an enemy unit and, in the process, removes the fog/shroud over an enemy unit, the sighted event does ''not'' fire. This makes the sighted event unreliable: It may or may not fire, depending on the user actions. (This may be part of the sighted event's bugs.)<br />
<br />
: '''Alternatives:''' It is sometimes possible to replace a sighted event by a moveto event with a [[StandardLocationFilter|location filter]] matching a nearby location. A [[FilterWML#Filtering_Vision|filter_vision]] filter may be useful in some cases.<br />
<br />
; attack<br />
: Triggers when the primary unit attacks the secondary unit.<br />
<br />
; attack end<br />
: Similar to '''attack''', but is triggered ''after'' the fight instead of before. Note that if either unit is killed during the fight, this event triggers before any '''die''' events.<br />
<br />
; attacker hits<br />
: Triggers when the the primary unit (the attacker) hits the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the attacker.<br />
<br />
; attacker misses<br />
: Same as ''attacker hits'', but is triggered when the attacker misses.<br />
<br />
; defender hits<br />
: Triggers when the primary unit (the attacker) is hit in retaliation by the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the defender.<br />
<br />
; defender misses<br />
: Same as ''defender hits'', but is triggered when the defender misses.<br />
<br />
; stone<br />
: Triggers when the primary unit is hit by an attack with the 'stones' ability (See ''stones'', [[AbilitiesWML]]) by the secondary unit (the unit with the 'stones' ability). In {{DevFeature}}, this event name is changed to "petrified".<br />
<br />
; last breath<br />
: Triggers when the primary unit is killed by the secondary unit, but before the death animation is triggered. Use this instead of name=die when you want the primary unit to make a final [message]. <br />
<br />
; die<br />
: Triggers when the primary unit is killed by the secondary unit. ''Note: The primary unit is not removed from the game until the end of this event. The primary unit can still be manipulated, will block other units from taking its hex, and will still be found by standard unit filters (except [have_unit]). To prevent this behavior, you can use [kill] to remove the unit immediately. However, this will stop any (still unfired) other events that also match the unit from firing afterwards, so use with caution.'' If you want to the primary unit to make a final [message], use name=last_breath, see above.<br />
<br />
; capture<br />
: Triggers when the primary unit captures a village. The village may have been previously neutral, or previously owned by another side; merely moving into your own villages does not constitute a capture.<br />
<br />
; recruit<br />
: Triggers when the primary unit is recruited. (That is, when a unit is recruited it will trigger this event and this event's filter will filter that unit.).<br />
<br />
; prerecruit<br />
: Triggers when the primary unit is recruited but before it is displayed.<br />
<br />
; recall<br />
: Triggers after a unit is recalled.<br />
<br />
; prerecall<br />
: Triggers when a unit is recalled but before it is displayed.<br />
<br />
; advance<br />
: Triggers just before the primary unit is going to advance to another unit.<br />
<br />
; post advance<br />
: Triggers just after the primary unit has advanced to another unit.<br />
<br />
; select<br />
: Triggers when the primary unit is selected. Also triggers when ending a move, as the game keeps the moving unit selected by selecting it again at the end of movement. ''Note: in networked multiplayer, these events are only executed by the client on which the event is triggered, leading to out of sync errors if you modify the game state in the event.''<br />
<br />
; menu item ''X''<br />
: Triggers when a WML menu item with id=''X'' is selected. ''Note: if the menu item has a [command], this event may be executed before or after the command; there is no guarantee.''<br />
<br />
==== Custom events ====<br />
<br />
An event with a custom name may be invoked using the [[InternalActionsWML#.5Bfire_event.5D|[fire_event]]] tag. Normally you'll use such custom events as named subroutines to be called by events with predefined types. One common case of this, for example, is that more than one '''sighted''' events might fire the same custom event that changes the scenario objectives.<br />
<br />
=== Optional Keys and Tags ===<br />
<br />
These keys and tags are more complex ways to filter when an event should trigger:<br />
<br />
==== first_time_only ====<br />
: Whether the event should be removed from the scenario after it is triggered. This key takes a [[ConditionalActionsWML#Boolean_Values|boolean]]; for example:<br />
: ''first_time_only=yes''<br />
:: Default behavior if key is omitted. The event will trigger the first time it can and never again.<br />
: ''first_time_only=no''<br />
:: The event will trigger every time the criteria are met instead of only the first time.<br />
<br />
==== [filter] ====<br />
: The event will only trigger if the primary unit matches this filter.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_second] ====<br />
: Like [filter], but for the secondary unit.<br />
:* [[StandardUnitFilter]]: selection criteria<br />
<br />
==== [filter_attack] ====<br />
: Can be used to set additional filtering criteria for the primary unit and the secondary unit that are not generally available in a standard unit filter. Can be used in events ''attack'', ''attacker hits'', ''attacker misses'', ''defender hits'', ''defender misses'' and ''attack end''. For more information and other filter keys, see [[FilterWML]].<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_second_attack] ====<br />
: Like [filter_attack], but for the secondary unit.<br />
:* '''name''': the name of the weapon used.<br />
:* '''range''': the range of the weapon used.<br />
:* '''special''': filter on the attack's special power.<br />
<br />
==== [filter_condition] ====<br />
: {{DevFeature1.9}}<br />
: This tag makes sense inside any sort of event - even those that don't have units, or custom events,... The event will only trigger if this condition evaluates to true.<br />
:* True Condition Tags and Meta Condition Tags as described in [[ConditionalActionsWML]].<br />
: note: This tag is meant to be used when the firing of an event shall be based on variables/conditions which cannot be retrieved from the filtered units.<br />
<br />
==== [event] ====<br />
: A special case 'action', the [event] tag may be used to create a [[#Nested Events|nested event]].<br />
<br />
==== delayed_variable_substitution ====<br />
: This key is only relevant inside of a [[#Delayed Variable Substitution|nested event]] and controls when variable substitution will occur in those special case actions.<br />
<br />
=== Actions triggered by [event] ===<br />
<br />
After the trigger conditions have been met, all action tags within the [event] tag are executed in the order they are written in.<br />
<br />
There are 3 main types of actions:<br />
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay<br />
* display actions ([[InterfaceActionsWML]]) which show something to the user<br />
* internal actions ([[InternalActionsWML]]) which are used by WML internally<br />
<br />
* conditional action ([[ConditionalActionsWML]]) contain other actions which are executed on certain conditions<br />
* [[#Nested Events|nested events]]<br />
<br />
Several actions use standard filters to find out which units<br />
to execute the command on. These are denoted by the phrases<br />
"standard unit filter" and "standard location filter".<br />
<br />
=== Nested Events ===<br />
<br />
There is one special type of action: event creation. By placing an '''[event]''' tag inside another '''[event]''' tag, the nested event is spawned (created) when the parent (outer) event is encountered (when executing the contents of the parent event).<br />
<br />
([[#Nested Event Example|See Examples]])<br />
<br />
==== Delayed Variable Substitution ====<br />
<br />
Variable substitution for a nested event can happen either when it is spawned by the parent event or when it is triggered itself. This is controlled with the key '''delayed_variable_substitution''' which is used in the nested event.<br />
<br />
If this key is set to ''yes'', the variables in the nested event will contain values from the turn in which the ''nested'' event was triggered. ''This is the default behavior if the key is omitted.'' If set to ''no'', the variables in the nested event are set at the time the ''parent'' event is triggered.<br />
<br />
This behavior can be fine tuned with a special syntax when referencing variables. Instead of the normal '''$variable''' syntax, use '''$|variable''' to cause a variable to contain values relevant to the turn in which the nested event was triggered even when '''delayed_variable_substitution''' is set to ''no''. In this way you can have a mix of variables relevant to the parent and nested event trigger times.<br />
<br />
([[#Delayed Variable Substitution Example|See Examples]])<br />
<br />
== Multiplayer safety ==<br />
<br />
In multiplayer it is only safe to use WML that might require synchronization with other players because of input or random numbers (like [message] with input or options or [unstore_unit] where a unit might advance) in the following events. This is because in these cases WML needs data from other players to work right and/or do the same thing for all players. This data is only available after a network synchronization.<br />
<br />
List of synchronized events:<br />
* moveto<br />
* sighted <br />
* attack<br />
* attack_end <br />
* attacker hits <br />
* attacker misses <br />
* defender hits<br />
* defender misses <br />
* stone<br />
* last breath <br />
* menu item X<br />
* die<br />
* capture <br />
* recruit<br />
* prerecruit <br />
* recall <br />
* prerecall <br />
* advance <br />
* post_advance <br />
getting message options (etc) from the following events is not synchronized, except in the development version (1.9+svn):<br />
* new turn <br />
* side turn <br />
* turn X <br />
* side X turn <br />
* side X turn Y <br />
* turn refresh <br />
<br />
There is also the possibility of events that are normally synchronized when fired by the engine but can be non-synchronized when fired by WML tags from non-synchronized event. So when you are using them you must be extra careful. For example [unstore_unit] may trigger a unit advancement that will fire ''advance'' and ''post advance'' events.<br />
<br />
== A Trap for the Unwary ==<br />
<br />
You need to beware of using macros to generate events. If you include a macro expanding to an event definition twice, the event will be executed twice (not once) each time the trigger condition fires. Consider this code:<br />
<br />
#define DOUBLE<br />
[event]<br />
name=multiply_by_2<br />
{VARIABLE_OP 2_becomes_4 multiply 2}<br />
[/event]<br />
#enddef<br />
<br />
{DOUBLE}<br />
{DOUBLE}<br />
<br />
{VARIABLE 2_becomes_4 2}<br />
<br />
[fire_event]<br />
name=multiply_by_2<br />
[/fire_event]<br />
<br />
{DEBUG_MSG "$2_becomes_4 should be 4"}<br />
<br />
After it executes, the debug message will reveal that the variable has been set to 8, not 4.<br />
<br />
== Miscellaneous Notes and Examples ==<br />
<br />
=== Primary/Secondary Unit Speaker Example ===<br />
<br />
In events, the primary unit can be referred to as '''unit''' and the secondary unit can be referred to as '''second_unit''' in [message] tags using the '''speaker''' key. For example:<br />
<br />
[event]<br />
name=die<br />
[message]<br />
speaker='''second_unit'''<br />
message= _ "Hahaha! I finally killed you!"<br />
[/message]<br />
<br />
[message]<br />
speaker='''unit'''<br />
message= _ "It's not over yet! I'll come back to haunt you!"<br />
[/message]<br />
[/event]<br />
<br />
=== Nested Event Example ===<br />
<br />
An event is created for a portal that opens on turn 10. The parent (or 'outer') event executes on turn 10 at which point the nested moveto event is created. This nested event executes when a player steps on a certain spot.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
# moving to 5,8 will trigger this event only on turn 10 and after<br />
[/event]<br />
[/event]<br />
<br />
An equivalent way of doing this would be to create a single moveto event with an '''[if]''' statement to check for turn number but using nested '''[event]''' tags is a convenient shortcut to accomplish this task without resorting to '''[if]''' statements.<br />
<br />
=== Delayed Variable Substitution Example ===<br />
<br />
This code will display a message showing the turn number on which the nested ''moveto'' event happens.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=yes<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
Since this is the default behavior for the '''delayed_variable_substitution''' key, the following example is identical.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
The following code will always display "Turn 10" when the nested ''moveto'' event happens. This is because the variable substitution is done when the parent event is triggered and spawns the nested event, ''not'' when the nested event is triggered.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
Finally, the following example is identical to the first two in that it will display a message showing the turn number on which the nested ''moveto'' event happens, despite the fact that the '''delayed_variable_substitution''' key is set to ''no''. This is because the special '''$|variable''' syntax is used.<br />
<br />
[event]<br />
name=turn 10<br />
<br />
[event]<br />
name=moveto<br />
delayed_variable_substitution=no<br />
<br />
[filter]<br />
x,y=5,8<br />
[/filter]<br />
<br />
{DEBUG_MSG "Turn $|turn_number"} <br />
[/event]<br />
[/event]<br />
<br />
=== Multiple Nested Events ===<br />
<br />
Every delayed_variable_substitution=no causes a variable substitution run on the subevent where it occurs at the spawn time of this event and on all following subevents. For any specific event, variable substitution happens at least one time when the event is executed. For each delayed=no key appearing in itself or in an event of an "older" generation, which is not the toplevel event, an additional variable substitution run is made.<br />
[event]# parent<br />
name=turn 2<br />
#delayed_variable_substitution=no # In the parent event, delayed= has no effect.<br />
<br />
[event]# child<br />
name=turn 3<br />
delayed_variable_substitution=no # Causes variable substitution in the child, grandchild and great-grandchild event<br />
# at execution time of the parent event = spawn time of the child event.<br />
<br />
[event]# grandchild<br />
name=turn 4<br />
delayed_variable_substitution=yes # no variable substitution in the grandchild and great-grandchild event<br />
# at execution time of the child event = spawn time of the grandchild event<br />
<br />
[event]# great-grandchild<br />
name=turn 5<br />
{DEBUG_MSG $turn_number}# output: 2 - value from the variable substitution at execution time of the parent event,<br />
# caused by delayed=no in the child event<br />
<br />
{DEBUG_MSG $||turn_number}# output: "$turn_number"<br />
# Each variable substitution transforms a "$|" to a "$" (except when no | left).<br />
<br />
{DEBUG_MSG $|turn_number}# output: 5 - from the variable substitution at execution time<br />
# of the great-grandchild event<br />
[/event]<br />
[/event]<br />
[/event]<br />
[/event]<br />
<br />
== See Also ==<br />
<br />
* [[DirectActionsWML]]<br />
* [[InternalActionsWML]]<br />
* [[InterfaceActionsWML]]<br />
* [[FilterWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlohttps://wiki.wesnoth.org/index.php?title=ScenarioWML&diff=39494ScenarioWML2010-12-10T13:43:01Z<p>Paŭlo: /* the toplevel tags [multiplayer], [test], [tutorial], [scenario] */ - mention allow_new_game=no here, too</p>
<hr />
<div>{{WML Tags}}<br />
== the toplevel tags [multiplayer], [test], [tutorial], [scenario] ==<br />
<br />
The top level tags '''[multiplayer]''', '''[test]''', '''[tutorial]''' and '''[scenario]''' are all formatted the same way.<br />
The difference between these tags is the way that the scenarios they describe are accessed.<br />
<br />
The keys '''id''' and '''next_scenario''' affect how scenarios can be accessed.<br />
Whenever a scenario is won, the scenario with id=''next_scenario'' of the same tag type will be played.<br />
Units from the first scenario will be available for recall in the second.<br />
<br />
Some scenarios can be played without playing other scenarios first<br />
(in this case there is nothing on the recall list).<br />
These scenarios are called ''initial scenario''s.<br />
<br />
A list of initial scenarios, and how to access them:<br />
<br />
* All '''[multiplayer]''' scenarios (without ''allow_new_game=no'') are initial scenarios listed in the multiplayer scenario selector screen (accessed by the "multiplayer" button).<br />
<br />
* The '''[test]''' scenario with the attribute '''id=test''' is an initial scenario. This test scenario can be accessed by running the game in test mode. (note: this is NOT the same as debug mode. It can be accessed using -t or --test)<br />
<br />
* The '''[tutorial]''' scenario with the attribute '''id=tutorial''' is an initial scenario. The tutorial is accessed by clicking on the "tutorial" button.<br />
<br />
* Any '''[scenario]''' scenario with an id listed in the value of ''first_scenario'' in a campaign tag (see [[CampaignWML]]) is an initial scenario accessed by selecting that campaign after clicking on the "campaign" button.<br />
<br />
== The [scenario] tag ==<br />
<br />
The following keys and tags are recognized in '''[scenario]''' tags:<br />
<br />
* '''id''': A unique identifier for this scenario. All scenarios must have an id.<br />
<br />
* '''next_scenario''': The id of the scenario to load when the current one is won. This can be changed dynamically, to build non-linear campaigns.<br />
<br />
* '''description''': (translatable) only for multiplayer maps. Will show up as a tooltip when mousing over the minimap in the multiplayer setup screen.<br />
<br />
* '''name''': (translatable) is shown in several places in the level, including the intro screen. It is also the default name for saves on the level.<br />
<br />
* '''map_data''': inputs valid Wesnoth map data. See [[BuildingMaps]] for a description of the Wesnoth map syntax.<br />
<br />
* '''turns''': sets an event on turn ''turns'' causing the player to lose. Use ''-1'' to have no turn limit. See also [[EventWML]]<br />
<br />
* '''turn_at''': the turn to start on (default=1)<br />
<br />
* '''random_start_time''': controls random starting time of day. Possible values are yes and no or list of possible start times; starting from 1 to number of times. for example ''random_start_time=2,3,5,6'' (default=no)<br />
<br />
* '''music''': the music file relative to ''./music/'' to play during the scenario<br />
<br />
* '''[music]''': specifies the music tracks to play during this scenario, see [[MusicListWML]].<br />
<br />
* '''defeat_music''': specifies a comma-separated list of music tracks which may be chosen to play on defeat. If not provided, the default in [[GameConfigWML]] is used instead. May be overridden by [[DirectActionsWML|endlevel]] clauses.<br />
<br />
* '''victory_music''': specifies a comma-separated list of music tracks which may be chosen to play on victory. If not provided, the default in [[GameConfigWML]] is used instead. May be overridden by [[DirectActionsWML|endlevel]] clauses.<br />
<br />
* '''theme''': the name of the UI theme that should be used when playing this scenario.<br />
<br />
* '''victory_when_enemies_defeated''': when this is set to '''yes''' (default), the player wins once all non-allied units with '''canrecruit=yes''' (aka leaders) are killed. (Currently this only controls the win condition for when all enemies are defeated; it does not prevent the player from losing if he has no leader.) When this value is true the following keys can be used:<br />
** '''carryover_percentage''': by default 80% of the gold is carried over to the next scenario, with this key the amount can be changed.<br />
** '''carryover_add''': if true the gold will be added to the starting gold the next scenario, if false the next scenario will start with the amount of the current scenario (after taxes) or the minimum in the next scenario. Default is false.<br />
<br />
* '''disallow_recall''': when this is set to 'no'(default), the player is allowed to recall units from previous scenarios.<br />
<br />
* '''experience_modifier''': the percentage that required XP to level up (for all units in the scenario) is multiplied by. Default 100. Note that when used in a campaign, weird things (like units being above the required XP to level up) can happen if this value is different for different scenarios.<br />
<br />
* '''[story]''': describes the intro screen. See [[IntroWML]]<br />
<br />
* '''[label]''': sets a label<br />
** '''x''', '''y''': location to set label<br />
** '''text''': the label<br />
<br />
* '''[time]''', '''[illuminated_time]''': how a day should progress. See [[TimeWML]]<br />
<br />
* '''[time_area]''': how a day should progress in a given area. Everywhere not specified in a [time_area] tag is affected by the [time] and [illuminated_time] tags in the [scenario] tag<br />
** takes x and y coordinates.<br />
** '''[time]''', '''[illuminated_time]''': how a day should progress in those locations. See [[TimeWML]]<br />
** time areas can be used in events, assigned identifiers, and removed at discretion. They also accept complete Standard Location Filters. See [[DirectActionsWML]].<br />
<br />
* '''[side]''': describes one player. See [[SideWML]]<br />
<br />
* '''[event]''': describes an event that may be triggered at a certain point of the scenario. See [[EventWML]]<br />
<br />
* '''map_generation''': another way to generate a map. The map will be generated randomly<br />
** '''default''': the default random map generator<br />
<br />
* '''[generator]''' if this is present, the map and scenario will be generated randomly. See [[MapGeneratorWML]]<br />
<br />
the following key is additionally recognized in '''[multiplayer]''' scenarios:<br />
* '''allow_new_game''': (default=yes) allow/prevent the scenario to be listed in the game creation interface. This is intended for extra scenarios in multiplayer campaigns<br />
<br />
== See Also ==<br />
<br />
* [[EventWML]]<br />
* [[ReferenceWML]]<br />
<br />
<br />
[[Category: WML Reference]]</div>Paŭlo