Merge branch 'develop' of github.com:ennorehling/eressea into develop

This commit is contained in:
Enno Rehling 2018-10-20 10:09:37 +02:00
commit c2570b1e58
211 changed files with 2356 additions and 1569 deletions

2
.gitignore vendored
View file

@ -25,6 +25,7 @@ ipch/
*.user
*~
*.pyc
*.bak
bin/
build*/
@ -36,6 +37,7 @@ Thumbs.db
*.cfg
*.cmd
tmp/
tests/orders.txt
tests/config.lua
tests/reports/
tests/data/185.dat

View file

@ -8,6 +8,7 @@ addons:
apt:
packages:
- libbsd-dev
- libdb-dev
- liblua5.1-dev
- libtolua-dev
- libncurses5-dev

2
clibs

@ -1 +1 @@
Subproject commit d86c8525489d7f11b7ba13e101bb59ecf160b871
Subproject commit 12139c7ce25e6731393f863e248ab16aa0578a3a

View file

@ -1,7 +1,7 @@
install(PROGRAMS create-orders backup-eressea run-turn send-zip-report
send-bz2-report compress.py compress.sh epasswd.py orders-process
process-orders.py accept-orders.py
checkpasswd.py sendreport.sh sendreports.sh orders-accept DESTINATION bin)
process-orders.py accept-orders.py getemail.py checkpasswd.py
sendreport.sh sendreports.sh orders-accept DESTINATION bin)
install(DIRECTORY cron/ DESTINATION bin USE_SOURCE_PERMISSIONS
FILES_MATCHING PATTERN "*.cron")

View file

@ -16,6 +16,7 @@ else
mv orders.dir "orders.dir.$TURN"
mkdir -p orders.dir
fi
rm -f "orders.$TURN"
find "orders.dir.$TURN" -maxdepth 1 -type f -printf "%T+\t%p\n" | sort | cut -f2 | while read -r
do
cat "$REPLY" >> "orders.$TURN"
@ -23,7 +24,7 @@ done
lockfile -r3 -l120 orders.queue.lock
if [ -e orders.queue ] ; then
mv orders.queue "orders.dir.$TURN/orders.queue"
mv orders.queue "orders.queue.bak.$TURN"
fi
rm -f orders.queue.lock

View file

@ -35,7 +35,7 @@ class EPasswd:
def __init__(self):
self.data = {}
def set_data(no, email, passwd):
def set_data(self, no, email, passwd):
lc_id = lower(no)
self.data[lc_id] = {}
self.data[lc_id]["id"] = no

22
process/getemail.py Executable file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env python
import sys, re
from epasswd import EPasswd
if len(sys.argv)<3:
sys.exit(-2)
filename=sys.argv[1]
myfaction=sys.argv[2]
pw_data = EPasswd()
try:
pw_data.load_database(filename)
except:
pw_data.load_file(filename)
if pw_data.fac_exists(myfaction):
email = pw_data.get_email(myfaction)
print(email)
sys.exit(0)
sys.exit(-1)

View file

@ -45,12 +45,8 @@ fi
bash "${FACTION}.sh" "$EMAIL" || reply "Unbekannte Partei $FACTION"
if [ -e "$ERESSEA/game-$GAME/eressea.db" ]; then
SQL="select email from faction f left join faction_data fd on fd.faction_id=f.id where f.game_id=$GAME AND fd.code='$FACTION' and fd.turn=(select max(turn) from faction_data fx where fx.faction_id=f.id)"
OWNER=$(sqlite3 "$ERESSEA/game-$GAME/eressea.db" "$SQL")
if [ ! -z "$OWNER" ]; then
echo "Der Report Deiner Partei wurde an ${EMAIL} gesandt." \
| mutt -s "Reportnachforderung Partei ${FACTION}" "$OWNER"
fi
OWNER=$(getfaction.py "$PWFILE" "$FACTION")
if [ ! -z "$OWNER" ]; then
echo "Der Report Deiner Partei wurde an ${EMAIL} gesandt." \
| mutt -s "Reportnachforderung Partei ${FACTION}" "$OWNER"
fi

View file

@ -22,11 +22,12 @@ exit $2 # otherwise
function build() {
assert_dir $SOURCE
cd $SOURCE
rm -rf crypto tolua
rm -rf tolua
git fetch || abort "failed to update source. do you have local changes?"
[ -z $1 ] || git checkout $1
git pull -q
git submodule update
s/cmake-init
s/build > /dev/null || abort "build failed."
}

View file

@ -31,8 +31,8 @@ cppcheck_tests() {
set -e
[ -z $BUILD ] && BUILD=Debug ; export BUILD
s/cmake-init
# cppcheck_tests
s/cmake-init --db=sqlite
s/build
cd process
make

View file

@ -1,3 +1,4 @@
-- Weltentor portal module
local tunnels = {}
local buildings = {}
@ -24,25 +25,15 @@ local function get_target(param)
end
local function tunnel_action(b, param)
local r = nil
if tonumber(param)~=nil then
r = get_region_by_id(tonumber(param))
end
local units = tunnel_travelers(b)
if units~=nil then
local rto = get_target(param)
if rto and units then
eressea.log.debug("Tunnel from " .. tostring(b) .. " [" .. param .. "]")
for key, u in pairs(units) do
local rto = r
if r==nil then
rto = get_target(param)
end
if rto~=nil then
u.region = rto
eressea.log.debug("teleported " .. tostring(u) .. " to " .. tostring(rto))
end
end
end
return 1 -- return 0 to destroy
end
function tunnels.init()

View file

@ -136,3 +136,15 @@ function test_familiar_lynx()
assert_equal(1, u:get_skill('magic'))
assert_equal(1, u:get_skill('perception'))
end
function test_bug_2480()
local r = region.create(0, 0, "plain")
local f = faction.create("human", "2480@eressea.de", "de")
local u1 = unit.create(f, r, 1)
local monster = unit.create(get_monsters(), r, 1, "wyrm")
u1.number = 30
u1.hp = u1.hp_max * u1.number
monster:add_order("ATTACK " .. itoa36(u1.id))
process_orders()
assert_equal(0, u1.number);
end

View file

@ -34,22 +34,18 @@ function test_build_watch()
local u = unit.create(f, r, 1)
u.number = 20
u:add_item("log", 20)
u:add_item("log", 30)
u.id = 42
u:set_skill("building", 1)
u:add_order("MACHE Wache")
process_orders()
assert_not_nil(u.building)
if 5 ~= u.building.size then
-- debug logging to find intermittent errors
for k,v in ipairs(f.messages) do
print(v)
end
end
-- stage two needs skill 2, this unit can only build a first stage:
assert_equal(5, u.building.size)
u:set_skill("building", 2)
u:clear_orders()
u:add_order("MACHE Wache " .. itoa36(u.building.id))
process_orders()
assert_not_nil(u.building)

View file

@ -1,52 +0,0 @@
-- create a fixed path to a specific region
local function create_path(from, to)
local param = tostring(to.uid)
local b = building.create(from, "portal")
b.name = "Weltentor"
b.size = 1
b:add_action("tunnel_action", param)
end
-- create a wonky tunnel wth more than one exit
local function create_tunnel(from, param)
local b = building.create(from, "portal")
b.name = "Weltentor"
b.size = 1
b:add_action("tunnel_action", param)
end
-- make a tunnel from the cursor to the first selected region
function mktunnel()
local from = gmtool.get_cursor()
local to = gmtool.get_selection()()
if to~=nil then
region.create(from.x, from.y, "glacier")
create_tunnel(from, to)
gmtool.select(to, 0)
gmtool.highlight(to, 1)
end
end
-- turn all selected regions into targets for a wonky tunnel ("tnnL")
function mkanchors()
for r in gmtool.get_selection() do
if not r:get_key("tnnL") then
r:set_key("tnnL", true)
if r:get_flag(0) then
-- RF_CHAOTIC gets removed
r:set_flag(0, false)
end
r:set_resource("peasant", r:get_resource("peasant") + 1)
end
end
end
-- region.create and prepare all hell-regions to become wonky gates
function mkgates()
for r in regions() do
if r.plane_id==0 and r.terrain=="hell" then
create_tunnel(r, "tnnL")
region.create(r.x, r.y, "glacier")
end
end
end

View file

@ -85,6 +85,11 @@ TOLUA_BINDING(eressea.pkg bind_eressea.h)
TOLUA_BINDING(settings.pkg kenel/config.h)
ENDIF()
set (PARSER_SRC
${DB_SRC}
${UTIL_SRC}
)
set (ERESSEA_SRC
vortex.c
academy.c
@ -104,7 +109,6 @@ set (ERESSEA_SRC
items.c
json.c
jsonconf.c
keyword.c
laws.c
lighthouse.c
magic.c
@ -113,6 +117,7 @@ set (ERESSEA_SRC
morale.c
move.c
names.c
orderdb.c
orderfile.c
piracy.c
prefix.c
@ -138,9 +143,11 @@ set (ERESSEA_SRC
${TRIGGERS_SRC}
${ATTRIBUTES_SRC}
${KERNEL_SRC}
${DB_SRC}
${UTIL_SRC}
)
)
set(CHECK_SRC
checker.c
)
set(SERVER_SRC
bind_building.c
@ -161,7 +168,7 @@ set(SERVER_SRC
console.c
helpers.c
main.c
)
)
if (CURSES_FOUND)
set (SERVER_SRC ${SERVER_SRC}
@ -176,24 +183,29 @@ if(NOT IWYU_PATH)
message(STATUS "Could not find the program include-what-you-use")
endif()
add_library(version STATIC ${VERSION_SRC})
add_library(game ${ERESSEA_SRC})
add_library(parser ${PARSER_SRC})
target_link_libraries(parser
${CLIBS_LIBRARIES}
${CRYPTO_LIBRARIES}
)
#add_executable(checker ${CHECK_SRC})
add_executable(checker ${CHECK_SRC})
target_link_libraries(checker parser)
add_library(game ${ERESSEA_SRC})
target_link_libraries(game parser version)
add_executable(eressea ${SERVER_SRC})
if (IWYU_PATH)
set_property(TARGET eressea PROPERTY C_INCLUDE_WHAT_YOU_USE ${IWYU_PATH})
endif(IWYU_PATH)
target_link_libraries(game version)
target_link_libraries(eressea
game
${TOLUA_LIBRARIES}
${LUA_LIBRARIES}
${STORAGE_LIBRARIES}
${CLIBS_LIBRARIES}
${CRYPTO_LIBRARIES}
${CJSON_LIBRARIES}
${INIPARSER_LIBRARIES}
)
@ -211,7 +223,6 @@ set(TESTS_SRC
guard.test.c
json.test.c
jsonconf.test.c
keyword.test.c
laws.test.c
lighthouse.test.c
magic.test.c
@ -219,6 +230,7 @@ set(TESTS_SRC
monsters.test.c
move.test.c
names.test.c
orderdb.test.c
orderfile.test.c
piracy.test.c
prefix.test.c
@ -254,7 +266,6 @@ target_link_libraries(test_eressea
${LUA_LIBRARIES}
${CLIBS_LIBRARIES}
${STORAGE_LIBRARIES}
${CRYPTO_LIBRARIES}
${CJSON_LIBRARIES}
${INIPARSER_LIBRARIES}
)
@ -286,8 +297,7 @@ if (HAVE_STRDUP)
endif(HAVE_STRDUP)
if (HAVE_LIBBSD)
target_link_libraries(test_eressea bsd)
target_link_libraries(eressea bsd)
target_link_libraries(parser bsd)
endif (HAVE_LIBBSD)
if (SQLITE3_FOUND)

View file

@ -33,8 +33,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/unit.h>
/* util includes */
#include <util/attrib.h>
#include <util/gamedata.h>
#include <kernel/attrib.h>
#include <kernel/gamedata.h>
#include <util/base36.h>
#include <util/log.h>
#include <util/macros.h>

View file

@ -45,16 +45,16 @@ static void test_herbsearch(CuTest * tc)
CuAssertPtrEquals(tc, u2, is_guarded(r, u));
herbsearch(u, INT_MAX);
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error70"));
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error59"));
test_clear_messages(f);
setguard(u2, false);
CuAssertPtrEquals(tc, 0, is_guarded(r, u));
CuAssertPtrEquals(tc, 0, (void *)rherbtype(r));
CuAssertPtrEquals(tc, NULL, is_guarded(r, u));
CuAssertPtrEquals(tc, NULL, (void *)rherbtype(r));
herbsearch(u, INT_MAX);
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error108"));
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error70"));
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error70"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error59"));
test_clear_messages(f);
rsetherbtype(r, itype);
@ -62,9 +62,9 @@ static void test_herbsearch(CuTest * tc)
CuAssertIntEquals(tc, 0, rherbs(r));
herbsearch(u, INT_MAX);
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "researchherb_none"));
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error108"));
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error70"));
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error108"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error70"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error59"));
test_clear_messages(f);
rsetherbs(r, 100);
@ -73,10 +73,10 @@ static void test_herbsearch(CuTest * tc)
CuAssertIntEquals(tc, 99, rherbs(r));
CuAssertIntEquals(tc, 1, i_get(u->items, itype));
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "herbfound"));
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "researchherb_none"));
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error108"));
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error70"));
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "researchherb_none"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error108"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error70"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error59"));
test_clear_messages(f);
test_teardown();

View file

@ -53,9 +53,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/building.h>
/* util includes */
#include <util/attrib.h>
#include <util/event.h>
#include <util/gamedata.h>
#include <kernel/attrib.h>
#include <kernel/event.h>
#include <kernel/gamedata.h>
#include <util/macros.h>
#include <util/resolve.h>

View file

@ -29,10 +29,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/unit.h>
/* util includes */
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/log.h>
#include <util/gamedata.h>
#include <kernel/gamedata.h>
#include <util/resolve.h>
#include <util/strings.h>

View file

@ -22,8 +22,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/config.h>
#include <kernel/unit.h>
#include <util/attrib.h>
#include <util/gamedata.h>
#include <kernel/attrib.h>
#include <kernel/gamedata.h>
#include <util/variant.h>
#include <storage.h>

View file

