diff --git a/conf/e4/config.xml b/conf/e4/config.xml
index 95bcde300..a6439db21 100644
--- a/conf/e4/config.xml
+++ b/conf/e4/config.xml
@@ -58,6 +58,7 @@
+
diff --git a/conf/eressea.ini b/conf/eressea.ini
index 1bc14283d..a0d0b9fed 100644
--- a/conf/eressea.ini
+++ b/conf/eressea.ini
@@ -9,7 +9,7 @@ memcheck = 0
locales = de,en
[lua]
-install = ../git
+install = .
paths = lunit:scripts
maxnmrs = 20
rules = e2
diff --git a/game-e2/catalog.xml b/game-e2/catalog.xml
deleted file mode 100644
index a6c2882c8..000000000
--- a/game-e2/catalog.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/game-e2/config.xml b/game-e2/config.xml
deleted file mode 100644
index ec8a8855e..000000000
--- a/game-e2/config.xml
+++ /dev/null
@@ -1,114 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- eressea-server@eressea.de
- eressea-server@eressea.de
-
-
- Bitte denke daran, deine Befehle mit dem Betreff
- ERESSEA BEFEHLE an eressea-server@eressea.de zu senden.
- Remember to send your orders to
- eressea-server@eressea.de with the subject ERESSEA ORDERS.
-
-
- ERESSEA BEFEHLE
- ERESSEA ORDERS
-
-
-
diff --git a/game-e2/eressea.ini b/game-e2/eressea.ini
deleted file mode 100644
index 1abf1be35..000000000
--- a/game-e2/eressea.ini
+++ /dev/null
@@ -1,16 +0,0 @@
-[eressea]
-base = .
-report = reports
-verbose = 0
-lomem = 0
-debug = 0
-memcheck = 0
-locales = de,en
-
-[config]
-rules = eressea
-source_dir = ..
-maxnmrs = 10
-
-[editor]
-color = 1
diff --git a/game-e2/runtests.lua b/game-e2/runtests.lua
deleted file mode 100644
index 423094391..000000000
--- a/game-e2/runtests.lua
+++ /dev/null
@@ -1,2 +0,0 @@
-require "setup"
-run_tests()
diff --git a/game-e2/setup.lua b/game-e2/setup.lua
deleted file mode 100644
index ccd43719d..000000000
--- a/game-e2/setup.lua
+++ /dev/null
@@ -1,14 +0,0 @@
-local srcpath = config.source_dir
-local respath = srcpath .. '/res'
-local paths = {
- 'scripts/?.lua',
- 'core/scripts/?.lua',
- 'lunit/?.lua'
-}
-
-for idx, path in pairs(paths) do
- package.path = srcpath .. '/' .. path .. ';' .. package.path
-end
-
-assert(read_xml())
-require "init"
diff --git a/game-e3/catalog.xml b/game-e3/catalog.xml
deleted file mode 100644
index 3d82919cd..000000000
--- a/game-e3/catalog.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/game-e3/config.xml b/game-e3/config.xml
deleted file mode 100644
index a66b20393..000000000
--- a/game-e3/config.xml
+++ /dev/null
@@ -1,182 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- eressea-server@eressea.de
- eressea-server@eressea.de
-
-
- Bitte denke daran, deine Befehle mit dem Betreff
- ERESSEA 4 BEFEHLE an eressea-server@eressea.de zu senden.
- Remember to send your orders to
- eressea-server@eressea.de with the subject ERESSEA 4 ORDERS.
-
-
- ERESSEA 4 BEFEHLE
- ERESSEA 4 ORDERS
-
-
-
diff --git a/game-e3/eressea.ini b/game-e3/eressea.ini
deleted file mode 100644
index fdfe6277c..000000000
--- a/game-e3/eressea.ini
+++ /dev/null
@@ -1,16 +0,0 @@
-[eressea]
-base = .
-report = reports
-verbose = 0
-lomem = 0
-debug = 0
-memcheck = 0
-locales = de,en
-
-[config]
-rules = e3a
-source_dir = ..
-maxnmrs = 20
-
-[editor]
-color = 1
diff --git a/game-e3/runtests.lua b/game-e3/runtests.lua
deleted file mode 100644
index 423094391..000000000
--- a/game-e3/runtests.lua
+++ /dev/null
@@ -1,2 +0,0 @@
-require "setup"
-run_tests()
diff --git a/game-e3/setup.lua b/game-e3/setup.lua
deleted file mode 100644
index ccd43719d..000000000
--- a/game-e3/setup.lua
+++ /dev/null
@@ -1,14 +0,0 @@
-local srcpath = config.source_dir
-local respath = srcpath .. '/res'
-local paths = {
- 'scripts/?.lua',
- 'core/scripts/?.lua',
- 'lunit/?.lua'
-}
-
-for idx, path in pairs(paths) do
- package.path = srcpath .. '/' .. path .. ';' .. package.path
-end
-
-assert(read_xml())
-require "init"
diff --git a/process/cron/backup-eressea b/process/cron/backup-eressea
new file mode 100755
index 000000000..4f1d42144
--- /dev/null
+++ b/process/cron/backup-eressea
@@ -0,0 +1,31 @@
+#!/bin/bash
+if [ -z $ERESSEA ] ; then
+ ERESSEA=$HOME/eressea
+ echo "The ERESSEA environment variable is not set. Assuming $ERESSEA."
+fi
+GAME=$1
+if [ ! -d $ERESSEA/game-$GAME ]; then
+ echo "No such game: game-$GAME."
+ exit 1
+fi
+cd $ERESSEA/game-$GAME
+TURN=$2
+if [ -z $TURN ]; then
+ TURN=$(cat turn)
+fi
+if [ ! -e data/$TURN.dat ]; then
+ echo "No data for turn $TURN in game $GAME."
+ exit 2
+fi
+if [ ! -d backup ] ; then
+ echo "creating missing backup directory for game $GAME."
+ mkdir -p ~/backup/eressea/game-$GAME
+ ln -sf ~/backup/eressea/game-$GAME backup
+fi
+
+files="data/$TURN.dat parteien.full parteien"
+if [ -e orders.$TURN ]; then
+files="$files orders.$TURN"
+fi
+echo "backup turn $TURN, game $GAME, files: $files"
+tar cjf backup/$TURN.tar.bz2 $files
diff --git a/process/cron/create-orders b/process/cron/create-orders
new file mode 100755
index 000000000..ff784f9aa
--- /dev/null
+++ b/process/cron/create-orders
@@ -0,0 +1,16 @@
+GAME=$1
+TURN=$2
+
+if [ ! -d $ERESSEA/game-$GAME ] ; then
+ echo "No such game: $GAME"
+ exit 1
+fi
+
+cd $ERESSEA/game-$GAME
+if [ -d orders.dir.$TURN ]; then
+ echo "orders.dir.$TURN already exists"
+else
+ mv orders.dir orders.dir.$TURN
+ mkdir -p orders.dir
+fi
+ls -1rt orders.dir.$TURN/turn-* | xargs cat > orders.$TURN
diff --git a/process/cron/run-eressea b/process/cron/run-eressea
index f31150c1a..e932378fc 100755
--- a/process/cron/run-eressea
+++ b/process/cron/run-eressea
@@ -12,14 +12,15 @@ if [ -d $REPORTS ]; then
rm -rf $REPORTS
fi
mkdir $REPORTS
-$BIN/backup-eressea $GAME $TURN
cd $ERESSEA/game-$GAME
if [ -d test ]; then
touch test/execute.lock
fi
+$BIN/create-orders $GAME $TURN
+$BIN/backup-eressea $GAME $TURN
rm -f execute.lock
-$BIN/run-turn $GAME
+$BIN/run-turn $GAME $TURN
touch execute.lock
if [ ! -s $ERESSEA/game-$GAME/orders.$TURN ]; then
diff --git a/process/cron/run-turn b/process/cron/run-turn
new file mode 100755
index 000000000..80e12b093
--- /dev/null
+++ b/process/cron/run-turn
@@ -0,0 +1,14 @@
+GAME=$1
+TURN=$2
+
+if [ ! -d $ERESSEA/game-$GAME ] ; then
+ echo "No such game: $GAME"
+ exit 1
+fi
+
+cd $ERESSEA/game-$GAME
+
+echo "running turn $TURN, game $GAME"
+$ERESSEA/server/bin/eressea -v1 -t $TURN run-turn.lua
+mkdir -p log
+ln -f eressea.log log/eressea.log.$TURN
diff --git a/res/buildings/castle-2.xml b/res/buildings/castle-2.xml
index 5f48e73ee..76c908572 100644
--- a/res/buildings/castle-2.xml
+++ b/res/buildings/castle-2.xml
@@ -1,24 +1,24 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/res/buildings/castle.xml b/res/buildings/castle.xml
index 296d1f716..49d1ca5a8 100644
--- a/res/buildings/castle.xml
+++ b/res/buildings/castle.xml
@@ -1,26 +1,26 @@
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/res/core/common/items.xml b/res/core/common/items.xml
index d867a3126..9508653e7 100644
--- a/res/core/common/items.xml
+++ b/res/core/common/items.xml
@@ -1,6 +1,10 @@
+
+
+
+
diff --git a/res/core/messages.xml b/res/core/messages.xml
index 52b132220..cbc5dd780 100644
--- a/res/core/messages.xml
+++ b/res/core/messages.xml
@@ -1,5 +1,23 @@
+
+
+
+
+
+
+ $unit($owner) bittet $unit($unit), $ship($ship) zu verlassen.
+ $unit($owner) asks $unit($unit) to leave $ship($ship).
+
+
+
+
+
+
+
+ $unit($owner) bittet $unit($unit), $building($building) zu verlassen.
+ $unit($owner) asks $unit($unit) to leave $building($building).
+
diff --git a/res/e3a/buildings.xml b/res/e3a/buildings.xml
index b3e59f0a4..227a2e47a 100644
--- a/res/e3a/buildings.xml
+++ b/res/e3a/buildings.xml
@@ -5,15 +5,15 @@
-
+
-
+
-
+
-
+
diff --git a/scripts/eressea/e3/rules.lua b/scripts/eressea/e3/rules.lua
index 0c5e9be85..c0ac8978a 100644
--- a/scripts/eressea/e3/rules.lua
+++ b/scripts/eressea/e3/rules.lua
@@ -26,10 +26,6 @@ function item_canuse(u, iname)
return true
end
-function building_protection(b, u)
- return 1
-end
-
function building_taxes(b, blevel)
btype = b.type
if btype=="castle" then
diff --git a/scripts/tests/e3/rules.lua b/scripts/tests/e3/rules.lua
index 07fbb1a60..193551ea9 100644
--- a/scripts/tests/e3/rules.lua
+++ b/scripts/tests/e3/rules.lua
@@ -712,6 +712,42 @@ function test_golem_use_four_iron()
assert_equal(4, u1:get_item("towershield"))
end
+function skip_test_silver_weight_stops_movement()
+ local r1 = region.create(1, 1, "plain")
+ local r2 = region.create(2, 1, "plain")
+ region.create(3, 1, "plain")
+ local f1 = faction.create("noreply@eressea.de", "human", "de")
+ local u1 = unit.create(f1, r1, 1)
+ u1:clear_orders()
+ u1:add_order("NACH OST")
+ u1:add_item("money", 540)
+ assert_equal(1540, u1.weight)
+ process_orders()
+ assert_equal(r2, u1.region)
+ u1:add_item("money", 1)
+ process_orders()
+ assert_equal(r2, u1.region)
+end
+
+function skip_test_silver_weight_stops_ship()
+ local r1 = region.create(1, 1, "ocean")
+ local r2 = region.create(2, 1, "ocean")
+ region.create(3, 1, "ocean")
+ local f1 = faction.create("noreply@eressea.de", "human", "de")
+ local u1 = unit.create(f1, r1, 1)
+ u1:set_skill("sailing", 3)
+ local s1 = ship.create(r1, "canoe")
+ u1.ship = s1
+ u1:clear_orders()
+ u1:add_order("NACH OST")
+ u1:add_item("money", 2000)
+ process_orders()
+ assert_equal(r2, u1.region)
+ u1:add_item("money", 1)
+ process_orders()
+ assert_equal(r2, u1.region)
+end
+
function test_building_owner_can_enter_ship()
local r1 = region.create(1, 2, "plain")
local f1 = faction.create("noreply@eressea.de", "human", "de")
@@ -734,3 +770,12 @@ function test_building_owner_can_enter_ship()
assert_equal(s1, u1.ship)
assert_equal(null, u1.building, "owner of the building can not go into a ship")
end
+
+function test_weightless_silver()
+ local r1 = region.create(1, 2, "plain")
+ local f1 = faction.create("noreply@eressea.de", "human", "de")
+ local u1 = unit.create(f1, r1, 1)
+ assert_equal(1000, u1.weight)
+ u1:add_item("money", 540)
+ assert_equal(1000, u1.weight)
+end
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b64ae7072..348a4be52 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -126,25 +126,27 @@ set(SERVER_SRC
bind_ship.c
bind_storage.c
bind_unit.c
- ${ERESSEA_SRC})
+)
if (SQLITE3_FOUND)
-set (SERVER_SRC
+set (SERVER_SRC ${SERVER_SRC}
sqlite.c
bind_sqlite.c
- ${SERVER_SRC})
+)
endif (SQLITE3_FOUND)
if (CURSES_FOUND)
-set (SERVER_SRC
+set (SERVER_SRC ${SERVER_SRC}
gmtool.c
listbox.c
bind_gmtool.c
- ${SERVER_SRC})
+)
endif(CURSES_FOUND)
+add_library(game ${ERESSEA_SRC})
add_executable(eressea ${SERVER_SRC})
target_link_libraries(eressea
+ game
${TOLUA_LIBRARIES}
${LUA_LIBRARIES}
${QUICKLIST_LIBRARIES}
@@ -178,12 +180,12 @@ set(TESTS_SRC
${ATTRIBUTES_TESTS}
${UTIL_TESTS}
${KERNEL_TESTS}
- ${ERESSEA_SRC}
)
add_executable(test_eressea ${TESTS_SRC})
-target_link_libraries(test_eressea ${CUTEST_LIBRARIES})
target_link_libraries(test_eressea
+ game
+ ${CUTEST_LIBRARIES}
${LUA_LIBRARIES}
${QUICKLIST_LIBRARIES}
${STORAGE_LIBRARIES}
diff --git a/src/attributes/stealth.c b/src/attributes/stealth.c
index 129802c09..9d76ffb29 100644
--- a/src/attributes/stealth.c
+++ b/src/attributes/stealth.c
@@ -1,4 +1,3 @@
-#include
#include
#include
#include
diff --git a/src/battle.c b/src/battle.c
index 7065ad11b..ed4354049 100644
--- a/src/battle.c
+++ b/src/battle.c
@@ -1901,7 +1901,7 @@ int skilldiff(troop at, troop dt, int dist)
init = true;
}
if (df->building->type->protection) {
- int beff = df->building->type->protection(df->building, du);
+ int beff = df->building->type->protection(df->building, du, DEFENSE_BONUS);
if (beff) {
skdiff -= beff;
is_protected = 2;
@@ -1918,7 +1918,7 @@ int skilldiff(troop at, troop dt, int dist)
if (magicwalls_ct
&& curse_active(get_curse(df->building->attribs, magicwalls_ct))) {
/* Verdoppelt Burgenbonus */
- skdiff -= buildingeffsize(df->building, false);
+ skdiff -= df->building->type->protection(df->building, du, DEFENSE_BONUS);
}
}
/* Goblin-Verteidigung
diff --git a/src/battle.test.c b/src/battle.test.c
index e35864c12..1a329252c 100644
--- a/src/battle.test.c
+++ b/src/battle.test.c
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
#include "tests.h"
@@ -26,7 +27,7 @@ static void test_make_fighter(CuTest * tc)
test_cleanup();
test_create_world();
r = findregion(0, 0);
- f = test_create_faction(rc_find("human"));
+ f = test_create_faction(NULL);
au = test_create_unit(f, r);
enable_skill(SK_MAGIC, true);
enable_skill(SK_RIDING, true);
@@ -57,131 +58,160 @@ static void test_make_fighter(CuTest * tc)
test_cleanup();
}
-static int add_two(building * b, unit * u) {
+static int add_two(building * b, unit * u, building_bonus bonus) {
return 2;
}
static void test_defenders_get_building_bonus(CuTest * tc)
{
- unit *du, *au;
- region *r;
- building * bld;
- fighter *df, *af;
- battle *b;
- side *ds, *as;
- int diff;
- troop dt, at;
- building_type * btype;
+ unit *du, *au;
+ region *r;
+ building * bld;
+ fighter *df, *af;
+ battle *b;
+ side *ds, *as;
+ int diff;
+ troop dt, at;
+ building_type * btype;
- test_cleanup();
- test_create_world();
- r = findregion(0, 0);
- btype = bt_get_or_create("castle");
- btype->protection = &add_two;
- bld = test_create_building(r, btype);
- bld->size = 10;
+ test_cleanup();
+ test_create_world();
+ r = findregion(0, 0);
+ btype = bt_get_or_create("castle");
+ btype->protection = &add_two;
+ bld = test_create_building(r, btype);
+ bld->size = 10;
- du = test_create_unit(test_create_faction(rc_find("human")), r);
- au = test_create_unit(test_create_faction(rc_find("human")), r);
- u_set_building(du, bld);
+ du = test_create_unit(test_create_faction(NULL), r);
+ au = test_create_unit(test_create_faction(NULL), r);
+ u_set_building(du, bld);
- b = make_battle(r);
- ds = make_side(b, du->faction, 0, 0, 0);
- df = make_fighter(b, du, ds, false);
- as = make_side(b, au->faction, 0, 0, 0);
- af = make_fighter(b, au, as, true);
+ b = make_battle(r);
+ ds = make_side(b, du->faction, 0, 0, 0);
+ df = make_fighter(b, du, ds, false);
+ as = make_side(b, au->faction, 0, 0, 0);
+ af = make_fighter(b, au, as, true);
- CuAssertPtrEquals(tc, bld, df->building);
- CuAssertPtrEquals(tc, 0, af->building);
+ CuAssertPtrEquals(tc, bld, df->building);
+ CuAssertPtrEquals(tc, 0, af->building);
- dt.fighter = df;
- dt.index = 0;
- at.fighter = af;
- at.index = 0;
+ dt.fighter = df;
+ dt.index = 0;
+ at.fighter = af;
+ at.index = 0;
- diff = skilldiff(at, dt, 0);
- CuAssertIntEquals(tc, -2, diff);
+ diff = skilldiff(at, dt, 0);
+ CuAssertIntEquals(tc, -2, diff);
- diff = skilldiff(dt, at, 0);
- CuAssertIntEquals(tc, 0, diff);
+ diff = skilldiff(dt, at, 0);
+ CuAssertIntEquals(tc, 0, diff);
free_battle(b);
test_cleanup();
}
static void test_attackers_get_no_building_bonus(CuTest * tc)
{
- unit *au;
- region *r;
- building * bld;
- fighter *af;
- battle *b;
- side *as;
- building_type * btype;
+ unit *au;
+ region *r;
+ building * bld;
+ fighter *af;
+ battle *b;
+ side *as;
+ building_type * btype;
- test_cleanup();
- test_create_world();
- r = findregion(0, 0);
- btype = bt_get_or_create("castle");
- btype->protection = &add_two;
- bld = test_create_building(r, btype);
- bld->size = 10;
+ test_cleanup();
+ test_create_world();
+ r = findregion(0, 0);
+ btype = bt_get_or_create("castle");
+ btype->protection = &add_two;
+ bld = test_create_building(r, btype);
+ bld->size = 10;
- au = test_create_unit(test_create_faction(rc_find("human")), r);
- u_set_building(au, bld);
+ au = test_create_unit(test_create_faction(NULL), r);
+ u_set_building(au, bld);
- b = make_battle(r);
- as = make_side(b, au->faction, 0, 0, 0);
- af = make_fighter(b, au, as, true);
+ b = make_battle(r);
+ as = make_side(b, au->faction, 0, 0, 0);
+ af = make_fighter(b, au, as, true);
- CuAssertPtrEquals(tc, 0, af->building);
+ CuAssertPtrEquals(tc, 0, af->building);
free_battle(b);
test_cleanup();
}
static void test_building_bonus_respects_size(CuTest * tc)
{
- unit *au, *du;
- region *r;
- building * bld;
- fighter *af, *df;
- battle *b;
- side *as;
- building_type * btype;
- faction * f;
+ unit *au, *du;
+ region *r;
+ building * bld;
+ fighter *af, *df;
+ battle *b;
+ side *as;
+ building_type * btype;
+ faction * f;
- test_cleanup();
- test_create_world();
- r = findregion(0, 0);
- btype = bt_get_or_create("castle");
- btype->protection = &add_two;
- bld = test_create_building(r, btype);
- bld->size = 10;
+ test_cleanup();
+ test_create_world();
+ r = findregion(0, 0);
+ btype = bt_get_or_create("castle");
+ btype->protection = &add_two;
+ bld = test_create_building(r, btype);
+ bld->size = 10;
- f = test_create_faction(rc_find("human"));
- au = test_create_unit(f, r);
- scale_number(au, 9);
- u_set_building(au, bld);
- du = test_create_unit(f, r);
- u_set_building(du, bld);
- scale_number(du, 2);
+ f = test_create_faction(NULL);
+ au = test_create_unit(f, r);
+ scale_number(au, 9);
+ u_set_building(au, bld);
+ du = test_create_unit(f, r);
+ u_set_building(du, bld);
+ scale_number(du, 2);
- b = make_battle(r);
- as = make_side(b, au->faction, 0, 0, 0);
- af = make_fighter(b, au, as, false);
- df = make_fighter(b, du, as, false);
+ b = make_battle(r);
+ as = make_side(b, au->faction, 0, 0, 0);
+ af = make_fighter(b, au, as, false);
+ df = make_fighter(b, du, as, false);
- CuAssertPtrEquals(tc, bld, af->building);
- CuAssertPtrEquals(tc, 0, df->building);
+ CuAssertPtrEquals(tc, bld, af->building);
+ CuAssertPtrEquals(tc, 0, df->building);
free_battle(b);
test_cleanup();
}
+static void test_building_defence_bonus(CuTest * tc)
+{
+ unit *au;
+ region *r;
+ building * bld;
+ building_type * btype;
+ faction * f;
+ int def;
+ test_cleanup();
+ test_create_world();
+ r = findregion(0, 0);
+ register_buildings();
+ btype = bt_get_or_create("castle");
+ btype->protection = (int (*)(struct building *, struct unit *, building_bonus))get_function("building_protection");
+ btype->construction->defense_bonus = 3;
+ bld = test_create_building(r, btype);
+ bld->size = 1;
+
+ f = test_create_faction(NULL);
+ au = test_create_unit(f, r);
+ scale_number(au, 1);
+ u_set_building(au, bld);
+
+ def = btype->protection(bld, au, DEFENSE_BONUS);
+ CuAssertIntEquals(tc, 3, def);
+ test_cleanup();
+}
+
CuSuite *get_battle_suite(void)
{
- CuSuite *suite = CuSuiteNew();
- SUITE_ADD_TEST(suite, test_make_fighter);
- SUITE_ADD_TEST(suite, test_defenders_get_building_bonus);
- SUITE_ADD_TEST(suite, test_attackers_get_no_building_bonus);
- SUITE_ADD_TEST(suite, test_building_bonus_respects_size);
- return suite;
+ CuSuite *suite = CuSuiteNew();
+ SUITE_ADD_TEST(suite, test_make_fighter);
+ SUITE_ADD_TEST(suite, test_defenders_get_building_bonus);
+ SUITE_ADD_TEST(suite, test_attackers_get_no_building_bonus);
+ SUITE_ADD_TEST(suite, test_building_bonus_respects_size);
+ SUITE_ADD_TEST(suite, test_building_defence_bonus);
+ return suite;
}
diff --git a/src/bind_config.c b/src/bind_config.c
index 35f04eaa6..e40055ee6 100644
--- a/src/bind_config.c
+++ b/src/bind_config.c
@@ -32,6 +32,7 @@ int config_parse(const char *json)
if (conf) {
json_config(conf);
cJSON_Delete(conf);
+ init_locales();
return 0;
} else {
int line;
diff --git a/src/bind_tolua.c b/src/bind_tolua.c
index 26e536f9c..c6df54a10 100644
--- a/src/bind_tolua.c
+++ b/src/bind_tolua.c
@@ -1,3 +1,4 @@
+#include
#pragma warning(push)
#pragma warning(disable: 4100)
#include "config.pkg.c"
diff --git a/src/bindings.c b/src/bindings.c
index 6021339fd..58779bc0a 100755
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -193,7 +193,7 @@ static int tolua_translate(lua_State * L)
const char *lang = tolua_tostring(L, 2, 0);
struct locale *loc = lang ? get_locale(lang) : default_locale;
if (loc) {
- str = locale_string(loc, str);
+ str = LOC(loc, str);
tolua_pushstring(L, str);
return 1;
}
diff --git a/src/buildno.h b/src/buildno.h
index 07fcd6b87..d2eaeffee 100644
--- a/src/buildno.h
+++ b/src/buildno.h
@@ -1,3 +1,3 @@
#define VERSION_MAJOR 3
-#define VERSION_MINOR 4
-#define VERSION_BUILD 695
+#define VERSION_MINOR 5
+#define VERSION_BUILD 697
diff --git a/src/callback.c b/src/callback.c
index c2d178819..9d76f30c8 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -1,4 +1,3 @@
-#include
#include
#include "callback.h"
#include
diff --git a/src/creport.c b/src/creport.c
index 0bfe10033..7d0963165 100644
--- a/src/creport.c
+++ b/src/creport.c
@@ -92,7 +92,7 @@ static const char *crtag(const char *key)
static const struct locale *lang = NULL;
if (!lang)
lang = get_locale(TAG_LOCALE);
- return locale_string(lang, key);
+ return LOC(lang, key);
}
#else
#define crtag(x) (x)
@@ -274,7 +274,7 @@ cr_output_curses(FILE * F, const faction * viewer, const void *obj, objtype_t ty
fputs("EFFECTS\n", F);
}
fprintf(F, "\"%d %s\"\n", data->value, translate(key,
- locale_string(default_locale, key)));
+ LOC(default_locale, key)));
}
}
a = a->next;
@@ -331,7 +331,7 @@ static int cr_resource(variant var, char *buffer, const void *userdata)
if (r) {
const char *key = resourcename(r, 0);
sprintf(buffer, "\"%s\"",
- translate(key, locale_string(report->locale, key)));
+ translate(key, LOC(report->locale, key)));
return 0;
}
return -1;
@@ -343,7 +343,7 @@ static int cr_race(variant var, char *buffer, const void *userdata)
const struct race *rc = (const race *)var.v;
const char *key = rc_name_s(rc, NAME_SINGULAR);
sprintf(buffer, "\"%s\"",
- translate(key, locale_string(report->locale, key)));
+ translate(key, LOC(report->locale, key)));
return 0;
}
@@ -649,7 +649,7 @@ const faction * f, const region * r)
if (sh->display && sh->display[0])
fprintf(F, "\"%s\";Beschr\n", sh->display);
fprintf(F, "\"%s\";Typ\n", translate(sh->type->_name,
- locale_string(f->locale, sh->type->_name)));
+ LOC(f->locale, sh->type->_name)));
fprintf(F, "%d;Groesse\n", sh->size);
if (sh->damage) {
int percent =
@@ -839,20 +839,20 @@ static void cr_output_unit(FILE * F, const region * r, const faction * f,
if (u->faction == f && fval(u_race(u), RCF_SHAPESHIFTANY)) {
const char *zRace = rc_name_s(u_race(u), NAME_PLURAL);
fprintf(F, "\"%s\";wahrerTyp\n",
- translate(zRace, locale_string(f->locale, zRace)));
+ translate(zRace, LOC(f->locale, zRace)));
}
}
else {
const race *irace = u_irace(u);
const char *zRace = rc_name_s(irace, NAME_PLURAL);
fprintf(F, "\"%s\";Typ\n",
- translate(zRace, locale_string(f->locale, zRace)));
+ translate(zRace, LOC(f->locale, zRace)));
if (u->faction == f && irace != u_race(u)) {
assert(skill_enabled(SK_STEALTH)
|| !"we're resetting this on load, so.. ircase should never be used");
zRace = rc_name_s(u_race(u), NAME_PLURAL);
fprintf(F, "\"%s\";wahrerTyp\n",
- translate(zRace, locale_string(f->locale, zRace)));
+ translate(zRace, LOC(f->locale, zRace)));
}
}
@@ -902,7 +902,7 @@ static void cr_output_unit(FILE * F, const region * r, const faction * f,
c = hp_status(u);
if (c && *c && (u->faction == f || omniscient(f))) {
fprintf(F, "\"%s\";hp\n", translate(c,
- locale_string(u->faction->locale, c)));
+ LOC(u->faction->locale, c)));
}
if (fval(u, UFL_HERO)) {
fputs("1;hero\n", F);
@@ -998,8 +998,7 @@ static void cr_output_unit(FILE * F, const region * r, const faction * f,
pr = 1;
fputs("GEGENSTAENDE\n", F);
}
- fprintf(F, "%d;%s\n", in, translate(ic, locale_string(f->locale,
- ic)));
+ fprintf(F, "%d;%s\n", in, translate(ic, LOC(f->locale, ic)));
}
cr_output_curses(F, f, u, TYP_UNIT);
@@ -1294,8 +1293,7 @@ static void cr_output_region(FILE * F, report_context * ctx, seen_region * sr)
}
tname = terrain_name(r);
- fprintf(F, "\"%s\";Terrain\n", translate(tname, locale_string(f->locale,
- tname)));
+ fprintf(F, "\"%s\";Terrain\n", translate(tname, LOC(f->locale, tname)));
if (sr->mode != see_unit)
fprintf(F, "\"%s\";visibility\n", visibility[sr->mode]);
if (sr->mode == see_neighbour) {
@@ -1359,12 +1357,12 @@ static void cr_output_region(FILE * F, report_context * ctx, seen_region * sr)
if (lux) {
const char *ch = resourcename(lux->rtype, 0);
fprintf(F, "%d;%s\n", 1, translate(ch,
- locale_string(f->locale, ch)));
+ LOC(f->locale, ch)));
}
if (herb) {
const char *ch = resourcename(herb->rtype, 0);
fprintf(F, "%d;%s\n", 1, translate(ch,
- locale_string(f->locale, ch)));
+ LOC(f->locale, ch)));
}
}
}
@@ -1376,7 +1374,7 @@ static void cr_output_region(FILE * F, report_context * ctx, seen_region * sr)
fprintf(F, "%d;%s\n", (dmd->value
? dmd->value * dmd->type->price
: -dmd->type->price),
- translate(ch, locale_string(f->locale, ch)));
+ translate(ch, LOC(f->locale, ch)));
dmd = dmd->next;
}
}
@@ -1491,7 +1489,7 @@ report_computer(const char *filename, report_context * ctx, const char *charset)
faction *f = ctx->f;
const char *prefix;
region *r;
- const char *mailto = locale_string(f->locale, "mailto");
+ const char *mailto = LOC(f->locale, "mailto");
const attrib *a;
seen_region *sr = NULL;
#if SCORE_MODULE
@@ -1530,7 +1528,7 @@ report_computer(const char *filename, report_context * ctx, const char *charset)
fprintf(F, "%d.%d.%d;Build\n", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD);
if (mailto != NULL) {
fprintf(F, "\"%s\";mailto\n", mailto);
- fprintf(F, "\"%s\";mailcmd\n", locale_string(f->locale, "mailcmd"));
+ fprintf(F, "\"%s\";mailcmd\n", LOC(f->locale, "mailcmd"));
}
show_alliances_cr(F, f);
@@ -1651,8 +1649,7 @@ report_computer(const char *filename, report_context * ctx, const char *charset)
continue;
ch = resourcename(ptype->itype->rtype, 0);
fprintf(F, "TRANK %d\n", hashstring(ch));
- fprintf(F, "\"%s\";Name\n", translate(ch, locale_string(f->locale,
- ch)));
+ fprintf(F, "\"%s\";Name\n", translate(ch, LOC(f->locale, ch)));
fprintf(F, "%d;Stufe\n", ptype->level);
if (description == NULL) {
@@ -1669,8 +1666,7 @@ report_computer(const char *filename, report_context * ctx, const char *charset)
while (m->number) {
ch = resourcename(m->rtype, 0);
- fprintf(F, "\"%s\"\n", translate(ch, locale_string(f->locale,
- ch)));
+ fprintf(F, "\"%s\"\n", translate(ch, LOC(f->locale, ch)));
m++;
}
}
diff --git a/src/direction.c b/src/direction.c
index c74434fb3..66603663c 100644
--- a/src/direction.c
+++ b/src/direction.c
@@ -43,7 +43,7 @@ void init_directions(struct locale *lang) {
register_special_direction(lang, "vortex");
for (i = 0; dirs[i].direction != NODIRECTION; ++i) {
- const char *str = locale_string(lang, dirs[i].name);
+ const char *str = locale_string(lang, dirs[i].name, false);
if (str) {
variant token;
token.i = dirs[i].direction;
diff --git a/src/eressea.c b/src/eressea.c
index 120ad573b..4bfe59daf 100755
--- a/src/eressea.c
+++ b/src/eressea.c
@@ -20,12 +20,14 @@
#include
#include
#include
+#include
#include "chaos.h"
#include "report.h"
#include "items.h"
#include "creport.h"
#include "names.h"
#include "wormhole.h"
+#include "spells.h"
void game_done(void)
{
@@ -55,6 +57,8 @@ void game_init(void)
register_nr();
register_cr();
+ register_races();
+ register_spells();
register_names();
register_resources();
register_buildings();
diff --git a/src/give.test.c b/src/give.test.c
index f4d929c31..5437dfa5b 100644
--- a/src/give.test.c
+++ b/src/give.test.c
@@ -106,7 +106,7 @@ static void test_give_men_none(CuTest * tc) {
env.f2 = env.f1 = test_create_faction(0);
setup_give(&env);
msg = give_men(0, env.src, env.dst, NULL);
- CuAssertStrEquals(tc, "error96", (const char *)msg->parameters[3].v);
+ CuAssertStrEquals(tc, "error96", test_get_messagetype(msg));
CuAssertIntEquals(tc, 1, env.dst->number);
CuAssertIntEquals(tc, 1, env.src->number);
test_cleanup();
@@ -137,7 +137,7 @@ static void test_give_men_requires_contact(CuTest * tc) {
env.f2 = test_create_faction(0);
setup_give(&env);
msg = give_men(1, env.src, env.dst, NULL);
- CuAssertStrEquals(tc, "feedback_no_contact", (const char *)msg->parameters[3].v);
+ CuAssertStrEquals(tc, "feedback_no_contact", test_get_messagetype(msg));
CuAssertIntEquals(tc, 1, env.dst->number);
CuAssertIntEquals(tc, 1, env.src->number);
test_cleanup();
@@ -150,7 +150,7 @@ static void test_give_men_not_to_self(CuTest * tc) {
env.f2 = env.f1 = test_create_faction(0);
setup_give(&env);
msg = give_men(1, env.src, env.src, NULL);
- CuAssertStrEquals(tc, "error10", (const char *)msg->parameters[3].v);
+ CuAssertStrEquals(tc, "error10", test_get_messagetype(msg));
CuAssertIntEquals(tc, 1, env.src->number);
test_cleanup();
}
diff --git a/src/helpers.c b/src/helpers.c
index 5f0b3a12d..e37865be5 100644
--- a/src/helpers.c
+++ b/src/helpers.c
@@ -388,32 +388,6 @@ static void lua_agebuilding(building * b)
}
}
-static int lua_building_protection(building * b, unit * u)
-{
- lua_State *L = (lua_State *) global.vm_state;
- const char *fname = "building_protection";
- int result = 0;
-
- lua_getglobal(L, fname);
- if (lua_isfunction(L, -1)) {
- tolua_pushusertype(L, (void *)b, TOLUA_CAST "building");
- tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
-
- if (lua_pcall(L, 2, 1, 0) != 0) {
- const char *error = lua_tostring(L, -1);
- log_error("building_protection(%s, %s) calling '%s': %s.\n", buildingname(b), unitname(u), fname, error);
- lua_pop(L, 1);
- } else {
- result = (int)lua_tonumber(L, -1);
- lua_pop(L, 1);
- }
- } else {
- log_error("building_protection(%s, %s) calling '%s': not a function.\n", buildingname(b), unitname(u), fname);
- lua_pop(L, 1);
- }
- return result;
-}
-
static double lua_building_taxes(building * b, int level)
{
lua_State *L = (lua_State *) global.vm_state;
@@ -545,8 +519,6 @@ void register_tolua_helpers(void)
at_register(&at_direction);
at_register(&at_building_action);
- register_function((pf_generic) & lua_building_protection,
- TOLUA_CAST "lua_building_protection");
register_function((pf_generic) & lua_building_taxes,
TOLUA_CAST "lua_building_taxes");
register_function((pf_generic) & lua_agebuilding,
diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt
index 9dbb73b49..bc2c20418 100644
--- a/src/kernel/CMakeLists.txt
+++ b/src/kernel/CMakeLists.txt
@@ -21,6 +21,7 @@ race.test.c
spellbook.test.c
curse.test.c
jsonconf.test.c
+messages.test.c
)
SET(_FILES
diff --git a/src/kernel/build.h b/src/kernel/build.h
index 4e3bbedaa..8bd41e409 100644
--- a/src/kernel/build.h
+++ b/src/kernel/build.h
@@ -45,6 +45,9 @@ extern "C" {
int maxsize; /* maximum size of this type */
int reqsize; /* size of object using up 1 set of requirement. */
+ int defense_bonus; /* protection bonus (defense) during combat */
+ int close_combat_bonus; /* close combat attack bonus*/
+ int ranged_bonus; /* ranged attack bonus */
requirement *materials; /* material req'd to build one object */
const struct building_type *btype;
/* building type required to make this thing */
diff --git a/src/kernel/building.c b/src/kernel/building.c
index bd3463744..f74976661 100644
--- a/src/kernel/building.c
+++ b/src/kernel/building.c
@@ -305,7 +305,7 @@ const building_type *findbuildingtype(const char *name,
for (qi = 0, ql = buildingtypes; ql; ql_advance(&ql, &qi, 1)) {
building_type *btype = (building_type *)ql_get(ql, qi);
- const char *n = locale_string(lang, btype->_name);
+ const char *n = LOC(lang, btype->_name);
type.v = (void *)btype;
addtoken(&bn->names, n, type);
}
@@ -316,12 +316,32 @@ const building_type *findbuildingtype(const char *name,
return (const building_type *)type.v;
}
-static int eressea_building_protection(building * b, unit * u)
+static int building_protection(building * b, unit * u, building_bonus bonus)
{
- int beff = buildingeffsize(b, false) - 1;
- /* -1 because the tradepost has no protection value */
- return beff;
+ int i = 0;
+ int bsize = buildingeffsize(b, false);
+ const construction *cons = b->type->construction;
+ if (!cons) {
+ return 0;
+ }
+
+ for (i = 0; i < bsize; i++)
+ {
+ cons = cons->improvement;
+ }
+
+ switch (bonus)
+ {
+ case DEFENSE_BONUS:
+ return cons->defense_bonus;
+ case CLOSE_COMBAT_ATTACK_BONUS:
+ return cons->close_combat_bonus;
+ case RANGED_ATTACK_BONUS:
+ return cons->ranged_bonus;
+ default:
+ return 0;
+ }
}
static int meropis_building_protection(building * b, unit * u)
@@ -331,8 +351,8 @@ static int meropis_building_protection(building * b, unit * u)
void register_buildings(void)
{
- register_function((pf_generic)& eressea_building_protection,
- "eressea_building_protection");
+ register_function((pf_generic)& building_protection,
+ "building_protection");
register_function((pf_generic)& meropis_building_protection,
"meropis_building_protection");
register_function((pf_generic)& init_smithy, "init_smithy");
diff --git a/src/kernel/building.h b/src/kernel/building.h
index cf80de84f..98db1bd2f 100644
--- a/src/kernel/building.h
+++ b/src/kernel/building.h
@@ -48,6 +48,12 @@ extern "C" {
#define BTF_ONEPERTURN 0x80 /* one one sizepoint can be added per turn */
#define BTF_NAMECHANGE 0x100 /* name and description can be changed more than once */
+ typedef enum {
+ DEFENSE_BONUS,
+ CLOSE_COMBAT_ATTACK_BONUS,
+ RANGED_ATTACK_BONUS,
+ } building_bonus;
+
typedef struct building_type {
char *_name;
@@ -66,7 +72,7 @@ extern "C" {
const struct building * b, int size);
void (*init) (struct building_type *);
void (*age) (struct building *);
- int (*protection) (struct building *, struct unit *);
+ int (*protection) (struct building *, struct unit *, building_bonus);
double (*taxes) (const struct building *, int size);
struct attrib *attribs;
} building_type;
diff --git a/src/kernel/config.c b/src/kernel/config.c
index 8cf3e0805..413f4d253 100644
--- a/src/kernel/config.c
+++ b/src/kernel/config.c
@@ -144,7 +144,7 @@ bool ExpensiveMigrants(void)
gamecookie = global.cookie;
value = get_param_int(global.parameters, "study.expensivemigrants", 0);
}
- return value;
+ return value!=0;
}
/** Specifies automatic alliance modes.
@@ -932,12 +932,12 @@ void init_terrains_translation(const struct locale *lang) {
variant var;
const char *name;
var.v = (void *)terrain;
- name = LOC(lang, terrain->_name);
+ name = locale_string(lang, terrain->_name, false);
if (name) {
addtoken(tokens, name, var);
}
else {
- log_error("no translation for terrain %s in locale %s", terrain->_name, locale_name(lang));
+ log_debug("no translation for terrain %s in locale %s", terrain->_name, locale_name(lang));
}
}
}
@@ -951,12 +951,12 @@ void init_options_translation(const struct locale * lang) {
variant var;
var.i = i;
if (options[i]) {
- const char *name = LOC(lang, options[i]);
+ const char *name = locale_string(lang, options[i], false);
if (name) {
addtoken(tokens, name, var);
}
else {
- log_error("no translation for OPTION %s in locale %s", options[i], locale_name(lang));
+ log_debug("no translation for OPTION %s in locale %s", options[i], locale_name(lang));
}
}
}
@@ -1006,9 +1006,9 @@ void init_locale(struct locale *lang)
for (rc = races; rc; rc = rc->next) {
const char *name;
var.v = (void *)rc;
- name = LOC(lang, rc_name_s(rc, NAME_PLURAL));
+ name = locale_string(lang, rc_name_s(rc, NAME_PLURAL), false);
if (name) addtoken(tokens, name, var);
- name = LOC(lang, rc_name_s(rc, NAME_SINGULAR));
+ name = locale_string(lang, rc_name_s(rc, NAME_SINGULAR), false);
if (name) addtoken(tokens, name, var);
}
@@ -1693,7 +1693,7 @@ order *default_order(const struct locale *lang)
assert(i < MAXLOCALES);
result = defaults[i];
if (!result && usedefault) {
- const char * str = locale_string(lang, "defaultorder");
+ const char * str = LOC(lang, "defaultorder");
if (str) {
result = defaults[i] = parse_order(str, lang);
}
diff --git a/src/kernel/curse.test.c b/src/kernel/curse.test.c
index a7f88218b..ecee69c24 100644
--- a/src/kernel/curse.test.c
+++ b/src/kernel/curse.test.c
@@ -2,7 +2,11 @@
#include "types.h"
#include "curse.h"
+#include
+#include
#include
+#include
+#include
#include
@@ -22,9 +26,70 @@ static void test_curse(CuTest * tc)
CuAssertPtrEquals(tc, NULL, result);
}
+typedef struct {
+ curse *c;
+ region *r;
+ unit *u;
+} curse_fixture;
+
+static void setup_curse(curse_fixture *fix, const char *name) {
+ test_cleanup();
+ fix->r = test_create_region(0, 0, NULL);
+ fix->u = test_create_unit(test_create_faction(NULL), fix->r);
+ fix->c = create_curse(fix->u, &fix->r->attribs, ct_find(name), 1.0, 1, 1.0, 0);
+}
+
+static void test_magicstreet(CuTest *tc) {
+ curse_fixture fix;
+ message *msg;
+ setup_curse(&fix, "magicstreet");
+ fix.c->duration = 2;
+ msg = fix.c->type->curseinfo(fix.r, TYP_REGION, fix.c, 0);
+ CuAssertStrEquals(tc, "curseinfo::magicstreet", test_get_messagetype(msg));
+ msg_release(msg);
+ test_cleanup();
+}
+
+static void test_magicstreet_warning(CuTest *tc) {
+ curse_fixture fix;
+ message *msg;
+ setup_curse(&fix, "magicstreet");
+ fix.c->duration = 1;
+ msg = fix.c->type->curseinfo(fix.r, TYP_REGION, fix.c, 0);
+ CuAssertStrEquals(tc, "curseinfo::magicstreetwarn", test_get_messagetype(msg));
+ msg_release(msg);
+ test_cleanup();
+}
+
+static void test_good_dreams(CuTest *tc) {
+ curse_fixture fix;
+ message *msg;
+ setup_curse(&fix, "gbdream");
+ fix.c->effect = 1;
+ msg = fix.c->type->curseinfo(fix.r, TYP_REGION, fix.c, 0);
+ CuAssertStrEquals(tc, "curseinfo::gooddream", test_get_messagetype(msg));
+ msg_release(msg);
+ test_cleanup();
+}
+
+static void test_bad_dreams(CuTest *tc) {
+ curse_fixture fix;
+ message *msg;
+ setup_curse(&fix, "gbdream");
+ fix.c->effect = -1;
+ msg = fix.c->type->curseinfo(fix.r, TYP_REGION, fix.c, 0);
+ CuAssertStrEquals(tc, "curseinfo::baddream", test_get_messagetype(msg));
+ msg_release(msg);
+ test_cleanup();
+}
+
CuSuite *get_curse_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_curse);
+ SUITE_ADD_TEST(suite, test_magicstreet);
+ SUITE_ADD_TEST(suite, test_magicstreet_warning);
+ SUITE_ADD_TEST(suite, test_good_dreams);
+ SUITE_ADD_TEST(suite, test_bad_dreams);
return suite;
}
diff --git a/src/kernel/faction.c b/src/kernel/faction.c
index db317ee8f..b17db7b3d 100755
--- a/src/kernel/faction.c
+++ b/src/kernel/faction.c
@@ -280,9 +280,7 @@ unit *addplayer(region * r, faction * f)
bool checkpasswd(const faction * f, const char *passwd)
{
- if (passwd && unicode_utf8_strcasecmp(f->passw, passwd) == 0)
- return true;
- return false;
+ return (passwd && unicode_utf8_strcasecmp(f->passw, passwd) == 0);
}
variant read_faction_reference(struct storage * store)
diff --git a/src/kernel/faction.h b/src/kernel/faction.h
index 20c6f9785..31705860f 100644
--- a/src/kernel/faction.h
+++ b/src/kernel/faction.h
@@ -82,7 +82,6 @@ typedef struct faction {
int no_units;
struct ally *allies;
struct group *groups;
- bool alive; /* enno: sollte ein flag werden */
int nregions;
int money;
#if SCORE_MODULE
@@ -104,6 +103,7 @@ typedef struct faction {
struct item *items; /* items this faction can claim */
struct seen_region **seen;
struct quicklist *seen_factions;
+ bool alive; /* enno: sollte ein flag werden */
} faction;
extern struct faction *factions;
diff --git a/src/kernel/item.c b/src/kernel/item.c
index b09ea1b67..584f8b0a2 100644
--- a/src/kernel/item.c
+++ b/src/kernel/item.c
@@ -1045,7 +1045,7 @@ static int add_resourcename_cb(const void * match, const void * key, size_t keyl
cb_get_kv(match, &rtype, sizeof(rtype));
for (i = 0; i != 2; ++i) {
char buffer[128];
- const char * name = locale_string(lang, resourcename(rtype, (i==0) ? 0 : NMF_PLURAL));
+ const char * name = LOC(lang, resourcename(rtype, (i == 0) ? 0 : NMF_PLURAL));
if (name && transliterate(buffer, sizeof(buffer), name)) {
size_t len = strlen(buffer);
@@ -1096,7 +1096,7 @@ static int add_itemname_cb(const void * match, const void * key, size_t keylen,
int i;
for (i = 0; i != 2; ++i) {
char buffer[128];
- const char * name = locale_string(lang, resourcename(rtype, (i == 0) ? 0 : NMF_PLURAL));
+ const char * name = LOC(lang, resourcename(rtype, (i == 0) ? 0 : NMF_PLURAL));
if (name && transliterate(buffer, sizeof(buffer), name)) {
size_t len = strlen(buffer);
diff --git a/src/kernel/item.h b/src/kernel/item.h
index d40e2d90c..9f2513134 100644
--- a/src/kernel/item.h
+++ b/src/kernel/item.h
@@ -193,11 +193,11 @@ extern "C" {
typedef struct armor_type {
const item_type *itype;
+ unsigned int flags;
double penalty;
double magres;
int prot;
float projectile; /* chance, dass ein projektil abprallt */
- unsigned int flags;
} armor_type;
#define WTF_NONE 0x00
@@ -223,7 +223,7 @@ extern "C" {
int reload; /* time to reload this weapon */
weapon_mod *modifiers;
/* --- functions --- */
- bool(*attack) (const struct troop *, const struct weapon_type *,
+ bool(*attack) (const struct troop *, const struct weapon_type *,
int *deaths);
} weapon_type;
diff --git a/src/kernel/item.test.c b/src/kernel/item.test.c
index dcb7ca878..981edf641 100644
--- a/src/kernel/item.test.c
+++ b/src/kernel/item.test.c
@@ -143,6 +143,27 @@ static void test_fix_demand(CuTest *tc) {
test_cleanup();
}
+static void test_core_resources(CuTest *tc) {
+ resource_type * rtype;
+ test_cleanup();
+ init_resources();
+ CuAssertPtrNotNull(tc, rtype = rt_find("money"));
+ CuAssertPtrNotNull(tc, rtype->itype);
+ CuAssertPtrNotNull(tc, rtype->uchange);
+ CuAssertPtrNotNull(tc, rtype->itype->give);
+ CuAssertPtrNotNull(tc, rtype = rt_find("peasant"));
+ CuAssertPtrEquals(tc, 0, rtype->itype);
+ CuAssertPtrNotNull(tc, rtype = rt_find("person"));
+ CuAssertPtrEquals(tc, 0, rtype->itype);
+ CuAssertPtrNotNull(tc, rtype = rt_find("permaura"));
+ CuAssertPtrEquals(tc, 0, rtype->itype);
+ CuAssertPtrNotNull(tc, rtype = rt_find("hp"));
+ CuAssertPtrEquals(tc, 0, rtype->itype);
+ CuAssertPtrNotNull(tc, rtype = rt_find("aura"));
+ CuAssertPtrEquals(tc, 0, rtype->itype);
+ test_cleanup();
+}
+
CuSuite *get_item_suite(void)
{
CuSuite *suite = CuSuiteNew();
@@ -153,5 +174,6 @@ CuSuite *get_item_suite(void)
SUITE_ADD_TEST(suite, test_finditemtype);
SUITE_ADD_TEST(suite, test_findresourcetype);
SUITE_ADD_TEST(suite, test_fix_demand);
+ SUITE_ADD_TEST(suite, test_core_resources);
return suite;
}
diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c
index 500c952ec..4c8c8a0fc 100644
--- a/src/kernel/jsonconf.test.c
+++ b/src/kernel/jsonconf.test.c
@@ -373,8 +373,8 @@ static void test_skills(CuTest * tc)
CuAssertIntEquals(tc, SK_CROSSBOW, get_skill("kreuz", lang));
CuAssertIntEquals(tc, SK_ALCHEMY, get_skill("alchemie", lang));
- CuAssertStrEquals(tc, "ALCHEMIE", locale_string(lang, "skill::alchemy"));
- CuAssertStrEquals(tc, "ARMBRUST", locale_string(lang, "skill::crossbow"));
+ CuAssertStrEquals(tc, "ALCHEMIE", LOC(lang, "skill::alchemy"));
+ CuAssertStrEquals(tc, "ARMBRUST", LOC(lang, "skill::crossbow"));
test_cleanup();
}
@@ -396,8 +396,8 @@ static void test_keywords(CuTest * tc)
CuAssertIntEquals(tc, K_STUDY, get_keyword("lerne", lang));
CuAssertIntEquals(tc, K_MOVE, get_keyword("nach", lang));
- CuAssertStrEquals(tc, "LERNEN", locale_string(lang, "keyword::study"));
- CuAssertStrEquals(tc, "NACH", locale_string(lang, "keyword::move"));
+ CuAssertStrEquals(tc, "LERNEN", LOC(lang, "keyword::study"));
+ CuAssertStrEquals(tc, "NACH", LOC(lang, "keyword::move"));
test_cleanup();
}
@@ -413,10 +413,10 @@ static void test_strings(CuTest * tc)
test_cleanup();
lang = get_or_create_locale("de");
CuAssertPtrNotNull(tc, lang);
- CuAssertPtrEquals(tc, NULL, (void *)locale_string(lang, "move"));
+ CuAssertPtrEquals(tc, NULL, (void *)LOC(lang, "move"));
json_config(json);
- CuAssertStrEquals(tc, "NACH", locale_string(lang, "move"));
- CuAssertStrEquals(tc, "LERNEN", locale_string(lang, "study"));
+ CuAssertStrEquals(tc, "NACH", LOC(lang, "move"));
+ CuAssertStrEquals(tc, "LERNEN", LOC(lang, "study"));
}
static void test_infinitive_from_config(CuTest *tc) {
diff --git a/src/kernel/messages.c b/src/kernel/messages.c
index f7297f832..46329d66b 100644
--- a/src/kernel/messages.c
+++ b/src/kernel/messages.c
@@ -17,7 +17,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#include
-#include
#include "messages.h"
/* kernel includes */
@@ -140,7 +139,7 @@ struct message *msg_feedback(const struct unit *u, struct order *ord,
message *msg_message(const char *name, const char *sig, ...)
/* msg_message("oops_error", "unit region command", u, r, cmd) */
{
- va_list marker;
+ va_list vargs;
const message_type *mtype = mt_find(name);
char paramname[64];
const char *ic = sig;
@@ -155,7 +154,7 @@ message *msg_message(const char *name, const char *sig, ...)
return NULL;
}
- va_start(marker, sig);
+ va_start(vargs, sig);
while (*ic && !isalnum(*ic))
ic++;
while (*ic) {
@@ -172,9 +171,9 @@ message *msg_message(const char *name, const char *sig, ...)
}
if (i != mtype->nparameters) {
if (mtype->types[i]->vtype == VAR_VOIDPTR) {
- args[i].v = va_arg(marker, void *);
+ args[i].v = va_arg(vargs, void *);
} else if (mtype->types[i]->vtype == VAR_INT) {
- args[i].i = va_arg(marker, int);
+ args[i].i = va_arg(vargs, int);
} else {
assert(!"unknown variant type");
}
@@ -185,7 +184,7 @@ message *msg_message(const char *name, const char *sig, ...)
while (*ic && !isalnum(*ic))
ic++;
}
- va_end(marker);
+ va_end(vargs);
return msg_create(mtype, args);
}
diff --git a/src/kernel/messages.h b/src/kernel/messages.h
index 83c0f2613..b9c07b0c9 100644
--- a/src/kernel/messages.h
+++ b/src/kernel/messages.h
@@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
extern "C" {
#endif
+#include
#include
struct faction;
diff --git a/src/kernel/messages.test.c b/src/kernel/messages.test.c
new file mode 100644
index 000000000..e237ab8de
--- /dev/null
+++ b/src/kernel/messages.test.c
@@ -0,0 +1,44 @@
+#include
+#include "messages.h"
+
+#include
+#include
+
+void test_missing_message(CuTest *tc) {
+ message *msg;
+ msg = msg_message("unknown", "unit", NULL);
+ CuAssertPtrNotNull(tc, msg);
+ CuAssertPtrNotNull(tc, msg->type);
+ CuAssertStrEquals(tc, msg->type->name, "missing_message");
+ msg_release(msg);
+}
+
+void test_message(CuTest *tc) {
+ message *msg;
+// const char * args[] = { }
+ message_type *mtype = mt_new("custom", NULL);
+ mt_register(mtype);
+ CuAssertPtrEquals(tc, mtype, (void *)mt_find("custom"));
+ CuAssertIntEquals(tc, 0, mtype->nparameters);
+ CuAssertPtrEquals(tc, NULL, (void *)mtype->pnames);
+ CuAssertPtrEquals(tc, NULL, (void *)mtype->types);
+ msg = msg_message("custom", "");
+ CuAssertPtrNotNull(tc, msg);
+ CuAssertIntEquals(tc, 1, msg->refcount);
+ CuAssertPtrEquals(tc, NULL, msg->parameters);
+ CuAssertPtrEquals(tc, mtype, (void *)msg->type);
+
+ CuAssertPtrEquals(tc, msg, msg_addref(msg));
+ CuAssertIntEquals(tc, 2, msg->refcount);
+ msg_release(msg);
+ CuAssertIntEquals(tc, 1, msg->refcount);
+ msg_release(msg);
+ test_cleanup();
+}
+
+CuSuite *get_messages_suite(void) {
+ CuSuite *suite = CuSuiteNew();
+ SUITE_ADD_TEST(suite, test_missing_message);
+ SUITE_ADD_TEST(suite, test_message);
+ return suite;
+}
\ No newline at end of file
diff --git a/src/kernel/order.c b/src/kernel/order.c
index 83171ddfe..ed0c1642b 100644
--- a/src/kernel/order.c
+++ b/src/kernel/order.c
@@ -388,8 +388,6 @@ order *parse_order(const char *s, const struct locale * lang)
bool is_repeated(const order * ord)
{
keyword_t kwd = ORD_KEYWORD(ord);
- int result = 0;
-
switch (kwd) {
case K_CAST:
case K_BUY:
@@ -411,13 +409,12 @@ bool is_repeated(const order * ord)
case K_MAKE:
case K_LOOT:
case K_DESTROY:
- result = 1;
- break;
+ return true;
default:
- result = 0;
+ break;
}
- return result;
+ return false;
}
/**
@@ -431,7 +428,6 @@ bool is_repeated(const order * ord)
bool is_exclusive(const order * ord)
{
keyword_t kwd = ORD_KEYWORD(ord);
- int result = 0;
switch (kwd) {
case K_MOVE:
@@ -452,13 +448,12 @@ bool is_exclusive(const order * ord)
case K_MAKE:
case K_LOOT:
case K_DESTROY:
- result = 1;
- break;
+ return true;
default:
- result = 0;
+ break;
}
- return result;
+ return false;
}
/**
diff --git a/src/kernel/race.c b/src/kernel/race.c
index 14541346e..2919fdb8b 100644
--- a/src/kernel/race.c
+++ b/src/kernel/race.c
@@ -177,7 +177,11 @@ race *rc_get_or_create(const char *zName)
rc = (race *)calloc(sizeof(race), 1);
rc->hitpoints = 1;
+ rc->weight = PERSON_WEIGHT;
+ rc->capacity = 540;
rc->recruit_multi = 1.0F;
+ rc->regaura = 1.0F;
+ rc->speed = 1.0F;
if (strchr(zName, ' ') != NULL) {
log_error("race '%s' has an invalid name. remove spaces\n", zName);
assert(strchr(zName, ' ') == NULL);
diff --git a/src/kernel/race.h b/src/kernel/race.h
index 6882af222..fa61e4cec 100644
--- a/src/kernel/race.h
+++ b/src/kernel/race.h
@@ -140,14 +140,13 @@ extern "C" {
int at_bonus; /* Verändert den Angriffsskill (default: 0) */
int df_bonus; /* Verändert den Verteidigungskill (default: 0) */
const struct spell *precombatspell;
- struct att attack[10];
- signed char bonus[MAXSKILLS];
signed char *study_speed; /* study-speed-bonus in points/turn (0=30 Tage) */
- bool __remove_me_nonplayer;
int flags;
int battle_flags;
int ec_flags;
race_t oldfamiliars[MAXMAGIETYP];
+ struct att attack[10];
+ signed char bonus[MAXSKILLS];
const char *(*generate_name) (const struct unit *);
const char *(*describe) (const struct unit *, const struct locale *);
diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c
index 31c058bea..ef4fc640e 100644
--- a/src/kernel/race.test.c
+++ b/src/kernel/race.test.c
@@ -8,17 +8,43 @@
#include
static void test_rc_name(CuTest *tc) {
- struct race *rc = test_create_race("human");
+ struct race *rc;
+ test_cleanup();
+ rc = test_create_race("human");
CuAssertStrEquals(tc, "race::human", rc_name_s(rc, NAME_SINGULAR));
CuAssertStrEquals(tc, "race::human_p", rc_name_s(rc, NAME_PLURAL));
CuAssertStrEquals(tc, "race::human_d", rc_name_s(rc, NAME_DEFINITIVE));
CuAssertStrEquals(tc, "race::human_x", rc_name_s(rc, NAME_CATEGORY));
+ test_cleanup();
+}
+
+static void test_rc_defaults(CuTest *tc) {
+ struct race *rc;
+ test_cleanup();
+ rc = rc_get_or_create("human");
+ CuAssertStrEquals(tc, "human", rc->_name);
+ CuAssertDblEquals(tc, 0.0, rc->magres, 0.0);
+ CuAssertDblEquals(tc, 0.0, rc->maxaura, 0.0);
+ CuAssertDblEquals(tc, 1.0, rc->recruit_multi, 0.0);
+ CuAssertDblEquals(tc, 1.0, rc->regaura, 0.0);
+ CuAssertDblEquals(tc, 1.0, rc->speed, 0.0);
+ CuAssertIntEquals(tc, 0, rc->flags);
+ CuAssertIntEquals(tc, 0, rc->recruitcost);
+ CuAssertIntEquals(tc, 0, rc->maintenance);
+ CuAssertIntEquals(tc, 540, rc->capacity);
+ CuAssertIntEquals(tc, 1, rc->hitpoints);
+ CuAssertIntEquals(tc, 0, rc->armor);
+ CuAssertIntEquals(tc, 0, rc->at_bonus);
+ CuAssertIntEquals(tc, 0, rc->df_bonus);
+ CuAssertIntEquals(tc, PERSON_WEIGHT, rc->weight);
+ test_cleanup();
}
CuSuite *get_race_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_rc_name);
+ SUITE_ADD_TEST(suite, test_rc_defaults);
return suite;
}
diff --git a/src/kernel/save.c b/src/kernel/save.c
index 95a85cf3b..059f960ad 100644
--- a/src/kernel/save.c
+++ b/src/kernel/save.c
@@ -1568,7 +1568,7 @@ int readgame(const char *filename, int backup)
sh->type = st_find(name);
if (sh->type == NULL) {
/* old datafiles */
- sh->type = st_find((const char *)locale_string(default_locale, name));
+ sh->type = st_find((const char *)LOC(default_locale, name));
}
assert(sh->type || !"ship_type not registered!");
diff --git a/src/kernel/ship.c b/src/kernel/ship.c
index 0cf04918c..19f3fa743 100644
--- a/src/kernel/ship.c
+++ b/src/kernel/ship.c
@@ -76,7 +76,7 @@ const ship_type *findshiptype(const char *name, const struct locale *lang)
for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) {
ship_type *stype = (ship_type *)ql_get(ql, qi);
variant var2;
- const char *n = locale_string(lang, stype->_name);
+ const char *n = LOC(lang, stype->_name);
var2.v = (void *)stype;
addtoken(&sn->names, n, var2);
}
diff --git a/src/kernel/unit.c b/src/kernel/unit.c
index e837e6b15..348a46437 100644
--- a/src/kernel/unit.c
+++ b/src/kernel/unit.c
@@ -1725,21 +1725,23 @@ int unit_max_hp(const unit * u)
get_param_int(global.parameters, "rules.stamina", STAMINA_AFFECTS_HP);
}
h = u_race(u)->hitpoints;
- if (heal_ct == NULL)
- heal_ct = ct_find("healingzone");
if (rules_stamina & 1) {
p = pow(effskill(u, SK_STAMINA) / 2.0, 1.5) * 0.2;
h += (int)(h * p + 0.5);
}
+
/* der healing curse veraendert die maximalen hp */
- if (heal_ct) {
- curse *c = get_curse(u->region->attribs, heal_ct);
- if (c) {
- h = (int)(h * (1.0 + (curse_geteffect(c) / 100)));
+ if (u->region) {
+ if (heal_ct == NULL)
+ heal_ct = ct_find("healingzone");
+ if (heal_ct) {
+ curse *c = get_curse(u->region->attribs, heal_ct);
+ if (c) {
+ h = (int)(h * (1.0 + (curse_geteffect(c) / 100)));
+ }
}
}
-
return h;
}
@@ -1883,7 +1885,7 @@ char *write_unitname(const unit * u, char *buffer, size_t size)
} else {
const struct locale * lang = u->faction ? u->faction->locale : default_locale;
const char * name = rc_name_s(u->_race, u->number == 1 ? NAME_SINGULAR : NAME_PLURAL);
- slprintf(buffer, size, "%s (%s)", locale_string(lang, name), itoa36(u->no));
+ slprintf(buffer, size, "%s (%s)", LOC(lang, name), itoa36(u->no));
}
buffer[size - 1] = 0;
return buffer;
@@ -1902,8 +1904,8 @@ bool unit_name_equals_race(const unit *u) {
rc_name(u->_race, NAME_SINGULAR, sing, sizeof(sing));
rc_name(u->_race, NAME_PLURAL, plur, sizeof(plur));
if (strcmp(u->name, sing) == 0 || strcmp(u->name, plur) == 0 ||
- strcmp(u->name, locale_string(lang, sing)) == 0 ||
- strcmp(u->name, locale_string(lang, plur)) == 0) {
+ strcmp(u->name, LOC(lang, sing)) == 0 ||
+ strcmp(u->name, LOC(lang, plur)) == 0) {
return true;
}
}
diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c
index 77d2270e1..5061abb07 100644
--- a/src/kernel/xmlreader.c
+++ b/src/kernel/xmlreader.c
@@ -167,7 +167,10 @@ construction ** consPtr)
con->maxsize = xml_ivalue(node, "maxsize", -1);
con->minskill = xml_ivalue(node, "minskill", -1);
con->reqsize = xml_ivalue(node, "reqsize", -1);
-
+ con->defense_bonus = xml_ivalue(node, "defense_bonus", 0);
+ con->close_combat_bonus = xml_ivalue(node, "close_combat_bonus", 0);
+ con->ranged_bonus = xml_ivalue(node, "ranged_bonus", 0);
+
propValue = xmlGetProp(node, BAD_CAST "building");
if (propValue != NULL) {
con->btype = bt_get_or_create((const char *)propValue);
@@ -297,7 +300,7 @@ static int parse_buildings(xmlDocPtr doc)
btype->age = (void(*)(struct building *))fun;
}
else if (strcmp((const char *)propValue, "protection") == 0) {
- btype->protection = (int(*)(struct building *, struct unit *))fun;
+ btype->protection = (int(*)(struct building *, struct unit *, building_bonus))fun;
}
else if (strcmp((const char *)propValue, "taxes") == 0) {
btype->taxes = (double(*)(const struct building *, int))fun;
@@ -1623,22 +1626,22 @@ static int parse_races(xmlDocPtr doc)
rc->def_damage = _strdup((const char *)propValue);
xmlFree(propValue);
- rc->magres = (float)xml_fvalue(node, "magres", 0.0);
- rc->maxaura = (float)xml_fvalue(node, "maxaura", 0.0);
- rc->regaura = (float)xml_fvalue(node, "regaura", 1.0);
- rc->recruitcost = xml_ivalue(node, "recruitcost", 0);
- rc->maintenance = xml_ivalue(node, "maintenance", 0);
- rc->weight = xml_ivalue(node, "weight", PERSON_WEIGHT);
- rc->capacity = xml_ivalue(node, "capacity", 540);
- rc->speed = (float)xml_fvalue(node, "speed", 1.0F);
- rc->hitpoints = xml_ivalue(node, "hp", 0);
- rc->armor = (char)xml_ivalue(node, "ac", 0);
+ rc->magres = (float)xml_fvalue(node, "magres", rc->magres);
+ rc->maxaura = (float)xml_fvalue(node, "maxaura", rc->maxaura);
+ rc->regaura = (float)xml_fvalue(node, "regaura", rc->regaura);
+ rc->recruitcost = xml_ivalue(node, "recruitcost", rc->recruitcost);
+ rc->maintenance = xml_ivalue(node, "maintenance", rc->maintenance);
+ rc->weight = xml_ivalue(node, "weight", rc->weight);
+ rc->capacity = xml_ivalue(node, "capacity", rc->capacity);
+ rc->speed = (float)xml_fvalue(node, "speed", rc->speed);
+ rc->hitpoints = xml_ivalue(node, "hp", rc->hitpoints);
+ rc->armor = (char)xml_ivalue(node, "ac", rc->armor);
study_speed_base = xml_ivalue(node, "studyspeed", 0);
rc->at_default = (char)xml_ivalue(node, "unarmedattack", -2);
rc->df_default = (char)xml_ivalue(node, "unarmeddefense", -2);
- rc->at_bonus = (char)xml_ivalue(node, "attackmodifier", 0);
- rc->df_bonus = (char)xml_ivalue(node, "defensemodifier", 0);
+ rc->at_bonus = (char)xml_ivalue(node, "attackmodifier", rc->at_bonus);
+ rc->df_bonus = (char)xml_ivalue(node, "defensemodifier", rc->df_bonus);
if (!xml_bvalue(node, "playerrace", false))
rc->flags |= RCF_NPC;
diff --git a/src/laws.c b/src/laws.c
index 0c01f0471..693df8f5c 100755
--- a/src/laws.c
+++ b/src/laws.c
@@ -968,7 +968,7 @@ static bool CheckOverload(void)
if (value < 0) {
value = get_param_int(global.parameters, "rules.check_overload", 0);
}
- return value;
+ return value!=0;
}
int enter_ship(unit * u, struct order *ord, int id, bool report)
@@ -1411,11 +1411,11 @@ static void init_prefixnames(void)
for (key = 0; race_prefixes[key]; ++key) {
variant var;
const char *pname =
- locale_string(lang, mkname("prefix", race_prefixes[key]));
+ LOC(lang, mkname("prefix", race_prefixes[key]));
if (findtoken(in->names, pname, &var) == E_TOK_NOMATCH || var.i != key) {
var.i = key;
addtoken(&in->names, pname, var);
- addtoken(&in->names, locale_string(lang, mkname("prefix",
+ addtoken(&in->names, LOC(lang, mkname("prefix",
race_prefixes[key])), var);
}
}
@@ -2209,7 +2209,7 @@ static bool display_item(faction * f, unit * u, const item_type * itype)
info = locale_getstring(f->locale, key);
if (info == NULL) {
- info = locale_string(f->locale, mkname("iteminfo", "no_info"));
+ info = LOC(f->locale, mkname("iteminfo", "no_info"));
}
ADDMSG(&f->msgs, msg_message("displayitem", "weight item description",
itype->weight, itype->rtype, info));
@@ -2261,7 +2261,7 @@ static bool display_race(faction * f, unit * u, const race * rc)
key = mkname("raceinfo", rc->_name);
info = locale_getstring(f->locale, key);
if (info == NULL) {
- info = locale_string(f->locale, mkname("raceinfo", "no_info"));
+ info = LOC(f->locale, mkname("raceinfo", "no_info"));
}
bytes = (int)strlcpy(bufp, info, size);
@@ -4269,6 +4269,36 @@ static void enter_2(region * r)
do_enter(r, 1);
}
+static bool help_enter(unit *uo, unit *u) {
+ return uo->faction == u->faction || alliedunit(uo, u->faction, HELP_GUARD);
+}
+
+void force_leave(region *r) {
+ unit *u;
+ for (u = r->units; u; u = u->next) {
+ unit *uo = NULL;
+ if (u->building) {
+ uo = building_owner(u->building);
+ }
+ if (u->ship && r->land) {
+ uo = ship_owner(u->ship);
+ }
+ if (uo && !help_enter(uo, u)) {
+ message *msg = NULL;
+ if (u->building) {
+ msg = msg_message("force_leave_building", "unit owner building", u, uo, u->building);
+ }
+ else {
+ msg = msg_message("force_leave_ship", "unit owner ship", u, uo, u->ship);
+ }
+ if (msg) {
+ ADDMSG(&u->faction->msgs, msg);
+ }
+ leave(u, false);
+ }
+ }
+}
+
static void maintain_buildings_1(region * r)
{
maintain_buildings(r, false);
@@ -4306,15 +4336,15 @@ void init_processor(void)
int p;
p = 10;
- add_proc_global(p, &new_units, "Neue Einheiten erschaffen");
+ add_proc_global(p, new_units, "Neue Einheiten erschaffen");
p += 10;
add_proc_unit(p, update_long_order, "Langen Befehl aktualisieren");
add_proc_order(p, K_BANNER, banner_cmd, 0, NULL);
- add_proc_order(p, K_EMAIL, &email_cmd, 0, NULL);
- add_proc_order(p, K_PASSWORD, &password_cmd, 0, NULL);
- add_proc_order(p, K_SEND, &send_cmd, 0, NULL);
- add_proc_order(p, K_GROUP, &group_cmd, 0, NULL);
+ add_proc_order(p, K_EMAIL, email_cmd, 0, NULL);
+ add_proc_order(p, K_PASSWORD, password_cmd, 0, NULL);
+ add_proc_order(p, K_SEND, send_cmd, 0, NULL);
+ add_proc_order(p, K_GROUP, group_cmd, 0, NULL);
p += 10;
add_proc_order(p, K_QUIT, &quit_cmd, 0, NULL);
@@ -4331,46 +4361,47 @@ void init_processor(void)
if (get_param_int(global.parameters, "rules.alliances", 0) == 1) {
p += 10;
- add_proc_global(p, &alliance_cmd, NULL);
+ add_proc_global(p, alliance_cmd, NULL);
}
p += 10;
add_proc_region(p, do_contact, "Kontaktieren");
- add_proc_order(p, K_MAIL, &mail_cmd, 0, "Botschaften");
+ add_proc_order(p, K_MAIL, mail_cmd, 0, "Botschaften");
p += 10; /* all claims must be done before we can USE */
add_proc_region(p, &enter_1, "Betreten (1. Versuch)"); /* for GIVE CONTROL */
- add_proc_order(p, K_USE, &use_cmd, 0, "Benutzen");
+ add_proc_order(p, K_USE, use_cmd, 0, "Benutzen");
p += 10; /* in case it has any effects on alliance victories */
- add_proc_order(p, K_GIVE, &give_control_cmd, 0, "GIB KOMMANDO");
+ add_proc_order(p, K_GIVE, give_control_cmd, 0, "GIB KOMMANDO");
p += 10; /* in case it has any effects on alliance victories */
- add_proc_order(p, K_LEAVE, &leave_cmd, 0, "Verlassen");
+ add_proc_order(p, K_LEAVE, leave_cmd, 0, "Verlassen");
p += 10;
- add_proc_region(p, &enter_1, "Betreten (2. Versuch)"); /* to allow a buildingowner to enter the castle pre combat */
+ add_proc_region(p, enter_1, "Betreten (2. Versuch)"); /* to allow a buildingowner to enter the castle pre combat */
p += 10;
- add_proc_region(p, &do_battle, "Attackieren");
+ add_proc_region(p, do_battle, "Attackieren");
if (!keyword_disabled(K_BESIEGE)) {
p += 10;
- add_proc_region(p, &do_siege, "Belagern");
+ add_proc_region(p, do_siege, "Belagern");
}
p += 10; /* can't allow reserve before siege (weapons) */
- add_proc_region(p, &enter_1, "Betreten (3. Versuch)"); /* to claim a castle after a victory and to be able to DESTROY it in the same turn */
+ add_proc_region(p, enter_1, "Betreten (3. Versuch)"); /* to claim a castle after a victory and to be able to DESTROY it in the same turn */
if (get_param_int(global.parameters, "rules.reserve.twophase", 0)) {
add_proc_order(p, K_RESERVE, &reserve_self, 0, "RESERVE (self)");
p += 10;
}
add_proc_order(p, K_RESERVE, &reserve_cmd, 0, "RESERVE (all)");
add_proc_order(p, K_CLAIM, &claim_cmd, 0, NULL);
- add_proc_unit(p, &follow_unit, "Folge auf Einheiten setzen");
+ add_proc_unit(p, follow_unit, "Folge auf Einheiten setzen");
p += 10; /* rest rng again before economics */
- add_proc_region(p, &economics, "Zerstoeren, Geben, Rekrutieren, Vergessen");
+ add_proc_region(p, force_leave, "kick non-allies out of buildings/ships");
+ add_proc_region(p, economics, "Zerstoeren, Geben, Rekrutieren, Vergessen");
add_proc_order(p, K_PROMOTION, &promotion_cmd, 0, "Heldenbefoerderung");
p += 10;
diff --git a/src/laws.h b/src/laws.h
index f5209ac3f..27232982b 100755
--- a/src/laws.h
+++ b/src/laws.h
@@ -105,6 +105,7 @@ extern "C" {
bool seefaction(const struct faction *f, const struct region *r,
const struct unit *u, int modifier);
int armedmen(const struct unit *u, bool siege_weapons);
+ void force_leave(struct region *r);
#ifdef __cplusplus
diff --git a/src/laws.test.c b/src/laws.test.c
index 9f91ffc77..2b2f0bb9f 100644
--- a/src/laws.test.c
+++ b/src/laws.test.c
@@ -15,6 +15,7 @@
#include
#include
+#include
#include
#include
@@ -226,6 +227,74 @@ static void test_display_cmd(CuTest *tc) {
test_cleanup();
}
+static void test_force_leave_buildings(CuTest *tc) {
+ ally *al;
+ region *r;
+ unit *u1, *u2, *u3;
+ building * b;
+ message *msg;
+ test_cleanup();
+ r = test_create_region(0, 0, test_create_terrain("plain", LAND_REGION));
+ u1 = test_create_unit(test_create_faction(NULL), r);
+ u2 = test_create_unit(u1->faction, r);
+ u3 = test_create_unit(test_create_faction(NULL), r);
+ b = test_create_building(r, NULL);
+ u_set_building(u1, b);
+ building_set_owner(u1);
+ u_set_building(u2, b);
+ u_set_building(u3, b);
+ force_leave(r);
+ CuAssertPtrEquals_Msg(tc, "owner should not be forecd to leave", b, u1->building);
+ CuAssertPtrEquals_Msg(tc, "same faction should not be forced to leave", b, u2->building);
+ CuAssertPtrEquals_Msg(tc, "non-allies should be forced to leave", NULL, u3->building);
+ msg = test_get_last_message(u3->faction->msgs);
+ CuAssertStrEquals(tc, "force_leave_building", test_get_messagetype(msg));
+
+ u_set_building(u3, b);
+ al = ally_add(&u1->faction->allies, u3->faction);
+ al->status = HELP_GUARD;
+ force_leave(r);
+ CuAssertPtrEquals_Msg(tc, "allies should not be forced to leave", b, u3->building);
+ test_cleanup();
+}
+
+static void test_force_leave_ships(CuTest *tc) {
+ region *r;
+ unit *u1, *u2;
+ ship *sh;
+ message *msg;
+ test_cleanup();
+ r = test_create_region(0, 0, test_create_terrain("plain", LAND_REGION));
+ u1 = test_create_unit(test_create_faction(NULL), r);
+ u2 = test_create_unit(test_create_faction(NULL), r);
+ sh = test_create_ship(r, NULL);
+ u_set_ship(u1, sh);
+ u_set_ship(u2, sh);
+ ship_set_owner(u1);
+ force_leave(r);
+ CuAssertPtrEquals_Msg(tc, "non-allies should be forced to leave", NULL, u2->ship);
+ msg = test_get_last_message(u2->faction->msgs);
+ CuAssertStrEquals(tc, "force_leave_ship", test_get_messagetype(msg));
+ test_cleanup();
+}
+
+static void test_force_leave_ships_on_ocean(CuTest *tc) {
+ region *r;
+ unit *u1, *u2;
+ ship *sh;
+ test_cleanup();
+ r = test_create_region(0, 0, test_create_terrain("ocean", SEA_REGION));
+ u1 = test_create_unit(test_create_faction(NULL), r);
+ u2 = test_create_unit(test_create_faction(NULL), r);
+ sh = test_create_ship(r, NULL);
+ u_set_ship(u1, sh);
+ u_set_ship(u2, sh);
+ ship_set_owner(u1);
+ force_leave(r);
+ CuAssertPtrEquals_Msg(tc, "no forcing out of ships on oceans", sh, u2->ship);
+ test_cleanup();
+}
+
static void test_fishing_feeds_2_people(CuTest * tc)
{
const resource_type *rtype;
@@ -649,5 +718,9 @@ CuSuite *get_laws_suite(void)
SUITE_ADD_TEST(suite, test_enter_building);
SUITE_ADD_TEST(suite, test_enter_ship);
SUITE_ADD_TEST(suite, test_display_cmd);
+ SUITE_ADD_TEST(suite, test_force_leave_buildings);
+ SUITE_ADD_TEST(suite, test_force_leave_ships);
+ SUITE_ADD_TEST(suite, test_force_leave_ships_on_ocean);
+
return suite;
}
diff --git a/src/lighthouse.c b/src/lighthouse.c
index f05687e69..da9d489dd 100644
--- a/src/lighthouse.c
+++ b/src/lighthouse.c
@@ -104,9 +104,9 @@ bool check_leuchtturm(region * r, faction * f)
{
attrib *a;
- if (!fval(r->terrain, SEA_REGION))
+ if (!fval(r->terrain, SEA_REGION)) {
return false;
-
+ }
for (a = a_find(r->attribs, &at_lighthouse); a && a->type == &at_lighthouse;
a = a->next) {
building *b = (building *)a->data.v;
@@ -141,7 +141,7 @@ bool check_leuchtturm(region * r, faction * f)
}
else {
/* E3A rule: no perception req'd */
- return maxd;
+ return true;
}
}
}
diff --git a/src/main.c b/src/main.c
index 6868d36e9..316c3c206 100644
--- a/src/main.c
+++ b/src/main.c
@@ -304,8 +304,6 @@ int main(int argc, char **argv)
L = lua_init();
game_init();
- register_races();
- register_spells();
bind_monsters(L);
err = eressea_run(L, luafile);
if (err) {
diff --git a/src/names.c b/src/names.c
index 8f4ed75ce..650717792 100644
--- a/src/names.c
+++ b/src/names.c
@@ -275,7 +275,7 @@ static const char *dragon_name(const unit * u)
if (anzahl > 1) {
const char *no_article = strchr((const char *)str, ' ');
assert(no_article);
- /* TODO: GERMAN */
+ // TODO: localization
sprintf(name, "Die %sn von %s", no_article + 1, rname(u->region,
default_locale));
}
diff --git a/src/platform.h b/src/platform.h
index e83600fa2..64c369c0a 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -26,7 +26,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifdef _MSC_VER
# define VC_EXTRALEAN
# define WIN32_LEAN_AND_MEAN
+#pragma warning(push)
+#pragma warning(disable:4820 4255 4668)
# include
+# include
+#pragma warning(pop)
# undef MOUSE_MOVED
# define STDIO_CP 1252 /* log.c, convert to console character set */
# pragma warning (disable: 4201 4214 4514 4115 4711)
@@ -41,6 +45,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# pragma warning(disable: 4996)
/* is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' */
# pragma warning(disable: 4668)
+/* : bytes padding after data member */
+# pragma warning(disable: 4820)
/* warning C4100: was declared deprecated */
#ifndef _CRT_SECURE_NO_DEPRECATE
@@ -113,9 +119,5 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include
#endif
-#ifdef HAVE_IO_H
-#include
-#endif
-
#endif
diff --git a/src/report.c b/src/report.c
index 3500e938f..efdb80268 100644
--- a/src/report.c
+++ b/src/report.c
@@ -1025,7 +1025,7 @@ static void describe(FILE * F, const seen_region * sr, faction * f)
if (r->land->ownership) {
const char *str =
- locale_string(f->locale, mkname("morale", itoa10(r->land->morale)));
+ LOC(f->locale, mkname("morale", itoa10(r->land->morale)));
bytes = _snprintf(bufp, size, " %s", str);
if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER();
@@ -1100,6 +1100,7 @@ static void describe(FILE * F, const seen_region * sr, faction * f)
if (rule_region_owners()) {
const faction *owner = region_get_owner(r);
if (owner != NULL) {
+ // TODO: localization
bytes = _snprintf(bufp, size, " Die Region ist im Besitz von %s.",
factionname(owner));
if (wrptr(&bufp, &size, bytes) != 0)
@@ -1701,7 +1702,7 @@ show_allies(const faction * f, const ally * allies, char *buf, size_t size)
if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER();
if ((mode & HELP_ALL) == HELP_ALL) {
- bytes = (int)strlcpy(bufp, locale_string(f->locale, parameters[P_ANY]), size);
+ bytes = (int)strlcpy(bufp, LOC(f->locale, parameters[P_ANY]), size);
if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER();
}
@@ -1736,7 +1737,7 @@ show_allies(const faction * f, const ally * allies, char *buf, size_t size)
if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER();
}
- bytes = (int)strlcpy(bufp, locale_string(f->locale, parameters[p]), size);
+ bytes = (int)strlcpy(bufp, LOC(f->locale, parameters[p]), size);
if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER();
hh = 1;
diff --git a/src/reports.c b/src/reports.c
index e478a0200..f770bb655 100644
--- a/src/reports.c
+++ b/src/reports.c
@@ -150,7 +150,7 @@ const char **name, const char **basename, int *number, bool singular)
if (owner && owner->faction == viewer) {
if (name)
*name =
- locale_string(viewer->locale, resourcename(i->type->rtype,
+ LOC(viewer->locale, resourcename(i->type->rtype,
((i->number != 1 && !singular) ? GR_PLURAL : 0)));
if (basename)
*basename = resourcename(i->type->rtype, 0);
@@ -163,19 +163,19 @@ const char **name, const char **basename, int *number, bool singular)
*number = 1;
if (pp > 50000 && dragonrace(u_race(owner))) {
if (name)
- *name = locale_string(viewer->locale, "dragonhoard");
+ *name = LOC(viewer->locale, "dragonhoard");
if (basename)
*basename = "dragonhoard";
}
else if (pp > 5000) {
if (name)
- *name = locale_string(viewer->locale, "moneychest");
+ *name = LOC(viewer->locale, "moneychest");
if (basename)
*basename = "moneychest";
}
else if (pp > 500) {
if (name)
- *name = locale_string(viewer->locale, "moneybag");
+ *name = LOC(viewer->locale, "moneybag");
if (basename)
*basename = "moneybag";
}
@@ -191,7 +191,7 @@ const char **name, const char **basename, int *number, bool singular)
else {
if (name)
*name =
- locale_string(viewer->locale, resourcename(i->type->rtype,
+ LOC(viewer->locale, resourcename(i->type->rtype,
NMF_APPEARANCE | ((i->number != 1 && !singular) ? GR_PLURAL : 0)));
if (basename)
*basename = resourcename(i->type->rtype, NMF_APPEARANCE);
@@ -584,7 +584,7 @@ size_t size)
if (u->number && (u->faction == f || telepath_see || isbattle)) {
const char *c = hp_status(u);
- c = c ? locale_string(f->locale, c) : 0;
+ c = c ? LOC(f->locale, c) : 0;
bytes = (int)strlcpy(bufp, ", ", size);
if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER();
@@ -1956,7 +1956,7 @@ const char *trailinto(const region * r, const struct locale *lang)
if (r) {
const char *tname = terrain_name(r);
strcat(strcpy(ref, tname), "_trail");
- s = locale_string(lang, ref);
+ s = LOC(lang, ref);
if (s && *s) {
if (strstr(s, "%s"))
return s;
@@ -2003,7 +2003,7 @@ static void eval_localize(struct opstack **stack, const void *userdata)
const struct faction *f = (const struct faction *)userdata;
const struct locale *lang = f ? f->locale : default_locale;
const char *c = (const char *)opop_v(stack);
- c = locale_string(lang, c);
+ c = LOC(lang, c);
opush_v(stack, strcpy(balloc(strlen(c) + 1), c));
}
diff --git a/src/reports.test.c b/src/reports.test.c
index 5f9ce5ae0..060934ddb 100644
--- a/src/reports.test.c
+++ b/src/reports.test.c
@@ -1,3 +1,4 @@
+#include
#include
#include "reports.h"
diff --git a/src/skill.c b/src/skill.c
index d7ca2fee5..0df94a85f 100644
--- a/src/skill.c
+++ b/src/skill.c
@@ -66,7 +66,7 @@ void init_skills(const struct locale *lang) {
const char *skillname(skill_t sk, const struct locale *lang)
{
if (skill_disabled[sk]) return 0;
- return locale_string(lang, mkname("skill", skillnames[sk]));
+ return LOC(lang, mkname("skill", skillnames[sk]));
}
diff --git a/src/spells/regioncurse.c b/src/spells/regioncurse.c
index 71138ac2b..e0c6d8bf7 100644
--- a/src/spells/regioncurse.c
+++ b/src/spells/regioncurse.c
@@ -74,10 +74,11 @@ static message *cinfo_dreamcurse(const void *obj, objtype_t typ, const curse * c
unused_arg(obj);
assert(typ == TYP_REGION);
- if (curse_geteffect(c) > 0) {
+ if (c->effect > 0) {
return msg_message("curseinfo::gooddream", "id", c->no);
+ } else {
+ return msg_message("curseinfo::baddream", "id", c->no);
}
- return msg_message("curseinfo::baddream", "id", c->no);
}
static struct curse_type ct_gbdream = {
@@ -99,7 +100,7 @@ static message *cinfo_magicstreet(const void *obj, objtype_t typ, const curse *
assert(typ == TYP_REGION);
/* Warnung vor Auflösung */
- if (c->duration <= 2) {
+ if (c->duration >= 2) {
return msg_message("curseinfo::magicstreet", "id", c->no);
}
return msg_message("curseinfo::magicstreetwarn", "id", c->no);
diff --git a/src/test_eressea.c b/src/test_eressea.c
index d33f75fe8..ca6ebf604 100644
--- a/src/test_eressea.c
+++ b/src/test_eressea.c
@@ -1,4 +1,5 @@
#include
+#include
#include
#include
#include
@@ -30,7 +31,7 @@ int RunAllTests(void)
int fail_count, flags = log_flags;
log_flags = LOG_FLUSH | LOG_CPERROR;
- kernel_init();
+ game_init();
/* self-test */
RUN_TESTS(suite, tests);
@@ -70,6 +71,7 @@ int RunAllTests(void)
RUN_TESTS(suite, building);
RUN_TESTS(suite, spell);
RUN_TESTS(suite, ally);
+ RUN_TESTS(suite, messages);
/* gamecode */
RUN_TESTS(suite, battle);
RUN_TESTS(suite, economy);
@@ -86,7 +88,7 @@ int RunAllTests(void)
log_flags = flags;
fail_count = suite->failCount;
CuSuiteDelete(suite);
- kernel_done();
+ game_done();
return fail_count;
}
diff --git a/src/tests.c b/src/tests.c
index 79ff5ad38..83c6fe6fa 100644
--- a/src/tests.c
+++ b/src/tests.c
@@ -14,8 +14,10 @@
#include
#include
#include
+#include
#include
#include
+#include
#include
#include
@@ -81,14 +83,14 @@ test_create_terrain(const char * name, unsigned int flags)
building * test_create_building(region * r, const building_type * btype)
{
- building * b = new_building(btype?btype:bt_find("castle"), r, default_locale);
+ building * b = new_building(btype?btype:bt_get_or_create("castle"), r, default_locale);
b->size = b->type->maxsize>0?b->type->maxsize:1;
return b;
}
ship * test_create_ship(region * r, const ship_type * stype)
{
- ship * s = new_ship(stype?stype:st_find("boat"), r, default_locale);
+ ship * s = new_ship(stype?stype:st_get_or_create("boat"), r, default_locale);
s->size = s->type->construction?s->type->construction->maxsize:1;
return s;
}
@@ -192,3 +194,22 @@ void test_create_world(void)
test_create_shiptype("boat");
}
+message * test_get_last_message(message_list *msgs) {
+ struct mlist *iter = msgs->begin;
+ while (iter->next) {
+ iter = iter->next;
+ }
+ return iter->msg;
+}
+
+const char * test_get_messagetype(const message *msg) {
+ const char * name = msg->type->name;
+ if (strcmp(name, "missing_message") == 0) {
+ name = (const char *)msg->parameters[0].v;
+ }
+ else if (strcmp(name, "missing_feedback") == 0) {
+ name = (const char *)msg->parameters[3].v;
+ }
+ return name;
+}
+
diff --git a/src/tests.h b/src/tests.h
index 5a565076f..b83beab40 100644
--- a/src/tests.h
+++ b/src/tests.h
@@ -13,6 +13,8 @@ extern "C" {
struct faction;
struct building;
struct ship;
+ struct message;
+ struct message_list;
struct item_type;
struct building_type;
struct ship_type;
@@ -35,6 +37,8 @@ extern "C" {
int RunAllTests(void);
void test_translate_param(const struct locale *lang, param_t param, const char *text);
+ const char * test_get_messagetype(const struct message *msg);
+ struct message * test_get_last_message(struct message_list *mlist);
#ifdef __cplusplus
}
diff --git a/src/util/language.c b/src/util/language.c
index 564ade080..f23643b6d 100644
--- a/src/util/language.c
+++ b/src/util/language.c
@@ -123,7 +123,7 @@ const char *locale_getstring(const locale * lang, const char *key)
return NULL;
}
-const char *locale_string(const locale * lang, const char *key)
+const char *locale_string(const locale * lang, const char *key, bool warn)
{
assert(lang);
assert(key);
@@ -150,9 +150,11 @@ const char *locale_string(const locale * lang, const char *key)
if (find) {
return find->str;
}
- log_error("missing translation for \"%s\" in locale %s\n", key, lang->name);
+ if (warn) {
+ log_warning("missing translation for \"%s\" in locale %s\n", key, lang->name);
+ }
if (lang->fallback) {
- return locale_string(lang->fallback, key);
+ return locale_string(lang->fallback, key, warn);
}
}
return 0;
@@ -262,7 +264,7 @@ void init_translations(const struct locale *lang, int ut, const char * (*string_
tokens = get_translations(lang, ut);
for (i = 0; i != maxstrings; ++i) {
const char * s = string_cb(i);
- const char * key = s ? locale_string(lang, s) : 0;
+ const char * key = s ? locale_string(lang, s, false) : 0;
key = key ? key : s;
if (key) {
struct critbit_tree ** cb = (struct critbit_tree **)tokens;
diff --git a/src/util/language.h b/src/util/language.h
index d02a562ea..b6e22d5e5 100644
--- a/src/util/language.h
+++ b/src/util/language.h
@@ -18,6 +18,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifndef MY_LOCALE_H
#define MY_LOCALE_H
+
+#include
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -39,7 +42,7 @@ extern "C" {
const char *value);
extern const char *locale_getstring(const struct locale *lang,
const char *key);
- extern const char *locale_string(const struct locale *lang, const char *key); /* does fallback */
+ extern const char *locale_string(const struct locale *lang, const char *key, bool warn); /* does fallback */
extern unsigned int locale_index(const struct locale *lang);
extern const char *locale_name(const struct locale *lang);
@@ -48,7 +51,7 @@ extern "C" {
extern void make_locales(const char *str);
-#define LOC(lang, s) (lang?locale_string(lang, s):s)
+#define LOC(lang, s) (lang?locale_string(lang, s, true):s)
extern struct locale *default_locale;
extern struct locale *locales;
diff --git a/src/util/message.c b/src/util/message.c
index 7e9c1a9f0..79c1949f5 100644
--- a/src/util/message.c
+++ b/src/util/message.c
@@ -146,7 +146,7 @@ message *msg_create(const struct message_type *mtype, variant args[])
return NULL;
}
msg->type = mtype;
- msg->parameters = (variant *) calloc(mtype->nparameters, sizeof(variant));
+ msg->parameters = (variant *)(mtype->nparameters ? calloc(mtype->nparameters, sizeof(variant)) : NULL);
msg->refcount = 1;
for (i = 0; i != mtype->nparameters; ++i) {
msg->parameters[i] = copy_arg(mtype->types[i], args[i]);
diff --git a/src/util/unicode.test.c b/src/util/unicode.test.c
index 52392fda4..958b695e2 100644
--- a/src/util/unicode.test.c
+++ b/src/util/unicode.test.c
@@ -1,3 +1,4 @@
+#include
#include
#include "unicode.h"
#include
@@ -10,14 +11,14 @@ static void test_unicode_tolower(CuTest * tc)
CuAssertIntEquals(tc, 0, unicode_utf8_tolower(buffer, sizeof(buffer), "HeLlO W0Rld"));
CuAssertStrEquals(tc, "hello w0rld", buffer);
memset(buffer, 0, sizeof(buffer));
- buffer[5]='X';
+ buffer[5] = 'X';
CuAssertIntEquals(tc, ENOMEM, unicode_utf8_tolower(buffer, 5, "HeLlO W0Rld"));
CuAssertStrEquals(tc, "helloX", buffer);
}
CuSuite *get_unicode_suite(void)
{
- CuSuite *suite = CuSuiteNew();
- SUITE_ADD_TEST(suite, test_unicode_tolower);
- return suite;
+ CuSuite *suite = CuSuiteNew();
+ SUITE_ADD_TEST(suite, test_unicode_tolower);
+ return suite;
}
diff --git a/src/vortex.c b/src/vortex.c
index c9cea4649..79b37fb8a 100644
--- a/src/vortex.c
+++ b/src/vortex.c
@@ -1,4 +1,3 @@
-#include
#include
#include "vortex.h"
@@ -28,7 +27,7 @@ static dir_lookup *dir_name_lookup;
void register_special_direction(struct locale *lang, const char *name)
{
- const char *token = LOC(lang, name);
+ const char *token = locale_string(lang, name, false);
if (token) {
void **tokens = get_translations(lang, UT_SPECDIR);
@@ -47,7 +46,7 @@ void register_special_direction(struct locale *lang, const char *name)
}
}
else {
- log_error("no translation for spec_direction '%s' in locale '%s'\n", name, locale_name(lang));
+ log_debug("no translation for spec_direction '%s' in locale '%s'\n", name, locale_name(lang));
}
}