From c98612f44e1037f368c25ae531eeb86497ebe921 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 16 Jun 2012 19:14:23 -0700 Subject: [PATCH] adding battle and siege to the eressea.process module --- scripts/tests/bindings.lua | 2 + src/bindings/bind_process.c | 80 ++++++++++++++++++------------ src/bindings/bind_process.h | 2 + src/bindings/bindings.c | 2 +- src/bindings/process.pkg | 2 + src/gamecode/laws.c | 97 +++++++++++++++++++++++++++++++++++++ src/gamecode/laws.h | 1 + src/kernel/build.c | 96 ------------------------------------ src/kernel/build.h | 1 - 9 files changed, 154 insertions(+), 129 deletions(-) diff --git a/scripts/tests/bindings.lua b/scripts/tests/bindings.lua index a686b063f..614c7e414 100755 --- a/scripts/tests/bindings.lua +++ b/scripts/tests/bindings.lua @@ -30,6 +30,8 @@ function test_process() assert_equal("function", _G.type(eressea.process.study)) assert_equal("function", _G.type(eressea.process.movement)) assert_equal("function", _G.type(eressea.process.use)) + assert_equal("function", _G.type(eressea.process.battle)) + assert_equal("function", _G.type(eressea.process.siege)) assert_equal("function", _G.type(eressea.process.leave)) end diff --git a/src/bindings/bind_process.c b/src/bindings/bind_process.c index a3de48c29..3475b9765 100755 --- a/src/bindings/bind_process.c +++ b/src/bindings/bind_process.c @@ -3,7 +3,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -11,31 +13,36 @@ #include #include -static void process_cmd(keyword_t kwd, int (*callback)(unit *, order *)) -{ - region * r; - for (r=regions; r; r=r->next) { - unit * u; - for (u=r->units; u; u=u->next) { - order * ord; - for (ord=u->orders; ord; ord=ord->next) { - if (kwd == get_keyword(ord)) { - callback(u, ord); - } - } - } - } -} +#define PROC_LAND_REGION 0x0001 +#define PROC_LONG_ORDER 0x0002 -static void process_long_cmd(keyword_t kwd, int (*callback)(unit *, order *)) +static void process_cmd(keyword_t kwd, int (*callback)(unit *, order *), int flags) { region * r; for (r=regions; r; r=r->next) { unit * u; + + /* look for shortcuts */ + if (flags&PROC_LAND_REGION) { + /* only execute when we are on solid terrain */ + while (r && (r->terrain->flags&LAND_REGION)==0) { + r = r->next; + } + if (!r) break; + } + for (u=r->units; u; u=u->next) { - order * ord = u->thisorder; - if (kwd == get_keyword(ord)) { - callback(u, ord); + if (flags & PROC_LONG_ORDER) { + if (kwd == get_keyword(u->thisorder)) { + callback(u, u->thisorder); + } + } else { + order * ord; + for (ord=u->orders; ord; ord=ord->next) { + if (kwd == get_keyword(ord)) { + callback(u, ord); + } + } } } } @@ -58,6 +65,17 @@ void process_produce(void) { } } +void process_battle(void) { + struct region *r; + for (r = regions; r; r = r->next) { + do_battle(r); + } +} + +void process_siege(void) { + process_cmd(K_BESIEGE, siege_cmd, PROC_LAND_REGION); +} + void process_update_long_order(void) { region * r; for (r=regions; r; r=r->next) { @@ -102,41 +120,41 @@ void process_settings(void) { } void process_ally(void) { - process_cmd(K_ALLY, ally_cmd); + process_cmd(K_ALLY, ally_cmd, 0); } void process_prefix(void) { - process_cmd(K_PREFIX, prefix_cmd); + process_cmd(K_PREFIX, prefix_cmd, 0); } void process_setstealth(void) { - process_cmd(K_SETSTEALTH, setstealth_cmd); + process_cmd(K_SETSTEALTH, setstealth_cmd, 0); } void process_status(void) { - process_cmd(K_STATUS, status_cmd); + process_cmd(K_STATUS, status_cmd, 0); } void process_display(void) { - process_cmd(K_DISPLAY, display_cmd); + process_cmd(K_DISPLAY, display_cmd, 0); } void process_group(void) { - process_cmd(K_GROUP, group_cmd); + process_cmd(K_GROUP, group_cmd, 0); } void process_origin(void) { - process_cmd(K_URSPRUNG, origin_cmd); + process_cmd(K_URSPRUNG, origin_cmd, 0); } void process_quit(void) { - process_cmd(K_QUIT, quit_cmd); + process_cmd(K_QUIT, quit_cmd, 0); quit(); } void process_study(void) { - process_long_cmd(K_TEACH, teach_cmd); - process_long_cmd(K_STUDY, learn_cmd); + process_cmd(K_TEACH, teach_cmd, PROC_LONG_ORDER); + process_cmd(K_STUDY, learn_cmd, PROC_LONG_ORDER); } void process_movement(void) { @@ -144,9 +162,9 @@ void process_movement(void) { } void process_use(void) { - process_cmd(K_USE, use_cmd); + process_cmd(K_USE, use_cmd, 0); } void process_leave(void) { - process_cmd(K_LEAVE, leave_cmd); + process_cmd(K_LEAVE, leave_cmd, 0); } diff --git a/src/bindings/bind_process.h b/src/bindings/bind_process.h index b2363c6d0..b1a6638e0 100755 --- a/src/bindings/bind_process.h +++ b/src/bindings/bind_process.h @@ -21,6 +21,8 @@ void process_quit(void); void process_study(void); void process_movement(void); void process_use(void); +void process_battle(void); +void process_siege(void); void process_leave(void); #ifdef __cplusplus diff --git a/src/bindings/bindings.c b/src/bindings/bindings.c index ea86df4a0..c73136b44 100755 --- a/src/bindings/bindings.c +++ b/src/bindings/bindings.c @@ -1313,4 +1313,4 @@ int eressea_run(lua_State *L, const char *luafile, const char *entry_point) err = lua_console(L); } return err; -} +} diff --git a/src/bindings/process.pkg b/src/bindings/process.pkg index ed0d57520..4bb8d9362 100755 --- a/src/bindings/process.pkg +++ b/src/bindings/process.pkg @@ -18,6 +18,8 @@ module eressea { void process_study @ study(void); /* LEARN/TEACH */ void process_movement @ movement(void); /* MOVE/FOLLOW/ROUTE */ void process_use @ use(void); /* USE */ + void process_battle @ battle(void); /* ATTACK */ + void process_siege @ siege(void); /* SIEGE */ void process_leave @ leave(void); /* LEAVE */ } } diff --git a/src/gamecode/laws.c b/src/gamecode/laws.c index 565ae8aec..584e8ef94 100755 --- a/src/gamecode/laws.c +++ b/src/gamecode/laws.c @@ -4431,6 +4431,103 @@ void process(void) } +int siege_cmd(unit * u, order * ord) +{ + region *r = u->region; + building *b; + int d, pooled; + int bewaffnete, katapultiere = 0; + static boolean init = false; + static const curse_type *magicwalls_ct; + static item_type *it_catapultammo = NULL; + static item_type *it_catapult = NULL; + if (!init) { + init = true; + magicwalls_ct = ct_find("magicwalls"); + it_catapultammo = it_find("catapultammo"); + it_catapult = it_find("catapult"); + } + /* gibt es ueberhaupt Burgen? */ + + init_tokens(ord); + skip_token(); + b = getbuilding(r); + + if (!b) { + cmistake(u, ord, 31, MSG_BATTLE); + return 31; + } + + if (!playerrace(u->race)) { + /* keine Drachen, Illusionen, Untote etc */ + cmistake(u, ord, 166, MSG_BATTLE); + return 166; + } + /* schaden durch katapulte */ + + d = i_get(u->items, it_catapult); + d = MIN(u->number, d); + pooled = get_pooled(u, it_catapultammo->rtype, GET_DEFAULT, d); + d = MIN(pooled, d); + if (eff_skill(u, SK_CATAPULT, r) >= 1) { + katapultiere = d; + d *= eff_skill(u, SK_CATAPULT, r); + } else { + d = 0; + } + + bewaffnete = armedmen(u, true); + if (d == 0 && bewaffnete == 0) { + /* abbruch, falls unbewaffnet oder unfaehig, katapulte zu benutzen */ + cmistake(u, ord, 80, MSG_EVENT); + return 80; + } + + if (!is_guard(u, GUARD_TRAVELTHRU)) { + /* abbruch, wenn die einheit nicht vorher die region bewacht - als + * warnung fuer alle anderen! */ + cmistake(u, ord, 81, MSG_EVENT); + return 81; + } + /* einheit und burg markieren - spart zeit beim behandeln der einheiten + * in der burg, falls die burg auch markiert ist und nicht alle + * einheiten wieder abgesucht werden muessen! */ + + usetsiege(u, b); + b->besieged += MAX(bewaffnete, katapultiere); + + /* definitiver schaden eingeschraenkt */ + + d = MIN(d, b->size - 1); + + /* meldung, schaden anrichten */ + if (d && !curse_active(get_curse(b->attribs, magicwalls_ct))) { + b->size -= d; + use_pooled(u, it_catapultammo->rtype, + GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, d); + /* send message to the entire region */ + ADDMSG(&r->msgs, msg_message("siege_catapults", + "unit building destruction", u, b, d)); + } else { + /* send message to the entire region */ + ADDMSG(&r->msgs, msg_message("siege", "unit building", u, b)); + } + return 0; +} + +void do_siege(region * r) +{ + if (fval(r->terrain, LAND_REGION)) { + unit *u; + + for (u = r->units; u; u = u->next) { + if (get_keyword(u->thisorder) == K_BESIEGE) { + siege_cmd(u, u->thisorder); + } + } + } +} + static void enter_1(region * r) { do_misc(r, 0); diff --git a/src/gamecode/laws.h b/src/gamecode/laws.h index d0ba9965e..23c727e18 100755 --- a/src/gamecode/laws.h +++ b/src/gamecode/laws.h @@ -67,6 +67,7 @@ extern "C" { extern int quit_cmd(struct unit *u, struct order *ord); extern int name_cmd(struct unit *u, struct order *ord); extern int use_cmd(struct unit *u, struct order *ord); + extern int siege_cmd(struct unit *u, struct order *ord); extern int leave_cmd(struct unit *u, struct order *ord); #ifdef __cplusplus diff --git a/src/kernel/build.c b/src/kernel/build.c index a37265d23..5726f4828 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -89,102 +89,6 @@ ship *getship(const struct region * r) /* ------------------------------------------------------------- */ -static void siege_cmd(unit * u, order * ord) -{ - region *r = u->region; - building *b; - int d, pooled; - int bewaffnete, katapultiere = 0; - static boolean init = false; - static const curse_type *magicwalls_ct; - static item_type *it_catapultammo = NULL; - static item_type *it_catapult = NULL; - if (!init) { - init = true; - magicwalls_ct = ct_find("magicwalls"); - it_catapultammo = it_find("catapultammo"); - it_catapult = it_find("catapult"); - } - /* gibt es ueberhaupt Burgen? */ - - init_tokens(ord); - skip_token(); - b = getbuilding(r); - - if (!b) { - cmistake(u, ord, 31, MSG_BATTLE); - return; - } - - if (!playerrace(u->race)) { - /* keine Drachen, Illusionen, Untote etc */ - cmistake(u, ord, 166, MSG_BATTLE); - return; - } - /* schaden durch katapulte */ - - d = i_get(u->items, it_catapult); - d = MIN(u->number, d); - pooled = get_pooled(u, it_catapultammo->rtype, GET_DEFAULT, d); - d = MIN(pooled, d); - if (eff_skill(u, SK_CATAPULT, r) >= 1) { - katapultiere = d; - d *= eff_skill(u, SK_CATAPULT, r); - } else { - d = 0; - } - - bewaffnete = armedmen(u, true); - if (d == 0 && bewaffnete == 0) { - /* abbruch, falls unbewaffnet oder unfaehig, katapulte zu benutzen */ - cmistake(u, ord, 80, MSG_EVENT); - return; - } - - if (!is_guard(u, GUARD_TRAVELTHRU)) { - /* abbruch, wenn die einheit nicht vorher die region bewacht - als - * warnung fuer alle anderen! */ - cmistake(u, ord, 81, MSG_EVENT); - return; - } - /* einheit und burg markieren - spart zeit beim behandeln der einheiten - * in der burg, falls die burg auch markiert ist und nicht alle - * einheiten wieder abgesucht werden muessen! */ - - usetsiege(u, b); - b->besieged += MAX(bewaffnete, katapultiere); - - /* definitiver schaden eingeschraenkt */ - - d = MIN(d, b->size - 1); - - /* meldung, schaden anrichten */ - if (d && !curse_active(get_curse(b->attribs, magicwalls_ct))) { - b->size -= d; - use_pooled(u, it_catapultammo->rtype, - GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, d); - /* send message to the entire region */ - ADDMSG(&r->msgs, msg_message("siege_catapults", - "unit building destruction", u, b, d)); - } else { - /* send message to the entire region */ - ADDMSG(&r->msgs, msg_message("siege", "unit building", u, b)); - } -} - -void do_siege(region * r) -{ - if (fval(r->terrain, LAND_REGION)) { - unit *u; - - for (u = r->units; u; u = u->next) { - if (get_keyword(u->thisorder) == K_BESIEGE) { - siege_cmd(u, u->thisorder); - } - } - } -} - /* ------------------------------------------------------------- */ static void destroy_road(unit * u, int nmax, struct order *ord) diff --git a/src/kernel/build.h b/src/kernel/build.h index 20577da8e..1e7b7d623 100644 --- a/src/kernel/build.h +++ b/src/kernel/build.h @@ -64,7 +64,6 @@ extern "C" { extern int destroy_cmd(struct unit *u, struct order *ord); extern int leave_cmd(struct unit *u, struct order *ord); - void do_siege(struct region *r); void build_road(struct region *r, struct unit *u, int size, direction_t d); void create_ship(struct region *r, struct unit *u, const struct ship_type *newtype, int size, struct order *ord);