diff --git a/res/core/common/items.xml b/res/core/common/items.xml
index 0e1505205..8f2bbabf8 100644
--- a/res/core/common/items.xml
+++ b/res/core/common/items.xml
@@ -110,20 +110,16 @@
- -
-
-
+
- -
-
-
+
-
+
diff --git a/res/eressea/artrewards.xml b/res/eressea/artrewards.xml
index 2a3c09950..b18fd5b20 100644
--- a/res/eressea/artrewards.xml
+++ b/res/eressea/artrewards.xml
@@ -3,16 +3,12 @@
- -
-
-
+
- -
-
-
+
diff --git a/scripts/tests/e2/items.lua b/scripts/tests/e2/items.lua
index da72bdbbc..9bc747650 100644
--- a/scripts/tests/e2/items.lua
+++ b/scripts/tests/e2/items.lua
@@ -1,6 +1,6 @@
require "lunit"
-module("tests.items", package.seeall, lunit.testcase )
+module("tests.e2.items", package.seeall, lunit.testcase )
function setup()
eressea.free_game()
@@ -18,9 +18,11 @@ function test_meow()
u:add_item("aoc", 1)
u:clear_orders()
u:add_order("BENUTZEN 1 Katzenamulett")
- process_orders()
+ turn_begin()
+ turn_process()
assert_equal(1, u:get_item("aoc"))
assert_equal(1, r:count_msg_type('meow'))
+ turn_end()
end
function test_aurapotion50()
@@ -33,10 +35,12 @@ function test_aurapotion50()
u.aura = 0
u:clear_orders()
u:add_order("BENUTZEN 1 Auratrank")
- process_orders()
+ turn_begin()
+ turn_process()
assert_equal(0, u:get_item("aurapotion50"))
assert_equal(1, f:count_msg_type('aurapotion50'))
assert_equal(50, u.aura)
+ turn_end()
end
function test_bagpipe()
@@ -69,24 +73,26 @@ function test_foolpotion()
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("p7", 1)
u:clear_orders()
u:add_order("BENUTZEN 1 Dumpfbackenbrot 4242")
- process_orders()
+ turn_process()
assert_equal(1, u:get_item("p7"))
assert_equal(1, f:count_msg_type('feedback_unit_not_found'))
local u2 = unit.create(f, r, 1)
u:clear_orders()
u:add_order("BENUTZEN 1 Dumpfbackenbrot " .. itoa36(u2.id))
- process_orders()
+ turn_process()
assert_equal(1, u:get_item("p7"))
assert_equal(1, f:count_msg_type('error64'))
u:set_skill("stealth", 1);
- process_orders()
+ turn_process()
assert_equal(0, u:get_item("p7"))
assert_equal(1, f:count_msg_type('givedumb'))
+ turn_end()
end
function test_snowman()
diff --git a/scripts/tests/items.lua b/scripts/tests/items.lua
index ff292b4cb..48f466409 100644
--- a/scripts/tests/items.lua
+++ b/scripts/tests/items.lua
@@ -11,6 +11,22 @@ function setup()
eressea.settings.set("magic.regeneration.enable", "0")
end
+function test_mistletoe()
+ local r = region.create(0, 0, "plain")
+ local f = faction.create("noreply@eressea.de", "human", "de")
+ local u = unit.create(f, r, 1)
+ u:add_item('mistletoe', 2)
+ u:clear_orders()
+ u:add_order("BENUTZEN 1 Mistelzweig")
+ process_orders()
+ assert_equal(1, u:get_item('mistletoe'))
+ assert_equal(1, f:count_msg_type('use_item'))
+ u.number = 2
+ process_orders()
+ assert_equal(1, u:get_item('mistletoe'))
+ assert_equal(1, f:count_msg_type('use_singleperson'))
+end
+
function test_dreameye()
local r = region.create(0, 0, "plain")
local f = faction.create("noreply@eressea.de", "human", "de")
@@ -18,9 +34,14 @@ function test_dreameye()
u:add_item("dreameye", 2)
u:clear_orders()
u:add_order("BENUTZEN 1 Traumauge")
- process_orders()
+ assert_false(u:is_cursed('skillmod'))
+ turn_begin()
+ turn_process()
+ assert_true(u:is_cursed('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'))
end
function test_manacrystal()
@@ -33,10 +54,12 @@ function test_manacrystal()
u:set_skill('magic', 1)
u.aura = 0
u:add_order("BENUTZEN 1 Astralkristall")
- process_orders()
+ turn_begin()
+ turn_process()
assert_equal(1, u:get_item("manacrystal"))
assert_equal(25, u.aura)
assert_equal(1, f:count_msg_type('manacrystal_use'))
+ turn_end()
end
function test_skillpotion()
diff --git a/src/bind_unit.c b/src/bind_unit.c
index c8ac2b362..0358e1938 100755
--- a/src/bind_unit.c
+++ b/src/bind_unit.c
@@ -26,6 +26,7 @@ without prior permission by the authors of Eressea.
/* kernel includes */
#include
#include
+#include
#include
#include
#include
@@ -770,6 +771,21 @@ static int tolua_unit_get_orders(lua_State * L)
return 1;
}
+static int tolua_unit_is_cursed(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;
+}
+
+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));
+ lua_pushboolean(L, a != NULL);
+ return 1;
+}
+
static int tolua_unit_get_flag(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
@@ -956,6 +972,9 @@ 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 "has_attrib", &tolua_unit_has_attrib);
+
/* key-attributes for named flags: */
tolua_function(L, TOLUA_CAST "set_flag", &tolua_unit_set_flag);
tolua_function(L, TOLUA_CAST "get_flag", &tolua_unit_get_flag);
diff --git a/src/bindings.c b/src/bindings.c
index 18261a507..1d6270b35 100755
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -480,44 +480,30 @@ static int tolua_write_reports(lua_State * L)
return 1;
}
-static void reset_game(void)
-{
- region *r;
- faction *f;
- for (r = regions; r; r = r->next) {
- unit *u;
- building *b;
- r->flags &= RF_SAVEMASK;
- for (u = r->units; u; u = u->next) {
- u->flags &= UFL_SAVEMASK;
- }
- for (b = r->buildings; b; b = b->next) {
- b->flags &= BLD_SAVEMASK;
- }
- if (r->land && r->land->ownership && r->land->ownership->owner) {
- faction *owner = r->land->ownership->owner;
- if (owner == get_monsters()) {
- /* some compat-fix, i believe. */
- owner = update_owners(r);
- }
- if (owner) {
- fset(r, RF_GUARDED);
- }
- }
- }
- for (f = factions; f; f = f->next) {
- f->flags &= FFL_SAVEMASK;
- }
-}
-
static int tolua_process_orders(lua_State * L)
{
- ++turn;
- reset_game();
processorders();
return 0;
}
+static int tolua_turn_begin(lua_State * L)
+{
+ turn_begin();
+ return 0;
+}
+
+static int tolua_turn_process(lua_State * L)
+{
+ turn_process();
+ return 0;
+}
+
+static int tolua_turn_end(lua_State * L)
+{
+ turn_end();
+ return 0;
+}
+
static int tolua_write_passwords(lua_State * L)
{
int result = writepasswd();
@@ -1063,6 +1049,9 @@ int tolua_bindings_open(lua_State * L, const dictionary *inifile)
tolua_function(L, TOLUA_CAST "factions", tolua_get_factions);
tolua_function(L, TOLUA_CAST "regions", tolua_get_regions);
tolua_function(L, TOLUA_CAST "read_turn", tolua_read_turn);
+ tolua_function(L, TOLUA_CAST "turn_begin", tolua_turn_begin);
+ tolua_function(L, TOLUA_CAST "turn_process", tolua_turn_process);
+ tolua_function(L, TOLUA_CAST "turn_end", tolua_turn_end);
tolua_function(L, TOLUA_CAST "process_orders", tolua_process_orders);
tolua_function(L, TOLUA_CAST "init_reports", tolua_init_reports);
tolua_function(L, TOLUA_CAST "write_reports", tolua_write_reports);
diff --git a/src/items.c b/src/items.c
index ccba7ae7f..192bb111d 100644
--- a/src/items.c
+++ b/src/items.c
@@ -21,6 +21,8 @@
#include
#include
+#include
+
/* triggers includes */
#include
#include
@@ -347,7 +349,7 @@ use_tacticcrystal(unit * u, const struct item_type *itype, int amount,
{
int i;
for (i = 0; i != amount; ++i) {
- int duration = 1; /* wirkt nur eine Runde */
+ int duration = 1; /* wirkt nur in dieser Runde */
curse *c;
float effect;
float power = 5; /* Widerstand gegen Antimagiesprueche, ist in diesem
@@ -366,9 +368,32 @@ use_tacticcrystal(unit * u, const struct item_type *itype, int amount,
return 0;
}
+static int
+use_mistletoe(struct unit *user, const struct item_type *itype, int amount,
+ struct order *ord)
+{
+ int mtoes =
+ get_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,
+ user->number);
+
+ if (user->number > mtoes) {
+ ADDMSG(&user->faction->msgs, msg_message("use_singleperson",
+ "unit item region command", user, itype->rtype, user->region, ord));
+ return -1;
+ }
+ use_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,
+ user->number);
+ a_add(&user->attribs, make_fleechance((float)1.0));
+ ADDMSG(&user->faction->msgs,
+ msg_message("use_item", "unit item", user, itype->rtype));
+
+ return 0;
+}
+
void register_itemfunctions(void)
{
/* have tests: */
+ register_item_use(use_mistletoe, "use_mistletoe");
register_item_use(use_tacticcrystal, "use_dreameye");
register_item_use(use_studypotion, "use_studypotion");
register_item_use(use_antimagiccrystal, "use_antimagic");
diff --git a/src/kernel/item.c b/src/kernel/item.c
index adfddf6f4..1692ed706 100644
--- a/src/kernel/item.c
+++ b/src/kernel/item.c
@@ -746,29 +746,6 @@ static int use_warmthpotion(unit *u, const item_type *itype,
return 0;
}
-#include
-static int
-use_mistletoe(struct unit *user, const struct item_type *itype, int amount,
-struct order *ord)
-{
- int mtoes =
- get_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,
- user->number);
-
- if (user->number > mtoes) {
- ADDMSG(&user->faction->msgs, msg_message("use_singleperson",
- "unit item region command", user, itype->rtype, user->region, ord));
- return -1;
- }
- use_pooled(user, itype->rtype, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK,
- user->number);
- a_add(&user->attribs, make_fleechance((float)1.0));
- ADDMSG(&user->faction->msgs,
- msg_message("use_item", "unit item", user, itype->rtype));
-
- return 0;
-}
-
static int
use_magicboost(struct unit *user, const struct item_type *itype, int amount,
struct order *ord)
@@ -1137,7 +1114,6 @@ void register_resources(void)
register_item_use(use_potion_delayed, "use_p2");
register_item_use(use_warmthpotion, "use_nestwarmth");
- register_item_use(use_mistletoe, "usemistletoe");
register_item_use(use_magicboost, "usemagicboost");
register_item_use(use_snowball, "usesnowball");
diff --git a/src/laws.c b/src/laws.c
index 0d0e53110..cc10baeb5 100644
--- a/src/laws.c
+++ b/src/laws.c
@@ -4186,16 +4186,54 @@ void init_processor(void)
}
}
-void processorders(void)
+static void reset_game(void)
+{
+ region *r;
+ faction *f;
+ for (r = regions; r; r = r->next) {
+ unit *u;
+ building *b;
+ r->flags &= RF_SAVEMASK;
+ for (u = r->units; u; u = u->next) {
+ u->flags &= UFL_SAVEMASK;
+ }
+ for (b = r->buildings; b; b = b->next) {
+ b->flags &= BLD_SAVEMASK;
+ }
+ if (r->land && r->land->ownership && r->land->ownership->owner) {
+ faction *owner = r->land->ownership->owner;
+ if (owner == get_monsters()) {
+ /* some compat-fix, i believe. */
+ owner = update_owners(r);
+ }
+ if (owner) {
+ fset(r, RF_GUARDED);
+ }
+ }
+ }
+ for (f = factions; f; f = f->next) {
+ f->flags &= FFL_SAVEMASK;
+ }
+}
+
+void turn_begin(void)
+{
+ ++turn;
+ reset_game();
+}
+
+void turn_process(void)
{
init_processor();
process();
- /*************************************************/
if (config_get_int("modules.markets", 0)) {
do_markets();
}
+}
+void turn_end(void)
+{
log_info(" - Attribute altern");
ageing();
remove_empty_units();
@@ -4210,6 +4248,13 @@ void processorders(void)
update_spells();
}
+void processorders(void)
+{
+ turn_begin();
+ turn_process();
+ turn_end();
+}
+
void update_subscriptions(void)
{
FILE *F;
diff --git a/src/laws.h b/src/laws.h
index f05c11ab4..090d2b978 100755
--- a/src/laws.h
+++ b/src/laws.h
@@ -53,8 +53,10 @@ extern "C" {
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);
+ void turn_begin(void);
+ void turn_process(void);
+ void turn_end(void);
void new_units(void);
void defaultorders(void);
diff --git a/src/util/attrib.c b/src/util/attrib.c
index fda143168..993f634d2 100644
--- a/src/util/attrib.c
+++ b/src/util/attrib.c
@@ -179,7 +179,17 @@ void at_register(attrib_type * at)
at_hash[at->hashkey % MAXATHASH] = at;
}
-static attrib_type *at_find(unsigned int hk)
+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] = {
{ "zielregion", "targetregion" }, /* remapping: from 'zielregion, heute targetregion */
@@ -193,7 +203,7 @@ static attrib_type *at_find(unsigned int hk)
int i = 0;
while (translate[i][0]) {
if (__at_hashkey(translate[i][0]) == hk)
- return at_find(__at_hashkey(translate[i][1]));
+ return at_find_key(__at_hashkey(translate[i][1]));
++i;
}
}
@@ -408,7 +418,7 @@ void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct gamed
static int a_read_i(gamedata *data, attrib ** attribs, void *owner, unsigned int key) {
int retval = AT_READ_OK;
int(*reader)(attrib *, void *, struct gamedata *) = 0;
- attrib_type *at = at_find(key);
+ attrib_type *at = at_find_key(key);
attrib * na = 0;
if (at) {
diff --git a/src/util/attrib.h b/src/util/attrib.h
index 601a6f32a..6043a960f 100644
--- a/src/util/attrib.h
+++ b/src/util/attrib.h
@@ -65,19 +65,19 @@ extern "C" {
unsigned int hashkey;
} attrib_type;
- extern void at_register(attrib_type * at);
- extern void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct gamedata *));
+ void at_register(attrib_type * at);
+ void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct gamedata *));
+ struct attrib_type *at_find(const char *name);
void write_attribs(struct storage *store, struct attrib *alist, const void *owner);
int read_attribs(struct gamedata *store, struct attrib **alist, void *owner);
- extern attrib *a_select(attrib * a, const void *data,
- bool(*compare) (const attrib *, const void *));
- extern attrib *a_find(attrib * a, const attrib_type * at);
- extern attrib *a_add(attrib ** pa, attrib * at);
- extern int a_remove(attrib ** pa, attrib * at);
- extern void a_removeall(attrib ** a, const attrib_type * at);
- extern attrib *a_new(const attrib_type * at);
+ attrib *a_select(attrib * a, const void *data, bool(*compare) (const attrib *, const void *));
+ attrib *a_find(attrib * a, const attrib_type * at);
+ attrib *a_add(attrib ** pa, attrib * at);
+ int a_remove(attrib ** pa, attrib * at);
+ void a_removeall(attrib ** a, const attrib_type * at);
+ attrib *a_new(const attrib_type * at);
int a_age(attrib ** attribs, void *owner);
int a_read_orig(struct gamedata *data, attrib ** attribs, void *owner);