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)); } }