@ -22,8 +22,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/unit.h>
#include <util/attrib.h>
#include <util/gamedata.h>
#include <kernel/attrib.h>
#include <kernel/gamedata.h>
#include <util/macros.h>
#include <util/resolve.h>

View file

@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/config.h>
#include "iceberg.h"
#include <util/attrib.h>
#include <kernel/attrib.h>
attrib_type at_iceberg = {
"iceberg_drift",

View file

@ -20,8 +20,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/config.h>
#include "key.h"
#include <util/attrib.h>
#include <util/gamedata.h>
#include <kernel/attrib.h>
#include <kernel/gamedata.h>
#include <util/log.h>
#include <storage.h>

View file

@ -2,7 +2,7 @@
#include "key.h"
#include "dict.h"
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <CuTest.h>
#include <stdlib.h>

View file

@ -20,8 +20,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/config.h>
#include "movement.h"
#include <util/attrib.h>
#include <util/gamedata.h>
#include <kernel/attrib.h>
#include <kernel/gamedata.h>
#include <util/macros.h>
#include <storage.h>

View file

@ -23,8 +23,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/ally.h>
#include <kernel/faction.h>
#include <kernel/unit.h>
#include <util/attrib.h>
#include <util/gamedata.h>
#include <kernel/attrib.h>
#include <kernel/gamedata.h>
#include <storage.h>
#include <assert.h>

View file

@ -7,7 +7,7 @@
#include <kernel/region.h>
#include <kernel/faction.h>
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <CuTest.h>
#include <tests.h>

View file

@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/config.h>
#include "overrideroads.h"
#include <util/attrib.h>
#include <kernel/attrib.h>
attrib_type at_overrideroads = {
"roads_override", NULL, NULL, NULL, a_writestring, a_readstring

View file

@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/config.h>
#include "racename.h"
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/strings.h>
/* libc includes */

View file

@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/config.h>
#include "raceprefix.h"
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/strings.h>
#include <assert.h>

View file

@ -22,7 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/region.h>
#include <kernel/messages.h>
#include <util/message.h>
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <assert.h>
static int age_reduceproduction(attrib * a, void *owner)

View file

@ -23,8 +23,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/faction.h>
#include <kernel/spell.h>
#include <kernel/spellbook.h>
#include <util/attrib.h>
#include <util/gamedata.h>
#include <kernel/attrib.h>
#include <kernel/gamedata.h>
#include <util/log.h>
#include <util/macros.h>

View file

@ -1,7 +1,7 @@
#include <platform.h>
#include <kernel/unit.h>
#include <kernel/region.h>
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <attributes/stealth.h>
#include <stdlib.h>

View file

@ -22,8 +22,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/config.h>
#include <kernel/region.h>
#include <util/attrib.h>
#include <util/gamedata.h>
#include <kernel/attrib.h>
#include <kernel/gamedata.h>
#include <util/resolve.h>
#include <storage.h>

View file

@ -6,10 +6,10 @@
#include "kernel/region.h"
#include "kernel/unit.h"
#include "util/keyword.h"
#include "util/log.h"
#include "automate.h"
#include "keyword.h"
#include "laws.h"
#include "study.h"
@ -36,20 +36,22 @@ int autostudy_init(scholar scholars[], int max_scholars, region *r)
for (u = r->units; u; u = u->next) {
keyword_t kwd = getkeyword(u->thisorder);
if (kwd == K_AUTOSTUDY) {
if (long_order_allowed(u) && unit_can_study(u)) {
scholar * st = scholars + nscholars;
init_order(u->thisorder, u->faction->locale);
st->sk = getskill(u->faction->locale);
st->level = effskill_study(u, st->sk);
st->learn = 0;
st->u = u;
if (++nscholars == max_scholars) {
log_fatal("you must increase MAXSCHOLARS");
if (long_order_allowed(u)) {
if (unit_can_study(u)) {
scholar * st = scholars + nscholars;
init_order(u->thisorder, u->faction->locale);
st->sk = getskill(u->faction->locale);
st->level = effskill_study(u, st->sk);
st->learn = 0;
st->u = u;
if (++nscholars == max_scholars) {
log_fatal("you must increase MAXSCHOLARS");
}
}
else {
ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "error_race_nolearn", "race",
u_race(u)));
}
}
else {
ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "error_race_nolearn", "race",
u_race(u)));
}
}
}
@ -81,13 +83,13 @@ void autostudy_run(scholar scholars[], int nscholars)
int mint;
ts += scholars[se].u->number; /* count total scholars */
mint = (ts + 10) / 11; /* need a minimum of ceil(ts/11) teachers */
for (; mint > tt && si != nscholars; ++si) {
for (; mint > tt && si != nscholars && scholars[si].sk == sk; ++si) {
tt += scholars[si].u->number;
}
}
/* now si splits the teachers and students 1:10 */
/* first student must be 2 levels below first teacher: */
for (; si != se && scholars[ti].level - TEACHDIFFERENCE > scholars[si].level; ++si) {
for (; si != se && scholars[ti].level - TEACHDIFFERENCE > scholars[si].level && scholars[si].sk == sk; ++si) {
tt += scholars[si].u->number;
}
if (si == se) {
@ -134,7 +136,7 @@ void autostudy_run(scholar scholars[], int nscholars)
learning(scholars + s, (n - i));
i = 0;
if (++s == se) {
continue;
break;
}
n = scholars[s].u->number;
} while (scholars[t].level - TEACHDIFFERENCE < scholars[s].level);

View file

@ -60,7 +60,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* util includes */
#include <util/assert.h>
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/language.h>
#include <util/lists.h>
@ -120,7 +120,7 @@ const troop no_troop = { 0, 0 };
#define DAMAGE_CRITICAL (1<<0)
#define DAMAGE_MELEE_BONUS (1<<1)
#define DAMAGE_MISSILE_BONUS (1<<2)
#define DAMAGE_MISSILE_BONUS (1<<2) /* deprecated */
#define DAMAGE_SKILL_BONUS (1<<4)
static int max_turns;
@ -173,7 +173,7 @@ static void init_rules(void)
if (config_get_int("rules.combat.melee_bonus", 1)) {
rule_damage |= DAMAGE_MELEE_BONUS;
}
if (config_get_int("rules.combat.missile_bonus", 1)) {
if (config_get_int("rules.combat.missile_bonus", 1)) { /* deprecated */
rule_damage |= DAMAGE_MISSILE_BONUS;
}
if (config_get_int("rules.combat.skill_bonus", 1)) {
@ -559,8 +559,7 @@ static weapon *preferred_weapon(const troop t, bool attacking)
return melee;
}
static weapon *select_weapon(const troop t, bool attacking,
bool ismissile)
weapon *select_weapon(const troop t, bool attacking, bool ismissile)
/* select the primary weapon for this trooper */
{
if (attacking) {
@ -774,7 +773,7 @@ bool missile)
return skill;
}
static const armor_type *select_armor(troop t, bool shield)
const armor_type *select_armor(troop t, bool shield)
{
unsigned int type = shield ? ATF_SHIELD : 0;
unit *u = t.fighter->unit;
@ -954,6 +953,9 @@ void drain_exp(struct unit *u, int n)
static void vampirism(troop at, int damage)
{
const unit *au = at.fighter->unit;
if (u_race(au) == get_race(RC_DAEMON)) {
if (rule_vampire > 0) {
int gain = damage / rule_vampire;
int chance = damage - rule_vampire * gain;
@ -967,6 +969,16 @@ static void vampirism(troop at, int damage)
at.fighter->person[at.index].hp = maxhp;
}
}
}
}
static void ship_damage(int turn, unit *du) {
if (turn>1) {
/* someone on the ship got damaged, damage the ship */
ship *sh = du->ship ? du->ship : leftship(du);
if (sh)
fset(sh, SF_DAMAGED);
}
}
#define MAXRACES 128
@ -1016,85 +1028,94 @@ static int rc_specialdamage(const unit *au, const unit *du, const struct weapon_
return modifier;
}
int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awtype, variant *magres) {
fighter *df = dt.fighter;
int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awtype,
const armor_type *armor, const armor_type *shield, bool magic) {
const fighter *df = dt.fighter;
unit *du = df->unit;
int ar = 0, an, am;
const armor_type *armor = select_armor(dt, false);
const armor_type *shield = select_armor(dt, true);
int total_armor = 0, nat_armor, magic_armor;
bool missile = awtype && (awtype->flags&WTF_MISSILE);
if (armor) {
ar += armor->prot;
total_armor += armor->prot;
if (missile && armor->projectile > 0 && chance(armor->projectile)) {
return -1;
}
}
if (shield) {
ar += shield->prot;
total_armor += shield->prot;
if (missile && shield->projectile > 0 && chance(shield->projectile)) {
return -1;
}
}
if (magic) {
/* gegen Magie wirkt nur natuerliche und magische Ruestung */
total_armor = 0;
}
/* nat<61>rliche R<>stung */
an = natural_armor(du);
nat_armor = natural_armor(du);
/* magische R<>stung durch Artefakte oder Spr<70>che */
/* Momentan nur Trollg<6C>rtel und Werwolf-Eigenschaft */
am = select_magicarmor(dt);
magic_armor = select_magicarmor(dt);
if (rule_nat_armor == 0) {
/* nat<61>rliche R<>stung ist halbkumulativ */
if (ar > 0) {
ar += an / 2;
if (total_armor > 0) {
total_armor += nat_armor / 2;
}
else {
ar = an;
total_armor = nat_armor;
}
}
else {
/* use the higher value, add half the other value */
ar = (ar > an) ? (ar + an / 2) : (an + ar / 2);
total_armor = (total_armor > nat_armor) ? (total_armor + nat_armor / 2) : (nat_armor + total_armor / 2);
}
if (awtype && fval(awtype, WTF_ARMORPIERCING)) {
/* crossbows */
ar /= 2;
total_armor /= 2;
}
ar += am;
total_armor += magic_armor;
if (magres) {
/* calculate damage multiplier for magical damage */
variant res;
res = frac_sub(frac_one, magic_resistance(du));
assert(total_armor >= 0 || !"armor < 0 means hit denied");
if (u_race(du)->battle_flags & BF_EQUIPMENT) {
/* der Effekt von Laen steigt nicht linear */
if (armor && fval(armor, ATF_LAEN)) {
res = frac_mul(res, frac_sub(frac_one, armor->magres));
}
if (shield && fval(shield, ATF_LAEN)) {
res = frac_mul(res, frac_sub(frac_one, shield->magres));
}
if (dwtype) {
res = frac_mul(res, frac_sub(frac_one, dwtype->magres));
}
}
return total_armor;
}
/* gegen Magie wirkt nur natuerliche und magische Ruestung */
ar = an + am;
if (res.sa[0] >= 0) {
*magres = res;
}
else {
*magres = frac_make(0, 1);
}
int apply_resistance(int damage, troop dt, const weapon_type *dwtype, const armor_type *armor, const armor_type *shield, bool magic) {
const fighter *df = dt.fighter;
unit *du = df->unit;
if (!magic)
return damage;
/* calculate damage multiplier for magical damage */
variant resistance_factor = frac_sub(frac_one, magic_resistance(du));
if (u_race(du)->battle_flags & BF_EQUIPMENT) {
/* der Effekt von Laen steigt nicht linear */
if (armor && fval(armor, ATF_LAEN)) {
resistance_factor = frac_mul(resistance_factor, frac_sub(frac_one, armor->magres));
}
if (shield && fval(shield, ATF_LAEN)) {
resistance_factor = frac_mul(resistance_factor, frac_sub(frac_one, shield->magres));
}
if (dwtype) {
resistance_factor = frac_mul(resistance_factor, frac_sub(frac_one, dwtype->magres));
}
}
if (resistance_factor.sa[0] <= 0) {
return 0;
}
variant reduced_damage = frac_mul(frac_make(damage, 1), resistance_factor);
return reduced_damage.sa[0] / reduced_damage.sa[1];
return ar;
}
static bool resurrect_troop(troop dt)
@ -1112,174 +1133,30 @@ static bool resurrect_troop(troop dt)
return false;
}
bool
terminate(troop dt, troop at, int type, const char *damage, bool missile)
{
item **pitm;
fighter *df = dt.fighter;
fighter *af = at.fighter;
unit *au = af->unit;
unit *du = df->unit;
battle *b = df->side->battle;
/* Schild */
side *ds = df->side;
int ar;
const weapon_type *dwtype = NULL;
const weapon_type *awtype = NULL;
const weapon *weapon;
variant res = frac_one;
int rda, sk = 0, sd;
bool magic = false;
int da = dice_rand(damage);
assert(du->number > 0);
++at.fighter->hits;
switch (type) {
case AT_STANDARD:
weapon = select_weapon(at, true, missile);
sk = weapon_effskill(at, dt, weapon, true, missile);
if (weapon)
awtype = weapon->type;
if (awtype && fval(awtype, WTF_MAGICAL))
magic = true;
break;
case AT_NATURAL:
sk = weapon_effskill(at, dt, NULL, true, missile);
break;
case AT_SPELL:
case AT_COMBATSPELL:
magic = true;
break;
default:
break;
}
weapon = select_weapon(dt, false, true); /* missile=true to get the unmodified best weapon she has */
sd = weapon_effskill(dt, at, weapon, false, false);
if (weapon != NULL)
dwtype = weapon->type;
if (is_riding(at) && (awtype == NULL || (fval(awtype, WTF_HORSEBONUS)
&& !fval(awtype, WTF_MISSILE)))) {
da += CavalryBonus(au, dt, BONUS_DAMAGE);
}
ar = calculate_armor(dt, dwtype, awtype, magic ? &res : 0);
if (ar < 0) {
return false;
}
if (magic) {
res = frac_sub(frac_one, res);
res = frac_mul(frac_make(da, 1), res);
da = res.sa[0] / res.sa[1];
}
if (type != AT_COMBATSPELL && type != AT_SPELL) {
if (rule_damage & DAMAGE_CRITICAL) {
double kritchance = (sk * 3 - sd) / 200.0;
int maxk = 4;
kritchance = fmax(kritchance, 0.005);
kritchance = fmin(0.9, kritchance);
while (maxk-- && chance(kritchance)) {
da += dice_rand(damage);
}
}
da += rc_specialdamage(au, du, awtype);
if (awtype != NULL && fval(awtype, WTF_MISSILE)) {
/* missile weapon bonus */
if (rule_damage & DAMAGE_MISSILE_BONUS) {
da += af->person[at.index].damage_rear;
}
}
else {
/* melee bonus */
if (rule_damage & DAMAGE_MELEE_BONUS) {
da += af->person[at.index].damage;
}
}
/* Skilldifferenzbonus */
if (rule_damage & DAMAGE_SKILL_BONUS) {
da += MAX(0, (sk - sd) / DAMAGE_QUOTIENT);
static void demon_dazzle(fighter *af, troop dt) {
const fighter *df = dt.fighter;
if (u_race(af->unit) == get_race(RC_DAEMON)) {
if (!(df->person[dt.index].flags & (FL_COURAGE | FL_DAZZLED))) {
df->person[dt.index].flags |= FL_DAZZLED;
df->person[dt.index].defense--;
}
}
}
rda = MAX(da - ar, 0);
static bool survives(fighter *af, troop dt, battle *b) {
const unit *du = af->unit;
const fighter *df = dt.fighter;
if ((u_race(du)->battle_flags & BF_INV_NONMAGIC) && !magic)
rda = 0;
else {
int qi;
selist *ql;
unsigned int i = 0;
if (u_race(du)->battle_flags & BF_RES_PIERCE)
i |= WTF_PIERCE;
if (u_race(du)->battle_flags & BF_RES_CUT)
i |= WTF_CUT;
if (u_race(du)->battle_flags & BF_RES_BASH)
i |= WTF_BLUNT;
if (i && awtype && fval(awtype, i))
rda /= 2;
/* Schilde */
for (qi = 0, ql = b->meffects; ql; selist_advance(&ql, &qi, 1)) {
meffect *me = (meffect *)selist_get(ql, qi);
if (meffect_protection(b, me, ds) != 0) {
assert(0 <= rda); /* rda sollte hier immer mindestens 0 sein */
/* jeder Schaden wird um effect% reduziert bis der Schild duration
* Trefferpunkte aufgefangen hat */
if (me->typ == SHIELD_REDUCE) {
int hp = rda * (me->effect / 100);
rda -= hp;
me->duration -= hp;
}
/* gibt R<>stung +effect f<>r duration Treffer */
if (me->typ == SHIELD_ARMOR) {
rda = MAX(rda - me->effect, 0);
me->duration--;
}
}
}
}
assert(dt.index >= 0 && dt.index < du->number);
if (rda>0) {
df->person[dt.index].hp -= rda;
if (u_race(au) == get_race(RC_DAEMON)) {
vampirism(at, rda);
}
if (b->turn>1) {
/* someone on the ship got damaged, damage the ship */
ship *sh = du->ship ? du->ship : leftship(du);
if (sh)
fset(sh, SF_DAMAGED);
}
}
if (df->person[dt.index].hp > 0) { /* Hat <20>berlebt */
if (u_race(au) == get_race(RC_DAEMON)) {
if (!(df->person[dt.index].flags & (FL_COURAGE | FL_DAZZLED))) {
df->person[dt.index].flags |= FL_DAZZLED;
df->person[dt.index].defence--;
}
}
return false;
demon_dazzle(af, dt);
return true;
}
/* Sieben Leben */
if (u_race(du) == get_race(RC_CAT) && (chance(1.0 / 7))) {
df->person[dt.index].hp = unit_max_hp(du);
return false;
return true;
}
/* healing potions can avert a killing blow */
@ -1287,23 +1164,218 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile)
message *m = msg_message("potionsave", "unit", du);
battle_message_faction(b, du->faction, m);
msg_release(m);
return true;
}
return false;
}
static void destroy_items(troop dt) {
unit *du = dt.fighter->unit;
item **pitm;
for (pitm = &du->items; *pitm;) {
item *itm = *pitm;
const item_type *itype = itm->type;
if (!(itype->flags & ITF_CURSED) && dt.index < itm->number) {
/* 25% Grundchance, das ein Item kaputtgeht. */
if (rng_int() % 4 < 1) {
i_change(pitm, itype, -1);
}
}
if (*pitm == itm) {
pitm = &itm->next;
}
}
}
static void calculate_defense_type(troop dt, troop at, int type, bool missile,
const weapon_type **dwtype, int *defskill) {
const weapon *weapon;
weapon = select_weapon(dt, false, true); /* missile=true to get the unmodified best weapon she has */
*defskill = weapon_effskill(dt, at, weapon, false, false);
if (weapon != NULL)
*dwtype = weapon->type;
}
static void calculate_attack_type(troop dt, troop at, int type, bool missile,
const weapon_type **awtype, int *attskill, bool *magic) {
const weapon *weapon;
switch (type) {
case AT_STANDARD:
weapon = select_weapon(at, true, missile);
*attskill = weapon_effskill(at, dt, weapon, true, missile);
if (weapon)
*awtype = weapon->type;
if (*awtype && fval(*awtype, WTF_MAGICAL))
*magic = true;
break;
case AT_NATURAL:
*attskill = weapon_effskill(at, dt, NULL, true, missile);
break;
case AT_SPELL:
case AT_COMBATSPELL:
*magic = true;
break;
default:
break;
}
}
static int crit_damage(int attskill, int defskill, const char *damage_formula) {
int damage = 0;
if (rule_damage & DAMAGE_CRITICAL) {
double kritchance = (attskill * 3 - defskill) / 200.0;
int maxk = 4;
kritchance = fmax(kritchance, 0.005);
kritchance = fmin(0.9, kritchance);
while (maxk-- && chance(kritchance)) {
damage += dice_rand(damage_formula);
}
}
return damage;
}
static int apply_race_resistance(int reduced_damage, fighter *df,
const weapon_type *awtype, bool magic) {
unit *du = df->unit;
if ((u_race(du)->battle_flags & BF_INV_NONMAGIC) && !magic)
reduced_damage = 0;
else {
unsigned int i = 0;
if (u_race(du)->battle_flags & BF_RES_PIERCE)
i |= WTF_PIERCE;
if (u_race(du)->battle_flags & BF_RES_CUT)
i |= WTF_CUT;
if (u_race(du)->battle_flags & BF_RES_BASH)
i |= WTF_BLUNT;
if (i && awtype && fval(awtype, i))
reduced_damage /= 2;
}
return reduced_damage;
}
static int apply_magicshield(int reduced_damage, fighter *df,
const weapon_type *awtype, battle *b, bool magic) {
side *ds = df->side;
selist *ql;
int qi;
if (reduced_damage <= 0)
return 0;
/* Schilde */
for (qi = 0, ql = b->meffects; ql; selist_advance(&ql, &qi, 1)) {
meffect *me = (meffect *) selist_get(ql, qi);
if (meffect_protection(b, me, ds) != 0) {
assert(0 <= reduced_damage); /* rda sollte hier immer mindestens 0 sein */
/* jeder Schaden wird um effect% reduziert bis der Schild duration
* Trefferpunkte aufgefangen hat */
if (me->typ == SHIELD_REDUCE) {
int hp = reduced_damage * (me->effect / 100);
reduced_damage -= hp;
me->duration -= hp;
}
/* gibt R<>stung +effect f<>r duration Treffer */
if (me->typ == SHIELD_ARMOR) {
reduced_damage = MAX(reduced_damage - me->effect, 0);
me->duration--;
}
}
}
return reduced_damage;
}
bool
terminate(troop dt, troop at, int type, const char *damage_formula, bool missile)
{
fighter *df = dt.fighter;
fighter *af = at.fighter;
unit *au = af->unit;
unit *du = df->unit;
battle *b = df->side->battle;
int armor_value;
const weapon_type *dwtype = NULL;
const weapon_type *awtype = NULL;
const armor_type *armor = NULL;
const armor_type *shield = NULL;
int reduced_damage, attskill = 0, defskill = 0;
bool magic = false;
int damage = dice_rand(damage_formula);
assert(du->number > 0);
++at.fighter->hits;
calculate_attack_type(at, dt, type, missile, &awtype, &attskill, &magic);
calculate_defense_type(at, dt, type, missile, &awtype, &attskill);
if (is_riding(at) && (awtype == NULL || (fval(awtype, WTF_HORSEBONUS)
&& !fval(awtype, WTF_MISSILE)))) {
damage += CavalryBonus(au, dt, BONUS_DAMAGE);
}
armor = select_armor(dt, false);
shield = select_armor(dt, true);
armor_value = calculate_armor(dt, dwtype, awtype, armor, shield, magic);
if (armor_value < 0) {
return false;
}
++at.fighter->kills;
for (pitm = &du->items; *pitm;) {
item *itm = *pitm;
const item_type *itype = itm->type;
if (!(itype->flags & ITF_CURSED) && dt.index < itm->number) {
/* 25% Grundchance, das ein Item kaputtgeht. */
if (rng_int() % 4 < 1) {
i_change(pitm, itype, -1);
damage = apply_resistance(damage, dt, dwtype, armor, shield, magic);
if (type != AT_COMBATSPELL && type != AT_SPELL) {
damage += crit_damage(attskill, defskill, damage_formula);
damage += rc_specialdamage(au, du, awtype);
if (awtype == NULL || !fval(awtype, WTF_MISSILE)) {
/* melee bonus */
if (rule_damage & DAMAGE_MELEE_BONUS) {
damage += af->person[at.index].damage;
}
}
if (*pitm == itm) {
pitm = &itm->next;
/* Skilldifferenzbonus */
if (rule_damage & DAMAGE_SKILL_BONUS) {
damage += MAX(0, (attskill - defskill) / DAMAGE_QUOTIENT);
}
}
reduced_damage = MAX(damage - armor_value, 0);
reduced_damage = apply_race_resistance(reduced_damage, df, awtype, magic);
reduced_damage = apply_magicshield(reduced_damage, df, awtype, b, magic);
assert(dt.index >= 0 && dt.index < du->number);
if (reduced_damage > 0) {
df->person[dt.index].hp -= reduced_damage;
vampirism(at, reduced_damage);
ship_damage(b->turn, du);
}
if (survives(af, dt, b))
return false;
++at.fighter->kills;
destroy_items(dt);
kill_troop(dt);
return true;
@ -1874,7 +1946,7 @@ int skilldiff(troop at, troop dt, int dist)
rc_goblin = get_race(RC_GOBLIN);
}
skdiff += af->person[at.index].attack;
skdiff -= df->person[dt.index].defence;
skdiff -= df->person[dt.index].defense;
if (df->person[dt.index].flags & FL_SLEEPING)
skdiff += 2;
@ -2003,7 +2075,7 @@ void dazzle(battle * b, troop * td)
}
td->fighter->person[td->index].flags |= FL_DAZZLED;
td->fighter->person[td->index].defence--;
td->fighter->person[td->index].defense--;
}
void damage_building(battle * b, building * bldg, int damage_abs)
@ -2169,7 +2241,7 @@ static void attack(battle * b, troop ta, const att * a, int numattack)
td.fighter->person[td.index].attack -= 1;
}
else {
td.fighter->person[td.index].defence -= 1;
td.fighter->person[td.index].defense -= 1;
}
c--;
}
@ -3112,7 +3184,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
strongmen = trollbelts(u);
if (strongmen > fig->unit->number) strongmen = fig->unit->number;
/* Hitpoints, Attack- und Defence-Boni f<>r alle Personen */
/* Hitpoints, Attack- und Defense-Boni fuer alle Personen */
for (i = 0; i < fig->alive; i++) {
assert(i < fig->unit->number);
fig->person[i].hp = h;

View file

@ -173,9 +173,8 @@ extern "C" {
struct person {
int hp; /* Trefferpunkte der Personen */
int attack;
int defence;
int defense;
int damage;
int damage_rear;
int flags;
int speed;
int reload;
@ -233,7 +232,10 @@ extern "C" {
int count_enemies(struct battle *b, const struct fighter *af,
int minrow, int maxrow, int select);
int natural_armor(struct unit * u);
int calculate_armor(troop dt, const struct weapon_type *dwtype, const struct weapon_type *awtype, union variant *magres);
const struct armor_type *select_armor(struct troop t, bool shield);
struct weapon *select_weapon(const struct troop t, bool attacking, bool ismissile);
int calculate_armor(troop dt, const struct weapon_type *dwtype, const struct weapon_type *awtype, const struct armor_type *armor, const struct armor_type *shield, bool magic);
int apply_resistance(int damage, struct troop dt, const struct weapon_type *dwtype, const struct armor_type *armor, const struct armor_type *shield, bool magic);
bool terminate(troop dt, troop at, int type, const char *damage,
bool missile);
void message_all(battle * b, struct message *m);

View file

@ -3,7 +3,6 @@
#include "battle.h"
#include "guard.h"
#include "keyword.h"
#include "reports.h"
#include "skill.h"
@ -22,6 +21,7 @@
#include <util/base36.h>
#include <util/functions.h>
#include "util/keyword.h"
#include <util/language.h>
#include <util/message.h>
#include <util/rand.h>
@ -78,7 +78,7 @@ static void test_make_fighter(CuTest * tc)
af = make_fighter(b, au, as, false);
CuAssertIntEquals(tc, 1, b->nfighters);
CuAssertPtrEquals(tc, 0, af->building);
CuAssertPtrEquals(tc, NULL, af->building);
CuAssertPtrEquals(tc, as, af->side);
CuAssertIntEquals(tc, 0, af->run.hp);
CuAssertIntEquals(tc, ST_BEHIND, af->status);
@ -216,7 +216,7 @@ static void test_defenders_get_building_bonus(CuTest * tc)
af = make_fighter(b, au, as, true);
CuAssertPtrEquals(tc, bld, df->building);
CuAssertPtrEquals(tc, 0, af->building);
CuAssertPtrEquals(tc, NULL, af->building);
dt.fighter = df;
dt.index = 0;
@ -261,7 +261,7 @@ static void test_attackers_get_no_building_bonus(CuTest * tc)
as = make_side(b, au->faction, 0, 0, 0);
af = make_fighter(b, au, as, true);
CuAssertPtrEquals(tc, 0, af->building);
CuAssertPtrEquals(tc, NULL, af->building);
free_battle(b);
test_teardown();
}
@ -298,12 +298,12 @@ static void test_building_bonus_respects_size(CuTest * tc)
df = make_fighter(b, du, as, false);
CuAssertPtrEquals(tc, bld, af->building);
CuAssertPtrEquals(tc, 0, df->building);
CuAssertPtrEquals(tc, NULL, df->building);
free_battle(b);
test_teardown();
}
static void test_building_defence_bonus(CuTest * tc)
static void test_building_defense_bonus(CuTest * tc)
{
building_type * btype;
@ -358,6 +358,16 @@ static void test_natural_armor(CuTest * tc)
test_teardown();
}
static int test_armor(troop dt, weapon_type *awtype, bool magic) {
return calculate_armor(dt, 0, awtype, select_armor(dt, false), select_armor(dt, true), magic);
}
static int test_resistance(troop dt) {
return apply_resistance(1000, dt,
select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0,
select_armor(dt, false), select_armor(dt, true), true);
}
static void test_calculate_armor(CuTest * tc)
{
troop dt;
@ -368,7 +378,6 @@ static void test_calculate_armor(CuTest * tc)
armor_type *ashield, *achain;
item_type *ibelt, *ishield, *ichain;
race *rc;
variant magres = frac_zero;
variant v50p = frac_make(1, 2);
test_setup();
@ -384,18 +393,19 @@ static void test_calculate_armor(CuTest * tc)
dt.index = 0;
dt.fighter = setup_fighter(&b, du);
CuAssertIntEquals_Msg(tc, "default ac", 0, calculate_armor(dt, 0, 0, &magres));
CuAssertIntEquals_Msg(tc, "magres unmodified", magres.sa[0], magres.sa[1]);
CuAssertIntEquals_Msg(tc, "default ac", 0, test_armor(dt, 0, false));
CuAssertIntEquals_Msg(tc, "magres unmodified", 1000, test_resistance(dt));
free_battle(b);
b = NULL;
i_change(&du->items, ibelt, 1);
dt.fighter = setup_fighter(&b, du);
CuAssertIntEquals_Msg(tc, "without natural armor", 0, natural_armor(du));
CuAssertIntEquals_Msg(tc, "magical armor", 1, calculate_armor(dt, 0, 0, 0));
CuAssertIntEquals_Msg(tc, "magical armor", 1, test_armor(dt, 0, false));
rc->armor = 2;
CuAssertIntEquals_Msg(tc, "with natural armor", 2, natural_armor(du));
CuAssertIntEquals_Msg(tc, "natural armor", 3, calculate_armor(dt, 0, 0, 0));
CuAssertIntEquals_Msg(tc, "natural armor", 3, test_armor(dt, 0, false));
rc->armor = 0;
free_battle(b);
@ -404,29 +414,30 @@ static void test_calculate_armor(CuTest * tc)
i_change(&du->items, ichain, 1);
dt.fighter = setup_fighter(&b, du);
rc->battle_flags &= ~BF_EQUIPMENT;
CuAssertIntEquals_Msg(tc, "require BF_EQUIPMENT", 1, calculate_armor(dt, 0, 0, 0));
CuAssertIntEquals_Msg(tc, "require BF_EQUIPMENT", 1, test_armor(dt, 0, false));
free_battle(b);
b = NULL;
rc->battle_flags |= BF_EQUIPMENT;
dt.fighter = setup_fighter(&b, du);
CuAssertIntEquals_Msg(tc, "stack equipment rc", 5, calculate_armor(dt, 0, 0, 0));
CuAssertIntEquals_Msg(tc, "stack equipment rc", 5, test_armor(dt, 0, false));
rc->armor = 2;
CuAssertIntEquals_Msg(tc, "natural armor adds 50%", 6, calculate_armor(dt, 0, 0, 0));
CuAssertIntEquals_Msg(tc, "natural armor adds 50%", 6, test_armor(dt, 0, false));
wtype->flags = WTF_NONE;
CuAssertIntEquals_Msg(tc, "regular weapon has no effect", 6, calculate_armor(dt, 0, wtype, 0));
CuAssertIntEquals_Msg(tc, "regular weapon has no effect", 6, test_armor(dt, wtype, false));
wtype->flags = WTF_ARMORPIERCING;
CuAssertIntEquals_Msg(tc, "armor piercing weapon", 3, calculate_armor(dt, 0, wtype, 0));
CuAssertIntEquals_Msg(tc, "armor piercing weapon", 3, test_armor(dt, wtype, false));
wtype->flags = WTF_NONE;
CuAssertIntEquals_Msg(tc, "magical attack", 3, calculate_armor(dt, 0, 0, &magres));
CuAssertIntEquals_Msg(tc, "magres unmodified", magres.sa[1], magres.sa[0]);
CuAssertIntEquals_Msg(tc, "magical attack", 3, test_armor(dt, wtype, true));
CuAssertIntEquals_Msg(tc, "magres unmodified", 1000,
test_resistance(dt));
ashield->flags |= ATF_LAEN;
achain->flags |= ATF_LAEN;
magres = frac_one;
CuAssertIntEquals_Msg(tc, "laen armor", 3, calculate_armor(dt, 0, 0, &magres));
CuAssertIntEquals_Msg(tc, "laen magres bonus", 4, magres.sa[1]);
CuAssertIntEquals_Msg(tc, "laen armor", 3, test_armor(dt, wtype, true));
CuAssertIntEquals_Msg(tc, "laen magres bonus", 250, test_resistance(dt));
free_battle(b);
test_teardown();
}
@ -456,15 +467,17 @@ static void test_magic_resistance(CuTest *tc)
i_change(&du->items, ishield, 1);
dt.fighter = setup_fighter(&b, du);
calculate_armor(dt, 0, 0, &magres);
CuAssertIntEquals_Msg(tc, "no magres reduction", magres.sa[1], magres.sa[0]);
CuAssertIntEquals_Msg(tc, "no magres reduction", 1000, test_resistance(dt));
magres = magic_resistance(du);
CuAssertIntEquals_Msg(tc, "no magres reduction", 0, magres.sa[0]);
ashield->flags |= ATF_LAEN;
ashield->magres = v10p;
calculate_armor(dt, 0, 0, &magres);
CuAssert(tc, "laen reduction => 10%%", frac_equal(frac_make(9, 10), magres));
CuAssertIntEquals_Msg(tc, "laen reduction => 10%%", 900, test_resistance(dt));
CuAssertIntEquals_Msg(tc, "no magic, no resistance", 1000,
apply_resistance(1000, dt,
select_weapon(dt, false, true) ? select_weapon(dt, false, true)->type : 0,
select_armor(dt, false), select_armor(dt, true), false));
free_battle(b);
b = NULL;
@ -474,8 +487,7 @@ static void test_magic_resistance(CuTest *tc)
ashield->flags |= ATF_LAEN;
ashield->magres = v10p;
dt.fighter = setup_fighter(&b, du);
calculate_armor(dt, 0, 0, &magres);
CuAssert(tc, "2x laen reduction => 81%%", frac_equal(frac_make(81, 100), magres));
CuAssertIntEquals_Msg(tc, "2x laen reduction => 81%%", 810, test_resistance(dt));
free_battle(b);
b = NULL;
@ -483,21 +495,18 @@ static void test_magic_resistance(CuTest *tc)
i_change(&du->items, ichain, -1);
set_level(du, SK_MAGIC, 2);
dt.fighter = setup_fighter(&b, du);
calculate_armor(dt, 0, 0, &magres);
CuAssert(tc, "skill reduction => 90%%", frac_equal(magres, frac_make(9, 10)));
CuAssertIntEquals_Msg(tc, "skill reduction => 90%%", 900, test_resistance(dt));
magres = magic_resistance(du);
CuAssert(tc, "skill reduction", frac_equal(magres, v10p));
rc->magres = v50p; /* percentage, gets added to skill bonus */
calculate_armor(dt, 0, 0, &magres);
CuAssert(tc, "race reduction => 40%%", frac_equal(magres, frac_make(4, 10)));
CuAssertIntEquals_Msg(tc, "race reduction => 40%%", 400, test_resistance(dt));
magres = magic_resistance(du);
CuAssert(tc, "race bonus => 60%%", frac_equal(magres, frac_make(60, 100)));
rc->magres = frac_make(15, 10); /* 150% resistance should not cause negative damage multiplier */
magres = magic_resistance(du);
CuAssert(tc, "magic resistance is never > 0.9", frac_equal(magres, frac_make(9, 10)));
calculate_armor(dt, 0, 0, &magres);
CuAssert(tc, "damage reduction is never < 0.1", frac_equal(magres, frac_make(1, 10)));
CuAssertIntEquals_Msg(tc, "damage reduction is never < 0.1", 100, test_resistance(dt));
free_battle(b);
test_teardown();
@ -532,12 +541,12 @@ static void test_projectile_armor(CuTest * tc)
dt.fighter = setup_fighter(&b, du);
wtype->flags = WTF_MISSILE;
achain->projectile = 1.0;
CuAssertIntEquals_Msg(tc, "projectile armor", -1, calculate_armor(dt, 0, wtype, 0));
CuAssertIntEquals_Msg(tc, "projectile armor", -1, test_armor(dt, wtype, false));
achain->projectile = 0.0;
ashield->projectile = 1.0;
CuAssertIntEquals_Msg(tc, "projectile shield", -1, calculate_armor(dt, 0, wtype, 0));
CuAssertIntEquals_Msg(tc, "projectile shield", -1, test_armor(dt, wtype, false));
wtype->flags = WTF_NONE;
CuAssertIntEquals_Msg(tc, "no projectiles", 4, calculate_armor(dt, 0, wtype, 0));
CuAssertIntEquals_Msg(tc, "no projectiles", 4, test_armor(dt, wtype, false));
free_battle(b);
test_teardown();
}
@ -561,7 +570,7 @@ static void test_battle_skilldiff(CuTest *tc)
CuAssertIntEquals(tc, 0, skilldiff(ta, td, 0));
ta.fighter->person[0].attack = 2;
td.fighter->person[0].defence = 1;
td.fighter->person[0].defense = 1;
CuAssertIntEquals(tc, 1, skilldiff(ta, td, 0));
td.fighter->person[0].flags |= FL_SLEEPING;
@ -575,6 +584,38 @@ static void test_battle_skilldiff(CuTest *tc)
test_teardown();
}
static void test_terminate(CuTest * tc)
{
troop at, dt;
battle *b = NULL;
region *r;
unit *au, *du;
race *rc;
test_setup();
r = test_create_region(0, 0, NULL);
rc = test_create_race("human");
au = test_create_unit(test_create_faction(rc), r);
du = test_create_unit(test_create_faction(rc), r);
dt.index = 0;
at.index = 0;
at.fighter = setup_fighter(&b, au);
dt.fighter = setup_fighter(&b, du);
CuAssertIntEquals_Msg(tc, "not killed", 0, terminate(dt, at, AT_STANDARD, "1d1", false));
b = NULL;
at.fighter = setup_fighter(&b, au);
dt.fighter = setup_fighter(&b, du);
CuAssertIntEquals_Msg(tc, "killed", 1, terminate(dt, at, AT_STANDARD, "100d1", false));
CuAssertIntEquals_Msg(tc, "number", 0, dt.fighter->person[0].hp);
free_battle(b);
test_teardown();
}
static void test_battle_report_one(CuTest *tc)
{
battle * b = NULL;
@ -847,12 +888,13 @@ CuSuite *get_battle_suite(void)
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);
SUITE_ADD_TEST(suite, test_building_defense_bonus);
SUITE_ADD_TEST(suite, test_calculate_armor);
SUITE_ADD_TEST(suite, test_natural_armor);
SUITE_ADD_TEST(suite, test_magic_resistance);
SUITE_ADD_TEST(suite, test_projectile_armor);
SUITE_ADD_TEST(suite, test_tactics_chance);
SUITE_ADD_TEST(suite, test_terminate);
DISABLE_TEST(suite, test_drain_exp);
return suite;
}

View file

@ -12,6 +12,7 @@
#include <kernel/save.h>
#include <util/language.h>
#include <util/log.h>
#include <stream.h>
#include <stdio.h>
@ -21,7 +22,7 @@
void eressea_free_game(void) {
free_gamedata();
init_resources();
init_locales();
init_locales(init_locale);
}
int eressea_read_game(const char * filename) {
@ -34,7 +35,13 @@ int eressea_write_game(const char * filename) {
}
int eressea_read_orders(const char * filename) {
return readorders(filename);
FILE * F = fopen(filename, "r");
if (!F) {
perror(filename);
return -1;
}
log_info("reading orders from %s", filename);
return parseorders(F);
}
int eressea_export_json(const char * filename, int flags) {

View file

@ -4,20 +4,22 @@
#include "bind_process.h"
#include "battle.h"
#include "economy.h"
#include "laws.h"
#include "magic.h"
#include "market.h"
#include "move.h"
#include "study.h"
#include <kernel/alliance.h>
#include <kernel/config.h>
#include <kernel/order.h>
#include <kernel/region.h>
#include <kernel/terrain.h>
#include <kernel/unit.h>
#include "battle.h"
#include "economy.h"
#include "keyword.h"
#include "laws.h"
#include "magic.h"
#include "market.h"
#include "move.h"
#include "study.h"
#include "util/keyword.h"
#define PROC_LAND_REGION 0x0001
#define PROC_LONG_ORDER 0x0002

View file

@ -22,7 +22,7 @@
#include <kernel/terrain.h>
#include <kernel/messages.h>
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/log.h>
#include <util/macros.h>

View file

@ -14,7 +14,7 @@
#include <kernel/ship.h>
#include <kernel/build.h>
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/language.h>
#include <util/log.h>
#include <util/macros.h>

View file

@ -6,7 +6,7 @@
#include <kernel/save.h>
#include <util/gamedata.h>
#include <kernel/gamedata.h>
#include <util/log.h>
#include <util/macros.h>

View file

@ -11,9 +11,9 @@
#include "skill.h"
/* util includes */
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/event.h>
#include <kernel/event.h>
#include <util/log.h>
#include <util/macros.h>
#include "util/variant.h"

View file

@ -47,7 +47,7 @@
#include <modules/score.h>
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/language.h>
#include <util/log.h>

View file

@ -34,7 +34,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/terrainid.h>
#include <kernel/unit.h>
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/rng.h>
#include <stdlib.h>

92
src/checker.c Normal file
View file

@ -0,0 +1,92 @@
#ifdef _MSV_VER
#include <platform.h>
#endif
#include "util/order_parser.h"
#include "util/keyword.h"
#include "util/language.h"
#include "util/path.h"
#include "util/pofile.h"
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
typedef struct parser_state {
FILE * F;
} parser_state;
static void handle_order(void *userData, const char *str) {
parser_state * state = (parser_state*)userData;
fputs(str, state->F);
fputc('\n', state->F);
}
int parsefile(FILE *F) {
OP_Parser parser;
char buf[1024];
int done = 0, err = 0;
parser_state state = { NULL };
state.F = stdout;
parser = OP_ParserCreate();
OP_SetOrderHandler(parser, handle_order);
OP_SetUserData(parser, &state);
while (!done) {
size_t len = (int)fread(buf, 1, sizeof(buf), F);
if (ferror(F)) {
/* TODO: error message */
err = errno;
break;
}
done = feof(F);
if (OP_Parse(parser, buf, len, done) == OP_STATUS_ERROR) {
/* TODO: error message */
err = (int)OP_GetErrorCode(parser);
break;
}
}
OP_ParserFree(parser);
return err;
}
static int handle_po(const char *msgid, const char *msgstr, const char *msgctxt, void *data) {
struct locale *lang = (struct locale *)data;
if (msgctxt) {
if (strcmp(msgctxt, "keyword") == 0) {
keyword_t kwd = findkeyword(msgid);
init_keyword(lang, kwd, msgstr);
locale_setstring(lang, mkname("keyword", keywords[kwd]), msgstr);
}
}
return 0;
}
static void read_config(const char *respath) {
char path[PATH_MAX];
struct locale *lang;
lang = get_or_create_locale("de");
path_join(respath, "translations/strings.de.po", path, sizeof(path));
pofile_read(path, handle_po, lang);
}
int main(int argc, char **argv) {
FILE * F = stdin;
if (argc > 1) {
const char *filename = argv[1];
F = fopen(filename, "r");
if (!F) {
perror(filename);
return -1;
}
}
read_config("../git");
parsefile(F);
if (F != stdin) {
fclose(F);
}
return 0;
}

View file

@ -64,7 +64,7 @@ without prior permission by the authors of Eressea.
#include "kernel/unit.h"
/* util includes */
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/crmessage.h>
#include <util/strings.h>

View file

@ -3,7 +3,6 @@
#include "move.h"
#include "spy.h"
#include "travelthru.h"
#include "keyword.h"
#include <kernel/ally.h>
#include <kernel/building.h>
@ -17,6 +16,7 @@
#include <kernel/spell.h>
#include <kernel/spellbook.h>
#include "util/keyword.h"
#include <util/language.h>
#include <util/lists.h>
#include <util/message.h>

View file

@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifdef _MSC_VER
#include <platform.h>
#endif
#include <kernel/config.h>
#include "economy.h"
#include "alchemy.h"
@ -45,10 +45,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* kernel includes */
#include "kernel/ally.h"
#include "kernel/attrib.h"
#include "kernel/building.h"
#include "kernel/calendar.h"
#include "kernel/config.h"
#include "kernel/curse.h"
#include "kernel/equipment.h"
#include "kernel/event.h"
#include "kernel/faction.h"
#include "kernel/item.h"
#include "kernel/messages.h"
@ -64,13 +67,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "kernel/unit.h"
/* util includes */
#include <util/attrib.h>
#include <util/base36.h>
#include <util/event.h>
#include <util/goodies.h>
#include <util/language.h>
#include <util/lists.h>
#include <util/log.h>
#include "util/param.h"
#include <util/parser.h>
#include <util/rng.h>

View file

@ -19,7 +19,7 @@
#include <kernel/terrainid.h>
#include <kernel/unit.h>
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/language.h>
#include <util/macros.h>
@ -357,7 +357,7 @@ static void test_tax_cmd(CuTest *tc) {
set_level(u, SK_TAXING, 1);
tax_cmd(u, ord, &taxorders);
CuAssertPtrEquals(tc, 0, test_find_messagetype(u->faction->msgs, "error_no_tax_skill"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(u->faction->msgs, "error_no_tax_skill"));
CuAssertPtrNotNull(tc, taxorders);
rsetmoney(r, 11);
@ -415,8 +415,8 @@ static void test_maintain_buildings(CuTest *tc) {
b->flags = 0;
maintain_buildings(r);
CuAssertIntEquals(tc, BLD_MAINTAINED, fval(b, BLD_MAINTAINED));
CuAssertPtrEquals(tc, 0, f->msgs);
CuAssertPtrEquals(tc, 0, r->msgs);
CuAssertPtrEquals(tc, NULL, f->msgs);
CuAssertPtrEquals(tc, NULL, r->msgs);
req = calloc(2, sizeof(maintenance));
req[0].number = 100;
@ -438,8 +438,8 @@ static void test_maintain_buildings(CuTest *tc) {
maintain_buildings(r);
CuAssertIntEquals(tc, BLD_MAINTAINED, fval(b, BLD_MAINTAINED));
CuAssertIntEquals(tc, 0, i_get(u->items, itype));
CuAssertPtrEquals(tc, 0, r->msgs);
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "maintenance_nowork"));
CuAssertPtrEquals(tc, NULL, r->msgs);
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "maintenance_nowork"));
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "maintenance"));
test_clear_messagelist(&f->msgs);
@ -448,7 +448,7 @@ static void test_maintain_buildings(CuTest *tc) {
b->flags = 0;
maintain_buildings(r);
CuAssertIntEquals(tc, 0, fval(b, BLD_MAINTAINED));
CuAssertPtrEquals(tc, 0, f->msgs);
CuAssertPtrEquals(tc, NULL, f->msgs);
CuAssertPtrNotNull(tc, test_find_messagetype(r->msgs, "maintenance_noowner"));
test_clear_messagelist(&r->msgs);

View file

@ -1,14 +1,13 @@
#include <platform.h>
#include "eressea.h"
#include "kernel/building.h"
#include "kernel/calendar.h"
#include "kernel/config.h"
#include "kernel/curse.h"
#include "kernel/faction.h"
#include "kernel/building.h"
#include "kernel/equipment.h"
#include "kernel/faction.h"
#include "kernel/item.h"
#include "kernel/database.h"
#include "util/functions.h"
#include "util/language.h"
@ -28,6 +27,7 @@
#include "creport.h"
#include "report.h"
#include "names.h"
#include "orderdb.h"
#include "reports.h"
#include "spells.h"
#include "vortex.h"
@ -54,12 +54,12 @@ void game_done(void)
free_locales();
#endif
kernel_done();
dblib_close();
orderdb_close();
}
void game_init(void)
{
dblib_open();
orderdb_open();
errno = 0;
kernel_init();
register_triggers();

View file

@ -6,7 +6,6 @@
#include "kernel/config.h"
#include "kernel/calendar.h"
#include "kernel/database.h"
#include "kernel/faction.h"
#include "kernel/db/driver.h"
@ -21,7 +20,7 @@ int gamedb_update(void)
err = db_driver_open(DB_GAME, dbname);
if (err == 0) {
for (f = factions; f; f = f->next) {
int uid = dblib_save_faction(f, turn);
int uid = db_driver_faction_save(f->uid, f->no, turn, f->email, f->_password);
if (uid > 0) {
f->uid = uid;
}

View file

@ -25,6 +25,8 @@
#include <attributes/racename.h>
/* kernel includes */
#include <kernel/attrib.h>
#include <kernel/event.h>
#include <kernel/ally.h>
#include <kernel/build.h>
#include <kernel/curse.h>
@ -41,11 +43,10 @@
#include <kernel/unit.h>
/* util includes */
#include <util/attrib.h>
#include <util/base36.h>
#include <util/event.h>
#include <util/log.h>
#include <util/macros.h>
#include <util/param.h>
#include <util/parser.h>
/* libc includes */

View file

@ -16,6 +16,7 @@
#include <util/base36.h>
#include <util/language.h>
#include <util/message.h>
#include <util/param.h>
#include <CuTest.h>
#include <tests.h>
@ -91,7 +92,7 @@ static void test_give_unit(CuTest * tc) {
give_unit(env.src, env.dst, NULL);
CuAssertPtrEquals(tc, env.f2, env.src->faction);
CuAssertIntEquals(tc, 1, env.f2->newbies);
CuAssertPtrEquals(tc, 0, env.f1->units);
CuAssertPtrEquals(tc, NULL, env.f1->units);
CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "give_person"));
CuAssertPtrNotNull(tc, test_find_messagetype(env.f2->msgs, "receive_person"));
test_teardown();
@ -303,7 +304,7 @@ static void test_give_men_requires_contact(CuTest * tc) {
ord = create_order(K_GIVE, env.f1->locale, "%s ALLES PERSONEN", itoa36(env.dst->no));
test_clear_messages(env.f1);
give_cmd(env.src, ord);
CuAssertPtrEquals(tc, 0, test_find_messagetype(env.f1->msgs, "give_person"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(env.f1->msgs, "give_person"));
CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "feedback_no_contact"));
msg_release(msg);
@ -407,7 +408,7 @@ static void test_give_okay(CuTest * tc) {
setup_give(&env);
config_set("rules.give.flags", "0");
CuAssertPtrEquals(tc, 0, check_give(env.src, env.dst, NULL));
CuAssertPtrEquals(tc, NULL, check_give(env.src, env.dst, NULL));
test_teardown();
}
@ -450,7 +451,7 @@ static void test_give_new_unit(CuTest * tc) {
setup_give(&env);
env.dst->number = 0;
fset(env.dst, UFL_ISNEW);
CuAssertPtrEquals(tc, 0, check_give(env.src, env.dst, NULL));
CuAssertPtrEquals(tc, NULL, check_give(env.src, env.dst, NULL));
test_teardown();
}

View file

@ -30,7 +30,7 @@
#include "kernel/ship.h"
#include "kernel/terrain.h"
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/lists.h>
#include <util/macros.h>

View file

@ -29,7 +29,7 @@ static void test_is_guarded(CuTest *tc) {
r = test_create_region(0, 0, NULL);
u1 = test_create_unit(test_create_faction(NULL), r);
u2 = test_create_unit(test_create_faction(rc), r);
CuAssertPtrEquals(tc, 0, is_guarded(r, u1));
CuAssertPtrEquals(tc, NULL, is_guarded(r, u1));
setguard(u2, true);
CuAssertPtrEquals(tc, u2, is_guarded(r, u1));
test_teardown();

View file

@ -19,10 +19,10 @@ without prior permission by the authors of Eressea.
#include "alchemy.h"
#include "magic.h"
#include <util/attrib.h>
#include <util/event.h>
#include <kernel/attrib.h>
#include <kernel/event.h>
#include <util/functions.h>
#include <util/gamedata.h>
#include <kernel/gamedata.h>
#include <util/log.h>
#include <util/macros.h>
#include <util/parser.h>

View file

@ -5,7 +5,6 @@
#include "alchemy.h"
#include "skill.h"
#include "keyword.h"
#include "direction.h"
#include "study.h"
#include "economy.h"
@ -33,8 +32,9 @@
#include <triggers/changerace.h>
#include <triggers/timeout.h>
#include <util/attrib.h>
#include <util/event.h>
#include <kernel/attrib.h>
#include <kernel/event.h>
#include <util/keyword.h>
#include <util/macros.h>
#include <util/parser.h>
#include <util/rand.h>

View file

@ -31,7 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <attributes/movement.h>
/* util includes */
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/log.h>
#include <util/macros.h>

View file

@ -71,8 +71,8 @@ static cJSON *export_a_region(CuTest * tc, const struct terrain_type *terrain, r
json = cJSON_Parse(buf);
CuAssertPtrNotNull(tc, json);
CuAssertIntEquals(tc, cJSON_Object, json->type);
CuAssertPtrEquals(tc, 0, cJSON_GetObjectItem(json, "factions"));
CuAssertPtrEquals(tc, 0, cJSON_GetObjectItem(json, "units"));
CuAssertPtrEquals(tc, NULL, cJSON_GetObjectItem(json, "factions"));
CuAssertPtrEquals(tc, NULL, cJSON_GetObjectItem(json, "units"));
CuAssertPtrNotNull(tc, regs = cJSON_GetObjectItem(json, "regions"));
CuAssertIntEquals(tc, cJSON_Object, regs->type);
result = regs->child;
@ -111,7 +111,7 @@ static void test_export_ocean_region(CuTest * tc) {
test_setup();
terrain = test_create_terrain("ocean", SEA_REGION);
json = export_a_region(tc, terrain, 0);
CuAssertPtrEquals(tc, 0, cJSON_GetObjectItem(json, "name"));
CuAssertPtrEquals(tc, NULL, cJSON_GetObjectItem(json, "name"));
cJSON_Delete(json);
test_teardown();
}

View file

@ -29,9 +29,10 @@ without prior permission by the authors of Eressea.
#include "kernel/spellbook.h"
/* util includes */
#include "util/attrib.h"
#include "kernel/attrib.h"
#include "util/crmessage.h"
#include "util/functions.h"
#include "util/keyword.h"
#include "util/language.h"
#include "util/log.h"
#include "util/message.h"
@ -42,7 +43,6 @@ without prior permission by the authors of Eressea.
/* game modules */
#include "direction.h"
#include "keyword.h"
#include "move.h"
#include "prefix.h"
#include "skill.h"

View file

@ -15,11 +15,11 @@
#include "kernel/order.h"
#include "kernel/terrain.h"
#include "util/keyword.h"
#include "util/language.h"
#include "kernel/calendar.h"
#include "direction.h"
#include "keyword.h"
#include "move.h"
#include "prefix.h"

View file

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 2.6)
project(kernel C)
SET(_DBFILES db/critbit.c)
SET(_DBFILES db/memory.c)
IF(SQLITE3_FOUND)
SET(_DBFILES db/sqlite.c)
@ -12,6 +12,7 @@ ENDIF(SQLITE3_FOUND)
SET(_TEST_FILES
alliance.test.c
ally.test.c
attrib.test.c
build.test.c
building.test.c
# callbacks.test.c
@ -22,12 +23,13 @@ config.test.c
curse.test.c
database.test.c
equipment.test.c
# event.test.c
faction.test.c
gamedata.test.c
group.test.c
item.test.c
messages.test.c
order.test.c
orderdb.test.c
# pathfinder.test.c
plane.test.c
pool.test.c
@ -47,6 +49,7 @@ SET(_FILES
${_DBFILES}
alliance.c
ally.c
attrib.c
build.c
building.c
callbacks.c
@ -55,14 +58,14 @@ command.c
config.c
connection.c
curse.c
database.c
equipment.c
event.c
faction.c
gamedata.c
group.c
item.c
messages.c
order.c
orderdb.c
pathfinder.c
plane.c
pool.c

View file

@ -27,7 +27,7 @@ without prior permission by the authors of Eressea.
#include <attributes/key.h>
/* util includes */
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/language.h>
#include <util/parser.h>

View file

@ -34,14 +34,14 @@ static void test_alliance_make(CuTest *tc) {
CuAssertStrEquals(tc, "Hodor", al->name);
CuAssertIntEquals(tc, 1, al->id);
CuAssertIntEquals(tc, 0, al->flags);
CuAssertPtrEquals(tc, 0, al->members);
CuAssertPtrEquals(tc, 0, al->_leader);
CuAssertPtrEquals(tc, 0, al->allies);
CuAssertPtrEquals(tc, NULL, al->members);
CuAssertPtrEquals(tc, NULL, al->_leader);
CuAssertPtrEquals(tc, NULL, al->allies);
CuAssertPtrEquals(tc, al, findalliance(1));
CuAssertPtrEquals(tc, al, alliances);
free_alliances();
CuAssertPtrEquals(tc, 0, findalliance(1));
CuAssertPtrEquals(tc, 0, alliances);
CuAssertPtrEquals(tc, NULL, findalliance(1));
CuAssertPtrEquals(tc, NULL, alliances);
test_teardown();
}
@ -50,8 +50,8 @@ static void test_alliance_join(CuTest *tc) {
alliance * al;
setup_alliance(&fix);
CuAssertPtrEquals(tc, 0, fix.f1->alliance);
CuAssertPtrEquals(tc, 0, fix.f2->alliance);
CuAssertPtrEquals(tc, NULL, fix.f1->alliance);
CuAssertPtrEquals(tc, NULL, fix.f2->alliance);
al = makealliance(1, "Hodor");
setalliance(fix.f1, al);
CuAssertPtrEquals(tc, fix.f1, alliance_get_leader(al));
@ -99,7 +99,7 @@ static void test_alliance_cmd(CuTest *tc) {
unit_addorder(u2, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_JOIN], itoa36(42)));
CuAssertTrue(tc, is_allied(u1->faction, u1->faction));
CuAssertTrue(tc, !is_allied(u1->faction, u2->faction));
CuAssertPtrEquals(tc, 0, f_get_alliance(u1->faction));
CuAssertPtrEquals(tc, NULL, f_get_alliance(u1->faction));
alliance_cmd();
al = f_get_alliance(u1->faction);
CuAssertPtrNotNull(tc, al);
@ -126,10 +126,10 @@ static void test_alliance_limits(CuTest *tc) {
unit_addorder(u1, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_INVITE], itoa36(u2->faction->no)));
unit_addorder(u2, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_JOIN], itoa36(42)));
CuAssertTrue(tc, !is_allied(u1->faction, u2->faction));
CuAssertPtrEquals(tc, 0, f_get_alliance(u1->faction));
CuAssertPtrEquals(tc, NULL, f_get_alliance(u1->faction));
alliance_cmd();
CuAssertPtrNotNull(tc, f_get_alliance(u1->faction));
CuAssertPtrEquals(tc, 0, f_get_alliance(u2->faction));
CuAssertPtrEquals(tc, NULL, f_get_alliance(u2->faction));
CuAssertTrue(tc, !is_allied(u1->faction, u2->faction));
CuAssertPtrNotNull(tc, test_find_messagetype(u2->faction->msgs, "too_many_units_in_alliance"));
test_teardown();
@ -152,7 +152,7 @@ static void test_alliance_cmd_kick(CuTest *tc) {
CuAssertTrue(tc, is_allied(u1->faction, u2->faction));
alliance_cmd();
CuAssertTrue(tc, !is_allied(u1->faction, u2->faction));
CuAssertPtrEquals(tc, 0, f_get_alliance(u2->faction));
CuAssertPtrEquals(tc, NULL, f_get_alliance(u2->faction));
test_teardown();
}
@ -168,10 +168,10 @@ static void test_alliance_cmd_no_invite(CuTest *tc) {
unit_addorder(u2, create_order(K_ALLIANCE, u1->faction->locale, "%s %s", alliance_kwd[ALLIANCE_JOIN], itoa36(42)));
CuAssertTrue(tc, is_allied(u1->faction, u1->faction));
CuAssertTrue(tc, !is_allied(u1->faction, u2->faction));
CuAssertPtrEquals(tc, 0, f_get_alliance(u1->faction));
CuAssertPtrEquals(tc, NULL, f_get_alliance(u1->faction));
alliance_cmd();
CuAssertPtrNotNull(tc, f_get_alliance(u1->faction));
CuAssertPtrEquals(tc, 0, f_get_alliance(u2->faction));
CuAssertPtrEquals(tc, NULL, f_get_alliance(u2->faction));
CuAssertTrue(tc, !is_allied(u1->faction, u2->faction));
test_teardown();
}
@ -193,7 +193,7 @@ static void test_alliance_cmd_leave(CuTest *tc) {
CuAssertTrue(tc, is_allied(u1->faction, u2->faction));
alliance_cmd();
CuAssertTrue(tc, !is_allied(u1->faction, u2->faction));
CuAssertPtrEquals(tc, 0, f_get_alliance(u1->faction));
CuAssertPtrEquals(tc, NULL, f_get_alliance(u1->faction));
test_teardown();
}

View file

@ -10,9 +10,9 @@
#include "objtypes.h"
#include "plane.h"
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/strings.h>
#include <util/gamedata.h>
#include <kernel/gamedata.h>
#include <storage.h>

View file

@ -15,8 +15,8 @@ static void test_ally(CuTest * tc)
CuAssertPtrEquals(tc, f1, ally_find(al, f1)->faction);
ally_remove(&al, f1);
CuAssertPtrEquals(tc, 0, al);
CuAssertPtrEquals(tc, 0, ally_find(al, f1));
CuAssertPtrEquals(tc, NULL, al);
CuAssertPtrEquals(tc, NULL, ally_find(al, f1));
}
static void test_ally_null(CuTest * tc)
@ -28,7 +28,7 @@ static void test_ally_null(CuTest * tc)
CuAssertPtrNotNull(tc, a1);
CuAssertPtrNotNull(tc, a2);
CuAssertPtrEquals(tc, a2, a1->next);
CuAssertPtrEquals(tc, 0, a2->next);
CuAssertPtrEquals(tc, NULL, a2->next);
free(a1);
free(a2);
}

View file

@ -19,12 +19,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <platform.h>
#include "attrib.h"
#include "gamedata.h"
#include "log.h"
#include "variant.h"
#include "storage.h"
#include "strings.h"
#include <util/log.h>
#include <util/strings.h>
#include <util/variant.h>
#include <kernel/gamedata.h>
#include <storage.h>
#include <critbit.h>
#include <assert.h>

View file

@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define ATTRIB_H
#include <stdbool.h>
#include "variant.h"
#include <util/variant.h>
#ifdef __cplusplus
extern "C" {
#endif

View file

@ -1,7 +1,7 @@
#include <platform.h>
#include "attrib.h"
#include <util/gamedata.h>
#include <kernel/gamedata.h>
#include <util/strings.h>
#include <storage.h>
@ -15,11 +15,11 @@ static void test_attrib_new(CuTest * tc)
attrib_type at_test = { "test" };
attrib * a;
CuAssertPtrNotNull(tc, (a = a_new(&at_test)));
CuAssertPtrEquals(tc, 0, a->next);
CuAssertPtrEquals(tc, 0, a->nexttype);
CuAssertPtrEquals(tc, NULL, a->next);
CuAssertPtrEquals(tc, NULL, a->nexttype);
CuAssertPtrEquals(tc, (void *)a->type, (void *)&at_test);
a_remove(&a, a);
CuAssertPtrEquals(tc, 0, a);
CuAssertPtrEquals(tc, NULL, a);
}
static void test_attrib_add(CuTest * tc)
@ -51,7 +51,7 @@ static void test_attrib_remove_self(CuTest * tc) {
CuAssertPtrNotNull(tc, a_add(&alist, a_new(&at_foo)));
CuAssertPtrNotNull(tc, a = a_add(&alist, a_new(&at_foo)));
CuAssertPtrEquals(tc, a, alist->next);
CuAssertPtrEquals(tc, 0, alist->nexttype);
CuAssertPtrEquals(tc, NULL, alist->nexttype);
CuAssertIntEquals(tc, 1, a_remove(&alist, alist));
CuAssertPtrEquals(tc, a, alist);
a_removeall(&alist, NULL);
@ -66,11 +66,11 @@ static void test_attrib_removeall(CuTest * tc) {
a_add(&alist, a_new(&at_foo));
a_removeall(&alist, &at_foo);
CuAssertPtrEquals(tc, a, alist);
CuAssertPtrEquals(tc, 0, alist->next);
CuAssertPtrEquals(tc, NULL, alist->next);
a_add(&alist, a_new(&at_bar));
a_add(&alist, a_new(&at_foo));
a_removeall(&alist, NULL);
CuAssertPtrEquals(tc, 0, alist);
CuAssertPtrEquals(tc, NULL, alist);
}
static void test_attrib_remove(CuTest * tc)
@ -83,7 +83,7 @@ static void test_attrib_remove(CuTest * tc)
CuAssertIntEquals(tc, 1, a_remove(&alist, a));
CuAssertPtrNotNull(tc, alist);
CuAssertIntEquals(tc, 1, a_remove(&alist, alist));
CuAssertPtrEquals(tc, 0, alist);
CuAssertPtrEquals(tc, NULL, alist);
}
static void test_attrib_nexttype(CuTest * tc)
@ -92,16 +92,16 @@ static void test_attrib_nexttype(CuTest * tc)
attrib_type at_bar = { "bar" };
attrib *a, *alist = 0;
CuAssertPtrNotNull(tc, (a = a_new(&at_foo)));
CuAssertPtrEquals(tc, 0, a->nexttype);
CuAssertPtrEquals(tc, NULL, a->nexttype);
CuAssertPtrEquals(tc, a, a_add(&alist, a));
CuAssertPtrEquals(tc, 0, alist->nexttype);
CuAssertPtrEquals(tc, NULL, alist->nexttype);
CuAssertPtrNotNull(tc, a_add(&alist, a_new(&at_foo)));
CuAssertPtrEquals(tc, 0, alist->nexttype);
CuAssertPtrEquals(tc, NULL, alist->nexttype);
CuAssertPtrNotNull(tc, (a = a_add(&alist, a_new(&at_bar))));
CuAssertPtrEquals(tc, a, alist->nexttype);
CuAssertPtrEquals(tc, 0, a->nexttype);
CuAssertPtrEquals(tc, NULL, a->nexttype);
a_remove(&alist, alist);
CuAssertPtrEquals(tc, a, alist->nexttype);

View file

@ -33,10 +33,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* kernel includes */
#include <kernel/ally.h>
#include <kernel/alliance.h>
#include <kernel/connection.h>
#include <kernel/attrib.h>
#include <kernel/building.h>
#include <kernel/config.h>
#include <kernel/connection.h>
#include <kernel/curse.h>
#include <kernel/event.h>
#include <kernel/faction.h>
#include <kernel/group.h>
#include <kernel/item.h>
@ -52,12 +54,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/unit.h>
/* from libutil */
#include <util/attrib.h>
#include <util/base36.h>
#include <util/event.h>
#include <util/goodies.h>
#include <util/language.h>
#include <util/log.h>
#include <util/param.h>
#include <util/parser.h>
#include <util/resolve.h>
@ -79,7 +80,7 @@ struct building *getbuilding(const struct region *r)
ship *getship(const struct region * r)
{
ship *sh, *sx = findship(getshipid());
ship *sh, *sx = findship(getid());
for (sh = r->ships; sh; sh = sh->next) {
if (sh == sx)
return sh;

View file

@ -1,19 +1,24 @@
#ifdef _MSC_VER
#include <platform.h>
#include <kernel/config.h>
#endif
#include <kernel/messages.h>
#include "alchemy.h"
#include "types.h"
#include "build.h"
#include "guard.h"
#include "order.h"
#include "unit.h"
#include "building.h"
#include "config.h"
#include "faction.h"
#include "region.h"
#include "race.h"
#include "guard.h"
#include "item.h"
#include <util/language.h>
#include "messages.h"
#include "order.h"
#include "race.h"
#include "region.h"
#include "types.h"
#include "unit.h"
#include "util/language.h"
#include "util/param.h"
#include <CuTest.h>
#include <tests.h>
@ -197,8 +202,8 @@ static void test_build_building_no_materials(CuTest *tc) {
set_level(u, SK_BUILDING, 1);
u->orders = create_order(K_MAKE, u->faction->locale, 0);
CuAssertIntEquals(tc, ENOMATERIALS, build_building(u, btype, 0, 4, u->orders));
CuAssertPtrEquals(tc, 0, u->region->buildings);
CuAssertPtrEquals(tc, 0, u->building);
CuAssertPtrEquals(tc, NULL, u->region->buildings);
CuAssertPtrEquals(tc, NULL, u->building);
teardown_build(&bf);
}
@ -262,7 +267,7 @@ static void test_build_destroy_road(CuTest *tc)
CuAssertIntEquals(tc, 0, destroy_cmd(u, ord));
CuAssertIntEquals(tc, 100, rroad(r, D_EAST));
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "destroy_road"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "destroy_road"));
set_level(u, SK_ROAD_BUILDING, 1);
CuAssertIntEquals(tc, 0, destroy_cmd(u, ord));
@ -319,7 +324,7 @@ static void test_build_destroy_road_guard(CuTest *tc)
CuAssertIntEquals(tc, 0, destroy_cmd(u, ord));
CuAssertIntEquals(tc, 100, rroad(r, D_EAST));
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error70"));
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "destroy_road"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "destroy_road"));
test_clear_messages(f);
setguard(ug, false);

