diff --git a/.travis.yml b/.travis.yml
index 6a2ce24d13b0..7c82a2392d45 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,7 +11,6 @@ compiler:
env:
- BUILD="-O0"
- BUILD="-O2"
- - BUILD="C++14 -O2"
- BUILD="translations"
matrix:
@@ -47,7 +46,7 @@ before_install:
- if [ "$BUILD" == "C++14 -O2" ]; then export WML_TEST_TIME=15; fi
- if [ "$BUILD" == "C++14 -O2" ]; then export CXXSTD="1y"; fi
- - if [ "$BUILD" == "-O0" ]; then export EXTRA_FLAGS_RELEASE="-O0 -Wno-literal-suffix -Wno-deprecated-declarations"; fi
+ - if [ "$BUILD" == "-O0" ]; then export EXTRA_FLAGS_RELEASE="-O0 -Wno-deprecated-declarations"; fi
- if [[ "$BUILD" == "-O0" ]] && [[ "$CXX" == "clang++" ]]; then export EXTRA_FLAGS_RELEASE="-O0 -Wno-literal-suffix -Wno-deprecated-declarations -Wno-deprecated-register"; fi
- if [ "$BUILD" == "-O0" ]; then export PLAY_TEST=false; fi
- if [ "$BUILD" == "-O0" ]; then export MP_TEST=false; fi
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cd46110fbc81..5df802e1f62b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,7 +18,7 @@ endif(COMMAND cmake_policy)
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
# use our own version of FindBoost.cmake and other Find* scripts
-set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
#
# Options
@@ -706,7 +706,7 @@ install(FILES l10n-track DESTINATION ${DATADIR})
#
configure_file(
- "${CMAKE_MODULE_PATH}/uninstall.cmake.in"
+ "${CMAKE_SOURCE_DIR}/cmake/uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/uninstall.cmake"
IMMEDIATE @ONLY
)
diff --git a/changelog b/changelog
index da8f1a9f38cc..5054619911c6 100644
--- a/changelog
+++ b/changelog
@@ -4,6 +4,10 @@ Version 1.13.4+dev:
* Removed support for SDL 1.2. SDL 2 is now the only supported version.
* Terrains:
* Changed terrain code of Desert Mountains from Mdy to Mdd.
+ * User Interface:
+ * Various design improvements to GUI2 widgets
+ * New simpler GUI2 loading screen
+ * New colored cursor graphics
* WML engine:
* Fix some issues with [foreach]
* Fix some issues with backstab-like weapon specials
@@ -16,6 +20,11 @@ Version 1.13.4+dev:
* New ~SCALE_INTO_SHARP(w,h) IPF which preserves aspect ratio, using
nearest neighbor scaling.
* Support delayed_variable_substitution= in [on_undo], [on_redo]
+ Note that this means $unit.x and $unit.y may not reflect the unit's
+ true location, so using [unstore_unit] on $unit may have unexpected effects.
+ This applies to $second_unit too. The $x1, $y1, $x2, $y2 variables work fine
+ though, so in most cases they can be used instead. Anything else in $unit
+ or $second_unit is also fine.
* formula= in SUF can now reference $other_unit via the formula variable "other"
* formula= now supported in location, side, and weapon filters
* Weapon filters now support number, parry, accuracy, and movement_used
@@ -23,6 +32,9 @@ Version 1.13.4+dev:
uses full weapon filter.
* lua_function=var.member now works in SUF; however, 'var' still needs to
be a global variable.
+ * Added new keys name_generator, male_name_generator and female_name_generator
+ for the [race] tag to declare a context-free grammar to describe how names
+ are derived
* AiWML:
* Simplified aspect syntax which works for all aspects, present and future:
* All aspects with simple values can be specified as key=value
@@ -120,6 +132,13 @@ Version 1.13.4+dev:
of the time in the overall schedule (eg, 1 would be dawn in the default
schedule). Optional second argument takes a time area ID, to set
local instead of global time.
+ * New wesnoth.add_fog and wesnoth.remove_fog functions allow changing fog
+ on the map. The [lift_fog] and [clear_fog] tags now use this.
+ * New wesnoth.add_sound_source, wesnoth.remove_sound_source, and
+ wesnoth.get_sound_source functions to allow manipulation of sound
+ sources. The [sound_source] and [remove_sound_source] now use these.
+ * New wesnoth.log function for printing log messages. The [wml_message]
+ and [deprecated_message] tags now use this.
* WML tables defined in Lua now accept string keys with array values
(where "array" is a table whose keys are all integers). This joins
the elements of the array with commas and produces a single string
@@ -263,6 +282,8 @@ Version 1.13.4+dev:
* Miscellaneous and bug fixes:
* Resolve translated logo images not being used (bug #24357)
* Ported the "hexometer" tool from Bash to Python 3
+ * Recognize hotkey release events
+ * Allow changing keybindings for scrolling the map.
Version 1.13.4:
* Language and i18n:
diff --git a/data/campaigns/Dead_Water/scenarios/10_The_Flaming_Sword.cfg b/data/campaigns/Dead_Water/scenarios/10_The_Flaming_Sword.cfg
index 382203f6c391..16b855207bf0 100644
--- a/data/campaigns/Dead_Water/scenarios/10_The_Flaming_Sword.cfg
+++ b/data/campaigns/Dead_Water/scenarios/10_The_Flaming_Sword.cfg
@@ -233,7 +233,7 @@
# This is where the lich starts, so he will pick up this
# object immediately:
- {FLAMING_SWORD 37 3 flaming-sword1}
+ {FLAMING_SWORD 37 3 flaming_sword1}
[recall]
id=Caladon
@@ -667,7 +667,7 @@
# (because he will be near the top of the screen).
[/delay]
- {FLAMING_SWORD $x1 $y1 flaming-sword2}
+ {FLAMING_SWORD $x1 $y1 flaming_sword2}
[object]
id=drop_staff
silent=yes
@@ -978,7 +978,7 @@
equals=yes
[/variable]
[then]
- {FLAMING_SWORD $sword_x $sword_y flaming-sword3}
+ {FLAMING_SWORD $sword_x $sword_y flaming_sword3}
{CLEAR_VARIABLE get_sword}
{CLEAR_VARIABLE sword_x}
{CLEAR_VARIABLE sword_y}
@@ -1021,7 +1021,7 @@
equals=yes
[/variable]
[then]
- {FLAMING_SWORD $sword_x $sword_y flaming-sword3}
+ {FLAMING_SWORD $sword_x $sword_y flaming_sword3}
{CLEAR_VARIABLE get_sword}
{CLEAR_VARIABLE sword_x}
{CLEAR_VARIABLE sword_y}
diff --git a/data/core/about.cfg b/data/core/about.cfg
index 600794a3fa93..2de0c9bf0088 100644
--- a/data/core/about.cfg
+++ b/data/core/about.cfg
@@ -1058,6 +1058,9 @@
name = "Doug Rosvick (dlr365)"
wikiuser = "dlr365"
[/entry]
+ [entry]
+ name= "Dugi"
+ [/entry]
[entry]
name = "Duthlet"
[/entry]
@@ -1357,6 +1360,10 @@
[entry]
name = "Ryan Henszey"
[/entry]
+ [entry]
+ name = "Ryan Roden-Corrent (rcorre)"
+ comment = "Hotkey release and scroll key rebinding"
+ [/entry]
[entry]
name = "Sachith Seneviratne (sachith500)"
email = "sachith500@gmail.com"
@@ -1862,7 +1869,6 @@
[/entry]
[entry]
name = "Steven Panek (Espreon)"
- comment = "Current maintainer"
email = "Majora700_AT_gmail_DOT_com"
wikiuser = "Espreon"
[/entry]
@@ -1870,6 +1876,9 @@
name = "Thomas Hockings (Deusite)"
wikiuser = "Deusite"
[/entry]
+ [entry]
+ name = "Wedge009"
+ [/entry]
[/about]
[about]
diff --git a/data/core/hotkeys.cfg b/data/core/hotkeys.cfg
index a9cc925b2fba..f3a5622ade6f 100644
--- a/data/core/hotkeys.cfg
+++ b/data/core/hotkeys.cfg
@@ -13,6 +13,23 @@
#endif
#enddef
+[hotkey]
+ command=scroll-up
+ key=UP
+[/hotkey]
+[hotkey]
+ command=scroll-down
+ key=DOWN
+[/hotkey]
+[hotkey]
+ command=scroll-left
+ key=LEFT
+[/hotkey]
+[hotkey]
+ command=scroll-right
+ key=RIGHT
+[/hotkey]
+
[hotkey]
button=1
command="selectmoveaction"
diff --git a/data/core/macros/names.cfg b/data/core/macros/names.cfg
index 582d59ac93b8..a06301d8d2f9 100644
--- a/data/core/macros/names.cfg
+++ b/data/core/macros/names.cfg
@@ -17,62 +17,226 @@
#define DRAKE_NAMES
male_names= _ "Egar,Elch,Ga’ash,Gadé Ihn,Gakré Ohm,Galeck,Galsh,Garadin,Garchin,Gark,Garlan,Garlin Ohn,Garrutin,Gart’lo,Garushi,Gashinar,Gashol,Gaushii,Gaustun,Gegchi,Gelka Kon,Gelknick,Gillan,Gisharri,Gost,Grada,Græt Ihn,Grashen,Gravlan,Grag,Grelnit,Grenn Ohn,Greth,Gribbel,Gridda,Grish,Gron Ihn,Ka,Kahn Ih,Karigan,Karri Kon,Karron,Kask,Kegrid,Kerath Ihn,Kerath Kor,Klash,Kon Garashé,Kraag,Krall Ohn,Kran Kor,Krash,Kraslar,Krenli,Kruggen,Kun,Mah Toa,Margian,Mar’Ildian,Markan,Markinos,Mar Ohn,Marra Di’lek,Marrito,Marritos,Merkush,Merritos Gark,Morusté,Murr,Omataké,Reshan,Vashitt,Velnick,Veralon,Veramo,Verath,Verditt,Verkon,Verlinn,Vermad,Vertick,Vladnir"
female_names= _ "Alen Ka,Alinash Mal,Ashirt,Auginet Ka,Auuglann,Damell,Dell,Demla,Dinsill,Eshi,Olath,Omage,Omagrra,Orra Ka,Orridan,Orrida,Oshibi,Vallin,Valnirra,Valnitt,Velisk,Verra,Vellin Ka,Veshtar,Vushtin"
+ male_name_generator= _ <<
+main={prefix}{suffix}|{prefix}’{suffix}|{prefix}{suffix} {short_name}
+short_name=Ohm|Ihn|Ohn|Ka|Murr|Kon|Elch|Ko|Græt|Egar
+prefix=Ga|Ge|Gel|Gi|Go|Gra|Gri|Ka|Ko|Kla|Mar|Di|Mer|Mor|Oma|Re|Vel|Vash|Ver|Vla
+suffix=ash|kré|lsh|lin|rutin|shinar|rushi|ka|ash|ag|all|ash|slar|li|dian|ritos|rusté|shitt|nick|rath|ditt|kon|mad|tick|nir
+>>
+ female_name_generator= _ <<
+main={prefix}{suffix}|{prefix}{suffix} {short_name}
+prefix=Al|Ali|Ash|Aug|Auug|Da|De|Dem|Din|Ol|Oma|Orri|Oshi|Val|Ver|Vel|Vush
+suffix=en|nash|irt|glann|ll|ge|lin|nitt|tin|tar|lisk|rida|grra|sill|la|mell
+short_name=Mal|Ka|Emth|Dar|Eshi
+>>
#enddef
#define DWARVISH_NAMES
- male_names= _ "Aigaithas,Aigaithil,Aigaithing,Aigaithol,Aigalas,Aigaling,Aigalis,Aigalol,Aigalsil,Aigatas,Aigatis,Aigatlos,Aigatsil,Aigatsol,Aigatus,Aigcatas,Aigcatil,Aigcating,Aigcatis,Aigcatsil,Aigcatsol,Aigcatus,Aigdring,Aigdris,Aigdrlos,Aigdrsil,Aigdrsol,Aigduras,Aigdurlos,Aigdursol,Aigthaing,Aigthais,Aigthasil,Aigthaus,Alaithas,Alaithis,Alaithlos,Alaithol,Alaithsol,Alaithus,Alalas,Alalil,Alalol,Alalsol,Alalus,Alatas,Alatil,Alating,Alatlos,Alatsil,Alcatil,Alcatis,Alcatlos,Alcatsil,Aldras,Aldril,Aldring,Aldris,Aldrlos,Aldrol,Aldrsol,Alduras,Aldurlos,Aldurol,Althaas,Althail,Althalos,Althaol,Althasil,Althasol,Althaus,Anaithas,Anaithil,Anaithing,Anaithis,Anaithsil,Anaithus,Analil,Anallos,Analol,Analsil,Analus,Anatas,Anating,Anatis,Anatol,Anatsol,Ancatas,Ancatil,Ancatol,Ancatus,Andril,Andris,Andrlos,Andrus,Anduril,Andurol,Andursol,Andurus,Anthaas,Anthaing,Anthais,Anthaol,Anthasil,Anthasol,Anthaus,Augaithas,Augaithing,Augaithsil,Augaithus,Augalas,Augaling,Augalol,Augating,Augatlos,Augatol,Augatsil,Augatsol,Augcatas,Augcatil,Augcatis,Augcatol,Augcatsil,Augcatus,Augdras,Augdris,Augdrsil,Augdrus,Augduras,Augduril,Augduring,Augdurol,Augdursol,Augdurus,Augthail,Augthais,Augthalos,Augthaol,Dulaithil,Dulaithing,Dulaithlos,Dulaithsil,Dulaithsol,Dulalas,Dulaling,Dulalis,Dulalsil,Dulatil,Dulating,Dulatol,Dulatsol,Dulatus,Dulcatil,Dulcating,Dulcatlos,Dulcatol,Dulcatsil,Dulcatsol,Duldril,Duldris,Duldrlos,Duldrol,Duldrsil,Duldrus,Dulduras,Dulduring,Duldursil,Duldurus,Dulthalos,Dulthasil,Dulthasol,Dulthaus,Glamaithil,Glamaithis,Glamaithol,Glamaithsol,Glamalil,Glamaling,Glamalis,Glamallos,Glamalsil,Glamalus,Glamatil,Glamatus,Glamcatas,Glamcatil,Glamcating,Glamcatsil,Glamcatus,Glamdras,Glamdril,Glamdrlos,Glamdrsol,Glamduras,Glamduril,Glamduring,Glamduris,Glamdursol,Glamthaas,Glamthaol,Glamthasil,Glamthasol,Glamthaus,Glomin,Gomaithas,Gomaithil,Gomaithol,Gomaithsol,Gomalil,Gomalis,Gomalus,Gomatas,Gomatil,Gomating,Gomatis,Gomatlos,Gomatol,Gomcatil,Gomcatis,Gomcatlos,Gomdras,Gomdril,Gomdring,Gomdris,Gomdrol,Gomdrsil,Gomduris,Gomdurlos,Gomdursil,Gomdursol,Gomdurus,Gomthaas,Gomthalos,Gomthasol,Naraithil,Naraithing,Naraithol,Naraithsil,Naraithsol,Naraithus,Naralas,Naralil,Naralsil,Naralus,Naratlos,Naratol,Naratsil,Narcating,Narcatis,Narcatol,Narcatsil,Narcatsol,Nardras,Nardril,Nardring,Nardris,Nardrol,Nardrsil,Nardrsol,Nardrus,Narduras,Narduril,Nardurol,Narthalos,Narthaol,Pelaithas,Pelaithil,Pelaithing,Pelaithis,Pelaithlos,Pelaithol,Pelaithsil,Pelaithsol,Pelalil,Pelaling,Pelalis,Pelalsil,Pelalsol,Pelalus,Pelatil,Pelating,Pelatis,Pelatol,Pelatsil,Pelatus,Pelcating,Pelcatlos,Pelcatol,Pelcatsil,Peldras,Peldril,Peldrsol,Peldrus,Pelduril,Pelduring,Pelduris,Peldurol,Peldursol,Peldurus,Pelthaas,Pelthail,Pelthasil,Trithaithas,Trithaithil,Trithaithis,Trithaithlos,Trithaithol,Trithaithsil,Trithaithsol,Trithaithus,Trithalis,Trithalol,Trithatas,Trithatil,Trithatlos,Trithatsol,Trithcatlos,Trithcatsol,Trithcatus,Trithdril,Trithdring,Trithdris,Trithdrlos,Trithdrol,Trithdrsol,Trithdrus,Trithduril,Trithduring,Trithdurlos,Trithdurol,Trithdursil,Trithdurus,Triththaas,Triththail,Triththaing,Triththasol,Triththaus"
+ male_names= _ "Aigaithas,Aigaithil,Aigaithing,Aigaithol,Aigalas,Aigaling,Aigalis,Aigalol,Aigalsil,Aigatas,Aigatis,Aigatlos,Aigatsil,Aigatsol,Aigatus,Aigcatas,Aigcatil,Aigcating,Aigcatis,Aigcatsil,Aigcatsol,Aigcatus,Aigdring,Aigdris,Aigdrlos,Aigdrsil,Aigdrsol,Aigduras,Aigdurlos,Aigdursol,Aigthaing,Aigthais,Aigthasil,Aigthaus,Alaithas,Alaithis,Alaithlos,Alaithol,Alaithsol,Alaithus,Alalas,Alalil,Alalol,Alalsol,Alalus,Alatas,Alatil,Alating,Alatlos,Alatsil,Alcatil,Alcatis,Alcatlos,Alcatsil,Aldras,Aldril,Aldring,Aldris,Aldrlos,Aldrol,Aldrsol,Alduras,Aldurlos,Aldurol,Althaas,Althail,Althalos,Althaol,Althasil,Althasol,Althaus,Anaithas,Anaithil,Anaithing,Anaithis,Anaithsil,Anaithus,Analil,Anallos,Analol,Analsil,Analus,Anatas,Anating,Anatis,Anatol,Anatsol,Ancatas,Ancatil,Ancatol,Ancatus,Andril,Andris,Andrlos,Andrus,Anduril,Andurol,Andursol,Andurus,Anthaas,Anthaing,Anthais,Anthaol,Anthasil,Anthasol,Anthaus,Augaithas,Augaithing,Augaithsil,Augaithus,Augalas,Augaling,Augalol,Augating,Augatlos,Augatol,Augatsil,Augatsol,Augcatas,Augcatil,Augcatis,Augcatol,Augcatsil,Augcatus,Augdras,Augdris,Augdrsil,Augdrus,Augduras,Augduril,Augduring,Augdurol,Augdursol,Augdurus,Augthail,Augthais,Augthalos,Augthaol,Dulaithil,Dulaithing,Dulaithlos,Dulaithsil,Dulaithsol,Dulalas,Dulaling,Dulalis,Dulalsil,Dulatil,Dulating,Dulatol,Dulatsol,Dulatus,Dulcatil,Dulcating,Dulcatlos,Dulcatol,Dulcatsil,Dulcatsol,Duldril,Duldris,Duldrlos,Duldrol,Duldrsil,Duldrus,Dulduras,Dulduring,Duldursil,Duldurus,Dulthalos,Dulthasil,Dulthasol,Dulthaus,Glamaithil,Glamaithis,Glamaithol,Glamaithsol,Glamalil,Glamaling,Glamalis,Glamallos,Glamalsil,Glamalus,Glamatil,Glamatus,Glamcatas,Glamcatil,Glamcating,Glamcatsil,Glamcatus,Glamdras,Glamdril,Glamdrlos,Glamdrsol,Glamduras,Glamduril,Glamduring,Glamduris,Glamdursol,Glamthaas,Glamthaol,Glamthasil,Glamthasol,Glamthaus,Glomin,Gomaithas,Gomaithil,Gomaithol,Gomaithsol,Gomalil,Gomalis,Gomalus,Gomatas,Gomatil,Gomating,Gomatis,Gomatlos,Gomatol,Gomcatil,Gomcatis,Gomcatlos,Gomdras,Gomdril,Gomdring,Gomdris,Gomdrol,Gomdrsil,Gomduris,Gomdurlos,Gomdursil,Gomdursol,Gomdurus,Gomthaas,Gomthalos,Gomthasol,Naraithil,Naraithing,Naraithol,Naraithsil,Naraithsol,Naraithus,Naralas,Naralil,Naralsil,Naralus,Naratlos,Naratol,Naratsil,Narcating,Narcatis,Narcatol,Narcatsil,Narcatsol,Nardras,Nardril,Nardring,Nardris,Nardrol,Nardrsil,Nardrsol,Nardrus,Narduras,Narduril,Nardurol,Narthalos,Narthaol,Pelaithas,Pelaithil,Pelaithing,Pelaithis,Pelaithlos,Pelaithol,Pelaithsil,Pelaithsol,Pelalil,Pelaling,Pelalis,Pelalsil,Pelalsol,Pelalus,Pelatil,Pelating,Pelatis,Pelatol,Pelatsil,Pelatus,Pelcating,Pelcatlos,Pelcatol,Pelcatsil,Peldras,Peldril,Peldrsol,Peldrus,Pelduril,Pelduring,Pelduris,Peldurol,Peldursol,Peldurus,Pelthaas,Pelthail,Pelthasil,Trithaithas,Trithaithil,Trithaithis,Trithaithlos,Trithaithol,Trithaithsil,Trithaithsol,Trithaithus,Trithalis,Trithalol,Trithatas,Trithatil,Trithatlos,Trithatsol,Trithcatlos,Trithcatsol,Trithcatus,Trithdril,Trithdring,Trithdris,Trithdrlos,Trithdrol,Trithdrsol,Trithdrus,Trithduril,Trithduring,Trithdurlos,Trithdurol,Trithdursil,Trithdurus,Triththaas,Triththail,Triththaing,Triththasol,Triththaus"
+ name_generator= _ <<
+main={long_name}
+long_name={prefix}{centre}{suffix}|{prefix}{centre}{centre}{suffix}
+short_name={prefix}{suffix}
+prefix=Ai|Al|A|Du|Glam|Dul|Gom|Nar|Pel|Tri|Dun|Do|Bar|Er|Tim|Al|Du|Bu|Bur|Nor|Der|Ur|Gar
+suffix=sil|fur|bor|bus|bur|bor|gos|dor|rin|dur|ing|ras|this|tis|rol|sol|las|til|til|tol|los|rol|sol|ril|sil|as|us|lil|fur|mur|fur
+centre=lal|mal|ra|dur|thal|thas|ma|gal|thau|ga|ith|ma|cat|la|ral|dur|bur
+>>
#enddef
#define ELVISH_NAMES
male_names= _ "Amadrieriand,Amáril,Amelad,Ameldor,Amendel,Ameng,Amilmaldur,Amilmalith,Amilmandir,Amind,Amiol,Amiorion,Amithrarion,Amóldor,Amorfimir,Amorfir,Amowyn,Amulas,Amundil,Anán,Anebrin,Anebrir,Anémbor,Anénduil,Anerion,Anilad,Anil-Gawyn,Anilmambor,Anilmariand,Anior,Anithranduil,Anol,Anon,Anorfing,Anundil,Belán,Belandil,Belarandel,Belel,Belén,Belil-Gandil,Belilmand,Belilmang,Beliondil,Beliril,Belithraldor,Belithrawyn,Belólad,Belómir,Belondel,Belyrion,Cadriembor,Cadrieriand,Cálad,Caladrielas,Calándel,Caldur,Cáldur,Calebrindel,Calebrindir,Calénduil,Calil-Gandir,Calil-Gawyn,Calioriand,Caliril,Calónduil,Caloril,Cándir,Canduil,Caraldur,Carang,Célad,Celadrieriand,Celang,Celaral,Celarandil,Celáriand,Celebririon,Celelas,Celendel,Celér,Celilmalas,Celiondir,Celior,Celiorion,Celong,Celór,Celóril,Celorion,Celundir,Celuwyn,Celyndel,Cénduil,Cindil,Ciong,Cithralad,Cithraldur,Cithrand,Cithrandel,Cithraril,Col,Corfil,Corfildur,Cówyn,Cun,Cundir,Cylas,Delán,Delánd,Delandel,Delaraldur,Deláril,Delawyn,Deléng,Delilmaldor,Deliol,Delithrar,Deliwyn,Delóldor,Delorfilad,Delorfilith,Delorion,Delundil,Eäradriendel,Eäradrier,Eäránduil,Eäraralad,Eärebrindel,Eäréldor,Eäreng,Eärérion,Eärithrandil,Eäromir,Eärorfiriand,Eäryldur,Eäryriand,Eladrieng,Elálith,Elánd,Elándil,Elebrildor,Elebrindel,Elebriril,Elélas,Elémbor,Elemir,Elen,Elil-Garil,Elilmaldur,Eliomir,Eliondil,Elolas,Elólas,Elor,Elorfilad,Elradrien,Elralith,Elran,Elreldur,Elrilmand,Elrioldor,Elriolith,Elrithralith,Elrithranduil,Elrorfir,Elval,Elvandir,Elvaramir,Elváwyn,Elvebrind,Elvebrindel,Elvélith,Elvémir,Elverion,Elvil-Garion,Elvilmaldur,Elvilmaril,Elvioldur,Elvombor,Elvónduil,Elvorfimir,Elvorfiriand,Elvorfiril,Elvóriand,Elvund,Elyldor,Elyrion,Eowambor,Eowanduil,Eowar,Eowaraldor,Eowaran,Eowarar,Eowariand,Eowarion,Eowebrind,Eowémir,Eowil-Garion,Eowimbor,Eowiomir,Eowithrawyn,Eowóldur,Eoworfildor,Eowówyn,Eowylas,Fadriendel,Fandel,Farandir,Fáwyn,Fendel,Fer,Filman,Fioril,Fithraril,Forfilas,Fyrion,Gadriendil,Gadrieng,Galadrieldor,Galálad,Galálas,Galalith,Galar,Galelas,Galeldur,Galelith,Galémbor,Galithrariand,Galoldur,Galuldur,Galur,Galurion,Gambor,Gán,Ganduil,Garaldor,Gararil,Gelad,Géril,Gil-Gandel,Gil-Gang,Giombor,Githral,Githralad,Gladriendil,Glal,Glámbor,Glandil,Glarang,Glararil,Glilmal,Glimir,Glior,Glólas,Gloldor,Glómir,Glon,Glul,Golad,Gor,Gumbor,Gyl,Gymbor,Gyn,Harariand,Háriand,Hebril,Hemir,Hénduil,Hilas,Hil-Garion,Hilmariand,Hiong,Hirion,Hithrandel,Horfilad,Horfindel,Hundel,Hymir,Hyrion,Hywyn,Isadrieng,Isándir,Isarandel,Isarar,Iselas,Isér,Isilmandel,Isirion,Isithral,Isól,Isóndel,Isóng,Isorfilad,Isorfindir,Isuwyn,Isyndel,Legal,Legaran,Legémir,Legéril,Legilad,Legil-Gal,Legiondel,Legithralith,Legorfindil,Legorfirion,Legówyn,Legyl,Legyn,Linduilas,Lómadrieril,Lómarand,Lómariand,Lómebrilad,Lómebrind,Lómémbor,Lómilmaril,Lómiriand,Lómorfindil,Lómowyn,Madrieril,Maldur,Mánduil,Maraldur,Mebrin,Méng,Mérion,Miolith,Miomir,Mithrand,Mondir,Móndir,Morfilas,Morfin,Morfiriand,Mylith,Nadrieldor,Nalith,Nán,Nél,Nil-Galas,Nil-Galith,Nil-Gar,Nilmar,Nóndel,Norfildor,Norfilith,Norfindil,Norfindir,Numbor,Nyldur,Padrieriand,Padrieril,Pamir,Paraldor,Parariand,Pilmalad,Pindir,Pór,Porfildur,Pumbor,Pyldur,Rebrir,Réndir,Rilmandil,Rithrandil,Ról,Róldor,Roldur,Róldur,Rorfilad,Rorfindil,Rówyn,Ryn,Sadrielas,Sebrin,Sebriril,Sénd,Sil-Gal,Sólad,Sorfind,Sóriand,Tadriendir,Taral,Taraldur,Táriand,Tendel,Téwyn,Thradrieriand,Thrambor,Thraral,Threbring,Thrélad,Thréldur,Thril-Gamir,Thril-Gandir,Thril-Gar,Thrilmandel,Thrimir,Thrion,Thrithran,Throlas,Thrón,Thróng,Thrund,Thryriand,Til-Gan,Tilmalad,Tilmalas,Tinandir,Tinarambor,Tinarariand,Tinén,Tinil-Ganduil,Tinilmand,Tinilmawyn,Tinimir,Tinindil,Tinithrar,Tinoldor,Tinond,Tinorfind,Tinorfiriand,Tinóriand,Tinowyn,Tinun,Tinyl,Tion,Tolas,Torfildur,Tówyn,Tylad,Unadrieldor,Unadrier,Unál,Unalas,Unálas,Unaraldur,Unaril,Unárion,Unebrin,Unebrind,Uneldor,Unil,Unil-Gan,Uniolith,Unioril,Unólith,Unombor,Unóndel,Unondir,Unorfildor,Unorfiril,Unorfiwyn,Unulad,Uradrielas,Uradrierion,Urálas,Urálith,Urambor,Urér,Uril-Gambor,Urilmalith,Uróldor,Urorfildor,Urul,Urymir,Válad,Ván,Vándel,Vandir,Varalas,Vararion,Vebril,Vebrilas,Vebrinduil,Vel,Vilith,Vol,Vólas,Vóldur,Vondel,Vorfin,Vorfindil,Vulas,Vuldur,Vunduil,Vylas,Vyldor"
female_names= _ "Amadrielia,Amadrielindë,Amadriendra,Amadriewen,Amarang,Amebrilindë,Amedë,Améthien,Amewien,Amil-Gadith,Amil-Garith,Amilmadia,Amiolith,Amionia,Amithraniel,Amithrawien,Amiwen,Amodë,Amorfilith,Amorith,Amulia,Amuviel,Amuwen,Analia,Anang,Anaraclya,Anáthien,Anebriniel,Anilmarith,Aning,Aniorith,Anówien,Anundra,Anuthiel,Anuthien,Anylindë,Anythien,Anywien,Belaclya,Beladrielith,Beladriewen,Beladriewien,Belarania,Belaraviel,Belebrindra,Belendra,Beliolia,Belithraniel,Belithrawiel,Belithrawien,Belowen,Belulindë,Cádë,Cadriewen,Caladrieng,Calándra,Calang,Calánia,Calebriwien,Calewen,Calewiel,Calil-Galith,Calilmalith,Calithraclya,Calóniel,Calorfiniel,Calówien,Caluclya,Ceclya,Celadë,Celália,Celálindë,Celarandra,Celararith,Celárith,Celebriniel,Celebriviel,Celelith,Celéng,Celérith,Celidien,Celilith,Celindë,Celiodë,Celioniel,Celith,Celithradith,Celódith,Celorfilindë,Celorfing,Celorfiwien,Celówien,Celylia,Cethien,Cing,Cithralith,Cithrania,Cithrawen,Cólindë,Corfiviel,Cydia,Delararith,Delebrinia,Deléthien,Delil-Ganiel,Deliowen,Delithrathiel,Delóndra,Delorfilindë,Delorfithien,Deloviel,Delydien,Eäradriedien,Eärániel,Eärarawien,Eärélia,Eärenia,Eärewen,Eäréwiel,Eärilmadë,Eärilmathien,Eäriolith,Eärithrang,Eärorfiwien,Eärudë,Eladriedë,Eladrielia,Elarawiel,Elebrindra,Eledë,Elelith,Elil-Gang,Elilmalia,Elilmawien,Elithraclya,Elithradien,Elóndra,Elorfing,Elorfithien,Elradrierith,Elránia,Elrebridith,Elréthiel,Elrilindë,Elrilmandra,Elrilmathien,Elrithiel,Elrithradith,Elriwen,Elródith,Elrorfidia,Eluviel,Elvádia,Elvánia,Elvil-Gawien,Elvilmathiel,Elviniel,Elviondra,Elvithrang,Elvithrathien,Elvowien,Elvyniel,Elvyviel,Elynia,Elywen,Eowalia,Eowarawien,Eowathiel,Eowebridith,Eowedith,Eowidien,Eowil-Galindë,Eowilindë,Eowiowien,Eowylia,Eowyniel,Fadriedith,Fadrielia,Fadriendra,Fadrienia,Falindë,Fáthiel,Fathien,Fáwien,Feclya,Féthiel,Fil-Galia,Fil-Gathiel,Fil-Gawien,Filmaclya,Fioniel,Fódë,Fólindë,Fulindë,Gadrieclya,Gadrieviel,Galadriethien,Galándra,Galaraniel,Galebrilia,Galebrindra,Galédë,Galedien,Galéwiel,Galil-Gania,Galilmadia,Galiothiel,Galithrathien,Galólia,Galolindë,Galorfiwiel,Galothiel,Galowen,Galundra,Galyniel,Gathien,Gáviel,Gebririth,Gewen,Gil-Gawien,Gilia,Gioniel,Gioviel,Giowen,Githrania,Githrawiel,Glália,Glebrithien,Gléndra,Glilmadien,Glilmawiel,Glithiel,Gloclya,Glodith,Glorfilith,Gloviel,Glowiel,Goclya,Godien,Gólia,Golindë,Guviel,Harawiel,Haviel,Háwien,Héclya,Hedia,Helith,Hewen,Hil-Gania,Hiodë,Hiwien,Hodia,Hódia,Horfinia,Horfiwien,Hóthiel,Huclya,Hunia,Huthien,Hyclya,Hythiel,Hythien,Isadrieng,Isáwen,Isebridien,Isebrinia,Isendra,Iséng,Iseviel,Isil-Garith,Isilindë,Isithradë,Isithradien,Isithrarith,Isithrawiel,Isóthien,Legádë,Legadien,Legadrieclya,Legadriedë,Legadrieniel,Legaraclya,Legebrilia,Legelith,Legeng,Legéniel,Legethiel,Legidia,Legil-Galindë,Legilmadith,Legilmawiel,Legithralindë,Legithrandra,Legithrania,Legolith,Legondra,Legorfidë,Lómániel,Lómebriclya,Lómebriniel,Lómedia,Lómeniel,Lómiclya,Lómilindë,Lómilmathiel,Lómilmawiel,Lómithradë,Lómithrarith,Lómódë,Lómolith,Lómóndra,Lómorfing,Lómorith,Lómudia,Lómulindë,Lómuniel,Lómuthiel,Lómynia,Lómythien,Mádia,Madrieclya,Maraclya,Mebriwiel,Meclya,Medien,Mil-Gathiel,Mil-Gathien,Milindë,Milith,Miowen,Miowiel,Mithradë,Mithralindë,Módë,Módia,Moniel,Morfilindë,Munia,Myndra,Mywiel,Narania,Naraniel,Náviel,Nawen,Newen,Nil-Gang,Nilmadia,Niodien,Niolia,Niothien,Nithraniel,Nithrarith,Nowen,Nydith,Pádia,Padriedith,Paralindë,Parandra,Pawen,Pebridien,Pil-Gadia,Pil-Gadien,Pilindë,Pindra,Pong,Porfindra,Porfiwien,Póviel,Pulia,Puthien,Reniel,Réviel,Ril-Gawien,Rindra,Riothien,Róng,Rorfiviel,Sadrienia,Sadrierith,Sálindë,Sáng,Saradith,Sarandra,Sédith,Sendra,Sethien,Silmaclya,Silmathiel,Sioclya,Siorith,Sithrang,Sithrawen,Soniel,Sothiel,Sothien,Syniel,Tadrierith,Tang,Taradien,Tarathiel,Tathiel,Terith,Thradia,Thrália,Thraraviel,Threbriniel,Thredien,Thrérith,Thridith,Thrinia,Thrithradia,Thrithrandra,Thrithraniel,Throlith,Throng,Throthiel,Thrulith,Thruthien,Thryng,Til-Gandra,Tilmaclya,Tilmaviel,Tináclya,Tinadriethien,Tinálindë,Tinaraniel,Tinarathien,Tinawiel,Tinebrithiel,Tinerith,Tinil-Gania,Tinil-Gawiel,Tiniolith,Tinithrathiel,Tinóng,Tinorfilith,Tinorfithien,Tinudia,Tiorith,Tithrathien,Tówiel,Tuniel,Unadrieng,Unáthien,Unebridë,Unénia,Unil-Gadia,Unilmadia,Unindra,Uniodë,Uniolia,Uniong,Unionia,Unóndra,Unorfiwen,Unulindë,Unuviel,Unynia,Uraclya,Uradriedia,Uránia,Urárith,Urebriclya,Ureclya,Urilmadia,Urilmawiel,Uriolia,Urithralindë,Uruthien,Uryrith,Vadrierith,Vadrieviel,Vadriewen,Varawiel,Vebrithien,Vil-Gandra,Violindë,Viowiel,Vithrang,Vithraniel,Viwiel,Vódia,Vóng,Vorficlya,Vorfing,Vorfirith,Vorfiwiel,Vówien"
+ male_name_generator= _ <<
+main={generated_prefix}{consonnant}{suffix}|{prefix}{centre}{suffix}
+generated_prefix={starting_consonnant}{vowel}
+starting_consonnant=C|D|F|L|M|N|P|Qu|R|S|T|V
+vowel=a|e|i|o|ae|é|ë
+consonnant=n|l|r|m|s|v|th|nn
+prefix={prefix_vc}{vowel}|{prefix_cv}
+prefix_vc=Lon|Eon|Ad|Sar|Al|Tal|Tin|El|Leg|Or|Tir|Ol|Cál|Cán|Elv|Fan|Fad|Fith|Fil|Gal|Glad|Leg|Glar|Gli|Hár|Tad|Sór|Pyr
+prefix_cv=Ama|Ami|Be|Ca|Ga|Isi|Ha|He|Le|Ló|Ny|Ni|Ma|Thu|Thri|Ti|Unu|Ve|Va
+suffix=or|im|ian|in|ar|iel|as|eon|as|or|ion|al|and|ér|as|ir|el|al|ad|ael
+centre={short_centre}|{short_centre}|-{short_centre}|{short_centre}-
+short_centre=lol|febr|tom|lith|nal|lor|wón|rad|rien|mar|reb|riel|mal|ram|nil|nim|nol|bris|lad|rier|ra|fil|thran|man
+>>
+ female_name_generator= _ <<
+main={generated_prefix_v}{centre_v}{suffix_v}|{generated_prefix_c}{centre_c}{suffix_c}
+generated_prefix_v={starting_consonnant}{vowel}
+generated_prefix_c={starting_consonnant}{vowel}{consonnant}
+starting_consonnant=C|D|F|L|M|N|P|Qu|R|S|T|V
+vowel=a|e|i|o|ae|é|ë
+consonnant=n|l|r|m|s|v|th|p|d|f|t
+prefix_c=Val|Ol|Am|An|El|Fa|El|Glo|Hu|Le|Mil|Nil|Pin|Por|Mot|Mor|Thral|Leg|Nam|Nym|Sim|Len|Is|Thal
+prefix_v=La|Va|Tha|Ne|Ay|Ce|Fa|Phe|Ja|Que|Ma|Mi|Pa|Ri|Siu|Ga|Ca|De|Eä|Eo|No|Pó|Le|Ló|Isá|Pa|Sa|Ni|Ti|Uno|Uni|Vó|Gio
+suffix_v=thea|nia|lia|kea|ni|ith|niel|wiel|ra|dë|lya|thiel|nna|nne
+suffix_c=iel|ien|ya|a|ë|i|ia|ea
+centre_v=|{short_centre_v}
+short_centre_v=nna|lla|na|thi|saie|li|ma|lo|thra|ló|rá|bri|fi|mi|nio|wi|né|nu|wi
+centre_c=|{short_centre_c}
+short_centre_c=enn|all|an|ith|el|il|am|ol|arth|ól|ár|ir|if|im|ion|iw|én|un|iw
+>>
#enddef
# Very restricted phonotactics on these for a reason: Gryphons have beaks.
#define GRYPHON_NAMES
male_names= _ "Graa,Greaa,Gree,Kaaa,Kassshh,Kessshh,Korro,Kraa,Kuu,Kzaaa,Kzuuu"
female_names= _ "Kaasa,Kayya,Keyya,Kiira,Korra"
+ male_name_generator= _ <<
+main={prefix}{suffix}|{prefix}{centre}{suffix}
+prefix=Gr|Ka|Ke|Ko|Kr|Kz
+suffix=aa|eaa|ee|aaa|ssshh|rro|uu|uuu
+centre=arr|aash|eez|ozz
+>>
+ female_name_generator= _ <<
+main={prefix}{suffix}|{prefix}{centre}{suffix}
+prefix=Kaa|Ka|Ke|Kuu|Ko
+suffix=sa|yya|ra|rra
+centre=err|aash|eez|azz
+>>
#enddef
#define HUMAN_NAMES
male_names= _ "Addraecyn,Addraenvan,Addraer,Addraercyn,Addraryn,Addreddry,Addredry,Addregwyn,Addrenyc,Addreoddry,Addreoddyn,Addreonyc,Addreorcyn,Addreran,Addribryn,Addriddyn,Addrocyn,Addroryn,Addrunvan,Addrurcyn,Addryllyn,Addrynvan,Aethacyn,Aethadry,Aethaec,Aethaeran,Aethaeryn,Aethagwyn,Aethanry,Aetharcyn,Aethec,Aethellyn,Aethenvan,Aetheoc,Aetheollyn,Aetheonyc,Aetheorcyn,Aethercyn,Aetherraent,Aethibryn,Aethiddry,Aethircyn,Aethobryn,Aethoddyn,Aethonnyn,Aethuc,Aethudry,Aethugwyn,Aethun,Aethunry,Aethydry,Aethynyc,Blac,Bladoc,Blaec,Blaedry,Blanry,Blebryn,Bledoc,Blemyr,Blennyn,Blenvan,Bleollyn,Blercyn,Blidd,Bliddry,Blillyn,Blinvan,Blollyn,Blubryn,Blucyn,Bludry,Blullyn,Bluran,Blybryn,Blydd,Blygwyn,Blymyr,Blyr,Bucyn,Cac,Cadry,Caebryn,Caedry,Caeran,Caercyn,Car,Carac,Caraddry,Caradoc,Caraedry,Caraennyn,Cararyn,Caredd,Careddry,Caregwyn,Caren,Careobryn,Careogwyn,Careonvan,Careorraent,Careoryn,Carercyn,Caric,Cariddry,Carocyn,Caroddyn,Caror,Caroran,Carraent,Carudoc,Carullyn,Carygwyn,Caryn,Cebryn,Cemyr,Cennyn,Ceoc,Ceoddry,Ceoddyn,Ceomyr,Ceonnyn,Ceonry,Ceoryn,Cicyn,Cin,Cinry,Coc,Convan,Corcyn,Cubryn,Cunry,Curyn,Cynyc,Cyryn,Dac,Dadd,Dadoc,Daeddry,Daedoc,Daellyn,Demyr,Denvan,Deodd,Deollyn,Deonyc,Derraent,Dibryn,Dinnyn,Dircyn,Dycyn,Dyddyn,Gaddry,Gaebryn,Gaedry,Gaercyn,Gagwyn,Gan,Gannyn,Gar,Gecyn,Geddyn,Gegwyn,Geodry,Ginvan,Glacyn,Gladoc,Glaercyn,Glarraent,Gleddry,Gleoddyn,Gleran,Gliddyn,Glillyn,Glinry,Glircyn,Gloddry,Gloddyn,Glonry,Glonvan,Glumyr,Glun,Glunry,Glunvan,Glyc,Glydd,Glydoc,Glynry,Glynvan,Glyran,Goc,Gor,Gubryn,Gudd,Gullyn,Gumyr,Gur,Gwadoc,Gwaec,Gwaeddyn,Gwan,Gweddyn,Gwegwyn,Gwellyn,Gwennyn,Gwenyc,Gweocyn,Gweodd,Gweodoc,Gweodry,Gweogwyn,Gweoran,Gwidoc,Gwilam,Gwodd,Gwoddyn,Gwollyn,Gwor,Gwucyn,Gwudoc,Gwumyr,Gwuran,Gwybryn,Gwycyn,Gwyddry,Gwydoc,Gwymyr,Gwynnyn,Gydoc,Gyllyn,Gymyr,Haldar,Labryn,Ladoc,Laellyn,Lan,Lannyn,Laran,Lec,Lemyr,Lenvan,Leogwyn,Lercyn,Ligwyn,Lin,Liryn,Lonnyn,Lorraent,Luddry,Ludoc,Lunnyn,Lunvan,Lurraent,Mac,Maddyn,Maennyn,Manry,Manyc,Marcyn,Mec,Menvan,Meollyn,Meon,Meonnyn,Meorraent,Middry,Midry,Mimyr,Modd,Moddry,Monry,Moran,Morcyn,Mubryn,Mudoc,Mugwyn,Murcyn,Mydoc,Mygwyn,Myn,Myrraent,Owac,Owadd,Owaddyn,Owaecyn,Owaedry,Owain,Owarcyn,Owaryn,Owecyn,Owedry,Oweomyr,Oweor,Oweorcyn,Oweran,Owercyn,Owidry,Owinvan,Owinyc,Owodd,Owoddry,Owogwyn,Owollyn,Oworan,Oworcyn,Oworraent,Owuddry,Owuddyn,Owugwyn,Owur,Owyran,Rabryn,Radd,Ranvan,Rar,Reoddyn,Reodry,Rhaecyn,Rhaedoc,Rhaemyr,Rhaerraent,Rhanry,Rharcyn,Rhenry,Rhenvan,Rhenyc,Rheodd,Rheoddyn,Rheollyn,Rheor,Rheoran,Rheorraent,Rheran,Rherraent,Rhobryn,Rhodry,Rhollyn,Rhonvan,Rhubryn,Rhugwyn,Rhunyc,Rhur,Rhygwyn,Rhyllyn,Rhynyc,Rhyrcyn,Rhyrraent,Rocyn,Roddyn,Romyr,Ron,Ronry,Rubryn,Ruddry,Rumyr,Run,Rurcyn,Rybryn,Rycyn,Ryddry,Rygwyn,Rynnyn,Rynry,Saec,Saellyn,Saemyr,Saenvan,Saercyn,Sanyc,Saran,Sarraent,Secyn,Seddyn,Sedry,Sellyn,Sennyn,Seoddry,Seorcyn,Sercyn,Siddry,Simyr,Siryn,Sodd,Sodry,Soran,Suc,Sudd,Surcyn,Sydd,Syran,Syryn,Tabryn,Taec,Taedd,Taedoc,Taemyr,Taenvan,Taercyn,Tanry,Tarcyn,Teddyn,Tegwyn,Ten,Tennyn,Tenvan,Teobryn,Teoddyn,Teor,Teorcyn,Terraent,Tinry,Tinvan,Tiryn,Todd,Tudd,Tuddry,Tudoc,Tunvan,Turraent,Tyddyn,Vaddyn,Vaeddyn,Vaedry,Vaennyn,Varcyn,Ven,Vennyn,Veocyn,Veoddyn,Veodry,Veogwyn,Veomyr,Vinvan,Vinyc,Virraent,Vobryn,Vogwyn,Vonry,Vuddyn,Vugwyn,Vyc,Vygwyn,Vyrcyn,Yracyn,Yraec,Yran,Yrannyn,Yranvan,Yraryn,Yredd,Yreddyn,Yregwyn,Yreryn,Yrinvan,Yrirraent,Yroddry,Yrullyn,Yrumyr,Yrunnyn,Yrunvan,Yryllyn,Yrymyr,Yrynyc,Yryrcyn"
female_names= _ "Alabrylla,Alaebrylla,Alaeniver,Alalla,Alalonna,Alaryan,Aleacla,Aleaniver,Aleara,Alearka,Alena,Alengwen,Alilonna,Alingwen,Alolla,Alolonna,Alora,Alubrylla,Aluniver,Aluryan,Alussa,Alwcla,Alwllyra,Alwlyan,Alwna,Alybrylla,Alynoic,Alyra,Alyryan,Braedda,Brassa,Bravyan,Breabrylla,Breall,Brealla,Brealonna,Breana,Brell,Brellyra,Brera,Brerka,Breryan,Bricla,Brirka,Brobrylla,Brollyra,Brona,Bronoic,Brora,Brorka,Brungwen,Bruryan,Brwra,Brycla,Brynoic,Caella,Caena,Caengwen,Caevyan,Call,Calla,Cassa,Cealonna,Cera,Ceryan,Cibrylla,Cicla,Cinoic,Cira,Cissa,Clacla,Claella,Claelyan,Claenoic,Clalla,Clallyra,Clara,Clarka,Clavyan,Cleacla,Cleall,Clealyan,Cleana,Cleanoic,Clenoic,Clibrylla,Clill,Clillyra,Clilyan,Clinoic,Clissa,Clobrylla,Clollyra,Clona,Clongwen,Clungwen,Clurka,Cluvyan,Clwdda,Clwlla,Clwvyan,Clydda,Clylla,Cora,Coryan,Cucla,Cudda,Curyan,Cwdda,Cwlonna,Cwngwen,Cwvyan,Cydda,Cylla,Cyllyra,Cylyan,Cyniver,Cyvyan,Daedda,Daelyan,Daengwen,Daenoic,Dalla,Dallyra,Dangwen,Dara,Dassa,Deanoic,Deassa,Della,Devyan,Dicla,Diniver,Dissa,Dollyra,Dullyra,Dulonna,Dwbrylla,Dwdda,Dwna,Dwnoic,Dwra,Dybrylla,Dydda,Dyssa,Elacla,Elaedda,Elaell,Elaelonna,Elaessa,Elaevyan,Elallyra,Elalonna,Elara,Elavyan,Elealla,Eleanoic,Elearka,Elenoic,Elerka,Elivyan,Elulonna,Elurka,Elwllyra,Elwlonna,Elwngwen,Elwra,Elycla,Elyllyra,Elyngwen,Elyniver,Elyrka,Gwaera,Gwaessa,Gwangwen,Gweacla,Gwedda,Gwerka,Gwicla,Gwirka,Gwobrylla,Gwoll,Gwona,Gwongwen,Gwonoic,Gworyan,Gwullyra,Gwussa,Gwwcla,Gwwna,Gwwvyan,Gwycla,Gwydda,Heldra,Jacla,Jaena,Jaerka,Jaevyan,Jalyan,Jana,Jarka,Jassa,Jeabrylla,Jealla,Jeanoic,Jeniver,Jiryan,Jissa,Joll,Jolla,Jona,Jongwen,Jonoic,Jora,Jorka,Jovyan,Judda,Jull,Julonna,Jura,Jwll,Jwlyan,Jycla,Jyniver,Jynoic,Jyrka,Jyvyan,Laeniver,Laenoic,Laeryan,Langwen,Larka,Lassa,Lealonna,Lealyan,Ledda,Lelonna,Lelyan,Lengwen,Lerka,Lessa,Lidda,Lill,Lina,Lirka,Liryan,Livyan,Locla,Lodda,Lollyra,Lolonna,Lulla,Lulyan,Lungwen,Lunoic,Luryan,Lwcla,Lwlla,Lwnoic,Lwryan,Lycla,Lylla,Lylyan,Lyna,Lynoic,Maecla,Maeniver,Mavyan,Meacla,Mealyan,Meana,Meangwen,Meanoic,Medda,Melonna,Mengwen,Meniver,Meradda,Meraecla,Meraelyan,Merall,Merallyra,Meralonna,Merana,Meranoic,Merealonna,Mereangwen,Mereaniver,Merebrylla,Merella,Merengwen,Meressa,Merilyan,Merina,Merinoic,Merissa,Merivyan,Merolla,Merolyan,Merona,Meroniver,Merubrylla,Merudda,Merurka,Merwlla,Merwnoic,Merwryan,Merydda,Merylyan,Messa,Milonna,Molyan,Moniver,Mossa,Mudda,Mullyra,Mulyan,Muryan,Mwbrylla,Mwlyan,Mwngwen,Mwnoic,Mycla,Myll,Mylla,Myra,Myvyan,Nabrylla,Naebrylla,Naecla,Naell,Nalyan,Nangwen,Nealla,Neallyra,Nealonna,Neavyan,Nera,Nessa,Ninoic,Niryan,Nivyan,Nobrylla,Nolla,Nonoic,Norka,Noryan,Nucla,Nulla,Nulyan,Nungwen,Nuvyan,Nwllyra,Nwryan,Nwvyan,Nybrylla,Nyll,Nylyan,Nyryan,Nyssa,Nyvyan,Raebrylla,Raera,Raerka,Ralonna,Rara,Rarka,Rassa,Reacla,Realla,Reana,Reangwen,Rella,Relyan,Rengwen,Rerka,Revyan,Rilonna,Rilyan,Rirka,Rora,Rucla,Ruryan,Rwdda,Rwlla,Rwllyra,Rwlonna,Rwngwen,Rybrylla,Ryna,Ryngwen,Saell,Saellyra,Saeniver,Saerka,Saessa,Sallyra,Sanoic,Sara,Sassa,Searka,Sena,Senoic,Sera,Silonna,Sira,Siryan,Sona,Sorka,Subrylla,Sull,Sulonna,Sulyan,Sura,Sussa,Swlla,Swlyan,Swngwen,Swnoic,Swvyan,Syllyra,Sylyan,Syssa,Ysacla,Ysaenoic,Ysaerka,Ysanoic,Yseacla,Ysealonna,Ysealyan,Ysedda,Ysell,Yselonna,Ysilyan,Ysinoic,Ysodda,Ysongwen,Ysonoic,Ysura,Yswniver,Ysycla,Ysylla,Ysylyan,Ysyrka,Ysyssa"
+ male_name_generator= _ <<
+main={generated_prefix_c}{suffix_c}|{generated_prefix_v}{suffix_v}|{prefix_c}{centre_c}{suffix_c}|{prefix_v}{centre_v}{suffix_v}
+generated_prefix_c={starting_consonnant}{vowel}{consonnant}|{starting_vowel}{consonnant}
+generated_prefix_v={starting_consonnant}{vowel}|{starting_vowel}
+starting_consonnant=B|C|D|G|H|L|M|R|Rh|S|T|V
+starting_vowel=A|E|I|Y|Ae
+vowel=a|e|i|o|u|y|eo|ae
+consonnant=w|l|d|n|r|rc|ll|nn|dd|th
+prefix_c=Add|Den|Derr|Gum|Mad|Mar|Ow|Tedd|T{vowel}n|Var|Vin|Vob|Vug|Yr|Rhyr
+prefix_v=Ae|Bl{vowel}|C{vowel}|D{vowel}|Gl{vowel}|G{vowel}|Gw{vowel}|Ha|L{vowel}|M{vowel}|R{vowel}|Rh{vowel}|S{vowel}|S{vowel}|T{vowel}|V{vowel}
+suffix_c=yn|er|yc|ec|oc|yr|in|aent
+suffix_v=ry|ryn|ran|lyn|van|nyc
+centre_c=redd|reor|og|thyn
+centre_v=rae|ra|thar|gwy
+>>
+ female_name_generator= _ <<
+main={generated_prefix_c}{suffix_c}|{generated_prefix_v}{suffix_v}|{prefix_c}{centre_c}{suffix_c}|{prefix_v}{centre_v}{suffix_v}
+generated_prefix_c={starting_consonnant}{vowel}{consonnant}|{starting_vowel}{consonnant}
+generated_prefix_v={starting_consonnant}{vowel}|{starting_vowel}
+starting_consonnant=B|C|D|G|H|L|M|R|Rh|S|T|V
+starting_vowel=A|E|I|Y|Ae
+vowel=a|e|i|o|u|y|eo|ae
+consonnant=w|l|d|n|r|rc|ll|nn|dd|th
+prefix_c=Al|El|Mer|Mil|Rer|Ys|M{vowel}r|M{vowel}l
+prefix_v=A|Br{vowel}|Cl{vowel}|C{vowel}|D{vowel}|Gw{vowel}|He|J{vowel}|L{vowel}|M{vowel}|N{vowel}|R{vowel}|S{vowel}
+suffix_c=yan|oic|ell|yll
+suffix_v=wyn|nna|lla|ra|la|wyan|ssa|ka|ven
+centre_c=il|ing|ol|ur|ung|ean|eal|ong|al|iv
+centre_v=na|lla|na|ry|li|ni|ri|rae|bry
+>>
#enddef
#define KHALIFATE_NAMES
male_names=_ "Aban,Abbas,Abbud,Abdul-ʿAdl,Abdul-Ahad,Abdul-Alim,Abdul-Aliyy,Abdul-Azim,Abdul-Aziz,Abdul-Badi,Abdul-Baʿith,Abdul-Baqi,Abdul-Bari,Abdul-Barr,Abdul-Basir,Abdul-Basit,Abdul-Fattah,Abdul-Ghaffar,Abdul-Ghafur,Abdul-Ghani,Abdul-Hadi,Abdul-Hafiz,Abdul-Hakam,Abdul-Hakim,Abdul-Halim,Abdul-Hamid,Abdul-Haqq,Abdul-Hasib,Abdul-Hayy,Abdul-Jabbar,Abdul-Jalil,Abdul-Karim,Abdul-Khabir,Abdul-Khaliq,Abdul-Latif,Abdul-Malik,Abdul-Majid,Abdul-Matin,Abdul-Mubdiʾ,Abdul-Mughni,Abdul-Muhaimin,Abdul-Muhsi,Abdul-Muhyi,Abdul-Muʿid,Abdul-Muʿizz,Abdul-Mujib,Abdul-Mumin,Abdul-Muqaddim,Abdul-Muqtadir,Abdul-Musawwir,Abdul-Mutaʿal,Abdul-Nafi,Abdul-Nasser,Abdul-Nasir,Abdul-Nur,Abdul-Qadir,Abdul-Qahhar,Abdul-Qawi,Abdul-Qayyum,Abdul-Quddus,Abdul-Rafi,Abdul-Rahim,Abdul-Rahman,Abdul-Rashid,Abdul-Raʿuf,Abdul-Razzaq,Abdul-Shakur,Abdul-Tawwab,Abdul-Wadud,Abdul-Wahhab,Abdul-Wahid,Abdul-Wajid,Abdul-Wakil,Abdul-Wali,Abdul-Waliy,Abdul-Warith,Abdul-Zahir,Abdullah,ʿAbid,ʿAbidin,Abu Bakr,Aby al-Khayr,Adil,Adham,Adib,ʿAdli,ʿAdnan,ʿAfif,Ahmad,ʿAjib,ʿAkif,Akil,Akram,Alaʾ,Alaʾ al-Din,Alʿ Abbas,Aladdin,al-Bara,al-Hakam,al-Harith,Alhasan,Alhusain,Ali,Alim,Almahdi,al-Safi,Altaf,Altair,al-Tayyib,al-Tijani,al-Tufail,Amid,ʿAmid,Amin,Amir,ʿAmir,Amjad,ʿAmmar,ʿAmro,Anas,Anis,ʿAntarah,Anwar,ʿAqil,Arfan,Arif,ʿArif,Asad,Asʿad,Asadel,Ashraf,Asif,ʿAsim,Aswad,Ataʿ,Ataʿ Allah,Ataʿ al-Rahman,Athil,Athir,ʿAtif,ʿAwad,ʿAwf,Aws,Awwab,Ayham,Ayman,Ayser,Ayyub,Aza,ʿAzab,Azhar,Azim,ʿAziz,ʿAzzam,Badi,Badi al-Zaman,Badr,Badr al-Din,Badri,Bahaʿ,Bahiyy al-Din,Bahij,Bahir,Bakr,Bakri,Baligh,Bandar,Barakah,Barir,Bashshar,Basil,Basim,Bassam,Bayezid,Bayhas,Bilal,Bishr,Boulos,Budail,Burhan,Bushr,Butrus,Dabir,Dani,Darwish,Daʿud,Dhakir,Dhakiy,Dhakwan,Dhul Fiqar,Dirar,Diya,Diya al-Din,Duqaq,Fadi,Fadil,Fadl,Fadl Allah,Fahd,Fahad,Fahmi,Faisal,Faʿiz,Fakhir,Fakhr al-Din,Fakhri,Fakih,Falah,Falih,Faraj,Farhan,Farid,Fariq,Fariq,Faris,Faruq,Fath,Fathi,Fatih,Fatin,Fawwaz,Fawzan,Fawzi,Fayyad,Ferran,Fida,Fikri,Firas,Fuʿad,Fudail,Gamal,Ghayth,Ghali,Ghalib,Ghanim,Ghassan,Ghawth,Ghazwan,Ghiyath,Habbab,Habib,Haddad,Hadi,Hafiz,Hakem,Hakim,Halim,Hamal,Hamas,Hamdan,Hamdi,Hamid,Hamim,Hamzah,Hana,Hanaʾi,Hanbal,Hani,Hanif,Hannad,Haris,Harith,Harun,Hashim,Hassan,Hatim,Haydar,Haytham,Hayyan,Hazim,Hilal,Hilmi,Hisham,Hud,Hudad,Hudhafah,Hudhayfah,Humam,Hussein,Husam,Husam al-Din,Ibrahim,ʿId,Idris,Ihsan,Ihtisham,ʿIkrimah,Ilias,ʿImad,Imad al-Din,Imran,Imtiyaz,Inʿam,Iqbal,ʿIrfan,ʿIsa,ʿIsam,Ishaq,Ismaʿil,Iyad,Iyas,Izz al-Din,Jabbar,Jabr,Jabir,Jad Allah,Jaʿfar,Jal,Jalal,Jalal al-Din,Jalil,Jamal,Jamal al-Din,Jamil,Jarir,Jasim,Jaul,Jaun,Jawad,Jawdah,Jawhar,Jibran,Jibril,Jubair,Jul,Jumah,Junayd,Juwain,Kadar,Kadin,Kadir,Kahil,Kaliq,Kamal,Kamil,Karam,Kardal,Karif,Karim,Kasib,Kasim,Katib,Kazim,Khalaf,Khaldun,Khalid,Khalil,Khalil al-Allah,Khalis,Khatib,Khair al-Din,Khairi,Khoury,Khulus,Khuzaymah,Kutaiba,Labib,Lablab,Latif,Layth,LuʿayLubayd,Luqman,Lut,Lutfi,Maʿd,Madani,Mahbub,Mahdi,Mahfuz,Mahir,Mahjub,Mahmud,Mahrus,Maimun,Majd,Majdy,Majd al-Din,Majid,Makin,Malik,Mamduh,Maʿmun,Maʿin,Mandhur,Mansur,Marghub,Marid,Maʿruf,Marwan,Marzuq,Mashʿal,Mashhur,Masrur,Masʿud,Masun,Maysarah,Mazhar,Mazin,Mehmed,Mihran,Mihyar,Mikaʾil,Miqdad,Misbah,Mishʿal,Miyaz,Muʾadh,Muʾawiyah,Muʾayyad,Mubarak,Mubin,Mudar,Muddaththir,Mufid,Muflih,Muhab,Muhayr,Muhammad,Muhanna,Muhannad,Muhib,Muhibb,Muhsin,Muhtadi,Muhyi al-Din,Muʿin,Muʿizz,Mujab,Mujahid,Mukarram,Mukhlis,Mukhtar,Mulham,Mulhim,Muʿmmar,Muʿmin,Mumtaz,Munahid,Mundhir,Munib,Munif,Munir,Muʿnis,Munjid,Munsif,Muntasir,Murad,Murid,Murshid,Murtada,Musa,Musʿab,Musaʿid,Mushtaq,Muslih,Muslim,Mutafa,Mutaʾ,Muʿtasim,Mutawalli,Muʿtazz,Muthanna,Muti,Muwaffaq,Muyassar,Muzaffar,Mussammil,Nabhan,Nabighah,Nabih,Nabil,Nadhir,Nadim,Nadir,Nafiʾ,Nahid,Naʾil,Naʾim,Naji,Najib,Najid,Najjar,Najm al-Din,Naʿaman,Namir,Nashʿah,Nashʿat,Nashwan,Nasib,Nasih,Nasim,Nasir,Nasir al-Din,Nasr,Nasri,Nasuh,Nawaf,Nawfal,Nayif,Nazih,Nazim,Nazmi,Nibras,Nidal,Nijad,Nimr,Nizar,Nuʿaym,Nuh,Nuhayd,Numair,Nuʿman,Nur al-Din,Nuri,Nusrah,Nusrat,Omar,Orhan,Osman,Qasim,Qays,Qudamah,Qusay,Qatadah,Qutaybah,Qutb,Qutuz,Rabah,Rabi,Radi,Rafi,Rafid,Rafiq,Raghib,Rahman,Raʿid,Raʿif,Rais,Rajaa,Rajab,Raji,Rajih,Rakin,Rami,Ramih,Ramiz,Ramzi,Rani,Rashad,Rashid,Rasil,Rasin,Rasmi,Rasul,Ratib,Raʿuf,Rayhan,Rayyan,Razin,Ridha,Ridwan,Rihab,Riyad,Rizq,Ruhi,Rushd,Rushdi,Ruwayd,Saad,Saʿadah,Sab,Sabih,Sabir,Sabri,Saʿd,Saʿd al-Din,Sadad,Sadid,Sadiq,Saʿdun,Saʿid,Safi,Safiy,Safiy al-Din,Safuh,Safwah,Safwat,Safwan,Sahib,Sahir,Sahl,Saʾib,Saif,Saif al-Din,Sajid,Sajjad,Sakhr,Salah,Salah al-Din,Salamah,Salih,Salim,Salman,Sami,Samih,Samir,Samman,Saqr,Sariyah,Sati,Saud,Sayyid,Shaʿban,Shadi,Shadin,Shafi,Shafiq,Shahid,Shahin,Shahir,Shakib,Shakir,Shams al-Din,Shamal,Shamil,Shamim,Sharaf,Sharif,Shawqi,Shihab,Shihab al-Din,Shihad,Shuʿayb,Shukri,Shumayl,Siddiq,Sinan,Siraj,Siraj al-Din,Sofian,Subhi,Sufyan,Suhayb,Suhayl,Suhaym,Sulaiman,Sumrah,Suraqah,Suʿud,Tahir,Tahsin,Taym Allah,Taj,Taj al-Din,Talal,Talib,Tamim,Tamir,Tamam,Tammam,Taqiy,Tarif,Tariq,Taslim,Tawfiq,Tawhid,Taymullah,Taysir,Tayyib,Thabit,Thamir,Thaqib,Thawab,Thawban,ʿUbaidah,Ubaid,Ubayy,ʿUdayl,ʿUday,ʿUmar,Umarah,Umair,ʾaUrwah,Usaym,Usama,ʿUtbah,Uthal,Uthman,Waddah,Wadi,Wadid,Wafiq,Wahab,Wahhab,Wahid,Waʾil,Wajdi,Wajid,Wajih,Wakil,Walid,Walif,Waliy Allah,Waliy al-Din,Waqar,Waqqas,Ward,Wasif,Wasil,Wasim,Wazir,Yahya,Yaman,Yaʿqub,Yasar,Yasin,Yasir,Yazan,Yazid,Yunus,Yushua,Yusri,Yusuf,Zafar,Zafir,Zahid,Zahir,Zayd,Zaim,Zayn,Zarif,Zakarriya,Zaki,Zakwan,Ziyad,Zubayr,Zuhayr"
+ name_generator= _ <<
+main={name_long}|{prefix}{suffix}|{name_mid}{connector}{name_mid}
+name_mid={prefix}{suffix}|{name_short}
+name_long={prefix}{suffix}|{prefix}{centre}{suffix}
+name_short=Din|Sif|Din|Taj|Sud|Ali|Lut|Nuh|Qays|Nimr|Jad|Bushr|Lut|Maʿd|Nur|Fadl
+prefix=Ab|Bas|Fat|Gha|Al|Ba|Ja|Ha|Mu|Ra|Raz|Abi|Am|La|ʿAj|Ala|ʿAk|Fa|Du|Im|Ju|Mun|Ma|Ni|Ji|Mu|Lab|Luf|Mih|Mi|Qu|Tal|Ta|Tha|Za|Zi|Yas|Wa|Su|Qa|ʿIkri|Lu|Su|Osa|Rag|Saf|Da|Fay|Nib|Nash
+suffix=af|al|lih|bair|sur|bi|lah|at|sim|ma|ih|yl|iq|raj|mam|man|ya|zid|riya|ail|air|ah|en|in|ayd|ud|rah|wah|nan|as|ir|ba|ni|yad|ras|zuq|hid|mal|kib
+connector= al-| bin | ibn
+centre=ʿ|{centre_syllabe}
+centre_syllabe=hi|sa|kar|da|na|ja|tay|ki|hai|saw
+>>
#enddef
#define LIZARD_NAMES
male_names= _ "Amprixta,Anexir,Anitraz,Arix,Axiz,Bzz’Kza,Chamil,Cleezi,Clezz,Fazzis,Fizztrax,Flixta,Flizzil,Frikes,Frizzle,Hasz,Heffez,Hertrazzir,Hesz,Hezzir,Hezzis,Hix,Inexis,Irix,Jezzix,Jizz,Kaliez,Kepzs,Kernix,Kersezz,Kertrasz,Kerx,Kerxenix,Kezz,Klexaz,Klezyx,Krarax,Krenarex,Krex,Krinex,Krisess,Laizix,Lazki,Lixeez,Merax,Mexiss,Moxanzz,Naxisz,Nix,Pekzs,Plaxis,Plesix,Presch,Sailik,Salanix,Salik,Sandix,Saprazz,Satras,Skalix,Skandix,Skazix,Skeely,Skeezix,Sklizle,Skrez,Slizilx,Sprizz,Ssexur,Ssizer,Ssorix,Sszasz,Sterizz,Talerez,Tarex,Tarnix,Tezzaz,Tirasch,Tirax,Tirix,Trezz,Venezz,Vriss,Waks,Xaffrasz,Xartrez,Xasz,Xaztex,Xerxix,Xirasz,Xirr,Xirtras,Xirtrez,Xirz,Zandler,Zedrix,Zilrix,Zizzasz,Zslap,Zzalkz,Zzupde"
+ name_generator= _ <<
+main={prefix}{suffix}|{prefix}{centre}{suffix}
+prefix=Am|An|Ar|Bzz|Cha|Clee|Fa|Fi|Fli|Fri|Ha|He|In|Ir|In|Ka|Ke|Jezz|Ji|Ka|Ke|Lo|Ma|Ox|Po|Sa|Se|Li|Me|Na|Pre|Ska|Sse|Ssi|Sto|Ste|Szi|Sza|Ti|Ve|Vri|Xa|Xe|Xi|Zan|Zil|Zzu
+suffix=ta|ir|az|ix|za|trax|il|le|esz|izs|ezz|irr|asch|ez|is|iss|azz
+centre=ix|’Kza|tra|na|an|ex|ssa|zzi|’Usz
+>>
#enddef
#define MERMAN_NAMES
male_names= _ "Absu,Abzu,Aigaion,Alastyn,Apalala,Apam,Apsu,Aremata,Atlahua,Atlaua,Barinthus,Dhakhan,Dylan,Elcmar,Ember,Enki,Faro,Habaek,Ikatere,Jamm,Jin,Kinilau,Kulullu,Labuna,Laut,Lir,Llyr,Ludd,Makara,Maui,Melicertes,Mimir,Natat,Nechtan,Neptune,Nereus,Nethuns,Njord,Nuada,Nudd,Nudimmud,Nun,Oceanus,Okeanos,Phorcys,Pontus,Popoa,Poseidon,Proteus,Raja,Rau,Rorua,Ryujin,Scylla,Sinilau,Sisiutl,Tagaloa,Tanaoa,Tangaloa,Tangaroa,Thaumas,Tikitiki,Tini,Tinilau,Tinirau,Toniwha,Triton,Vizi,Vodnik,Vourukasa"
female_names= _ "Aglaopheme,Amphitrite,Aphrodite,Ariel,Atargatis,Calypso,Delphine,Derceto,Diktynna,Electra,Galatea,Himeropa,Jengu,Leucosia,Ligia,Lori Lamaris,Mama Wata,Marina,Miranda,Miriam,Molpe,Parthenope,Pelagia,Pisinoe,Rân,Sedna,Stella Maris,Thelxiepia,Tirgata,Vatea,Ved-Ava,Veen emo,Vete-ema"
+ male_name_generator= _ <<
+main={prefix}{suffix}|{prefix}{centre}{suffix}
+prefix=A|Ai|Apa|Bar|Atla|Dha|El|Fa|Ja|La|Ku|Li|Ma|Me|Mi|Na|Ne|Njo|Nua|Nu|Oce|Okre|Phor|Po|Pro|Ra|Ro|Ryu|Scy|Si|Ta|Thau|Ti|Vi|Tri|Vo|Vou
+suffix=su|ion|la|ta|ua|mar|re|lau|lu|na|yr|ra|tes|nus|teus|tes|tan|mas|ki|ni|lau|nik|sa|loa|roa
+centre=la|ma|ri|sei|te|ka|li|cer|tu|ni|ki|na|ga|si
+>>
+ female_name_generator= _ <<
+main={prefix}{suffix}|{prefix}{centre}{suffix}
+prefix=Agla|Amphi|A|Ca|Del|Der|Di|El|Ga|Je|Leu|Li|Lo|Ma|Wa|Ma|Mi|Mo|Par|Pel|Pi|Se|Ste|Ma|The|Ti|Va|Ve
+suffix=me|pe|gia|noe|dna|la|ris|ta|tea|va|mo|pe|riam|riel|na|ra|tea
+centre=ophe|phri|tri|phro|di|si|xie|ce|ty|la|me|ro|co|mar|ran|then|la|ga
+>>
#enddef
#define NAGA_NAMES
male_names= _ "Abraxas,Aleiss,Amail,Axmail,Blanal,Bleii,Blo,Bress,Briss,Gaxmol,Griam,Griss,Grissileii,Hailoss,Hainoss,Harxos,Huzel,Inaloss,Ineii,Issal,Klezel,Kras,Krezkps,Kzap,Lamaiss,Lameii,Lexpek,Liness,Lobor,Maissol,Malinos,Milbor,Mileii,Nildloss,Oxpeii,Poniaz,Psell,Pson,Pzakp,Reii,Sassal,Saxil,Saxrireii,Sekol,Silas,Skell,Skepz,Slell,Snol,Soill,Sorkol,Srell,Trixoz,Vilail,Vissal,Vlanis,Xabrak,Xamalel,Xinas,Xnamos,Xopkon,Zalsp,Zlek,Zpsek,Zsekp"
female_names= _ "Aliasse,Amailis,Axmailia,Blai,Blanalai,Bli,Bliana,Brassas,Brissal,Gaxmail,Griama,Grissa,Grissilai,Haila,Haina,Harxias,Huzi,Inai,Inalai,Issalai,Klez,Kras,Krezkps,Kzap,Lamai,Lamaissa,Lexpek,Liabra,Lilin,Linassa,Maissa,Malina,Mila,Milbra,Nildlasi,Oxpel,Poniazal,Psal,Psen,Pzakp,Riaa,Sall,Sassalia,Saxiala,Saxririaa,Sek,Skal,Skepz,Sla,Snelia,Srak,Sral,Szak,Trixzed,Vilaila,Vissalai,Vlanissa,Xabrak,Xamalia,Xina,Xinasia,Xnamas,Xopkne,Zalsp,Zlek,Zpsek,Zsekp"
+ male_name_generator= _ <<
+main={prefix}{suffix}
+prefix=Abra|Ale|Ama|Ax|Bla|Ble|Bre|Bri|Gri|Hai|Har|Hu|Ine|Kle|Krez|Lam|Lin|Lob|Mai|Lal|Nild|Pon|Pse|Pza|Sa|Se|Sle|So|Sor|Tri|Vi|Vla|Xa|Xi|Xna|Za|Zle|Zse
+suffix=iss|ail|nal|eii|mol|loss|noss|xos|sal|zel|kps|pek|ness|or|sol|peii|iaz|on|sal|ol|kil|oz|ail|al|nis|rak|lel|nas|kon|ekp
+>>
+ female_name_generator= _ <<
+main={prefix}{suffix}
+prefix=Ali|Ama|Ax|Bla|Bli|Bra|Bri|Gax|Gri|Hai|Har|Hu|Ina|Iss|Krez|Kzap|Lam|Lex|Li|Lin|Mai|Mu|Nil|Ox|Pon|Pza|Ri|Sal|Sax|Sek|Snel|Sra|Trix|Vil|Vis|Blan|Xab|Xam|Xi|Xnam|Xop|Zal|Zle|Zse
+suffix=asse|mailia|ilis|ana|ama|ssa|ssilai|zi|xias|lai|maissa|bra|lin|lina|na|bra|aa|lia|lai|laila|na|pkne|alsp|ekp
+>>
#enddef
#define OGRE_NAMES
male_names= _ "Akoark,Akort,Akzalk,Arkarm,Barkuk,Blokkar,Borkuk,Bukkak,Bulruk,Corkkar,Delkkak,Garkuk,Gnukk,Goruk,Grak,Gurk,Gurm,Kalknix,Karak,Karbuk,Kargnak,Karterak,Kayrak,Kelkrar,Kerta,Kilkrar,Kingrok,Kirk,Klud,Kokkan,Kolk,Komak,Korgnak,Kork,Koruck,Kramak,Krog,Krukrak,Krumuk,Kuknuk,Kurkur,Kurmak,Makron,Markaak,Markuk,Merknik,Nargak,Olk,Orkut,Reknak,Takolak,Trabuk,Trakkon,Urkar,Urkark"
+ name_generator= _ <<
+main={prefix}{suffix}
+prefix=Ak|Ar|Bar|Blok|Bor|Bul|Cork|Del|Gar|Gnu|Gra|Gru|Gu|Kal|Kar|Kay|Kel|Ker|Kil|King|Kor|Kru|Kur|Mar|Mer|Nal|Trak|Urk
+suffix=ark|ort|alk|arm|kuk|kak|ukk|nak|ta|k|rok|rar|kon|gak|nik
+>>
#enddef
#define ORCISH_NAMES
male_names= _ "Badush,Bagar,Bagdish,Barag,Barbag,Bart,Bashnak,Bidish,Bidush,Bik,Bilg,Bilo,Binak,Bink,Biol,Birt,Bogar,Bogdish,Bogdush,Bogor,Bok,Bolg,Bong,Borg,Bork,Bort,Boshnak,Budush,Bugdish,Buk,Bunak,Bung,Bunk,Burag,Burg,Burk,Buurk,Eradash,Eradish,Eragdish,Eragdush,Eragor,Eranak,Erang,Erarag,Erarg,Erart,Erigdush,Erik,Erinak,Eriol,Erirag,Erirbag,Erirg,Erirt,Erishnak,Eriurk,Erogdish,Erogdush,Erok,Erong,Eronk,Erorbag,Erudish,Erudush,Erugar,Erugdush,Erulo,Erunk,Eruol,Erurag,Eruurk,Gadash,Gagar,Gagdush,Gagor,Galo,Ganak,Gank,Gaol,Garag,Gashnak,Gigor,Ginak,Ging,Gink,Girt,Gogdish,Gogdush,Gong,Gork,Gort,Goshnak,Gradash,Gragar,Gragor,Grak,Gralg,Gralo,Granak,Graol,Grarbag,Gridash,Gridish,Gridush,Grigar,Grigor,Grilg,Grilo,Grink,Grirag,Grirg,Grirk,Grishnak,Grodish,Grogar,Grogdish,Grok,Grolg,Grong,Gronk,Grorag,Grorg,Grork,Grort,Groshnak,Grudash,Grugar,Grugdish,Grugdush,Gruk,Grulo,Grunk,Gruol,Grurg,Grurk,Grurt,Gruurk,Gugdish,Gugdush,Gulg,Gulo,Gunak,Gurbag,Gurt,Gushnak,Hadash,Hadish,Hadush,Hagar,Hagdush,Hagor,Hak,Halg,Hank,Hashnak,Hidash,Hidish,Hidush,Higdush,Hilg,Hinak,Hing,Hink,Hiol,Hirag,Hirg,Hodush,Hogar,Hogor,Hong,Hool,Horbag,Hork,Hort,Hoshnak,Hudash,Hudish,Hugor,Huk,Hulg,Hulo,Hunk,Huol,Hurag,Hurbag,Hurk,Hushnak,Huurk,Pagdish,Pagor,Palg,Palo,Paol,Parag,Pashnak,Pidush,Pigdish,Pigdush,Pilg,Pinak,Pink,Pirbag,Podash,Podish,Podush,Pogdish,Polg,Porbag,Porg,Pork,Port,Poshnak,Pradish,Pragdush,Pragor,Pralg,Pralo,Prang,Praol,Prarag,Prarbag,Prarg,Prark,Prart,Prashnak,Praurk,Pridish,Prigar,Prigdish,Prigor,Prilg,Prilo,Prinak,Priol,Prirbag,Prirg,Prirt,Priurk,Prodash,Prodish,Prodush,Prolg,Prolo,Pronak,Prong,Pronk,Prool,Prourk,Prudish,Prugar,Prugdish,Pruk,Prunak,Prunk,Prurg,Prurk,Pruurk,Puk,Pulg,Pulo,Punak,Pung,Punk,Purag,Purbag,Purg,Puurk,Radash,Ragar,Ragdish,Rak,Rang,Rank,Raol,Rarag,Rarbag,Rark,Rashnak,Raurk,Rigor,Rik,Rilg,Rinak,Rink,Rirg,Rirk,Rodish,Rodush,Rogdish,Rok,Rolo,Ronak,Rudash,Rugar,Rugdish,Ruk,Rung,Ruol,Rurag,Rushnak,Vadash,Vadish,Vadush,Vak,Valo,Vank,Varag,Varbag,Vigar,Vigdish,Vigor,Vilg,Vilo,Vink,Virag,Virt,Vishnak,Vogdish,Vogor,Vonak,Vong,Vorg,Vork,Voshnak,Vourk,Vradash,Vragar,Vragdush,Vragor,Vralo,Vrang,Vrarbag,Vrarg,Vrart,Vraurk,Vridash,Vridish,Vrigor,Vrik,Vrinak,Vring,Vrirt,Vrishnak,Vriurk,Vrodash,Vrodish,Vrogar,Vrogor,Vrolo,Vrong,Vrorg,Vrork,Vrudish,Vrugdush,Vrulg,Vrung,Vruol,Vrurg,Vrurt,Vruurk,Vudish,Vuk,Vulg,Vulo,Vunak,Vurag,Vurbag,Vurg,Vushnak"
+ name_generator= _ <<
+main={starting_consonnant}{vowel}{consonnant}{vowel}{ending_consonnant}|{starting_consonnant}{vowel}{consonnant}{ending_vowel}|{starting_vowel}{consonnant}{vowel}{ending_consonnant}|{starting_consonnant}{vowel}{ending_consonnant}|{starting_vowel}{consonnant}{ending_vowel}
+starting_consonnant=B|Br|D|Dr|G|Gr|Gh|H|Kh|M|N|P|Pr|R|S|Sh|T|V
+starting_vowel=A|I|O|U
+consonnant=b|br|d|dr|g|gr|gh|kh|m|n|p|pr|r|s|sh|t|v|gz|zg|rb|br|dr|vr|khr|gd|shn
+vowel=a|i|o|u
+ending_consonnant=b|g|r|sh|k
+ending_vowel=o|u
+>>
#enddef
#define TROLL_NAMES
male_names= _ "Äg,Agh,Bog Äh,Borb,Brag,Brag Goh,Brok,Dak,Drog,Frok,Ga,Gah,Gark,Gnarf,Grar,Grokk,Grumph,Gulk,Hak,Hask,Hoth,Hug Bah,Hu Kah,Kak,Krak,Krug,Kub,Kuh,Lok,Luk,Nak,Nuk Kar,Pag,Reck,Rok,Ruk,Sark,Shak,Shuf,Stuh,Targ,Thog,Thruf,Thur,Tohg,Torg,Trok,Tsok,Tuh,Tuk Ruh,Ugg,Üh,Urg,Urgh,Urk,Vak,Zog,Zuug"
+ name_generator= _ <<
+main={short_name}|{short_name}|{short_name}|{short_name} {short_name}
+short_name={prefix}{middle}{suffix}|{prefix}{middle}{suffix}|{prefix}{middle}{suffix}|{beginning}{suffix}
+prefix=B|Br|D|G|Gn|H|K|Kr|L|N|K|P|R|S|Sh|St|Th|Ts|T|V|Z
+middle=a|o|u|uu|ä|ü
+beginning=Ä|Ü|A|U
+suffix=rb|g|gh|k|rf|kk|r|g|th|h|rg
+>>
#enddef
#define WOSE_NAMES
male_names= _ "Bludebalmen,Boladrumbadrum,Bolwuldelman,Bombempomgontor,Bomtanbomkenton,Bomtanbomtonum,Bregalad,Bremdebubde,Brenbasnudnem,Brendumadoak,Brommantendronnor,Brumbendublun,Brumennarunom,Brummdlebroak,Bumbadadabum,Buomdumdenlol,Carnimirië,Dabumdabumtam,Dammantongonnur,Danmonlulbam,Debundbemun,Delmduelmdelom,Diblembumnde,Dolmannumbil,Drongnoblemdu,Dulmandarook,Dulwulmendom,Dumdumdumatum,Elmaroomadrum,Grelmadrumbumadum,Gulladroamadoak,Gumabeladrelm,Laffalialomdium,Landunwonbam,Lassemista,Lefnublemdde,Libleddnumm,Lolmandindel,Monlamwimdan,Muldondindal,Mundionalafla,Mundumblemdum,Munnamdulbon,Nanmildaldum,Nunmaldildun,Orofarnië,Pambedrumne,Pomtamkomtrobum,Rithramcamhan,Tantondernintan,Temtundembenn,Temtunnongetem,Tondenkontenkon,Troombadoom,Tumtentantarun,Tumtonnongatum,Tumtumgamtomtom,Wonrunmaldin,Wudadoonopl"
+ name_generator= _ <<
+main={prefix}{centre}{centre}{suffix}|{prefix}{centre}{centre}{centre}{suffix}
+prefix=Blu|Bo|Bre|Bro|Bru|Bu|Car|Da|Da|De|Dib|Dol|Dro|Dul|Dum|El|Gre|Gul|Gum|Laf|Lan|Las|Lef|Lib|Lol|Mon|Mul|Mun|Nan|Nun|Or|Pam|Pom|Rith|Tan|Tem|Ton|Troom|Tun|Tum|Won|Wun
+centre=de|bal|drum|wul|del|bem|pom|gon|tan|bom|ken|tan|ton|man|ten|dron|dub|na|da|ni|mi|lul|mon|duel|lem|num|nob|mand|room|lad|roam|be|lom|sem|nub|di|wim|din|blem|nand|dul|dil|of|tam|kon|ton|tun|kon|ten|run|mal|do
+suffix=men|drum|tor|num|lad|de|ak|lol|dum|tam|nur|dium|deum|bil|rook|relm|dium|numm|dan|doom|tum|din
+>>
#enddef
#define VILLAGE_NAMES
male_names= _ "Bal,Cam,Corn,Del,Earl,El,Fox,Fren,Gel,Hel,Hex,Hol,Hox,Il,Kin,Nam,Nes,New,Ol,Old,Olf,Oul,Ox,Rock,Rook,Sal,Sam,Sed,Sel,Sen,Sil,Tal,Water,Wet,York"
+ name_generator= _ <<
+main={prefix}{middle}{suffix}
+prefix=B|C|D|E|F|Fr|Wat|G|H|K|N|O|R|S|T|W|Y|Ro
+middle=a|e|o|u|i
+suffix=l|m|rn|x|w|ld|ck|k|rk
+>>
#enddef
diff --git a/data/gui/macros/_initial.cfg b/data/gui/macros/_initial.cfg
index 5f93746827f4..db950ac1aa78 100644
--- a/data/gui/macros/_initial.cfg
+++ b/data/gui/macros/_initial.cfg
@@ -29,7 +29,7 @@
# If the text is too high it returns the top side.
# Rounding happens to the bottom side.
#define GUI__TEXT_VERTICALLY_CENTRED
- "(if(text_height < height, (height - text_height - 2) / 2, 0))"
+ "(if(text_height < height, (height - text_height) / 2, 0))"
#enddef
#define GUI__CENTERED_TEXT FONT_SIZE FONT_STYLE FONT_COLOR
@@ -279,6 +279,37 @@
[/row]
#enddef
+#define GUI_VERTICAL_SPACER_LINE
+ [column]
+ border = "all"
+ border_size = 10
+ vertical_grow = true
+
+ [drawing]
+ definition = "default"
+
+ width = 1
+ height = (height)
+
+ [draw]
+
+ [line]
+ x1 = 0
+ y1 = 1
+ x2 = 0
+ y2 = (height - 1)
+
+ color = {GUI__FONT_COLOR_DISABLED__DEFAULT}
+ thickness = 1
+ [/line]
+
+ [/draw]
+
+ [/drawing]
+
+ [/column]
+#enddef
+
###############################################################################
### ###
### Macros for the normal gui. ###
@@ -307,5 +338,5 @@
#enddef
#define GUI_NORMAL__FONT_SIZE__TITLE
- 24
+ 22
#enddef
diff --git a/data/gui/macros/horizontal_scrollbar.cfg b/data/gui/macros/horizontal_scrollbar.cfg
index 4f0d2d70ae77..08019cb2d01d 100644
--- a/data/gui/macros/horizontal_scrollbar.cfg
+++ b/data/gui/macros/horizontal_scrollbar.cfg
@@ -13,7 +13,7 @@ horizontal_grow = "true"
# note we want a special button definition for this later.
[repeating_button]
id = "_half_page_up"
- definition = "left_arrow"
+ definition = "scrollbar_left_arrow"
[/repeating_button]
[/column]
@@ -34,7 +34,7 @@ horizontal_grow = "true"
# note we want a special button definition for this later.
[repeating_button]
id = "_half_page_down"
- definition = "right_arrow"
+ definition = "scrollbar_right_arrow"
[/repeating_button]
[/column]
diff --git a/data/gui/widget/button_default.cfg b/data/gui/widget/button_default.cfg
index a6b5b559da92..7d8e7f412aa4 100644
--- a/data/gui/widget/button_default.cfg
+++ b/data/gui/widget/button_default.cfg
@@ -148,8 +148,9 @@
[draw]
{_GUI_STATE "background"
- ({_GUI_BORDER_COLOR_ALPHA {ALPHA}})
- ({_GUI_BORDER_COLOR_DARK_ALPHA {ALPHA}}) ("1, 10, 16, 255") "~GS(){IPF}"}
+ ("128, 128, 128, {ALPHA}") # Same as GUI__FONT_COLOR_DISABLED__DEFAULT, but with an alpha componant
+ ("89, 89, 89, {ALPHA}")
+ ("1, 10, 16, 255") "~GS(){IPF}"}
{GUI__CENTERED_TEXT ({FONT_SIZE}) () ({GUI__FONT_COLOR_DISABLED__TITLE})}
diff --git a/data/gui/widget/horizontal_scrollbar_default.cfg b/data/gui/widget/horizontal_scrollbar_default.cfg
index 4a9c720daf80..594123b47cda 100644
--- a/data/gui/widget/horizontal_scrollbar_default.cfg
+++ b/data/gui/widget/horizontal_scrollbar_default.cfg
@@ -3,43 +3,27 @@
### Definition of a horizontal scrollbar.
###
-#define _GUI_STATE GROOVE_LEFT GROOVE_RIGHT POSITIONER_LEFT POSITIONER_RIGHT IMAGE_SUFFIX IPF
+#define _GUI_STATE POSITIONER_LEFT IMAGE_SUFFIX IPF
[draw]
#
# Groove
#
- [image]
- # 4 pixels wide
+ [rectangle]
x = 0
y = 0
- name = "buttons/scrollbars/scrollgroove-left.png{IPF}"
- [/image]
-
- [image]
- x = {GROOVE_LEFT}
- y = 0
- w = "(if(width - {GROOVE_LEFT} - {GROOVE_RIGHT} < 0
- , 0, width - {GROOVE_LEFT} - {GROOVE_RIGHT}))"
- h = 0
- resize_mode = "stretch"
- name = "buttons/scrollbars/scrollgroove-horizontal.png{IPF}"
- [/image]
-
- [image]
- # 5 pixels wide
- x = "(width - {GROOVE_RIGHT})"
- y = 0
- name = "buttons/scrollbars/scrollgroove-right.png{IPF}"
- [/image]
+ w = "(width)"
+ h = "(height)"
+ fill_color = "4, 4, 4, 255"
+ [/rectangle]
#
# Positioner
#
[image]
- # 5 pixels wide
+ # 5 pixels high
x = "(positioner_offset)"
y = 0
name = "buttons/scrollbars/scrollleft{IMAGE_SUFFIX}{IPF}"
@@ -49,15 +33,15 @@
x = "(positioner_offset + {POSITIONER_LEFT})"
y = 0
w = "(
-if(positioner_length - {POSITIONER_LEFT} - {POSITIONER_RIGHT} < 0
- , 0, positioner_length - {POSITIONER_LEFT} - {POSITIONER_RIGHT}))"
+if(positioner_length - {POSITIONER_LEFT} < 0
+ , 0, positioner_length - {POSITIONER_LEFT}))"
resize_mode = "stretch"
name = "buttons/scrollbars/scrollhorizontal{IMAGE_SUFFIX}{IPF}"
[/image]
[image]
- # 5 pixels wide
- x = "(positioner_offset + positioner_length - {POSITIONER_RIGHT})"
+ # 5 pixels high
+ x = "(positioner_offset + positioner_length)"
y = 0
name = "buttons/scrollbars/scrollright{IMAGE_SUFFIX}{IPF}"
[/image]
@@ -65,7 +49,7 @@ if(positioner_length - {POSITIONER_LEFT} - {POSITIONER_RIGHT} < 0
[/draw]
#enddef
-#define _GUI_RESOLUTION RESOLUTION WIDTH HEIGHT POSITIONER_LENGHT GROOVE_LEFT GROOVE_RIGHT POSITIONER_LEFT POSITIONER_RIGHT IPF
+#define _GUI_RESOLUTION RESOLUTION WIDTH HEIGHT POSITIONER_LENGHT POSITIONER_LEFT IPF
[resolution]
{RESOLUTION}
@@ -74,7 +58,7 @@ if(positioner_length - {POSITIONER_LEFT} - {POSITIONER_RIGHT} < 0
min_height = {HEIGHT}
default_width = {WIDTH}
- default_height = {HEIGHT}
+ default_height = 15
max_width = 0
max_height = {HEIGHT}
@@ -85,19 +69,19 @@ if(positioner_length - {POSITIONER_LEFT} - {POSITIONER_RIGHT} < 0
right_offset = 0
[state_enabled]
- {_GUI_STATE ({GROOVE_LEFT}) ({GROOVE_RIGHT}) ({POSITIONER_LEFT}) ({POSITIONER_RIGHT}) ".png" ({IPF}) }
+ {_GUI_STATE ({POSITIONER_LEFT}) ".png" ({IPF}) }
[/state_enabled]
[state_disabled]
- {_GUI_STATE ({GROOVE_LEFT}) ({GROOVE_RIGHT}) ({POSITIONER_LEFT}) ({POSITIONER_RIGHT}) ".png~GS()" ({IPF}) }
+ {_GUI_STATE ({POSITIONER_LEFT}) ".png~GS()" ({IPF}) }
[/state_disabled]
[state_pressed]
- {_GUI_STATE ({GROOVE_LEFT}) ({GROOVE_RIGHT}) ({POSITIONER_LEFT}) ({POSITIONER_RIGHT}) "-pressed.png" ({IPF}) }
+ {_GUI_STATE ({POSITIONER_LEFT}) "-pressed.png" ({IPF}) }
[/state_pressed]
[state_focused]
- {_GUI_STATE ({GROOVE_LEFT}) ({GROOVE_RIGHT}) ({POSITIONER_LEFT}) ({POSITIONER_RIGHT}) "-active.png" ({IPF}) }
+ {_GUI_STATE ({POSITIONER_LEFT}) "-active.png" ({IPF}) }
[/state_focused]
[/resolution]
#enddef
@@ -109,7 +93,7 @@ if(positioner_length - {POSITIONER_LEFT} - {POSITIONER_RIGHT} < 0
# Note a scrollbar is normally sized by the item that "masters" it
# that's why the default height is rather low.
- {_GUI_RESOLUTION () 20 25 11 4 5 5 5 ()}
+ {_GUI_RESOLUTION () 20 25 11 2 ()}
[/horizontal_scrollbar_definition]
@@ -120,7 +104,7 @@ if(positioner_length - {POSITIONER_LEFT} - {POSITIONER_RIGHT} < 0
# Note a scrollbar is normally sized by the item that "masters" it
# that's why the default height is rather low.
- {_GUI_RESOLUTION () 20 25 11 4 5 5 5 "~O(65%)"}
+ {_GUI_RESOLUTION () 20 25 11 5 "~O(65%)"}
[/horizontal_scrollbar_definition]
diff --git a/data/gui/widget/unit_preview_pane.cfg b/data/gui/widget/unit_preview_pane.cfg
index 2dc6bbe7cc45..1d638319c4f9 100644
--- a/data/gui/widget/unit_preview_pane.cfg
+++ b/data/gui/widget/unit_preview_pane.cfg
@@ -132,6 +132,24 @@
#define _GUI_UNIT_PREVIEW_PANE_MINIMAL
[grid]
+ [row]
+ grow_factor = 0
+
+ [column]
+ border = "bottom"
+ border_size = 5
+ horizontal_alignment = "center"
+ vertical_alignment = "center"
+
+ [image]
+ id = "type_image"
+ definition = "default"
+ [/image]
+
+ [/column]
+
+ [/row]
+
[row]
grow_factor = 0
@@ -153,51 +171,64 @@
[row]
grow_factor = 0
-
[column]
+ border = "bottom"
+ border_size = 5
+ vertical_grow = "true"
horizontal_grow = "true"
- [grid]
+ [label]
+ id = "type_name"
+ wrap = "true"
+ [/label]
- [row]
- grow_factor = 1
+ [/column]
- [column]
- border = "right,bottom"
- border_size = 5
- horizontal_alignment = "left"
+ [/row]
+
+ [row]
+ grow_factor = 0
- [label]
- id = "type_level"
- [/label]
+ [column]
+ border = "right,bottom"
+ border_size = 5
+ horizontal_alignment = "left"
- [/column]
+ [label]
+ id = "type_level"
+ [/label]
- [column]
- border = "right,bottom"
- border_size = 5
- horizontal_alignment = "left"
+ [/column]
- [image]
- id = "type_race"
- [/image]
+ [/row]
- [/column]
+ [row]
+ grow_factor = 0
- [column]
- border = "bottom"
- border_size = 5
- horizontal_alignment = "left"
+ [column]
+ border = "right,bottom"
+ border_size = 5
+ horizontal_alignment = "left"
- [image]
- id = "type_alignment"
- [/image]
+ [label]
+ id = "type_race"
+ [/label]
- [/column]
+ [/column]
- [/row]
+ [/row]
- [/grid]
+ [row]
+ grow_factor = 0
+
+ [column]
+ border = "right,bottom"
+ border_size = 5
+ horizontal_alignment = "left"
+
+ [label]
+ id = "type_alignment"
+ [/label]
[/column]
diff --git a/data/gui/window/campaign_dialog.cfg b/data/gui/window/campaign_dialog.cfg
index e9f706e77be3..96e8a3667236 100644
--- a/data/gui/window/campaign_dialog.cfg
+++ b/data/gui/window/campaign_dialog.cfg
@@ -26,12 +26,6 @@
fixed_width = "true"
[/linked_group]
- [linked_group]
- id = "tree_name"
- fixed_width = "true"
- fixed_height = "true"
- [/linked_group]
-
[tooltip]
id = "tooltip"
[/tooltip]
@@ -373,7 +367,7 @@
[label]
id = "name"
definition = "default"
- linked_group = "tree_name"
+ linked_group = "name"
[/label]
[/column]
diff --git a/data/gui/window/custom_tod.cfg b/data/gui/window/custom_tod.cfg
index 74ec70884130..9951809a6b55 100644
--- a/data/gui/window/custom_tod.cfg
+++ b/data/gui/window/custom_tod.cfg
@@ -4,398 +4,406 @@
###
[window]
- id = "custom_tod"
- description = "Custom ToD schedules dialog."
-
- [resolution]
- definition = "default"
-
- automatic_placement = "true"
- vertical_placement = "center"
- horizontal_placement = "center"
-
- [tooltip]
- id = "tooltip"
- [/tooltip]
-
- [helptip]
- id = "tooltip"
- [/helptip]
-
- [linked_group]
- id = "labels"
- fixed_width = "true"
- [/linked_group]
-
- [linked_group]
- id = "tod_index"
- fixed_width = "true"
- [/linked_group]
-
- [grid]
- [row]
- grow_factor = 0
- [column]
- grow_factor = 1
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [label]
- definition = "title"
- label = _ "Custom Time Schedule"
- [/label]
- [/column]
- [/row]
- [row]
- grow_factor = 0
- [column]
- horizontal_alignment = "left"
- [grid]
- [row]
- grow_factor = 0
- [column]
- horizontal_grow = "true"
- [grid]
- [row]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [label]
- definition = "default"
- linked_group = "labels"
- label = _ "Name:"
- [/label]
- [/column]
- [column]
- grow_factor = 1
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [text_box]
- id = "tod_name"
- definition = "default"
- [/text_box]
- [/column]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "right"
- [image]
- id = "current_tod_image"
- definition = "default"
- [/image]
- [/column]
- [/row]
- [row]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [label]
- definition = "default"
- linked_group = "labels"
- label = _ "ID:"
- [/label]
- [/column]
- [column]
- grow_factor = 1
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [text_box]
- id = "tod_id"
- definition = "default"
- [/text_box]
- [/column]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "right"
- [image]
- id = "current_tod_mask"
- definition = "default"
- [/image]
- [/column]
- [/row]
- [row]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [label]
- definition = "default"
- linked_group = "labels"
- label = _ "Metadata:"
- [/label]
- [/column]
- [column]
- horizontal_alignment = "left"
- [grid]
- [row]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [button]
- id = "image_button"
- definition = "default"
- label = _ "Image"
- [/button]
- [/column]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [button]
- id = "mask_button"
- definition = "default"
- label = _ "Mask"
- [/button]
- [/column]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [button]
- id = "sound_button"
- definition = "default"
- label = _ "Sound"
- [/button]
- [/column]
- [/row]
- [/grid]
- [/column]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "right"
- [label]
- id = "current_sound"
- definition = "default"
- [/label]
- [/column]
- [/row]
- [/grid]
- [/column]
- [/row]
- [row]
- [column]
- [grid]
- [row]
- grow_factor = 0
- [column]
- grow_factor = 1
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [label]
- definition = "default"
- linked_group = "labels"
- label = _ "Lawful Bonus:"
- [/label]
- [/column]
- [column]
- grow_factor = 1
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [slider]
- id = "lawful_bonus"
- definition = "default"
- best_slider_length = 512
- minimum_value = -100
- maximum_value = 100
- step_size = 5
- [/slider]
- [/column]
- [/row]
- [row]
- [column]
- grow_factor = 0
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [label]
- definition = "default"
- linked_group = "labels"
- label = _ "Red:"
- [/label]
- [/column]
- [column]
- grow_factor = 1
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [slider]
- id = "tod_red"
- definition = "default"
- best_slider_length = 512
- minimum_value = -255
- maximum_value = 255
- step_size = 1
- [/slider]
- [/column]
- [/row]
- [row]
- [column]
- grow_factor = 0
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [label]
- definition = "default"
- linked_group = "labels"
- label = _ "Green:"
- [/label]
- [/column]
- [column]
- grow_factor = 1
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [slider]
- id = "tod_green"
- definition = "default"
- best_slider_length = 512
- minimum_value = -255
- maximum_value = 255
- step_size = 1
- [/slider]
- [/column]
- [/row]
- [row]
- [column]
- grow_factor = 0
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [label]
- definition = "default"
- linked_group = "labels"
- label = _ "Blue:"
- [/label]
- [/column]
- [column]
- grow_factor = 1
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [slider]
- id = "tod_blue"
- definition = "default"
- best_slider_length = 512
- minimum_value = -255
- maximum_value = 255
- step_size = 1
- [/slider]
- [/column]
- [/row]
- [/grid]
- [/column]
- [/row]
- [/grid]
- [/column]
- [/row]
- [row]
- grow_factor = 1
- [column]
- horizontal_grow = "true"
- [grid]
- [row]
- grow_factor = 1
- [column]
- horizontal_alignment = "left"
- [grid]
- [row]
- grow_factor = 1
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [button]
- id = "previous_tod"
- definition = "left_arrow"
- linked_group = "tod_index"
- label = _ "Previous"
- [/button]
- [/column]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [label]
- id = "tod_number"
- definition = "default"
- linked_group = "tod_index"
- [/label]
- [/column]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "left"
- [button]
- id = "next_tod"
- definition = "right_arrow"
- linked_group = "tod_index"
- label = _ "Next"
- [/button]
- [/column]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "right"
- [button]
- id = "new"
- definition = "add"
- label = _ "New ToD"
- [/button]
- [/column]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "right"
- [button]
- id = "delete"
- definition = "delete"
- label = _ "Delete ToD"
- [/button]
- [/column]
- [/row]
- [/grid]
- [/column]
- [column]
- horizontal_alignment = "right"
- [grid]
- [row]
- grow_factor = 1
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "right"
- [button]
- id = "save"
- definition = "default"
- label = _ "OK"
- [/button]
- [/column]
- [column]
- border = "all"
- border_size = 5
- horizontal_alignment = "right"
- [button]
- id = "cancel"
- definition = "default"
- label = _ "Cancel"
- [/button]
- [/column]
- [/row]
- [/grid]
- [/column]
- [/row]
- [/grid]
- [/column]
- [/row]
- [/grid]
- [/resolution]
+ id = "custom_tod"
+ description = "Custom ToD schedules dialog."
+
+ [resolution]
+ definition = "default"
+
+ automatic_placement = "true"
+ vertical_placement = "center"
+ horizontal_placement = "center"
+
+ [tooltip]
+ id = "tooltip"
+ [/tooltip]
+
+ [helptip]
+ id = "tooltip"
+ [/helptip]
+
+ [linked_group]
+ id = "labels"
+ fixed_width = "true"
+ [/linked_group]
+
+ [linked_group]
+ id = "tod_index"
+ fixed_width = "true"
+ [/linked_group]
+
+ [grid]
+ [row]
+ grow_factor = 0
+ [column]
+ grow_factor = 1
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [label]
+ definition = "title"
+ label = _ "Custom Time Schedule"
+ [/label]
+ [/column]
+ [/row]
+
+ [row]
+ grow_factor = 0
+ [column]
+ horizontal_grow = "true"
+ [grid]
+ [row]
+ [column]
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [label]
+ definition = "default"
+ linked_group = "labels"
+ label = _ "Name:"
+ [/label]
+ [/column]
+
+ [column]
+ grow_factor = 1
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [text_box]
+ id = "tod_name"
+ definition = "default"
+ [/text_box]
+ [/column]
+
+ [column]
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "right"
+ [image]
+ id = "current_tod_image"
+ definition = "default"
+ [/image]
+ [/column]
+ [/row]
+
+ [row]
+ [column]
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [label]
+ definition = "default"
+ linked_group = "labels"
+ label = _ "ID:"
+ [/label]
+ [/column]
+
+ [column]
+ grow_factor = 1
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [text_box]
+ id = "tod_id"
+ definition = "default"
+ [/text_box]
+ [/column]
+
+ [column]
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "right"
+ [image]
+ id = "current_tod_mask"
+ definition = "default"
+ [/image]
+ [/column]
+ [/row]
+
+ [row]
+ [column]
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [label]
+ definition = "default"
+ linked_group = "labels"
+ label = _ "Metadata:"
+ [/label]
+ [/column]
+
+ [column]
+ horizontal_alignment = "left"
+ [grid]
+ [row]
+ [column]
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [button]
+ id = "image_button"
+ definition = "default"
+ label = _ "Image"
+ [/button]
+ [/column]
+
+ [column]
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [button]
+ id = "mask_button"
+ definition = "default"
+ label = _ "Mask"
+ [/button]
+ [/column]
+
+ [column]
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [button]
+ id = "sound_button"
+ definition = "default"
+ label = _ "Sound"
+ [/button]
+ [/column]
+ [/row]
+ [/grid]
+ [/column]
+
+ [column]
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "right"
+ [label]
+ id = "current_sound"
+ definition = "default"
+ [/label]
+ [/column]
+ [/row]
+ [/grid]
+ [/column]
+ [/row]
+ [row]
+ [column]
+ [grid]
+ [row]
+ grow_factor = 0
+ [column]
+ grow_factor = 1
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [label]
+ definition = "default"
+ linked_group = "labels"
+ label = _ "Lawful Bonus:"
+ [/label]
+ [/column]
+
+ [column]
+ grow_factor = 1
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [slider]
+ id = "lawful_bonus"
+ definition = "default"
+ best_slider_length = 512
+ minimum_value = -100
+ maximum_value = 100
+ step_size = 5
+ [/slider]
+ [/column]
+ [/row]
+
+ [row]
+ [column]
+ grow_factor = 0
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [label]
+ definition = "default"
+ linked_group = "labels"
+ label = _ "Red:"
+ [/label]
+ [/column]
+
+ [column]
+ grow_factor = 1
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [slider]
+ id = "tod_red"
+ definition = "default"
+ best_slider_length = 512
+ minimum_value = -255
+ maximum_value = 255
+ step_size = 1
+ [/slider]
+ [/column]
+ [/row]
+
+ [row]
+ [column]
+ grow_factor = 0
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [label]
+ definition = "default"
+ linked_group = "labels"
+ label = _ "Green:"
+ [/label]
+ [/column]
+
+ [column]
+ grow_factor = 1
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [slider]
+ id = "tod_green"
+ definition = "default"
+ best_slider_length = 512
+ minimum_value = -255
+ maximum_value = 255
+ step_size = 1
+ [/slider]
+ [/column]
+ [/row]
+
+ [row]
+ [column]
+ grow_factor = 0
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [label]
+ definition = "default"
+ linked_group = "labels"
+ label = _ "Blue:"
+ [/label]
+ [/column]
+
+ [column]
+ grow_factor = 1
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [slider]
+ id = "tod_blue"
+ definition = "default"
+ best_slider_length = 512
+ minimum_value = -255
+ maximum_value = 255
+ step_size = 1
+ [/slider]
+ [/column]
+ [/row]
+ [/grid]
+ [/column]
+ [/row]
+
+ [row]
+ grow_factor = 1
+ [column]
+ horizontal_grow = "true"
+ [grid]
+ [row]
+ grow_factor = 1
+ [column]
+ grow_factor = 0
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [button]
+ id = "previous_tod"
+ definition = "left_arrow"
+ linked_group = "tod_index"
+ label = _ "Previous"
+ [/button]
+ [/column]
+
+ [column]
+ grow_factor = 0
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [label]
+ id = "tod_number"
+ definition = "default"
+ linked_group = "tod_index"
+ [/label]
+ [/column]
+
+ [column]
+ grow_factor = 0
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [button]
+ id = "next_tod"
+ definition = "right_arrow"
+ linked_group = "tod_index"
+ label = _ "Next"
+ [/button]
+ [/column]
+
+ [column]
+ grow_factor = 0
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [button]
+ id = "new"
+ definition = "add"
+ label = _ "New ToD"
+ [/button]
+ [/column]
+
+ [column]
+ grow_factor = 1
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "left"
+ [button]
+ id = "delete"
+ definition = "delete"
+ label = _ "Delete ToD"
+ [/button]
+ [/column]
+
+ [column]
+ grow_factor = 0
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "right"
+ [button]
+ id = "ok"
+ definition = "default"
+ label = _ "OK"
+ [/button]
+ [/column]
+
+ [column]
+ grow_factor = 0
+ border = "all"
+ border_size = 5
+ horizontal_alignment = "right"
+ [button]
+ id = "cancel"
+ definition = "default"
+ label = _ "Cancel"
+ [/button]
+ [/column]
+ [/row]
+ [/grid]
+ [/column]
+ [/row]
+ [/grid]
+ [/resolution]
[/window]
diff --git a/data/gui/window/loadscreen.cfg b/data/gui/window/loadscreen.cfg
index 0da663c1151b..bfc28156f090 100644
--- a/data/gui/window/loadscreen.cfg
+++ b/data/gui/window/loadscreen.cfg
@@ -45,7 +45,7 @@
[column]
[spacer]
- height = "((screen_height - if(screen_height < 800, 400, 0)) / 4)"
+ height = "((screen_height - if(screen_height < 800, 200, 0)) / 3.5)"
[/spacer]
[/column]
@@ -75,7 +75,7 @@
{_GUI_PADDING}
[row]
- grow_factor = 1
+ grow_factor = 2
[column]
grow_factor = 1
@@ -100,22 +100,20 @@
grow_factor = 1
border = "all"
border_size = 5
- horizontal_grow = "true"
+ horizontal_alignment = "center"
vertical_alignment = "center"
- [label]
- text_alignment = "center"
- definition = "default_large"
- id = "status"
- label = _ "Loading..."
- [/label]
+ [image]
+ definition = "decoration"
+ label = "misc/loadscreen_decor.png"
+ [/image]
[/column]
[/row]
[row]
- grow_factor = 0
+ grow_factor = 1
[column]
grow_factor = 1
@@ -142,13 +140,15 @@
grow_factor = 1
border = "all"
border_size = 5
- horizontal_alignment = "center"
+ horizontal_grow = "true"
vertical_alignment = "center"
- [image]
- definition = "decoration"
- label = "misc/loadscreen_decor.png"
- [/image]
+ [label]
+ text_alignment = "center"
+ definition = "default_large"
+ id = "status"
+ label = _ "Loading..."
+ [/label]
[/column]
diff --git a/data/gui/window/lobby_main.cfg b/data/gui/window/lobby_main.cfg
index 77b6e6e3359c..a392e13ee102 100644
--- a/data/gui/window/lobby_main.cfg
+++ b/data/gui/window/lobby_main.cfg
@@ -104,7 +104,7 @@
#define GAMELISTBOX
border = "all"
border_size = 5
-
+
[listbox]
id = "game_list"
definition = "default"
@@ -679,7 +679,7 @@ border_size = 5
border_size = 5
[button]
id = "quit"
- definition = "default"
+ definition = "large"
label = _ "Log Out"
[/button]
{VERTICAL_SEP}
@@ -687,7 +687,7 @@ border_size = 5
border_size = 5
[button]
id = "show_preferences"
- definition = "default"
+ definition = "large"
label = _ "Preferences"
[/button]
{VERTICAL_SEP}
@@ -695,7 +695,7 @@ border_size = 5
border_size = 5
[button]
id = "refresh"
- definition = "default"
+ definition = "large"
label = _ "Refresh"
[/button]
{VERTICAL_SEP}
@@ -703,7 +703,7 @@ border_size = 5
border_size = 10
[button]
id = "create"
- definition = "default"
+ definition = "large"
label = _ "Create Game"
[/button]
{VERTICAL_SEP}
@@ -711,7 +711,7 @@ border_size = 5
border_size = 5
[button]
id = "join_global"
- definition = "default"
+ definition = "large"
label = _ "Join"
[/button]
{VERTICAL_SEP}
@@ -719,7 +719,7 @@ border_size = 5
border_size = 5
[button]
id = "observe_global"
- definition = "default"
+ definition = "large"
label = _ "Observe"
[/button]
{VERTICAL_SEP}
@@ -727,7 +727,7 @@ border_size = 5
border_size = 5
[toggle_button]
id = "skip_replay"
- definition = "default"
+ definition = "large"
label = _ "Quick replay"
[/toggle_button]
# wmlxgettext: [column]
@@ -794,8 +794,10 @@ border_size = 5
[column]
horizontal_grow = "true"
vertical_grow = "true"
+ border = "all"
+ border_size = 5
{GUI_FORCE_OUTLINED_WIDGET_MINIMUM_SIZE
- 0 "((screen_height * 30) / 100)"
+ 0 "((screen_height * if(screen_height < 800, 30, 50)) / 100)"
5 1 {GUI__BORDER_COLOR_BRIGHT} (
{GAMELISTBOX}
)}
diff --git a/data/gui/window/preferences/03_display.cfg b/data/gui/window/preferences/03_display.cfg
index efe34cfac20d..d838993ccd67 100644
--- a/data/gui/window/preferences/03_display.cfg
+++ b/data/gui/window/preferences/03_display.cfg
@@ -253,7 +253,7 @@
[slider]
id = "scaling_slider"
definition = "minimal"
- minimum_value,maximum_value=100,200
+ minimum_value,maximum_value=80,200
step_size=5
tooltip= _ "Set the scaling factor of fonts"
[/slider]
diff --git a/data/gui/window/unit_attack.cfg b/data/gui/window/unit_attack.cfg
index 6186bd6c3397..b040c7b2eb10 100644
--- a/data/gui/window/unit_attack.cfg
+++ b/data/gui/window/unit_attack.cfg
@@ -162,34 +162,7 @@
{_GUI_BIG_ATTACKER_PANEL}
[/column]
- [column]
- border = "all"
- border_size = 10
- vertical_grow = true
-
- [drawing]
- definition = "default"
-
- width = 1
- height = (height)
-
- [draw]
-
- [line]
- x1 = 0
- y1 = 1
- x2 = 0
- y2 = (height - 1)
-
- color = {GUI__FONT_COLOR_DISABLED__DEFAULT}
- thickness = 1
- [/line]
-
- [/draw]
-
- [/drawing]
-
- [/column]
+ {GUI_VERTICAL_SPACER_LINE}
[column]
grow_factor = 1
diff --git a/data/hardwired/fonts.cfg b/data/hardwired/fonts.cfg
index b6d850283709..435850e8b8b4 100644
--- a/data/hardwired/fonts.cfg
+++ b/data/hardwired/fonts.cfg
@@ -5,12 +5,19 @@
# provide different font orders: one just has to install the
# missing fonts without needing to change the gmo files
order=_ "DejaVuSans.ttf,Andagii.ttf,DroidSansJapanese.ttf,DroidSansFallbackFull.ttf,Junicode-Regular.ttf"
- family_order=_ "DejaVu Sans,Andagii,Droid Sans Japanese,Droid Sans Fallback,Junicode"
+ family_order=_ "Lato"
# Used by GUI2 only, hence no [font] blocks for these. The font files are
# also automatically determined.
family_order_monospace=_ "DejaVu Sans Mono"
+ [font]
+ name="Lato-Regular.ttf"
+ bold_name="Lato-Bold.ttf"
+ italic_name="Lato-Italic.ttf"
+ codepoints="32-126,160-831,834,837-879,885,890-893,900-902,904-906,908,910-929,931-974,976-1158,1160-1299,3647,7424-7626,7678-7835,7838,7840-7929,7936-7957,7960-7965,7968-8005,8008-8013,8016-8023,8025,8027,8029,8031-8048,8050,8052,8054,8056,8058,8060,8064-8116,8118-8122,8124-8125,8127-8132,8134-8136,8138,8140-8146,8150-8154,8157-8162,8164-8170,8172-8173,8178-8180,8182-8184,8186,8188,8190,8194-8208,8210-8226,8230,8239-8240,8242-8244,8249-8250,8252-8254,8260,8286-8287,8304-8305,8308-8340,8352-8373,8376-8378,8413,8453,8467,8470-8471,8480,8482,8494,8498,8525-8526,8531-8543,8579-8580,8592-8601,8616,8706,8710,8719,8721-8722,8725,8729-8730,8734-8735,8745,8747,8776,8800-8801,8804-8805,8962,8976,8992-8993,9312-9331,9450-9460,9471-9472,9474,9484,9488,9492,9496,9633,9642-9643,9674-9676,9679,9702,9728,9788,9833,10102-10111,11360-11372,11380-11383,11799,42775-42778,42784-42785,63743,64256-64260,65056-65059,65279"
+ [/font]
+
[font]
name="DejaVuSans.ttf"
bold_name="DejaVuSans-Bold.ttf"
diff --git a/data/lua/wml-flow.lua b/data/lua/wml-flow.lua
new file mode 100644
index 000000000000..8043129850bd
--- /dev/null
+++ b/data/lua/wml-flow.lua
@@ -0,0 +1,259 @@
+local helper = wesnoth.require "lua/helper.lua"
+local utils = wesnoth.require "lua/wml-utils.lua"
+local wml_actions = wesnoth.wml_actions
+
+function wml_actions.command(cfg)
+ utils.handle_event_commands(cfg, "plain")
+end
+
+-- we can't create functions with names that are Lua keywords (eg if, while)
+-- instead, we store the following anonymous functions directly into
+-- the table, using the [] operator, rather than by using the point syntax
+
+wml_actions["if"] = function(cfg)
+ if not (helper.get_child(cfg, 'then') or helper.get_child(cfg, 'elseif') or helper.get_child(cfg, 'else')) then
+ helper.wml_error("[if] didn't find any [then], [elseif], or [else] children.")
+ end
+
+ if wesnoth.eval_conditional(cfg) then -- evaluate [if] tag
+ for then_child in helper.child_range(cfg, "then") do
+ local action = utils.handle_event_commands(then_child, "conditional")
+ if action ~= "none" then break end
+ end
+ return -- stop after executing [then] tags
+ end
+
+ for elseif_child in helper.child_range(cfg, "elseif") do
+ if wesnoth.eval_conditional(elseif_child) then -- we'll evaluate the [elseif] tags one by one
+ for then_tag in helper.child_range(elseif_child, "then") do
+ local action = utils.handle_event_commands(then_tag, "conditional")
+ if action ~= "none" then break end
+ end
+ return -- stop on first matched condition
+ end
+ end
+
+ -- no matched condition, try the [else] tags
+ for else_child in helper.child_range(cfg, "else") do
+ local action = utils.handle_event_commands(else_child, "conditional")
+ if action ~= "none" then break end
+ end
+end
+
+wml_actions["while"] = function( cfg )
+ if helper.child_count(cfg, "do") == 0 then
+ helper.wml_error "[while] does not contain any [do] tags"
+ end
+
+ -- execute [do] up to 65536 times
+ for i = 1, 65536 do
+ if wesnoth.eval_conditional( cfg ) then
+ for do_child in helper.child_range( cfg, "do" ) do
+ local action = utils.handle_event_commands(do_child, "loop")
+ if action == "break" then
+ utils.set_exiting("none")
+ return
+ elseif action == "continue" then
+ utils.set_exiting("none")
+ break
+ elseif action ~= "none" then
+ return
+ end
+ end
+ else return end
+ end
+end
+
+wml_actions["break"] = function(cfg)
+ utils.set_exiting("break")
+end
+
+wml_actions["return"] = function(cfg)
+ utils.set_exiting("return")
+end
+
+function wml_actions.continue(cfg)
+ utils.set_exiting("continue")
+end
+
+wesnoth.wml_actions["for"] = function(cfg)
+ if helper.child_count(cfg, "do") == 0 then
+ helper.wml_error "[for] does not contain any [do] tags"
+ end
+
+ local loop_lim = {}
+ local first
+ if cfg.array ~= nil then
+ if cfg.reverse then
+ first = wesnoth.get_variable(cfg.array .. ".length") - 1
+ loop_lim.last = 0
+ loop_lim.step = -1
+ else
+ first = 0
+ loop_lim.last = '$($' .. cfg.array .. ".length - 1)"
+ loop_lim.step = 1
+ end
+ else
+ -- Get a literal config to fetch end and step;
+ -- this done is to delay expansion of variables
+ local cfg_lit = helper.literal(cfg)
+ first = cfg.start or 0
+ loop_lim.last = cfg_lit["end"] or first
+ if cfg.step then loop_lim.step = cfg_lit.step end
+ end
+ loop_lim = wesnoth.tovconfig(loop_lim)
+ if loop_lim.step == 0 then -- Sanity check
+ helper.wml_error("[for] has a step of 0!")
+ end
+ if (first < loop_lim.last and loop_lim.step <= 0) or (first > loop_lim.last and loop_lim.step >= 0) then
+ -- Sanity check: If they specify something like start,end,step=1,4,-1
+ -- then we do nothing
+ return
+ end
+ local i_var = cfg.variable or "i"
+ local save_i = utils.start_var_scope(i_var)
+ wesnoth.set_variable(i_var, first)
+ local function loop_condition()
+ local sentinel = loop_lim.last
+ if loop_lim.step then
+ sentinel = sentinel + loop_lim.step
+ elseif loop_lim.last < first then
+ sentinel = sentinel - 1
+ else
+ sentinel = sentinel + 1
+ end
+ if loop_lim.step > 0 then
+ return wesnoth.get_variable(i_var) < sentinel
+ else
+ return wesnoth.get_variable(i_var) > sentinel
+ end
+ end
+ while loop_condition() do
+ for do_child in helper.child_range( cfg, "do" ) do
+ local action = utils.handle_event_commands(do_child, "loop")
+ if action == "break" then
+ utils.set_exiting("none")
+ goto exit
+ elseif action == "continue" then
+ utils.set_exiting("none")
+ break
+ elseif action ~= "none" then
+ goto exit
+ end
+ end
+ wesnoth.set_variable(i_var, wesnoth.get_variable(i_var) + loop_lim.step)
+ end
+ ::exit::
+ utils.end_var_scope(i_var, save_i)
+end
+
+wml_actions["repeat"] = function(cfg)
+ if helper.child_count(cfg, "do") == 0 then
+ helper.wml_error "[repeat] does not contain any [do] tags"
+ end
+
+ local times = cfg.times or 1
+ for i = 1, times do
+ for do_child in helper.child_range( cfg, "do" ) do
+ local action = utils.handle_event_commands(do_child, "loop")
+ if action == "break" then
+ utils.set_exiting("none")
+ return
+ elseif action == "continue" then
+ utils.set_exiting("none")
+ break
+ elseif action ~= "none" then
+ return
+ end
+ end
+ end
+end
+
+function wml_actions.foreach(cfg)
+ if helper.child_count(cfg, "do") == 0 then
+ helper.wml_error "[foreach] does not contain any [do] tags"
+ end
+
+ local array_name = cfg.variable or helper.wml_error "[foreach] missing required variable= attribute"
+ local array = helper.get_variable_array(array_name)
+ if #array == 0 then return end -- empty and scalars unwanted
+ local item_name = cfg.item_var or "this_item"
+ local this_item = utils.start_var_scope(item_name) -- if this_item is already set
+ local i_name = cfg.index_var or "i"
+ local i = utils.start_var_scope(i_name) -- if i is already set
+ local array_length = wesnoth.get_variable(array_name .. ".length")
+
+ for index, value in ipairs(array) do
+ -- Some protection against external modification
+ -- It's not perfect, though - it'd be nice if *any* change could be detected
+ if array_length ~= wesnoth.get_variable(array_name .. ".length") then
+ helper.wml_error("WML array length changed during [foreach] iteration")
+ end
+ wesnoth.set_variable(item_name, value)
+ -- set index variable
+ wesnoth.set_variable(i_name, index-1) -- here -1, because of WML array
+ -- perform actions
+ for do_child in helper.child_range(cfg, "do") do
+ local action = utils.handle_event_commands(do_child, "loop")
+ if action == "break" then
+ utils.set_exiting("none")
+ goto exit
+ elseif action == "continue" then
+ utils.set_exiting("none")
+ break
+ elseif action ~= "none" then
+ goto exit
+ end
+ end
+ -- set back the content, in case the author made some modifications
+ if not cfg.readonly then
+ array[index] = wesnoth.get_variable(item_name)
+ end
+ end
+ ::exit::
+
+ -- house cleaning
+ utils.end_var_scope(item_name, this_item)
+ utils.end_var_scope(i_name, i)
+
+ --[[
+ This forces the readonly key to be taken literally.
+
+ If readonly=yes, then this line guarantees that the array
+ is unchanged after the [foreach] loop ends.
+
+ If readonly=no, then this line updates the array with any
+ changes the user has applied through the $this_item
+ variable (or whatever variable was given in item_var).
+
+ Note that altering the array via indexing (with the index_var)
+ is not supported; any such changes will be reverted by this line.
+ ]]
+ helper.set_variable_array(array_name, array)
+end
+
+function wml_actions.switch(cfg)
+ local var_value = wesnoth.get_variable(cfg.variable)
+ local found = false
+
+ -- Execute all the [case]s where the value matches.
+ for v in helper.child_range(cfg, "case") do
+ for w in utils.split(v.value) do
+ if w == tostring(var_value) then
+ local action = utils.handle_event_commands(v, "switch")
+ found = true
+ if action ~= "none" then goto exit end
+ break
+ end
+ end
+ end
+ ::exit::
+
+ -- Otherwise execute [else] statements.
+ if not found then
+ for v in helper.child_range(cfg, "else") do
+ local action = utils.handle_event_commands(v, "switch")
+ if action ~= "none" then break end
+ end
+ end
+end
\ No newline at end of file
diff --git a/data/lua/wml-tags.lua b/data/lua/wml-tags.lua
index 2cd194dc9cf5..3a2efde140bd 100644
--- a/data/lua/wml-tags.lua
+++ b/data/lua/wml-tags.lua
@@ -11,10 +11,16 @@ function wesnoth.game_events.on_save()
return {}
end
+wesnoth.require "lua/wml-flow.lua"
wesnoth.require "lua/wml/objectives.lua"
wesnoth.require "lua/wml/items.lua"
wesnoth.require "lua/wml/message.lua"
wesnoth.require "lua/wml/object.lua"
+wesnoth.require "lua/wml/modify_unit.lua"
+wesnoth.require "lua/wml/harm_unit.lua"
+wesnoth.require "lua/wml/find_path.lua"
+wesnoth.require "lua/wml/endlevel.lua"
+wesnoth.require "lua/wml/random_placement.lua"
local helper = wesnoth.require "lua/helper.lua"
local location_set = wesnoth.require "lua/location_set.lua"
@@ -260,262 +266,6 @@ function wml_actions.music(cfg)
wesnoth.set_music(cfg)
end
-function wml_actions.command(cfg)
- utils.handle_event_commands(cfg, "plain")
-end
-
--- we can't create functions with names that are Lua keywords (eg if, while)
--- instead, we store the following anonymous functions directly into
--- the table, using the [] operator, rather than by using the point syntax
-
-wml_actions["if"] = function(cfg)
- if not (helper.get_child(cfg, 'then') or helper.get_child(cfg, 'elseif') or helper.get_child(cfg, 'else')) then
- helper.wml_error("[if] didn't find any [then], [elseif], or [else] children.")
- end
-
- if wesnoth.eval_conditional(cfg) then -- evaluate [if] tag
- for then_child in helper.child_range(cfg, "then") do
- local action = utils.handle_event_commands(then_child, "conditional")
- if action ~= "none" then break end
- end
- return -- stop after executing [then] tags
- end
-
- for elseif_child in helper.child_range(cfg, "elseif") do
- if wesnoth.eval_conditional(elseif_child) then -- we'll evaluate the [elseif] tags one by one
- for then_tag in helper.child_range(elseif_child, "then") do
- local action = utils.handle_event_commands(then_tag, "conditional")
- if action ~= "none" then break end
- end
- return -- stop on first matched condition
- end
- end
-
- -- no matched condition, try the [else] tags
- for else_child in helper.child_range(cfg, "else") do
- local action = utils.handle_event_commands(else_child, "conditional")
- if action ~= "none" then break end
- end
-end
-
-wml_actions["while"] = function( cfg )
- if helper.child_count(cfg, "do") == 0 then
- helper.wml_error "[while] does not contain any [do] tags"
- end
-
- -- execute [do] up to 65536 times
- for i = 1, 65536 do
- if wesnoth.eval_conditional( cfg ) then
- for do_child in helper.child_range( cfg, "do" ) do
- local action = utils.handle_event_commands(do_child, "loop")
- if action == "break" then
- utils.set_exiting("none")
- return
- elseif action == "continue" then
- utils.set_exiting("none")
- break
- elseif action ~= "none" then
- return
- end
- end
- else return end
- end
-end
-
-wml_actions["break"] = function(cfg)
- utils.set_exiting("break")
-end
-
-wml_actions["return"] = function(cfg)
- utils.set_exiting("return")
-end
-
-function wml_actions.continue(cfg)
- utils.set_exiting("continue")
-end
-
-wesnoth.wml_actions["for"] = function(cfg)
- if helper.child_count(cfg, "do") == 0 then
- helper.wml_error "[for] does not contain any [do] tags"
- end
-
- local loop_lim = {}
- local first
- if cfg.array ~= nil then
- if cfg.reverse then
- first = wesnoth.get_variable(cfg.array .. ".length") - 1
- loop_lim.last = 0
- loop_lim.step = -1
- else
- first = 0
- loop_lim.last = '$($' .. cfg.array .. ".length - 1)"
- loop_lim.step = 1
- end
- else
- -- Get a literal config to fetch end and step;
- -- this done is to delay expansion of variables
- local cfg_lit = helper.literal(cfg)
- first = cfg.start or 0
- loop_lim.last = cfg_lit["end"] or first
- if cfg.step then loop_lim.step = cfg_lit.step end
- end
- loop_lim = wesnoth.tovconfig(loop_lim)
- if loop_lim.step == 0 then -- Sanity check
- helper.wml_error("[for] has a step of 0!")
- end
- if (first < loop_lim.last and loop_lim.step <= 0) or (first > loop_lim.last and loop_lim.step >= 0) then
- -- Sanity check: If they specify something like start,end,step=1,4,-1
- -- then we do nothing
- return
- end
- local i_var = cfg.variable or "i"
- local save_i = utils.start_var_scope(i_var)
- wesnoth.set_variable(i_var, first)
- local function loop_condition()
- local sentinel = loop_lim.last
- if loop_lim.step then
- sentinel = sentinel + loop_lim.step
- elseif loop_lim.last < first then
- sentinel = sentinel - 1
- else
- sentinel = sentinel + 1
- end
- if loop_lim.step > 0 then
- return wesnoth.get_variable(i_var) < sentinel
- else
- return wesnoth.get_variable(i_var) > sentinel
- end
- end
- while loop_condition() do
- for do_child in helper.child_range( cfg, "do" ) do
- local action = utils.handle_event_commands(do_child, "loop")
- if action == "break" then
- utils.set_exiting("none")
- goto exit
- elseif action == "continue" then
- utils.set_exiting("none")
- break
- elseif action ~= "none" then
- goto exit
- end
- end
- wesnoth.set_variable(i_var, wesnoth.get_variable(i_var) + loop_lim.step)
- end
- ::exit::
- utils.end_var_scope(i_var, save_i)
-end
-
-wml_actions["repeat"] = function(cfg)
- if helper.child_count(cfg, "do") == 0 then
- helper.wml_error "[repeat] does not contain any [do] tags"
- end
-
- local times = cfg.times or 1
- for i = 1, times do
- for do_child in helper.child_range( cfg, "do" ) do
- local action = utils.handle_event_commands(do_child, "loop")
- if action == "break" then
- utils.set_exiting("none")
- return
- elseif action == "continue" then
- utils.set_exiting("none")
- break
- elseif action ~= "none" then
- return
- end
- end
- end
-end
-
-function wml_actions.foreach(cfg)
- if helper.child_count(cfg, "do") == 0 then
- helper.wml_error "[foreach] does not contain any [do] tags"
- end
-
- local array_name = cfg.variable or helper.wml_error "[foreach] missing required variable= attribute"
- local array = helper.get_variable_array(array_name)
- if #array == 0 then return end -- empty and scalars unwanted
- local item_name = cfg.item_var or "this_item"
- local this_item = utils.start_var_scope(item_name) -- if this_item is already set
- local i_name = cfg.index_var or "i"
- local i = utils.start_var_scope(i_name) -- if i is already set
- local array_length = wesnoth.get_variable(array_name .. ".length")
-
- for index, value in ipairs(array) do
- -- Some protection against external modification
- -- It's not perfect, though - it'd be nice if *any* change could be detected
- if array_length ~= wesnoth.get_variable(array_name .. ".length") then
- helper.wml_error("WML array length changed during [foreach] iteration")
- end
- wesnoth.set_variable(item_name, value)
- -- set index variable
- wesnoth.set_variable(i_name, index-1) -- here -1, because of WML array
- -- perform actions
- for do_child in helper.child_range(cfg, "do") do
- local action = utils.handle_event_commands(do_child, "loop")
- if action == "break" then
- utils.set_exiting("none")
- goto exit
- elseif action == "continue" then
- utils.set_exiting("none")
- break
- elseif action ~= "none" then
- goto exit
- end
- end
- -- set back the content, in case the author made some modifications
- if not cfg.readonly then
- array[index] = wesnoth.get_variable(item_name)
- end
- end
- ::exit::
-
- -- house cleaning
- utils.end_var_scope(item_name, this_item)
- utils.end_var_scope(i_name, i)
-
- --[[
- This forces the readonly key to be taken literally.
-
- If readonly=yes, then this line guarantees that the array
- is unchanged after the [foreach] loop ends.
-
- If readonly=no, then this line updates the array with any
- changes the user has applied through the $this_item
- variable (or whatever variable was given in item_var).
-
- Note that altering the array via indexing (with the index_var)
- is not supported; any such changes will be reverted by this line.
- ]]
- helper.set_variable_array(array_name, array)
-end
-
-function wml_actions.switch(cfg)
- local var_value = wesnoth.get_variable(cfg.variable)
- local found = false
-
- -- Execute all the [case]s where the value matches.
- for v in helper.child_range(cfg, "case") do
- for w in utils.split(v.value) do
- if w == tostring(var_value) then
- local action = utils.handle_event_commands(v, "switch")
- found = true
- if action ~= "none" then goto exit end
- break
- end
- end
- end
- ::exit::
-
- -- Otherwise execute [else] statements.
- if not found then
- for v in helper.child_range(cfg, "else") do
- local action = utils.handle_event_commands(v, "switch")
- if action ~= "none" then break end
- end
- end
-end
-
-- This is mainly for use in unit test macros, but maybe it can be useful elsewhere too
function wml_actions.test_condition(cfg)
local logger = cfg.logger or "warning"
@@ -558,7 +308,7 @@ function wml_actions.test_condition(cfg)
if tag == "variable" then
explanation = string.format("%s\n\tNote: The variable %s currently has the value %q.", explanation, this_cfg.name, tostring(wesnoth.get_variable(this_cfg.name)))
end
- wesnoth.wml_actions.wml_message{message = explanation, logger = logger}
+ wesnoth.log(logger, explanation, true)
return true
end
end
@@ -748,77 +498,6 @@ function wml_actions.unhide_unit(cfg)
wml_actions.redraw {}
end
-function wml_actions.modify_unit(cfg)
- local unit_variable = "LUA_modify_unit"
-
- local function handle_attributes(cfg, unit_path, toplevel)
- for current_key, current_value in pairs(helper.shallow_parsed(cfg)) do
- if type(current_value) ~= "table" and (not toplevel or current_key ~= "type") then
- wesnoth.set_variable(string.format("%s.%s", unit_path, current_key), current_value)
- end
- end
- end
-
- local function handle_child(cfg, unit_path)
- local children_handled = {}
- local cfg = helper.shallow_parsed(cfg)
- handle_attributes(cfg, unit_path)
-
- for current_index, current_table in ipairs(cfg) do
- local current_tag = current_table[1]
- local tag_index = children_handled[current_tag] or 0
- handle_child(current_table[2], string.format("%s.%s[%u]",
- unit_path, current_tag, tag_index))
- children_handled[current_tag] = tag_index + 1
- end
- end
-
- local filter = helper.get_child(cfg, "filter") or helper.wml_error "[modify_unit] missing required [filter] tag"
- local function handle_unit(unit_num)
- local children_handled = {}
- local unit_path = string.format("%s[%u]", unit_variable, unit_num)
- local this_unit = wesnoth.get_variable(unit_path)
- wesnoth.set_variable("this_unit", this_unit)
- handle_attributes(cfg, unit_path, true)
-
- for current_index, current_table in ipairs(helper.shallow_parsed(cfg)) do
- local current_tag = current_table[1]
- if current_tag == "filter" then
- -- nothing
- elseif current_tag == "object" or current_tag == "trait" or current_tag == "advancement" then
- local unit = wesnoth.get_variable(unit_path)
- unit = wesnoth.create_unit(unit)
- wesnoth.add_modification(unit, current_tag, current_table[2])
- unit = unit.__cfg;
- wesnoth.set_variable(unit_path, unit)
- else
- local tag_index = children_handled[current_tag] or 0
- handle_child(current_table[2], string.format("%s.%s[%u]",
- unit_path, current_tag, tag_index))
- children_handled[current_tag] = tag_index + 1
- end
- end
-
- if cfg.type then
- if cfg.type ~= "" then wesnoth.set_variable(unit_path .. ".advances_to", cfg.type) end
- wesnoth.set_variable(unit_path .. ".experience", wesnoth.get_variable(unit_path .. ".max_experience"))
- end
- wml_actions.kill({ id = this_unit.id, animate = false })
- wml_actions.unstore_unit { variable = unit_path }
- end
-
- wml_actions.store_unit { {"filter", filter}, variable = unit_variable }
- local max_index = wesnoth.get_variable(unit_variable .. ".length") - 1
-
- local this_unit = utils.start_var_scope("this_unit")
- for current_unit = 0, max_index do
- handle_unit(current_unit)
- end
- utils.end_var_scope("this_unit", this_unit)
-
- wesnoth.set_variable(unit_variable)
-end
-
function wml_actions.move_unit(cfg)
local coordinate_error = "invalid coordinate in [move_unit]"
local to_x = tostring(cfg.to_x or helper.wml_error(coordinate_error))
@@ -949,207 +628,6 @@ function wml_actions.unpetrify(cfg)
end
end
-function wml_actions.harm_unit(cfg)
- local filter = helper.get_child(cfg, "filter") or helper.wml_error("[harm_unit] missing required [filter] tag")
- -- we need to use shallow_literal field, to avoid raising an error if $this_unit (not yet assigned) is used
- if not helper.shallow_literal(cfg).amount then helper.wml_error("[harm_unit] has missing required amount= attribute") end
- local variable = cfg.variable -- kept out of the way to avoid problems
- local _ = wesnoth.textdomain "wesnoth"
- -- #textdomain wesnoth
- local harmer
-
- local function toboolean( value ) -- helper for animate fields
- -- units will be animated upon leveling or killing, even
- -- with special attacker and defender values
- if value then return true
- else return false end
- end
-
- local this_unit = utils.start_var_scope("this_unit")
-
- for index, unit_to_harm in ipairs(wesnoth.get_units(filter)) do
- if unit_to_harm.valid then
- -- block to support $this_unit
- wesnoth.set_variable ( "this_unit" ) -- clearing this_unit
- wesnoth.set_variable("this_unit", unit_to_harm.__cfg) -- cfg field needed
- local amount = tonumber(cfg.amount)
- local animate = cfg.animate -- attacker and defender are special values
- local delay = cfg.delay or 500
- local kill = cfg.kill
- local fire_event = cfg.fire_event
- local primary_attack = helper.get_child(cfg, "primary_attack")
- local secondary_attack = helper.get_child(cfg, "secondary_attack")
- local harmer_filter = helper.get_child(cfg, "filter_second")
- local experience = cfg.experience
- local resistance_multiplier = tonumber(cfg.resistance_multiplier) or 1
- if harmer_filter then harmer = wesnoth.get_units(harmer_filter)[1] end
- -- end of block to support $this_unit
-
- if animate then
- if animate ~= "defender" and harmer and harmer.valid then
- wesnoth.scroll_to_tile(harmer.x, harmer.y, true)
- wml_actions.animate_unit {
- flag = "attack",
- hits = true,
- with_bars = true,
- T.filter { id = harmer.id },
- T.primary_attack ( primary_attack ),
- T.secondary_attack ( secondary_attack ),
- T.facing { x = unit_to_harm.x, y = unit_to_harm.y },
- }
- end
- wesnoth.scroll_to_tile(unit_to_harm.x, unit_to_harm.y, true)
- end
-
- -- the two functions below are taken straight from the C++ engine, utils.cpp and actions.cpp, with a few unuseful parts removed
- -- may be moved in helper.lua in 1.11
- local function round_damage( base_damage, bonus, divisor )
- local rounding
- if base_damage == 0 then return 0
- else
- if bonus < divisor or divisor == 1 then
- rounding = divisor / 2 - 0
- else
- rounding = divisor / 2 - 1
- end
- return math.max( 1, math.floor( ( base_damage * bonus + rounding ) / divisor ) )
- end
- end
-
- local function calculate_damage( base_damage, alignment, tod_bonus, resistance, modifier )
- local damage_multiplier = 100
- if alignment == "lawful" then
- damage_multiplier = damage_multiplier + tod_bonus
- elseif alignment == "chaotic" then
- damage_multiplier = damage_multiplier - tod_bonus
- elseif alignment == "liminal" then
- damage_multiplier = damage_multiplier - math.abs( tod_bonus )
- else -- neutral, do nothing
- end
- local resistance_modified = resistance * modifier
- damage_multiplier = damage_multiplier * resistance_modified
- local damage = round_damage( base_damage, damage_multiplier, 10000 ) -- if harmer.status.slowed, this may be 20000 ?
- return damage
- end
-
- local damage = calculate_damage(
- amount,
- cfg.alignment or "neutral",
- wesnoth.get_time_of_day( { unit_to_harm.x, unit_to_harm.y, true } ).lawful_bonus,
- wesnoth.unit_resistance( unit_to_harm, cfg.damage_type or "dummy" ),
- resistance_multiplier
- )
-
- if unit_to_harm.hitpoints <= damage then
- if kill == false then damage = unit_to_harm.hitpoints - 1
- else damage = unit_to_harm.hitpoints
- end
- end
-
- unit_to_harm.hitpoints = unit_to_harm.hitpoints - damage
- local text = string.format("%d%s", damage, "\n")
- local add_tab = false
- local gender = unit_to_harm.__cfg.gender
-
- local function set_status(name, male_string, female_string, sound)
- if not cfg[name] or unit_to_harm.status[name] then return end
- if gender == "female" then
- text = string.format("%s%s%s", text, tostring(female_string), "\n")
- else
- text = string.format("%s%s%s", text, tostring(male_string), "\n")
- end
-
- unit_to_harm.status[name] = true
- add_tab = true
-
- if animate and sound then -- for unhealable, that has no sound
- wesnoth.play_sound (sound)
- end
- end
-
- if not unit_to_harm.status.unpoisonable then
- set_status("poisoned", _"poisoned", _"female^poisoned", "poison.ogg")
- end
- set_status("slowed", _"slowed", _"female^slowed", "slowed.wav")
- set_status("petrified", _"petrified", _"female^petrified", "petrified.ogg")
- set_status("unhealable", _"unhealable", _"female^unhealable")
-
- -- Extract unit and put it back to update animation if status was changed
- wesnoth.extract_unit(unit_to_harm)
- wesnoth.put_unit(unit_to_harm)
-
- if add_tab then
- text = string.format("%s%s", "\t", text)
- end
-
- if animate and animate ~= "attacker" then
- if harmer and harmer.valid then
- wml_actions.animate_unit {
- flag = "defend",
- hits = true,
- with_bars = true,
- T.filter { id = unit_to_harm.id },
- T.primary_attack ( primary_attack ),
- T.secondary_attack ( secondary_attack ),
- T.facing { x = harmer.x, y = harmer.y },
- }
- else
- wml_actions.animate_unit {
- flag = "defend",
- hits = true,
- with_bars = true,
- T.filter { id = unit_to_harm.id },
- T.primary_attack ( primary_attack ),
- T.secondary_attack ( secondary_attack ),
- }
- end
- end
-
- wesnoth.float_label( unit_to_harm.x, unit_to_harm.y, string.format( "%s", text ) )
-
- local function calc_xp( level ) -- to calculate the experience in case of kill
- if level == 0 then return 4
- else return level * 8 end
- end
-
- if experience ~= false and harmer and harmer.valid and wesnoth.is_enemy( unit_to_harm.side, harmer.side ) then -- no XP earned for harming friendly units
- if kill ~= false and unit_to_harm.hitpoints <= 0 then
- harmer.experience = harmer.experience + calc_xp( unit_to_harm.__cfg.level )
- else
- unit_to_harm.experience = unit_to_harm.experience + harmer.__cfg.level
- harmer.experience = harmer.experience + unit_to_harm.__cfg.level
- end
- end
-
- if kill ~= false and unit_to_harm.hitpoints <= 0 then
- wml_actions.kill { id = unit_to_harm.id, animate = toboolean( animate ), fire_event = fire_event }
- end
-
- if animate then
- wesnoth.delay(delay)
- end
-
- if variable then
- wesnoth.set_variable(string.format("%s[%d]", variable, index - 1), { harm_amount = damage })
- end
-
- -- both units may no longer be alive at this point, so double check
- if experience ~= false and unit_to_harm and unit_to_harm.valid then
- unit_to_harm:advance(toboolean(animate), fire_event ~= false)
- end
-
- if experience ~= false and harmer and harmer.valid then
- harmer:advance(toboolean(animate), fire_event ~= false)
- end
- end
-
- wml_actions.redraw {}
- end
-
- wesnoth.set_variable ( "this_unit" ) -- clearing this_unit
- utils.end_var_scope("this_unit", this_unit)
-end
-
function wml_actions.heal_unit(cfg)
wesnoth.heal_unit(cfg)
end
@@ -1255,103 +733,6 @@ function wml_actions.add_ai_behavior(cfg)
}
end
-function wml_actions.find_path(cfg)
- local filter_unit = helper.get_child(cfg, "traveler") or helper.wml_error("[find_path] missing required [traveler] tag")
- -- only the first unit matching
- local unit = wesnoth.get_units(filter_unit)[1] or helper.wml_error("[find_path]'s filter didn't match any unit")
- local filter_location = helper.get_child(cfg, "destination") or helper.wml_error( "[find_path] missing required [destination] tag" )
- -- support for $this_unit
- local this_unit = utils.start_var_scope("this_unit")
-
- wesnoth.set_variable ( "this_unit" ) -- clearing this_unit
- wesnoth.set_variable("this_unit", unit.__cfg) -- cfg field needed
-
- local variable = cfg.variable or "path"
- local ignore_units = false
- local ignore_teleport = false
-
- if cfg.check_zoc == false then --if we do not want to check the ZoCs, we must ignore units
- ignore_units = true
- end
- if cfg.check_teleport == false then --if we do not want to check teleport, we must ignore it
- ignore_teleport = true
- end
-
- local allow_multiple_turns = cfg.allow_multiple_turns
- local viewing_side
-
- if not cfg.check_visibility then viewing_side = 0 end -- if check_visiblity then shroud is taken in account
-
- local locations = wesnoth.get_locations(filter_location) -- only the location with the lowest distance and lowest movement cost will match. If there will still be more than 1, only the 1st maching one.
- local max_cost = nil
- if not allow_multiple_turns then max_cost = unit.moves end --to avoid wrong calculation on already moved units
- local current_distance, current_cost = math.huge, math.huge
- local current_location = {}
-
- local width,heigth,border = wesnoth.get_map_size() -- data for test below
-
- for index, location in ipairs(locations) do
- -- we test if location passed to pathfinder is invalid (border); if is, do nothing, do not return and continue the cycle
- if location[1] == 0 or location[1] == ( width + 1 ) or location[2] == 0 or location[2] == ( heigth + 1 ) then
- else
- local distance = helper.distance_between ( unit.x, unit.y, location[1], location[2] )
- -- if we pass an unreachable locations an high value will be returned
- local path, cost = wesnoth.find_path( unit, location[1], location[2], { max_cost = max_cost, ignore_units = ignore_units, ignore_teleport = ignore_teleport, viewing_side = viewing_side } )
-
- if ( distance < current_distance and cost <= current_cost ) or ( cost < current_cost and distance <= current_distance ) then -- to avoid changing the hex with one with less distance and more cost, or vice versa
- current_distance = distance
- current_cost = cost
- current_location = location
- end
- end
- end
-
- if #current_location == 0 then wesnoth.message("WML warning","[find_path]'s filter didn't match any location")
- else
- local path, cost = wesnoth.find_path( unit, current_location[1], current_location[2], { max_cost = max_cost, ignore_units = ignore_units, ignore_teleport = ignore_teleport, viewing_side = viewing_side } )
- local turns
-
- if cost == 0 then -- if location is the same, of course it doesn't cost any MP
- turns = 0
- else
- turns = math.ceil( ( ( cost - unit.moves ) / unit.max_moves ) + 1 )
- end
-
- if cost >= 42424242 then -- it's the high value returned for unwalkable or busy terrains
- wesnoth.set_variable ( string.format("%s", variable), { hexes = 0 } ) -- set only length, nil all other values
- -- support for $this_unit
- wesnoth.set_variable ( "this_unit" ) -- clearing this_unit
- utils.end_var_scope("this_unit", this_unit)
- return end
-
- if not allow_multiple_turns and turns > 1 then -- location cannot be reached in one turn
- wesnoth.set_variable ( string.format("%s", variable), { hexes = 0 } )
- -- support for $this_unit
- wesnoth.set_variable ( "this_unit" ) -- clearing this_unit
- utils.end_var_scope("this_unit", this_unit)
- return end -- skip the cycles below
-
- wesnoth.set_variable ( string.format( "%s", variable ), { hexes = current_distance, from_x = unit.x, from_y = unit.y, to_x = current_location[1], to_y = current_location[2], movement_cost = cost, required_turns = turns } )
-
- for index, path_loc in ipairs(path) do
- local sub_path, sub_cost = wesnoth.find_path( unit, path_loc[1], path_loc[2], { max_cost = max_cost, ignore_units = ignore_units, ignore_teleport = ignore_teleport, viewing_side = viewing_side } )
- local sub_turns
-
- if sub_cost == 0 then
- sub_turns = 0
- else
- sub_turns = math.ceil( ( ( sub_cost - unit.moves ) / unit.max_moves ) + 1 )
- end
-
- wesnoth.set_variable ( string.format( "%s.step[%d]", variable, index - 1 ), { x = path_loc[1], y = path_loc[2], terrain = wesnoth.get_terrain( path_loc[1], path_loc[2] ), movement_cost = sub_cost, required_turns = sub_turns } ) -- this structure takes less space in the inspection window
- end
- end
-
- -- support for $this_unit
- wesnoth.set_variable ( "this_unit" ) -- clearing this_unit
- utils.end_var_scope("this_unit", this_unit)
-end
-
function wml_actions.store_starting_location(cfg)
local writer = utils.vwriter.init(cfg, "location")
for possibly_wrong_index, side in ipairs(wesnoth.get_sides(cfg)) do
@@ -1459,98 +840,6 @@ function wml_actions.end_turn(cfg)
wesnoth.end_turn()
end
-function wml_actions.endlevel(cfg)
- local parsed = helper.parsed(cfg)
- if wesnoth.check_end_level_disabled() then
- wesnoth.message("Repeated [endlevel] execution, ignoring")
- return
- end
-
- local next_scenario = cfg.next_scenario
- if next_scenario then
- wesnoth.set_next_scenario(next_scenario)
- end
-
- local end_text = cfg.end_text
- local end_text_duration = cfg.end_text_duration
- if end_text or end_text_duration then
- wesnoth.set_end_campaign_text(end_text or "", end_text_duration)
- end
-
- local end_credits = cfg.end_credits
- if end_credits ~= nil then
- wesnoth.set_end_campaign_credits(end_credits)
- end
-
- local side_results = {}
- for result in helper.child_range(parsed, "result") do
- local side = result.side or helper.wml_error("[result] in [endlevel] missing required side= key")
- side_results[side] = result
- end
- local there_is_a_human_victory = false
- local there_is_a_human_defeat = false
- local there_is_a_local_human_victory = false
- local there_is_a_local_human_defeat = false
- local bool_int = function(b)
- if b == true then
- return 1
- elseif b == false then
- return 0
- else
- return b
- end
- end
- for k,v in ipairs(wesnoth.sides) do
- local side_result = side_results[v.side] or {}
- local victory_or_defeat = side_result.result or cfg.result or "victory"
- local victory = victory_or_defeat == "victory"
- if victory_or_defeat ~= "victory" and victory_or_defeat ~= "defeat" then
- return helper.wml_error("invalid result= key in [endlevel] '" .. victory_or_defeat .."'")
- end
- if v.controller == "human" or v.controller == "network" then
- if victory then
- there_is_a_human_victory = true
- else
- there_is_a_human_defeat = true
- end
- end
- if v.controller == "human" then
- if victory then
- there_is_a_local_human_victory = true
- else
- there_is_a_local_human_defeat = true
- end
- end
- if side_result.bonus ~= nil then
- v.carryover_bonus = bool_int(side_result.bonus)
- elseif cfg.bonus ~= nil then
- v.carryover_bonus = bool_int(cfg.bonus)
- end
- if side_result.carryover_add ~= nil then
- v.carryover_add = side_result.carryover_add
- elseif cfg.carryover_add ~= nil then
- v.carryover_add = cfg.carryover_add
- end
- if side_result.carryover_percentage ~= nil then
- v.carryover_percentage = side_result.carryover_percentage
- elseif cfg.carryover_percentage ~= nil then
- v.carryover_percentage = cfg.carryover_percentage
- end
- end
- local proceed_to_next_level = there_is_a_human_victory or (not there_is_a_human_defeat and cfg.result ~= "defeat")
- local victory = there_is_a_local_human_victory or (not there_is_a_local_human_defeat and proceed_to_next_level)
- wesnoth.end_level {
- music = cfg.music,
- carryover_report = cfg.carryover_report,
- save = cfg.save,
- replay_save = cfg.replay_save,
- linger_mode = cfg.linger_mode,
- reveal_map = cfg.reveal_map,
- proceed_to_next_level = proceed_to_next_level,
- result = victory and "victory" or "defeat",
- }
-end
-
function wml_actions.event(cfg)
if cfg.remove then
wml_actions.remove_event(cfg)
@@ -1661,79 +950,6 @@ function wml_actions.unsynced(cfg)
end)
end
-wesnoth.wml_actions.random_placement = function(cfg)
- local dist_le = nil
-
- local parsed = helper.shallow_parsed(cfg)
- -- TODO: In most cases this tag is used to place units, so maybe make include_borders=no the default for [filter_location]?
- local filter = helper.get_child(parsed, "filter_location") or {}
- local command = helper.get_child(parsed, "command") or helper.wml_error("[random_placement] missing required [command] subtag")
- local distance = cfg.min_distance or 0
- local num_items = cfg.num_items or helper.wml_error("[random_placement] missing required 'num_items' attribute")
- local variable = cfg.variable or helper.wml_error("[random_placement] missing required 'variable' attribute")
- local allow_less = cfg.allow_less == true
- local variable_previous = utils.start_var_scope(variable)
-
- if distance < 0 then
- -- optimisation for distance = -1
- dist_le = function() return false end
- elseif distance == 0 then
- -- optimisation for distance = 0
- dist_le = function(x1,y1,x2,y2) return x1 == x2 and y1 == y2 end
- else
- -- optimisation: cloasure is faster than string lookups.
- local math_abs = math.abs
- -- same effect as helper.distance_between(x1,y1,x2,y2) <= distance but faster.
- dist_le = function(x1,y1,x2,y2)
- local d_x = math_abs(x1-x2)
- if d_x > distance then
- return false
- end
- if d_x % 2 ~= 0 then
- if x1 % 2 == 0 then
- y2 = y2 - 0.5
- else
- y2 = y2 + 0.5
- end
- end
- local d_y = math_abs(y1-y2)
- return d_x + 2*d_y <= 2*distance
- end
- end
-
- local locs = wesnoth.get_locations(filter)
- if type(num_items) == "string" then
- num_items = math.floor(loadstring("local size = " .. #locs .. "; return " .. num_items)())
- print("num_items=" .. num_items .. ", #locs=" .. #locs)
- end
- local size = #locs
- for i = 1, num_items do
- if size == 0 then
- if allow_less then
- print("placed only " .. i .. " items")
- return
- else
- helper.wml_error("[random_placement] failed to place items. only " .. i .. " items were placed")
- end
- end
- local index = wesnoth.random(size)
- local point = locs[index]
- wesnoth.set_variable(variable .. ".x", point[1])
- wesnoth.set_variable(variable .. ".y", point[2])
- wesnoth.set_variable(variable .. ".n", i)
- for j = size, 1, -1 do
- if dist_le(locs[j][1], locs[j][2], point[1], point[2]) then
- -- optimisation: swapping elements and storing size in an extra variable is faster than table.remove(locs, j)
- locs[j] = locs[size]
- size = size - 1
- end
- end
- wesnoth.wml_actions.command (command)
- end
- utils.end_var_scope(variable, variable_previous)
-
-end
-
local function on_board(x, y)
if type(x) ~= "number" or type(y) ~= "number" then
return false
@@ -1788,6 +1004,42 @@ wml_actions.teleport = function(cfg)
wesnoth.teleport(unit, cfg.check_passability == false, cfg.clear_shroud ~= false, cfg.animate)
end
+function wml_actions.remove_sound_source(cfg)
+ wesnoth.remove_sound_source(cfg.id)
+end
+
+function wml_actions.sound_source(cfg)
+ wesnoth.add_sound_source(cfg)
+end
+
+function wml_actions.deprecated_message(cfg)
+ wesnoth.log('wml', cfg.message)
+end
+
+function wml_actions.wml_message(cfg)
+ local logger = cfg.logger or ''
+ wesnoth.log(cfg.logger, cfg.message, cfg.to_chat)
+end
+
+local function parse_fog_cfg(cfg)
+ -- Side filter
+ local ssf = helper.child(cfg, "filter_side")
+ local sides = wesnoth.get_sides(ssf or {})
+ -- Location filter
+ local locs = wesnoth.get_locations(cfg)
+ return locs, sides
+end
+
+function wml_actions.lift_fog(cfg)
+ local locs, sides = parse_fog_cfg(cfg)
+ wesnoth.remove_fog(sides, locs, not cfg.multiturn)
+end
+
+function wml_actions.reset_fog(cfg)
+ local locs, sides = parse_fog_cfg(cfg)
+ wesnoth.add_fog(sides, locs, cfg.reset_view)
+end
+
function wml_actions.set_variable(cfg)
local name = cfg.name or helper.wml_error "trying to set a variable with an empty name"
local var = wesnoth.get_variable(name)
@@ -1920,3 +1172,4 @@ function wml_actions.set_variable(cfg)
wesnoth.set_variable(name, table.concat(string_to_join, separator))
end
end
+end
diff --git a/data/lua/wml/endlevel.lua b/data/lua/wml/endlevel.lua
new file mode 100644
index 000000000000..67cdbbd3a52f
--- /dev/null
+++ b/data/lua/wml/endlevel.lua
@@ -0,0 +1,93 @@
+local helper = wesnoth.require "lua/helper.lua"
+
+function wesnoth.wml_actions.endlevel(cfg)
+ local parsed = helper.parsed(cfg)
+ if wesnoth.check_end_level_disabled() then
+ wesnoth.message("Repeated [endlevel] execution, ignoring")
+ return
+ end
+
+ local next_scenario = cfg.next_scenario
+ if next_scenario then
+ wesnoth.set_next_scenario(next_scenario)
+ end
+
+ local end_text = cfg.end_text
+ local end_text_duration = cfg.end_text_duration
+ if end_text or end_text_duration then
+ wesnoth.set_end_campaign_text(end_text or "", end_text_duration)
+ end
+
+ local end_credits = cfg.end_credits
+ if end_credits ~= nil then
+ wesnoth.set_end_campaign_credits(end_credits)
+ end
+
+ local side_results = {}
+ for result in helper.child_range(parsed, "result") do
+ local side = result.side or helper.wml_error("[result] in [endlevel] missing required side= key")
+ side_results[side] = result
+ end
+ local there_is_a_human_victory = false
+ local there_is_a_human_defeat = false
+ local there_is_a_local_human_victory = false
+ local there_is_a_local_human_defeat = false
+ local bool_int = function(b)
+ if b == true then
+ return 1
+ elseif b == false then
+ return 0
+ else
+ return b
+ end
+ end
+ for k,v in ipairs(wesnoth.sides) do
+ local side_result = side_results[v.side] or {}
+ local victory_or_defeat = side_result.result or cfg.result or "victory"
+ local victory = victory_or_defeat == "victory"
+ if victory_or_defeat ~= "victory" and victory_or_defeat ~= "defeat" then
+ return helper.wml_error("invalid result= key in [endlevel] '" .. victory_or_defeat .."'")
+ end
+ if v.controller == "human" or v.controller == "network" then
+ if victory then
+ there_is_a_human_victory = true
+ else
+ there_is_a_human_defeat = true
+ end
+ end
+ if v.controller == "human" then
+ if victory then
+ there_is_a_local_human_victory = true
+ else
+ there_is_a_local_human_defeat = true
+ end
+ end
+ if side_result.bonus ~= nil then
+ v.carryover_bonus = bool_int(side_result.bonus)
+ elseif cfg.bonus ~= nil then
+ v.carryover_bonus = bool_int(cfg.bonus)
+ end
+ if side_result.carryover_add ~= nil then
+ v.carryover_add = side_result.carryover_add
+ elseif cfg.carryover_add ~= nil then
+ v.carryover_add = cfg.carryover_add
+ end
+ if side_result.carryover_percentage ~= nil then
+ v.carryover_percentage = side_result.carryover_percentage
+ elseif cfg.carryover_percentage ~= nil then
+ v.carryover_percentage = cfg.carryover_percentage
+ end
+ end
+ local proceed_to_next_level = there_is_a_human_victory or (not there_is_a_human_defeat and cfg.result ~= "defeat")
+ local victory = there_is_a_local_human_victory or (not there_is_a_local_human_defeat and proceed_to_next_level)
+ wesnoth.end_level {
+ music = cfg.music,
+ carryover_report = cfg.carryover_report,
+ save = cfg.save,
+ replay_save = cfg.replay_save,
+ linger_mode = cfg.linger_mode,
+ reveal_map = cfg.reveal_map,
+ proceed_to_next_level = proceed_to_next_level,
+ result = victory and "victory" or "defeat",
+ }
+end
\ No newline at end of file
diff --git a/data/lua/wml/find_path.lua b/data/lua/wml/find_path.lua
new file mode 100644
index 000000000000..654597c66159
--- /dev/null
+++ b/data/lua/wml/find_path.lua
@@ -0,0 +1,99 @@
+local helper = wesnoth.require "lua/helper.lua"
+local utils = wesnoth.require "lua/wml-utils.lua"
+
+function wesnoth.wml_actions.find_path(cfg)
+ local filter_unit = helper.get_child(cfg, "traveler") or helper.wml_error("[find_path] missing required [traveler] tag")
+ -- only the first unit matching
+ local unit = wesnoth.get_units(filter_unit)[1] or helper.wml_error("[find_path]'s filter didn't match any unit")
+ local filter_location = helper.get_child(cfg, "destination") or helper.wml_error( "[find_path] missing required [destination] tag" )
+ -- support for $this_unit
+ local this_unit = utils.start_var_scope("this_unit")
+
+ wesnoth.set_variable ( "this_unit" ) -- clearing this_unit
+ wesnoth.set_variable("this_unit", unit.__cfg) -- cfg field needed
+
+ local variable = cfg.variable or "path"
+ local ignore_units = false
+ local ignore_teleport = false
+
+ if cfg.check_zoc == false then --if we do not want to check the ZoCs, we must ignore units
+ ignore_units = true
+ end
+ if cfg.check_teleport == false then --if we do not want to check teleport, we must ignore it
+ ignore_teleport = true
+ end
+
+ local allow_multiple_turns = cfg.allow_multiple_turns
+ local viewing_side
+
+ if not cfg.check_visibility then viewing_side = 0 end -- if check_visiblity then shroud is taken in account
+
+ local locations = wesnoth.get_locations(filter_location) -- only the location with the lowest distance and lowest movement cost will match. If there will still be more than 1, only the 1st maching one.
+ local max_cost = nil
+ if not allow_multiple_turns then max_cost = unit.moves end --to avoid wrong calculation on already moved units
+ local current_distance, current_cost = math.huge, math.huge
+ local current_location = {}
+
+ local width,heigth,border = wesnoth.get_map_size() -- data for test below
+
+ for index, location in ipairs(locations) do
+ -- we test if location passed to pathfinder is invalid (border); if is, do nothing, do not return and continue the cycle
+ if location[1] == 0 or location[1] == ( width + 1 ) or location[2] == 0 or location[2] == ( heigth + 1 ) then
+ else
+ local distance = helper.distance_between ( unit.x, unit.y, location[1], location[2] )
+ -- if we pass an unreachable locations an high value will be returned
+ local path, cost = wesnoth.find_path( unit, location[1], location[2], { max_cost = max_cost, ignore_units = ignore_units, ignore_teleport = ignore_teleport, viewing_side = viewing_side } )
+
+ if ( distance < current_distance and cost <= current_cost ) or ( cost < current_cost and distance <= current_distance ) then -- to avoid changing the hex with one with less distance and more cost, or vice versa
+ current_distance = distance
+ current_cost = cost
+ current_location = location
+ end
+ end
+ end
+
+ if #current_location == 0 then wesnoth.message("WML warning","[find_path]'s filter didn't match any location")
+ else
+ local path, cost = wesnoth.find_path( unit, current_location[1], current_location[2], { max_cost = max_cost, ignore_units = ignore_units, ignore_teleport = ignore_teleport, viewing_side = viewing_side } )
+ local turns
+
+ if cost == 0 then -- if location is the same, of course it doesn't cost any MP
+ turns = 0
+ else
+ turns = math.ceil( ( ( cost - unit.moves ) / unit.max_moves ) + 1 )
+ end
+
+ if cost >= 42424242 then -- it's the high value returned for unwalkable or busy terrains
+ wesnoth.set_variable ( string.format("%s", variable), { hexes = 0 } ) -- set only length, nil all other values
+ -- support for $this_unit
+ wesnoth.set_variable ( "this_unit" ) -- clearing this_unit
+ utils.end_var_scope("this_unit", this_unit)
+ return end
+
+ if not allow_multiple_turns and turns > 1 then -- location cannot be reached in one turn
+ wesnoth.set_variable ( string.format("%s", variable), { hexes = 0 } )
+ -- support for $this_unit
+ wesnoth.set_variable ( "this_unit" ) -- clearing this_unit
+ utils.end_var_scope("this_unit", this_unit)
+ return end -- skip the cycles below
+
+ wesnoth.set_variable ( string.format( "%s", variable ), { hexes = current_distance, from_x = unit.x, from_y = unit.y, to_x = current_location[1], to_y = current_location[2], movement_cost = cost, required_turns = turns } )
+
+ for index, path_loc in ipairs(path) do
+ local sub_path, sub_cost = wesnoth.find_path( unit, path_loc[1], path_loc[2], { max_cost = max_cost, ignore_units = ignore_units, ignore_teleport = ignore_teleport, viewing_side = viewing_side } )
+ local sub_turns
+
+ if sub_cost == 0 then
+ sub_turns = 0
+ else
+ sub_turns = math.ceil( ( ( sub_cost - unit.moves ) / unit.max_moves ) + 1 )
+ end
+
+ wesnoth.set_variable ( string.format( "%s.step[%d]", variable, index - 1 ), { x = path_loc[1], y = path_loc[2], terrain = wesnoth.get_terrain( path_loc[1], path_loc[2] ), movement_cost = sub_cost, required_turns = sub_turns } ) -- this structure takes less space in the inspection window
+ end
+ end
+
+ -- support for $this_unit
+ wesnoth.set_variable ( "this_unit" ) -- clearing this_unit
+ utils.end_var_scope("this_unit", this_unit)
+end
\ No newline at end of file
diff --git a/data/lua/wml/harm_unit.lua b/data/lua/wml/harm_unit.lua
new file mode 100644
index 000000000000..30fbbb47c8e9
--- /dev/null
+++ b/data/lua/wml/harm_unit.lua
@@ -0,0 +1,204 @@
+local helper = wesnoth.require "lua/helper.lua"
+local utils = wesnoth.require "lua/wml-utils.lua"
+local wml_actions = wesnoth.wml_actions
+
+function wml_actions.harm_unit(cfg)
+ local filter = helper.get_child(cfg, "filter") or helper.wml_error("[harm_unit] missing required [filter] tag")
+ -- we need to use shallow_literal field, to avoid raising an error if $this_unit (not yet assigned) is used
+ if not helper.shallow_literal(cfg).amount then helper.wml_error("[harm_unit] has missing required amount= attribute") end
+ local variable = cfg.variable -- kept out of the way to avoid problems
+ local _ = wesnoth.textdomain "wesnoth"
+ -- #textdomain wesnoth
+ local harmer
+
+ local function toboolean( value ) -- helper for animate fields
+ -- units will be animated upon leveling or killing, even
+ -- with special attacker and defender values
+ if value then return true
+ else return false end
+ end
+
+ local this_unit = utils.start_var_scope("this_unit")
+
+ for index, unit_to_harm in ipairs(wesnoth.get_units(filter)) do
+ if unit_to_harm.valid then
+ -- block to support $this_unit
+ wesnoth.set_variable ( "this_unit" ) -- clearing this_unit
+ wesnoth.set_variable("this_unit", unit_to_harm.__cfg) -- cfg field needed
+ local amount = tonumber(cfg.amount)
+ local animate = cfg.animate -- attacker and defender are special values
+ local delay = cfg.delay or 500
+ local kill = cfg.kill
+ local fire_event = cfg.fire_event
+ local primary_attack = helper.get_child(cfg, "primary_attack")
+ local secondary_attack = helper.get_child(cfg, "secondary_attack")
+ local harmer_filter = helper.get_child(cfg, "filter_second")
+ local experience = cfg.experience
+ local resistance_multiplier = tonumber(cfg.resistance_multiplier) or 1
+ if harmer_filter then harmer = wesnoth.get_units(harmer_filter)[1] end
+ -- end of block to support $this_unit
+
+ if animate then
+ if animate ~= "defender" and harmer and harmer.valid then
+ wesnoth.scroll_to_tile(harmer.x, harmer.y, true)
+ wml_actions.animate_unit {
+ flag = "attack",
+ hits = true,
+ with_bars = true,
+ T.filter { id = harmer.id },
+ T.primary_attack ( primary_attack ),
+ T.secondary_attack ( secondary_attack ),
+ T.facing { x = unit_to_harm.x, y = unit_to_harm.y },
+ }
+ end
+ wesnoth.scroll_to_tile(unit_to_harm.x, unit_to_harm.y, true)
+ end
+
+ -- the two functions below are taken straight from the C++ engine, utils.cpp and actions.cpp, with a few unuseful parts removed
+ -- may be moved in helper.lua in 1.11
+ local function round_damage( base_damage, bonus, divisor )
+ local rounding
+ if base_damage == 0 then return 0
+ else
+ if bonus < divisor or divisor == 1 then
+ rounding = divisor / 2 - 0
+ else
+ rounding = divisor / 2 - 1
+ end
+ return math.max( 1, math.floor( ( base_damage * bonus + rounding ) / divisor ) )
+ end
+ end
+
+ local function calculate_damage( base_damage, alignment, tod_bonus, resistance, modifier )
+ local damage_multiplier = 100
+ if alignment == "lawful" then
+ damage_multiplier = damage_multiplier + tod_bonus
+ elseif alignment == "chaotic" then
+ damage_multiplier = damage_multiplier - tod_bonus
+ elseif alignment == "liminal" then
+ damage_multiplier = damage_multiplier - math.abs( tod_bonus )
+ else -- neutral, do nothing
+ end
+ local resistance_modified = resistance * modifier
+ damage_multiplier = damage_multiplier * resistance_modified
+ local damage = round_damage( base_damage, damage_multiplier, 10000 ) -- if harmer.status.slowed, this may be 20000 ?
+ return damage
+ end
+
+ local damage = calculate_damage(
+ amount,
+ cfg.alignment or "neutral",
+ wesnoth.get_time_of_day( { unit_to_harm.x, unit_to_harm.y, true } ).lawful_bonus,
+ wesnoth.unit_resistance( unit_to_harm, cfg.damage_type or "dummy" ),
+ resistance_multiplier
+ )
+
+ if unit_to_harm.hitpoints <= damage then
+ if kill == false then damage = unit_to_harm.hitpoints - 1
+ else damage = unit_to_harm.hitpoints
+ end
+ end
+
+ unit_to_harm.hitpoints = unit_to_harm.hitpoints - damage
+ local text = string.format("%d%s", damage, "\n")
+ local add_tab = false
+ local gender = unit_to_harm.__cfg.gender
+
+ local function set_status(name, male_string, female_string, sound)
+ if not cfg[name] or unit_to_harm.status[name] then return end
+ if gender == "female" then
+ text = string.format("%s%s%s", text, tostring(female_string), "\n")
+ else
+ text = string.format("%s%s%s", text, tostring(male_string), "\n")
+ end
+
+ unit_to_harm.status[name] = true
+ add_tab = true
+
+ if animate and sound then -- for unhealable, that has no sound
+ wesnoth.play_sound (sound)
+ end
+ end
+
+ if not unit_to_harm.status.unpoisonable then
+ set_status("poisoned", _"poisoned", _"female^poisoned", "poison.ogg")
+ end
+ set_status("slowed", _"slowed", _"female^slowed", "slowed.wav")
+ set_status("petrified", _"petrified", _"female^petrified", "petrified.ogg")
+ set_status("unhealable", _"unhealable", _"female^unhealable")
+
+ -- Extract unit and put it back to update animation if status was changed
+ wesnoth.extract_unit(unit_to_harm)
+ wesnoth.put_unit(unit_to_harm)
+
+ if add_tab then
+ text = string.format("%s%s", "\t", text)
+ end
+
+ if animate and animate ~= "attacker" then
+ if harmer and harmer.valid then
+ wml_actions.animate_unit {
+ flag = "defend",
+ hits = true,
+ with_bars = true,
+ T.filter { id = unit_to_harm.id },
+ T.primary_attack ( primary_attack ),
+ T.secondary_attack ( secondary_attack ),
+ T.facing { x = harmer.x, y = harmer.y },
+ }
+ else
+ wml_actions.animate_unit {
+ flag = "defend",
+ hits = true,
+ with_bars = true,
+ T.filter { id = unit_to_harm.id },
+ T.primary_attack ( primary_attack ),
+ T.secondary_attack ( secondary_attack ),
+ }
+ end
+ end
+
+ wesnoth.float_label( unit_to_harm.x, unit_to_harm.y, string.format( "%s", text ) )
+
+ local function calc_xp( level ) -- to calculate the experience in case of kill
+ if level == 0 then return 4
+ else return level * 8 end
+ end
+
+ if experience ~= false and harmer and harmer.valid and wesnoth.is_enemy( unit_to_harm.side, harmer.side ) then -- no XP earned for harming friendly units
+ if kill ~= false and unit_to_harm.hitpoints <= 0 then
+ harmer.experience = harmer.experience + calc_xp( unit_to_harm.__cfg.level )
+ else
+ unit_to_harm.experience = unit_to_harm.experience + harmer.__cfg.level
+ harmer.experience = harmer.experience + unit_to_harm.__cfg.level
+ end
+ end
+
+ if kill ~= false and unit_to_harm.hitpoints <= 0 then
+ wml_actions.kill { id = unit_to_harm.id, animate = toboolean( animate ), fire_event = fire_event }
+ end
+
+ if animate then
+ wesnoth.delay(delay)
+ end
+
+ if variable then
+ wesnoth.set_variable(string.format("%s[%d]", variable, index - 1), { harm_amount = damage })
+ end
+
+ -- both units may no longer be alive at this point, so double check
+ if experience ~= false and unit_to_harm and unit_to_harm.valid then
+ unit_to_harm:advance(toboolean(animate), fire_event ~= false)
+ end
+
+ if experience ~= false and harmer and harmer.valid then
+ harmer:advance(toboolean(animate), fire_event ~= false)
+ end
+ end
+
+ wml_actions.redraw {}
+ end
+
+ wesnoth.set_variable ( "this_unit" ) -- clearing this_unit
+ utils.end_var_scope("this_unit", this_unit)
+end
\ No newline at end of file
diff --git a/data/lua/wml/message.lua b/data/lua/wml/message.lua
index 8f5b3629bca9..16c36e51847c 100644
--- a/data/lua/wml/message.lua
+++ b/data/lua/wml/message.lua
@@ -5,10 +5,7 @@ local location_set = wesnoth.require "lua/location_set.lua"
local _ = wesnoth.textdomain "wesnoth"
local function log(msg, level)
- wesnoth.wml_actions.wml_message({
- message = msg,
- logger = level,
- })
+ wesnoth.log(level, msg, true)
end
local function get_image(cfg, speaker)
@@ -24,6 +21,10 @@ local function get_image(cfg, speaker)
image = speaker.portrait
end
+ if image == "none" or image == nil then
+ return "", true
+ end
+
if image:find("~RIGHT%(%)") then
left_side = false
-- The percent signs escape the parentheses for a literal match
@@ -38,10 +39,6 @@ local function get_image(cfg, speaker)
image = image:gsub("~LEFT%(%)", "")
end
- if image == "none" or image == nil then
- return "", true
- end
-
return image, left_side
end
diff --git a/data/lua/wml/modify_unit.lua b/data/lua/wml/modify_unit.lua
new file mode 100644
index 000000000000..10766719e23a
--- /dev/null
+++ b/data/lua/wml/modify_unit.lua
@@ -0,0 +1,74 @@
+local helper = wesnoth.require "lua/helper.lua"
+local utils = wesnoth.require "lua/wml-utils.lua"
+local wml_actions = wesnoth.wml_actions
+
+function wml_actions.modify_unit(cfg)
+ local unit_variable = "LUA_modify_unit"
+
+ local function handle_attributes(cfg, unit_path, toplevel)
+ for current_key, current_value in pairs(helper.shallow_parsed(cfg)) do
+ if type(current_value) ~= "table" and (not toplevel or current_key ~= "type") then
+ wesnoth.set_variable(string.format("%s.%s", unit_path, current_key), current_value)
+ end
+ end
+ end
+
+ local function handle_child(cfg, unit_path)
+ local children_handled = {}
+ local cfg = helper.shallow_parsed(cfg)
+ handle_attributes(cfg, unit_path)
+
+ for current_index, current_table in ipairs(cfg) do
+ local current_tag = current_table[1]
+ local tag_index = children_handled[current_tag] or 0
+ handle_child(current_table[2], string.format("%s.%s[%u]",
+ unit_path, current_tag, tag_index))
+ children_handled[current_tag] = tag_index + 1
+ end
+ end
+
+ local filter = helper.get_child(cfg, "filter") or helper.wml_error "[modify_unit] missing required [filter] tag"
+ local function handle_unit(unit_num)
+ local children_handled = {}
+ local unit_path = string.format("%s[%u]", unit_variable, unit_num)
+ local this_unit = wesnoth.get_variable(unit_path)
+ wesnoth.set_variable("this_unit", this_unit)
+ handle_attributes(cfg, unit_path, true)
+
+ for current_index, current_table in ipairs(helper.shallow_parsed(cfg)) do
+ local current_tag = current_table[1]
+ if current_tag == "filter" then
+ -- nothing
+ elseif current_tag == "object" or current_tag == "trait" or current_tag == "advancement" then
+ local unit = wesnoth.get_variable(unit_path)
+ unit = wesnoth.create_unit(unit)
+ wesnoth.add_modification(unit, current_tag, current_table[2])
+ unit = unit.__cfg;
+ wesnoth.set_variable(unit_path, unit)
+ else
+ local tag_index = children_handled[current_tag] or 0
+ handle_child(current_table[2], string.format("%s.%s[%u]",
+ unit_path, current_tag, tag_index))
+ children_handled[current_tag] = tag_index + 1
+ end
+ end
+
+ if cfg.type then
+ if cfg.type ~= "" then wesnoth.set_variable(unit_path .. ".advances_to", cfg.type) end
+ wesnoth.set_variable(unit_path .. ".experience", wesnoth.get_variable(unit_path .. ".max_experience"))
+ end
+ wml_actions.kill({ id = this_unit.id, animate = false })
+ wml_actions.unstore_unit { variable = unit_path }
+ end
+
+ wml_actions.store_unit { {"filter", filter}, variable = unit_variable }
+ local max_index = wesnoth.get_variable(unit_variable .. ".length") - 1
+
+ local this_unit = utils.start_var_scope("this_unit")
+ for current_unit = 0, max_index do
+ handle_unit(current_unit)
+ end
+ utils.end_var_scope("this_unit", this_unit)
+
+ wesnoth.set_variable(unit_variable)
+end
\ No newline at end of file
diff --git a/data/lua/wml/random_placement.lua b/data/lua/wml/random_placement.lua
new file mode 100644
index 000000000000..6f4e1c66642e
--- /dev/null
+++ b/data/lua/wml/random_placement.lua
@@ -0,0 +1,75 @@
+local helper = wesnoth.require "lua/helper.lua"
+local utils = wesnoth.require "lua/wml-utils.lua"
+
+wesnoth.wml_actions.random_placement = function(cfg)
+ local dist_le = nil
+
+ local parsed = helper.shallow_parsed(cfg)
+ -- TODO: In most cases this tag is used to place units, so maybe make include_borders=no the default for [filter_location]?
+ local filter = helper.get_child(parsed, "filter_location") or {}
+ local command = helper.get_child(parsed, "command") or helper.wml_error("[random_placement] missing required [command] subtag")
+ local distance = cfg.min_distance or 0
+ local num_items = cfg.num_items or helper.wml_error("[random_placement] missing required 'num_items' attribute")
+ local variable = cfg.variable or helper.wml_error("[random_placement] missing required 'variable' attribute")
+ local allow_less = cfg.allow_less == true
+ local variable_previous = utils.start_var_scope(variable)
+
+ if distance < 0 then
+ -- optimisation for distance = -1
+ dist_le = function() return false end
+ elseif distance == 0 then
+ -- optimisation for distance = 0
+ dist_le = function(x1,y1,x2,y2) return x1 == x2 and y1 == y2 end
+ else
+ -- optimisation: cloasure is faster than string lookups.
+ local math_abs = math.abs
+ -- same effect as helper.distance_between(x1,y1,x2,y2) <= distance but faster.
+ dist_le = function(x1,y1,x2,y2)
+ local d_x = math_abs(x1-x2)
+ if d_x > distance then
+ return false
+ end
+ if d_x % 2 ~= 0 then
+ if x1 % 2 == 0 then
+ y2 = y2 - 0.5
+ else
+ y2 = y2 + 0.5
+ end
+ end
+ local d_y = math_abs(y1-y2)
+ return d_x + 2*d_y <= 2*distance
+ end
+ end
+
+ local locs = wesnoth.get_locations(filter)
+ if type(num_items) == "string" then
+ num_items = math.floor(loadstring("local size = " .. #locs .. "; return " .. num_items)())
+ print("num_items=" .. num_items .. ", #locs=" .. #locs)
+ end
+ local size = #locs
+ for i = 1, num_items do
+ if size == 0 then
+ if allow_less then
+ print("placed only " .. i .. " items")
+ return
+ else
+ helper.wml_error("[random_placement] failed to place items. only " .. i .. " items were placed")
+ end
+ end
+ local index = wesnoth.random(size)
+ local point = locs[index]
+ wesnoth.set_variable(variable .. ".x", point[1])
+ wesnoth.set_variable(variable .. ".y", point[2])
+ wesnoth.set_variable(variable .. ".n", i)
+ for j = size, 1, -1 do
+ if dist_le(locs[j][1], locs[j][2], point[1], point[2]) then
+ -- optimisation: swapping elements and storing size in an extra variable is faster than table.remove(locs, j)
+ locs[j] = locs[size]
+ size = size - 1
+ end
+ end
+ wesnoth.wml_actions.command (command)
+ end
+ utils.end_var_scope(variable, variable_previous)
+
+end
\ No newline at end of file
diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt
index 2eb79b622b5e..782f1e57b7e4 100644
--- a/doc/man/CMakeLists.txt
+++ b/doc/man/CMakeLists.txt
@@ -23,7 +23,7 @@ if(ENABLE_POT_UPDATE_TARGET)
COMMAND ${CMAKE_COMMAND}
-DPROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}"
-DMANPAGES="${ALL_MANPAGES}"
- -P "${CMAKE_MODULE_PATH}/po4a-man.cmake"
+ -P "${CMAKE_SOURCE_DIR}/cmake/po4a-man.cmake"
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/wesnoth.6
${CMAKE_CURRENT_SOURCE_DIR}/wesnothd.6
diff --git a/doc/manual/CMakeLists.txt b/doc/manual/CMakeLists.txt
index 3179de3ab612..7f193734303d 100644
--- a/doc/manual/CMakeLists.txt
+++ b/doc/manual/CMakeLists.txt
@@ -83,7 +83,7 @@ if(ENABLE_POT_UPDATE_TARGET)
COMMAND ${CMAKE_COMMAND}
-DSOURCE="manual.${LINGUA}.xml"
-DCMD="${CMD}"
- -P "${CMAKE_MODULE_PATH}/po4a-manual.cmake"
+ -P "${CMAKE_SOURCE_DIR}/cmake/po4a-manual.cmake"
COMMAND ${CMAKE_COMMAND} -E remove manual.${LINGUA}.xml
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/manual.${LINGUA}.xml
COMMENT "[update-po4a-manual ${LINGUA}] Building ${LINGUA}.html."
diff --git a/fonts/Lato-Bold.ttf b/fonts/Lato-Bold.ttf
new file mode 100644
index 000000000000..ef5ae3b43e99
Binary files /dev/null and b/fonts/Lato-Bold.ttf differ
diff --git a/fonts/Lato-Italic.ttf b/fonts/Lato-Italic.ttf
new file mode 100644
index 000000000000..b23256ff5326
Binary files /dev/null and b/fonts/Lato-Italic.ttf differ
diff --git a/fonts/Lato-Regular.ttf b/fonts/Lato-Regular.ttf
new file mode 100644
index 000000000000..adbfc467d2d0
Binary files /dev/null and b/fonts/Lato-Regular.ttf differ
diff --git a/fonts/OFL b/fonts/OFL
new file mode 100755
index 000000000000..6d2c4160b08f
--- /dev/null
+++ b/fonts/OFL
@@ -0,0 +1,94 @@
+Copyright (c) 2010-2015, Łukasz Dziedzic (dziedzic@typoland.com),
+with Reserved Font Name Lato.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/images/buttons/scrollbars/scrollgroove-bottom-minimal.png b/images/buttons/scrollbars/scrollgroove-bottom-minimal.png
deleted file mode 100644
index ff5792c03ce2..000000000000
Binary files a/images/buttons/scrollbars/scrollgroove-bottom-minimal.png and /dev/null differ
diff --git a/images/buttons/scrollbars/scrollgroove-mid-minimal.png b/images/buttons/scrollbars/scrollgroove-mid-minimal.png
deleted file mode 100644
index 16be9b99050c..000000000000
Binary files a/images/buttons/scrollbars/scrollgroove-mid-minimal.png and /dev/null differ
diff --git a/images/buttons/scrollbars/scrollgroove-top-minimal.png b/images/buttons/scrollbars/scrollgroove-top-minimal.png
deleted file mode 100644
index 2a79bfadec50..000000000000
Binary files a/images/buttons/scrollbars/scrollgroove-top-minimal.png and /dev/null differ
diff --git a/images/buttons/scrollbars/scrollhorizontal-active.png b/images/buttons/scrollbars/scrollhorizontal-active.png
index 3dc98f743c18..ca5aefec1808 100644
Binary files a/images/buttons/scrollbars/scrollhorizontal-active.png and b/images/buttons/scrollbars/scrollhorizontal-active.png differ
diff --git a/images/buttons/scrollbars/scrollhorizontal-pressed.png b/images/buttons/scrollbars/scrollhorizontal-pressed.png
index bfdeeba4764c..2c2e5cca7555 100644
Binary files a/images/buttons/scrollbars/scrollhorizontal-pressed.png and b/images/buttons/scrollbars/scrollhorizontal-pressed.png differ
diff --git a/images/buttons/scrollbars/scrollhorizontal.png b/images/buttons/scrollbars/scrollhorizontal.png
index a965ddaa56bb..b079d701c73a 100644
Binary files a/images/buttons/scrollbars/scrollhorizontal.png and b/images/buttons/scrollbars/scrollhorizontal.png differ
diff --git a/images/buttons/scrollbars/scrollleft-active.png b/images/buttons/scrollbars/scrollleft-active.png
index 9b46a81a431e..004ed4a0bb07 100644
Binary files a/images/buttons/scrollbars/scrollleft-active.png and b/images/buttons/scrollbars/scrollleft-active.png differ
diff --git a/images/buttons/scrollbars/scrollleft-pressed.png b/images/buttons/scrollbars/scrollleft-pressed.png
index e50d2ebd2d19..50f0ede923d3 100644
Binary files a/images/buttons/scrollbars/scrollleft-pressed.png and b/images/buttons/scrollbars/scrollleft-pressed.png differ
diff --git a/images/buttons/scrollbars/scrollleft.png b/images/buttons/scrollbars/scrollleft.png
index 1b06489af3e5..4b6a097d3d6d 100644
Binary files a/images/buttons/scrollbars/scrollleft.png and b/images/buttons/scrollbars/scrollleft.png differ
diff --git a/images/buttons/scrollbars/scrollmid-active.png b/images/buttons/scrollbars/scrollmid-active.png
index 0920f4505b1f..893c7b59a1a5 100644
Binary files a/images/buttons/scrollbars/scrollmid-active.png and b/images/buttons/scrollbars/scrollmid-active.png differ
diff --git a/images/buttons/scrollbars/scrollmid-pressed.png b/images/buttons/scrollbars/scrollmid-pressed.png
index a62272bf0a7c..1b891113040e 100644
Binary files a/images/buttons/scrollbars/scrollmid-pressed.png and b/images/buttons/scrollbars/scrollmid-pressed.png differ
diff --git a/images/buttons/scrollbars/scrollmid.png b/images/buttons/scrollbars/scrollmid.png
index d1f7bedfdc65..0fd38fb2983e 100644
Binary files a/images/buttons/scrollbars/scrollmid.png and b/images/buttons/scrollbars/scrollmid.png differ
diff --git a/images/buttons/scrollbars/scrollright-active.png b/images/buttons/scrollbars/scrollright-active.png
index 3da73626448e..48b4f658c421 100644
Binary files a/images/buttons/scrollbars/scrollright-active.png and b/images/buttons/scrollbars/scrollright-active.png differ
diff --git a/images/buttons/scrollbars/scrollright-pressed.png b/images/buttons/scrollbars/scrollright-pressed.png
index dbd5e343db35..9c919791470c 100644
Binary files a/images/buttons/scrollbars/scrollright-pressed.png and b/images/buttons/scrollbars/scrollright-pressed.png differ
diff --git a/images/buttons/scrollbars/scrollright.png b/images/buttons/scrollbars/scrollright.png
index 9c71a84f5275..1f275c151826 100644
Binary files a/images/buttons/scrollbars/scrollright.png and b/images/buttons/scrollbars/scrollright.png differ
diff --git a/images/buttons/scrollbars_large/scrollbottom-active.png b/images/buttons/scrollbars_large/scrollbottom-active.png
new file mode 100644
index 000000000000..77ba8520324d
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollbottom-active.png differ
diff --git a/images/buttons/scrollbars_large/scrollbottom-pressed.png b/images/buttons/scrollbars_large/scrollbottom-pressed.png
new file mode 100644
index 000000000000..e766e3a1015b
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollbottom-pressed.png differ
diff --git a/images/buttons/scrollbars_large/scrollbottom.png b/images/buttons/scrollbars_large/scrollbottom.png
new file mode 100644
index 000000000000..1ad530bd4b08
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollbottom.png differ
diff --git a/images/buttons/scrollbars/scrollgroove-bottom.png b/images/buttons/scrollbars_large/scrollgroove-bottom.png
similarity index 100%
rename from images/buttons/scrollbars/scrollgroove-bottom.png
rename to images/buttons/scrollbars_large/scrollgroove-bottom.png
diff --git a/images/buttons/scrollbars/scrollgroove-horizontal.png b/images/buttons/scrollbars_large/scrollgroove-horizontal.png
similarity index 100%
rename from images/buttons/scrollbars/scrollgroove-horizontal.png
rename to images/buttons/scrollbars_large/scrollgroove-horizontal.png
diff --git a/images/buttons/scrollbars/scrollgroove-left.png b/images/buttons/scrollbars_large/scrollgroove-left.png
similarity index 100%
rename from images/buttons/scrollbars/scrollgroove-left.png
rename to images/buttons/scrollbars_large/scrollgroove-left.png
diff --git a/images/buttons/scrollbars/scrollgroove-mid.png b/images/buttons/scrollbars_large/scrollgroove-mid.png
similarity index 100%
rename from images/buttons/scrollbars/scrollgroove-mid.png
rename to images/buttons/scrollbars_large/scrollgroove-mid.png
diff --git a/images/buttons/scrollbars/scrollgroove-right.png b/images/buttons/scrollbars_large/scrollgroove-right.png
similarity index 100%
rename from images/buttons/scrollbars/scrollgroove-right.png
rename to images/buttons/scrollbars_large/scrollgroove-right.png
diff --git a/images/buttons/scrollbars/scrollgroove-top.png b/images/buttons/scrollbars_large/scrollgroove-top.png
similarity index 100%
rename from images/buttons/scrollbars/scrollgroove-top.png
rename to images/buttons/scrollbars_large/scrollgroove-top.png
diff --git a/images/buttons/scrollbars_large/scrollhorizontal-active.png b/images/buttons/scrollbars_large/scrollhorizontal-active.png
new file mode 100644
index 000000000000..3dc98f743c18
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollhorizontal-active.png differ
diff --git a/images/buttons/scrollbars_large/scrollhorizontal-pressed.png b/images/buttons/scrollbars_large/scrollhorizontal-pressed.png
new file mode 100644
index 000000000000..bfdeeba4764c
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollhorizontal-pressed.png differ
diff --git a/images/buttons/scrollbars_large/scrollhorizontal.png b/images/buttons/scrollbars_large/scrollhorizontal.png
new file mode 100644
index 000000000000..a965ddaa56bb
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollhorizontal.png differ
diff --git a/images/buttons/scrollbars_large/scrollleft-active.png b/images/buttons/scrollbars_large/scrollleft-active.png
new file mode 100644
index 000000000000..9b46a81a431e
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollleft-active.png differ
diff --git a/images/buttons/scrollbars_large/scrollleft-pressed.png b/images/buttons/scrollbars_large/scrollleft-pressed.png
new file mode 100644
index 000000000000..e50d2ebd2d19
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollleft-pressed.png differ
diff --git a/images/buttons/scrollbars_large/scrollleft.png b/images/buttons/scrollbars_large/scrollleft.png
new file mode 100644
index 000000000000..1b06489af3e5
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollleft.png differ
diff --git a/images/buttons/scrollbars_large/scrollmid-active.png b/images/buttons/scrollbars_large/scrollmid-active.png
new file mode 100644
index 000000000000..000f4f9659ea
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollmid-active.png differ
diff --git a/images/buttons/scrollbars_large/scrollmid-pressed.png b/images/buttons/scrollbars_large/scrollmid-pressed.png
new file mode 100644
index 000000000000..42414e203051
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollmid-pressed.png differ
diff --git a/images/buttons/scrollbars_large/scrollmid.png b/images/buttons/scrollbars_large/scrollmid.png
new file mode 100644
index 000000000000..407eaf899355
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollmid.png differ
diff --git a/images/buttons/scrollbars_large/scrollright-active.png b/images/buttons/scrollbars_large/scrollright-active.png
new file mode 100644
index 000000000000..3da73626448e
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollright-active.png differ
diff --git a/images/buttons/scrollbars_large/scrollright-pressed.png b/images/buttons/scrollbars_large/scrollright-pressed.png
new file mode 100644
index 000000000000..dbd5e343db35
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollright-pressed.png differ
diff --git a/images/buttons/scrollbars_large/scrollright.png b/images/buttons/scrollbars_large/scrollright.png
new file mode 100644
index 000000000000..9c71a84f5275
Binary files /dev/null and b/images/buttons/scrollbars_large/scrollright.png differ
diff --git a/images/buttons/scrollbars_large/scrolltop-active.png b/images/buttons/scrollbars_large/scrolltop-active.png
new file mode 100644
index 000000000000..961297f7cc10
Binary files /dev/null and b/images/buttons/scrollbars_large/scrolltop-active.png differ
diff --git a/images/buttons/scrollbars_large/scrolltop-pressed.png b/images/buttons/scrollbars_large/scrolltop-pressed.png
new file mode 100644
index 000000000000..f6ecfa487b02
Binary files /dev/null and b/images/buttons/scrollbars_large/scrolltop-pressed.png differ
diff --git a/images/buttons/scrollbars_large/scrolltop.png b/images/buttons/scrollbars_large/scrolltop.png
new file mode 100644
index 000000000000..2ea0951b9089
Binary files /dev/null and b/images/buttons/scrollbars_large/scrolltop.png differ
diff --git a/images/cursors/attack.png b/images/cursors/attack.png
index b59b774b1eed..25fdd7491d7d 100644
Binary files a/images/cursors/attack.png and b/images/cursors/attack.png differ
diff --git a/images/cursors/attack_drag.png b/images/cursors/attack_drag.png
index 7257f0fa2cca..ffd216632b70 100644
Binary files a/images/cursors/attack_drag.png and b/images/cursors/attack_drag.png differ
diff --git a/images/cursors/move.png b/images/cursors/move.png
index 14606b12e4ea..7298be968c9f 100644
Binary files a/images/cursors/move.png and b/images/cursors/move.png differ
diff --git a/images/cursors/move_drag.png b/images/cursors/move_drag.png
index bdd335256f2a..1760d436a818 100644
Binary files a/images/cursors/move_drag.png and b/images/cursors/move_drag.png differ
diff --git a/images/cursors/normal.png b/images/cursors/normal.png
index d181bbdccf09..45898885ae70 100644
Binary files a/images/cursors/normal.png and b/images/cursors/normal.png differ
diff --git a/images/cursors/select-illegal.png b/images/cursors/select-illegal.png
index 744357d0ec83..2273edcdb040 100644
Binary files a/images/cursors/select-illegal.png and b/images/cursors/select-illegal.png differ
diff --git a/images/cursors/select-location.png b/images/cursors/select-location.png
index 3e124ae585b0..aaed99495a43 100644
Binary files a/images/cursors/select-location.png and b/images/cursors/select-location.png differ
diff --git a/images/cursors/select.png b/images/cursors/select.png
index 91a37b715596..a6c528c4056a 100644
Binary files a/images/cursors/select.png and b/images/cursors/select.png differ
diff --git a/images/cursors/wait.png b/images/cursors/wait.png
index 31ec10805a35..9c8e8bc653fa 100644
Binary files a/images/cursors/wait.png and b/images/cursors/wait.png differ
diff --git a/images/icons/action/trash_25-active.png b/images/icons/action/trash_25-active.png
new file mode 100644
index 000000000000..2fd98ec68d4c
Binary files /dev/null and b/images/icons/action/trash_25-active.png differ
diff --git a/images/icons/action/trash_25-pressed.png b/images/icons/action/trash_25-pressed.png
new file mode 100644
index 000000000000..22ca8a21d4d5
Binary files /dev/null and b/images/icons/action/trash_25-pressed.png differ
diff --git a/images/icons/action/trash_25.png b/images/icons/action/trash_25.png
new file mode 100644
index 000000000000..556c4f258941
Binary files /dev/null and b/images/icons/action/trash_25.png differ
diff --git a/images/icons/alignments/alignment_chaotic_30-pressed.png b/images/icons/alignments/alignment_chaotic_30-pressed.png
new file mode 100644
index 000000000000..12280c6612b1
Binary files /dev/null and b/images/icons/alignments/alignment_chaotic_30-pressed.png differ
diff --git a/images/icons/alignments/alignment_chaotic_30-pressed@2x.png b/images/icons/alignments/alignment_chaotic_30-pressed@2x.png
new file mode 100644
index 000000000000..6cdc5d361c13
Binary files /dev/null and b/images/icons/alignments/alignment_chaotic_30-pressed@2x.png differ
diff --git a/images/icons/alignments/alignment_chaotic_30.png b/images/icons/alignments/alignment_chaotic_30.png
index 19f8d2446a1c..e2df68cc37fa 100644
Binary files a/images/icons/alignments/alignment_chaotic_30.png and b/images/icons/alignments/alignment_chaotic_30.png differ
diff --git a/images/icons/alignments/alignment_chaotic_30@2x.png b/images/icons/alignments/alignment_chaotic_30@2x.png
new file mode 100644
index 000000000000..92e1837c7347
Binary files /dev/null and b/images/icons/alignments/alignment_chaotic_30@2x.png differ
diff --git a/images/icons/alignments/alignment_lawful_30-pressed.png b/images/icons/alignments/alignment_lawful_30-pressed.png
new file mode 100644
index 000000000000..27dcd15e2824
Binary files /dev/null and b/images/icons/alignments/alignment_lawful_30-pressed.png differ
diff --git a/images/icons/alignments/alignment_lawful_30-pressed@2x.png b/images/icons/alignments/alignment_lawful_30-pressed@2x.png
new file mode 100644
index 000000000000..5e3240b87515
Binary files /dev/null and b/images/icons/alignments/alignment_lawful_30-pressed@2x.png differ
diff --git a/images/icons/alignments/alignment_lawful_30.png b/images/icons/alignments/alignment_lawful_30.png
index d423ef62caee..2fc66fb686c9 100644
Binary files a/images/icons/alignments/alignment_lawful_30.png and b/images/icons/alignments/alignment_lawful_30.png differ
diff --git a/images/icons/alignments/alignment_lawful_30@2x.png b/images/icons/alignments/alignment_lawful_30@2x.png
new file mode 100644
index 000000000000..200611de6e86
Binary files /dev/null and b/images/icons/alignments/alignment_lawful_30@2x.png differ
diff --git a/images/icons/alignments/alignment_liminal_30-pressed.png b/images/icons/alignments/alignment_liminal_30-pressed.png
new file mode 100644
index 000000000000..b0d528ced596
Binary files /dev/null and b/images/icons/alignments/alignment_liminal_30-pressed.png differ
diff --git a/images/icons/alignments/alignment_liminal_30-pressed@2x.png b/images/icons/alignments/alignment_liminal_30-pressed@2x.png
new file mode 100644
index 000000000000..3eb9cf44e71e
Binary files /dev/null and b/images/icons/alignments/alignment_liminal_30-pressed@2x.png differ
diff --git a/images/icons/alignments/alignment_liminal_30.png b/images/icons/alignments/alignment_liminal_30.png
index 752639cf858d..025446c73fad 100644
Binary files a/images/icons/alignments/alignment_liminal_30.png and b/images/icons/alignments/alignment_liminal_30.png differ
diff --git a/images/icons/alignments/alignment_liminal_30@2x.png b/images/icons/alignments/alignment_liminal_30@2x.png
new file mode 100644
index 000000000000..d943efc8be65
Binary files /dev/null and b/images/icons/alignments/alignment_liminal_30@2x.png differ
diff --git a/images/icons/alignments/alignment_neutral_30-pressed.png b/images/icons/alignments/alignment_neutral_30-pressed.png
new file mode 100644
index 000000000000..f420db1c1a09
Binary files /dev/null and b/images/icons/alignments/alignment_neutral_30-pressed.png differ
diff --git a/images/icons/alignments/alignment_neutral_30-pressed@2x.png b/images/icons/alignments/alignment_neutral_30-pressed@2x.png
new file mode 100644
index 000000000000..5372251ff1dc
Binary files /dev/null and b/images/icons/alignments/alignment_neutral_30-pressed@2x.png differ
diff --git a/images/icons/alignments/alignment_neutral_30.png b/images/icons/alignments/alignment_neutral_30.png
index 1a09ed7de928..553b42fa75b2 100644
Binary files a/images/icons/alignments/alignment_neutral_30.png and b/images/icons/alignments/alignment_neutral_30.png differ
diff --git a/images/icons/alignments/alignment_neutral_30@2x.png b/images/icons/alignments/alignment_neutral_30@2x.png
new file mode 100644
index 000000000000..2b058d998a02
Binary files /dev/null and b/images/icons/alignments/alignment_neutral_30@2x.png differ
diff --git a/images/misc/loadscreen_decor.png b/images/misc/loadscreen_decor.png
index 0ef7a1423967..2ed96051d069 100644
Binary files a/images/misc/loadscreen_decor.png and b/images/misc/loadscreen_decor.png differ
diff --git a/players_changelog b/players_changelog
index aa08524aedb4..2633a73a0b44 100644
--- a/players_changelog
+++ b/players_changelog
@@ -5,6 +5,8 @@ changelog: https://github.com/wesnoth/wesnoth/blob/master/changelog
Version 1.13.4+dev:
* Language and i18n:
* Updated translations:
+ * Miscellaneous and bug fixes:
+ * Allow changing keybindings for scrolling the map.
Version 1.13.4:
* Language and i18n:
diff --git a/projectfiles/CodeBlocks/wesnoth.cbp b/projectfiles/CodeBlocks/wesnoth.cbp
index 804b86401c12..df0347a4a959 100644
--- a/projectfiles/CodeBlocks/wesnoth.cbp
+++ b/projectfiles/CodeBlocks/wesnoth.cbp
@@ -894,7 +894,6 @@
-
diff --git a/projectfiles/Xcode/Wesnoth.xcodeproj/project.pbxproj b/projectfiles/Xcode/Wesnoth.xcodeproj/project.pbxproj
index 3cb749247b6d..3ba884ad8a82 100644
--- a/projectfiles/Xcode/Wesnoth.xcodeproj/project.pbxproj
+++ b/projectfiles/Xcode/Wesnoth.xcodeproj/project.pbxproj
@@ -1555,6 +1555,7 @@
912DCA6A1CA6F65A0019A6F9 /* manual.en.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = manual.en.html; path = manual/manual.en.html; sourceTree = ""; };
9130A45E1C73BB6100852782 /* select_orb_colors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = select_orb_colors.cpp; sourceTree = ""; };
9130A45F1C73BB6100852782 /* select_orb_colors.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = select_orb_colors.hpp; sourceTree = ""; };
+ 918056BE1CB1E4C0001A7F35 /* functional.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = functional.hpp; sourceTree = ""; };
9190B73A1CA0554900B0EF66 /* lua_pathfind_cost_calculator.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = lua_pathfind_cost_calculator.hpp; sourceTree = ""; };
9190B73B1CA0564700B0EF66 /* register_widget.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = register_widget.hpp; sourceTree = ""; };
919B37F71BAF789D00E0094C /* synced_user_choice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = synced_user_choice.cpp; sourceTree = ""; };
@@ -1699,7 +1700,6 @@
91E3562D1CACA6E600774252 /* visitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = visitor.cpp; sourceTree = ""; };
91ECD5D01BA11A5200B25CF1 /* unit_creator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unit_creator.cpp; sourceTree = ""; };
91ECD5D11BA11A5200B25CF1 /* unit_creator.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = unit_creator.hpp; sourceTree = ""; };
- 91EF6BFB1C9E22E400E2A733 /* boost_function_guarded.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = boost_function_guarded.hpp; sourceTree = ""; };
91EF6BFC1C9E22E400E2A733 /* const_clone.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = const_clone.hpp; sourceTree = ""; };
91EF6BFF1C9E22E400E2A733 /* iterator.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = iterator.hpp; sourceTree = ""; };
91EF6C001C9E22E400E2A733 /* reference_counter.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = reference_counter.hpp; sourceTree = ""; };
@@ -1713,9 +1713,9 @@
91F462871C7115C50050A9C9 /* combobox.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = combobox.hpp; sourceTree = ""; };
91F462921C7117400050A9C9 /* drop_down_list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = drop_down_list.cpp; sourceTree = ""; };
91F462931C7117400050A9C9 /* drop_down_list.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = drop_down_list.hpp; sourceTree = ""; };
- 91FAC70B1C80168600DAB2C3 /* group.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = group.hpp; sourceTree = ""; };
91FAC7081C7F931900DAB2C3 /* lua_formula_bridge.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = lua_formula_bridge.hpp; sourceTree = ""; };
91FAC7091C7FBC2C00DAB2C3 /* lua_formula_bridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_formula_bridge.cpp; sourceTree = ""; };
+ 91FAC70B1C80168600DAB2C3 /* group.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = group.hpp; sourceTree = ""; };
B504B94A1284C06B00261FE9 /* tips.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tips.cpp; sourceTree = ""; };
B504B94B1284C06B00261FE9 /* tips.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = tips.hpp; sourceTree = ""; };
B508D13E10013BF900B12852 /* Growl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Growl.framework; path = lib/Growl.framework; sourceTree = ""; };
@@ -2119,7 +2119,6 @@
B5951A831013BB0800C10B66 /* multiplayer_error_codes.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = multiplayer_error_codes.hpp; sourceTree = ""; };
B5951A841013BB0800C10B66 /* resources.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resources.cpp; sourceTree = ""; };
B5951A851013BB0800C10B66 /* resources.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = resources.hpp; sourceTree = ""; };
- B5951A871013BB0800C10B66 /* savegame_config.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = savegame_config.hpp; sourceTree = ""; };
B5951A931013BB3400C10B66 /* game_delete.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = game_delete.cpp; sourceTree = ""; };
B5951A941013BB3400C10B66 /* game_delete.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = game_delete.hpp; sourceTree = ""; };
B5951A971013BB5A00C10B66 /* callable_objects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = callable_objects.cpp; sourceTree = ""; };
@@ -3033,7 +3032,6 @@
ECD39892194B830300CF2125 /* saved_game.hpp */,
B52EE8C2121359A600CFBDAB /* savegame.cpp */,
B52EE8C3121359A600CFBDAB /* savegame.hpp */,
- B5951A871013BB0800C10B66 /* savegame_config.hpp */,
B55999B50EC62181008DD061 /* scoped_resource.hpp */,
B597EC060FC0832B00CE81F5 /* scripting */,
91B621A61B76A7CD00B00E0F /* sdl */,
@@ -3566,8 +3564,8 @@
91EF6BF01C9E217C00E2A733 /* utils */ = {
isa = PBXGroup;
children = (
- 91EF6BFB1C9E22E400E2A733 /* boost_function_guarded.hpp */,
91EF6BFC1C9E22E400E2A733 /* const_clone.hpp */,
+ 918056BE1CB1E4C0001A7F35 /* functional.hpp */,
911F471B1CAE5A7E00F47035 /* iterable_pair.hpp */,
91EF6BFF1C9E22E400E2A733 /* iterator.hpp */,
EC53B04D1B23BB0E002F758F /* make_enum.cpp */,
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ca40fc0c7c48..c61b56db26f2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -982,6 +982,7 @@ set(wesnoth-main_SRC
units/map.cpp
units/types.cpp
utils/sha1.cpp
+ utils/context_free_grammar_generator.cpp
variable.cpp
variable_info.cpp
whiteboard/action.cpp
diff --git a/src/SConscript b/src/SConscript
index d7bd2b41c1a1..67881dea8587 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -556,6 +556,7 @@ wesnoth_sources = Split("""
units/udisplay.cpp
units/unit.cpp
utils/sha1.cpp
+ utils/context_free_grammar_generator.cpp
variable_info.cpp
variable.cpp
whiteboard/action.cpp
diff --git a/src/actions/undo_action.cpp b/src/actions/undo_action.cpp
index eac5b74b7233..89642a0d29ff 100644
--- a/src/actions/undo_action.cpp
+++ b/src/actions/undo_action.cpp
@@ -2,40 +2,188 @@
#include "scripting/game_lua_kernel.hpp"
#include "resources.hpp"
#include "variable.hpp" // vconfig
-#include "game_events/pump.hpp" //game_events::queued_event
+#include "game_data.hpp"
+#include "units/unit.hpp"
#include
+#include
+#include
namespace actions
{
+
+undo_event::undo_event(const config& cmds, const game_events::queued_event& ctx)
+ : commands(cmds)
+ , data(ctx.data)
+ , loc1(ctx.loc1)
+ , loc2(ctx.loc2)
+ , filter_loc1(ctx.loc1.filter_x(), ctx.loc1.filter_y())
+ , filter_loc2(ctx.loc2.filter_x(), ctx.loc2.filter_y())
+ , uid1(), uid2()
+{
+ unit_const_ptr u1 = ctx.loc1.get_unit(), u2 = ctx.loc2.get_unit();
+ if(u1) {
+ id1 = u1->id();
+ uid1 = u1->underlying_id();
+ }
+ if(u2) {
+ id2 = u2->id();
+ uid2 = u2->underlying_id();
+ }
+}
+
+undo_event::undo_event(const config& first, const config& second, const config& weapons, const config& cmds)
+ : commands(cmds)
+ , data(weapons)
+ , loc1(first["x"], first["y"])
+ , loc2(second["x"], second["y"])
+ , filter_loc1(first["filter_x"], first["filter_y"])
+ , filter_loc2(second["filter_x"], second["filter_y"])
+ , uid1(first["underlying_id"])
+ , uid2(second["underlying_id"])
+ , id1(first["id"])
+ , id2(second["id"])
+{
+}
+
+undo_action::undo_action()
+ : undo_action_base()
+ , replay_data()
+ , unit_id_diff(synced_context::get_unit_id_diff())
+{
+ auto& undo = synced_context::get_undo_commands();
+ auto& redo = synced_context::get_redo_commands();
+ auto command_transformer = [](const std::pair& p) {
+ return undo_event(p.first, p.second);
+ };
+ std::transform(undo.begin(), undo.end(), std::back_inserter(umc_commands_undo), command_transformer);
+ std::transform(redo.begin(), redo.end(), std::back_inserter(umc_commands_redo), command_transformer);
+ undo.clear();
+ redo.clear();
+}
+
+undo_action::undo_action(const config& cfg)
+ : undo_action_base()
+ , replay_data(cfg.child_or_empty("replay_data"))
+ , unit_id_diff(cfg["unit_id_diff"])
+{
+ read_event_vector(umc_commands_undo, cfg, "undo_actions");
+ read_event_vector(umc_commands_redo, cfg, "redo_actions");
+}
+
+namespace {
+ unit_ptr get_unit(size_t uid, const std::string& id) {
+ assert(resources::units);
+ auto iter = resources::units->find(uid);
+ if(!iter.valid() || iter->id() != id) {
+ return nullptr;
+ }
+ return iter.get_shared_ptr();
+ }
+ void execute_event(const undo_event& e, std::string tag) {
+ assert(resources::lua_kernel);
+ assert(resources::gamedata);
+
+ config::attribute_value& x1 = resources::gamedata->get_variable("x1");
+ config::attribute_value& y1 = resources::gamedata->get_variable("y1");
+ config::attribute_value& x2 = resources::gamedata->get_variable("x2");
+ config::attribute_value& y2 = resources::gamedata->get_variable("y2");
+ int oldx1 = x1, oldy1 = y1, oldx2 = x2, oldy2 = y2;
+ x1 = e.filter_loc1.x + 1; y1 = e.filter_loc1.y + 1;
+ x2 = e.filter_loc2.x + 1; y2 = e.filter_loc2.y + 1;
+
+ int realx1 = 0, realy1 = 0, realx2 = 0, realy2 = 0;
+ boost::scoped_ptr u1, u2;
+ if(unit_ptr who = get_unit(e.uid1, e.id1)) {
+ realx1 = who->get_location().x;
+ realy1 = who->get_location().y;
+ who->set_location(e.loc1);
+ u1.reset(new scoped_xy_unit("unit", realx1, realy1, *resources::units));
+ }
+ if(unit_ptr who = get_unit(e.uid2, e.id2)) {
+ realx2 = who->get_location().x;
+ realy2 = who->get_location().y;
+ who->set_location(e.loc2);
+ u2.reset(new scoped_xy_unit("unit", realx2, realy2, *resources::units));
+ }
+
+ scoped_weapon_info w1("weapon", e.data.child("first"));
+ scoped_weapon_info w2("second_weapon", e.data.child("second"));
+
+ game_events::queued_event q(tag, map_location(x1, y1), map_location(x2, y2), e.data);
+ resources::lua_kernel->run_wml_action("command", vconfig(e.commands), q);
+
+ if(u1) {
+ unit_ptr who = get_unit(e.uid1, e.id1);
+ who->set_location(map_location(realx1, realy1));
+ }
+ if(u2) {
+ unit_ptr who = get_unit(e.uid2, e.id2);
+ who->set_location(map_location(realx2, realy2));
+ }
+
+ x1 = oldx1; y1 = oldy1;
+ x2 = oldx2; y2 = oldy2;
+ }
+}
+
void undo_action::execute_undo_umc_wml()
{
- assert(resources::lua_kernel);
- for(const config& c : umc_commands_undo)
+ for(const undo_event& e : umc_commands_undo)
{
- resources::lua_kernel->run_wml_action("command", vconfig(c), game_events::queued_event("undo", map_location(), map_location(), config()));
+ execute_event(e, "undo");
}
}
void undo_action::execute_redo_umc_wml()
{
assert(resources::lua_kernel);
- for(const config& c : umc_commands_redo)
+ assert(resources::gamedata);
+ for(const undo_event& e : umc_commands_redo)
{
- resources::lua_kernel->run_wml_action("command", vconfig(c), game_events::queued_event("redo", map_location(), map_location(), config()));
+ execute_event(e, "redo");
}
}
-void undo_action::read_tconfig_vector(tconfig_vector& vec, const config& cfg, const std::string& tag)
+void undo_action::write(config & cfg) const
{
- config::const_child_itors r = cfg.child_range(tag);
- vec.insert(vec.end(), r.first, r.second);
+ cfg.add_child("replay_data", replay_data);
+ cfg["unit_id_diff"] = unit_id_diff;
+ write_event_vector(umc_commands_undo, cfg, "undo_actions");
+ write_event_vector(umc_commands_redo, cfg, "redo_actions");
+ undo_action_base::write(cfg);
}
-void undo_action::write_tconfig_vector(const tconfig_vector& vec, config& cfg, const std::string& tag)
+
+void undo_action::read_event_vector(event_vector& vec, const config& cfg, const std::string& tag)
+{
+ for(auto c : cfg.child_range(tag)) {
+ vec.emplace_back(c.child("filter"), c.child("filter_second"), c.child("filter_weapons"), c.child("commands"));
+ }
+}
+
+void undo_action::write_event_vector(const event_vector& vec, config& cfg, const std::string& tag)
{
- for(const config& c : vec)
+ for(const auto& evt : vec)
{
- cfg.add_child(tag, c);
+ config& entry = cfg.add_child(tag);
+ config& first = entry.add_child("filter");
+ config& second = entry.add_child("filter_second");
+ entry.add_child("filter_weapons", evt.data);
+ entry.add_child("command", evt.commands);
+ // First location
+ first["filter_x"] = evt.filter_loc1.x;
+ first["filter_y"] = evt.filter_loc1.y;
+ first["underlying_id"] = evt.uid1;
+ first["id"] = evt.id1;
+ first["x"] = evt.loc1.x;
+ first["y"] = evt.loc1.y;
+ // Second location
+ second["filter_x"] = evt.filter_loc2.x;
+ second["filter_y"] = evt.filter_loc2.y;
+ second["underlying_id"] = evt.uid2;
+ second["id"] = evt.id2;
+ second["x"] = evt.loc2.x;
+ second["y"] = evt.loc2.y;
}
}
diff --git a/src/actions/undo_action.hpp b/src/actions/undo_action.hpp
index 8917bd21b8b3..3021a66ed723 100644
--- a/src/actions/undo_action.hpp
+++ b/src/actions/undo_action.hpp
@@ -4,14 +4,23 @@
#include "map/location.hpp"
#include "units/ptr.hpp"
#include "synced_context.hpp"
+#include "game_events/pump.hpp" // for queued_event
+#include "config.hpp"
#include
-#include
#include
+
namespace actions {
class undo_list;
-}
-namespace actions {
+
+ struct undo_event {
+ config commands, data;
+ map_location loc1, loc2, filter_loc1, filter_loc2;
+ size_t uid1, uid2;
+ std::string id1, id2;
+ undo_event(const config& cmds, const game_events::queued_event& ctx);
+ undo_event(const config& first, const config& second, const config& weapons, const config& cmds);
+ };
/// Records information to be able to undo an action.
/// Each type of action gets its own derived type.
@@ -40,38 +49,13 @@ namespace actions {
/// Default constructor.
/// It is assumed that undo actions are contructed after the action is performed
/// so that the unit id diff does not change after this contructor.
- undo_action()
- : undo_action_base()
- , replay_data()
- , unit_id_diff(synced_context::get_unit_id_diff())
- , umc_commands_undo()
- , umc_commands_redo()
- {
- umc_commands_undo.swap(synced_context::get_undo_commands());
- umc_commands_redo.swap(synced_context::get_redo_commands());
- }
- undo_action(const config& cfg)
- : undo_action_base()
- , replay_data(cfg.child_or_empty("replay_data"))
- , unit_id_diff(cfg["unit_id_diff"])
- , umc_commands_undo()
- , umc_commands_redo()
- {
- read_tconfig_vector(umc_commands_undo, cfg, "undo_actions");
- read_tconfig_vector(umc_commands_redo, cfg, "redo_actions");
- }
+ undo_action();
+ undo_action(const config& cfg);
// Virtual destructor to support derived classes.
virtual ~undo_action() {}
/// Writes this into the provided config.
- virtual void write(config & cfg) const
- {
- cfg.add_child("replay_data", replay_data);
- cfg["unit_id_diff"] = unit_id_diff;
- write_tconfig_vector(umc_commands_undo, cfg, "undo_actions");
- write_tconfig_vector(umc_commands_redo, cfg, "redo_actions");
- undo_action_base::write(cfg);
- }
+ virtual void write(config & cfg) const;
/// Undoes this action.
/// @return true on success; false on an error.
@@ -87,14 +71,14 @@ namespace actions {
/// TODO: does it really make sense to allow undoing if the unit id counter has changed?
int unit_id_diff;
/// actions wml (specified by wml) that should be executed when undoing this command.
- typedef boost::ptr_vector tconfig_vector;
- tconfig_vector umc_commands_undo;
- tconfig_vector umc_commands_redo;
+ typedef std::vector event_vector;
+ event_vector umc_commands_undo;
+ event_vector umc_commands_redo;
void execute_undo_umc_wml();
void execute_redo_umc_wml();
- static void read_tconfig_vector(tconfig_vector& vec, const config& cfg, const std::string& tag);
- static void write_tconfig_vector(const tconfig_vector& vec, config& cfg, const std::string& tag);
+ static void read_event_vector(event_vector& vec, const config& cfg, const std::string& tag);
+ static void write_event_vector(const event_vector& vec, config& cfg, const std::string& tag);
};
/// entry for player actions that do not need any special code to be performed when undoing such as right-click menu items.
diff --git a/src/ai/actions.cpp b/src/ai/actions.cpp
index 55fd2a42b459..1c4acb66b50c 100644
--- a/src/ai/actions.cpp
+++ b/src/ai/actions.cpp
@@ -52,6 +52,7 @@
#include "team.hpp"
#include "units/unit.hpp"
#include "units/ptr.hpp"
+#include "whiteboard/manager.hpp"
namespace ai {
@@ -286,6 +287,7 @@ void attack_result::do_execute()
//FIXME: find a way to 'ask' the ai which advancement should be chosen from synced_commands.cpp .
if(!synced_context::is_synced()) //RAII block for set_scontext_synced
{
+ wb::real_map rm;
//we don't use synced_context::run_in_synced_context because that wouldn't allow us to pass advancements_
resources::recorder->add_synced_command("attack", replay_helper::get_attack(attacker_loc_, defender_loc_, attacker_weapon, defender_weapon, a_->type_id(),
d_->type_id(), a_->level(), d_->level(), resources::tod_manager->turn(),
diff --git a/src/ai/default/recruitment.cpp b/src/ai/default/recruitment.cpp
index 3ecd8819fedd..ca9d54257e04 100644
--- a/src/ai/default/recruitment.cpp
+++ b/src/ai/default/recruitment.cpp
@@ -1786,12 +1786,11 @@ recruitment_aspect::recruitment_aspect(readonly_context &context, const config &
parsed_cfg["pattern"] = true;
parsed_cfg.add_child("recruit", pattern);
}
- parsed_cfg.clear_children("pattern");
for (config total : parsed_cfg.child_range("total")) {
parsed_cfg["total"] = true;
parsed_cfg.add_child("recruit", total);
}
- parsed_cfg.clear_children("total");
+ parsed_cfg.clear_children("pattern", "total");
// Then, if there's no [recruit], add one.
if (!parsed_cfg.has_child("recruit")) {
parsed_cfg.add_child("recruit", config_of("importance", 0));
diff --git a/src/carryover.cpp b/src/carryover.cpp
index 1b3d2f2b20cb..fa4ad1c683d7 100644
--- a/src/carryover.cpp
+++ b/src/carryover.cpp
@@ -34,11 +34,7 @@ carryover::carryover(const config& side)
for(const config& u : side.child_range("unit")) {
recall_list_.push_back(u);
config& u_back = recall_list_.back();
- u_back.remove_attribute("side");
- u_back.remove_attribute("goto_x");
- u_back.remove_attribute("goto_y");
- u_back.remove_attribute("x");
- u_back.remove_attribute("y");
+ u_back.remove_attributes("side", "goto_x", "goto_y", "x", "y");
}
}
diff --git a/src/config.hpp b/src/config.hpp
index 701f6b45fb1b..9fc315c9b3f4 100644
--- a/src/config.hpp
+++ b/src/config.hpp
@@ -450,7 +450,9 @@ class config
template
config &child(const char(&key)[N], int n = 0)
{ return child_impl(key, N - 1, n); }
+private:
config &child_impl(const char* key, int len, int n = 0);
+public:
#endif
/**
* Returns the nth child with the given @a key, or
@@ -564,6 +566,12 @@ class config
void remove_attribute(const std::string &key);
void merge_attributes(const config &);
+ template
+ void remove_attributes(T... keys) {
+ for(const std::string& key : {keys...}) {
+ remove_attribute(key);
+ }
+ }
const_attr_itors attribute_range() const;
@@ -579,6 +587,12 @@ class config
{ return const_cast(this)->find_child(key, name, value); }
void clear_children(const std::string& key);
+ template
+ void clear_children(T... keys) {
+ for(std::string key : {keys...}) {
+ clear_children(key);
+ }
+ }
/**
* Moves all the children with tag @a key from @a src to this.
@@ -660,7 +674,7 @@ class config
* A function to get the differences between this object,
* and 'c', as another config object.
* I.e. calling cfg2.apply_diff(cfg1.get_diff(cfg2))
- * will make cfg1 identical to cfg2.
+ * will make cfg2 identical to cfg1.
*/
config get_diff(const config& c) const;
void get_diff(const config& c, config& res) const;
diff --git a/src/controller_base.cpp b/src/controller_base.cpp
index ffe7ec5fb2f3..1a9e03d04e5b 100644
--- a/src/controller_base.cpp
+++ b/src/controller_base.cpp
@@ -34,6 +34,10 @@ controller_base::controller_base(
: game_config_(game_config)
, key_()
, scrolling_(false)
+ , scroll_up_(false)
+ , scroll_down_(false)
+ , scroll_left_(false)
+ , scroll_right_(false)
, joystick_manager_()
{
}
@@ -61,13 +65,14 @@ void controller_base::handle_event(const SDL_Event& event)
process_keydown_event(event);
hotkey::key_event(event, get_hotkey_command_executor());
+ process_keyup_event(event);
} else {
process_focus_keydown_event(event);
- break;
}
- // intentionally fall-through
+ break;
case SDL_KEYUP:
process_keyup_event(event);
+ hotkey::key_event(event, get_hotkey_command_executor());
break;
case SDL_JOYBUTTONDOWN:
process_keydown_event(event);
@@ -128,11 +133,10 @@ void controller_base::process_keyup_event(const SDL_Event& /*event*/) {
//no action by default
}
-bool controller_base::handle_scroll(CKey& key, int mousex, int mousey, int mouse_flags, double x_axis, double y_axis)
+bool controller_base::handle_scroll(int mousex, int mousey, int mouse_flags, double x_axis, double y_axis)
{
bool mouse_in_window = (SDL_GetAppState() & SDL_APPMOUSEFOCUS) != 0
|| preferences::get("scroll_when_mouse_outside", true);
- bool keyboard_focus = have_keyboard_focus();
int scroll_speed = preferences::scroll_speed();
int dx = 0, dy = 0;
int scroll_threshold = (preferences::mouse_scroll_enabled())
@@ -142,26 +146,30 @@ bool controller_base::handle_scroll(CKey& key, int mousex, int mousey, int mouse
scroll_threshold = 0;
}
}
- if ((key[SDLK_UP] && keyboard_focus) ||
- (mousey < scroll_threshold && mouse_in_window))
- {
- dy -= scroll_speed;
- }
- if ((key[SDLK_DOWN] && keyboard_focus) ||
- (mousey > get_display().h() - scroll_threshold && mouse_in_window))
- {
- dy += scroll_speed;
- }
- if ((key[SDLK_LEFT] && keyboard_focus) ||
- (mousex < scroll_threshold && mouse_in_window))
- {
- dx -= scroll_speed;
- }
- if ((key[SDLK_RIGHT] && keyboard_focus) ||
- (mousex > get_display().w() - scroll_threshold && mouse_in_window))
- {
- dx += scroll_speed;
+
+ // apply keyboard scrolling
+ dy -= scroll_up_ * scroll_speed;
+ dy += scroll_down_ * scroll_speed;
+ dx -= scroll_left_ * scroll_speed;
+ dx += scroll_right_ * scroll_speed;
+
+ // scroll if mouse is placed near the edge of the screen
+ if (mouse_in_window) {
+ if (mousey < scroll_threshold) {
+ dy -= scroll_speed;
+ }
+ if (mousey > get_display().h() - scroll_threshold) {
+ dy += scroll_speed;
+ }
+ if (mousex < scroll_threshold) {
+ dx -= scroll_speed;
+ }
+ if (mousex > get_display().w() - scroll_threshold) {
+ dx += scroll_speed;
+ }
}
+
+ // scroll with middle-mouse if enabled
if ((mouse_flags & SDL_BUTTON_MMASK) != 0 && preferences::middle_click_scrolls()) {
const map_location original_loc = get_mouse_handler_base().get_scroll_start();
@@ -185,6 +193,7 @@ bool controller_base::handle_scroll(CKey& key, int mousex, int mousey, int mouse
}
}
+ // scroll with joystick
dx += round_double( x_axis * scroll_speed);
dy += round_double( y_axis * scroll_speed);
@@ -238,7 +247,7 @@ void controller_base::play_slice(bool is_delay_enabled)
mousey += values.second * 10;
SDL_WarpMouse(mousex, mousey);
*/
- scrolling_ = handle_scroll(key, mousex, mousey, mouse_flags, joystickx, joysticky);
+ scrolling_ = handle_scroll(mousex, mousey, mouse_flags, joystickx, joysticky);
map_location highlighted_hex = get_display().mouseover_hex();
@@ -341,3 +350,23 @@ const config& controller_base::get_theme(const config& game_config, std::string
static config empty;
return empty;
}
+
+void controller_base::set_scroll_up(bool on)
+{
+ scroll_up_ = on;
+}
+
+void controller_base::set_scroll_down(bool on)
+{
+ scroll_down_ = on;
+}
+
+void controller_base::set_scroll_left(bool on)
+{
+ scroll_left_ = on;
+}
+
+void controller_base::set_scroll_right(bool on)
+{
+ scroll_right_ = on;
+}
diff --git a/src/controller_base.hpp b/src/controller_base.hpp
index 87df5cfe8a03..8512661ec688 100644
--- a/src/controller_base.hpp
+++ b/src/controller_base.hpp
@@ -64,6 +64,12 @@ class controller_base : public video2::draw_layering
void play_slice(bool is_delay_enabled = true);
static const config &get_theme(const config& game_config, std::string theme_name);
+
+ void apply_keyboard_scroll(int x, int y);
+ void set_scroll_up(bool on);
+ void set_scroll_down(bool on);
+ void set_scroll_left(bool on);
+ void set_scroll_right(bool on);
protected:
virtual bool is_browsing() const
{ return false; }
@@ -102,10 +108,10 @@ class controller_base : public video2::draw_layering
/**
* Handle scrolling by keyboard, joystick and moving mouse near map edges
- * @see is_keyboard_scroll_active
+ * @see scrolling_, which is set if the display is being scrolled
* @return true when there was any scrolling, false otherwise
*/
- bool handle_scroll(CKey& key, int mousex, int mousey, int mouse_flags, double joystickx, double joysticky);
+ bool handle_scroll(int mousex, int mousey, int mouse_flags, double joystickx, double joysticky);
/**
* Process mouse- and keypress-events from SDL.
@@ -141,6 +147,10 @@ class controller_base : public video2::draw_layering
const config& game_config_;
CKey key_;
bool scrolling_;
+ bool scroll_up_;
+ bool scroll_down_;
+ bool scroll_left_;
+ bool scroll_right_;
joystick_manager joystick_manager_;
};
diff --git a/src/display.cpp b/src/display.cpp
index 8196908faadc..79d8a52a1c7a 100644
--- a/src/display.cpp
+++ b/src/display.cpp
@@ -1300,7 +1300,7 @@ inline display::drawing_buffer_key::drawing_buffer_key(const map_location &loc,
SHIFT_Y = BITS_FOR_X_PARITY + SHIFT_X_PARITY,
SHIFT_LAYER_GROUP = BITS_FOR_Y + SHIFT_Y
};
- BOOST_STATIC_ASSERT(SHIFT_LAYER_GROUP + BITS_FOR_LAYER_GROUP == sizeof(key_) * 8);
+ static_assert(SHIFT_LAYER_GROUP + BITS_FOR_LAYER_GROUP == sizeof(key_) * 8, "Bit field too small");
// the parity of x must be more significant than the layer but less significant than y.
// Thus basically every row is split in two: First the row containing all the odd x
diff --git a/src/editor/controller/editor_controller.cpp b/src/editor/controller/editor_controller.cpp
index 606501177a59..02210ba648e0 100644
--- a/src/editor/controller/editor_controller.cpp
+++ b/src/editor/controller/editor_controller.cpp
@@ -86,7 +86,6 @@ editor_controller::editor_controller(const config &game_config, CVideo& video)
init_music(game_config);
context_manager_->get_map_context().set_starting_position_labels(gui());
cursor::set(cursor::NORMAL);
- image::set_color_adjustment(preferences::editor::tod_r(), preferences::editor::tod_g(), preferences::editor::tod_b());
gui().create_buttons();
gui().redraw_everything();
@@ -287,6 +286,10 @@ bool editor_controller::can_execute_command(const hotkey::hotkey_command& cmd, i
case HOTKEY_PREFERENCES:
case HOTKEY_HELP:
case HOTKEY_QUIT_GAME:
+ case HOTKEY_SCROLL_UP:
+ case HOTKEY_SCROLL_DOWN:
+ case HOTKEY_SCROLL_LEFT:
+ case HOTKEY_SCROLL_RIGHT:
return true; //general hotkeys we can always do
case hotkey::HOTKEY_UNIT_LIST:
@@ -585,12 +588,18 @@ hotkey::ACTION_STATE editor_controller::get_action_state(hotkey::HOTKEY_COMMAND
}
}
-bool editor_controller::execute_command(const hotkey::hotkey_command& cmd, int index)
+bool editor_controller::execute_command(const hotkey::hotkey_command& cmd, int index, bool press)
{
const int zoom_amount = 4;
hotkey::HOTKEY_COMMAND command = cmd.id;
SCOPE_ED;
using namespace hotkey;
+
+ // nothing here handles release; fall through to base implementation
+ if (!press) {
+ return hotkey::command_executor::execute_command(cmd, index, press);
+ }
+
switch (command) {
case HOTKEY_NULL:
switch (active_menu_) {
@@ -973,7 +982,7 @@ bool editor_controller::execute_command(const hotkey::hotkey_command& cmd, int i
gui().invalidate_all();
return true;
default:
- return hotkey::command_executor::execute_command(cmd, index);
+ return hotkey::command_executor::execute_command(cmd, index, press);
}
}
@@ -1357,4 +1366,24 @@ hotkey::command_executor * editor_controller::get_hotkey_command_executor() {
return this;
}
+void editor_controller::scroll_up(bool on)
+{
+ controller_base::set_scroll_up(on);
+}
+
+void editor_controller::scroll_down(bool on)
+{
+ controller_base::set_scroll_down(on);
+}
+
+void editor_controller::scroll_left(bool on)
+{
+ controller_base::set_scroll_left(on);
+}
+
+void editor_controller::scroll_right(bool on)
+{
+ controller_base::set_scroll_right(on);
+}
+
} //end namespace editor
diff --git a/src/editor/controller/editor_controller.hpp b/src/editor/controller/editor_controller.hpp
index ab4cce2a4a7c..88411d2b5188 100644
--- a/src/editor/controller/editor_controller.hpp
+++ b/src/editor/controller/editor_controller.hpp
@@ -107,7 +107,7 @@ class editor_controller : public controller_base,
hotkey::ACTION_STATE get_action_state(hotkey::HOTKEY_COMMAND command, int index) const;
/** command_executor override */
- bool execute_command(const hotkey::hotkey_command& command, int index = -1);
+ bool execute_command(const hotkey::hotkey_command& command, int index = -1, bool press=true);
/** controller_base override */
void show_menu(const std::vector& items_arg, int xloc, int yloc, bool context_menu, display& disp);
@@ -118,6 +118,12 @@ class editor_controller : public controller_base,
/** Show the preferences dialog */
void preferences();
+ /** Handle hotkeys to scroll map */
+ void scroll_up(bool on);
+ void scroll_down(bool on);
+ void scroll_left(bool on);
+ void scroll_right(bool on);
+
/** Grid toggle */
void toggle_grid();
diff --git a/src/editor/editor_preferences.cpp b/src/editor/editor_preferences.cpp
index 5e53172422b9..33e638cf7be2 100644
--- a/src/editor/editor_preferences.cpp
+++ b/src/editor/editor_preferences.cpp
@@ -50,51 +50,6 @@ namespace editor {
preferences::set("editor_draw_hex_coordinates", value);
}
- namespace {
- void normalize_editor_rgb(int rval)
- {
- if (rval < -255) {
- rval = -255;
- }
- else if (rval > 255) {
- rval = 255;
- }
- }
- }
-
- void set_tod_r(int value)
- {
- normalize_editor_rgb(value);
- preferences::set("editor_r",std::to_string(value));
- }
-
- void set_tod_g(int value)
- {
- normalize_editor_rgb(value);
- preferences::set("editor_g",std::to_string(value));
- }
-
- void set_tod_b(int value)
- {
- normalize_editor_rgb(value);
- preferences::set("editor_b",std::to_string(value));
- }
-
- int tod_r()
- {
- return lexical_cast_in_range(preferences::get("editor_r"), 0, -255, 255);
- }
-
- int tod_g()
- {
- return lexical_cast_in_range(preferences::get("editor_g"), 0, -255, 255);
- }
-
- int tod_b()
- {
- return lexical_cast_in_range(preferences::get("editor_b"), 0, -255, 255);
- }
-
namespace {
size_t editor_mru_limit()
{
diff --git a/src/editor/editor_preferences.hpp b/src/editor/editor_preferences.hpp
index b229aeaa97c9..ae4e97e15c1c 100644
--- a/src/editor/editor_preferences.hpp
+++ b/src/editor/editor_preferences.hpp
@@ -42,21 +42,6 @@ namespace editor {
bool draw_hex_coordinates();
void set_draw_hex_coordinates(bool value);
-
- /** Set editor red tint level. */
- void set_tod_r(int value);
- /** Set editor green tint level. */
- void set_tod_g(int value);
- /** Set editor blue tint level. */
- void set_tod_b(int value);
-
- /** Get editor red tint level. */
- int tod_r();
- /** Get editor green tint level. */
- int tod_g();
- /** Get editor blue tint level. */
- int tod_b();
-
/** Retrieves the list of recently opened files. */
std::vector recent_files();
/** Adds an entry to the recent files list. */
diff --git a/src/events.cpp b/src/events.cpp
index 1e422d473a38..0917720f3a38 100644
--- a/src/events.cpp
+++ b/src/events.cpp
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
#define ERR_GEN LOG_STREAM(err, lg::general)
@@ -332,9 +333,14 @@ static bool remove_on_resize(const SDL_Event &a) {
return false;
}
-
+// TODO: I'm uncertain if this is always safe to call at static init; maybe set in main() instead?
+static const boost::thread::id main_thread = boost::this_thread::get_id();
void pump()
{
+ if(boost::this_thread::get_id() != main_thread) {
+ // Can only call this on the main thread!
+ return;
+ }
SDL_PumpEvents();
peek_for_resize();
pump_info info;
diff --git a/src/formula/callable_objects.cpp b/src/formula/callable_objects.cpp
index 83d9bbe3f574..248f22038ab1 100644
--- a/src/formula/callable_objects.cpp
+++ b/src/formula/callable_objects.cpp
@@ -528,7 +528,7 @@ void config_callable::get_inputs(std::vector* inputs)
int config_callable::do_compare(const game_logic::formula_callable* callable) const
{
const config_callable* cfg_callable = dynamic_cast(callable);
- if(cfg_callable == NULL) {
+ if(cfg_callable == nullptr) {
return formula_callable::do_compare(callable);
}
diff --git a/src/game_classification.cpp b/src/game_classification.cpp
index 2f220f93a189..a2aefa411fc2 100644
--- a/src/game_classification.cpp
+++ b/src/game_classification.cpp
@@ -30,7 +30,6 @@ static lg::log_domain log_engine("engine");
const std::string DEFAULT_DIFFICULTY("NORMAL");
game_classification::game_classification():
- savegame_config(),
label(),
version(),
campaign_type(),
@@ -50,7 +49,6 @@ game_classification::game_classification():
{}
game_classification::game_classification(const config& cfg):
- savegame_config(),
label(cfg["label"]),
version(cfg["version"]),
campaign_type(cfg["campaign_type"].to_enum(game_classification::CAMPAIGN_TYPE::SCENARIO)),
@@ -70,7 +68,6 @@ game_classification::game_classification(const config& cfg):
{}
game_classification::game_classification(const game_classification& gc):
- savegame_config(),
label(gc.label),
version(gc.version),
campaign_type(gc.campaign_type),
diff --git a/src/game_classification.hpp b/src/game_classification.hpp
index 8a8d5cdcb874..6e5522513e63 100644
--- a/src/game_classification.hpp
+++ b/src/game_classification.hpp
@@ -16,7 +16,7 @@
#define GAME_CLASSIFICATION_HPP_INCLUDED
#include "utils/make_enum.hpp"
-#include "savegame_config.hpp"
+
#include
class config;
@@ -25,7 +25,7 @@ class config;
extern const std::string DEFAULT_DIFFICULTY;
//meta information of the game
-class game_classification : public savegame::savegame_config
+class game_classification
{
public:
game_classification();
diff --git a/src/game_events/action_wml.cpp b/src/game_events/action_wml.cpp
index bc3b9a71227d..5fe11435b452 100644
--- a/src/game_events/action_wml.cpp
+++ b/src/game_events/action_wml.cpp
@@ -205,71 +205,8 @@ namespace { // Support functions
}
return path;
}
-
- /**
- * Implements the lifting and resetting of fog via WML.
- * Keeping affect_normal_fog as false causes only the fog override to be affected.
- * Otherwise, fog lifting will be implemented similar to normal sight (cannot be
- * individually reset and ends at the end of the turn), and fog resetting will, in
- * addition to removing overrides, extend the specified teams' normal fog to all
- * hexes.
- */
- void toggle_fog(const bool clear, const vconfig& cfg, const bool affect_normal_fog=false)
- {
- // Filter the sides.
- const vconfig &ssf = cfg.child("filter_side");
- const side_filter s_filter(ssf.null() ? vconfig::empty_vconfig() : ssf, resources::filter_con);
- const std::vector sides = s_filter.get_teams();
-
- // Filter the locations.
- std::set locs;
- const terrain_filter t_filter(cfg, resources::filter_con);
- t_filter.get_locations(locs, true);
-
- // Loop through sides.
- for (const int &side_num : sides)
- {
- team &t = (*resources::teams)[side_num-1];
- if ( !clear )
- {
- // Extend fog.
- t.remove_fog_override(locs);
- if ( affect_normal_fog )
- t.refog();
- }
- else if ( !affect_normal_fog )
- // Force the locations clear of fog.
- t.add_fog_override(locs);
- else
- // Simply clear fog from the locations.
- for (const map_location &hex : locs) {
- t.clear_fog(hex);
- }
- }
-
- // Flag a screen update.
- resources::screen->recalculate_minimap();
- resources::screen->invalidate_all();
- }
} // end anonymous namespace (support functions)
-void handle_deprecated_message(const config& cfg)
-{
- // Note: no need to translate the string, since only used for deprecated things.
- const std::string& message = cfg["message"];
- lg::wml_error() << message << '\n';
-}
-
-void handle_wml_log_message(const config& cfg)
-{
- const std::string& logger = cfg["logger"];
- const std::string& msg = cfg["message"];
- bool in_chat = cfg["to_chat"].to_bool(true);
-
- resources::game_events->pump().put_wml_message(logger,msg,in_chat);
-}
-
-
/**
* Using this constructor for a static object outside action_wml.cpp
* will likely lead to a static initialization fiasco.
@@ -310,25 +247,20 @@ wml_action::wml_action(const std::string & tag, handler function)
* }
* \endcode
*/
-#define WML_HANDLER_FUNCTION(pname, pcfg) \
- static void wml_func_##pname(const vconfig &pcfg); \
+#define WML_HANDLER_FUNCTION(pname, pei, pcfg) \
+ static void wml_func_##pname(const queued_event &pei, const vconfig &pcfg); \
static wml_action wml_action_##pname(#pname, &wml_func_##pname); \
- static void wml_func_##pname(const vconfig& pcfg)
+ static void wml_func_##pname(const queued_event& pei, const vconfig& pcfg)
/// Experimental data persistence
/// @todo Finish experimenting.
-WML_HANDLER_FUNCTION(clear_global_variable,pcfg)
+WML_HANDLER_FUNCTION(clear_global_variable,,pcfg)
{
if (!resources::controller->is_replay())
verify_and_clear_global_variable(pcfg);
}
-WML_HANDLER_FUNCTION(deprecated_message, cfg)
-{
- handle_deprecated_message( cfg.get_parsed_config() );
-}
-
static void on_replay_error(const std::string& message, bool /*b*/)
{
ERR_NG << "Error via [do_command]:" << std::endl;
@@ -337,7 +269,7 @@ static void on_replay_error(const std::string& message, bool /*b*/)
// This tag exposes part of the code path used to handle [command]'s in replays
// This allows to perform scripting in WML that will use the same code path as player actions, for example.
-WML_HANDLER_FUNCTION(do_command, cfg)
+WML_HANDLER_FUNCTION(do_command,, cfg)
{
// Doing this in a whiteboard applied context will cause bugs
// Note that even though game_events::pump() will always apply the real unit map
@@ -380,17 +312,12 @@ WML_HANDLER_FUNCTION(do_command, cfg)
/// Experimental data persistence
/// @todo Finish experimenting.
-WML_HANDLER_FUNCTION(get_global_variable, pcfg)
+WML_HANDLER_FUNCTION(get_global_variable,,pcfg)
{
verify_and_get_global_variable(pcfg);
}
-WML_HANDLER_FUNCTION(lift_fog, cfg)
-{
- toggle_fog(true, cfg, !cfg["multiturn"].to_bool(false));
-}
-
-WML_HANDLER_FUNCTION(modify_turns, cfg)
+WML_HANDLER_FUNCTION(modify_turns,, cfg)
{
config::attribute_value value = cfg["value"];
std::string add = cfg["add"];
@@ -417,7 +344,7 @@ WML_HANDLER_FUNCTION(modify_turns, cfg)
/// Moving a 'unit' - i.e. a dummy unit
/// that is just moving for the visual effect
-WML_HANDLER_FUNCTION(move_unit_fake, cfg)
+WML_HANDLER_FUNCTION(move_unit_fake,, cfg)
{
fake_unit_ptr dummy_unit(create_fake_unit(cfg));
if(!dummy_unit.get())
@@ -438,7 +365,7 @@ WML_HANDLER_FUNCTION(move_unit_fake, cfg)
}
}
-WML_HANDLER_FUNCTION(move_units_fake, cfg)
+WML_HANDLER_FUNCTION(move_units_fake,, cfg)
{
LOG_NG << "Processing [move_units_fake]\n";
@@ -491,7 +418,7 @@ WML_HANDLER_FUNCTION(move_units_fake, cfg)
}
/// If we should recall units that match a certain description.
-WML_HANDLER_FUNCTION(recall, cfg)
+WML_HANDLER_FUNCTION(recall,, cfg)
{
LOG_NG << "recalling unit...\n";
config temp_config(cfg.get_config());
@@ -573,10 +500,6 @@ WML_HANDLER_FUNCTION(recall, cfg)
LOG_WML << "A [recall] tag with the following content failed:\n" << cfg.get_config().debug();
}
-WML_HANDLER_FUNCTION(remove_sound_source, cfg)
-{
- resources::soundsources->remove(cfg["id"]);
-}
namespace {
struct map_choice : public mp_sync::user_choice
{
@@ -616,9 +539,10 @@ namespace {
};
}
+
/// Experimental map replace
/// @todo Finish experimenting.
-WML_HANDLER_FUNCTION(replace_map, cfg)
+WML_HANDLER_FUNCTION(replace_map,, cfg)
{
/*
* When a hex changes from a village terrain to a non-village terrain, and
@@ -676,20 +600,15 @@ WML_HANDLER_FUNCTION(replace_map, cfg)
ai::manager::raise_map_changed();
}
-WML_HANDLER_FUNCTION(reset_fog, cfg)
-{
- toggle_fog(false, cfg, cfg["reset_view"].to_bool(false));
-}
-
/// Experimental data persistence
/// @todo Finish experimenting.
-WML_HANDLER_FUNCTION(set_global_variable, pcfg)
+WML_HANDLER_FUNCTION(set_global_variable,,pcfg)
{
if (!resources::controller->is_replay())
verify_and_set_global_variable(pcfg);
}
-WML_HANDLER_FUNCTION(set_variables, cfg)
+WML_HANDLER_FUNCTION(set_variables,, cfg)
{
const t_string& name = cfg["name"];
variable_access_create dest = resources::gamedata->get_variable_access_write(name);
@@ -791,23 +710,10 @@ WML_HANDLER_FUNCTION(set_variables, cfg)
}
}
-WML_HANDLER_FUNCTION(sound_source, cfg)
-{
- config parsed = cfg.get_parsed_config();
- try {
- soundsource::sourcespec spec(parsed);
- resources::soundsources->add(spec);
- } catch (bad_lexical_cast &) {
- ERR_NG << "Error when parsing sound_source config: bad lexical cast." << std::endl;
- ERR_NG << "sound_source config was: " << parsed.debug() << std::endl;
- ERR_NG << "Skipping this sound source..." << std::endl;
- }
-}
-
/// Store the relative direction from one hex to another in a WML variable.
/// This is mainly useful as a diagnostic tool, but could be useful
/// for some kind of scenario.
-WML_HANDLER_FUNCTION(store_relative_direction, cfg)
+WML_HANDLER_FUNCTION(store_relative_direction,, cfg)
{
if (!cfg.child("source")) {
WRN_NG << "No source in [store_relative_direction]" << std::endl;
@@ -843,7 +749,7 @@ WML_HANDLER_FUNCTION(store_relative_direction, cfg)
/// In increments of 60 degrees, clockwise.
/// This is mainly useful as a diagnostic tool, but could be useful
/// for some kind of scenario.
-WML_HANDLER_FUNCTION(store_rotate_map_location, cfg)
+WML_HANDLER_FUNCTION(store_rotate_map_location,, cfg)
{
if (!cfg.child("source")) {
WRN_NG << "No source in [store_rotate_map_location]" << std::endl;
@@ -880,7 +786,7 @@ WML_HANDLER_FUNCTION(store_rotate_map_location, cfg)
/// Store time of day config in a WML variable. This is useful for those who
/// are too lazy to calculate the corresponding time of day for a given turn,
/// or if the turn / time-of-day sequence mutates in a scenario.
-WML_HANDLER_FUNCTION(store_time_of_day, cfg)
+WML_HANDLER_FUNCTION(store_time_of_day,, cfg)
{
const map_location loc = cfg_to_loc(cfg);
int turn = cfg["turn"];
@@ -903,7 +809,7 @@ WML_HANDLER_FUNCTION(store_time_of_day, cfg)
}
/// Creating a mask of the terrain
-WML_HANDLER_FUNCTION(terrain_mask, cfg)
+WML_HANDLER_FUNCTION(terrain_mask,, cfg)
{
map_location loc = cfg_to_loc(cfg, 1, 1);
@@ -934,7 +840,7 @@ WML_HANDLER_FUNCTION(terrain_mask, cfg)
resources::screen->needs_rebuild(true);
}
-WML_HANDLER_FUNCTION(tunnel, cfg)
+WML_HANDLER_FUNCTION(tunnel,, cfg)
{
const bool remove = cfg["remove"].to_bool(false);
if (remove) {
@@ -959,7 +865,7 @@ WML_HANDLER_FUNCTION(tunnel, cfg)
}
/// If we should spawn a new unit on the map somewhere
-WML_HANDLER_FUNCTION(unit, cfg)
+WML_HANDLER_FUNCTION(unit,, cfg)
{
config parsed_cfg = cfg.get_parsed_config();
@@ -1008,7 +914,7 @@ WML_HANDLER_FUNCTION(unit, cfg)
}
-WML_HANDLER_FUNCTION(volume, cfg)
+WML_HANDLER_FUNCTION(volume,, cfg)
{
int vol;
@@ -1036,26 +942,21 @@ WML_HANDLER_FUNCTION(volume, cfg)
}
-WML_HANDLER_FUNCTION(wml_message, cfg)
-{
- handle_wml_log_message( cfg.get_parsed_config() );
-}
-
-WML_HANDLER_FUNCTION(on_undo, cfg)
+WML_HANDLER_FUNCTION(on_undo, event_info, cfg)
{
if(cfg["delayed_variable_substitution"].to_bool(false)) {
- synced_context::add_undo_commands(cfg.get_config());
+ synced_context::add_undo_commands(cfg.get_config(), event_info);
} else {
- synced_context::add_undo_commands(cfg.get_parsed_config());
+ synced_context::add_undo_commands(cfg.get_parsed_config(), event_info);
}
}
-WML_HANDLER_FUNCTION(on_redo, cfg)
+WML_HANDLER_FUNCTION(on_redo, event_info, cfg)
{
if(cfg["delayed_variable_substitution"].to_bool(false)) {
- synced_context::add_redo_commands(cfg.get_config());
+ synced_context::add_redo_commands(cfg.get_config(), event_info);
} else {
- synced_context::add_redo_commands(cfg.get_parsed_config());
+ synced_context::add_redo_commands(cfg.get_parsed_config(), event_info);
}
}
diff --git a/src/game_events/action_wml.hpp b/src/game_events/action_wml.hpp
index 2389fd21b7fb..717f3a894fe5 100644
--- a/src/game_events/action_wml.hpp
+++ b/src/game_events/action_wml.hpp
@@ -48,7 +48,7 @@ namespace game_events
class wml_action {
public:
- typedef void (*handler)(const vconfig &);
+ typedef void (*handler)(const queued_event &, const vconfig &);
typedef std::map map;
/// Using this constructor for a static object outside action_wml.cpp
@@ -72,11 +72,6 @@ namespace game_events
*/
void change_terrain(const map_location &loc, const t_translation::t_terrain &t,
terrain_type_data::tmerge_mode mode, bool replace_if_failed);
-
- /** Used for [deprecated_message]. */
- void handle_deprecated_message(const config& cfg);
- /** Used for [wml_message]. */
- void handle_wml_log_message(const config& cfg);
}
#endif // GAME_EVENTS_ACTION_WML_H_INCLUDED
diff --git a/src/game_events/entity_location.cpp b/src/game_events/entity_location.cpp
index 75f6eed4526c..0a029d63229c 100644
--- a/src/game_events/entity_location.cpp
+++ b/src/game_events/entity_location.cpp
@@ -104,5 +104,20 @@ bool entity_location::matches_unit_filter(const unit_map::const_iterator & un_it
matches_unit(un_it);
}
+unit_const_ptr entity_location::get_unit() const
+{
+ if(resources::units == nullptr) {
+ return nullptr;
+ }
+ if(id_ == 0) {
+ auto un_it = resources::units->find(*this);
+ if(un_it.valid()) {
+ return un_it.get_shared_ptr();
+ }
+ return nullptr;
+ }
+ return resources::units->find(id_).get_shared_ptr();
+}
+
} // end namespace game_events
diff --git a/src/game_events/entity_location.hpp b/src/game_events/entity_location.hpp
index dd6bc6dc3c45..d8d07c5665e1 100644
--- a/src/game_events/entity_location.hpp
+++ b/src/game_events/entity_location.hpp
@@ -41,6 +41,7 @@ namespace game_events
bool matches_unit(const unit_map::const_iterator & un_it) const;
bool matches_unit_filter(const unit_map::const_iterator & un_it,
const vconfig & filter) const;
+ unit_const_ptr get_unit() const;
static const entity_location null_entity;
diff --git a/src/game_initialization/connect_engine.cpp b/src/game_initialization/connect_engine.cpp
index cd2819c587b5..0211aca50b89 100644
--- a/src/game_initialization/connect_engine.cpp
+++ b/src/game_initialization/connect_engine.cpp
@@ -988,11 +988,7 @@ config side_engine::new_config() const
// Merge the faction data to res.
config faction = flg_.current_faction();
res["faction_name"] = faction["name"];
- faction.remove_attribute("id");
- faction.remove_attribute("name");
- faction.remove_attribute("image");
- faction.remove_attribute("gender");
- faction.remove_attribute("type");
+ faction.remove_attributes("id", "name", "image", "gender", "type");
res.append(faction);
}
diff --git a/src/game_launcher.cpp b/src/game_launcher.cpp
index 29e619e91957..8ea22ba01c6e 100644
--- a/src/game_launcher.cpp
+++ b/src/game_launcher.cpp
@@ -883,14 +883,11 @@ bool game_launcher::play_multiplayer()
start_wesnothd();
} catch(game::mp_server_error&)
{
- std::string path = preferences::show_wesnothd_server_search(video());
-
- if (!path.empty())
- {
- preferences::set_mp_server_program_name(path);
+ preferences::show_wesnothd_server_search(video());
+
+ try {
start_wesnothd();
- }
- else
+ } catch(game::mp_server_error&)
{
return false;
}
diff --git a/src/gui/auxiliary/field.hpp b/src/gui/auxiliary/field.hpp
index 20ef5e5385fd..e7acae114e1a 100644
--- a/src/gui/auxiliary/field.hpp
+++ b/src/gui/auxiliary/field.hpp
@@ -31,8 +31,6 @@
#include "gui/widgets/window.hpp"
#include "wml_exception.hpp"
-#include
-
namespace gui2
{
@@ -289,7 +287,7 @@ class tfield : public tfield_
, callback_load_value_(callback_load_value)
, callback_save_value_(callback_save_value)
{
- BOOST_STATIC_ASSERT((!boost::is_same::value));
+ static_assert((!boost::is_same::value), "Second template argument cannot be tcontrol");
}
/**
@@ -313,7 +311,7 @@ class tfield : public tfield_
, callback_load_value_(std::function())
, callback_save_value_(std::function())
{
- BOOST_STATIC_ASSERT((!boost::is_same::value));
+ static_assert((!boost::is_same::value), "Second template argument cannot be tcontrol");
}
/**
@@ -340,7 +338,7 @@ class tfield : public tfield_
, callback_load_value_(std::function())
, callback_save_value_(std::function())
{
- BOOST_STATIC_ASSERT((boost::is_same::value));
+ static_assert((boost::is_same::value), "Second template argument must be tcontrol");
}
/** Inherited from tfield_. */
diff --git a/src/gui/auxiliary/formula.hpp b/src/gui/auxiliary/formula.hpp
index 9d7a4ef43240..cbe4b9ed47cf 100644
--- a/src/gui/auxiliary/formula.hpp
+++ b/src/gui/auxiliary/formula.hpp
@@ -24,8 +24,6 @@
#include "util.hpp"
#include "tstring.hpp"
-#include
-
#include
namespace gui2
@@ -235,7 +233,7 @@ tformula::execute(const game_logic::map_formula_callable& /*variables*/
{
// Every type needs its own execute function avoid instantiation of the
// default execute.
- BOOST_STATIC_ASSERT(sizeof(T) == 0);
+ static_assert(sizeof(T) == 0, "tformula: Missing execute specialization");
return T();
}
diff --git a/src/gui/core/timer.cpp b/src/gui/core/timer.cpp
index 97f325e43212..ab31805cf59b 100644
--- a/src/gui/core/timer.cpp
+++ b/src/gui/core/timer.cpp
@@ -17,8 +17,6 @@
#include "events.hpp"
#include "gui/core/log.hpp"
-#include
-
#include
#include