From 10edb1d3e9ec12300f05c36c98647841f719ae1e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 27 Feb 2017 19:35:14 +0100 Subject: [PATCH] enable process_orders to be done in steps. by checking before turn_end(), we can sense temporary attributes and curses on a unit before they age away. --- src/bind_unit.c | 19 +++++++++++++++++ src/bindings.c | 53 +++++++++++++++++++---------------------------- src/laws.c | 49 +++++++++++++++++++++++++++++++++++++++++-- src/laws.h | 4 +++- src/util/attrib.c | 16 +++++++++++--- src/util/attrib.h | 18 ++++++++-------- 6 files changed, 112 insertions(+), 47 deletions(-) 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/laws.c b/src/laws.c index 3d996971b..1c71f1192 100644 --- a/src/laws.c +++ b/src/laws.c @@ -4194,16 +4194,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(); @@ -4218,6 +4256,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);