View file

@ -38,13 +38,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "lighthouse.h"
/* util includes */
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/event.h>
#include <kernel/event.h>
#include <util/functions.h>
#include <util/gamedata.h>
#include <kernel/gamedata.h>
#include <util/language.h>
#include <util/log.h>
#include <util/param.h>
#include <util/resolve.h>
#include <util/strings.h>
#include <util/umlaut.h>
@ -128,14 +129,6 @@ static void free_buildingtype(void *ptr) {
free(btype);
}
void free_buildingtypes(void) {
cb_clear(&cb_bldgtypes);
selist_foreach(buildingtypes, free_buildingtype);
selist_free(buildingtypes);
buildingtypes = 0;
++bt_changes;
}
building_type *bt_get_or_create(const char *name)
{
assert(name && name[0]);
@ -264,17 +257,28 @@ building *findbuilding(int i)
static local_names *bnames;
/* Find the building type for a given localized name (as seen by the user). Useful for parsing
* orders. The inverse of locale_string(lang, btype->_name), sort of. */
const building_type *findbuildingtype(const char *name,
const struct locale *lang)
{
variant type;
local_names *bn = bnames;
static void free_bnames(void) {
while (bnames) {
local_names *bn = bnames;
bnames = bnames->next;
freetokens(bn->names);
free(bn);
}
}
static local_names *get_bnames(const struct locale *lang)
{
static int config;
local_names *bn;
if (bt_changed(&config)) {
free_bnames();
}
bn = bnames;
while (bn) {
if (bn->lang == lang)
if (bn->lang == lang) {
break;
}
bn = bn->next;
}
if (!bn) {
@ -291,14 +295,26 @@ const building_type *findbuildingtype(const char *name,
const char *n = LOC(lang, btype->_name);
if (!n) {
log_error("building type %s has no translation in %s",
btype->_name, locale_name(lang));
} else {
btype->_name, locale_name(lang));
}
else {
variant type;
type.v = (void *)btype;
addtoken((struct tnode **)&bn->names, n, type);
}
}
bnames = bn;
}
return bn;
}
/* Find the building type for a given localized name (as seen by the user). Useful for parsing
* orders. The inverse of locale_string(lang, btype->_name), sort of. */
const building_type *findbuildingtype(const char *name,
const struct locale *lang)
{
variant type;
local_names *bn = get_bnames(lang);
if (findtoken(bn->names, name, &type) == E_TOK_NOMATCH)
return NULL;
return (const building_type *)type.v;
@ -870,3 +886,12 @@ int cmp_current_owner(const building * b, const building * a)
}
return 0;
}
void free_buildingtypes(void) {
free_bnames();
cb_clear(&cb_bldgtypes);
selist_foreach(buildingtypes, free_buildingtype);
selist_free(buildingtypes);
buildingtypes = 0;
++bt_changes;
}

