From f55ab5f752ca4b3180fdb5f55b2fd4c2ee49742c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 9 Nov 2014 12:20:16 +0100 Subject: [PATCH 1/9] the build number is in a new file. --- s/preview | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s/preview b/s/preview index eab88c921..ee0c35089 100755 --- a/s/preview +++ b/s/preview @@ -45,7 +45,7 @@ function assert_dir() { function version() { assert_dir $SOURCE cd $SOURCE -build=$(grep BUILD src/build.h | awk '{ print $3 }') +build=$(grep BUILD src/buildno.h | awk '{ print $3 }') echo "eressea build $build" } From a28cbc647a40c1c9a42a7c1e61e80dffef3dfea9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 9 Nov 2014 14:39:48 +0100 Subject: [PATCH 2/9] loot refactoring and a small armor/shield fix. --- src/battle.c | 15 +++------------ src/report.c | 2 +- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/battle.c b/src/battle.c index a5e553f2e..3f33381f4 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1059,8 +1059,8 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile) int hp; int ar = 0, an, am; - const armor_type *armor = select_armor(dt, true); - const armor_type *shield = select_armor(dt, false); + const armor_type *armor = select_armor(dt, false); + const armor_type *shield = select_armor(dt, true); const weapon_type *dwtype = NULL; const weapon_type *awtype = NULL; @@ -2554,16 +2554,7 @@ static void loot_items(fighter * corpse) mustloot ? loot : loot_quota(corpse->unit, fig->unit, itm->type, loot); if (trueloot > 0) { - item *l = fig->loot; - while (l && l->type != itm->type) - l = l->next; - if (!l) { - l = calloc(sizeof(item), 1); - l->next = fig->loot; - fig->loot = l; - l->type = itm->type; - } - l->number += trueloot; + i_change(&fig->loot, itm->type, trueloot); } } } diff --git a/src/report.c b/src/report.c index 0b41598d4..4b2765158 100644 --- a/src/report.c +++ b/src/report.c @@ -1418,7 +1418,7 @@ static void durchreisende(FILE * F, const region * r, const faction * f) if (cansee_durchgezogen(f, r, u, 0)) { ++counter; if (u->ship != NULL) { -#ifdef GERMAN_FLUFF_DISABLED +#ifdef GERMAN_FLUFF_ENABLED if (counter == 1) { bytes = (int)strlcpy(bufp, "Die ", size); } From ebd115b04aa21f661994ebe4b1103fc8e8d3975d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 9 Nov 2014 22:31:41 +0100 Subject: [PATCH 3/9] refactor of rc_specialdamage, and move it into battle, nothing else uses it. --- src/battle.c | 37 ++++++++++++++++++++++++++++++++++++- src/kernel/race.c | 36 ------------------------------------ src/kernel/race.h | 2 -- 3 files changed, 36 insertions(+), 39 deletions(-) diff --git a/src/battle.c b/src/battle.c index 3f33381f4..018763093 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1042,6 +1042,41 @@ static int natural_armor(unit * du) return an; } +static int rc_specialdamage(const unit *au, const unit *du, const struct weapon_type *wtype) +{ + const race *ar = u_race(au); + int m, modifier = 0; + + switch (old_race(ar)) { + case RC_HALFLING: + if (wtype != NULL && dragonrace(u_race(du))) { + modifier += 5; + } + break; + default: + break; + } + if (wtype != NULL && wtype->modifiers != NULL) { + for (m = 0; wtype->modifiers[m].value; ++m) { + /* weapon damage for this weapon, possibly by race */ + if (wtype->modifiers[m].flags & WMF_DAMAGE) { + race_list *rlist = wtype->modifiers[m].races; + if (rlist != NULL) { + while (rlist) { + if (rlist->data == ar) + break; + rlist = rlist->next; + } + if (rlist == NULL) + continue; + } + modifier += wtype->modifiers[m].value; + } + } + } + return modifier; +} + bool terminate(troop dt, troop at, int type, const char *damage, bool missile) { @@ -1163,7 +1198,7 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile) } } - da += rc_specialdamage(u_race(au), u_race(du), awtype); + da += rc_specialdamage(au, du, awtype); if (awtype != NULL && fval(awtype, WTF_MISSILE)) { /* missile weapon bonus */ diff --git a/src/kernel/race.c b/src/kernel/race.c index 875920d28..e3953ea98 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -280,42 +280,6 @@ const char *racename(const struct locale *loc, const unit * u, const race * rc) return str ? str : rc->_name; } -int -rc_specialdamage(const race * ar, const race * dr, -const struct weapon_type *wtype) -{ - race_t art = old_race(ar); - int m, modifier = 0; - - if (wtype != NULL && wtype->modifiers != NULL) - for (m = 0; wtype->modifiers[m].value; ++m) { - /* weapon damage for this weapon, possibly by race */ - if (wtype->modifiers[m].flags & WMF_DAMAGE) { - race_list *rlist = wtype->modifiers[m].races; - if (rlist != NULL) { - while (rlist) { - if (rlist->data == ar) - break; - rlist = rlist->next; - } - if (rlist == NULL) - continue; - } - modifier += wtype->modifiers[m].value; - } - } - switch (art) { - case RC_HALFLING: - if (wtype != NULL && dragonrace(dr)) { - modifier += 5; - } - break; - default: - break; - } - return modifier; -} - void write_race_reference(const race * rc, struct storage *store) { WRITE_TOK(store, rc ? rc->_name : "none"); diff --git a/src/kernel/race.h b/src/kernel/race.h index 3cf24f84a..d7f9e12b8 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -178,8 +178,6 @@ extern "C" { extern race *rc_get_or_create(const char *name); extern const race *rc_find(const char *); - extern int rc_specialdamage(const race *, const race *, - const struct weapon_type *); void free_races(void); typedef enum name_t { NAME_SINGULAR, NAME_PLURAL, NAME_DEFINITIVE, NAME_CATEGORY } name_t; From b8306d42f5411d91440d88654c254a08b6f5c070 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 11 Nov 2014 12:13:44 +0100 Subject: [PATCH 4/9] remove unarmed damage bonus rule --- src/battle.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/battle.c b/src/battle.c index 018763093..2569bf0da 100644 --- a/src/battle.c +++ b/src/battle.c @@ -132,7 +132,6 @@ static int skill_formula = 0; #define DAMAGE_CRITICAL (1<<0) #define DAMAGE_MELEE_BONUS (1<<1) #define DAMAGE_MISSILE_BONUS (1<<2) -#define DAMAGE_UNARMED_BONUS (1<<3) #define DAMAGE_SKILL_BONUS (1<<4) /** initialize rules from configuration. */ @@ -158,9 +157,6 @@ static void static_rules(void) if (get_param_int(global.parameters, "rules.combat.missile_bonus", 1)) { damage_rules |= DAMAGE_MISSILE_BONUS; } - if (get_param_int(global.parameters, "rules.combat.unarmed_bonus", 1)) { - damage_rules |= DAMAGE_UNARMED_BONUS; - } if (get_param_int(global.parameters, "rules.combat.skill_bonus", 1)) { damage_rules |= DAMAGE_SKILL_BONUS; } @@ -1206,12 +1202,6 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile) da += af->person[at.index].damage_rear; } } - else if (awtype == NULL) { - /* skill bonus for unarmed combat */ - if (damage_rules & DAMAGE_UNARMED_BONUS) { - da += effskill(au, SK_WEAPONLESS); - } - } else { /* melee bonus */ if (damage_rules & DAMAGE_MELEE_BONUS) { From 5b9eb9080f343cbcfccc157396276b895711624c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 11 Nov 2014 16:53:56 +0100 Subject: [PATCH 5/9] refactoring: move all monster-related code into monster.c make some features depend on being NPCs, not monster faction. --- src/battle.c | 1 + src/bind_faction.c | 21 +++++++++++++++++---- src/bind_monsters.c | 1 + src/bindings.c | 9 --------- src/economy.c | 1 + src/kernel/faction.c | 20 +------------------- src/kernel/faction.h | 4 ---- src/kernel/faction.test.c | 1 + src/kernel/messages.c | 2 +- src/kernel/save.c | 17 +++++++++-------- src/kernel/teleport.c | 2 ++ src/kernel/unit.c | 12 ++---------- src/modules/autoseed.c | 2 +- src/modules/score.c | 4 ++-- src/monster.c | 27 +++++++++++++++++++++++++++ src/monster.h | 8 ++++++++ src/move.c | 1 + src/races/zombies.c | 2 ++ src/randenc.c | 7 ------- src/report.c | 2 ++ src/reports.c | 2 +- src/spells.c | 1 + src/spells/alp.c | 2 ++ src/summary.c | 3 ++- src/upkeep.c | 1 + 25 files changed, 86 insertions(+), 67 deletions(-) diff --git a/src/battle.c b/src/battle.c index 018763093..eb6d06155 100644 --- a/src/battle.c +++ b/src/battle.c @@ -23,6 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "move.h" #include "laws.h" #include "skill.h" +#include "monster.h" #include #include diff --git a/src/bind_faction.c b/src/bind_faction.c index 163685a36..8ac87c1d4 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -14,6 +14,7 @@ without prior permission by the authors of Eressea. #include "bind_faction.h" #include "bind_unit.h" #include "bindings.h" +#include "helpers.h" #include #include @@ -325,6 +326,14 @@ static int tolua_faction_destroy(lua_State * L) return 0; } +static int tolua_faction_get(lua_State * L) +{ + int no = tolua_toid(L, 1, 0); + faction *f = findfaction(no); + tolua_pushusertype(L, f, TOLUA_CAST "faction"); + return 1; +} + static int tolua_faction_create(lua_State * L) { const char *email = tolua_tostring(L, 1, 0); @@ -510,7 +519,10 @@ void tolua_faction_open(lua_State * L) tolua_module(L, NULL, 0); tolua_beginmodule(L, NULL); { - tolua_cclass(L, TOLUA_CAST "faction", TOLUA_CAST "faction", TOLUA_CAST "", + tolua_beginmodule(L, TOLUA_CAST "eressea"); + tolua_function(L, TOLUA_CAST "get_faction", tolua_faction_get); + tolua_endmodule(L); + tolua_cclass(L, TOLUA_CAST "faction", TOLUA_CAST "faction", TOLUA_CAST "", NULL); tolua_beginmodule(L, TOLUA_CAST "faction"); { @@ -561,9 +573,10 @@ void tolua_faction_open(lua_State * L) tolua_function(L, TOLUA_CAST "add_item", tolua_faction_add_item); tolua_variable(L, TOLUA_CAST "items", tolua_faction_get_items, NULL); - tolua_function(L, TOLUA_CAST "renumber", &tolua_faction_renumber); - tolua_function(L, TOLUA_CAST "create", &tolua_faction_create); - tolua_function(L, TOLUA_CAST "destroy", &tolua_faction_destroy); + tolua_function(L, TOLUA_CAST "renumber", tolua_faction_renumber); + tolua_function(L, TOLUA_CAST "create", tolua_faction_create); + tolua_function(L, TOLUA_CAST "get", tolua_faction_get); + tolua_function(L, TOLUA_CAST "destroy", tolua_faction_destroy); #ifdef TODO def("faction_origin", &faction_getorigin, pure_out_value(_2) + pure_out_value(_3)),.def_readwrite("subscription", diff --git a/src/bind_monsters.c b/src/bind_monsters.c index dc7bc012b..49b05ccc9 100644 --- a/src/bind_monsters.c +++ b/src/bind_monsters.c @@ -1,5 +1,6 @@ #include #include "spells/shipcurse.h" +#include "monster.h" #include #include diff --git a/src/bindings.c b/src/bindings.c index cb7da3899..87eab4c34 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -565,14 +565,6 @@ static int tolua_read_turn(lua_State * L) return 1; } -static int tolua_get_faction(lua_State * L) -{ - int no = tolua_toid(L, 1, 0); - faction *f = findfaction(no); - tolua_pushusertype(L, f, TOLUA_CAST "faction"); - return 1; -} - static int tolua_get_region(lua_State * L) { int x = (int)tolua_tonumber(L, 1, 0); @@ -1137,7 +1129,6 @@ int tolua_bindings_open(lua_State * L) tolua_function(L, TOLUA_CAST "get_ship", &config_get_stype); } tolua_endmodule(L); tolua_function(L, TOLUA_CAST "get_region_by_id", tolua_get_region_byid); - tolua_function(L, TOLUA_CAST "get_faction", tolua_get_faction); tolua_function(L, TOLUA_CAST "get_unit", tolua_get_unit); tolua_function(L, TOLUA_CAST "get_alliance", tolua_get_alliance); tolua_function(L, TOLUA_CAST "get_ship", tolua_get_ship); diff --git a/src/economy.c b/src/economy.c index d5cc4eca5..02c609a73 100644 --- a/src/economy.c +++ b/src/economy.c @@ -28,6 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "randenc.h" #include "spy.h" #include "move.h" +#include "monster.h" #include "reports.h" /* kernel includes */ diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 8204afd67..dbbd24aa0 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -143,24 +143,6 @@ void set_show_item(faction * f, const struct item_type *itype) a->data.v = (void *)itype; } -faction *get_or_create_monsters(void) -{ - faction *f = findfaction(666); - if (!f) { - const race *rc = rc_get_or_create("dragon"); - const char *email = get_param(global.parameters, "monster.email"); - f = addfaction(email ? email : "noreply@eressea.de", NULL, rc, NULL, 0); - renumber_faction(f, 666); - faction_setname(f, "Monster"); - fset(f, FFL_NPC | FFL_NOIDLEOUT); - } - return f; -} - -faction *get_monsters(void) { - return get_or_create_monsters(); -} - const unit *random_unit_in_faction(const faction * f) { unit *u; @@ -632,7 +614,7 @@ void remove_empty_factions(void) /* monster (0) werden nicht entfernt. alive kann beim readgame * () auf 0 gesetzt werden, wenn monsters keine einheiten mehr * haben. */ - if ((f->units == NULL || f->alive == 0) && !is_monsters(f)) { + if ((f->units == NULL || f->alive == 0) && !fval(f, FFL_NOIDLEOUT)) { ursprung *ur = f->ursprung; while (ur && ur->id != 0) ur = ur->next; diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 0ec42fe5c..3c110424c 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -54,8 +54,6 @@ extern "C" { #define FFL_SAVEMASK (FFL_DEFENDER|FFL_NEWID|FFL_GM|FFL_NPC|FFL_DBENTRY|FFL_NOIDLEOUT) -#define is_monsters(f) (f && fval(f, FFL_NPC) && f==get_monsters()) - typedef struct faction { struct faction *next; struct faction *nexthash; @@ -116,8 +114,6 @@ void fhash(struct faction *f); void funhash(struct faction *f); struct faction *findfaction(int n); -struct faction *get_monsters(void); -struct faction *get_or_create_monsters(void); int max_magicians(const faction * f); void set_show_item(faction * f, const struct item_type *itype); diff --git a/src/kernel/faction.test.c b/src/kernel/faction.test.c index 644fb83e0..b0d0d2ee2 100644 --- a/src/kernel/faction.test.c +++ b/src/kernel/faction.test.c @@ -7,6 +7,7 @@ #include #include +#include "monster.h" #include #include diff --git a/src/kernel/messages.c b/src/kernel/messages.c index 654916971..d70423251 100644 --- a/src/kernel/messages.c +++ b/src/kernel/messages.c @@ -257,7 +257,7 @@ message * cmistake(const unit * u, struct order *ord, int mno, int mtype) static char msgname[20]; unused_arg(mtype); - if (is_monsters(u->faction)) + if (fval(u->faction, FFL_NPC)) return 0; sprintf(msgname, "error%d", mno); result = msg_feedback(u, ord, msgname, ""); diff --git a/src/kernel/save.c b/src/kernel/save.c index a7d6ce0c2..fcaa4897b 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -222,7 +222,7 @@ static faction *factionorders(void) f = findfaction(fid); - if (f != NULL && !is_monsters(f)) { + if (f != NULL && !fval(f, FFL_NPC)) { const char *pass = getstrtoken(); if (!checkpasswd(f, (const char *)pass, true)) { @@ -499,7 +499,6 @@ static int resolve_owner(variant id, void *address) f = findfaction(id.i); if (f == NULL) { log_error("region has an invalid owner (%s)\n", itoa36(id.i)); - f = get_monsters(); } } owner->owner = f; @@ -1338,9 +1337,10 @@ faction *readfaction(struct gamedata * data) READ_INT(data->store, &n); f->options = n; - if ((n & (want(O_REPORT) | want(O_COMPUTER))) == 0 && !is_monsters(f)) { + n = want(O_REPORT) | want(O_COMPUTER); + if ((f->options & n) == 0) { /* Kein Report eingestellt, Fehler */ - f->options |= (want(O_REPORT) | want(O_ZUGVORLAGE)); + f->options |= n; } sfp = &f->allies; @@ -1720,7 +1720,7 @@ int readgame(const char *filename, int backup) if (mage) { faction *f = u->faction; int skl = effskill(u, SK_MAGIC); - if (!is_monsters(f) && f->magiegebiet == M_GRAY) { + if (!fval(f, FFL_NPC) && f->magiegebiet == M_GRAY) { log_error("faction %s had magic=gray, fixing (%s)\n", factionname(f), magic_school[mage->magietyp]); f->magiegebiet = mage->magietyp; } @@ -1778,9 +1778,8 @@ int readgame(const char *filename, int backup) return 0; } -static void clear_monster_orders(void) +static void clear_npc_orders(faction *f) { - faction *f = get_monsters(); if (f) { unit *u; for (u = f->units; u; u = u->nextF) { @@ -1804,7 +1803,6 @@ int writegame(const char *filename) stream strm; FILE *F; - clear_monster_orders(); sprintf(path, "%s/%s", datapath(), filename); #ifdef HAVE_UNISTD_H if (access(path, R_OK) == 0) { @@ -1884,6 +1882,9 @@ int writegame(const char *filename) log_printf(stdout, " - Schreibe %d Parteien...\n", n); for (f = factions; f; f = f->next) { + if (fval(f, FFL_NPC)) { + clear_npc_orders(f); + } writefaction(&gdata, f); WRITE_SECTION(&store); } diff --git a/src/kernel/teleport.c b/src/kernel/teleport.c index 2bec55440..2fc7794f1 100644 --- a/src/kernel/teleport.c +++ b/src/kernel/teleport.c @@ -34,6 +34,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include "monster.h" + /* libc includes */ #include diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 87648994b..460a941bc 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -362,14 +362,6 @@ int gift_items(unit * u, int flags) return retval; } -void make_zombie(unit * u) -{ - u_setfaction(u, get_monsters()); - scale_number(u, 1); - u_setrace(u, get_race(RC_ZOMBIE)); - u->irace = NULL; -} - /** remove the unit from the list of active units. * the unit is not actually freed, because there may still be references * dangling to it (from messages, for example). To free all removed units, @@ -733,7 +725,7 @@ void set_level(unit * u, skill_t sk, int value) { skill *sv = u->skills; - assert(sk != SK_MAGIC || !u->faction || u->number == 1 || is_monsters(u->faction)); + assert(sk != SK_MAGIC || !u->faction || u->number == 1 || fval(u->faction, FFL_NPC)); if (!skill_enabled(sk)) return; @@ -1197,7 +1189,7 @@ skill *add_skill(unit * u, skill_t id) sv->weeks = 1; sv->old = 0; sv->id = id; - if (id == SK_MAGIC && u->faction && !is_monsters(u->faction)) { + if (id == SK_MAGIC && u->faction && !fval(u->faction, FFL_NPC)) { assert(u->number==1 && max_magicians(u->faction) >= u->number); } return sv; diff --git a/src/modules/autoseed.c b/src/modules/autoseed.c index fbf4f32ac..7083a85c9 100644 --- a/src/modules/autoseed.c +++ b/src/modules/autoseed.c @@ -404,7 +404,7 @@ get_island_info(region * root, int *size_p, int *inhabited_p, int *maxage_p) if (r->units) { unit *u; for (u = r->units; u; u = u->next) { - if (!is_monsters(u->faction) && u->faction->age > maxage) { + if (!fval(u->faction, FFL_NOIDLEOUT) && u->faction->age > maxage) { maxage = u->faction->age; } } diff --git a/src/modules/score.c b/src/modules/score.c index 5bad3ab68..da9fc10a0 100644 --- a/src/modules/score.c +++ b/src/modules/score.c @@ -46,7 +46,7 @@ int average_score_of_age(int age, int a) int sum = 0, count = 0; for (f = factions; f; f = f->next) { - if (!is_monsters(f) && f->age <= age + a + if (!fval(f, FFL_NPC) && f->age <= age + a && f->age >= age - a && f->race != get_race(RC_TEMPLATE)) { sum += f->score; count++; @@ -143,7 +143,7 @@ void score(void) for (fc = factions; fc; fc = fc->next) { fc->score = fc->score / 5; - if (!is_monsters(fc) && fc->race != get_race(RC_TEMPLATE)) { + if (!fval(fc, FFL_NPC) && fc->race != get_race(RC_TEMPLATE)) { allscores += fc->score; } } diff --git a/src/monster.c b/src/monster.c index c162fe3cd..1dd81b06e 100644 --- a/src/monster.c +++ b/src/monster.c @@ -216,3 +216,30 @@ void monster_kills_peasants(unit * u) } } } + +faction *get_or_create_monsters(void) +{ + faction *f = findfaction(MONSTER_ID); + if (!f) { + const race *rc = rc_get_or_create("dragon"); + const char *email = get_param(global.parameters, "monster.email"); + f = addfaction(email ? email : "noreply@eressea.de", NULL, rc, NULL, 0); + renumber_faction(f, MONSTER_ID); + faction_setname(f, "Monster"); + fset(f, FFL_NPC | FFL_NOIDLEOUT); + } + return f; +} + +faction *get_monsters(void) { + return get_or_create_monsters(); +} + +void make_zombie(unit * u) +{ + u_setfaction(u, get_monsters()); + scale_number(u, 1); + u_setrace(u, get_race(RC_ZOMBIE)); + u->irace = NULL; +} + diff --git a/src/monster.h b/src/monster.h index 27a8f23f7..02eab5519 100644 --- a/src/monster.h +++ b/src/monster.h @@ -22,8 +22,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif +#define MONSTER_ID 666 + void monster_kills_peasants(struct unit *u); bool monster_is_waiting(const struct unit *u); + struct faction *get_monsters(void); + struct faction *get_or_create_monsters(void); + void make_zombie(struct unit * u); + +#define is_monsters(f) (f && fval(f, FFL_NPC) && f==get_monsters()) + #ifdef __cplusplus } diff --git a/src/move.c b/src/move.c index 4a9bd7ba7..c4b6b4202 100644 --- a/src/move.c +++ b/src/move.c @@ -24,6 +24,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "reports.h" #include "alchemy.h" #include "vortex.h" +#include "monster.h" #include #include diff --git a/src/races/zombies.c b/src/races/zombies.c index 9f1d6c764..97a826c3f 100644 --- a/src/races/zombies.c +++ b/src/races/zombies.c @@ -24,6 +24,8 @@ /* util iclude */ #include +#include "monster.h" + /* libc includes */ #include diff --git a/src/randenc.c b/src/randenc.c index e4bd79c46..93f3bb6a8 100644 --- a/src/randenc.c +++ b/src/randenc.c @@ -1139,13 +1139,6 @@ static void demon_skillchanges(void) while (weeks--) learn_skill(u, sv->id, 1.0); } - if (sv->old > sv->level) { - if (verbosity >= 3) { - log_printf(stdout, "%s dropped from %u to %u:%u in %s\n", - unitname(u), sv->old, sv->level, sv->weeks, skillname(sv->id, - NULL)); - } - } } ++sv; } diff --git a/src/report.c b/src/report.c index 4b2765158..9f0c6ba32 100644 --- a/src/report.c +++ b/src/report.c @@ -23,6 +23,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "reports.h" #include "laws.h" +#include "monster.h" + /* modules includes */ #include diff --git a/src/reports.c b/src/reports.c index 54e072a46..f22165e0e 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1688,7 +1688,7 @@ static void nmr_warnings(void) faction *f, *fa; #define FRIEND (HELP_GUARD|HELP_MONEY) for (f = factions; f; f = f->next) { - if (!is_monsters(f) && (turn - f->lastorders) >= 2) { + if (!fval(f, FFL_NOIDLEOUT) && (turn - f->lastorders) >= 2) { message *msg = NULL; for (fa = factions; fa; fa = fa->next) { int warn = 0; diff --git a/src/spells.c b/src/spells.c index daf114640..7929b004f 100644 --- a/src/spells.c +++ b/src/spells.c @@ -20,6 +20,7 @@ #include "laws.h" #include "spells.h" #include "direction.h" +#include "monster.h" #include #include diff --git a/src/spells/alp.c b/src/spells/alp.c index 82cf8c02f..73d17662a 100644 --- a/src/spells/alp.c +++ b/src/spells/alp.c @@ -28,6 +28,8 @@ #include #include +#include "monster.h" + #include #include diff --git a/src/summary.c b/src/summary.c index 70a908a26..df8bd1066 100644 --- a/src/summary.c +++ b/src/summary.c @@ -14,6 +14,7 @@ #include "summary.h" #include "laws.h" +#include "monster.h" #include #include @@ -88,7 +89,7 @@ int update_nmrs(void) if (fval(f, FFL_ISNEW)) { ++newplayers; } - else if (!is_monsters(f) && f->alive) { + else if (!fval(f, FFL_NOIDLEOUT) && f->alive) { int nmr = turn - f->lastorders + 1; if (nmr < 0 || nmr > NMRTimeout()) { log_error("faction %s has %d NMRS\n", factionid(f), nmr); diff --git a/src/upkeep.c b/src/upkeep.c index c807ec1d1..5eecc1b42 100644 --- a/src/upkeep.c +++ b/src/upkeep.c @@ -15,6 +15,7 @@ #include "alchemy.h" #include "economy.h" +#include "monster.h" #include From 64a2073033a69b3a67a2aba5f5d1f3b7be770997 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 21 Nov 2014 16:39:49 +0100 Subject: [PATCH 6/9] tests for entering buildings. --- src/laws.c | 2 +- src/laws.h | 2 +- src/laws.test.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/laws.c b/src/laws.c index e22824789..3994927a4 100755 --- a/src/laws.c +++ b/src/laws.c @@ -1054,7 +1054,7 @@ int enter_ship(unit * u, struct order *ord, int id, int report) return 0; } -int enter_building(unit * u, order * ord, int id, int report) +int enter_building(unit * u, order * ord, int id, bool report) { region *r = u->region; building *b; diff --git a/src/laws.h b/src/laws.h index 869534212..64bbe7b65 100755 --- a/src/laws.h +++ b/src/laws.h @@ -51,7 +51,7 @@ extern "C" { extern int dropouts[2]; extern int *age; - extern int enter_building(struct unit *u, struct order *ord, int id, int report); + extern int enter_building(struct unit *u, struct order *ord, int id, bool report); extern int enter_ship(struct unit *u, struct order *ord, int id, int report); extern void new_units(void); diff --git a/src/laws.test.c b/src/laws.test.c index 65b360f6f..f6a001179 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -117,6 +117,39 @@ static void test_contact(CuTest * tc) CuAssertIntEquals(tc, 1, can_contact(r, u1, u2)); } +static void test_enter_building(CuTest * tc) +{ + unit *u; + region *r; + building *b; + race * rc; + + test_cleanup(); + test_create_world(); + + r = findregion(0, 0); + rc = rc_get_or_create("human"); + u = test_create_unit(test_create_faction(rc), r); + b = test_create_building(r, bt_get_or_create("castle")); + + rc->flags = RCF_WALK; + u->building = 0; + enter_building(u, NULL, b->no, false); + CuAssertPtrEquals(tc, b, u->building); + + rc->flags = RCF_FLY; + u->building = 0; + enter_building(u, NULL, b->no, false); + CuAssertPtrEquals(tc, b, u->building); + + rc->flags = RCF_SWIM; + u->building = 0; + enter_building(u, NULL, b->no, false); + CuAssertPtrEquals(tc, 0, u->building); + + test_cleanup(); +} + static void test_fishing_feeds_2_people(CuTest * tc) { const resource_type *rtype; @@ -445,5 +478,6 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_new_units); SUITE_ADD_TEST(suite, test_cannot_create_unit_above_limit); SUITE_ADD_TEST(suite, test_contact); + SUITE_ADD_TEST(suite, test_enter_building); return suite; } From 7d5109329f90da824b365b92f128698880bbc829 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 21 Nov 2014 17:13:45 +0100 Subject: [PATCH 7/9] tests for entering ships (but not yet full coverage) --- src/laws.c | 16 +++++++++------ src/laws.h | 7 ++++--- src/laws.test.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/src/laws.c b/src/laws.c index 3994927a4..bd2abc9d8 100755 --- a/src/laws.c +++ b/src/laws.c @@ -993,31 +993,35 @@ static bool CheckOverload(void) return value; } -int enter_ship(unit * u, struct order *ord, int id, int report) +int enter_ship(unit * u, struct order *ord, int id, bool report) { region *r = u->region; ship *sh; + const race * rc = u_race(u); /* Muss abgefangen werden, sonst koennten Schwimmer an * Bord von Schiffen an Land gelangen. */ - if (!fval(u_race(u), RCF_CANSAIL) || (!fval(u_race(u), RCF_WALK) - && !fval(u_race(u), RCF_FLY))) { - cmistake(u, ord, 233, MSG_MOVE); + if (!(rc->flags & (RCF_CANSAIL|RCF_WALK|RCF_FLY))) { + if (report) { + cmistake(u, ord, 233, MSG_MOVE); + } return 0; } sh = findship(id); if (sh == NULL || sh->region != r) { - if (report) + if (report) { cmistake(u, ord, 20, MSG_MOVE); + } return 0; } if (sh == u->ship) { return 1; } if (!mayboard(u, sh)) { - if (report) + if (report) { cmistake(u, ord, 34, MSG_MOVE); + } return 0; } if (CheckOverload()) { diff --git a/src/laws.h b/src/laws.h index 64bbe7b65..5a7cd8024 100755 --- a/src/laws.h +++ b/src/laws.h @@ -44,15 +44,16 @@ extern "C" { void get_food(struct region * r); int can_contact(const struct region *r, const struct unit *u, const struct unit *u2); -/* eressea-specific. put somewhere else, please. */ + int enter_building(struct unit *u, struct order *ord, int id, bool report); + int enter_ship(struct unit *u, struct order *ord, int id, bool report); + + /* eressea-specific. put somewhere else, please. */ void processorders(void); extern struct attrib_type at_germs; extern int dropouts[2]; extern int *age; - extern int enter_building(struct unit *u, struct order *ord, int id, bool report); - extern int enter_ship(struct unit *u, struct order *ord, int id, int report); extern void new_units(void); extern void defaultorders(void); diff --git a/src/laws.test.c b/src/laws.test.c index f6a001179..2280b155d 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -134,18 +134,64 @@ static void test_enter_building(CuTest * tc) rc->flags = RCF_WALK; u->building = 0; - enter_building(u, NULL, b->no, false); + CuAssertIntEquals(tc, 1, enter_building(u, NULL, b->no, false)); CuAssertPtrEquals(tc, b, u->building); rc->flags = RCF_FLY; u->building = 0; - enter_building(u, NULL, b->no, false); + CuAssertIntEquals(tc, 1, enter_building(u, NULL, b->no, false)); CuAssertPtrEquals(tc, b, u->building); rc->flags = RCF_SWIM; u->building = 0; - enter_building(u, NULL, b->no, false); + CuAssertIntEquals(tc, 0, enter_building(u, NULL, b->no, false)); CuAssertPtrEquals(tc, 0, u->building); + CuAssertPtrEquals(tc, 0, u->faction->msgs); + + CuAssertIntEquals(tc, 0, enter_building(u, NULL, b->no, true)); + CuAssertPtrNotNull(tc, u->faction->msgs); + + test_cleanup(); +} + +static void test_enter_ship(CuTest * tc) +{ + unit *u; + region *r; + ship *sh; + race * rc; + + test_cleanup(); + test_create_world(); + + r = findregion(0, 0); + rc = rc_get_or_create("human"); + u = test_create_unit(test_create_faction(rc), r); + sh = test_create_ship(r, st_get_or_create("boat")); + + rc->flags = RCF_WALK; + u->ship = 0; + CuAssertIntEquals(tc, 1, enter_ship(u, NULL, sh->no, false)); + CuAssertPtrEquals(tc, sh, u->ship); + + rc->flags = RCF_FLY; + u->ship = 0; + CuAssertIntEquals(tc, 1, enter_ship(u, NULL, sh->no, false)); + CuAssertPtrEquals(tc, sh, u->ship); + + rc->flags = RCF_CANSAIL; + u->ship = 0; + CuAssertIntEquals(tc, 1, enter_ship(u, NULL, sh->no, false)); + CuAssertPtrEquals(tc, sh, u->ship); + + rc->flags = RCF_SWIM; + u->ship = 0; + CuAssertIntEquals(tc, 0, enter_ship(u, NULL, sh->no, false)); + CuAssertPtrEquals(tc, 0, u->ship); + CuAssertPtrEquals(tc, 0, u->faction->msgs); + + CuAssertIntEquals(tc, 0, enter_ship(u, NULL, sh->no, true)); + CuAssertPtrNotNull(tc, u->faction->msgs); test_cleanup(); } @@ -479,5 +525,6 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_cannot_create_unit_above_limit); SUITE_ADD_TEST(suite, test_contact); SUITE_ADD_TEST(suite, test_enter_building); + SUITE_ADD_TEST(suite, test_enter_ship); return suite; } From f92df416ff188524dbd64d11e29843c5aa69d3eb Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 23 Nov 2014 15:50:22 +0100 Subject: [PATCH 8/9] monsters need a default locale, or their report will crash (thanks, Don!) - empty factions have not seen any region, prevent the code from crashing in that case. - must load the rules even when only writing the reports (taxation affects guards?) --- scripts/config.lua | 1 + scripts/run-turn.lua | 8 +------- src/monster.c | 2 +- src/reports.c | 10 ++++++++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/scripts/config.lua b/scripts/config.lua index b9dc8bca8..1251c1e1c 100644 --- a/scripts/config.lua +++ b/scripts/config.lua @@ -5,3 +5,4 @@ end package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua' require 'eressea' require 'eressea.xmlconf' +return require('eressea.rules') diff --git a/scripts/run-turn.lua b/scripts/run-turn.lua index c9033afe3..283bdb1d1 100644 --- a/scripts/run-turn.lua +++ b/scripts/run-turn.lua @@ -174,12 +174,6 @@ end package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua' require 'eressea' require 'eressea.xmlconf' -- read xml data +local rules = require('eressea.rules') -local rules = {} -if config.rules then - rules = require('eressea.' .. config.rules) - eressea.log.info('loaded ' .. #rules .. ' modules for ' .. config.rules) -else - eressea.log.warning('no rule modules loaded, specify a game in eressea.ini or with -r') -end run_turn(rules) diff --git a/src/monster.c b/src/monster.c index 1dd81b06e..6302c1af4 100644 --- a/src/monster.c +++ b/src/monster.c @@ -223,7 +223,7 @@ faction *get_or_create_monsters(void) if (!f) { const race *rc = rc_get_or_create("dragon"); const char *email = get_param(global.parameters, "monster.email"); - f = addfaction(email ? email : "noreply@eressea.de", NULL, rc, NULL, 0); + f = addfaction(email ? email : "noreply@eressea.de", NULL, rc, default_locale, 0); renumber_faction(f, MONSTER_ID); faction_setname(f, "Monster"); fset(f, FFL_NPC | FFL_NOIDLEOUT); diff --git a/src/reports.c b/src/reports.c index f22165e0e..fba0eacea 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1204,6 +1204,8 @@ static void get_seen_interval(report_context * ctx) /* this is required to find the neighbour regions of the ones we are in, * which may well be outside of [firstregion, lastregion) */ int i; + + assert(ctx->seen); for (i = 0; i != MAXSEEHASH; ++i) { seen_region *sr = ctx->seen[i]; while (sr != NULL) { @@ -1643,7 +1645,9 @@ int write_reports(faction * f, time_t ltime) ctx.last = lastregion(f); ctx.addresses = NULL; ctx.userdata = NULL; - get_seen_interval(&ctx); + if (ctx.seen) { + get_seen_interval(&ctx); + } get_addresses(&ctx); _mkdir(reportpath()); do { @@ -1679,7 +1683,9 @@ int write_reports(faction * f, time_t ltime) log_warning("No report for faction %s!", factionid(f)); } ql_free(ctx.addresses); - seen_done(ctx.seen); + if (ctx.seen) { + seen_done(ctx.seen); + } return 0; } From 7b2d1991d899720ff6505df6ac2cac4846b23765 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 23 Nov 2014 21:15:09 +0100 Subject: [PATCH 9/9] add missing file, fix factions that lack a locale. --- scripts/eressea/rules.lua | 9 +++++++++ src/kernel/save.c | 1 + 2 files changed, 10 insertions(+) create mode 100644 scripts/eressea/rules.lua diff --git a/scripts/eressea/rules.lua b/scripts/eressea/rules.lua new file mode 100644 index 000000000..f8f7387fe --- /dev/null +++ b/scripts/eressea/rules.lua @@ -0,0 +1,9 @@ +local rules = {} +if config.rules then + rules = require('eressea.' .. config.rules) + eressea.log.info('loaded ' .. #rules .. ' modules for ' .. config.rules) +else + eressea.log.warning('no rule modules loaded, specify a game in eressea.ini or with -r') +end + +return rules diff --git a/src/kernel/save.c b/src/kernel/save.c index fcaa4897b..c1140e9ca 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1291,6 +1291,7 @@ faction *readfaction(struct gamedata * data) READ_STR(data->store, name, sizeof(name)); f->locale = get_locale(name); + if (!f->locale) f->locale = default_locale; READ_INT(data->store, &f->lastorders); READ_INT(data->store, &f->age); READ_STR(data->store, name, sizeof(name));