From a175c842324e72020dda51883ec8f8d053b4a451 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 8 Oct 2017 09:10:41 +0200 Subject: [PATCH 01/11] =?UTF-8?q?create=5Fmage=20sollte=20ein=20existieren?= =?UTF-8?q?des=20at=5Fmage=20nicht=20=C3=BCberschreiben,=20nur=20evtl.=20a?= =?UTF-8?q?ktualisieren.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/magic.c | 8 +++----- src/study.c | 5 +---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/magic.c b/src/magic.c index 7ec220875..f83e31a7d 100644 --- a/src/magic.c +++ b/src/magic.c @@ -488,12 +488,10 @@ sc_mage *create_mage(unit * u, magic_t mtyp) attrib *a; a = a_find(u->attribs, &at_mage); - if (a != NULL) { - a_remove(&u->attribs, a); + if (a == NULL) { + a = a_add(&u->attribs, a_new(&at_mage)); } - a = a_add(&u->attribs, a_new(&at_mage)); - mage = a->data.v; - + mage = (sc_mage *)a->data.v; mage->magietyp = mtyp; return mage; } diff --git a/src/study.c b/src/study.c index 88550fc30..9d37a7648 100644 --- a/src/study.c +++ b/src/study.c @@ -613,8 +613,6 @@ int study_cmd(unit * u, order * ord) /* Vertraute zaehlen nicht zu den Magiern einer Partei, * koennen aber nur Graue Magie lernen */ mtyp = M_GRAY; - if (!is_mage(u)) - create_mage(u, mtyp); } else if (!has_skill(u, SK_MAGIC)) { int mmax = skill_limit(u->faction, SK_MAGIC); @@ -654,8 +652,7 @@ int study_cmd(unit * u, order * ord) u->faction->magiegebiet = mtyp; } } - if (!is_mage(u)) - create_mage(u, mtyp); + create_mage(u, mtyp); } else { /* ist schon ein Magier und kein Vertrauter */ From 197fd48508d709a4ef2961e9f43a990df660052c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 3 Sep 2017 11:32:20 +0200 Subject: [PATCH 02/11] send bz2 report with new mail text location --- process/send-bz2-report | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/send-bz2-report b/process/send-bz2-report index 983564bea..f4b2ad6ea 100755 --- a/process/send-bz2-report +++ b/process/send-bz2-report @@ -26,4 +26,4 @@ addr=$1 subj=$2 shift 2 -cat $ERESSEA/etc/$TEMPLATE | mutt -F $ERESSEA/etc/muttrc -s "$subj" -a $* -- $addr +cat $ERESSEA/server/etc/$TEMPLATE | mutt -F $ERESSEA/etc/muttrc -s "$subj" -a $* -- $addr From dc2663571c041c352c42e310c377f071a0b9ecb4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 15 Sep 2017 19:58:22 +0200 Subject: [PATCH 03/11] move orders.queue file (clever use of lockfile program) --- process/create-orders | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/process/create-orders b/process/create-orders index ff784f9aa..7ddbde92e 100755 --- a/process/create-orders +++ b/process/create-orders @@ -1,3 +1,5 @@ +#!/bin/bash + GAME=$1 TURN=$2 @@ -7,6 +9,7 @@ if [ ! -d $ERESSEA/game-$GAME ] ; then fi cd $ERESSEA/game-$GAME + if [ -d orders.dir.$TURN ]; then echo "orders.dir.$TURN already exists" else @@ -14,3 +17,11 @@ else mkdir -p orders.dir fi ls -1rt orders.dir.$TURN/turn-* | xargs cat > orders.$TURN + +if [ -e orders.queue ] ; then + lockfile -r3 -l120 orders.queue.lock + mv orders.queue orders.dir.$TURN/orders.queue + rm -f orders.queue.lock +fi + + From 0ffb4e3ca957f8aac38989c3660cc99e3ebe7097 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 15 Sep 2017 19:59:42 +0200 Subject: [PATCH 04/11] small fix to orders.queue locking --- process/create-orders | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/process/create-orders b/process/create-orders index 7ddbde92e..b0ca292f4 100755 --- a/process/create-orders +++ b/process/create-orders @@ -18,10 +18,11 @@ else fi ls -1rt orders.dir.$TURN/turn-* | xargs cat > orders.$TURN +lockfile -r3 -l120 orders.queue.lock if [ -e orders.queue ] ; then - lockfile -r3 -l120 orders.queue.lock mv orders.queue orders.dir.$TURN/orders.queue - rm -f orders.queue.lock +fi +rm -f orders.queue.lock fi From 9d48bfc36c699323df265b86b47747ce01c66ead Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 10 Oct 2017 18:45:44 +0200 Subject: [PATCH 05/11] BUG 2366: add a test to verify that view_reality sets an observer. --- src/spells.h | 8 ++++---- src/spells.test.c | 37 +++++++++++++++++++++++++++++++++++++ src/teleport.c | 21 ++++++++++----------- src/teleport.h | 20 ++++++++++++++------ 4 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/spells.h b/src/spells.h index 3b6280e83..39157aaf6 100644 --- a/src/spells.h +++ b/src/spells.h @@ -22,11 +22,10 @@ extern "C" { #endif + struct castorder; struct curse_type; struct region; struct unit; - struct faction; - struct region; struct message; extern const struct curse_type ct_magicresistance; @@ -34,8 +33,9 @@ extern "C" { void register_magicresistance(void); void register_spells(void); - int sp_baddreams(castorder * co); - int sp_gooddreams(castorder * co); + int sp_baddreams(struct castorder * co); + int sp_gooddreams(struct castorder * co); + int sp_viewreality(struct castorder * co); #define ACTION_RESET 0x01 /* reset the one-time-flag FFL_SELECT (on first pass) */ #define ACTION_CANSEE 0x02 /* to people who can see the actor */ diff --git a/src/spells.test.c b/src/spells.test.c index cd72f0177..638d1e858 100644 --- a/src/spells.test.c +++ b/src/spells.test.c @@ -1,11 +1,13 @@ #include #include "spells.h" +#include "teleport.h" #include #include #include #include +#include #include #include #include @@ -113,6 +115,40 @@ static void test_bad_dreams(CuTest *tc) { test_cleanup(); } +static void test_view_reality(CuTest *tc) { + region *r, *ra; + faction *f; + unit *u; + castorder co; + + test_setup(); + r = test_create_region(0, 0, NULL); + ra = test_create_region(real2tp(r->x), real2tp(r->y), NULL); + ra->_plane = get_astralplane(); + f = test_create_faction(0); + u = test_create_unit(f, r); + + test_create_castorder(&co, u, 10, 10., 0, NULL); + CuAssertIntEquals(tc, -1, get_observer(r, f)); + CuAssertIntEquals(tc, 0, sp_viewreality(&co)); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "spell_astral_only")); + free_castorder(&co); + + test_clear_messagelist(&f->msgs); + move_unit(u, ra, NULL); + + test_create_castorder(&co, u, 9, 10., 0, NULL); + CuAssertIntEquals(tc, -1, get_observer(r, f)); + CuAssertIntEquals(tc, 9, sp_viewreality(&co)); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "spell_astral_only")); + CuAssertIntEquals(tc, 4, get_observer(r, f)); + CuAssertPtrEquals(tc, f, (void *)ra->individual_messages->viewer); + CuAssertPtrNotNull(tc, test_find_messagetype(ra->individual_messages->msgs, "viewreality_effect")); + free_castorder(&co); + + test_cleanup(); +} + static void test_watch_region(CuTest *tc) { region *r; faction *f; @@ -133,6 +169,7 @@ CuSuite *get_spells_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_watch_region); + SUITE_ADD_TEST(suite, test_view_reality); SUITE_ADD_TEST(suite, test_good_dreams); SUITE_ADD_TEST(suite, test_bad_dreams); SUITE_ADD_TEST(suite, test_dreams); diff --git a/src/teleport.c b/src/teleport.c index 78098c264..c529d5129 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -39,25 +39,24 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* libc includes */ #include -#define TE_CENTER_X 1000 -#define TE_CENTER_Y 1000 +#define TE_CENTER 1000 #define TP_RADIUS 2 #define TP_DISTANCE 4 -static int real2tp(int rk) +int real2tp(int rk) { /* in C: * -4 / 5 = 0; * +4 / 5 = 0; * !!!!!!!!!!; */ - return (rk + (TP_DISTANCE * 5000)) / TP_DISTANCE - 5000; + return TE_CENTER + (rk + (TP_DISTANCE * 5000)) / TP_DISTANCE - 5000; } static region *tpregion(const region * r) { region *rt = - findregion(TE_CENTER_X + real2tp(r->x), TE_CENTER_Y + real2tp(r->y)); + findregion(real2tp(r->x), real2tp(r->y)); if (!is_astral(rt)) return NULL; return rt; @@ -106,8 +105,8 @@ region *r_astral_to_standard(const region * r) region *r2; assert(is_astral(r)); - x = (r->x - TE_CENTER_X) * TP_DISTANCE; - y = (r->y - TE_CENTER_Y) * TP_DISTANCE; + x = (r->x - TE_CENTER) * TP_DISTANCE; + y = (r->y - TE_CENTER) * TP_DISTANCE; pnormalize(&x, &y, NULL); r2 = findregion(x, y); if (r2 == NULL || rplane(r2)) @@ -188,8 +187,8 @@ plane *get_astralplane(void) astralspace = getplanebyname("Astralraum"); if (!astralspace) { astralspace = create_new_plane(1, "Astralraum", - TE_CENTER_X - 500, TE_CENTER_X + 500, - TE_CENTER_Y - 500, TE_CENTER_Y + 500, 0); + TE_CENTER - 500, TE_CENTER + 500, + TE_CENTER - 500, TE_CENTER + 500, 0); } return astralspace; } @@ -208,8 +207,8 @@ void create_teleport_plane(void) region *ra = tpregion(r); if (ra == NULL) { - int x = TE_CENTER_X + real2tp(r->x); - int y = TE_CENTER_Y + real2tp(r->y); + int x = real2tp(r->x); + int y = real2tp(r->y); pnormalize(&x, &y, aplane); ra = new_region(x, y, aplane, 0); diff --git a/src/teleport.h b/src/teleport.h index cc0a3f143..153c0114b 100644 --- a/src/teleport.h +++ b/src/teleport.h @@ -18,24 +18,32 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifndef TELEPORT_H #define TELEPORT_H + +#include + #ifdef __cplusplus extern "C" { #endif + struct region; + struct region_list; + struct plane; + struct region *r_standard_to_astral(const struct region *r); struct region *r_astral_to_standard(const struct region *); - extern struct region_list *astralregions(const struct region *rastral, + struct region_list *astralregions(const struct region *rastral, bool(*valid) (const struct region *)); - extern struct region_list *all_in_range(const struct region *r, int n, + struct region_list *all_in_range(const struct region *r, int n, bool(*valid) (const struct region *)); - extern bool inhabitable(const struct region *r); - extern bool is_astral(const struct region *r); - extern struct plane *get_astralplane(void); + bool inhabitable(const struct region *r); + bool is_astral(const struct region *r); + struct plane *get_astralplane(void); void create_teleport_plane(void); - void set_teleport_plane_regiontypes(void); void spawn_braineaters(float chance); + int real2tp(int rk); + #ifdef __cplusplus } #endif From 1b53128e1a3116433531e1a985f9f38158042f87 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 10 Oct 2017 20:09:39 +0200 Subject: [PATCH 06/11] BUG 2366: Fix cansee for seen_spell regions. --- src/attributes/attributes.c | 2 +- src/attributes/attributes.h | 2 +- src/battle.c | 2 +- src/creport.c | 4 +- src/economy.c | 2 +- src/give.c | 2 +- src/guard.c | 2 +- src/kernel/build.c | 2 +- src/laws.c | 74 ++++++++++++++++++------------------- src/laws.h | 4 +- src/magic.c | 2 +- src/monsters.c | 4 +- src/move.c | 8 ++-- src/report.c | 10 ++--- src/reports.c | 11 +++--- src/reports.h | 2 +- src/reports.test.c | 19 ++++++++++ src/spells.c | 38 +++++++++---------- src/spy.c | 2 +- 19 files changed, 106 insertions(+), 86 deletions(-) diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index f003c2cde..95d4f41fc 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -114,7 +114,7 @@ static attrib *make_observer(faction *f, int perception) return a; } -int get_observer(region *r, faction *f) { +int get_observer(const region *r, const faction *f) { if (fval(r, RF_OBSERVER)) { attrib *a = a_find(r->attribs, &at_observer); while (a && a->type == &at_observer) { diff --git a/src/attributes/attributes.h b/src/attributes/attributes.h index 19b371dbb..3cd303f15 100644 --- a/src/attributes/attributes.h +++ b/src/attributes/attributes.h @@ -29,7 +29,7 @@ extern "C" { extern void register_attributes(void); void set_observer(struct region *r, struct faction *f, int perception, int turns); - int get_observer(struct region *r, struct faction *f); + int get_observer(const struct region *r, const struct faction *f); #ifdef __cplusplus } diff --git a/src/battle.c b/src/battle.c index ad1c0f8da..a60eeebb2 100644 --- a/src/battle.c +++ b/src/battle.c @@ -3847,7 +3847,7 @@ static bool start_battle(region * r, battle ** bp) /* Beginn Fehlerbehandlung */ /* Fehler: "Die Einheit wurde nicht gefunden" */ - if (!u2 || u2->number == 0 || !cansee(u->faction, u->region, u2, 0)) { + if (!u2 || u2->number == 0 || !cansee(u->faction, u->region, u2, 0, seen_battle)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", "")); continue; diff --git a/src/creport.c b/src/creport.c index 4ec7f9b0b..c26d28963 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1363,7 +1363,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r) building *b; ship *sh; unit *u; - int stealthmod = stealth_modifier(r->seen.mode); + int stealthmod = stealth_modifier(r, f, r->seen.mode); if (r->land && r->land->display && r->land->display[0]) fprintf(F, "\"%s\";Beschr\n", r->land->display); @@ -1497,7 +1497,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r) for (u = r->units; u; u = u->next) { if (u->building || u->ship || (stealthmod > INT_MIN - && cansee(f, r, u, stealthmod))) { + && cansee(f, r, u, stealthmod, r->seen.mode))) { cr_output_unit_compat(F, r, f, u, r->seen.mode); } } diff --git a/src/economy.c b/src/economy.c index 7c4b0efd3..73007b750 100644 --- a/src/economy.c +++ b/src/economy.c @@ -2454,7 +2454,7 @@ static void steal_cmd(unit * u, struct order *ord, request ** stealorders) } for (u2 = r->units; u2; u2 = u2->next) { - if (u2->faction == f && cansee(u->faction, r, u2, 0)) + if (u2->faction == f && cansee_depr(u->faction, r, u2, 0)) break; } diff --git a/src/give.c b/src/give.c index da75e56c5..0dab27f2f 100644 --- a/src/give.c +++ b/src/give.c @@ -614,7 +614,7 @@ bool can_give_to(unit *u, unit *u2) { return false; } if (u2 && !alliedunit(u2, u->faction, HELP_GIVE) - && !cansee(u->faction, u->region, u2, 0) && !ucontact(u2, u) + && !cansee_depr(u->faction, u->region, u2, 0) && !ucontact(u2, u) && !fval(u2, UFL_TAKEALL)) { return false; } diff --git a/src/guard.c b/src/guard.c index 118ede5fc..18281c7a0 100644 --- a/src/guard.c +++ b/src/guard.c @@ -93,7 +93,7 @@ static bool is_guardian_u(const unit * guard, unit * u) return false; if (ucontact(guard, u)) return false; - if (!cansee(guard->faction, u->region, u, 0)) + if (!cansee_depr(guard->faction, u->region, u, 0)) return false; if (!(u_race(guard)->flags & RCF_FLY) && u_race(u)->flags & RCF_FLY) return false; diff --git a/src/kernel/build.c b/src/kernel/build.c index 1f4e143df..2de25938e 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -113,7 +113,7 @@ static void destroy_road(unit * u, int nmax, struct order *ord) for (u2 = r->units; u2; u2 = u2->next) { if (u2->faction != u->faction && is_guard(u2) - && cansee(u2->faction, u->region, u, 0) + && cansee_depr(u2->faction, u->region, u, 0) && !alliedunit(u, u2->faction, HELP_GUARD)) { cmistake(u, ord, 70, MSG_EVENT); return; diff --git a/src/laws.c b/src/laws.c index f60af7f15..71309914a 100644 --- a/src/laws.c +++ b/src/laws.c @@ -1651,7 +1651,7 @@ static bool try_rename(unit *u, building *b, order *ord) { } if (owner) { - if (cansee(owner->faction, u->region, u, 0)) { + if (cansee(owner->faction, u->region, u, 0, seen_unit)) { ADDMSG(&owner->faction->msgs, msg_message("renamed_building_seen", "building renamer region", b, u, u->region)); @@ -1747,7 +1747,7 @@ int name_cmd(struct unit *u, struct order *ord) break; } } - if (cansee(f, r, u, 0)) { + if (cansee(f, r, u, 0, seen_unit)) { ADDMSG(&f->msgs, msg_message("renamed_faction_seen", "unit region", u, r)); } @@ -1794,7 +1794,7 @@ int name_cmd(struct unit *u, struct order *ord) } uo = ship_owner(sh); if (uo) { - if (cansee(uo->faction, r, u, 0)) { + if (cansee(uo->faction, r, u, 0, seen_unit)) { ADDMSG(&uo->faction->msgs, msg_message("renamed_ship_seen", "ship renamer region", sh, u, r)); } @@ -1823,7 +1823,7 @@ int name_cmd(struct unit *u, struct order *ord) unit *u2 = 0; getunit(r, u->faction, &u2); - if (!u2 || !cansee(u->faction, r, u2, 0)) { + if (!u2 || !cansee(u->faction, r, u2, 0, seen_unit)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", "")); break; @@ -1836,7 +1836,7 @@ int name_cmd(struct unit *u, struct order *ord) break; } } - if (cansee(u2->faction, r, u, 0)) { + if (cansee(u2->faction, r, u, 0, seen_unit)) { ADDMSG(&u2->faction->msgs, msg_message("renamed_seen", "renamer renamed region", u, u2, r)); } @@ -1898,7 +1898,7 @@ int name_cmd(struct unit *u, struct order *ord) void deliverMail(faction * f, region * r, unit * u, const char *s, unit * receiver) { - if (!cansee(f, r, u, 0)) { + if (!cansee(f, r, u, 0, seen_unit)) { u = NULL; } if (!receiver) { /* BOTSCHAFT an PARTEI */ @@ -1917,7 +1917,7 @@ mailunit(region * r, unit * u, int n, struct order *ord, const char *s) { unit *u2 = findunitr(r, n); - if (u2 && cansee(u->faction, r, u2, 0)) { + if (u2 && cansee(u->faction, r, u2, 0, seen_unit)) { deliverMail(u2->faction, r, u, s, u2); /* now done in prepare_mail_cmd */ } @@ -1995,7 +1995,7 @@ int mail_cmd(unit * u, struct order *ord) n = getid(); for (u2 = r->units; u2; u2 = u2->next) { - if (u2->no == n && cansee(u->faction, r, u2, 0)) { + if (u2->no == n && cansee(u->faction, r, u2, 0, seen_unit)) { break; } } @@ -2049,7 +2049,7 @@ int mail_cmd(unit * u, struct order *ord) for (u2 = r->units; u2; u2 = u2->next) { if (u2->building == b && !fval(u2->faction, FFL_SELECT) - && cansee(u->faction, r, u2, 0)) { + && cansee(u->faction, r, u2, 0, seen_unit)) { mailunit(r, u, u2->no, ord, s); fset(u2->faction, FFL_SELECT); } @@ -2078,7 +2078,7 @@ int mail_cmd(unit * u, struct order *ord) for (u2 = r->units; u2; u2 = u2->next) { if (u2->ship == sh && !fval(u2->faction, FFL_SELECT) - && cansee(u->faction, r, u2, 0)) { + && cansee(u->faction, r, u2, 0, seen_unit)) { mailunit(r, u, u2->no, ord, s); fset(u2->faction, FFL_SELECT); } @@ -4281,10 +4281,9 @@ void update_subscriptions(void) * Es muss auch niemand aus f in der region sein, wenn sie vom Turm * erblickt wird */ bool -cansee(const faction * f, const region * r, const unit * u, int modifier) +cansee(const faction * f, const region * r, const unit * u, int modifier, seen_mode mode) { int stealth, rings; - unit *u2 = r->units; if (u->faction == f || omniscient(f)) { return true; @@ -4303,44 +4302,45 @@ cansee(const faction * f, const region * r, const unit * u, int modifier) } } - if (leftship(u)) - return true; - - while (u2 && u2->faction != f) - u2 = u2->next; - if (u2 == NULL) - return false; - - /* simple visibility, just gotta have a unit in the region to see 'em */ - if (is_guard(u) || usiege(u) || u->building || u->ship) { + /* simple visibility, just gotta have a viewer in the region to see 'em */ + if (leftship(u) || is_guard(u) || usiege(u) || u->building || u->ship) { return true; } rings = invisible(u, NULL); stealth = eff_stealth(u, r) - modifier; - while (u2) { - if (rings < u->number || invisible(u, u2) < u->number) { - if (skill_enabled(SK_PERCEPTION)) { - int observation = effskill(u2, SK_PERCEPTION, 0); + if (mode > seen_unit) { + return (rings <= 0 || stealth <= 0); + } + else { + unit *u2; + for (u2 = r->units; u2; u2 = u2->next) { + if (u2->faction == f) { + if (rings < u->number || invisible(u, u2) < u->number) { + if (skill_enabled(SK_PERCEPTION)) { + int observation = effskill(u2, SK_PERCEPTION, 0); - if (observation >= stealth) { - return true; + if (observation >= stealth) { + return true; + } + } + else { + return true; + } } } - else { - return true; - } } - - /* find next unit in our faction */ - do { - u2 = u2->next; - } while (u2 && u2->faction != f); } return false; } +bool +cansee_depr(const faction * f, const region * r, const unit * u, int modifier) +{ + return cansee(f, r, u, modifier, seen_unit); +} + bool cansee_unit(const unit * u, const unit * target, int modifier) /* target->region kann != u->region sein, wenn es um durchreisen geht */ { @@ -4427,7 +4427,7 @@ bool seefaction(const faction * f, const region * r, const unit * u, int modifier) { if (((f == u->faction) || !fval(u, UFL_ANON_FACTION)) - && cansee(f, r, u, modifier)) + && cansee(f, r, u, modifier, seen_unit)) return true; return false; } diff --git a/src/laws.h b/src/laws.h index 7f1385483..32a5b4ef3 100755 --- a/src/laws.h +++ b/src/laws.h @@ -98,7 +98,9 @@ extern "C" { void nmr_warnings(void); - bool cansee(const struct faction *f, const struct region *r, + bool cansee(const struct faction * f, const struct region * r, + const struct unit *u, int modifier, seen_mode mode); + bool cansee_depr(const struct faction *f, const struct region *r, const struct unit *u, int modifier); bool cansee_durchgezogen(const struct faction *f, const struct region *r, const struct unit *u, int modifier); diff --git a/src/magic.c b/src/magic.c index f83e31a7d..d05c87b80 100644 --- a/src/magic.c +++ b/src/magic.c @@ -1621,7 +1621,7 @@ order * ord) if (u->region != r) u = NULL; else if (sp->sptyp & TESTCANSEE) { - if (!cansee(mage->faction, r, u, 0) && !ucontact(u, mage)) { + if (!cansee_depr(mage->faction, r, u, 0) && !ucontact(u, mage)) { u = NULL; } } diff --git a/src/monsters.c b/src/monsters.c index 115759d29..39186ae91 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -159,7 +159,7 @@ static order *monster_attack(unit * u, const unit * target) { assert(u->region == target->region); assert(u->faction != target->faction); - if (!cansee(u->faction, u->region, target, 0)) + if (!cansee_depr(u->faction, u->region, target, 0)) return NULL; if (monster_is_waiting(u)) return NULL; @@ -199,7 +199,7 @@ int monster_attacks(unit * monster, bool rich_only) int money = 0; for (u2 = r->units; u2; u2 = u2->next) { - if (u2->faction != monster->faction && cansee(monster->faction, r, u2, 0) && !in_safe_building(u2, monster)) { + if (u2->faction != monster->faction && cansee_depr(monster->faction, r, u2, 0) && !in_safe_building(u2, monster)) { int m = get_money(u2); if (u_race(monster) == rc_serpent) { /* attack bigger ships only */ diff --git a/src/move.c b/src/move.c index 3f899ac22..117ef266a 100644 --- a/src/move.c +++ b/src/move.c @@ -912,7 +912,7 @@ static void caught_target(region * r, unit * u) target, u)); } else if (!alliedunit(target, u->faction, HELP_ALL) - && cansee(target->faction, r, u, 0)) { + && cansee_depr(target->faction, r, u, 0)) { ADDMSG(&target->faction->msgs, msg_message("followdetect", "unit follower", target, u)); } @@ -1185,7 +1185,7 @@ static void init_transportation(void) continue; } if (!transport(ut, u)) { - if (cansee(u->faction, r, ut, 0)) { + if (cansee_depr(u->faction, r, ut, 0)) { cmistake(u, u->thisorder, 286, MSG_MOVE); } else { @@ -2093,7 +2093,7 @@ static const region_list *travel_i(unit * u, const region_list * route_begin, } } if (!found) { - if (cansee(u->faction, u->region, ut, 0)) { + if (cansee_depr(u->faction, u->region, ut, 0)) { cmistake(u, ord, 90, MSG_MOVE); } else { @@ -2604,7 +2604,7 @@ void follow_unit(unit * u) u2 = a->data.v; } - if (!u2 || (!followship && (u2->region != r || !cansee(u->faction, r, u2, 0)))) { + if (!u2 || (!followship && (u2->region != r || !cansee_depr(u->faction, r, u2, 0)))) { return; } diff --git a/src/report.c b/src/report.c index c23a9466c..311cd98b2 100644 --- a/src/report.c +++ b/src/report.c @@ -2269,7 +2269,7 @@ report_plaintext(const char *filename, report_context * ctx, anyunits = 0; for (r = ctx->first; r != ctx->last; r = r->next) { - int stealthmod = stealth_modifier(r->seen.mode); + int stealthmod = stealth_modifier(r, f, r->seen.mode); building *b = r->buildings; ship *sh = r->ships; @@ -2314,14 +2314,12 @@ report_plaintext(const char *filename, report_context * ctx, newline(out); report_travelthru(out, r, f); } - /* Statistik */ if (wants_stats && r->seen.mode >= seen_unit) statistics(out, r, f); /* Nachrichten an REGION in der Region */ - - if (r->seen.mode == seen_unit || r->seen.mode == seen_travel) { + if (r->seen.mode >= seen_travel) { message_list *mlist = r_getmessages(r, f); if (mlist) { struct mlist **split = merge_messages(mlist, r->msgs); @@ -2350,8 +2348,8 @@ report_plaintext(const char *filename, report_context * ctx, } } while (u && !u->ship) { - if (stealthmod > INT_MIN) { - if (u->faction == f || cansee(f, r, u, stealthmod)) { + if (stealthmod > INT_MIN && r->seen.mode >= seen_unit) { + if (u->faction == f || cansee(f, r, u, stealthmod, r->seen.mode)) { nr_unit(out, f, u, 4, r->seen.mode); } } diff --git a/src/reports.c b/src/reports.c index 1182f89c9..e6021134a 100644 --- a/src/reports.c +++ b/src/reports.c @@ -960,15 +960,16 @@ struct message *msg_curse(const struct curse *c, const void *obj, objtype_t typ, const struct unit *ucansee(const struct faction *f, const struct unit *u, const struct unit *x) { - if (cansee(f, u->region, u, 0)) + if (cansee_depr(f, u->region, u, 0)) return u; return x; } -int stealth_modifier(seen_mode mode) +int stealth_modifier(const region *r, const faction *f, seen_mode mode) { switch (mode) { case seen_spell: + return get_observer(r, f); case seen_unit: return 0; case seen_lighthouse: @@ -1061,14 +1062,14 @@ void get_addresses(report_context * ctx) } for (; r != NULL; r = r->next) { - int stealthmod = stealth_modifier(r->seen.mode); + int stealthmod = stealth_modifier(r, ctx->f, r->seen.mode); if (r->seen.mode == seen_lighthouse) { unit *u = r->units; for (; u; u = u->next) { faction *sf = visible_faction(ctx->f, u); if (lastf != sf) { if (u->building || u->ship || (stealthmod > INT_MIN - && cansee(ctx->f, r, u, stealthmod))) { + && cansee_depr(ctx->f, r, u, stealthmod))) { add_seen_faction_i(&flist, sf); lastf = sf; } @@ -1086,7 +1087,7 @@ void get_addresses(report_context * ctx) if (u->faction != ctx->f) { faction *sf = visible_faction(ctx->f, u); bool ballied = sf && sf != ctx->f && sf != lastf - && !fval(u, UFL_ANON_FACTION) && cansee(ctx->f, r, u, stealthmod); + && !fval(u, UFL_ANON_FACTION) && cansee_depr(ctx->f, r, u, stealthmod); if (ballied || is_allied(ctx->f, sf)) { add_seen_faction_i(&flist, sf); lastf = sf; diff --git a/src/reports.h b/src/reports.h index 083248fd9..a4850a0c7 100644 --- a/src/reports.h +++ b/src/reports.h @@ -70,7 +70,7 @@ extern "C" { const struct unit *ucansee(const struct faction *f, const struct unit *u, const struct unit *x); - int stealth_modifier(seen_mode seen_mode); + int stealth_modifier(const struct region *r, const struct faction *f, seen_mode mode); typedef struct report_context { struct faction *f; diff --git a/src/reports.test.c b/src/reports.test.c index 7c6e8ccf4..0c9cf2b78 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -762,6 +762,24 @@ static void test_report_far_vision(CuTest *tc) { test_cleanup(); } +static void test_stealth_modifier(CuTest *tc) { + region *r; + faction *f; + + test_setup(); + f = test_create_faction(NULL); + r = test_create_region(0, 0, NULL); + CuAssertIntEquals(tc, 0, stealth_modifier(r, f, seen_unit)); + CuAssertIntEquals(tc, -1, stealth_modifier(r, f, seen_travel)); + CuAssertIntEquals(tc, -2, stealth_modifier(r, f, seen_lighthouse)); + CuAssertIntEquals(tc, -1, stealth_modifier(r, f, seen_spell)); + + set_observer(r, f, 10, 1); + CuAssertIntEquals(tc, 10, stealth_modifier(r, f, seen_spell)); + CuAssertIntEquals(tc, -1, stealth_modifier(r, NULL, seen_spell)); + test_cleanup(); +} + CuSuite *get_reports_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -782,6 +800,7 @@ CuSuite *get_reports_suite(void) SUITE_ADD_TEST(suite, test_report_far_vision); SUITE_ADD_TEST(suite, test_reorder_units); SUITE_ADD_TEST(suite, test_seen_faction); + SUITE_ADD_TEST(suite, test_stealth_modifier); SUITE_ADD_TEST(suite, test_regionid); SUITE_ADD_TEST(suite, test_sparagraph); SUITE_ADD_TEST(suite, test_sparagraph_long); diff --git a/src/spells.c b/src/spells.c index c9e914904..2fc21ffff 100644 --- a/src/spells.c +++ b/src/spells.c @@ -362,11 +362,11 @@ int report_action(region * r, unit * actor, message * msg, int flags) if (view == ACTION_CANSEE) { /* Bei Fernzaubern sieht nur die eigene Partei den Magier */ show = show || (r == actor->region - && cansee(u->faction, r, actor, 0)); + && cansee_depr(u->faction, r, actor, 0)); } else if (view == ACTION_CANNOTSEE) { show = !show && !(r == actor->region - && cansee(u->faction, r, actor, 0)); + && cansee_depr(u->faction, r, actor, 0)); } else { /* the unliely (or lazy) case */ @@ -1328,7 +1328,7 @@ static int sp_rosthauch(castorder * co) "mage target amount", mage, u, ironweapon)); ADDMSG(&u->faction->msgs, msg_message("rust_effect", "mage target amount", - cansee(u->faction, r, mage, 0) ? mage : NULL, u, ironweapon)); + cansee_depr(u->faction, r, mage, 0) ? mage : NULL, u, ironweapon)); success += ironweapon; } else { @@ -1405,7 +1405,7 @@ static int sp_kaelteschutz(castorder * co) u)); if (u->faction != mage->faction) ADDMSG(&u->faction->msgs, msg_message("heat_effect", "mage target", - cansee(u->faction, r, mage, 0) ? mage : NULL, u)); + cansee_depr(u->faction, r, mage, 0) ? mage : NULL, u)); i = cast_level; } /* Erstattung? */ @@ -1825,7 +1825,7 @@ static int sp_treewalkenter(castorder * co) m = NULL; for (u2 = r->units; u2; u2 = u2->next) { if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, r, u, 0)) { + if (cansee_depr(u2->faction, r, u, 0)) { fset(u2->faction, FFL_SELECT); if (!m) m = msg_message("astral_disappear", "unit", u); @@ -1842,7 +1842,7 @@ static int sp_treewalkenter(castorder * co) m = NULL; for (u2 = rt->units; u2; u2 = u2->next) { if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, rt, u, 0)) { + if (cansee_depr(u2->faction, rt, u, 0)) { fset(u2->faction, FFL_SELECT); if (!m) m = msg_message("astral_appear", "unit", u); @@ -1971,7 +1971,7 @@ static int sp_treewalkexit(castorder * co) m = NULL; for (u2 = r->units; u2; u2 = u2->next) { if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, r, u, 0)) { + if (cansee_depr(u2->faction, r, u, 0)) { fset(u2->faction, FFL_SELECT); if (!m) m = msg_message("astral_disappear", "unit", u); @@ -1989,7 +1989,7 @@ static int sp_treewalkexit(castorder * co) m = NULL; for (u2 = rt->units; u2; u2 = u2->next) { if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, rt, u, 0)) { + if (cansee_depr(u2->faction, rt, u, 0)) { fset(u2->faction, FFL_SELECT); if (!m) m = msg_message("astral_appear", "unit", u); @@ -2954,7 +2954,7 @@ static int sp_deathcloud(castorder * co) if (!fval(u->faction, FFL_SELECT)) { fset(u->faction, FFL_SELECT); ADDMSG(&u->faction->msgs, msg_message("deathcloud_effect", - "mage region", cansee(u->faction, r, mage, 0) ? mage : NULL, r)); + "mage region", cansee_depr(u->faction, r, mage, 0) ? mage : NULL, r)); } } @@ -3848,7 +3848,7 @@ static int sp_song_of_peace(castorder * co) if (!fval(u->faction, FFL_SELECT)) { message *m = NULL; fset(u->faction, FFL_SELECT); - if (cansee(u->faction, r, mage, 0)) { + if (cansee_depr(u->faction, r, mage, 0)) { if (msg[0] == NULL) msg[0] = msg_message("song_of_peace_effect_0", "mage", mage); m = msg[0]; @@ -3905,7 +3905,7 @@ static int sp_generous(castorder * co) if (!fval(u->faction, FFL_SELECT)) { message *m = NULL; fset(u->faction, FFL_SELECT); - if (cansee(u->faction, r, mage, 0)) { + if (cansee_depr(u->faction, r, mage, 0)) { if (msg[0] == NULL) msg[0] = msg_message("generous_effect_0", "mage", mage); m = msg[0]; @@ -5040,7 +5040,7 @@ int sp_enterastral(castorder * co) m = NULL; for (u2 = r->units; u2; u2 = u2->next) { if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, r, u, 0)) { + if (cansee_depr(u2->faction, r, u, 0)) { fset(u2->faction, FFL_SELECT); if (!m) m = msg_message("astral_disappear", "unit", u); @@ -5058,7 +5058,7 @@ int sp_enterastral(castorder * co) m = NULL; for (u2 = rt->units; u2; u2 = u2->next) { if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, rt, u, 0)) { + if (cansee_depr(u2->faction, rt, u, 0)) { fset(u2->faction, FFL_SELECT); if (!m) m = msg_message("astral_appear", "unit", u); @@ -5184,7 +5184,7 @@ int sp_pullastral(castorder * co) m = NULL; for (u2 = r->units; u2; u2 = u2->next) { if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, r, u, 0)) { + if (cansee_depr(u2->faction, r, u, 0)) { fset(u2->faction, FFL_SELECT); if (!m) m = msg_message("astral_disappear", "unit", u); @@ -5202,7 +5202,7 @@ int sp_pullastral(castorder * co) m = NULL; for (u2 = rt->units; u2; u2 = u2->next) { if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, rt, u, 0)) { + if (cansee_depr(u2->faction, rt, u, 0)) { fset(u2->faction, FFL_SELECT); if (!m) m = msg_message("astral_appear", "unit", u); @@ -5315,7 +5315,7 @@ int sp_leaveastral(castorder * co) m = NULL; for (u2 = r->units; u2; u2 = u2->next) { if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, r, u, 0)) { + if (cansee_depr(u2->faction, r, u, 0)) { fset(u2->faction, FFL_SELECT); if (!m) m = msg_message("astral_disappear", "unit", u); @@ -5333,7 +5333,7 @@ int sp_leaveastral(castorder * co) m = NULL; for (u2 = rt->units; u2; u2 = u2->next) { if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, rt, u, 0)) { + if (cansee_depr(u2->faction, rt, u, 0)) { fset(u2->faction, FFL_SELECT); if (!m) m = msg_message("astral_appear", "unit", u); @@ -5443,7 +5443,7 @@ int sp_fetchastral(castorder * co) m = NULL; for (u2 = ro->units; u2; u2 = u2->next) { if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, ro, u, 0)) { + if (cansee_depr(u2->faction, ro, u, 0)) { fset(u2->faction, FFL_SELECT); if (!m) m = msg_message("astral_disappear", "unit", u); @@ -5460,7 +5460,7 @@ int sp_fetchastral(castorder * co) m = NULL; for (u2 = rt->units; u2; u2 = u2->next) { if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, rt, u, 0)) { + if (cansee_depr(u2->faction, rt, u, 0)) { fset(u2->faction, FFL_SELECT); if (!m) m = msg_message("astral_appear", "unit", u); diff --git a/src/spy.c b/src/spy.c index 210be63e4..4039e8a8a 100644 --- a/src/spy.c +++ b/src/spy.c @@ -193,7 +193,7 @@ static bool can_set_factionstealth(const unit * u, const faction * f) if (ru->number) { faction *fv = visible_faction(f, ru); if (fv == f) { - if (cansee(f, lastr, ru, 0)) + if (cansee_depr(f, lastr, ru, 0)) return true; } } From 9527460ca482424707f19bf61d0ab811eadbcfa5 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 10 Oct 2017 20:59:51 +0200 Subject: [PATCH 07/11] github issue 734: clear equipments after test. --- src/tests.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests.c b/src/tests.c index 7d20b59c4..770d2853c 100644 --- a/src/tests.c +++ b/src/tests.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -209,6 +210,7 @@ static void test_reset(void) { free_config(); default_locale = 0; calendar_cleanup(); + equipment_done(); close_orders(); free_special_directions(); free_locales(); From ed23853c4d5de25fec5e1c521e4ba99498f7b276 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 10 Oct 2017 21:30:53 +0200 Subject: [PATCH 08/11] add valgrind option to runtests, use in travis builds --- s/runtests | 21 ++++++++++++++++----- s/travis-build | 2 +- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/s/runtests b/s/runtests index 14b5a658b..7a39670dd 100755 --- a/s/runtests +++ b/s/runtests @@ -4,18 +4,29 @@ set -e ROOT=$(git rev-parse --show-toplevel) [ -z $BUILD ] && BUILD=Debug ; export BUILD +UNIT_TESTS=$BUILD/eressea/test_eressea +RUN_TESTS=$BUILD/eressea/eressea +if [ "$1" = "-V" ]; then +VALGRIND=$(which valgrind) +if [ -n "$VALGRIND" ]; then +SUPP=share/ubuntu-12_04.supp +UNIT_TESTS="$VALGRIND --quiet --suppressions=$SUPP --error-exitcode=1 --leak-check=no $UNIT_TESTS" +RUN_TESTS="$VALGRIND --quiet --suppressions=$SUPP --error-exitcode=1 --leak-check=no $RUN_TESTS" +fi +fi + if [ ! -e $ROOT/$BUILD ]; then echo "cannot find build directory $BUILD in $ROOT. did you run cmake-init?" exit fi -$ROOT/$BUILD/eressea/test_eressea +$UNIT_TESTS cd $ROOT [ -e eressea.ini ] || ln -sf conf/eressea.ini -$ROOT/$BUILD/eressea/eressea -v1 scripts/run-tests.lua -$ROOT/$BUILD/eressea/eressea -v1 scripts/run-tests-e2.lua -$ROOT/$BUILD/eressea/eressea -v1 scripts/run-tests-e3.lua -$ROOT/$BUILD/eressea/eressea --version +$RUN_TESTS -v1 scripts/run-tests.lua +$RUN_TESTS -v1 scripts/run-tests-e2.lua +$RUN_TESTS -v1 scripts/run-tests-e3.lua +$RUN_TESTS --version rm -rf data reports orders.txt score score.alliances datum turn cd $OLDWPD diff --git a/s/travis-build b/s/travis-build index 9293ac12d..438f2ce36 100755 --- a/s/travis-build +++ b/s/travis-build @@ -22,6 +22,6 @@ s/cmake-init s/build cd $ROOT inifile -s/runtests +s/runtests -V integration_tests From a82034b8a7e9a3aea4fb53d375edda293a2cc195 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 13 Oct 2017 18:30:22 +0200 Subject: [PATCH 09/11] BUG 2372 canride breakage --- src/move.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/move.c b/src/move.c index 117ef266a..eec5c74df 100644 --- a/src/move.c +++ b/src/move.c @@ -425,7 +425,7 @@ bool canswim(unit * u) return false; } -static int canride(const unit * u) +static int walk_mode(const unit * u) { int horses = 0, maxhorses, unicorns = 0, maxunicorns; int skill = effskill(u, SK_RIDING, 0); @@ -1407,7 +1407,7 @@ int movement_speed(const unit * u) mp = BP_DRAGON; break; default: - mp = canride(u); + mp = walk_mode(u); if (mp>=BP_RIDING) { dk = 1.0; } @@ -1611,7 +1611,7 @@ static const region_list *travel_route(unit * u, if (mode == TRAVEL_RUNNING) { walkmode = 0; } - if (canride(u)) { + else if (walk_mode(u) >= BP_RIDING) { walkmode = 1; produceexp(u, SK_RIDING, u->number); } From 8246639e57da1b9dc08a9a547e536c5f842ebe4f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 13 Oct 2017 18:41:29 +0200 Subject: [PATCH 10/11] test cansee for perception & stealth --- src/laws.test.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/laws.test.c b/src/laws.test.c index ee5c55f19..537aadd57 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1579,6 +1579,23 @@ static void test_demon_hunger(CuTest * tc) test_cleanup(); } +static void test_cansee(CuTest *tc) { + unit *u, *u2; + test_setup(); + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + u2 = test_create_unit(test_create_faction(0), u->region); + + CuAssertTrue(tc, cansee(u->faction, u->region, u2, 0, seen_unit)); + + set_level(u2, SK_STEALTH, 1); + CuAssertTrue(tc, !cansee(u->faction, u->region, u2, 0, seen_unit)); + + set_level(u, SK_PERCEPTION, 1); + CuAssertTrue(tc, cansee(u->faction, u->region, u2, 0, seen_unit)); + + test_cleanup(); +} + static void test_armedmen(CuTest *tc) { /* TODO: test RCF_NOWEAPONS and SK_WEAPONLESS */ unit *u; @@ -1683,6 +1700,7 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_immigration); SUITE_ADD_TEST(suite, test_demon_hunger); SUITE_ADD_TEST(suite, test_armedmen); + SUITE_ADD_TEST(suite, test_cansee); return suite; } From ca6cbe5906e748572a0eca19f21cc0fc1603113e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 13 Oct 2017 19:07:57 +0200 Subject: [PATCH 11/11] fixing commit 1b53128e1a and adding a test for cansee. --- src/laws.c | 2 +- src/laws.test.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/laws.c b/src/laws.c index 71309914a..6b27e7816 100644 --- a/src/laws.c +++ b/src/laws.c @@ -4311,7 +4311,7 @@ cansee(const faction * f, const region * r, const unit * u, int modifier, seen_m stealth = eff_stealth(u, r) - modifier; if (mode > seen_unit) { - return (rings <= 0 || stealth <= 0); + return (rings <= 0 && stealth <= 0); } else { unit *u2; diff --git a/src/laws.test.c b/src/laws.test.c index 537aadd57..87d5838b9 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1581,6 +1581,7 @@ static void test_demon_hunger(CuTest * tc) static void test_cansee(CuTest *tc) { unit *u, *u2; + test_setup(); u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); u2 = test_create_unit(test_create_faction(0), u->region); @@ -1589,9 +1590,45 @@ static void test_cansee(CuTest *tc) { set_level(u2, SK_STEALTH, 1); CuAssertTrue(tc, !cansee(u->faction, u->region, u2, 0, seen_unit)); + CuAssertTrue(tc, !cansee(u->faction, u->region, u2, 0, seen_spell)); + CuAssertTrue(tc, cansee(u->faction, u->region, u2, 1, seen_spell)); set_level(u, SK_PERCEPTION, 1); CuAssertTrue(tc, cansee(u->faction, u->region, u2, 0, seen_unit)); + CuAssertTrue(tc, !cansee(u->faction, u->region, u2, 0, seen_spell)); + + test_cleanup(); +} + +static void test_cansee_items(CuTest *tc) { + unit *u, *u2; + item_type *itype[3]; + + test_setup(); + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + u2 = test_create_unit(test_create_faction(0), u->region); + scale_number(u2, 2); + + itype[0] = test_create_itemtype("roi"); + itype[1] = test_create_itemtype("sphereofinv"); + itype[2] = test_create_itemtype("aots"); + CuAssertPtrNotNull(tc, get_resourcetype(R_RING_OF_INVISIBILITY)); + CuAssertPtrNotNull(tc, get_resourcetype(R_SPHERE_OF_INVISIBILITY)); + CuAssertPtrNotNull(tc, get_resourcetype(R_AMULET_OF_TRUE_SEEING)); + + CuAssertTrue(tc, cansee(u->faction, u->region, u2, 0, seen_unit)); + + i_change(&u2->items, itype[0], 1); + CuAssertTrue(tc, cansee(u->faction, u->region, u2, 0, seen_unit)); + CuAssertTrue(tc, !cansee(u->faction, u->region, u2, 0, seen_spell)); + + i_change(&u2->items, itype[0], 1); + CuAssertTrue(tc, !cansee(u->faction, u->region, u2, 0, seen_unit)); + CuAssertTrue(tc, !cansee(u->faction, u->region, u2, 0, seen_spell)); + + i_change(&u->items, itype[2], 1); + CuAssertTrue(tc, cansee(u->faction, u->region, u2, 0, seen_unit)); + CuAssertTrue(tc, !cansee(u->faction, u->region, u2, 0, seen_spell)); test_cleanup(); } @@ -1701,6 +1738,7 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_demon_hunger); SUITE_ADD_TEST(suite, test_armedmen); SUITE_ADD_TEST(suite, test_cansee); + SUITE_ADD_TEST(suite, test_cansee_items); return suite; }