View file

@ -37,8 +37,8 @@ static void test_command(CuTest * tc) {
st = stree_create();
CuAssertPtrNotNull(tc, st);
CuAssertPtrEquals(tc, loc, (struct locale *)st->lang);
CuAssertPtrEquals(tc, 0, st->root);
CuAssertPtrEquals(tc, 0, st->next);
CuAssertPtrEquals(tc, NULL, st->root);
CuAssertPtrEquals(tc, NULL, st->next);
stree_add(st, "two", parser_two);
stree_add(st, "six", parser_six);
CuAssertPtrNotNull(tc, st->root);

View file

@ -33,7 +33,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "faction.h"
#include "group.h"
#include "item.h"
#include "keyword.h"
#include "messages.h"
#include "move.h"
#include "objtypes.h"
@ -50,15 +49,18 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "unit.h"
/* util includes */
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <kernel/event.h>
#include <util/base36.h>
#include <util/crmessage.h>
#include <util/event.h>
#include <util/keyword.h>
#include <util/language.h>
#include <util/functions.h>
#include <util/log.h>
#include <util/lists.h>
#include <util/macros.h>
#include <util/param.h>
#include <util/parser.h>
#include <util/path.h>
#include <util/rand.h>
@ -91,54 +93,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#endif
struct settings global;
const char *parameters[MAXPARAMS] = {
"LOCALE",
"ALLES",
"JEDEM",
"BAUERN",
"BURG",
"EINHEIT",
"PRIVAT",
"HINTEN",
"KOMMANDO",
"KRAEUTER",
"NICHT",
"NAECHSTER",
"PARTEI",
"ERESSEA",
"PERSONEN",
"REGION",
"SCHIFF",
"SILBER",
"STRASSEN",
"TEMP",
"FLIEHE",
"GEBAEUDE",
"GIB", /* HELFE GIB */
"KAEMPFE",
"DURCHREISE",
"BEWACHE",
"ZAUBER",
"PAUSE",
"VORNE",
"AGGRESSIV",
"DEFENSIV",
"STUFE",
"HELFE",
"FREMDES",
"AURA",
"HINTER",
"VOR",
"ANZAHL",
"GEGENSTAENDE",
"TRAENKE",
"GRUPPE",
"PARTEITARNUNG",
"BAEUME",
"ALLIANZ",
"AUTO"
};
int findoption(const char *s, const struct locale *lang)
{
void **tokens = get_translations(lang, UT_OPTIONS);
@ -150,78 +104,6 @@ int findoption(const char *s, const struct locale *lang)
return NODIRECTION;
}
param_t findparam(const char *s, const struct locale * lang)
{
param_t result = NOPARAM;
char buffer[64];
char * str = s ? transliterate(buffer, sizeof(buffer) - sizeof(int), s) : 0;
if (str && *str) {
int i;
void * match;
void **tokens = get_translations(lang, UT_PARAMS);
critbit_tree *cb = (critbit_tree *)*tokens;
if (!cb) {
log_warning("no parameters defined in locale %s", locale_name(lang));
}
else if (cb_find_prefix(cb, str, strlen(str), &match, 1, 0)) {
cb_get_kv(match, &i, sizeof(int));
result = (param_t)i;
}
}
return result;
}
param_t findparam_block(const char *s, const struct locale *lang, bool any_locale)
{
param_t p;
if (!s || s[0] == '@') {
return NOPARAM;
}
p = findparam(s, lang);
if (any_locale && p==NOPARAM) {
const struct locale *loc;
for (loc=locales;loc;loc=nextlocale(loc)) {
if (loc!=lang) {
p = findparam(s, loc);
if (p==P_FACTION || p==P_GAMENAME) {
break;
}
}
}
}
return p;
}
param_t findparam_ex(const char *s, const struct locale * lang)
{
param_t result = findparam(s, lang);
if (result == NOPARAM) {
const building_type *btype = findbuildingtype(s, lang);
if (btype != NULL)
return P_GEBAEUDE;
}
return (result == P_BUILDING) ? P_GEBAEUDE : result;
}
bool isparam(const char *s, const struct locale * lang, param_t param)
{
assert(s);
if (s[0] > '@') {
param_t p = (param == P_GEBAEUDE) ? findparam_ex(s, lang) : findparam(s, lang);
return p == param;
}
return false;
}
param_t getparam(const struct locale * lang)
{
char token[64];
const char *s = gettoken(token, sizeof(token));
return s ? findparam(s, lang) : NOPARAM;
}
/* -- Erschaffung neuer Einheiten ------------------------------ */
static const char *forbidden[] = { "t", "te", "tem", "temp", NULL };
@ -267,17 +149,6 @@ int newcontainerid(void)
return random_no;
}
static const char * parameter_key(int i)
{
assert(i < MAXPARAMS && i >= 0);
return parameters[i];
}
void init_parameters(struct locale *lang) {
init_translations(lang, UT_PARAMS, parameter_key, MAXPARAMS);
}
void init_terrains_translation(const struct locale *lang) {
void **tokens;
const terrain_type *terrain;
@ -368,6 +239,7 @@ static void init_magic(struct locale *lang)
free(sstr);
}
}
void init_locale(struct locale *lang)
{
init_magic(lang);

View file

@ -44,12 +44,6 @@ extern "C" {
int findoption(const char *s, const struct locale *lang);
param_t findparam(const char *s, const struct locale *lang);
param_t findparam_block(const char *s, const struct locale *lang, bool any_locale);
param_t findparam_ex(const char *s, const struct locale * lang);
bool isparam(const char *s, const struct locale * lang, param_t param);
param_t getparam(const struct locale *lang);
const char * game_name(void);
const char * game_mailcmd(void);
int game_id(void);
@ -132,12 +126,9 @@ extern "C" {
struct order *default_order(const struct locale *lang);
void init_parameters(struct locale *lang);
void free_gamedata(void);
void free_config(void);
extern const char *parameters[];
extern settings global;
#ifdef __cplusplus

View file

@ -5,9 +5,12 @@
#include <kernel/terrain.h>
#include <kernel/unit.h>
#include <kernel/order.h>
#include <util/language.h>
#include <util/base36.h>
#include <util/attrib.h>
#include <util/language.h>
#include <util/param.h>
#include <kernel/attrib.h>
#include <iniparser.h>

View file

@ -26,9 +26,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "terrain.h"
#include "unit.h"
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/gamedata.h>
#include <kernel/gamedata.h>
#include <util/language.h>
#include <util/log.h>
#include <util/macros.h>

View file

@ -34,9 +34,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "unit.h"
/* util includes */
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/gamedata.h>
#include <kernel/gamedata.h>
#include <util/goodies.h>
#include <util/language.h>
#include <util/log.h>

View file

@ -4,9 +4,9 @@
#include <kernel/region.h>
#include <kernel/save.h>
#include <kernel/unit.h>
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/rng.h>
#include <util/gamedata.h>
#include <kernel/gamedata.h>
#include <util/message.h>
#include <binarystore.h>
#include <filestream.h>

View file

@ -1,46 +0,0 @@
#include <platform.h>
#include "database.h"
#include <platform.h>
#include <kernel/config.h>
#include <kernel/faction.h>
#include <kernel/database.h>
#include <kernel/orderdb.h>
#include <util/log.h>
#include "db/driver.h"
order_data *dblib_load_order(int id)
{
if (id > 0) {
return db_driver_order_load(id);
}
return NULL;
}
int dblib_save_order(order_data *od)
{
if (od->_str) {
return db_driver_order_save(od);
}
return 0;
}
int dblib_save_faction(const faction *f, int turn) {
return db_driver_faction_save(f->uid, f->no, turn, f->email, f->_password);
}
void dblib_open(void)
{
const char *dbname;
dbname = config_get("game.dbswap");
db_driver_open(DB_SWAP, dbname);
}
void dblib_close(void)
{
db_driver_close(DB_SWAP);
}

View file

@ -1,23 +0,0 @@
#ifndef H_DATABASE
#define H_DATABASE
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
struct order_data;
struct faction;
void dblib_open(void);
void dblib_close(void);
struct order_data *dblib_load_order(int id);
int dblib_save_order(struct order_data *od);
int dblib_save_faction(const struct faction *f, int turn);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,8 +1,9 @@
#include <platform.h>
#include <kernel/config.h>
#include <kernel/faction.h>
#include <kernel/order.h>
#include "database.h"
#include "db/driver.h"
#include "orderdb.h"
#include <CuTest.h>
@ -39,9 +40,9 @@ static void test_update_faction(CuTest *tc) {
test_setup();
f = test_create_faction(NULL);
uid = dblib_save_faction(f, 0);
uid = db_driver_faction_save(f->uid, f->no, 0, f->email, f->_password);
f->uid = uid;
uid = dblib_save_faction(f, 0);
uid = db_driver_faction_save(f->uid, f->no, 0, f->email, f->_password);
CuAssertIntEquals(tc, f->uid, uid);
test_teardown();
}

View file

@ -4,36 +4,35 @@
#include <platform.h>
#include "driver.h"
#include <kernel/config.h>
#include <kernel/orderdb.h>
#include <assert.h>
#include <string.h>
static DB *g_dbp;
void db_driver_open(void)
void db_driver_open(database_t db, const char *dbname)
{
int ret;
u_int32_t flags = DB_CREATE;
const char * dbname;
if (db == DB_SWAP) {
int ret;
u_int32_t flags = DB_CREATE;
dbname = config_get("game.dbname");
ret = db_create(&g_dbp, NULL, 0);
assert(ret==0);
ret = db_create(&g_dbp, NULL, 0);
assert(ret == 0);
ret = g_dbp->open(g_dbp, NULL, dbname, NULL, DB_RECNO, flags, 0);
assert(ret==0);
ret = g_dbp->open(g_dbp, NULL, dbname, NULL, DB_RECNO, flags, 0);
assert(ret == 0);
}
}
void db_driver_close(void)
void db_driver_close(database_t db)
{
int ret;
ret = g_dbp->close(g_dbp, 0);
assert(ret==0);
if (db == DB_SWAP) {
int ret;
ret = g_dbp->close(g_dbp, 0);
assert(ret == 0);
}
}
int db_driver_order_save(struct order_data *od)
int db_driver_order_save(const char *str)
{
int ret;
DBT key, data;
@ -46,18 +45,13 @@ int db_driver_order_save(struct order_data *od)
key.size = key.ulen = sizeof(recno);
key.flags = DB_DBT_USERMEM;
data.data = (void *)od->_str;
data.size = data.ulen = strlen(od->_str) + 1;
data.size = data.ulen = strlen(str) + 1;
data.flags = DB_DBT_USERMEM;
ret = g_dbp->put(g_dbp, NULL, &key, &data, DB_APPEND);
assert(ret == 0);
return (int)recno;
}
int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password)
{
return -1;
}
struct order_data *db_driver_order_load(int id)
{
int ret;
@ -79,3 +73,8 @@ struct order_data *db_driver_order_load(int id)
return od;
}
int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password)
{
return -1;
}

View file

@ -1,72 +0,0 @@
#include <platform.h>
#include "driver.h"
#include <kernel/orderdb.h>
#include <util/log.h>
#include <critbit.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
static critbit_tree cb_orders = { 0 };
static int auto_id = -1;
struct cb_entry {
int id;
order_data *data;
};
order_data *db_driver_order_load(int id)
{
void * match;
assert(id>0);
if (cb_find_prefix(&cb_orders, &id, sizeof(id), &match, 1, 0) > 0) {
struct cb_entry *ent = (struct cb_entry *)match;
order_data * od = ent->data;
++od->_refcount;
return od;
}
return NULL;
}
int db_driver_order_save(order_data *od)
{
struct cb_entry ent;
assert(od && od->_str);
++od->_refcount;
ent.id = ++auto_id;
ent.data = od;
cb_insert(&cb_orders, &ent, sizeof(ent));
return ent.id;
}
int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password)
{
return -1;
}
static int free_data_cb(const void *match, const void *key, size_t keylen,
void *udata)
{
struct cb_entry * ent = (struct cb_entry *)match;
order_data *od = ent->data;
odata_release(od);
return 0;
}
void db_driver_open(void)
{
assert(auto_id == -1);
auto_id = 0;
}
void db_driver_close(void)
{
cb_foreach(&cb_orders, NULL, 0, free_data_cb, NULL);
cb_clear(&cb_orders);
auto_id = -1;
}

