diff --git a/.gitmodules b/.gitmodules
index 4d903c57f..f76a3af9c 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,3 @@
-[submodule "lunit"]
- path = lunit
- url = https://github.com/ennorehling/lunit.git
[submodule "dlmalloc"]
path = dlmalloc
url = https://github.com/ennorehling/dlmalloc.git
diff --git a/.travis.yml b/.travis.yml
index d7a014d89..b702efaab 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,6 +17,7 @@ addons:
- valgrind
- cppcheck
- shellcheck
+ - luarocks
os:
- linux
notifications:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2d2635f05..0edbe230c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -48,8 +48,12 @@ endif()
find_package(EXPAT REQUIRED)
find_package (ToLua REQUIRED)
if (TOLUA_FOUND)
-if (${TOLUA_VERSION_STRING} VERSION_EQUAL "5.2")
+if (${TOLUA_VERSION_STRING} VERSION_EQUAL "5.3")
+find_package (Lua 5.3 REQUIRED)
+elseif (${TOLUA_VERSION_STRING} VERSION_EQUAL "5.2")
find_package (Lua 5.2 REQUIRED)
+elseif (${TOLUA_VERSION_STRING} VERSION_EQUAL "5.3")
+find_package ( Lua 5.3 REQUIRED)
else ()
find_package (Lua51 REQUIRED)
endif()
diff --git a/doc/befehle.txt b/doc/befehle.txt
new file mode 100644
index 000000000..0c725fb7b
--- /dev/null
+++ b/doc/befehle.txt
@@ -0,0 +1,15 @@
+# Befehlsverarbeitung in Eressea
+
+Einheiten haben zwei Listen von Befehlen: orders und old_orders.
+
+1. `read_unit`: Aus dem Datenfile gelesene (Default-)Befehl der Vorwoche werden in u->orders gespeichert.
+2. `begin_orders`: Wenn die Einheit neue Befehle erhält, werden "wiederholbare" Befehle (Handel, lange Befehle ausser NACH) aus u->orders nach u->old_orders kopiert.
+3. `unitorders`: Die neuen Befehle werden in u->orders gelesen.
+4. `update_long_order`: u->thisorder wird auf den ersten "langen" Befehl in u->orders gesetzt.
+5. Auswertung: Für lange Befehle wird in u->thisorder geschaut, für kurze und andere (inkl. KAUFE/ATTACKIERE) in u->orders.
+6. `movement`: NACH löscht u->thisorder, damit es nicht bei Auswertung der Zielregion ein zweites Mal ausgeführt werden kann. Das hat allerdings keine Auswirkung auf die beiden Listen.
+7. `build_building`: Wenn ein MACHE GEBAEUDE Befehl "fertig" ist, wird der Befehl in u->orders durch ein ARBEITE ersetzt (aber u->thisorder nicht geändert, das sollte also nichts tun).
+8. `defaultorders`: Nach allen langen Befehlen wird der DEFAULT Befehl gesetzt. Dieser löscht zuerst alle nicht-kurzen Befehle aus u->orders und u->old_orders, und hängt dann den neuen Befehl in u->old_orders an.
+9.1: `cr_output_unit`: In den CR werden alle "dauerhaften" Befehle aus u->old_orders geschrieben, d.h. kurze Befehle mit @ Prefix, Kommentare mit // und lange Befehle ausser NACH.
+9.2: `cr_output_unit`: In den CR werden alle "dauerhaften" Befehle aus u->orders geschrieben, d.h. kurze Befehle mit @ Prefix, Kommentare mit // und lange Befehle ausser NACH. Wenn u->old_orders nicht leer ist, werden "wiederholbare" Befehle dabei ignoriert.
+
diff --git a/lunit b/lunit
deleted file mode 160000
index 155c96594..000000000
--- a/lunit
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 155c96594435413b4f704eb17558ea0b70631bad
diff --git a/process/cron/preview.cron b/process/cron/preview.cron
index 63fe2ca76..5192d0f5a 100755
--- a/process/cron/preview.cron
+++ b/process/cron/preview.cron
@@ -3,6 +3,7 @@
[ "$PREVIEW" != "yes" ] && exit
[ -z "${ERESSEA}" ] && ERESSEA="$HOME/eressea"
+eval $(luarocks path)
branch="develop"
if [ -e "${ERESSEA}/build/.preview" ]; then
branch=$(cat "${ERESSEA}/build/.preview")
diff --git a/process/cron/run-eressea.cron b/process/cron/run-eressea.cron
index 697cc5e88..32ad873df 100755
--- a/process/cron/run-eressea.cron
+++ b/process/cron/run-eressea.cron
@@ -1,4 +1,6 @@
#!/bin/bash
+
+eval $(luarocks path)
GAME=$1
(
[ "$ENABLED" != "yes" ] && exit
diff --git a/process/sendreports.sh b/process/sendreports.sh
index 3219a69ea..6ed678d0a 100755
--- a/process/sendreports.sh
+++ b/process/sendreports.sh
@@ -17,8 +17,6 @@ fi
cd "$GAME/reports" || exit
for REPORT in *.sh
do
- #echo -n "Sending "
- #basename "$REPORT" .sh
bash "$REPORT"
done
cd - || exit
diff --git a/res/core/messages.xml b/res/core/messages.xml
index d40efb9ac..1fd1c106f 100644
--- a/res/core/messages.xml
+++ b/res/core/messages.xml
@@ -391,16 +391,6 @@
-
-
-
-
-
-
-
-
-
-
@@ -712,11 +702,6 @@
-
-
-
-
-
@@ -2690,6 +2675,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -3740,6 +3789,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/eressea/races.xml b/res/eressea/races.xml
index 82b642ba2..8c3822110 100644
--- a/res/eressea/races.xml
+++ b/res/eressea/races.xml
@@ -721,7 +721,7 @@
-
+
diff --git a/res/translations/messages.de.po b/res/translations/messages.de.po
index 5d2717e51..ae0f13dd4 100644
--- a/res/translations/messages.de.po
+++ b/res/translations/messages.de.po
@@ -437,9 +437,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - Pferde kann man
msgid "error307"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Snotlinge sind zu dumm, um auf den Feldern zu arbeiten.\""
-msgid "godcurse_destroy_ship"
-msgstr "\"Die Mannschaft krank vom vergifteten Wasser, Planken, Ruder und Segel zerfressen von den Wassern des verfluchten Meeres, ergibt sich die $ship($ship) in ihr Schicksal und sinkt.\""
-
msgid "too_many_units_in_faction"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Eine Partei darf nicht aus mehr als $int($allowed) Einheiten bestehen.\""
@@ -1034,9 +1031,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - Auf dem Schiff
msgid "sp_icastle_effect"
msgstr "\"Verwundert blicken die Bauern von $region($region) auf ein neues Gebäude.\""
-msgid "curseinfo::godcurse"
-msgstr "\"Diese Region wurde von den Göttern verflucht. Stinkende Nebel ziehen über die tote Erde und furchtbare Kreaturen ziehen über das Land. Die Brunnen sind vergiftet, und die wenigen essbaren Früchte sind von einem rosa Pilz überzogen. Niemand kann hier lange überleben. ($int36($id))\""
-
msgid "recruit_archetype"
msgstr "\"$unit($unit) rekrutiert $int($amount) $localize($archetype).\""
@@ -2555,9 +2549,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - Man benötigt m
msgid "error177"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Diesen Spruch kann der Vertraute nicht zaubern.\""
-msgid "curseinfo::godcurseocean"
-msgstr "\"Diese Region wurde von den Göttern verflucht. Das Meer ist eine ekelige Brühe, braunschwarze, stinkende Gase steigen aus den unergründlichen Tiefen hervor, und untote Seeungeheuer, Schiffe zerfressend und giftige grüne Galle geifernd, sind der Schrecken aller Seeleute, die diese Gewässer durchqueren. Niemand kann hier lange überleben. ($int36($id))\""
-
msgid "curseinfo::sparkle_4"
msgstr "\"Ein schimmernder Lichterkranz umgibt $unit($unit). ($int36($id))\""
@@ -2775,7 +2766,7 @@ msgid "error324"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit gehört nicht zu unserer Partei.\""
msgid "error322"
-msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit ist bereits auf einem Schiff.\""
+msgstr "\"$unit($unit) in $region($region): '$order($command)' - Nur Schiffe gleicher Bauart können einen Konvoi bilden.\""
msgid "error323"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Das Schiff ist verzaubert.\""
@@ -2783,6 +2774,9 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - Das Schiff ist
msgid "error327"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - So viele Schiffe kann die Einheit nicht übergeben.\""
+msgid "error328"
+msgstr "\"$unit($unit) in $region($region): '$order($command)' - Dafür müssen die Schiffe an derselben Küste liegen.\""
+
msgid "error326"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Diese Schiffe können keinen Konvoi bilden.\""
diff --git a/res/translations/messages.en.po b/res/translations/messages.en.po
index 659adee9f..b140f1690 100644
--- a/res/translations/messages.en.po
+++ b/res/translations/messages.en.po
@@ -437,9 +437,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - You can only br
msgid "error307"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - We snotlings is too stupid fer dat!\""
-msgid "godcurse_destroy_ship"
-msgstr "\"Her sailors sick from the poisened ocean, planks, rudder und sails corroded by the waters of the cursed ocean, the $ship($ship) finally succumbs to her destiny and sinks.\""
-
msgid "too_many_units_in_faction"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - A faction may not consist of more than $int($allowed) units.\""
@@ -1034,9 +1031,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - There are not e
msgid "sp_icastle_effect"
msgstr "\"Flabbergasted, the peasants of $region($region) behold a new building.\""
-msgid "curseinfo::godcurse"
-msgstr "\"This region was cursed by the gods. Stinking vapors billow over the dead ground and hideous creatures move about the country. The wells are poisened and the edible plants are covered by a pink fungus. Noone can live here for long. ($int36($id))\""
-
msgid "recruit_archetype"
msgstr "\"$unit($unit) recruits $int($amount) $localize($archetype).\""
@@ -1251,7 +1245,7 @@ msgid "error184"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit does not move.\""
msgid "income_entertainment"
-msgstr "\"$unit($unit) earns $int($amount) in $region($region) with entertainment.\""
+msgstr "\"$unit($unit) earns $int($amount) in $region($region) from entertainment.\""
msgid "error180"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The spell fails.\""
@@ -1620,7 +1614,7 @@ msgid "curseinfo::deathcloud"
msgstr "\"A poison elemental is spreading pestilence and death. ($int36($id))\""
msgid "income"
-msgstr "\"$unit($unit) earns $int($amount)$if($eq($wanted,$amount),\"\",\" of $int($wanted)\") in $region($region) $if($eq($mode,1),\" by entertainment\",$if($eq($mode,2),\" by taxes\",$if($eq($mode,3),\" by trade\",$if($eq($mode,5),\" by stealing\",$if($eq($mode,6),\" by magic\",$if($eq($mode,7),\" by pillaging\",\"\")))))).\""
+msgstr "\"$unit($unit) in $region($region) earns $int($amount)$if($eq($wanted,$amount),\"\",\" of $int($wanted)\") silver.\""
msgid "researchherb"
msgstr "\"$unit($unit) discovers that $localize($amount) $resource($herb,0) grow in $region($region).\""
@@ -2115,7 +2109,7 @@ msgid "deathcloud_effect"
msgstr "\"$unit($mage) summons a poison elemental in $region($region).\""
msgid "nr_population"
-msgstr "\"Your faction has $int($population) people in $int($units) of $int($limit) possible units.\""
+msgstr "\"Your faction has $int($population) $if($eq($population,1), \"person\", \"persons\") in $int($units) of $int($limit) possible units.\""
msgid "curseinfo::shipdisorientation"
msgstr "This ship has lost its path. ($int36($id))"
@@ -2223,7 +2217,7 @@ msgid "curseinfo::healingzone"
msgstr "Healing in this region is affected by magic. ($int36($id))"
msgid "income_entertainment_reduced"
-msgstr "\"In $region($region), $unit($unit) earns only $int($amount) instead of$if($eq($wanted,$amount),\"\",\" of$if($eq($wanted,$amount),\"\",\" of $int($wanted)\") \") with entertainment.\""
+msgstr "\"In $region($region), $unit($unit) earns only $int($amount) instead of$if($eq($wanted,$amount),\"\",\" of$if($eq($wanted,$amount),\"\",\" of $int($wanted)\") \") from entertainment.\""
msgid "errusingpotion"
msgstr "\"$unit($unit): '$order($command)' - The unit already uses $resource($using,0).\""
@@ -2555,9 +2549,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - You need at lea
msgid "error177"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The familiar cannot cast this spell.\""
-msgid "curseinfo::godcurseocean"
-msgstr "\"This region was cursed by the gods. The sea is a foul cesspool, noxious gases rise from the deep, undead seamonsters attack all ships. Noone can live here for long. ($int36($id))\""
-
msgid "curseinfo::sparkle_4"
msgstr "\"A circle of shimmering lights surrounds $unit($unit). ($int36($id))\""
@@ -2781,11 +2772,14 @@ msgid "error324"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit is not one of ours.\""
msgid "error322"
-msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit is already on a ship.\""
+msgstr "\"$unit($unit) in $region($region): '$order($command)' - Only ships of the same type can form a convoy.\""
msgid "error323"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - The ship is under a spell.\""
+msgid "error328"
+msgstr "\"$unit($unit) in $region($region): '$order($command)' - All ships of a convoy must be on the same coast.\""
+
msgid "dissolve_units_2"
msgstr "\"$unit($unit) in $region($region): $int($number) $race($race,$number) turned into $if($eq($number,1),\"a tree\", \"trees\").\""
diff --git a/res/translations/strings.de.po b/res/translations/strings.de.po
index 1351c3d05..ba16c31e9 100644
--- a/res/translations/strings.de.po
+++ b/res/translations/strings.de.po
@@ -2331,10 +2331,6 @@ msgstr "Seelenfrieden"
msgid "list_and"
msgstr " und "
-msgctxt "spell"
-msgid "godcursezone"
-msgstr "Fluch der Götter"
-
msgid "sptype_postcombat"
msgstr "Postkampfzauber"
@@ -3894,7 +3890,7 @@ msgstr "Ent"
msgctxt "iteminfo"
msgid "dwarfspoil"
-msgstr "Beim Barte des Proheten! Ach nein, Zwergen. Irgendetwas riecht hier ranzig."
+msgstr "Beim Barte des Propheten! Ach nein, Zwergen. Irgendetwas riecht hier ranzig."
msgctxt "race"
msgid "clone"
@@ -6324,3 +6320,44 @@ msgctxt "race"
msgid "wolf"
msgstr "Wolf"
+msgctxt "iteminfo"
+msgid "elfspoil"
+msgstr "Die Ohren sind spitz und beinahe trapezförmig. Wie kann
+damit hören?"
+
+msgctxt "iteminfo"
+msgid "goblinspoil"
+msgstr "Die Fratze des kleinen Kopfs wirkt beinahe etwas kindlich
+zierlich, aber dennoch liegt etwas Listiges darin."
+
+msgctxt "iteminfo"
+msgid "halflingspoil"
+msgstr "Die Sohle des behaarten Fußes ist deutlich dicker, beinahe
+wie ein Huf."
+
+msgctxt "iteminfo"
+msgid "aquarianspoil"
+msgstr "Die kleine, türkisfarbene Schuppe glänzt in der Sonne. Dennoch ist sie erstaunlich hart."
+
+msgctxt "iteminfo"
+msgid "humanspoil"
+msgstr "Ob blond oder braun, ob kurz oder lang, du hast ein Büschel Haare mit einem Stück Haut in der Hand."
+
+msgctxt "iteminfo"
+msgid "catspoil"
+msgstr "Wie ein kleines Seil aus weichem Fell."
+
+msgctxt "iteminfo"
+msgid "insectspoil"
+msgstr "Das am Kopf der meisten Gliederfüßer auftretende,
+gegliederte Extremitätenpaar, das mit Sensillen (Tastsinn, Geruchssinn)
+ausgestattet ist."
+
+msgctxt "iteminfo"
+msgid "orcspoil"
+msgstr "Große, spitze Zähne. Ob sie früher einem Ork oder doch einem Wildschwein gehörten ist nicht so leicht zu unterscheiden."
+
+msgctxt "iteminfo"
+msgid "demonspoil"
+msgstr "Eine giftige und grüne Flüssigkeit in einer kleinen Phiole,
+keine humanoide Rasse außer Dämonen wagt damit in Kontakt zu kommen."
diff --git a/res/translations/strings.en.po b/res/translations/strings.en.po
index eae203dbd..f1e04959e 100644
--- a/res/translations/strings.en.po
+++ b/res/translations/strings.en.po
@@ -1976,10 +1976,6 @@ msgstr " and "
msgid "h18_p"
msgstr "ice begonias"
-msgctxt "spell"
-msgid "godcursezone"
-msgstr "Curse of the Gods"
-
msgid "sptype_postcombat"
msgstr "post-combat spell"
diff --git a/s/build b/s/build
index 709c92510..e54f83ace 100755
--- a/s/build
+++ b/s/build
@@ -1,6 +1,6 @@
#!/bin/sh
ROOT=$(git rev-parse --show-toplevel)
-
+eval $(luarocks path)
[ -z "$BUILD" ] && BUILD=Debug
if [ -z "$JOBS" ] ; then
if [ -e /usr/sbin/sysctl ]; then
diff --git a/s/cmake-init b/s/cmake-init
index eea222334..00e6d3d06 100755
--- a/s/cmake-init
+++ b/s/cmake-init
@@ -6,6 +6,7 @@ pkg-config --exists sqlite3 && ERESSEA_DB=sqlite
GETOPT=getopt
GETOPT_LONG=1
+luarocks install lunitx --local
if [ "Darwin" = "$(uname)" ] ; then
if [ -x "/usr/local/opt/gnu-getopt/bin/getopt" ] ; then
GETOPT="/usr/local/opt/gnu-getopt/bin/getopt"
@@ -74,18 +75,19 @@ fi
DEST=$(dirname $ROOT)/server
-git submodule update --init
-
LUA_VERSION="5.2"
LUA_INCLUDE=/usr/include
LUA_DIR=/usr
-if [ -d /usr/include/lua5.1 ]; then
- LUA_VERSION="5.1"
- LUA_INCLUDE=/usr/include/lua5.1
+if [ -d /usr/local/include/lua5.3 ]; then
+ LUA_VERSION="5.3"
+ LUA_INCLUDE=/usr/local/include/lua5.3
elif [ -d /usr/include/lua5.2 ]; then
export LUA_DIR=/usr
LUA_VERSION="5.2"
LUA_INCLUDE=/usr/include/lua5.2
+elif [ -d /usr/include/lua5.1 ]; then
+ LUA_VERSION="5.1"
+ LUA_INCLUDE=/usr/include/lua5.1
elif [ -d /usr/local/include/lua5.1 ]; then
export LUA_DIR=/usr/local
LUA_VERSION="5.1"
@@ -125,6 +127,7 @@ TOLUA
else
echo "tolua is $path"
fi
+luarocks --local install lunitx
unset path
set -e
diff --git a/s/runtests b/s/runtests
index b74a4b785..2c8049098 100755
--- a/s/runtests
+++ b/s/runtests
@@ -1,6 +1,7 @@
#!/bin/bash
set -e
+eval $(luarocks path)
ROOT=$(git rev-parse --show-toplevel)
[ -z $BUILD ] && BUILD=Debug ; export BUILD
diff --git a/scripts/eressea/path.lua b/scripts/eressea/path.lua
index def970919..085cda997 100644
--- a/scripts/eressea/path.lua
+++ b/scripts/eressea/path.lua
@@ -3,4 +3,3 @@ if config.paths ~= nil then
package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua'
end
end
--- print(package.path)
diff --git a/scripts/run-tests-e2.lua b/scripts/run-tests-e2.lua
index 64a090108..dd0631086 100644
--- a/scripts/run-tests-e2.lua
+++ b/scripts/run-tests-e2.lua
@@ -1,17 +1,19 @@
-- Tests that work in all games. With game config of E2.
-- Tests are under scripts/test/e2 and all files must be in scripts/test/e2/init.lua
+lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+module = lunit.module
+end
+
path = 'scripts'
if config.install then
path = config.install .. '/' .. path
- package.path = package.path .. ';' .. config.install .. '/lunit/?.lua'
- --needed to find lunit if not run from eressea root. Needs right [lua] install setting in eressea.ini (point to eressea root from the start folder)
end
package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua'
config.rules = 'e2'
-lunit = require 'lunit'
require 'eressea'
require 'eressea.xmlconf'
require 'eressea.path'
diff --git a/scripts/run-tests-e3.lua b/scripts/run-tests-e3.lua
index 43d42635e..e2a808147 100644
--- a/scripts/run-tests-e3.lua
+++ b/scripts/run-tests-e3.lua
@@ -1,17 +1,19 @@
-- Tests that work in E3. With game config of E3.
-- Tests are under scripts/test/e3 and all files must be in scripts/test/e3/init.lua
+lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+module = lunit.module
+end
+
path = 'scripts'
if config.install then
path = config.install .. '/' .. path
- package.path = package.path .. ';' .. config.install .. '/lunit/?.lua'
- --needed to find lunit if not run form eressea root. Needs right [lua] install setting in eressea.ini (point to eressea root from the start folder)
end
package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua'
config.rules = 'e3'
-lunit = require 'lunit'
require 'eressea'
require 'eressea.path'
require 'eressea.xmlconf'
diff --git a/scripts/run-tests.lua b/scripts/run-tests.lua
index c41c29f01..e21ac3aa9 100644
--- a/scripts/run-tests.lua
+++ b/scripts/run-tests.lua
@@ -1,15 +1,17 @@
-- Basic test without loading XML Config. Test care about needed settings.
-- Tests are under scripts/test/ and all files must be in scripts/test/init.lua
+lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+module = lunit.module
+end
+
path = 'scripts'
if config.install then
path = config.install .. '/' .. path
- package.path = package.path .. ';' .. config.install .. '/lunit/?.lua'
- --needed to find lunit if not run form eressea root. Needs right [lua] install setting in eressea.ini (point to eressea root from the start folder)
end
package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua'
-lunit = require 'lunit'
require 'eressea'
require 'eressea.path'
require 'tests'
diff --git a/scripts/run-turn.lua b/scripts/run-turn.lua
index e5c90a7be..7ef29b00d 100644
--- a/scripts/run-turn.lua
+++ b/scripts/run-turn.lua
@@ -130,8 +130,9 @@ function process(rules, orders)
end
turn_begin()
-
- -- run the turn:
+ -- create orders for monsters:
+ plan_monsters()
+ -- read orders for players:
if eressea.read_orders(orders) ~= 0 then
print("could not read " .. orders)
return -1
@@ -140,8 +141,9 @@ function process(rules, orders)
if nmr_check(config.maxnmrs or 80)~=0 then
return -1
end
- plan_monsters()
callbacks(rules, 'init')
+
+ -- run the turn:
turn_process()
callbacks(rules, 'update')
turn_end() -- ageing, etc.
diff --git a/scripts/tests/bindings.lua b/scripts/tests/bindings.lua
index 5820e0a47..bdacf2660 100644
--- a/scripts/tests/bindings.lua
+++ b/scripts/tests/bindings.lua
@@ -1,10 +1,13 @@
-require "lunit"
+local tcname = 'tests.bindings'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
-local eressea = eressea
local _G = _G
-module("tests.bindings", lunit.testcase)
-
function test_eressea()
assert_equal("function", _G.type(eressea.free_game))
assert_equal("function", _G.type(eressea.read_game))
diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua
index 96069d4a5..058a53e2f 100644
--- a/scripts/tests/common.lua
+++ b/scripts/tests/common.lua
@@ -1,4 +1,10 @@
-require "lunit"
+local tcname = 'tests.shared.common'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
local function _test_create_ship(r)
local s = ship.create(r, config.ships[1])
@@ -26,8 +32,6 @@ local function two_factions()
return f1, f2
end
-module("tests.common", package.seeall, lunit.testcase)
-
function setup()
eressea.free_game()
eressea.settings.set("nmr.timeout", "0")
@@ -894,308 +898,3 @@ function test_walk_and_carry_the_cart()
process_orders()
assert_equal(1, u.region.x)
end
-
-module("tests.recruit", package.seeall, lunit.testcase)
-
-function setup()
- eressea.free_game()
- eressea.settings.set("rules.food.flags", "4")
- eressea.settings.set("rules.peasants.growth", "0")
-end
-
-function test_bug_1795_limit()
- local r = region.create(0, 0, "plain")
- local f = create_faction('human')
- local u1 = one_unit(r,f)
- u1:add_item("money", 100000000)
- u1:add_order("REKRUTIEREN 9999")
- r:set_resource("peasant", 2000) -- no fractional growth!
- local peasants = r:get_resource("peasant")
- local limit,frac = math.modf(peasants/40) -- one day this should be a parameter
-
- process_orders()
- assert_equal(limit+1, u1.number, u1.number .. "!=" .. (limit+1))
- assert_equal(peasants-limit, r:get_resource("peasant"))
-end
-
-function test_bug_1795_demons()
- local r = region.create(0, 0, "plain")
- local f = create_faction('demon')
- local u1 = one_unit(r,f)
- r:set_resource("peasant", 2000)
- local peasants = r:get_resource("peasant")
- local limit,frac = math.modf(peasants/40)
-
- u1:add_item("money", 100000000)
- u1:add_order("REKRUTIEREN 9999")
-
- process_orders()
-
- assert_equal(limit+1, u1.number, u1.number .. "!=" .. (limit+1))
- assert_equal(peasants, r:get_resource("peasant"))
-end
-
-module("tests.parser", package.seeall, lunit.testcase)
-
-function setup()
- eressea.free_game()
- eressea.settings.set("rules.food.flags", "4") -- FOOD_IS_FREE
- eressea.settings.set("rules.move.owner_leave", "0")
-end
-
-function test_parser()
- local r = region.create(0, 0, "mountain")
- local f = create_faction('human')
- local u = unit.create(f, r, 1)
- local filename = "orders.txt"
-
- local file = io.open(filename, "w")
- assert_not_nil(file)
- f.password = 'Hodor'
- file:write('ERESSEA ' .. itoa36(f.id) .. ' "Hodor"\n')
- file:write('EINHEIT ' .. itoa36(u.id) .. "\n")
- file:write("BENENNEN EINHEIT 'Goldene Herde'\n")
- file:close()
-
- eressea.read_orders(filename)
- process_orders()
- os.remove(filename)
- assert_equal("Goldene Herde", u.name)
-end
-
-local function set_order(u, str)
- u:clear_orders()
- u:add_order(str)
-end
-
-function test_prefix()
- local r0 = region.create(0, 0, "plain")
- local f1 = create_faction('human')
- local u1 = unit.create(f1, r0, 1)
-
- set_order(u1, "PRAEFIX See")
- process_orders()
- assert_not_nil(u1:show():find("Seemensch"))
-
- u1.race = "elf"
- assert_not_nil(u1:show():find("Seeelf"))
-
- set_order(u1, "PRAEFIX Mond")
- process_orders()
- assert_not_nil(u1:show():find("Mondelf"))
-
- set_order(u1, "PRAEFIX")
- process_orders()
- assert_not_nil(u1:show():find("Elf"))
-
- set_order(u1, "PRAEFIX Erz")
- process_orders()
- assert_not_nil(u1:show():find("Erzelf"))
- u1.faction.locale = "en"
- assert_not_nil(u1:show():find("archelf"))
-end
-
-function test_recruit()
- local r = region.create(0, 0, "plain")
- local f = create_faction('human')
- local u = unit.create(f, r, 1)
-
- u:add_item("money", 1000)
- set_order(u, "REKRUTIERE 5")
- process_orders()
- for u in f.units do
- assert_equal(6, u.number)
- end
-end
-
-function test_give_horses()
- local r = region.create(0, 0, "plain")
- local f = faction.create("human", "noreply@eressea.de", "de")
- local u = unit.create(f, r, 1)
-
- r:set_resource("horse", 0)
- u:add_item("horse", 21)
- u:add_item("dolphin", 10)
- u:add_order("GIB 0 7 PFERD")
- u:add_order("GIB 0 5 DELPHIN")
- process_orders()
- assert_equal(7, r:get_resource("horse"))
- assert_equal(5, u:get_item("dolphin"))
- assert_equal(14, u:get_item("horse"))
-end
-
-function test_give_silver()
- local r = region.create(0, 0, "plain")
- local f = faction.create("human", "noreply@eressea.de", "de")
- local u = unit.create(f, r, 1)
-
- r:set_resource("peasant", 0)
- r:set_resource("money", 11)
- u:clear_orders()
- u:add_item("money", 20)
- u:add_order("GIB 0 10 SILBER")
- process_orders()
- assert_equal(21, r:get_resource("money"))
- assert_equal(10, u:get_item("money"))
-end
-
-function test_give_horses()
- local r = region.create(0, 0, "plain")
- local f = create_faction('human')
- local u = unit.create(f, r, 1)
-
- r:set_resource("horse", 0)
- u:add_item("horse", 21)
- u:add_item("dolphin", 10)
- u:add_order("GIB 0 7 PFERD")
- u:add_order("GIB 0 5 DELPHIN")
- process_orders()
- assert_equal(7, r:get_resource("horse"))
- assert_equal(5, u:get_item("dolphin"))
- assert_equal(14, u:get_item("horse"))
-end
-
-function test_give_silver()
- local r = region.create(0, 0, "plain")
- local f = create_faction('human')
- local u = unit.create(f, r, 1)
-
- r:set_resource("peasant", 0)
- r:set_resource("money", 11)
- u:clear_orders()
- u:add_item("money", 20)
- u:add_order("GIB 0 10 SILBER")
- process_orders()
- assert_equal(21, r:get_resource("money"))
- assert_equal(10, u:get_item("money"))
-end
-
-function test_build_castle_one_stage()
- local r = region.create(0, 0, 'plain')
- local f = faction.create('human')
- local u = unit.create(f, r, 2)
-
- u:add_item('stone', 4)
-
- u:set_skill('building', 1)
- u:add_order('MACHE BURG')
-
- process_orders()
- assert_equal(2, u.building.size)
- assert_equal(2, u:get_item('stone'))
-end
-
-function test_build_castle()
- local r = region.create(0, 0, "plain")
- local f = create_faction('human')
- local u = unit.create(f, r, 1)
-
- u:add_item('stone', 1)
- u:set_skill('building', 1)
- u:add_order("MACHE BURG")
- process_orders()
- assert_not_nil(u.building)
- assert_equal(1, u.building.size)
- assert_equal(u.building.name, "Burg")
-end
-
-function test_route()
- local r1 = region.create(0, 0, "plain")
- local r2 = region.create(1, 0, "plain")
- local f = faction.create("human", "route@example.com")
- local u = unit.create(f, r1, 1)
- u:add_order("ROUTE O W P")
- process_orders()
- assert_equal("ROUTE West PAUSE Ost", u:get_order(0))
- assert_equal(r2, u.region)
-end
-
-function test_route_horse()
- local r1 = region.create(0, 0, "plain")
- local r2 = region.create(1, 0, "plain")
- local f = faction.create("human", "route@example.com")
- local u = unit.create(f, r1, 1)
- u:add_order("ROUTE O P W P")
- u:add_item('horse', 1)
- u:set_skill('riding', 1)
- process_orders()
- assert_equal("ROUTE West PAUSE Ost PAUSE", u:get_order(0))
- assert_equal(r2, u.region)
-end
-
-function test_route_pause()
- local r1 = region.create(0, 0, "plain")
- local r2 = region.create(1, 0, "plain")
- local f = faction.create("human", "route@example.com")
- local u = unit.create(f, r1, 1)
- u:add_order("ROUTE P O W")
- process_orders()
- assert_equal("ROUTE P O W", u:get_order(0))
- assert_equal(r1, u.region)
-end
-
-function test_immunity_stops_guard()
- eressea.settings.set("NewbieImmunity", 2)
- local f = faction.create('human')
- local r = region.create(0, 0, 'plain')
- local u = unit.create(f, r)
- u:set_skill('polearm', 2)
- u:add_item('lance', 1)
- u:add_order('BEWACHE')
- process_orders()
- assert_equal(f.age, 1)
- assert_true(not u.guard)
- process_orders()
- assert_equal(f.age, 2)
- assert_true(u.guard)
-end
-
-function test_region_keys()
- local r = region.create(0, 0, 'plain')
- assert_nil(r:get_key('test'))
- assert_nil(r:get_key('more'))
- r:set_key('test', 42)
- r:set_key('more') -- default is 1
- assert_equal(42, r:get_key('test'))
- assert_equal(1, r:get_key('more'))
-end
-
-function test_faction_keys()
- local f = faction.create('human')
- assert_nil(f:get_key('test'))
- assert_nil(f:get_key('more'))
- f:set_key('test', 42)
- f:set_key('more') -- default is 1
- assert_equal(42, f:get_key('test'))
- assert_equal(1, f:get_key('more'))
-end
-
-function test_cartmaking()
- local f = faction.create('human')
- local r = region.create(0, 0, 'plain')
- local u = unit.create(f, r)
- u:set_skill('cartmaking', 1)
- u:add_item('log', 10)
- u:add_order('MACHE Wagen')
- process_orders()
- assert_equal(1, u:get_item('cart'))
- assert_equal(5, u:get_item('log'))
-end
-
-function test_promote_after_recruit()
- local f = faction.create('human')
- local r1 = region.create(0, 0, 'plain')
- local r2 = region.create(1, 0, 'plain')
- local u1 = unit.create(f, r1, 1)
- u1.name = 'Xolgrim'
- local u2 = unit.create(f, r2, 55)
- u2:add_order('REKRUTIERE 1')
- u1:add_order('BEFOERDERE')
- u1:add_item('money', 57)
- u2:add_item('money', 150)
- local fl = u1.flags
- process_orders()
- assert_equal(56, u2.number)
- assert_equal(fl + 128, u1.flags) -- UFL_HERO
- assert_equal(0, u1:get_item('money'))
-end
diff --git a/scripts/tests/config.lua b/scripts/tests/config.lua
index 733a8ee07..0ea46b133 100644
--- a/scripts/tests/config.lua
+++ b/scripts/tests/config.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.eressea.config", package.seeall, lunit.testcase )
+local tcname = 'tests.shared.config'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/e2/adamantium.lua b/scripts/tests/e2/adamantium.lua
index a893d32d5..49766cb52 100644
--- a/scripts/tests/e2/adamantium.lua
+++ b/scripts/tests/e2/adamantium.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.adamantium", package.seeall, lunit.testcase )
+local tcname = 'tests.e2.adamantium'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/e2/allies.lua b/scripts/tests/e2/allies.lua
index ef38a97bf..977d75c61 100644
--- a/scripts/tests/e2/allies.lua
+++ b/scripts/tests/e2/allies.lua
@@ -1,17 +1,13 @@
-require "lunit"
+local tcname = 'tests.e2.allies'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
-module("tests.e2.allies", package.seeall, lunit.testcase)
-
-function skip_test_get_set_ally()
- local f1 = faction.create("human")
- local f2 = faction.create("human")
-
- assert_equal(false, f1:get_ally(f2, "guard"))
- f1:set_ally(f2, "guard", true)
- assert_equal(true, f1:get_ally(f2, "guard"))
- assert_equal(false, f1:get_ally(f2, "give"))
- f1:set_ally(f2, "give", true)
- assert_equal(true, f1:get_ally(f2, "give"))
+function setup()
+ eressea.free_game()
end
function test_get_allies()
@@ -28,3 +24,16 @@ function test_get_allies()
assert_equal(1, #allies[f2.id])
assert_equal("give", allies[f2.id][1])
end
+
+function test_get_set_ally()
+ local f1 = faction.create("human")
+ local f2 = faction.create("human")
+
+ assert_equal(false, f1:get_ally(f2, "guard"))
+ f1:set_ally(f2, "guard", true)
+ assert_equal(true, f1:get_ally(f2, "guard"))
+ assert_equal(false, f1:get_ally(f2, "give"))
+ f1:set_ally(f2, "give", true)
+ assert_equal(true, f1:get_ally(f2, "give"))
+end
+
diff --git a/scripts/tests/e2/astral.lua b/scripts/tests/e2/astral.lua
index 5c4461921..20e53cb73 100644
--- a/scripts/tests/e2/astral.lua
+++ b/scripts/tests/e2/astral.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.astral", package.seeall, lunit.testcase)
+local tcname = 'tests.e2.astral'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
@@ -17,7 +21,7 @@ function test_fetch_astral()
local r = region.create(0, 0, "plain")
local ra = r:get_astral('fog')
local rb = region.create(ra.x + 1, ra.y, 'fog')
- local f = faction.create("human")
+ local f = faction.create("human");
local u1 = unit.create(f, r, 1)
local u2 = unit.create(f, r, 1)
local u3 = unit.create(f, rb, 1)
diff --git a/scripts/tests/e2/buildings.lua b/scripts/tests/e2/buildings.lua
index 845c4ba7d..3ae9c0337 100644
--- a/scripts/tests/e2/buildings.lua
+++ b/scripts/tests/e2/buildings.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.buildings", package.seeall, lunit.testcase )
+local tcname = 'tests.e2.buildings'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.game.reset()
@@ -41,7 +45,6 @@ function test_build_tunnel_limited()
u:add_item('iron', 2)
u:add_item('money', 700)
u.building = b
- u.name = 'Xolgrim'
u:add_order('MACHE 2 BURG ' .. itoa36(b.id))
b.size = 99
process_orders()
diff --git a/scripts/tests/e2/carts.lua b/scripts/tests/e2/carts.lua
index 025b473df..f96affba7 100644
--- a/scripts/tests/e2/carts.lua
+++ b/scripts/tests/e2/carts.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.carts", package.seeall, lunit.testcase)
+local tcname = 'tests.e2.carts'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/e2/destroy.lua b/scripts/tests/e2/destroy.lua
index 430ca301c..bbdab2b0d 100644
--- a/scripts/tests/e2/destroy.lua
+++ b/scripts/tests/e2/destroy.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.destroy", package.seeall, lunit.testcase)
+local tcname = 'tests.e2.destroy'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
@@ -41,8 +45,8 @@ function test_destroy_is_long()
local u = unit.create(faction.create("human", "one@example.com", "de"), r1, 10)
u.building = building.create(u.region, "castle")
u:clear_orders()
- u:add_order("LERNE Unterhaltung")
u:add_order("ZERSTOERE " .. itoa36(u.building.id))
+ u:add_order("LERNE Unterhaltung")
process_orders()
assert_equal(0, u:get_skill("entertainment"))
assert_equal(nil, u.building)
diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua
index b0233c3fb..f0ee62414 100644
--- a/scripts/tests/e2/e2features.lua
+++ b/scripts/tests/e2/e2features.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.e2features", package.seeall, lunit.testcase )
+local tcname = 'tests.e2.features'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
@@ -12,6 +16,26 @@ function setup()
eressea.settings.set("rules.peasants.growth.factor", "0")
end
+function disabled_double_default()
+ local r = region.create(0, 0, "plain")
+ local f = faction.create("human")
+ local u = unit.create(f, r, 1)
+ region.create(1, 0, "plain")
+ region.create(2, 0, "plain")
+ region.create(3, 0, "plain")
+
+ u:add_order('NACH O')
+ u:add_order('DEFAULT "NACH O"')
+ u:add_order('DEFAULT "DEFAULT ARBEITE"')
+ process_orders()
+ assert_equal(1, u.region.x)
+ process_orders()
+ assert_equal(2, u.region.x)
+ process_orders()
+ assert_equal(2, u.region.x)
+ assert_equal("ARBEITE", u:get_order())
+end
+
function test_give_unit()
local r = region.create(0, 0, "plain")
local f1 = faction.create('elf')
diff --git a/scripts/tests/e2/guard.lua b/scripts/tests/e2/guard.lua
index e3cf8075f..0cc970f8c 100644
--- a/scripts/tests/e2/guard.lua
+++ b/scripts/tests/e2/guard.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.guard", package.seeall, lunit.testcase)
+local tcname = 'tests.e2.guard'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua
index 3bd09bafc..587c295c0 100644
--- a/scripts/tests/e2/init.lua
+++ b/scripts/tests/e2/init.lua
@@ -1,14 +1,14 @@
+require 'tests.e2.trolls'
+require 'tests.e2.trees'
require 'tests.e2.buildings'
-require 'tests.e2.allies'
-require 'tests.e2.quit'
require 'tests.e2.movement'
require 'tests.e2.carts'
-require 'tests.e2.quit'
require 'tests.e2.astral'
require 'tests.e2.spells'
require 'tests.e2.e2features'
require 'tests.e2.insects'
require 'tests.e2.production'
+require 'tests.e2.allies'
require 'tests.e2.adamantium'
require 'tests.e2.undead'
require 'tests.e2.shiplanding'
@@ -22,6 +22,8 @@ require 'tests.items'
require 'tests.economy'
require 'tests.orders'
require 'tests.common'
+require 'tests.recruit'
+require 'tests.parser'
require 'tests.report'
require 'tests.storage'
require 'tests.magicbag'
@@ -30,3 +32,4 @@ require 'tests.xmas'
require 'tests.production'
require 'tests.spells'
require 'tests.undead'
+
diff --git a/scripts/tests/e2/insects.lua b/scripts/tests/e2/insects.lua
index f5b8a3213..2e7fe5282 100644
--- a/scripts/tests/e2/insects.lua
+++ b/scripts/tests/e2/insects.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.insects", package.seeall, lunit.testcase)
+local tcname = 'tests.e2.insects'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/e2/items.lua b/scripts/tests/e2/items.lua
index 2492a7fdb..ba0d305c8 100644
--- a/scripts/tests/e2/items.lua
+++ b/scripts/tests/e2/items.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.items", package.seeall, lunit.testcase )
+local tcname = 'tests.e2.items'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/e2/movement.lua b/scripts/tests/e2/movement.lua
index aa42857f3..d5f2f886f 100644
--- a/scripts/tests/e2/movement.lua
+++ b/scripts/tests/e2/movement.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.movement", package.seeall, lunit.testcase)
+local tcname = 'tests.e2.movement'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/e2/production.lua b/scripts/tests/e2/production.lua
index 80d3447d2..092e44dd6 100644
--- a/scripts/tests/e2/production.lua
+++ b/scripts/tests/e2/production.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.production", package.seeall, lunit.testcase )
+local tcname = 'tests.e2.production'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.game.reset()
diff --git a/scripts/tests/e2/quit.lua b/scripts/tests/e2/quit.lua
index 7db59091b..f1a8e6a0c 100644
--- a/scripts/tests/e2/quit.lua
+++ b/scripts/tests/e2/quit.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.quit", package.seeall, lunit.testcase)
+local tcname = 'tests.e2.quit'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function test_quit_faction()
local r = region.create(47, 0, "plain")
diff --git a/scripts/tests/e2/shiplanding.lua b/scripts/tests/e2/shiplanding.lua
index 2258a1992..f5eb9f400 100644
--- a/scripts/tests/e2/shiplanding.lua
+++ b/scripts/tests/e2/shiplanding.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.shiplanding", package.seeall, lunit.testcase)
+local tcname = 'tests.e2.shiplanding'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/e2/ships.lua b/scripts/tests/e2/ships.lua
index 5b77220ec..db44871b3 100644
--- a/scripts/tests/e2/ships.lua
+++ b/scripts/tests/e2/ships.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.ships", package.seeall, lunit.testcase)
+local tcname = 'tests.e2.ships'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.game.reset()
diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua
index de2386113..2a5c50b2c 100644
--- a/scripts/tests/e2/spells.lua
+++ b/scripts/tests/e2/spells.lua
@@ -1,9 +1,13 @@
-require "lunit"
-
-module("tests.e2.spells", package.seeall, lunit.testcase)
+local tcname = 'tests.e2.spells'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
- eressea.free_game()
+ eressea.game.reset()
eressea.settings.set("nmr.removenewbie", "0")
eressea.settings.set("nmr.timeout", "0")
eressea.settings.set("NewbieImmunity", "0")
@@ -14,6 +18,26 @@ function setup()
eressea.settings.set("magic.regeneration.enable", "0")
end
+function test_undead_cannot_enter_holyground()
+ local r1 = region.create(0, 0, 'plain')
+ local r2 = region.create(1, 0, 'plain')
+ local f = faction.create('human')
+ local u1 = unit.create(f, r1, 1)
+ local u2 = unit.create(f, r2, 1)
+
+ u2.magic = 'gwyrrd'
+ u2:set_skill('magic', 100)
+ u2.aura = 200
+ u2:add_spell('holyground')
+ u2:add_order('ZAUBERE STUFE 10 "Heiliger Boden"')
+
+ u1.race = "skeleton"
+ u1:add_order("NACH Osten")
+ process_orders()
+ assert_not_nil(r2:get_curse('holyground'))
+ assert_equal(r1, u1.region)
+end
+
function test_shapeshift()
local r = region.create(42, 0, "plain")
local f = faction.create("demon", "noreply@eressea.de", "de")
@@ -204,7 +228,6 @@ function test_bug_2517()
local uf = nil
eressea.settings.set("magic.familiar.race", "lynx")
f.magic = 'gwyrrd'
- um.name = 'Xolgrim'
um.magic = 'gwyrrd'
um.race = 'elf'
um:set_skill('magic', 10)
diff --git a/scripts/tests/e2/stealth.lua b/scripts/tests/e2/stealth.lua
index 7f531776c..6a8fcd9f9 100644
--- a/scripts/tests/e2/stealth.lua
+++ b/scripts/tests/e2/stealth.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module('tests.e2.stealth', package.seeall, lunit.testcase)
+local tcname = 'tests.e2.stealth'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
local f
local u
diff --git a/scripts/tests/e2/trees.lua b/scripts/tests/e2/trees.lua
new file mode 100644
index 000000000..b5bfa1f6b
--- /dev/null
+++ b/scripts/tests/e2/trees.lua
@@ -0,0 +1,144 @@
+local tcname = 'tests.e2.trees'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
+
+function setup()
+ eressea.game.reset()
+ eressea.settings.set("rules.food.flags", "4") -- food is free
+ eressea.settings.set("rules.treeseeds.chance", "0.0") -- trees make no seeds
+ eressea.settings.set("rules.grow.formula", "0") -- no tree or seed growth
+ eressea.settings.set("NewbieImmunity", "0")
+end
+
+function test_no_growth()
+ eressea.settings.set("rules.grow.formula", "2") -- E2 growth rules
+ set_turn(204)
+ assert_equal('spring', get_season())
+ local r = region.create(0, 0, 'plain')
+ r:set_flag(1, false) -- no mallorn
+ r:set_resource('seed', 0)
+ r:set_resource('sapling', 0)
+ r:set_resource('tree', 0)
+ process_orders()
+ assert_equal(0, r:get_resource('seed'))
+ assert_equal(0, r:get_resource('sapling'))
+ assert_equal(0, r:get_resource('tree'))
+end
+
+function test_spring_growth()
+ eressea.settings.set("rules.grow.formula", "2") -- E2 growth rules
+ set_turn(204)
+ assert_equal('spring', get_season())
+ local r = region.create(0, 0, 'plain')
+ r:set_flag(1, false) -- no mallorn
+ r:set_resource('seed', 6)
+ r:set_resource('sapling', 17)
+ r:set_resource('tree', 0)
+ process_orders()
+ assert_equal(5, r:get_resource('seed'))
+ assert_equal(16, r:get_resource('sapling'))
+ assert_equal(2, r:get_resource('tree'))
+end
+
+-- hebalism < T6 cannot plant
+function test_plant_fail()
+ set_turn(184)
+ assert_equal('summer', get_season())
+ local f = faction.create('goblin')
+ local r = region.create(0, 0, 'plain')
+ r:set_flag(1, false) -- no mallorn
+ r:set_resource('seed', 0)
+ r:set_resource('sapling', 0)
+ r:set_resource('tree', 0)
+ local u = unit.create(f, r)
+ u:set_skill('herbalism', 5)
+ u:add_item('seed', 40)
+ u:add_order("PFLANZE 20 Samen")
+ process_orders()
+ assert_equal(0, r:get_resource('seed'))
+ assert_equal(0, r:get_resource('sapling'))
+ assert_equal(0, r:get_resource('tree'))
+ assert_equal(40, u:get_item('seed'))
+end
+
+-- T6+ herbalism allows planting seeds at 1:1 rates
+function test_plant_summer()
+ set_turn(184)
+ assert_equal('summer', get_season())
+ local f = faction.create('goblin')
+ local r = region.create(0, 0, 'plain')
+ r:set_flag(1, false) -- no mallorn
+ r:set_resource('seed', 0)
+ r:set_resource('sapling', 0)
+ r:set_resource('tree', 0)
+ local u = unit.create(f, r)
+ u:set_skill('herbalism', 20)
+ u:add_item('seed', 40)
+ u:add_order("PFLANZE 20 Samen")
+ process_orders()
+ assert_equal(20, r:get_resource('seed'))
+ assert_equal(0, r:get_resource('sapling'))
+ assert_equal(0, r:get_resource('tree'))
+ assert_equal(20, u:get_item('seed'))
+end
+
+-- in spring, herbalism >= T12 plants saplings at 10:1 rate
+function test_plant_spring_saplings()
+ set_turn(203)
+ assert_equal('spring', get_season())
+ local f = faction.create('goblin')
+ local r = region.create(0, 0, 'plain')
+ local u = unit.create(f, r)
+ r:set_flag(1, false) -- no mallorn
+ r:set_resource('seed', 0)
+ r:set_resource('sapling', 0)
+ r:set_resource('tree', 0)
+
+ assert_equal('spring', get_season())
+ process_orders() -- to initialize at_germs
+ assert_equal(0, r:get_resource('sapling'))
+ assert_equal(0, r:get_resource('seed'))
+ assert_equal(0, r:get_resource('tree'))
+
+ assert_equal('spring', get_season())
+ u:set_skill('herbalism', 12)
+ u:add_item('seed', 20)
+ u:add_order("PFLANZE 20 Samen") -- limited by herbalism
+ process_orders()
+ assert_equal(1, r:get_resource('sapling'))
+ assert_equal(2, r:get_resource('seed'))
+ assert_equal(0, r:get_resource('tree'))
+ assert_equal(8, u:get_item('seed'))
+end
+
+-- herbalism < T12 means we are still planting seeds at 1:1
+function test_plant_spring_seeds()
+ set_turn(204)
+ local f = faction.create('goblin')
+ local r = region.create(0, 0, 'plain')
+ local u = unit.create(f, r)
+ r:set_flag(1, false) -- no mallorn
+ r:set_resource('seed', 0)
+ r:set_resource('sapling', 0)
+ r:set_resource('tree', 0)
+
+ assert_equal('spring', get_season())
+ process_orders() -- to initialize at_germs
+ assert_equal(0, r:get_resource('sapling'))
+ assert_equal(0, r:get_resource('seed'))
+ assert_equal(0, r:get_resource('tree'))
+
+ assert_equal('spring', get_season())
+ u:set_skill('herbalism', 10)
+ u:add_item('seed', 40)
+ u:add_order("PFLANZE 10 Samen")
+ process_orders()
+ assert_equal(0, r:get_resource('sapling'))
+ assert_equal(10, r:get_resource('seed'))
+ assert_equal(0, r:get_resource('tree'))
+ assert_equal(30, u:get_item('seed'))
+end
diff --git a/scripts/tests/e2/trolls.lua b/scripts/tests/e2/trolls.lua
new file mode 100644
index 000000000..cc60ade2d
--- /dev/null
+++ b/scripts/tests/e2/trolls.lua
@@ -0,0 +1,54 @@
+local tcname = 'tests.e2.trolls'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
+
+function setup()
+ eressea.free_game()
+end
+
+function test_trolls_with_horses()
+ local r0 = region.create(0, 0, 'plain')
+ local r1 = region.create(1, 0, 'plain')
+ local r2 = region.create(2, 0, 'plain')
+ local r3 = region.create(3, 0, 'plain')
+ local r4 = region.create(4, 0, 'plain')
+ local r5 = region.create(5, 0, 'plain')
+
+ local f = faction.create('troll')
+ -- 1. 20 trolls can pull 5 loaded carts:
+ assert_not_nil(r0)
+ local u1 = unit.create(f, r0, 20)
+ u1:add_item('cart', 5)
+ -- trolls carry 10.8 GE, carts carry 100 GE:
+ u1:add_item('money', 100 * (5 * 100 + 2 * 108))
+ u1:add_order('NACH O O O')
+
+ process_orders()
+ assert_equal(r1, u1.region)
+
+ -- 20 trolls can also lead 20 horses
+ u1:add_item('horse', 20)
+ u1:add_item('money', 100 * 20 * 20)
+
+ process_orders()
+ assert_equal(r2, u1.region)
+
+ -- test if trolls are still "lazy". If yes they should still manage 10 full carts behind the 20 horses (5 more)
+ u1:add_item('cart', 5)
+ u1:add_item('money', 100 * 5 * 100)
+
+ process_orders()
+ assert_equal(r3, u1.region)
+
+ -- test if trolls are still "lazy". If not they should manage 15 full carts, 5 behind trolls and 10 behind 20 horses (again 5 more)
+ u1:add_item('cart', 5)
+ u1:add_item('money', 100 * 5 * 100)
+
+ process_orders()
+ assert_equal(r4, u1.region)
+
+end
diff --git a/scripts/tests/e2/undead.lua b/scripts/tests/e2/undead.lua
index f7586ee4b..5b8170ef6 100644
--- a/scripts/tests/e2/undead.lua
+++ b/scripts/tests/e2/undead.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e2.undead", package.seeall, lunit.testcase)
+local tcname = 'tests.e2.undead'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
@@ -28,7 +32,6 @@ function test_undead_reserve_other()
u1.race = "undead"
u1:clear_orders()
u1:add_order("RESERVIERE 1 Holz")
- u1.name = 'Xolgrim'
process_orders()
if 0 ~= u1:get_item("log") then
diff --git a/scripts/tests/e3/buildings.lua b/scripts/tests/e3/buildings.lua
index d5ea4fa51..1258f9824 100644
--- a/scripts/tests/e3/buildings.lua
+++ b/scripts/tests/e3/buildings.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e3.buildings", package.seeall, lunit.testcase )
+local tcname = 'tests.e3.buildings'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.game.reset()
diff --git a/scripts/tests/e3/init.lua b/scripts/tests/e3/init.lua
index 04b7da4a2..2ccd19139 100644
--- a/scripts/tests/e3/init.lua
+++ b/scripts/tests/e3/init.lua
@@ -10,6 +10,8 @@ require 'tests.spells'
require 'tests.economy'
require 'tests.orders'
require 'tests.common'
+require 'tests.recruit'
+require 'tests.parser'
require 'tests.items'
require 'tests.magicbag'
require 'tests.process'
diff --git a/scripts/tests/e3/items.lua b/scripts/tests/e3/items.lua
index 1df6be85a..60fce6b7a 100644
--- a/scripts/tests/e3/items.lua
+++ b/scripts/tests/e3/items.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e3.items", package.seeall, lunit.testcase )
+local tcname = 'tests.e3.items'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.game.reset()
diff --git a/scripts/tests/e3/morale.lua b/scripts/tests/e3/morale.lua
index 1dd92a758..60ed55965 100644
--- a/scripts/tests/e3/morale.lua
+++ b/scripts/tests/e3/morale.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e3.morale", package.seeall, lunit.testcase )
+local tcname = 'tests.e3.morale'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.game.reset()
@@ -171,7 +175,7 @@ function test_morale_change()
run_a_turn()
assert_equal(4, r.morale)
- -- regel: ohne herrscher fällt die moral jede woche um 1 punkt, bis sie 1 erreicht
+ -- regel: ohne herrscher fällt die moral jede woche um 1 punkt, bis sie 1 erreicht
assert_false(r.is_mourning)
u1.building = nil
update_owners()
@@ -186,7 +190,7 @@ function test_morale_change()
run_a_turn()
assert_equal(1, r.morale)
- -- ohne herrscher ändert sich auch beschissene Moral nicht:
+ -- ohne herrscher ändert sich auch beschissene Moral nicht:
r.morale = 0
run_a_turn()
assert_equal(0, r.morale)
diff --git a/scripts/tests/e3/parser.lua b/scripts/tests/e3/parser.lua
index a56f08f76..862f9d946 100644
--- a/scripts/tests/e3/parser.lua
+++ b/scripts/tests/e3/parser.lua
@@ -1,6 +1,10 @@
-require 'lunit'
-
-module('tests.e3.parser', package.seeall, lunit.testcase)
+local tcname = 'tests.e3.parser'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.game.reset()
diff --git a/scripts/tests/e3/production.lua b/scripts/tests/e3/production.lua
index 3469b06c4..9a631c755 100644
--- a/scripts/tests/e3/production.lua
+++ b/scripts/tests/e3/production.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e3.production", package.seeall, lunit.testcase )
+local tcname = 'tests.e3.production'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.game.reset()
diff --git a/scripts/tests/e3/rules.lua b/scripts/tests/e3/rules.lua
index aae3b3ab1..89a6d822a 100644
--- a/scripts/tests/e3/rules.lua
+++ b/scripts/tests/e3/rules.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e3.e3features", package.seeall, lunit.testcase)
+local tcname = 'tests.e3.rules'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
local settings
diff --git a/scripts/tests/e3/spells-e2.lua b/scripts/tests/e3/spells-e2.lua
index f232b8a1a..0e2ab4e6d 100644
--- a/scripts/tests/e3/spells-e2.lua
+++ b/scripts/tests/e3/spells-e2.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e3.spells-e2", package.seeall, lunit.testcase)
+local tcname = 'tests.e3.e2spells'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
local r, f, u
diff --git a/scripts/tests/e3/spells.lua b/scripts/tests/e3/spells.lua
index 24f97c221..fb68ba3d1 100644
--- a/scripts/tests/e3/spells.lua
+++ b/scripts/tests/e3/spells.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e3.spells", package.seeall, lunit.testcase)
+local tcname = 'tests.e3.spells'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.game.reset()
diff --git a/scripts/tests/e3/stealth.lua b/scripts/tests/e3/stealth.lua
index 866eb4f14..1db6436a1 100644
--- a/scripts/tests/e3/stealth.lua
+++ b/scripts/tests/e3/stealth.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.e3.stealth", package.seeall, lunit.testcase)
+local tcname = 'tests.e3.stealth'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
local f
local u
diff --git a/scripts/tests/economy.lua b/scripts/tests/economy.lua
index 0c140e418..271d245d6 100644
--- a/scripts/tests/economy.lua
+++ b/scripts/tests/economy.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.economy", package.seeall, lunit.testcase)
+local tcname = 'tests.shared.economy'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/faction.lua b/scripts/tests/faction.lua
index c264f4596..fe728e9a0 100644
--- a/scripts/tests/faction.lua
+++ b/scripts/tests/faction.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module ('tests.eressea.faction', package.seeall, lunit.testcase)
+local tcname = 'tests.faction'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
local f
diff --git a/scripts/tests/hunger.lua b/scripts/tests/hunger.lua
index a33c2208b..750d7c74b 100644
--- a/scripts/tests/hunger.lua
+++ b/scripts/tests/hunger.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.hunger", package.seeall, lunit.testcase)
+local tcname = 'tests.hunger'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/items.lua b/scripts/tests/items.lua
index f4d8657c6..c6252db17 100644
--- a/scripts/tests/items.lua
+++ b/scripts/tests/items.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.items", package.seeall, lunit.testcase )
+local tcname = 'tests.shared.items'
+local lunit = require("lunit")
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/laws.lua b/scripts/tests/laws.lua
index 6dc37daf7..d9a379319 100644
--- a/scripts/tests/laws.lua
+++ b/scripts/tests/laws.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.laws", package.seeall, lunit.testcase)
+local tcname = 'tests.laws'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
@@ -115,3 +119,4 @@ function test_force_leave_postcombat()
assert_equal(nil, u3.building)
assert_equal(1, u3.number)
end
+
diff --git a/scripts/tests/locale.lua b/scripts/tests/locale.lua
index 2770beb3f..2b4dbea8c 100644
--- a/scripts/tests/locale.lua
+++ b/scripts/tests/locale.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.eressea.locale", package.seeall, lunit.testcase )
+local tcname = 'tests.locale'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/magicbag.lua b/scripts/tests/magicbag.lua
index b51925726..e34d5fba5 100644
--- a/scripts/tests/magicbag.lua
+++ b/scripts/tests/magicbag.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.magicbag", package.seeall, lunit.testcase)
+local tcname = 'tests.shared.magicbag'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
local u
diff --git a/scripts/tests/movement.lua b/scripts/tests/movement.lua
index 22bd8d30e..16868dfec 100644
--- a/scripts/tests/movement.lua
+++ b/scripts/tests/movement.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.movement", package.seeall, lunit.testcase)
+local tcname = 'tests.movement'
+local lunit = require("lunit")
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname , 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/orders.lua b/scripts/tests/orders.lua
index 6dc191d6c..d3ade71d2 100644
--- a/scripts/tests/orders.lua
+++ b/scripts/tests/orders.lua
@@ -1,12 +1,14 @@
-require "lunit"
+local tcname = 'tests.shared.orders'
+local lunit = require("lunit")
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname , 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
local _G = _G
-local eressea = eressea
local default_ship = config.ships[1]
local default_building = config.buildings[1]
-
-module('tests.eressea.orders', package.seeall, lunit.testcase)
-
local r, f, u
function setup()
diff --git a/scripts/tests/parser.lua b/scripts/tests/parser.lua
new file mode 100644
index 000000000..7cd42b17f
--- /dev/null
+++ b/scripts/tests/parser.lua
@@ -0,0 +1,270 @@
+local tcname = 'tests.shared.parser'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
+
+function setup()
+ eressea.free_game()
+ eressea.settings.set("rules.food.flags", "4") -- FOOD_IS_FREE
+ eressea.settings.set("rules.move.owner_leave", "0")
+end
+
+function test_parser()
+ local r = region.create(0, 0, "mountain")
+ local f = faction.create('human')
+ local u = unit.create(f, r, 1)
+ local filename = "orders.txt"
+
+ local file = io.open(filename, "w")
+ assert_not_nil(file)
+ f.password = 'Hodor'
+ file:write('ERESSEA ' .. itoa36(f.id) .. ' "Hodor"\n')
+ file:write('EINHEIT ' .. itoa36(u.id) .. "\n")
+ file:write("BENENNEN EINHEIT 'Goldene Herde'\n")
+ file:close()
+
+ eressea.read_orders(filename)
+ process_orders()
+ os.remove(filename)
+ assert_equal("Goldene Herde", u.name)
+end
+
+local function set_order(u, str)
+ u:clear_orders()
+ u:add_order(str)
+end
+
+function test_prefix()
+ local r0 = region.create(0, 0, "plain")
+ local f1 = faction.create('human')
+ local u1 = unit.create(f1, r0, 1)
+
+ set_order(u1, "PRAEFIX See")
+ process_orders()
+ assert_not_nil(u1:show():find("Seemensch"))
+
+ u1.race = "elf"
+ assert_not_nil(u1:show():find("Seeelf"))
+
+ set_order(u1, "PRAEFIX Mond")
+ process_orders()
+ assert_not_nil(u1:show():find("Mondelf"))
+
+ set_order(u1, "PRAEFIX")
+ process_orders()
+ assert_not_nil(u1:show():find("Elf"))
+
+ set_order(u1, "PRAEFIX Erz")
+ process_orders()
+ assert_not_nil(u1:show():find("Erzelf"))
+ u1.faction.locale = "en"
+ assert_not_nil(u1:show():find("archelf"))
+end
+
+function test_recruit()
+ local r = region.create(0, 0, "plain")
+ local f = faction.create('human')
+ local u = unit.create(f, r, 1)
+
+ u:add_item("money", 1000)
+ set_order(u, "REKRUTIERE 5")
+ process_orders()
+ for u in f.units do
+ assert_equal(6, u.number)
+ end
+end
+
+function test_give_horses()
+ local r = region.create(0, 0, "plain")
+ local f = faction.create("human", "noreply@eressea.de", "de")
+ local u = unit.create(f, r, 1)
+
+ r:set_resource("horse", 0)
+ u:add_item("horse", 21)
+ u:add_item("dolphin", 10)
+ u:add_order("GIB 0 7 PFERD")
+ u:add_order("GIB 0 5 DELPHIN")
+ process_orders()
+ assert_equal(7, r:get_resource("horse"))
+ assert_equal(5, u:get_item("dolphin"))
+ assert_equal(14, u:get_item("horse"))
+end
+
+function test_give_silver()
+ local r = region.create(0, 0, "plain")
+ local f = faction.create("human", "noreply@eressea.de", "de")
+ local u = unit.create(f, r, 1)
+
+ r:set_resource("peasant", 0)
+ r:set_resource("money", 11)
+ u:clear_orders()
+ u:add_item("money", 20)
+ u:add_order("GIB 0 10 SILBER")
+ process_orders()
+ assert_equal(21, r:get_resource("money"))
+ assert_equal(10, u:get_item("money"))
+end
+
+function test_give_horses()
+ local r = region.create(0, 0, "plain")
+ local f = faction.create('human')
+ local u = unit.create(f, r, 1)
+
+ r:set_resource("horse", 0)
+ u:add_item("horse", 21)
+ u:add_item("dolphin", 10)
+ u:add_order("GIB 0 7 PFERD")
+ u:add_order("GIB 0 5 DELPHIN")
+ process_orders()
+ assert_equal(7, r:get_resource("horse"))
+ assert_equal(5, u:get_item("dolphin"))
+ assert_equal(14, u:get_item("horse"))
+end
+
+function test_give_silver()
+ local r = region.create(0, 0, "plain")
+ local f = faction.create('human')
+ local u = unit.create(f, r, 1)
+
+ r:set_resource("peasant", 0)
+ r:set_resource("money", 11)
+ u:clear_orders()
+ u:add_item("money", 20)
+ u:add_order("GIB 0 10 SILBER")
+ process_orders()
+ assert_equal(21, r:get_resource("money"))
+ assert_equal(10, u:get_item("money"))
+end
+
+function test_build_castle_one_stage()
+ local r = region.create(0, 0, 'plain')
+ local f = faction.create('human')
+ local u = unit.create(f, r, 2)
+
+ u:add_item('stone', 4)
+
+ u:set_skill('building', 1)
+ u:add_order('MACHE BURG')
+
+ process_orders()
+ assert_equal(2, u.building.size)
+ assert_equal(2, u:get_item('stone'))
+end
+
+function test_build_castle()
+ local r = region.create(0, 0, "plain")
+ local f = faction.create('human')
+ local u = unit.create(f, r, 1)
+
+ u:add_item('stone', 1)
+ u:set_skill('building', 1)
+ u:add_order("MACHE BURG")
+ process_orders()
+ assert_not_nil(u.building)
+ assert_equal(1, u.building.size)
+ assert_equal(u.building.name, "Burg")
+end
+
+function test_route()
+ local r1 = region.create(0, 0, "plain")
+ local r2 = region.create(1, 0, "plain")
+ local f = faction.create("human", "route@example.com")
+ local u = unit.create(f, r1, 1)
+ u:add_order("ROUTE O W P")
+ process_orders()
+ assert_equal("ROUTE West PAUSE Ost", u:get_order(0))
+ assert_equal(r2, u.region)
+end
+
+function test_route_horse()
+ local r1 = region.create(0, 0, "plain")
+ local r2 = region.create(1, 0, "plain")
+ local f = faction.create("human", "route@example.com")
+ local u = unit.create(f, r1, 1)
+ u:add_order("ROUTE O P W P")
+ u:add_item('horse', 1)
+ u:set_skill('riding', 1)
+ process_orders()
+ assert_equal("ROUTE West PAUSE Ost PAUSE", u:get_order(0))
+ assert_equal(r2, u.region)
+end
+
+function test_route_pause()
+ local r1 = region.create(0, 0, "plain")
+ local r2 = region.create(1, 0, "plain")
+ local f = faction.create("human", "route@example.com")
+ local u = unit.create(f, r1, 1)
+ u:add_order("ROUTE P O W")
+ process_orders()
+ assert_equal("ROUTE P O W", u:get_order(0))
+ assert_equal(r1, u.region)
+end
+
+function test_immunity_stops_guard()
+ eressea.settings.set("NewbieImmunity", 2)
+ local f = faction.create('human')
+ local r = region.create(0, 0, 'plain')
+ local u = unit.create(f, r)
+ u:set_skill('polearm', 2)
+ u:add_item('lance', 1)
+ u:add_order('BEWACHE')
+ process_orders()
+ assert_equal(f.age, 1)
+ assert_true(not u.guard)
+ process_orders()
+ assert_equal(f.age, 2)
+ assert_true(u.guard)
+end
+
+function test_region_keys()
+ local r = region.create(0, 0, 'plain')
+ assert_nil(r:get_key('test'))
+ assert_nil(r:get_key('more'))
+ r:set_key('test', 42)
+ r:set_key('more') -- default is 1
+ assert_equal(42, r:get_key('test'))
+ assert_equal(1, r:get_key('more'))
+end
+
+function test_faction_keys()
+ local f = faction.create('human')
+ assert_nil(f:get_key('test'))
+ assert_nil(f:get_key('more'))
+ f:set_key('test', 42)
+ f:set_key('more') -- default is 1
+ assert_equal(42, f:get_key('test'))
+ assert_equal(1, f:get_key('more'))
+end
+
+function test_cartmaking()
+ local f = faction.create('human')
+ local r = region.create(0, 0, 'plain')
+ local u = unit.create(f, r)
+ u:set_skill('cartmaking', 1)
+ u:add_item('log', 10)
+ u:add_order('MACHE Wagen')
+ process_orders()
+ assert_equal(1, u:get_item('cart'))
+ assert_equal(5, u:get_item('log'))
+end
+
+function test_promote_after_recruit()
+ local f = faction.create('human')
+ local r1 = region.create(0, 0, 'plain')
+ local r2 = region.create(1, 0, 'plain')
+ local u1 = unit.create(f, r1, 1)
+ u1.name = 'Xolgrim'
+ local u2 = unit.create(f, r2, 55)
+ u2:add_order('REKRUTIERE 1')
+ u1:add_order('BEFOERDERE')
+ u1:add_item('money', 57)
+ u2:add_item('money', 150)
+ local fl = u1.flags
+ process_orders()
+ assert_equal(56, u2.number)
+ assert_equal(fl + 128, u1.flags) -- UFL_HERO
+ assert_equal(0, u1:get_item('money'))
+end
diff --git a/scripts/tests/pool.lua b/scripts/tests/pool.lua
index 0d24f8129..398ff6fa2 100644
--- a/scripts/tests/pool.lua
+++ b/scripts/tests/pool.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.eressea.pool", package.seeall, lunit.testcase )
+local tcname = 'tests.pool'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.game.reset()
diff --git a/scripts/tests/process.lua b/scripts/tests/process.lua
index 1fc9a64f5..b9fcf5055 100644
--- a/scripts/tests/process.lua
+++ b/scripts/tests/process.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.process", package.seeall, lunit.testcase)
+local tcname = 'tests.shared.process'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
local u, r, f
diff --git a/scripts/tests/production.lua b/scripts/tests/production.lua
index c8a299676..bea8fcf33 100644
--- a/scripts/tests/production.lua
+++ b/scripts/tests/production.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.production", package.seeall, lunit.testcase )
+local tcname = 'tests.shared.production'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.game.reset()
diff --git a/scripts/tests/recruit.lua b/scripts/tests/recruit.lua
new file mode 100644
index 000000000..6a0cc5de6
--- /dev/null
+++ b/scripts/tests/recruit.lua
@@ -0,0 +1,46 @@
+local tcname = 'tests.shared.recruit'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
+
+function setup()
+ eressea.free_game()
+ eressea.settings.set("rules.food.flags", "4")
+ eressea.settings.set("rules.peasants.growth", "0")
+end
+
+function test_bug_1795_limit()
+ local r = region.create(0, 0, "plain")
+ local f = faction.create('human')
+ local u1 = unit.create(f, r, 1)
+ u1:add_item("money", 100000000)
+ u1:add_order("REKRUTIEREN 9999")
+ r:set_resource("peasant", 2000) -- no fractional growth!
+ local peasants = r:get_resource("peasant")
+ local limit,frac = math.modf(peasants/40) -- one day this should be a parameter
+
+ process_orders()
+ assert_equal(limit+1, u1.number, u1.number .. "!=" .. (limit+1))
+ local np = r:get_resource("peasant")
+ assert_equal(peasants-limit, np)
+end
+
+function test_bug_1795_demons()
+ local r = region.create(0, 0, "plain")
+ local f = faction.create('demon')
+ local u1 = unit.create(f, r, 1)
+ r:set_resource("peasant", 2000)
+ local peasants = r:get_resource("peasant")
+ local limit,frac = math.modf(peasants/40)
+
+ u1:add_item("money", 100000000)
+ u1:add_order("REKRUTIEREN 9999")
+
+ process_orders()
+
+ assert_equal(limit+1, u1.number, u1.number .. "!=" .. (limit+1))
+ assert_equal(peasants, r:get_resource("peasant"))
+end
diff --git a/scripts/tests/regions.lua b/scripts/tests/regions.lua
index 32197f0fd..881930a40 100644
--- a/scripts/tests/regions.lua
+++ b/scripts/tests/regions.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.regions", package.seeall, lunit.testcase)
+local tcname = 'tests.regions'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.game.reset()
diff --git a/scripts/tests/report.lua b/scripts/tests/report.lua
index b02f4a908..466e77e1a 100644
--- a/scripts/tests/report.lua
+++ b/scripts/tests/report.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.report", package.seeall, lunit.testcase)
+local tcname = 'tests.shared.report'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/settings.lua b/scripts/tests/settings.lua
index 8f2c5e637..ec4cac2d1 100644
--- a/scripts/tests/settings.lua
+++ b/scripts/tests/settings.lua
@@ -1,6 +1,10 @@
-require 'lunit'
-
-module('tests.eressea.settings', package.seeall, lunit.testcase )
+local tcname = 'tests.settings'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/spells.lua b/scripts/tests/spells.lua
index 27a5424f7..b0def9560 100644
--- a/scripts/tests/spells.lua
+++ b/scripts/tests/spells.lua
@@ -1,5 +1,10 @@
-require 'lunit'
-module("tests.spells", package.seeall, lunit.testcase)
+local tcname = 'tests.shared.spells'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/storage.lua b/scripts/tests/storage.lua
index 32fbe9ef3..d51912694 100644
--- a/scripts/tests/storage.lua
+++ b/scripts/tests/storage.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.storage", package.seeall, lunit.testcase)
+local tcname = 'tests.shared.storage'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/study.lua b/scripts/tests/study.lua
index 32638ba90..51065b12a 100644
--- a/scripts/tests/study.lua
+++ b/scripts/tests/study.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.eressea.study", package.seeall, lunit.testcase)
+local tcname = 'tests.study'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
conf = [[{
diff --git a/scripts/tests/undead.lua b/scripts/tests/undead.lua
index a3c541afa..43d910c9f 100644
--- a/scripts/tests/undead.lua
+++ b/scripts/tests/undead.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.undead", package.seeall, lunit.testcase)
+local tcname = 'tests.shared.undead'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/scripts/tests/xmas.lua b/scripts/tests/xmas.lua
index 8ae85fc76..58400aa9f 100644
--- a/scripts/tests/xmas.lua
+++ b/scripts/tests/xmas.lua
@@ -1,6 +1,10 @@
-require "lunit"
-
-module("tests.xmas", package.seeall, lunit.testcase )
+local tcname = 'tests.shared.xmas'
+local lunit = require('lunit')
+if _VERSION >= 'Lua 5.2' then
+ _ENV = module(tcname, 'seeall')
+else
+ module(tcname, lunit.testcase, package.seeall)
+end
function setup()
eressea.free_game()
diff --git a/src/attributes/stealth.c b/src/attributes/stealth.c
index ae00e8721..4a9b6f044 100644
--- a/src/attributes/stealth.c
+++ b/src/attributes/stealth.c
@@ -37,8 +37,13 @@ int u_geteffstealth(const unit *u)
if (skill_enabled(SK_STEALTH)) {
if (u->flags & UFL_STEALTH) {
attrib *a = a_find(u->attribs, &at_stealth);
- if (a != NULL)
+ if (a != NULL) {
+ int eff = effskill(u, SK_STEALTH, u->region);
+ if (eff < a->data.i) {
+ return eff;
+ }
return a->data.i;
+ }
}
}
return -1;
diff --git a/src/attributes/stealth.test.c b/src/attributes/stealth.test.c
index 36c020e7d..77d3fd09c 100644
--- a/src/attributes/stealth.test.c
+++ b/src/attributes/stealth.test.c
@@ -20,7 +20,7 @@ static void test_stealth(CuTest *tc) {
CuAssertIntEquals(tc, -1, u_geteffstealth(u));
CuAssertIntEquals(tc, 2, eff_stealth(u, u->region));
u_seteffstealth(u, 3);
- CuAssertIntEquals(tc, 3, u_geteffstealth(u));
+ CuAssertIntEquals(tc, 2, u_geteffstealth(u));
CuAssertIntEquals(tc, 2, eff_stealth(u, u->region));
u_seteffstealth(u, 1);
CuAssertIntEquals(tc, 1, u_geteffstealth(u));
diff --git a/src/automate.c b/src/automate.c
index 2c9a94ad0..ecb130fff 100644
--- a/src/automate.c
+++ b/src/automate.c
@@ -20,7 +20,8 @@
static int cmp_scholars(const void *lhs, const void *rhs) {
const scholar *a = (const scholar *)lhs;
const scholar *b = (const scholar *)rhs;
- return b->level - a->level;
+ int diff = b->level - a->level;
+ return (diff != 0) ? diff : b->u->number - a->u->number;
}
int autostudy_init(scholar scholars[], int max_scholars, unit **units, skill_t *o_skill)
@@ -77,6 +78,7 @@ int autostudy_init(scholar scholars[], int max_scholars, unit **units, skill_t *
static void teaching(scholar *s, int n) {
assert(n <= s->u->number);
+ // doppelter Effekt mit Lehrer:
s->learn += n;
s->u->flags |= UFL_LONGACTION;
}
@@ -91,27 +93,31 @@ void autostudy_run(scholar scholars[], int nscholars)
{
int ti = 0;
while (ti != nscholars) {
- int t, se, ts = 0, tt = 0, si = ti;
- for (se = ti; se != nscholars; ++se) {
- int mint;
- ts += scholars[se].u->number; /* count total scholars */
+ int t, ts = 0, tt = 0, si = ti, mint = 0, ns = 0;
+ for (t = ti; t != nscholars; ++t) {
+ ts += scholars[t].u->number; /* count total scholars */
mint = (ts + 10) / 11; /* need a minimum of ceil(ts/11) teachers */
for (; mint > tt && si != nscholars; ++si) {
tt += scholars[si].u->number;
}
}
+ if (mint < tt) {
+ /* die Einheit si-1 hat einen Mix aus Lehrer und Schüler */
+ --si;
+ ns = tt - mint;
+ }
/* now si splits the teachers and students 1:10 */
/* first student must be 2 levels below first teacher: */
- for (; si != se; ++si) {
+ for (; si != nscholars; ++si) {
if (scholars[si].level + TEACHDIFFERENCE <= scholars[ti].level) {
break;
}
- tt += scholars[si].u->number;
+ ns = 0;
}
/* now si is the first unit we can teach, if we can teach any */
- if (si == se) {
+ if (si == nscholars) {
/* there are no students, so standard learning for everyone */
- for (t = ti; t != se; ++t) {
+ for (t = ti; t != nscholars; ++t) {
learning(scholars + t, scholars[t].u->number);
}
}
@@ -119,16 +125,17 @@ void autostudy_run(scholar scholars[], int nscholars)
/* invariant: unit ti can still teach i students */
int i = scholars[ti].u->number * STUDENTS_PER_TEACHER;
/* invariant: unit si has n students that can still be taught */
- int s, n = scholars[si].u->number;
- for (t = ti, s = si; t != si && s != se; ) {
+ int s, n = (ns > 0) ? ns : scholars[si].u->number;
+ for (t = ti, s = si; t != si && s != nscholars; ) {
if (i >= n) {
/* t has more than enough teaching capacity for s */
i -= n;
teaching(scholars + s, n);
learning(scholars + s, scholars[s].u->number);
/* next student, please: */
- if (++s == se) {
- continue;
+ if (++s == nscholars) {
+ /* no more students */
+ break;
}
n = scholars[s].u->number;
}
@@ -147,7 +154,7 @@ void autostudy_run(scholar scholars[], int nscholars)
do {
/* remaining students learn without a teacher: */
learning(scholars + s, n);
- if (++s == se) {
+ if (++s == nscholars) {
break;
}
n = scholars[s].u->number;
@@ -163,10 +170,15 @@ void autostudy_run(scholar scholars[], int nscholars)
}
++t;
for (; t < si; ++t) {
+ /* teachers that did not teach */
learning(scholars + t, scholars[t].u->number);
}
+ for (; s < nscholars; ++s) {
+ /* students that were not taught */
+ learning(scholars + s, scholars[s].u->number);
+ }
}
- ti = se;
+ ti = nscholars;
}
}
diff --git a/src/automate.test.c b/src/automate.test.c
index 5508cce88..1e38a7605 100644
--- a/src/automate.test.c
+++ b/src/automate.test.c
@@ -110,6 +110,111 @@ static void test_autostudy_run_twoteachers(CuTest *tc) {
test_teardown();
}
+/**
+ * Reproduce Bug 2640
+ */
+static void test_autostudy_run_bigunit(CuTest *tc) {
+ scholar scholars[4];
+ int nscholars;
+ unit *u1, *u2, *ulist;
+ faction *f;
+ region *r;
+ skill_t skill;
+
+ test_setup();
+ r = test_create_plain(0, 0);
+ f = test_create_faction(NULL);
+ u1 = test_create_unit(f, r);
+ set_number(u1, 20);
+ set_level(u1, SK_ENTERTAINMENT, 16);
+ u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
+ u2 = test_create_unit(f, r);
+ set_number(u2, 1000);
+ set_level(u2, SK_ENTERTAINMENT, 10);
+ u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
+
+ ulist = r->units;
+ CuAssertIntEquals(tc, 2, nscholars = autostudy_init(scholars, 4, &ulist, &skill));
+ CuAssertPtrEquals(tc, NULL, ulist);
+ autostudy_run(scholars, nscholars);
+ CuAssertIntEquals(tc, SK_ENTERTAINMENT, skill);
+ CuAssertIntEquals(tc, 0, scholars[0].learn);
+ CuAssertIntEquals(tc, 1200, scholars[1].learn);
+
+ test_teardown();
+}
+
+static void test_autostudy_run_few_teachers(CuTest *tc) {
+ scholar scholars[4];
+ int nscholars;
+ unit *u1, *u2, *u3, *ulist;
+ faction *f;
+ region *r;
+ skill_t skill;
+
+ test_setup();
+ r = test_create_plain(0, 0);
+ f = test_create_faction(NULL);
+ u1 = test_create_unit(f, r);
+ set_number(u1, 20);
+ set_level(u1, SK_ENTERTAINMENT, 16);
+ u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
+ u2 = test_create_unit(f, r);
+ set_number(u2, 500);
+ set_level(u2, SK_ENTERTAINMENT, 10);
+ u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
+ u3 = test_create_unit(f, r);
+ set_number(u3, 100);
+ set_level(u3, SK_ENTERTAINMENT, 9);
+ u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
+
+ ulist = r->units;
+ CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist, &skill));
+ CuAssertPtrEquals(tc, NULL, ulist);
+ autostudy_run(scholars, nscholars);
+ CuAssertIntEquals(tc, SK_ENTERTAINMENT, skill);
+ CuAssertIntEquals(tc, 0, scholars[0].learn);
+ CuAssertIntEquals(tc, 700, scholars[1].learn);
+ CuAssertIntEquals(tc, 100, scholars[2].learn);
+
+ test_teardown();
+}
+
+static void test_autostudy_run_few_teachers_reverse(CuTest *tc) {
+ scholar scholars[4];
+ int nscholars;
+ unit *u1, *u2, *u3, *ulist;
+ faction *f;
+ region *r;
+ skill_t skill;
+
+ test_setup();
+ r = test_create_plain(0, 0);
+ f = test_create_faction(NULL);
+ u1 = test_create_unit(f, r);
+ set_number(u1, 20);
+ set_level(u1, SK_ENTERTAINMENT, 16);
+ u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
+ u2 = test_create_unit(f, r);
+ set_number(u2, 100);
+ set_level(u2, SK_ENTERTAINMENT, 10);
+ u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
+ u3 = test_create_unit(f, r);
+ set_number(u3, 500);
+ set_level(u3, SK_ENTERTAINMENT, 9);
+ u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
+
+ ulist = r->units;
+ CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist, &skill));
+ CuAssertPtrEquals(tc, NULL, ulist);
+ autostudy_run(scholars, nscholars);
+ CuAssertIntEquals(tc, SK_ENTERTAINMENT, skill);
+ CuAssertIntEquals(tc, 0, scholars[0].learn);
+ CuAssertIntEquals(tc, 800, scholars[1].learn + scholars[2].learn);
+
+ test_teardown();
+}
+
static void test_autostudy_run(CuTest *tc) {
scholar scholars[4];
int nscholars;
@@ -325,6 +430,9 @@ CuSuite *get_automate_suite(void)
SUITE_ADD_TEST(suite, test_autostudy_run_noteachers);
SUITE_ADD_TEST(suite, test_autostudy_run_teachers_learn);
SUITE_ADD_TEST(suite, test_autostudy_run_twoteachers);
+ SUITE_ADD_TEST(suite, test_autostudy_run_bigunit);
+ SUITE_ADD_TEST(suite, test_autostudy_run_few_teachers);
+ SUITE_ADD_TEST(suite, test_autostudy_run_few_teachers_reverse);
SUITE_ADD_TEST(suite, test_autostudy_run_skilldiff);
return suite;
}
diff --git a/src/battle.c b/src/battle.c
index 08d268224..8c1627d97 100644
--- a/src/battle.c
+++ b/src/battle.c
@@ -2933,7 +2933,7 @@ static void print_stats(battle * b)
header = LOC(f->locale, "battle_helpers");
for (s2 = b->sides; s2 != b->sides + b->nsides; ++s2) {
- if (friendly(s2, s)) {
+ if (s2 != s && friendly(s2, s)) {
const char *abbrev = seematrix(f, s2) ? sideabkz(s2, false) : "-?-";
rsize = slprintf(bufp, size, "%s %s %d(%s)",
komma++ ? "," : (const char *)header, loc_army, army_index(s2),
diff --git a/src/bind_monsters.c b/src/bind_monsters.c
index f9aef4a2a..2acacfaa3 100644
--- a/src/bind_monsters.c
+++ b/src/bind_monsters.c
@@ -28,9 +28,6 @@ static int tolua_levitate_ship(lua_State * L)
return 1;
}
-extern void spawn_undead(void);
-extern void plan_monsters(struct faction *f);
-
static int tolua_planmonsters(lua_State * L)
{
faction *f = (faction *)tolua_tousertype(L, 1, get_monsters());
diff --git a/src/bind_tolua.c b/src/bind_tolua.c
index d681b9088..3812e7689 100644
--- a/src/bind_tolua.c
+++ b/src/bind_tolua.c
@@ -14,7 +14,8 @@
#include
-void tolua_bind_open(lua_State * L) {
+void tolua_bind_open(lua_State * L)
+{
tolua_eressea_open(L);
tolua_process_open(L);
tolua_settings_open(L);
diff --git a/src/bindings.c b/src/bindings.c
index 5cb758175..6d2481a29 100755
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -3,6 +3,7 @@
#endif
#include "bindings.h"
+#include "bind_tolua.h"
#include "console.h"
#include "gamedb.h"
@@ -259,7 +260,7 @@ static int tolua_dice_rand(lua_State * L)
static int tolua_get_season(lua_State * L)
{
- int turn_no = (int)tolua_tonumber(L, 1, 0);
+ int turn_no = (int)tolua_tonumber(L, 1, turn);
season_t season = calendar_season(turn_no);
tolua_pushstring(L, seasonnames[season]);
return 1;
@@ -865,8 +866,6 @@ static int lua_rng_default(lua_State *L) {
return 0;
}
-void tolua_bind_open(lua_State * L);
-
int tolua_bindings_open(lua_State * L, const dictionary *inifile)
{
tolua_open(L);
diff --git a/src/bindings.h b/src/bindings.h
index 144f65ca6..f0259bc6e 100755
--- a/src/bindings.h
+++ b/src/bindings.h
@@ -12,6 +12,8 @@ extern "C" {
int tolua_selist_push(struct lua_State *L, const char *list_type,
const char *elem_type, struct selist *list);
+ void bind_monsters(struct lua_State *L);
+
int log_lua_error(struct lua_State *L);
void lua_done(struct lua_State *L);
diff --git a/src/chaos.c b/src/chaos.c
index fed9a5f49..69b9fa95d 100644
--- a/src/chaos.c
+++ b/src/chaos.c
@@ -76,7 +76,7 @@ static unit *random_unit(const region * r)
return u;
}
-static void chaos(region * r)
+static void chaos(region * r, faction *monsters)
{
if (rng_int() % 100 < 8) {
switch (rng_int() % 3) {
@@ -84,10 +84,10 @@ static void chaos(region * r)
if (!(r->terrain->flags & SEA_REGION)) {
unit *u = random_unit(r);
if (u && !undeadrace(u_race(u))) {
- ADDMSG(&u->faction->msgs, msg_message("chaos_disease", "unit", u));
- u_setfaction(u, get_monsters());
- u_freeorders(u);
- u_setrace(u, get_race(RC_GHOUL));
+ if (join_monsters(u, monsters)) {
+ ADDMSG(&u->faction->msgs, msg_message("chaos_disease", "unit", u));
+ u_setrace(u, get_race(RC_GHOUL));
+ }
}
}
break;
@@ -99,17 +99,17 @@ static void chaos(region * r)
case 0:
mfac = 100;
u =
- create_unit(r, get_monsters(), rng_int() % 8 + 1,
+ create_unit(r, monsters, rng_int() % 8 + 1,
get_race(RC_FIREDRAGON), 0, NULL, NULL);
break;
case 1:
mfac = 500;
- u = create_unit(r, get_monsters(), rng_int() % 4 + 1,
+ u = create_unit(r, monsters, rng_int() % 4 + 1,
get_race(RC_DRAGON), 0, NULL, NULL);
break;
default:
mfac = 1000;
- u = create_unit(r, get_monsters(), rng_int() % 2 + 1,
+ u = create_unit(r, monsters, rng_int() % 2 + 1,
get_race(RC_WYRM), 0, NULL, NULL);
break;
}
@@ -184,7 +184,7 @@ void chaos_update(void) {
/* Chaos */
for (r = regions; r; r = r->next) {
if ((r->flags & RF_CHAOTIC)) {
- chaos(r);
+ chaos(r, get_monsters());
}
}
}
diff --git a/src/creport.c b/src/creport.c
index d6383168d..0e88972f7 100644
--- a/src/creport.c
+++ b/src/creport.c
@@ -84,7 +84,7 @@ static char g_bigbuf[BUFFERSIZE];
bool opt_cr_absolute_coords = false;
/* globals */
-#define C_REPORT_VERSION 67
+#define C_REPORT_VERSION 68
struct locale *crtag_locale(void) {
static struct locale * lang;
@@ -495,38 +495,6 @@ static int cr_curse(variant var, char *buffer, const void *userdata)
/*static int msgno; */
-#define MTMAXHASH 1021
-
-static struct known_mtype {
- const struct message_type *mtype;
- struct known_mtype *nexthash;
-} *mtypehash[MTMAXHASH];
-
-static void report_crtypes(FILE * F, const struct locale *lang)
-{
- int i;
- for (i = 0; i != MTMAXHASH; ++i) {
- struct known_mtype *kmt;
- for (kmt = mtypehash[i]; kmt; kmt = kmt->nexthash) {
- char buffer[DISPLAYSIZE];
- int hash = (int)kmt->mtype->key;
- assert(hash > 0);
- fprintf(F, "MESSAGETYPE %d\n", hash);
- fputc('\"', F);
- fputs(crescape(nrt_string(kmt->mtype, lang), buffer, sizeof(buffer)), F);
- fputs("\";text\n", F);
- if (kmt->mtype->section) {
- fprintf(F, "\"%s\";section\n", kmt->mtype->section);
- }
- }
- while (mtypehash[i]) {
- kmt = mtypehash[i];
- mtypehash[i] = mtypehash[i]->nexthash;
- free(kmt);
- }
- }
-}
-
static int message_id(const struct message *msg)
{
variant var;
@@ -594,19 +562,6 @@ static void render_messages(FILE * F, faction * f, message_list * msgs)
else {
log_error("could not render cr-message %p: %s\n", m->msg, m->msg->type->name);
}
- if (printed) {
- unsigned int ihash = hash % MTMAXHASH;
- struct known_mtype *kmt = mtypehash[ihash];
- while (kmt && kmt->mtype != mtype)
- kmt = kmt->nexthash;
- if (kmt == NULL) {
- kmt = (struct known_mtype *)malloc(sizeof(struct known_mtype));
- if (!kmt) abort();
- kmt->nexthash = mtypehash[ihash];
- kmt->mtype = mtype;
- mtypehash[ihash] = kmt;
- }
- }
m = m->next;
}
}
@@ -1714,7 +1669,6 @@ report_computer(const char *filename, report_context * ctx, const char *bom)
cr_output_region(F, ctx, r);
}
}
- report_crtypes(F, f->locale);
if (f->locale != crtag_locale()) {
report_translations(F);
}
diff --git a/src/economy.c b/src/economy.c
index 0f7660308..4d2c30d90 100644
--- a/src/economy.c
+++ b/src/economy.c
@@ -290,10 +290,10 @@ static int forget_cmd(unit * u, order * ord)
else {
unit *ufam = get_familiar(u);
if (ufam) {
- a_removeall(&ufam->attribs, NULL);
- u_setfaction(ufam, get_monsters());
- u_freeorders(ufam);
- unit_convert_race(ufam, NULL, "ghost");
+ if (join_monsters(ufam, NULL)) {
+ a_removeall(&ufam->attribs, NULL);
+ unit_convert_race(ufam, NULL, "ghost");
+ }
}
a_removeall(&u->attribs, &at_mage);
a_removeall(&u->attribs, &at_familiar);
@@ -1680,84 +1680,41 @@ static void plant(unit * u, int raw)
u, r, planted, itype->rtype));
}
-static void planttrees(unit * u, int raw)
+static void planttrees(region * r, int type, int n)
{
- int n, i, skill, planted = 0;
- const resource_type *rtype;
- region * r = u->region;
-
- if (!fval(r->terrain, LAND_REGION)) {
- return;
+ if (n > 0) {
+ rsettrees(r, type, rtrees(r, type) + n);
}
-
- /* Mallornbaeume kann man nur in Mallornregionen zuechten */
- rtype = get_resourcetype(fval(r, RF_MALLORN) ? R_MALLORN_SEED : R_SEED);
-
- /* Skill pruefen */
- skill = effskill(u, SK_HERBALISM, NULL);
- if (skill < 6) {
- ADDMSG(&u->faction->msgs,
- msg_feedback(u, u->thisorder, "plant_skills",
- "skill minskill product", SK_HERBALISM, 6, rtype, 1));
- return;
- }
- if (fval(r, RF_MALLORN) && skill < 7) {
- ADDMSG(&u->faction->msgs,
- msg_feedback(u, u->thisorder, "plant_skills",
- "skill minskill product", SK_HERBALISM, 7, rtype, 1));
- return;
- }
-
- /* wenn eine Anzahl angegeben wurde, nur soviel verbrauchen */
- if (raw > skill * u->number) raw = skill * u->number;
- n = get_pooled(u, rtype, GET_DEFAULT, raw);
- if (n == 0) {
- ADDMSG(&u->faction->msgs,
- msg_feedback(u, u->thisorder, "resource_missing", "missing", rtype));
- return;
- }
- if (n > raw) n = raw;
-
- /* Fuer jeden Samen Talent*10% Erfolgschance. */
- for (i = n; i > 0; i--) {
- if (rng_int() % 10 < skill)
- planted++;
- }
- rsettrees(r, 0, rtrees(r, 0) + planted);
-
- /* Alles ok. Abziehen. */
- produceexp(u, SK_HERBALISM, u->number);
- use_pooled(u, rtype, GET_DEFAULT, n);
-
- ADDMSG(&u->faction->msgs, msg_message("plant",
- "unit region amount herb", u, r, planted, rtype));
}
/* zuechte baeume */
static void breedtrees(unit * u, int raw)
{
- int n, i, skill, planted = 0;
+ int n, i, skill;
const resource_type *rtype;
season_t current_season = calendar_season(turn);
region *r = u->region;
-
- /* Baeume zuechten geht nur im Fruehling */
- if (current_season != SEASON_SPRING) {
- planttrees(u, raw);
- return;
- }
+ int minskill = 6;
if (!fval(r->terrain, LAND_REGION)) {
return;
}
/* Mallornbaeume kann man nur in Mallornregionen zuechten */
- rtype = get_resourcetype(fval(r, RF_MALLORN) ? R_MALLORN_SEED : R_SEED);
+ if (fval(r, RF_MALLORN)) {
+ ++minskill;
+ rtype = get_resourcetype(R_MALLORN_SEED);
+ }
+ else {
+ rtype = get_resourcetype(R_SEED);
+ }
/* Skill pruefen */
skill = effskill(u, SK_HERBALISM, NULL);
- if (skill < 12) {
- planttrees(u, raw);
+ if (skill < minskill) {
+ ADDMSG(&u->faction->msgs,
+ msg_feedback(u, u->thisorder, "plant_skills",
+ "skill minskill product", SK_HERBALISM, 6, rtype, 1));
return;
}
@@ -1773,19 +1730,21 @@ static void breedtrees(unit * u, int raw)
}
if (n > raw) n = raw;
- /* Fuer jeden Samen Talent*5% Erfolgschance. */
- for (i = n; i > 0; i--) {
- if (rng_int() % 100 < skill * 5)
- planted++;
+ if (skill >= 12 && current_season == SEASON_SPRING) {
+ // Plant saplings for every 10 seeds
+ planttrees(r, 0, n % 10);
+ planttrees(r, 1, n / 10);
+ }
+ else {
+ planttrees(r, 0, n);
}
- rsettrees(r, 1, rtrees(r, 1) + planted);
- /* Alles ok. Abziehen. */
+ /* Alles ok. Samen abziehen. */
produceexp(u, SK_HERBALISM, u->number);
use_pooled(u, rtype, GET_DEFAULT, n);
ADDMSG(&u->faction->msgs, msg_message("plant",
- "unit region amount herb", u, r, planted, rtype));
+ "unit region amount herb", u, r, n, rtype));
}
/* zuechte pferde */
diff --git a/src/give.c b/src/give.c
index 8f8e72230..e1a3cec66 100644
--- a/src/give.c
+++ b/src/give.c
@@ -371,7 +371,7 @@ message * give_ship(unit *u1, unit *u2, int n, order *ord)
u2->ship->coast = u1->ship->coast;
}
else {
- return msg_error(u1, ord, 182);
+ return msg_error(u1, ord, 328);
}
}
}
@@ -799,6 +799,9 @@ static void give_all_items(unit *u, unit *u2, order *ord) {
}
}
}
+ else {
+ cmistake(u, ord, 123, MSG_COMMERCE);
+ }
}
}
}
diff --git a/src/gmtool.c b/src/gmtool.c
index d876b22bd..394f1efde 100644
--- a/src/gmtool.c
+++ b/src/gmtool.c
@@ -47,7 +47,7 @@
static int g_quit;
int force_color = 0;
-newfaction * new_players = 0;
+newfaction * new_players = NULL;
state *current_state = NULL;
diff --git a/src/kernel/building.c b/src/kernel/building.c
index aba7953a0..a6167f880 100644
--- a/src/kernel/building.c
+++ b/src/kernel/building.c
@@ -746,10 +746,6 @@ default_wage(const region * r, const faction * f, const race * rc, int in_turn)
variant vm;
/* Godcurse: Income -10 */
- c = get_curse(r->attribs, &ct_godcursezone);
- if (c && curse_active(c)) {
- wage = (wage < 10) ? 0 : (wage - 10);
- }
vm = frac_make(wage, 1);
/* Bei einer Duerre verdient man nur noch ein Viertel */
diff --git a/src/kernel/curse.c b/src/kernel/curse.c
index f96e2d212..8e8df36ac 100644
--- a/src/kernel/curse.c
+++ b/src/kernel/curse.c
@@ -129,6 +129,7 @@ static int read_ccompat(const char *cursename, struct storage *store)
} *seek, old_curses[] = {
{ "disorientationzone", "" },
{ "shipdisorientation", "" },
+ { "godcursezone", "" },
{ NULL, NULL }
};
for (seek = old_curses; seek->name; ++seek) {
diff --git a/src/kernel/messages.c b/src/kernel/messages.c
index 656e08b3a..98411973d 100644
--- a/src/kernel/messages.c
+++ b/src/kernel/messages.c
@@ -62,6 +62,7 @@ static message *missing_feedback(const char *name, const struct unit *u,
log_error("trying to create undefined feedback of type \"%s\"\n", name);
}
else if (missing_message_mode == MESSAGE_MISSING_REPLACE) {
+ log_warning("trying to create undefined message of type \"%s\"\n", name);
if (strcmp(name, "missing_feedback") != 0) {
if (!mt_find("missing_feedback")) {
mt_create_va(mt_new("missing_feedback", NULL), "unit:unit",
diff --git a/src/kernel/race.c b/src/kernel/race.c
index fdcd5e233..66dced6cf 100644
--- a/src/kernel/race.c
+++ b/src/kernel/race.c
@@ -292,7 +292,7 @@ static race *rc_find_i(const char *name)
return rc;
}
-const race * rc_find(const char *name) {
+race * rc_find(const char *name) {
return rc_find_i(name);
}
diff --git a/src/kernel/race.h b/src/kernel/race.h
index 663f33c16..4cd7fd3b7 100644
--- a/src/kernel/race.h
+++ b/src/kernel/race.h
@@ -159,7 +159,7 @@ extern "C" {
race *rc_create(const char *zName);
race *rc_get_or_create(const char *name);
bool rc_changed(int *cache);
- const race *rc_find(const char *);
+ race *rc_find(const char *);
void free_races(void);
bool rc_can_use(const struct race *rc, const struct item_type *itype);
diff --git a/src/kernel/version.c b/src/kernel/version.c
index 756eb3be5..7546bceac 100644
--- a/src/kernel/version.c
+++ b/src/kernel/version.c
@@ -8,7 +8,7 @@
#ifndef ERESSEA_VERSION
/* the version number, if it was not passed to make with -D */
-#define ERESSEA_VERSION "3.22.0"
+#define ERESSEA_VERSION "3.24.0"
#endif
const char *eressea_version(void) {
diff --git a/src/laws.c b/src/laws.c
index 10975c6a7..01aa4be8d 100644
--- a/src/laws.c
+++ b/src/laws.c
@@ -463,10 +463,7 @@ static void horses(region * r)
maxhorses = region_maxworkers(r) / 10;
horses = rhorses(r);
if (horses > 0) {
- if (is_cursed(r->attribs, &ct_godcursezone)) {
- rsethorses(r, (int)(horses * 0.9));
- }
- else if (maxhorses > 0) {
+ if (maxhorses > 0) {
double growth =
(RESOURCE_QUANTITY * (HORSEGROWTH * 200.0 * ((double)maxhorses -
horses))) / (double)maxhorses;
@@ -594,14 +591,21 @@ growing_trees_e3(region * r, const int current_season,
}
}
+static int cap_int(int i, int imin, int imax) {
+ if (i > imin) {
+ return ((i < imax) ? i : imax);
+ }
+ return imin;
+}
+
static void
growing_trees(region * r, const season_t current_season, const season_t last_weeks_season)
{
int grownup_trees, i, seeds, sprout;
attrib *a;
+ double seedchance = config_get_flt("rules.treeseeds.chance", 0.01F) * RESOURCE_QUANTITY;
if (current_season == SEASON_SUMMER || current_season == SEASON_AUTUMN) {
- double seedchance = 0.01F * RESOURCE_QUANTITY;
int mp, elves = count_race(r, get_race(RC_ELF));
direction_t d;
@@ -618,12 +622,6 @@ growing_trees(region * r, const season_t current_season, const season_t last_wee
a_removeall(&r->attribs, &at_germs);
}
- if (is_cursed(r->attribs, &ct_godcursezone)) {
- rsettrees(r, 1, (int)(rtrees(r, 1) * 0.9));
- rsettrees(r, 2, (int)(rtrees(r, 2) * 0.9));
- return;
- }
-
mp = max_production(r);
if (mp <= 0)
return;
@@ -655,84 +653,63 @@ growing_trees(region * r, const season_t current_season, const season_t last_wee
/* Gesamtzahl der Samen:
* bis zu 6% (FORESTGROWTH*3) der Baeume samen in die Nachbarregionen */
- seeds = (rtrees(r, 2) * FORESTGROWTH * 3) / 1000000;
- for (d = 0; d != MAXDIRECTIONS; ++d) {
- region *r2 = rconnect(r, d);
- if (r2 && fval(r2->terrain, LAND_REGION) && r2->terrain->size) {
- /* Eine Landregion, wir versuchen Samen zu verteilen:
- * Die Chance, das Samen ein Stueck Boden finden, in dem sie
- * keimen koennen, haengt von der Bewuchsdichte und der
- * verfuegbaren Flaeche ab. In Gletschern gibt es weniger
- * Moeglichkeiten als in Ebenen. */
- sprout = 0;
- seedchance = (1000.0 * region_maxworkers(r2)) / r2->terrain->size;
- for (i = 0; i < seeds / MAXDIRECTIONS; i++) {
- if (rng_int() % 10000 < seedchance)
- sprout++;
+ if (seedchance > 0) {
+ seeds = (rtrees(r, 2) * FORESTGROWTH * 3) / 1000000;
+ for (d = 0; d != MAXDIRECTIONS; ++d) {
+ region *r2 = rconnect(r, d);
+ if (r2 && fval(r2->terrain, LAND_REGION) && r2->terrain->size) {
+ /* Eine Landregion, wir versuchen Samen zu verteilen:
+ * Die Chance, das Samen ein Stueck Boden finden, in dem sie
+ * keimen koennen, haengt von der Bewuchsdichte und der
+ * verfuegbaren Flaeche ab. In Gletschern gibt es weniger
+ * Moeglichkeiten als in Ebenen. */
+ sprout = 0;
+ seedchance = (1000.0 * region_maxworkers(r2)) / r2->terrain->size;
+ for (i = 0; i < seeds / MAXDIRECTIONS; i++) {
+ if (rng_int() % 10000 < seedchance)
+ sprout++;
+ }
+ rsettrees(r2, 0, rtrees(r2, 0) + sprout);
}
- rsettrees(r2, 0, rtrees(r2, 0) + sprout);
}
}
-
}
else if (current_season == SEASON_SPRING) {
- int growth;
-
- if (is_cursed(r->attribs, &ct_godcursezone))
- return;
-
/* in at_germs merken uns die Zahl der Samen und Sproesslinge, die
* dieses Jahr aelter werden duerfen, damit nicht ein Same im selben
* Zyklus zum Baum werden kann */
a = a_find(r->attribs, &at_germs);
if (!a) {
a = a_add(&r->attribs, a_new(&at_germs));
- a->data.sa[0] = (short)rtrees(r, 0);
- a->data.sa[1] = (short)rtrees(r, 1);
+ a->data.sa[0] = (short)cap_int(rtrees(r, 0), 0, SHRT_MAX);
+ a->data.sa[1] = (short)cap_int(rtrees(r, 1), 0, SHRT_MAX);
}
- /* wir haben 6 Wochen zum wachsen, jeder Same/Spross hat 18% Chance
- * zu wachsen, damit sollten nach 5-6 Wochen alle gewachsen sein */
- growth = 1800;
-
- /* Samenwachstum */
-
- /* Raubbau abfangen, es duerfen nie mehr Samen wachsen, als aktuell
- * in der Region sind */
- seeds = rtrees(r, 0);
- if (seeds > a->data.sa[0]) seeds = a->data.sa[0];
- sprout = 0;
-
- for (i = 0; i < seeds; i++) {
- if (rng_int() % 10000 < growth)
- sprout++;
+ else if (a->data.sa[0] < 0 || a->data.sa[1] < 0) {
+ a->data.sa[0] = (short)cap_int(a->data.sa[0], 0, SHRT_MAX);
+ a->data.sa[1] = (short)cap_int(a->data.sa[1], 0, SHRT_MAX);
}
- /* aus dem Samenpool dieses Jahres abziehen */
- a->data.sa[0] = (short)(seeds - sprout);
- /* aus dem gesamt Samenpool abziehen */
- rsettrees(r, 0, rtrees(r, 0) - sprout);
- /* zu den Sproesslinge hinzufuegen */
- rsettrees(r, 1, rtrees(r, 1) + sprout);
/* Baumwachstum */
-
- /* hier gehen wir davon aus, das Jungbaeume nicht ohne weiteres aus
- * der Region entfernt werden koennen, da Jungbaeume in der gleichen
- * Runde nachwachsen, wir also nicht mehr zwischen diesjaehrigen und
- * 'alten' Jungbaeumen unterscheiden koennten */
sprout = rtrees(r, 1);
if (sprout > a->data.sa[1]) sprout = a->data.sa[1];
- grownup_trees = 0;
-
- for (i = 0; i < sprout; i++) {
- if (rng_int() % 10000 < growth)
- grownup_trees++;
- }
+ grownup_trees = sprout / 6;
/* aus dem Sproesslingepool dieses Jahres abziehen */
a->data.sa[1] = (short)(sprout - grownup_trees);
/* aus dem gesamt Sproesslingepool abziehen */
rsettrees(r, 1, rtrees(r, 1) - grownup_trees);
/* zu den Baeumen hinzufuegen */
rsettrees(r, 2, rtrees(r, 2) + grownup_trees);
+
+ /* Samenwachstum */
+ seeds = rtrees(r, 0);
+ if (seeds > a->data.sa[0]) seeds = a->data.sa[0];
+ sprout = seeds / 6;
+ /* aus dem Samenpool dieses Jahres abziehen */
+ a->data.sa[0] = (short)(seeds - sprout);
+ /* aus dem gesamt Samenpool abziehen */
+ rsettrees(r, 0, rtrees(r, 0) - sprout);
+ /* zu den Sproesslinge hinzufuegen */
+ rsettrees(r, 1, rtrees(r, 1) + sprout);
}
}
@@ -1003,7 +980,7 @@ int quit_cmd(unit * u, struct order *ord)
if (p == P_FACTION) {
#ifdef QUIT_WITH_TRANSFER
faction *f2 = getfaction();
- if (f2 == NULL) {
+ if (f2 == NULL || f2 == u->faction) {
cmistake(u, ord, 66, MSG_EVENT);
flags = 0;
}
@@ -1249,13 +1226,6 @@ void do_enter(struct region *r, bool is_final_attempt)
}
}
if (ulast != NULL) {
- /* Wenn wir hier angekommen sind, war der Befehl
- * erfolgreich und wir loeschen ihn, damit er im
- * zweiten Versuch nicht nochmal ausgefuehrt wird. */
- *ordp = ord->next;
- ord->next = NULL;
- free_order(ord);
-
if (ulast != u) {
/* put u behind ulast so it's the last unit in the building */
*uptr = u->next;
@@ -3121,14 +3091,7 @@ void update_long_order(unit * u)
}
break;
default:
- if (kwd > thiskwd) {
- /* swap out thisorder for the new one */
- cmistake(u, u->thisorder, 52, MSG_EVENT);
- set_order(&u->thisorder, copy_order(ord));
- }
- else {
- cmistake(u, ord, 52, MSG_EVENT);
- }
+ cmistake(u, ord, 52, MSG_EVENT);
break;
}
}
@@ -3712,8 +3675,9 @@ void process(void)
log_debug("- Step %u", prio);
while (proc && proc->priority == prio) {
- if (proc->name)
+ if (proc->name) {
log_debug(" - %s", proc->name);
+ }
proc = proc->next;
}
@@ -3721,8 +3685,9 @@ void process(void)
pglobal->data.global.process();
pglobal = pglobal->next;
}
- if (pglobal == NULL || pglobal->priority != prio)
+ if (pglobal == NULL || pglobal->priority != prio) {
continue;
+ }
for (r = regions; r; r = r->next) {
unit *u;
@@ -3733,8 +3698,9 @@ void process(void)
pregion->data.per_region.process(r);
pregion = pregion->next;
}
- if (pregion == NULL || pregion->priority != prio)
+ if (pregion == NULL || pregion->priority != prio) {
continue;
+ }
if (r->units) {
for (u = r->units; u; u = u->next) {
@@ -3744,14 +3710,16 @@ void process(void)
punit->data.per_unit.process(u);
punit = punit->next;
}
- if (punit == NULL || punit->priority != prio)
+ if (punit == NULL || punit->priority != prio) {
continue;
+ }
porder = punit;
while (porder && porder->priority == prio && porder->type == PR_ORDER) {
order **ordp = &u->orders;
- if (porder->flags & PROC_THISORDER)
+ if (porder->flags & PROC_THISORDER) {
ordp = &u->thisorder;
+ }
while (*ordp) {
order *ord = *ordp;
if (getkeyword(ord) == porder->data.per_order.kword) {
@@ -3780,8 +3748,9 @@ void process(void)
}
}
}
- if (!ord || *ordp == ord)
+ if (!ord || *ordp == ord) {
ordp = &(*ordp)->next;
+ }
}
porder = porder->next;
}
@@ -3798,9 +3767,9 @@ void process(void)
pregion->data.per_region.process(r);
pregion = pregion->next;
}
- if (pregion == NULL || pregion->priority != prio)
+ if (pregion == NULL || pregion->priority != prio) {
continue;
-
+ }
}
}
diff --git a/src/main.c b/src/main.c
index cfc2f9c22..130a2f6f7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -290,8 +290,6 @@ void locale_init(void)
}
}
-extern void bind_monsters(lua_State *L);
-
int main(int argc, char **argv)
{
int err = 0;
diff --git a/src/modules/autoseed.c b/src/modules/autoseed.c
index fca838c2a..b74690745 100644
--- a/src/modules/autoseed.c
+++ b/src/modules/autoseed.c
@@ -87,17 +87,17 @@ newfaction *read_newfactions(const char *filename)
if (fgets(buf, sizeof(buf), F) == NULL)
break;
+ if (buf[0] == '#') {
+ continue;
+ }
email[0] = '\0';
password[0] = '\0';
- if (sscanf(buf, "%54s %19s %7s %15s %4d", email, race, lang,
+ if (sscanf(buf, "%54s %19s %7s %15s %4d", email, race, lang,
password, &alliance) < 3) {
break;
}
- if (email[0] == '#') {
- continue;
- }
if (email[0] == '\0') {
break;
}
diff --git a/src/monsters.c b/src/monsters.c
index 6f20a8c8b..34214a342 100644
--- a/src/monsters.c
+++ b/src/monsters.c
@@ -43,8 +43,10 @@
#include
/* attributes includes */
-#include
#include
+#include
+#include
+#include
#include
@@ -142,21 +144,58 @@ static void reduce_weight(unit * u)
}
}
+static bool monster_is_waiting(const unit * u)
+{
+ int test = fval(u_race(u), RCF_ATTACK_MOVED) ? UFL_ISNEW : UFL_ISNEW | UFL_MOVED;
+ if (fval(u, test))
+ return true;
+ return false;
+}
+
+static bool monster_can_attack(const unit * u)
+{
+ if (u->status >= ST_AVOID) {
+ return false;
+ }
+ if (u->region->land) {
+ return is_guard(u);
+ }
+ else if (fval(u->region->terrain, SEA_REGION)) {
+ return fval(u_race(u), RCF_SWIM);
+ }
+ return fval(u_race(u), RCF_FLY);
+}
+
static order *monster_attack(unit * u, const unit * target)
{
assert(u->region == target->region);
assert(u->faction != target->faction);
- if (!cansee(u->faction, u->region, target, 0))
- return NULL;
- if (monster_is_waiting(u))
- return NULL;
-
- if (u->region->land && (u->region->flags & RF_GUARDED) == 0) {
+ if (!cansee(u->faction, u->region, target, 0)) {
return NULL;
}
+ if (monster_is_waiting(u)) {
+ return NULL;
+ }
+
return create_order(K_ATTACK, u->faction->locale, "%i", target->no);
}
+bool join_monsters(unit *u, faction *monsters) {
+ if (monsters == NULL) {
+ monsters = get_monsters();
+ if (monsters == NULL) {
+ return false;
+ }
+ }
+ u_setfaction(u, monsters);
+ u->status = ST_FIGHT;
+ a_removeall(&u->attribs, &at_otherfaction);
+ u->flags &= ~UFL_ANON_FACTION;
+ u_seteffstealth(u, -1);
+ u_freeorders(u);
+ return true;
+}
+
void monsters_desert(struct faction *monsters)
{
region *r;
@@ -166,15 +205,15 @@ void monsters_desert(struct faction *monsters)
unit *u;
for (u = r->units; u; u = u->next) {
- if (u->faction!=monsters
+ if (u->faction != monsters
&& (u_race(u)->flags & RCF_DESERT)) {
if (fval(u, UFL_ISNEW))
continue;
if (rng_int() % 100 < 5) {
- ADDMSG(&u->faction->msgs, msg_message("desertion",
- "unit region", u, r));
- u_setfaction(u, monsters);
- u_freeorders(u);
+ if (join_monsters(u, monsters)) {
+ ADDMSG(&u->faction->msgs, msg_message("desertion",
+ "unit region", u, r));
+ }
}
}
}
@@ -185,7 +224,8 @@ int monster_attacks(unit * monster, bool rich_only)
{
const race *rc_serpent = get_race(RC_SEASERPENT);
int result = -1;
- if (monster->status < ST_AVOID) {
+
+ if (monster_can_attack(monster)) {
region *r = monster->region;
unit *u2;
int money = 0;
@@ -214,10 +254,10 @@ int monster_attacks(unit * monster, bool rich_only)
return result;
}
-static order *get_money_for_dragon(region * r, unit * udragon, int wanted)
+static order *get_money_for_dragon(region * r, unit * u, int wanted)
{
int money;
- bool attacks = attack_chance > 0.0;
+ bool attacks = (attack_chance > 0.0) && armedmen(u, false);
/* falls genug geld in der region ist, treiben wir steuern ein. */
if (rmoney(r) >= wanted) {
@@ -231,8 +271,8 @@ static order *get_money_for_dragon(region * r, unit * udragon, int wanted)
/* falls der drache launisch ist, oder das regionssilber knapp, greift er alle an
* und holt sich Silber von Einheiten, vorausgesetzt er bewacht bereits */
money = 0;
- if (attacks && is_guard(udragon)) {
- int m = monster_attacks(udragon, true);
+ if (attacks && monster_can_attack(u)) {
+ int m = monster_attacks(u, true);
if (m > 0) money += m;
}
@@ -623,11 +663,11 @@ static order *plan_dragon(unit * u)
rc_wyrm = get_race(RC_WYRM);
}
- if (ta == NULL) {
- move |= (rpeasants(r) == 0); /* when no peasants, move */
- move |= (rmoney(r) == 0); /* when no money, move */
+ if (!move && ta == NULL) {
+ move = (rpeasants(r) == 0); /* when no peasants, move */
+ move = move || (rmoney(r) == 0); /* when no money, move */
}
- move |= chance(0.04); /* 4% chance to change your mind */
+ move = move || chance(0.04); /* 4% chance to change your mind */
if (rc == rc_wyrm && !move) {
unit *u2;
@@ -739,6 +779,7 @@ void plan_monsters(faction * f)
attrib *ta;
order *long_order = NULL;
bool can_move = true;
+ bool guarding;
/* Ab hier nur noch Befehle fuer NPC-Einheiten. */
if (u->faction != f || u->number <= 0) {
@@ -749,6 +790,7 @@ void plan_monsters(faction * f)
if (fval(u, UFL_ANON_FACTION)) {
u->flags &= ~UFL_ANON_FACTION;
}
+ a_removeall(&u->attribs, &at_otherfaction);
if (rc->splitsize < 10) {
/* hermit-type monsters eat each other */
@@ -763,8 +805,9 @@ void plan_monsters(faction * f)
/* Befehle muessen jede Runde neu gegeben werden: */
free_orders(&u->orders);
- /* All monsters guard the region: */
- if (u->status < ST_FLEE && !monster_is_waiting(u) && r->land) {
+ guarding = is_guard(u);
+ /* All monsters want to guard the region: */
+ if (!guarding && u->status < ST_FLEE && !monster_is_waiting(u) && r->land) {
unit_addorder(u, create_order(K_GUARD, u->faction->locale, NULL));
}
@@ -772,7 +815,7 @@ void plan_monsters(faction * f)
ta = a_find(u->attribs, &at_hate);
if (ta && !monster_is_waiting(u)) {
unit *tu = (unit *)ta->data.v;
- if (tu && tu->region == r) {
+ if (tu && tu->region == r && monster_can_attack(u)) {
order * ord = monster_attack(u, tu);
if (ord) {
unit_addorder(u, ord);
@@ -790,7 +833,7 @@ void plan_monsters(faction * f)
else
a_remove(&u->attribs, ta);
}
- else if (!r->land || is_guard(u)) {
+ else if (monster_can_attack(u)) {
if (chance(attack_chance)) {
int m = monster_attacks(u, false);
if (m >= 0) {
@@ -1011,14 +1054,6 @@ void spawn_undead(void)
}
}
-bool monster_is_waiting(const unit * u)
-{
- int test = fval(u_race(u), RCF_ATTACK_MOVED) ? UFL_ISNEW : UFL_ISNEW | UFL_MOVED;
- if (fval(u, test))
- return true;
- return false;
-}
-
static void eaten_by_monster(unit * u)
{
/* adjustment for smaller worlds */
@@ -1157,10 +1192,11 @@ void monster_kills_peasants(unit * u)
void make_zombie(unit * u)
{
- u_setfaction(u, get_monsters());
- u_freeorders(u);
- scale_number(u, 1);
- u->hp = unit_max_hp(u) * u->number;
- u_setrace(u, get_race(RC_ZOMBIE));
- u->irace = NULL;
+ if (join_monsters(u, NULL)) {
+ u_freeorders(u);
+ scale_number(u, 1);
+ u->hp = unit_max_hp(u) * u->number;
+ u_setrace(u, get_race(RC_ZOMBIE));
+ u->irace = NULL;
+ }
}
diff --git a/src/monsters.h b/src/monsters.h
index 81f7e39a3..d87398c2c 100644
--- a/src/monsters.h
+++ b/src/monsters.h
@@ -18,9 +18,13 @@ extern "C" {
void monsters_desert(struct faction *monsters);
void monster_kills_peasants(struct unit *u);
- bool monster_is_waiting(const struct unit *u);
void make_zombie(struct unit * u);
+ void spawn_undead(void);
+ void plan_monsters(struct faction *f);
+
+ bool join_monsters(struct unit *u, struct faction *monsters);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/monsters.test.c b/src/monsters.test.c
index 75a2cbc97..695e2f5e2 100644
--- a/src/monsters.test.c
+++ b/src/monsters.test.c
@@ -97,6 +97,7 @@ static void test_monsters_attack_ocean(CuTest * tc)
{
region *r;
unit *u, *m;
+ race *rc;
test_setup();
create_monsters(&u, &m);
@@ -105,12 +106,18 @@ static void test_monsters_attack_ocean(CuTest * tc)
unit_setid(u, 2);
m = test_create_unit(m->faction, r);
assert(!m->region->land);
-
+
config_set("rules.monsters.attack_chance", "1");
+ rc = rc_find(m->_race->_name);
+ freset(rc, RCF_SWIM);
plan_monsters(m->faction);
+ CuAssertPtrEquals(tc, NULL, find_order("attack 2", m));
+ fset(rc, RCF_SWIM);
+ plan_monsters(m->faction);
CuAssertPtrNotNull(tc, find_order("attack 2", m));
+
test_teardown();
}
@@ -145,7 +152,7 @@ static void test_seaserpent_piracy(CuTest * tc)
u_setrace(m, rc = test_create_race("seaserpent"));
assert(!m->region->land);
fset(m, UFL_MOVED);
- fset(rc, RCF_ATTACK_MOVED);
+ fset(rc, RCF_ATTACK_MOVED|RCF_SWIM);
config_set("rules.monsters.attack_chance", "1");
diff --git a/src/move.c b/src/move.c
index d33987d54..5d5513cd3 100644
--- a/src/move.c
+++ b/src/move.c
@@ -974,10 +974,17 @@ bool move_blocked(const unit * u, const region * r, const region * r2)
}
if (r->attribs) {
- const curse_type *fogtrap_ct = &ct_fogtrap;
- curse *c = get_curse(r->attribs, fogtrap_ct);
+ curse *c = get_curse(r->attribs, &ct_fogtrap);
+ if (curse_active(c)) {
+ return true;
+ }
+ }
+
+ if (r2->attribs && fval(u_race(u), RCF_UNDEAD)) {
+ curse *c = get_curse(r2->attribs, &ct_holyground);
return curse_active(c);
}
+
return false;
}
diff --git a/src/orderfile.c b/src/orderfile.c
index 5a3497b8e..a42d5ee69 100644
--- a/src/orderfile.c
+++ b/src/orderfile.c
@@ -48,182 +48,6 @@ static void begin_orders(unit *u) {
u->orders = NULL;
}
-static void unitorders(input *in, faction *f)
-{
- int i;
- unit *u;
-
- assert(f);
-
- i = getid();
- u = findunit(i);
-
- if (u && u->faction == f) {
- order **ordp;
-
- begin_orders(u);
- ordp = &u->orders;
-
- for (;;) {
- const char *s;
- /* Erst wenn wir sicher sind, dass kein Befehl
- * eingegeben wurde, checken wir, ob nun eine neue
- * Einheit oder ein neuer Spieler drankommt */
-
- s = in->getbuf(in->data);
- if (s == NULL)
- break;
-
- if (s[0]) {
- if (s[0] != '@') {
- char token[64];
- const char *stok = s;
- stok = parse_token(&stok, token, sizeof(token));
-
- if (stok) {
- bool quit = false;
- param_t param = findparam(stok, u->faction->locale);
- switch (param) {
- case P_UNIT:
- case P_REGION:
- quit = true;
- break;
- case P_FACTION:
- case P_NEXT:
- case P_GAMENAME:
- /* these terminate the orders, so we apply extra checking */
- if (strlen(stok) >= 3) {
- quit = true;
- break;
- }
- else {
- quit = false;
- }
- break;
- default:
- break;
- }
- if (quit) {
- break;
- }
- }
- }
- /* Nun wird der Befehl erzeut und eingehaengt */
- *ordp = parse_order(s, u->faction->locale);
- if (*ordp) {
- ordp = &(*ordp)->next;
- }
- else {
- ADDMSG(&f->msgs, msg_message("parse_error", "unit command", u, s));
- }
- }
- }
-
- }
-}
-
-static faction *factionorders(void)
-{
- int fid = getid();
- faction *f = findfaction(fid);
-
- if (f != NULL && (f->flags & FFL_NPC) == 0) {
- char token[PASSWORD_MAXSIZE];
- const char *pass = gettoken(token, sizeof(token));
-
- if (!checkpasswd(f, (const char *)pass)) {
- log_debug("Invalid password for faction %s", itoa36(fid));
- ADDMSG(&f->msgs, msg_message("wrongpasswd", "password", pass));
- return 0;
- }
- /* Die Partei hat sich zumindest gemeldet, so dass sie noch
- * nicht als untaetig gilt */
- f->lastorders = turn;
-
- }
- else {
- log_debug("orders for invalid faction %s", itoa36(fid));
- }
- return f;
-}
-
-int read_orders(input *in)
-{
- const char *b;
- int nfactions = 0;
- struct faction *f = NULL;
- const struct locale *lang = default_locale;
-
- /* TODO: recognize UTF8 BOM */
- b = in->getbuf(in->data);
-
- /* Auffinden der ersten Partei, und danach abarbeiten bis zur letzten
- * Partei */
-
- while (b) {
- char token[128];
- param_t p;
- const char *s;
- init_tokens_str(b);
- s = gettoken(token, sizeof(token));
- p = findparam_block(s, lang, true);
- switch (p) {
- case P_GAMENAME:
- case P_FACTION:
- f = factionorders();
- if (f) {
- lang = f->locale;
- ++nfactions;
- }
-
- b = in->getbuf(in->data);
- break;
-
- /* in factionorders wird nur eine zeile gelesen:
- * diejenige mit dem passwort. Die befehle der units
- * werden geloescht, und die Partei wird als aktiv
- * vermerkt. */
-
- case P_UNIT:
- if (f) {
- unitorders(in, f);
- do {
- b = in->getbuf(in->data);
- if (!b) {
- break;
- }
- init_tokens_str(b);
- s = gettoken(token, sizeof(token));
- p = (s && s[0] != '@') ? findparam(s, lang) : NOPARAM;
- } while ((p != P_UNIT || !f) && p != P_FACTION && p != P_NEXT
- && p != P_GAMENAME);
- }
- break;
-
- /* Falls in unitorders() abgebrochen wird, steht dort entweder eine neue
- * Partei, eine neue Einheit oder das File-Ende. Das switch() wird erneut
- * durchlaufen, und die entsprechende Funktion aufgerufen. Man darf buf
- * auf alle Faelle nicht ueberschreiben! Bei allen anderen Eintraegen hier
- * muss buf erneut gefaellt werden, da die betreffende Information in nur
- * einer Zeile steht, und nun die naechste gelesen werden muss.
- */
-
- case P_NEXT:
- f = NULL;
- lang = default_locale;
- b = in->getbuf(in->data);
- break;
-
- default:
- b = in->getbuf(in->data);
- break;
- }
- }
-
- log_info("done reading orders for %d factions", nfactions);
- return 0;
-}
-
typedef struct parser_state {
unit *u;
faction *f;
diff --git a/src/orderfile.h b/src/orderfile.h
index f7934556e..8803ae717 100644
--- a/src/orderfile.h
+++ b/src/orderfile.h
@@ -12,7 +12,6 @@ extern "C" {
void *data;
} input;
- int read_orders(struct input *in);
int parseorders(FILE *F);
#ifdef __cplusplus
diff --git a/src/orderfile.test.c b/src/orderfile.test.c
index 204e20d5d..39653391b 100644
--- a/src/orderfile.test.c
+++ b/src/orderfile.test.c
@@ -21,82 +21,36 @@
#include
#include
-static const char *getbuf_null(void *data)
-{
- return NULL;
-}
-
-static void test_read_orders(CuTest *tc) {
- input in;
- test_setup();
- in.getbuf = getbuf_null;
- in.data = NULL;
- CuAssertIntEquals(tc, 0, read_orders(&in));
- test_teardown();
-}
-
-static const char *getbuf_strings(void *data)
-{
- strlist **listp = (strlist **)data;
- if (listp && *listp) {
- strlist *list = *listp;
- *listp = list->next;
- return list->s;
- }
- return NULL;
-}
-
static void test_unit_orders(CuTest *tc) {
- input in;
unit *u;
faction *f;
- strlist *orders = NULL, *backup;
- char buf[64];
+ FILE *F = tmpfile();
test_setup();
u = test_create_unit(f = test_create_faction(NULL), test_create_plain(0, 0));
f->locale = test_create_locale();
u->orders = create_order(K_ENTERTAIN, f->locale, NULL);
faction_setpassword(f, password_hash("password", PASSWORD_DEFAULT));
- snprintf(buf, sizeof(buf), "%s %s %s",
+ fprintf(F, "%s %s %s\n",
LOC(f->locale, parameters[P_FACTION]), itoa36(f->no), "password");
- addstrlist(&orders, buf);
- snprintf(buf, sizeof(buf), "%s %s",
+ fprintf(F, "%s %s\n",
LOC(f->locale, parameters[P_UNIT]), itoa36(u->no));
- addstrlist(&orders, buf);
- snprintf(buf, sizeof(buf), "%s %s", keyword_name(K_MOVE, f->locale),
+ fprintf(F, "%s %s\n", keyword_name(K_MOVE, f->locale),
LOC(f->locale, shortdirections[D_WEST]));
- backup = orders;
- addstrlist(&orders, buf);
- in.data = &orders;
- in.getbuf = getbuf_strings;
- CuAssertIntEquals(tc, 0, read_orders(&in));
+ rewind(F);
+ CuAssertIntEquals(tc, 0, parseorders(F));
CuAssertPtrNotNull(tc, u->old_orders);
CuAssertPtrNotNull(tc, u->orders);
- CuAssertPtrEquals(tc, NULL, orders);
CuAssertIntEquals(tc, K_MOVE, getkeyword(u->orders));
CuAssertIntEquals(tc, K_ENTERTAIN, getkeyword(u->old_orders));
CuAssertIntEquals(tc, UFL_ORDERS, u->flags & UFL_ORDERS);
- freestrlist(backup);
+ fclose(F);
test_teardown();
}
-typedef struct order_list {
- const char **orders;
- int next;
-} order_list;
-
-static const char *getbuf_list(void *data)
-{
- order_list * olist = (order_list *)data;
- return olist->orders[olist->next++];
-}
-
static void test_faction_password_okay(CuTest *tc) {
- input in;
faction *f;
- order_list olist;
- const char *orders[] = { "ERESSEA 1 password", NULL };
+ FILE *F;
test_setup();
f = test_create_faction(NULL);
@@ -104,21 +58,18 @@ static void test_faction_password_okay(CuTest *tc) {
CuAssertIntEquals(tc, 1, f->no);
faction_setpassword(f, "password");
f->lastorders = turn - 1;
- olist.orders = orders;
- olist.next = 0;
- in.getbuf = getbuf_list;
- in.data = &olist;
- CuAssertIntEquals(tc, 0, read_orders(&in));
- CuAssertIntEquals(tc, 2, olist.next);
+ F = tmpfile();
+ fprintf(F, "ERESSEA 1 password\n");
+ rewind(F);
+ CuAssertIntEquals(tc, 0, parseorders(F));
CuAssertIntEquals(tc, turn, f->lastorders);
+ fclose(F);
test_teardown();
}
static void test_faction_password_bad(CuTest *tc) {
- input in;
faction *f;
- order_list olist;
- const char *orders[] = { "ERESSEA 1 password", NULL };
+ FILE *F;
test_setup();
mt_create_va(mt_new("wrongpasswd", NULL), "password:string", MT_NEW_END);
@@ -128,20 +79,18 @@ static void test_faction_password_bad(CuTest *tc) {
CuAssertIntEquals(tc, 1, f->no);
faction_setpassword(f, "patzword");
f->lastorders = turn - 1;
- olist.orders = orders;
- olist.next = 0;
- in.getbuf = getbuf_list;
- in.data = &olist;
- CuAssertIntEquals(tc, 0, read_orders(&in));
- CuAssertIntEquals(tc, 2, olist.next);
+ F = tmpfile();
+ fprintf(F, "ERESSEA 1 password\n");
+ rewind(F);
+ CuAssertIntEquals(tc, 0, parseorders(F));
CuAssertIntEquals(tc, turn - 1, f->lastorders);
+ fclose(F);
test_teardown();
}
CuSuite *get_orderfile_suite(void)
{
CuSuite *suite = CuSuiteNew();
- SUITE_ADD_TEST(suite, test_read_orders);
SUITE_ADD_TEST(suite, test_unit_orders);
SUITE_ADD_TEST(suite, test_faction_password_okay);
SUITE_ADD_TEST(suite, test_faction_password_bad);
diff --git a/src/randenc.c b/src/randenc.c
index 356c9c695..5464f0063 100644
--- a/src/randenc.c
+++ b/src/randenc.c
@@ -380,44 +380,6 @@ static void create_icebergs(void)
}
}
-static void godcurse(void)
-{
- region *r;
-
- for (r = regions; r; r = r->next) {
- if (is_cursed(r->attribs, &ct_godcursezone)) {
- unit *u;
- for (u = r->units; u; u = u->next) {
- skill *sv = u->skills;
- while (sv != u->skills + u->skill_size) {
- int weeks = 1 + rng_int() % 3;
- reduce_skill(u, sv, weeks);
- ++sv;
- }
- }
- if (fval(r->terrain, SEA_REGION)) {
- ship *sh;
- for (sh = r->ships; sh;) {
- ship *shn = sh->next;
- double dmg = config_get_flt("rules.ship.damage.godcurse", 0.1);
- damage_ship(sh, dmg);
- if (sh->damage >= sh->size * DAMAGE_SCALE) {
- unit *uo = ship_owner(sh);
- if (uo) {
- ADDMSG(&uo->faction->msgs,
- msg_message("godcurse_destroy_ship", "ship", sh));
- }
- sink_ship(sh);
- remove_ship(&sh->region->ships, sh);
- }
- sh = shn;
- }
- }
- }
- }
-
-}
-
/** handles the "orcish" curse that makes units grow like old orks
* TODO: This would probably be better handled in an age-function for the curse,
* but it's now being called by randomevents()
@@ -535,7 +497,6 @@ void randomevents(void)
for (r = regions; r; r = r->next) {
drown(r);
}
- godcurse();
orc_growth();
demon_skillchanges();
if (volcano_module()) {
diff --git a/src/report.c b/src/report.c
index 7fdf8e690..1560f42e2 100644
--- a/src/report.c
+++ b/src/report.c
@@ -1718,23 +1718,23 @@ nr_ship(struct stream *out, const region *r, const ship * sh, const faction * f,
char buffer[1024];
char ch;
sbstring sbs;
+ const char *stname;
sbs_init(&sbs, buffer, sizeof(buffer));
newline(out);
+ stname = locale_plural(f->locale, sh->type->_name, sh->number, true);
if (captain && captain->faction == f) {
int n = 0, p = 0;
- const char *stname;
getshipweight(sh, &n, &p);
n = (n + 99) / 100; /* 1 Silber = 1 GE */
- stname = locale_plural(f->locale, sh->type->_name, sh->number, true);
sbs_printf(&sbs, "%s, %d %s, (%d/%d)", shipname(sh), sh->number,
stname, n, ship_capacity(sh) / 100);
}
else {
- sbs_printf(&sbs, "%s, %s", shipname(sh), LOC(f->locale, sh->type->_name));
+ sbs_printf(&sbs, "%s, %d %s", shipname(sh), sh->number, stname);
}
if (!ship_finished(sh)) {
diff --git a/src/spells.c b/src/spells.c
index 6cff4bb9b..de2036225 100644
--- a/src/spells.c
+++ b/src/spells.c
@@ -2358,9 +2358,8 @@ static void patzer_peasantmob(const castorder * co)
rsetpeasants(r, rpeasants(r) - n);
assert(rpeasants(r) >= 0);
- u =
- create_unit(r, f, n, get_race(RC_PEASANT), 0, LOC(f->locale, "angry_mob"),
- NULL);
+ u = create_unit(r, f, n, get_race(RC_PEASANT), 0,
+ LOC(f->locale, "angry_mob"), NULL);
fset(u, UFL_ISNEW);
unit_addorder(u, create_order(K_GUARD, lang, NULL));
set_order(&u->thisorder, default_order(lang));
diff --git a/src/spells/flyingship.c b/src/spells/flyingship.c
index fb6a8faeb..3bf9b61b1 100644
--- a/src/spells/flyingship.c
+++ b/src/spells/flyingship.c
@@ -56,7 +56,7 @@ int sp_flying_ship(castorder * co)
if (pa->param[0]->flag == TARGET_NOTFOUND)
return 0;
sh = pa->param[0]->data.sh;
- if (sh->type->construction->maxsize > 50) {
+ if (sh->number > 1 || sh->type->construction->maxsize > 50) {
ADDMSG(&caster->faction->msgs, msg_feedback(caster, co->order,
"error_flying_ship_too_big", "ship", sh));
return 0;
diff --git a/src/spells/regioncurse.c b/src/spells/regioncurse.c
index 48565789e..9006d9218 100644
--- a/src/spells/regioncurse.c
+++ b/src/spells/regioncurse.c
@@ -22,30 +22,6 @@
#include
#include
-/*
- * godcursezone
- */
-static message *cinfo_cursed_by_the_gods(const void *obj, objtype_t typ,
- const curse * c, int self)
-{
- region *r = (region *)obj;
-
- UNUSED_ARG(typ);
- UNUSED_ARG(self);
- assert(typ == TYP_REGION);
-
- if (r->terrain->flags & SEA_REGION) {
- return msg_message("curseinfo::godcurseocean", "id", c->no);
- }
- return msg_message("curseinfo::godcurse", "id", c->no);
-}
-
-const struct curse_type ct_godcursezone = {
- "godcursezone",
- CURSETYP_NORM, CURSE_IMMUNE, (NO_MERGE),
- cinfo_cursed_by_the_gods,
-};
-
/* --------------------------------------------------------------------- */
/*
* C_GBDREAM
@@ -299,7 +275,6 @@ void register_regioncurse(void)
ct_register(&ct_badmagicresistancezone);
ct_register(&ct_goodmagicresistancezone);
ct_register(&ct_riotzone);
- ct_register(&ct_godcursezone);
ct_register(&ct_holyground);
ct_register(&ct_healing);
}
diff --git a/src/spells/regioncurse.h b/src/spells/regioncurse.h
index b1425daf0..7d11e6348 100644
--- a/src/spells/regioncurse.h
+++ b/src/spells/regioncurse.h
@@ -10,7 +10,6 @@ extern "C" {
extern const struct curse_type ct_peacezone;
extern const struct curse_type ct_drought;
extern const struct curse_type ct_blessedharvest;
- extern const struct curse_type ct_godcursezone;
extern const struct curse_type ct_gbdream;
extern const struct curse_type ct_healing;
extern const struct curse_type ct_antimagiczone;
diff --git a/src/util/message.c b/src/util/message.c
index 38254958b..a1618f832 100644
--- a/src/util/message.c
+++ b/src/util/message.c
@@ -277,7 +277,7 @@ const message_type *mt_find(const char *name)
return data;
}
}
- return 0;
+ return NULL;
}
void msg_free(message * msg)
diff --git a/src/util/param.c b/src/util/param.c
index 31066a4a9..0c486ce5a 100644
--- a/src/util/param.c
+++ b/src/util/param.c
@@ -106,10 +106,9 @@ param_t findparam_block(const char *s, const struct locale *lang, bool any_local
bool isparam(const char *s, const struct locale * lang, param_t param)
{
- assert(s);
assert(param != P_GEBAEUDE);
assert(param != P_BUILDING);
- if (s[0] > '@') {
+ if (s && s[0] > '@') {
param_t p = findparam(s, lang);
return p == param;
}