diff --git a/scripts/tests/e2/items.lua b/scripts/tests/e2/items.lua index 9bc747650..93c88790f 100644 --- a/scripts/tests/e2/items.lua +++ b/scripts/tests/e2/items.lua @@ -47,26 +47,38 @@ function test_bagpipe() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") local u = unit.create(f, r, 1) + turn_begin() u:add_item("bagpipeoffear", 1) u:clear_orders() u:add_order("BENUTZEN 1 Dudelsack") - process_orders() + assert_equal(nil, r:get_curse('depression')) + turn_process() + assert_equal(0, r:get_curse('depression')) assert_equal(1, u:get_item("bagpipeoffear")) assert_equal(1, f:count_msg_type('bagpipeoffear_faction')) assert_equal(1, r:count_msg_type('bagpipeoffear_region')) + turn_end() + -- duration is variable, but at least 4 + assert_equal(0, r:get_curse('depression')) end function test_speedsail() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") local u = unit.create(f, r, 1) + + turn_begin() u.ship = ship.create(r, "boat") u:add_item("speedsail", 2) u:clear_orders() u:add_order("BENUTZEN 1 Sonnensegel") - process_orders() + assert_equal(nil, u.ship:get_curse('shipspeed')) + turn_process() + assert_equal(1, u.ship:get_curse('shipspeed')) assert_equal(1, u:get_item("speedsail")) assert_equal(1, f:count_msg_type('use_speedsail')) + turn_end() + assert_equal(1, u.ship:get_curse('shipspeed')) -- effect stays forever end function test_foolpotion() diff --git a/scripts/tests/items.lua b/scripts/tests/items.lua index 48f466409..f82aa9e7b 100644 --- a/scripts/tests/items.lua +++ b/scripts/tests/items.lua @@ -11,20 +11,37 @@ function setup() eressea.settings.set("magic.regeneration.enable", "0") end -function test_mistletoe() +function test_mistletoe_okay() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") local u = unit.create(f, r, 1) + turn_begin() u:add_item('mistletoe', 2) u:clear_orders() u:add_order("BENUTZEN 1 Mistelzweig") - process_orders() + assert_false(u:has_attrib('fleechance')) + turn_process() + assert_true(u:has_attrib('fleechance')) assert_equal(1, u:get_item('mistletoe')) assert_equal(1, f:count_msg_type('use_item')) + turn_end() +end + +function test_mistletoe_fail() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + turn_begin() + u:add_item('mistletoe', 1) + u:clear_orders() + u:add_order("BENUTZEN 1 Mistelzweig") + assert_false(u:has_attrib('fleechance')) u.number = 2 - process_orders() + turn_process() + assert_false(u:has_attrib('fleechance')) assert_equal(1, u:get_item('mistletoe')) assert_equal(1, f:count_msg_type('use_singleperson')) + turn_end() end function test_dreameye() @@ -34,14 +51,14 @@ function test_dreameye() u:add_item("dreameye", 2) u:clear_orders() u:add_order("BENUTZEN 1 Traumauge") - assert_false(u:is_cursed('skillmod')) + assert_nil(u:get_curse('skillmod')) turn_begin() turn_process() - assert_true(u:is_cursed('skillmod')) + assert_not_nil(u:get_curse('skillmod')) assert_equal(1, u:get_item("dreameye")) assert_equal(1, f:count_msg_type('use_tacticcrystal')) turn_end() - assert_false(u:is_cursed('skillmod')) + assert_equal(nil, u:get_curse('skillmod')) end function test_manacrystal() @@ -78,24 +95,36 @@ function test_studypotion() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") local u = unit.create(f, r, 1) + turn_begin() u:add_item("studypotion", 2) u:clear_orders() u:add_order("LERNE Unterhaltung") u:add_order("BENUTZEN 1 Lerntrank") - process_orders() + turn_process() + -- cannot sense the "learning" attribute, because study_cmd + -- removes it during processing :( assert_equal(1, u:get_item("studypotion")) + turn_end() end function test_antimagic() local r = region.create(0, 0, "plain") local f = faction.create("noreply@eressea.de", "human", "de") local u = unit.create(f, r, 1) + + turn_begin() u:add_item("antimagic", 2) u:clear_orders() u:add_order("BENUTZEN 1 Antimagiekristall") - process_orders() + assert_equal(nil, r:get_curse('antimagiczone')) + turn_process() + assert_equal(5, r:get_curse('antimagiczone')) assert_equal(1, r:count_msg_type('use_antimagiccrystal')) assert_equal(1, u:get_item("antimagic")) + turn_end() + assert_equal(5, r:get_curse('antimagiczone')) -- haelt zwei wochen + turn_end() -- hack: age the curse again + assert_equal(nil, r:get_curse('antimagiczone')) end function test_ointment() diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index ae6869df8..0fe42a92e 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -25,6 +25,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* attributes includes */ #include "follow.h" +#include "fleechance.h" #include "hate.h" #include "iceberg.h" #include "key.h" @@ -58,6 +59,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include + attrib_type at_unitdissolve = { "unitdissolve", NULL, NULL, NULL, a_writechars, a_readchars }; @@ -92,6 +94,7 @@ void register_attributes(void) at_register(&at_woodcount); /* neue UNIT-Attribute */ + at_register(&at_fleechance); at_register(&at_siege); at_register(&at_effect); at_register(&at_private); diff --git a/src/attributes/fleechance.c b/src/attributes/fleechance.c index afba2d301..b8012fba5 100644 --- a/src/attributes/fleechance.c +++ b/src/attributes/fleechance.c @@ -38,8 +38,3 @@ attrib *make_fleechance(float fleechance) a->data.flt = fleechance; return a; } - -void init_fleechance(void) -{ - at_register(&at_fleechance); -} diff --git a/src/attributes/fleechance.h b/src/attributes/fleechance.h index b2f75671c..d5817b8b7 100644 --- a/src/attributes/fleechance.h +++ b/src/attributes/fleechance.h @@ -25,7 +25,6 @@ extern "C" { extern struct attrib_type at_fleechance; struct attrib *make_fleechance(float fleechance); - void init_fleechance(void); #ifdef __cplusplus } diff --git a/src/bind_region.c b/src/bind_region.c index 05c0e3842..fdab4a10f 100644 --- a/src/bind_region.c +++ b/src/bind_region.c @@ -19,6 +19,7 @@ without prior permission by the authors of Eressea. #include "chaos.h" #include +#include #include #include #include @@ -670,6 +671,27 @@ static int tolua_distance(lua_State * L) return 1; } +static int tolua_region_get_curse(lua_State *L) { + region *self = (region *)tolua_tousertype(L, 1, 0); + const char *name = tolua_tostring(L, 2, 0); + if (self->attribs) { + curse * c = get_curse(self->attribs, ct_find(name)); + if (c) { + lua_pushnumber(L, curse_geteffect(c)); + return 1; + } + } + return 0; +} + +static int tolua_region_has_attrib(lua_State *L) { + region *self = (region *)tolua_tousertype(L, 1, 0); + const char *name = tolua_tostring(L, 2, 0); + attrib * a = a_find(self->attribs, at_find(name)); + lua_pushboolean(L, a != NULL); + return 1; +} + void tolua_region_open(lua_State * L) { /* register user types */ @@ -691,6 +713,8 @@ void tolua_region_open(lua_State * L) tolua_function(L, TOLUA_CAST "count_msg_type", tolua_region_count_msg_type); + tolua_function(L, TOLUA_CAST "get_curse", &tolua_region_get_curse); + tolua_function(L, TOLUA_CAST "has_attrib", &tolua_region_has_attrib); /* flags */ tolua_variable(L, TOLUA_CAST "blocked", tolua_region_get_blocked, tolua_region_set_blocked); diff --git a/src/bind_ship.c b/src/bind_ship.c index 515fa8de3..c5e0735ed 100644 --- a/src/bind_ship.c +++ b/src/bind_ship.c @@ -16,11 +16,13 @@ without prior permission by the authors of Eressea. #include "move.h" +#include #include #include #include #include +#include #include #include @@ -198,6 +200,27 @@ static int tolua_ship_set_damage(lua_State * L) return 0; } +static int tolua_ship_get_curse(lua_State *L) { + ship *self = (ship *)tolua_tousertype(L, 1, 0); + const char *name = tolua_tostring(L, 2, 0); + if (self->attribs) { + curse * c = get_curse(self->attribs, ct_find(name)); + if (c) { + lua_pushnumber(L, curse_geteffect(c)); + return 1; + } + } + return 0; +} + +static int tolua_ship_has_attrib(lua_State *L) { + ship *self = (ship *)tolua_tousertype(L, 1, 0); + const char *name = tolua_tostring(L, 2, 0); + attrib * a = a_find(self->attribs, at_find(name)); + lua_pushboolean(L, a != NULL); + return 1; +} + void tolua_ship_open(lua_State * L) { /* register user types */ @@ -225,6 +248,10 @@ void tolua_ship_open(lua_State * L) tolua_variable(L, TOLUA_CAST "type", tolua_ship_get_type, 0); tolua_variable(L, TOLUA_CAST "damage", tolua_ship_get_damage, tolua_ship_set_damage); + + tolua_function(L, TOLUA_CAST "get_curse", &tolua_ship_get_curse); + tolua_function(L, TOLUA_CAST "has_attrib", &tolua_ship_has_attrib); + tolua_function(L, TOLUA_CAST "create", tolua_ship_create); } tolua_endmodule(L); diff --git a/src/bind_unit.c b/src/bind_unit.c index 0358e1938..8247e13d5 100755 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -771,17 +771,23 @@ static int tolua_unit_get_orders(lua_State * L) return 1; } -static int tolua_unit_is_cursed(lua_State *L) { +static int tolua_unit_get_curse(lua_State *L) { unit *self = (unit *)tolua_tousertype(L, 1, 0); const char *name = tolua_tostring(L, 2, 0); - lua_pushboolean(L, self->attribs && curse_active(get_curse(self->attribs, ct_find(name)))); - return 1; + if (self->attribs) { + curse * c = get_curse(self->attribs, ct_find(name)); + if (c) { + lua_pushnumber(L, curse_geteffect(c)); + return 1; + } + } + return 0; } static int tolua_unit_has_attrib(lua_State *L) { unit *self = (unit *)tolua_tousertype(L, 1, 0); const char *name = tolua_tostring(L, 2, 0); - attrib * a = a_find(self->attribs, at_find(name)); + attrib * a = self->attribs ? a_find(self->attribs, at_find(name)) : NULL; lua_pushboolean(L, a != NULL); return 1; } @@ -972,7 +978,7 @@ void tolua_unit_open(lua_State * L) tolua_function(L, TOLUA_CAST "clear_orders", &tolua_unit_clear_orders); tolua_variable(L, TOLUA_CAST "orders", &tolua_unit_get_orders, 0); - tolua_function(L, TOLUA_CAST "is_cursed", &tolua_unit_is_cursed); + tolua_function(L, TOLUA_CAST "get_curse", &tolua_unit_get_curse); tolua_function(L, TOLUA_CAST "has_attrib", &tolua_unit_has_attrib); /* key-attributes for named flags: */ diff --git a/src/items.c b/src/items.c index 192bb111d..f8739cb73 100644 --- a/src/items.c +++ b/src/items.c @@ -43,7 +43,7 @@ static int use_studypotion(struct unit *u, const struct item_type *itype, int amount, struct order *ord) { - if (init_order(u->thisorder) == K_STUDY) { + if (u->thisorder && init_order(u->thisorder) == K_STUDY) { char token[128]; skill_t sk = NOSKILL; skill *sv = 0; @@ -97,9 +97,8 @@ struct order *ord) } effect = SPEEDSAIL_EFFECT; - c = - create_curse(u, &sh->attribs, ct_find("shipspeedup"), 20, INT_MAX, effect, - 0); + c = create_curse(u, &sh->attribs, ct_find("shipspeedup"), 20, INT_MAX, + effect, 0); c_setflag(c, CURSE_NOAGE); ADDMSG(&u->faction->msgs, msg_message("use_speedsail", "unit speed", u, diff --git a/src/util/attrib.c b/src/util/attrib.c index 993f634d2..b3b9c0a6e 100644 --- a/src/util/attrib.c +++ b/src/util/attrib.c @@ -179,16 +179,6 @@ void at_register(attrib_type * at) at_hash[at->hashkey % MAXATHASH] = at; } -struct attrib_type *at_find(const char *name) { - attrib_type *find; - unsigned int hash = __at_hashkey(name); - find = at_hash[hash % MAXATHASH]; - while (find && hash != find->hashkey) { - find = find->nexthash; - } - return find; -} - static attrib_type *at_find_key(unsigned int hk) { const char *translate[3][2] = { @@ -210,6 +200,11 @@ static attrib_type *at_find_key(unsigned int hk) return find; } +struct attrib_type *at_find(const char *name) { + unsigned int hash = __at_hashkey(name); + return at_find_key(hash); +} + attrib *a_select(attrib * a, const void *data, bool(*compare) (const attrib *, const void *)) { @@ -220,6 +215,7 @@ attrib *a_select(attrib * a, const void *data, attrib *a_find(attrib * a, const attrib_type * at) { + assert(at); while (a && a->type != at) a = a->nexttype; return a;