forked from github/server
adding battle and siege to the eressea.process module
This commit is contained in:
parent
527d6c8bf9
commit
c98612f44e
|
@ -30,6 +30,8 @@ function test_process()
|
||||||
assert_equal("function", _G.type(eressea.process.study))
|
assert_equal("function", _G.type(eressea.process.study))
|
||||||
assert_equal("function", _G.type(eressea.process.movement))
|
assert_equal("function", _G.type(eressea.process.movement))
|
||||||
assert_equal("function", _G.type(eressea.process.use))
|
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))
|
assert_equal("function", _G.type(eressea.process.leave))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include <kernel/types.h>
|
#include <kernel/types.h>
|
||||||
#include <kernel/order.h>
|
#include <kernel/order.h>
|
||||||
|
#include <kernel/battle.h>
|
||||||
#include <kernel/region.h>
|
#include <kernel/region.h>
|
||||||
|
#include <kernel/terrain.h>
|
||||||
#include <kernel/unit.h>
|
#include <kernel/unit.h>
|
||||||
#include <kernel/move.h>
|
#include <kernel/move.h>
|
||||||
#include <gamecode/economy.h>
|
#include <gamecode/economy.h>
|
||||||
|
@ -11,12 +13,30 @@
|
||||||
#include <gamecode/market.h>
|
#include <gamecode/market.h>
|
||||||
#include <gamecode/study.h>
|
#include <gamecode/study.h>
|
||||||
|
|
||||||
static void process_cmd(keyword_t kwd, int (*callback)(unit *, order *))
|
#define PROC_LAND_REGION 0x0001
|
||||||
|
#define PROC_LONG_ORDER 0x0002
|
||||||
|
|
||||||
|
static void process_cmd(keyword_t kwd, int (*callback)(unit *, order *), int flags)
|
||||||
{
|
{
|
||||||
region * r;
|
region * r;
|
||||||
for (r=regions; r; r=r->next) {
|
for (r=regions; r; r=r->next) {
|
||||||
unit * u;
|
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) {
|
for (u=r->units; u; u=u->next) {
|
||||||
|
if (flags & PROC_LONG_ORDER) {
|
||||||
|
if (kwd == get_keyword(u->thisorder)) {
|
||||||
|
callback(u, u->thisorder);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
order * ord;
|
order * ord;
|
||||||
for (ord=u->orders; ord; ord=ord->next) {
|
for (ord=u->orders; ord; ord=ord->next) {
|
||||||
if (kwd == get_keyword(ord)) {
|
if (kwd == get_keyword(ord)) {
|
||||||
|
@ -25,19 +45,6 @@ static void process_cmd(keyword_t kwd, int (*callback)(unit *, order *))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void process_long_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 = u->thisorder;
|
|
||||||
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) {
|
void process_update_long_order(void) {
|
||||||
region * r;
|
region * r;
|
||||||
for (r=regions; r; r=r->next) {
|
for (r=regions; r; r=r->next) {
|
||||||
|
@ -102,41 +120,41 @@ void process_settings(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_ally(void) {
|
void process_ally(void) {
|
||||||
process_cmd(K_ALLY, ally_cmd);
|
process_cmd(K_ALLY, ally_cmd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_prefix(void) {
|
void process_prefix(void) {
|
||||||
process_cmd(K_PREFIX, prefix_cmd);
|
process_cmd(K_PREFIX, prefix_cmd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_setstealth(void) {
|
void process_setstealth(void) {
|
||||||
process_cmd(K_SETSTEALTH, setstealth_cmd);
|
process_cmd(K_SETSTEALTH, setstealth_cmd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_status(void) {
|
void process_status(void) {
|
||||||
process_cmd(K_STATUS, status_cmd);
|
process_cmd(K_STATUS, status_cmd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_display(void) {
|
void process_display(void) {
|
||||||
process_cmd(K_DISPLAY, display_cmd);
|
process_cmd(K_DISPLAY, display_cmd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_group(void) {
|
void process_group(void) {
|
||||||
process_cmd(K_GROUP, group_cmd);
|
process_cmd(K_GROUP, group_cmd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_origin(void) {
|
void process_origin(void) {
|
||||||
process_cmd(K_URSPRUNG, origin_cmd);
|
process_cmd(K_URSPRUNG, origin_cmd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_quit(void) {
|
void process_quit(void) {
|
||||||
process_cmd(K_QUIT, quit_cmd);
|
process_cmd(K_QUIT, quit_cmd, 0);
|
||||||
quit();
|
quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_study(void) {
|
void process_study(void) {
|
||||||
process_long_cmd(K_TEACH, teach_cmd);
|
process_cmd(K_TEACH, teach_cmd, PROC_LONG_ORDER);
|
||||||
process_long_cmd(K_STUDY, learn_cmd);
|
process_cmd(K_STUDY, learn_cmd, PROC_LONG_ORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_movement(void) {
|
void process_movement(void) {
|
||||||
|
@ -144,9 +162,9 @@ void process_movement(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_use(void) {
|
void process_use(void) {
|
||||||
process_cmd(K_USE, use_cmd);
|
process_cmd(K_USE, use_cmd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_leave(void) {
|
void process_leave(void) {
|
||||||
process_cmd(K_LEAVE, leave_cmd);
|
process_cmd(K_LEAVE, leave_cmd, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ void process_quit(void);
|
||||||
void process_study(void);
|
void process_study(void);
|
||||||
void process_movement(void);
|
void process_movement(void);
|
||||||
void process_use(void);
|
void process_use(void);
|
||||||
|
void process_battle(void);
|
||||||
|
void process_siege(void);
|
||||||
void process_leave(void);
|
void process_leave(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -18,6 +18,8 @@ module eressea {
|
||||||
void process_study @ study(void); /* LEARN/TEACH */
|
void process_study @ study(void); /* LEARN/TEACH */
|
||||||
void process_movement @ movement(void); /* MOVE/FOLLOW/ROUTE */
|
void process_movement @ movement(void); /* MOVE/FOLLOW/ROUTE */
|
||||||
void process_use @ use(void); /* USE */
|
void process_use @ use(void); /* USE */
|
||||||
|
void process_battle @ battle(void); /* ATTACK */
|
||||||
|
void process_siege @ siege(void); /* SIEGE */
|
||||||
void process_leave @ leave(void); /* LEAVE */
|
void process_leave @ leave(void); /* LEAVE */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
static void enter_1(region * r)
|
||||||
{
|
{
|
||||||
do_misc(r, 0);
|
do_misc(r, 0);
|
||||||
|
|
|
@ -67,6 +67,7 @@ extern "C" {
|
||||||
extern int quit_cmd(struct unit *u, struct order *ord);
|
extern int quit_cmd(struct unit *u, struct order *ord);
|
||||||
extern int name_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 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);
|
extern int leave_cmd(struct unit *u, struct order *ord);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -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)
|
static void destroy_road(unit * u, int nmax, struct order *ord)
|
||||||
|
|
|
@ -64,7 +64,6 @@ extern "C" {
|
||||||
extern int destroy_cmd(struct unit *u, struct order *ord);
|
extern int destroy_cmd(struct unit *u, struct order *ord);
|
||||||
extern int leave_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 build_road(struct region *r, struct unit *u, int size, direction_t d);
|
||||||
void create_ship(struct region *r, struct unit *u,
|
void create_ship(struct region *r, struct unit *u,
|
||||||
const struct ship_type *newtype, int size, struct order *ord);
|
const struct ship_type *newtype, int size, struct order *ord);
|
||||||
|
|
Loading…
Reference in New Issue