View file

@ -1,7 +1,11 @@
#pragma once
#include <stddef.h>
struct order_data;
extern void odata_create(struct order_data **pdata, size_t len, const char *str);
typedef enum database_t {
DB_SWAP,
DB_GAME,
@ -9,6 +13,6 @@ typedef enum database_t {
int db_driver_open(database_t db, const char *dbname);
void db_driver_close(database_t db);
int db_driver_order_save(struct order_data *od);
int db_driver_order_save(const char *str);
struct order_data *db_driver_order_load(int id);
int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password);

70
src/kernel/db/memory.c Normal file
View file

@ -0,0 +1,70 @@
#ifdef _MSC_VER
#include <platform.h>
#endif
#include "driver.h"
#include <util/log.h>
#include <util/strings.h>
#include <selist.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
static selist * g_orders;
static int auto_id = -1;
struct order_data *db_driver_order_load(int id)
{
void * match;
assert(id>0);
match = selist_get(g_orders, id - 1);
if (match) {
char * str = (char *)match;
struct order_data * od = NULL;
odata_create(&od, strlen(str), str);
return od;
}
return NULL;
}
int db_driver_order_save(const char * str)
{
assert(str);
selist_push(&g_orders, str_strdup(str));
return ++auto_id;
}
int db_driver_faction_save(int id, int no, int turn, const char *email, const char *password)
{
return -1;
}
static void free_data_cb(void *match)
{
char *str = (char *)match;
free(str);
}
int db_driver_open(database_t db, const char *dbname)
{
(void)dbname;
if (db == DB_SWAP) {
assert(auto_id == -1);
auto_id = 0;
return 0;
}
return -1;
}
void db_driver_close(database_t db)
{
if (db == DB_SWAP) {
selist_foreach(g_orders, free_data_cb);
selist_free(g_orders);
g_orders = NULL;
auto_id = -1;
}
}

View file

@ -1,8 +1,6 @@
#include <platform.h>
#include <kernel/config.h>
#include <kernel/database.h>
#include <kernel/orderdb.h>
#include <util/log.h>
@ -13,6 +11,7 @@
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static sqlite3 *g_game_db;
@ -25,9 +24,9 @@ static sqlite3_stmt * g_stmt_insert_faction;
static int g_order_batchsize;
static int g_order_tx_size;
order_data *db_driver_order_load(int id)
struct order_data *db_driver_order_load(int id)
{
order_data * od = NULL;
struct order_data * od = NULL;
int err;
ERRNO_CHECK();
@ -58,12 +57,12 @@ order_data *db_driver_order_load(int id)
return NULL;
}
int db_driver_order_save(order_data *od)
int db_driver_order_save(const char *str)
{
int err;
sqlite3_int64 id;
assert(od && od->_str);
assert(str);
ERRNO_CHECK();
@ -76,7 +75,7 @@ int db_driver_order_save(order_data *od)
err = sqlite3_reset(g_stmt_insert_order);
assert(err == SQLITE_OK);
err = sqlite3_bind_text(g_stmt_insert_order, 1, od->_str, -1, SQLITE_STATIC);
err = sqlite3_bind_text(g_stmt_insert_order, 1, str, -1, SQLITE_STATIC);
assert(err == SQLITE_OK);
err = sqlite3_step(g_stmt_insert_order);
assert(err == SQLITE_DONE);
@ -181,11 +180,14 @@ static int db_open_swap(const char *dbname) {
return 0;
}
static const char *g_swapname;
int db_driver_open(database_t db, const char *dbname)
{
ERRNO_CHECK();
if (db == DB_SWAP) {
g_swapname = dbname;
return db_open_swap(dbname);
}
else if (db == DB_GAME) {
@ -207,6 +209,13 @@ void db_driver_close(database_t db)
assert(err == SQLITE_OK);
err = sqlite3_close(g_temp_db);
assert(err == SQLITE_OK);
if (g_swapname) {
FILE * F = fopen(g_swapname, "r");
if (F) {
fclose(F);
remove(g_swapname);
}
}
}
else if (db == DB_GAME) {
assert(g_game_db);

View file

@ -18,12 +18,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <platform.h>
#include "event.h"
#include "attrib.h"
/* util includes */
#include "attrib.h"
#include "gamedata.h"
#include "log.h"
#include "strings.h"
#include <kernel/gamedata.h>
#include <util/log.h>
#include <util/strings.h>
#include <storage.h>

View file

@ -22,7 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
extern "C" {
#endif
#include "variant.h"
#include <util/variant.h>
struct attrib;
struct trigger;

View file

@ -42,10 +42,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <attributes/racename.h>
/* util includes */
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/event.h>
#include <util/gamedata.h>
#include <kernel/event.h>
#include <kernel/gamedata.h>
#include <util/goodies.h>
#include <util/lists.h>
#include <util/language.h>

View file

@ -57,7 +57,7 @@ static void test_remove_empty_factions_alliance(CuTest *tc) {
CuAssertPtrEquals(tc, f, alliance_get_leader(al));
CuAssertIntEquals(tc, 1, selist_length(al->members));
remove_empty_factions();
CuAssertPtrEquals(tc, 0, al->_leader);
CuAssertPtrEquals(tc, NULL, al->_leader);
CuAssertIntEquals(tc, 0, selist_length(al->members));
test_teardown();
}
@ -75,7 +75,7 @@ static void test_remove_empty_factions(CuTest *tc) {
CuAssertIntEquals(tc, false, f->_alive);
CuAssertPtrEquals(tc, fm, factions);
CuAssertPtrEquals(tc, NULL, fm->next);
CuAssertPtrEquals(tc, 0, findfaction(fno));
CuAssertPtrEquals(tc, NULL, findfaction(fno));
CuAssertPtrEquals(tc, fm, get_monsters());
test_teardown();
}
@ -99,7 +99,7 @@ static void test_remove_dead_factions(CuTest *tc) {
f->_alive = false;
fno = f->no;
remove_empty_factions();
CuAssertPtrEquals(tc, 0, findfaction(fno));
CuAssertPtrEquals(tc, NULL, findfaction(fno));
CuAssertPtrEquals(tc, fm, get_monsters());
test_teardown();
}
@ -162,7 +162,7 @@ static void test_set_origin(CuTest *tc) {
test_setup();
pl = create_new_plane(0, "", 0, 19, 0, 19, 0);
f = test_create_faction(NULL);
CuAssertPtrEquals(tc, 0, f->ursprung);
CuAssertPtrEquals(tc, NULL, f->ursprung);
faction_setorigin(f, 0, 1, 1);
CuAssertIntEquals(tc, 0, f->ursprung->id);
CuAssertIntEquals(tc, 1, f->ursprung->x);
@ -250,7 +250,7 @@ static void test_set_email(CuTest *tc) {
faction_setemail(f, "bugs@eressea.de");
CuAssertStrEquals(tc, "bugs@eressea.de", f->email);
faction_setemail(f, NULL);
CuAssertPtrEquals(tc, 0, f->email);
CuAssertPtrEquals(tc, NULL, f->email);
CuAssertStrEquals(tc, "", faction_getemail(f));
test_teardown();
}

View file

@ -1,7 +1,8 @@
#include <platform.h>
#include "gamedata.h"
#include "log.h"
#include <util/log.h>
#include <storage.h>
#include <filestream.h>

View file

@ -30,9 +30,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <attributes/raceprefix.h>
/* util includes */
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/gamedata.h>
#include <kernel/gamedata.h>
#include <util/resolve.h>
#include <util/strings.h>
#include <util/unicode.h>

View file

@ -8,8 +8,8 @@
#include "region.h"
#include "save.h"
#include <util/gamedata.h>
#include <util/attrib.h>
#include <kernel/gamedata.h>
#include <kernel/attrib.h>
#include <attributes/key.h>
#include <stream.h>
@ -35,7 +35,7 @@ static void test_group_readwrite_dead_faction(CuTest *tc) {
f = test_create_faction(NULL);
fno = f->no;
CuAssertPtrEquals(tc, f, factions);
CuAssertPtrEquals(tc, 0, f->next);
CuAssertPtrEquals(tc, NULL, f->next);
f2 = test_create_faction(NULL);
CuAssertPtrEquals(tc, f2, factions->next);
u = test_create_unit(f2, test_create_region(0, 0, NULL));
@ -58,14 +58,14 @@ static void test_group_readwrite_dead_faction(CuTest *tc) {
read_game(&data);
mstream_done(&data.strm);
gamedata_done(&data);
CuAssertPtrEquals(tc, 0, findfaction(fno));
CuAssertPtrEquals(tc, NULL, findfaction(fno));
f2 = factions;
CuAssertPtrNotNull(tc, f2);
u = f2->units;
CuAssertPtrNotNull(tc, u);
g = get_group(u);
CuAssertPtrNotNull(tc, g);
CuAssertPtrEquals(tc, 0, g->allies);
CuAssertPtrEquals(tc, NULL, g->allies);
test_teardown();
}
@ -106,11 +106,11 @@ static void test_group_readwrite(CuTest * tc)
CuAssertPtrNotNull(tc, f->groups->next);
CuAssertIntEquals(tc, 43, f->groups->next->gid);
CuAssertStrEquals(tc, "Egoisten", f->groups->next->name);
CuAssertPtrEquals(tc, 0, f->groups->allies);
CuAssertPtrEquals(tc, NULL, f->groups->allies);
g = f->groups->next;
CuAssertIntEquals(tc, 44, key_get(g->attribs, 44));
CuAssertPtrNotNull(tc, g->allies);
CuAssertPtrEquals(tc, 0, g->allies->next);
CuAssertPtrEquals(tc, NULL, g->allies->next);
CuAssertPtrEquals(tc, f, g->allies->faction);
CuAssertIntEquals(tc, HELP_GIVE, g->allies->status);
test_teardown();
@ -135,7 +135,7 @@ static void test_group(CuTest * tc)
CuAssertIntEquals(tc, 1, g->members);
set_group(u, 0);
CuAssertIntEquals(tc, 0, g->members);
CuAssertPtrEquals(tc, 0, get_group(u));
CuAssertPtrEquals(tc, NULL, get_group(u));
set_group(u, g);
CuAssertIntEquals(tc, 1, g->members);
CuAssertPtrEquals(tc, g, get_group(u));

View file

@ -35,7 +35,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "unit.h"
/* util includes */
#include <util/attrib.h>
#include <kernel/attrib.h>
#include <util/base36.h>
#include <util/functions.h>
#include <util/goodies.h>

View file

@ -61,7 +61,7 @@ static void test_uchange(CuTest * tc, unit * u, const resource_type * rtype) {
CuAssertIntEquals(tc, 0, rtype->uchange(u, rtype, -n));
CuAssertPtrNotNull(tc, sl);
CuAssertStrEquals(tc, "serious accounting error. number of items is %d.", sl->s);
CuAssertPtrEquals(tc, 0, sl->next);
CuAssertPtrEquals(tc, NULL, sl->next);
test_log_stop(log, sl);
}
@ -86,7 +86,7 @@ void test_resource_type(CuTest * tc)
test_setup();
CuAssertPtrEquals(tc, 0, rt_find("herpderp"));
CuAssertPtrEquals(tc, NULL, rt_find("herpderp"));
test_create_itemtype("herpderp");
test_create_itemtype("herpes");
@ -122,7 +122,7 @@ void test_findresourcetype(CuTest * tc)
locale_setstring(lang, "peasant", "Bauer");
init_resources();
CuAssertPtrNotNull(tc, rt_find("peasant"));
CuAssertPtrEquals(tc, 0, rt_find("log"));
CuAssertPtrEquals(tc, NULL, rt_find("log"));
itype = test_create_itemtype("log");
CuAssertPtrEquals(tc, (void*)itype->rtype, (void*)findresourcetype("Holz", lang));
@ -164,13 +164,13 @@ static void test_core_resources(CuTest *tc) {
CuAssertPtrNotNull(tc, rtype->itype);
CuAssertPtrNotNull(tc, rtype->uchange);
CuAssertPtrNotNull(tc, rtype = rt_find("peasant"));
CuAssertPtrEquals(tc, 0, rtype->itype);
CuAssertPtrEquals(tc, NULL, rtype->itype);
CuAssertPtrNotNull(tc, rtype = rt_find("permaura"));
CuAssertPtrEquals(tc, 0, rtype->itype);
CuAssertPtrEquals(tc, NULL, rtype->itype);
CuAssertPtrNotNull(tc, rtype = rt_find("hp"));
CuAssertPtrEquals(tc, 0, rtype->itype);
CuAssertPtrEquals(tc, NULL, rtype->itype);
CuAssertPtrNotNull(tc, rtype = rt_find("aura"));
CuAssertPtrEquals(tc, 0, rtype->itype);
CuAssertPtrEquals(tc, NULL, rtype->itype);
test_teardown();
}

Some files were not shown because too many files have changed in this diff Show more