diff --git a/res/e3a/races.xml b/res/e3a/races.xml index 46427ba92..164a599b7 100644 --- a/res/e3a/races.xml +++ b/res/e3a/races.xml @@ -883,7 +883,7 @@ - + diff --git a/res/eressea/races.xml b/res/eressea/races.xml index 7f6c6d873..ec119bd21 100644 --- a/res/eressea/races.xml +++ b/res/eressea/races.xml @@ -1171,7 +1171,7 @@ - + diff --git a/src/kernel/race.h b/src/kernel/race.h index 0ae925c5d..fa18cb8f2 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -214,6 +214,7 @@ extern "C" { #define RCF_SHIPSPEED (1<<26) /* race gets +1 on shipspeed */ #define RCF_STONEGOLEM (1<<27) /* race gets stonegolem properties */ #define RCF_IRONGOLEM (1<<28) /* race gets irongolem properties */ +#define RCF_ATTACK_MOVED (1<<29) /* may attack if it has moved */ /* Economic flags */ #define ECF_KEEP_ITEM (1<<1) /* gibt Gegenstände weg */ diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 28a351a72..c5af75d04 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1604,6 +1604,8 @@ static void parse_ai(race * rc, xmlNodePtr node) rc->flags |= RCF_MOVERANDOM; if (xml_bvalue(node, "learn", false)) rc->flags |= RCF_LEARN; + if (xml_bvalue(node, "moveattack", false)) + rc->flags |= RCF_ATTACK_MOVED; } static int parse_races(xmlDocPtr doc) diff --git a/src/monster.c b/src/monster.c index 47858fc5d..3d6fd6f82 100644 --- a/src/monster.c +++ b/src/monster.c @@ -69,7 +69,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. bool monster_is_waiting(const unit * u) { - if (fval(u, UFL_ISNEW | UFL_MOVED)) + int test = fval(u_race(u), RCF_ATTACK_MOVED) ? UFL_ISNEW : UFL_ISNEW | UFL_MOVED; + if (fval(u, test)) return true; return false; } diff --git a/src/piracy.c b/src/piracy.c index 8911f0882..4843880b8 100644 --- a/src/piracy.c +++ b/src/piracy.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +65,8 @@ static attrib *mk_piracy(const faction * pirate, const faction * target, } static bool validate_pirate(unit *u, order *ord) { + if (fval(u_race(u), RCF_SWIM | RCF_FLY)) + return true; if (!u->ship) { cmistake(u, ord, 144, MSG_MOVE); return false; diff --git a/src/piracy.test.c b/src/piracy.test.c index 53907f4df..acc220d3a 100644 --- a/src/piracy.test.c +++ b/src/piracy.test.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,7 @@ static void test_piracy_cmd(CuTest * tc) { } static void test_piracy_cmd_errors(CuTest * tc) { + race *r; faction *f; unit *u, *u2; order *ord; @@ -73,7 +75,8 @@ static void test_piracy_cmd_errors(CuTest * tc) { setup_piracy(); st_boat = st_get_or_create("boat"); - u = test_create_unit(f = test_create_faction(0), test_create_region(0, 0, get_or_create_terrain("ocean"))); + r = test_create_race("pirates"); + u = test_create_unit(f = test_create_faction(r), test_create_region(0, 0, get_or_create_terrain("ocean"))); f->locale = get_or_create_locale("de"); ord = create_order(K_PIRACY, f->locale, ""); assert(u && ord); @@ -81,6 +84,17 @@ static void test_piracy_cmd_errors(CuTest * tc) { piracy_cmd(u, ord); CuAssertPtrNotNullMsg(tc, "must be on a ship for PIRACY", test_find_messagetype(f->msgs, "error144")); + test_clear_messages(f); + fset(r, RCF_SWIM); + piracy_cmd(u, ord); + CuAssertPtrEquals_Msg(tc, "swimmers are pirates", 0, test_find_messagetype(f->msgs, "error144")); + CuAssertPtrEquals_Msg(tc, "swimmers are pirates", 0, test_find_messagetype(f->msgs, "error146")); + freset(r, RCF_SWIM); + fset(r, RCF_FLY); + CuAssertPtrEquals_Msg(tc, "flyers are pirates", 0, test_find_messagetype(f->msgs, "error144")); + freset(r, RCF_FLY); + test_clear_messages(f); + u_set_ship(u, test_create_ship(u->region, st_boat)); u2 = test_create_unit(u->faction, u->region);