Merge branch 'e4combat'

This commit is contained in:
Enno Rehling 2012-06-27 20:39:59 -07:00
commit d98742e4b5
14 changed files with 125 additions and 66 deletions

View File

@ -28,6 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/magic.h> #include <kernel/magic.h>
#include <kernel/message.h> #include <kernel/message.h>
#include <kernel/move.h> #include <kernel/move.h>
#include <kernel/order.h>
#include <kernel/race.h> #include <kernel/race.h>
#include <kernel/region.h> #include <kernel/region.h>
#include <kernel/ship.h> #include <kernel/ship.h>

View File

@ -40,6 +40,8 @@ extern "C" {
#define ALF_NON_ALLIED (1<<0) /* this alliance is just a default for a non-allied faction */ #define ALF_NON_ALLIED (1<<0) /* this alliance is just a default for a non-allied faction */
#define ALLY_ENEMY (1<<0)
typedef struct alliance { typedef struct alliance {
struct alliance *next; struct alliance *next;
struct faction *_leader; struct faction *_leader;
@ -47,6 +49,7 @@ extern "C" {
unsigned int flags; unsigned int flags;
int id; int id;
char *name; char *name;
struct ally *allies;
} alliance; } alliance;
extern alliance *alliances; extern alliance *alliances;

View File

@ -206,7 +206,7 @@ static void message_faction(battle * b, faction * f, struct message *m)
region *r = b->region; region *r = b->region;
if (f->battles == NULL || f->battles->r != r) { if (f->battles == NULL || f->battles->r != r) {
struct bmsg *bm = calloc(1, sizeof(struct bmsg)); struct bmsg *bm = (struct bmsg *)calloc(1, sizeof(struct bmsg));
bm->next = f->battles; bm->next = f->battles;
f->battles = bm; f->battles = bm;
bm->r = r; bm->r = r;
@ -3137,6 +3137,45 @@ static int weapon_weight(const weapon * w, bool missile)
return 0; return 0;
} }
side * get_side(battle * b, const struct unit * u)
{
side * s;
for (s = b->sides; s != b->sides + b->nsides; ++s) {
if (s->faction==u->faction) {
fighter * fig;
for (fig=s->fighters;fig;fig=fig->next) {
if (fig->unit==u) {
return s;
}
}
}
}
return 0;
}
side * find_side(battle * b, const faction * f, const group * g, int flags, const faction * stealthfaction)
{
side * s;
static int rule_anon_battle = -1;
if (rule_anon_battle < 0) {
rule_anon_battle = get_param_int(global.parameters, "rules.stealth.anon_battle", 1);
}
for (s = b->sides; s != b->sides + b->nsides; ++s) {
if (s->faction == f && s->group == g) {
int s1flags = flags | SIDE_HASGUARDS;
int s2flags = s->flags | SIDE_HASGUARDS;
if (rule_anon_battle && s->stealthfaction != stealthfaction) {
continue;
}
if (s1flags == s2flags) {
return s;
}
}
}
return 0;
}
fighter *make_fighter(battle * b, unit * u, side * s1, bool attack) fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
{ {
#define WMAX 20 #define WMAX 20
@ -3147,9 +3186,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
region *r = b->region; region *r = b->region;
item *itm; item *itm;
fighter *fig = NULL; fighter *fig = NULL;
int i, tactics = eff_skill(u, SK_TACTICS, r); int h, i, tactics = eff_skill(u, SK_TACTICS, r);
side *s2;
int h;
int berserk; int berserk;
int strongmen; int strongmen;
int speeded = 0, speed = 1; int speeded = 0, speed = 1;
@ -3159,14 +3196,8 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
const attrib *a = a_find(u->attribs, &at_otherfaction); const attrib *a = a_find(u->attribs, &at_otherfaction);
const faction *stealthfaction = a ? get_otherfaction(a) : NULL; const faction *stealthfaction = a ? get_otherfaction(a) : NULL;
unsigned int flags = 0; unsigned int flags = 0;
static int rule_anon_battle = -1;
assert(u->number); assert(u->number);
if (rule_anon_battle < 0) {
rule_anon_battle =
get_param_int(global.parameters, "rules.stealth.anon_battle", 1);
}
if (fval(u, UFL_ANON_FACTION) != 0) if (fval(u, UFL_ANON_FACTION) != 0)
flags |= SIDE_STEALTH; flags |= SIDE_STEALTH;
if (!(AllianceAuto() & HELP_FIGHT) && fval(u, UFL_GROUP)) { if (!(AllianceAuto() & HELP_FIGHT) && fval(u, UFL_GROUP)) {
@ -3180,20 +3211,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
return NULL; return NULL;
} }
if (s1 == NULL) { if (s1 == NULL) {
for (s2 = b->sides; s2 != b->sides + b->nsides; ++s2) { s1 = find_side(b, u->faction, g, flags, stealthfaction);
if (s2->faction == u->faction && s2->group == g) {
int s1flags = flags | SIDE_HASGUARDS;
int s2flags = s2->flags | SIDE_HASGUARDS;
if (rule_anon_battle && s2->stealthfaction != stealthfaction) {
continue;
}
if (s1flags == s2flags) {
s1 = s2;
break;
}
}
}
/* aliances are moved out of make_fighter and will be handled later */ /* aliances are moved out of make_fighter and will be handled later */
if (!s1) { if (!s1) {
s1 = make_side(b, u->faction, g, flags, stealthfaction); s1 = make_side(b, u->faction, g, flags, stealthfaction);
@ -3203,7 +3221,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
/* Zu diesem Zeitpunkt ist attacked noch 0, da die Einheit für noch /* Zu diesem Zeitpunkt ist attacked noch 0, da die Einheit für noch
* keinen Kampf ausgewählt wurde (sonst würde ein fighter existieren) */ * keinen Kampf ausgewählt wurde (sonst würde ein fighter existieren) */
} }
fig = calloc(1, sizeof(struct fighter)); fig = (struct fighter*)calloc(1, sizeof(struct fighter));
fig->next = s1->fighters; fig->next = s1->fighters;
s1->fighters = fig; s1->fighters = fig;
@ -3228,7 +3246,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
fig->catmsg = -1; fig->catmsg = -1;
/* Freigeben nicht vergessen! */ /* Freigeben nicht vergessen! */
fig->person = calloc(fig->alive, sizeof(struct person)); fig->person = (struct person*)calloc(fig->alive, sizeof(struct person));
h = u->hp / u->number; h = u->hp / u->number;
assert(h); assert(h);
@ -3459,6 +3477,23 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
return fig; return fig;
} }
fighter * get_fighter(battle * b, const struct unit * u)
{
side * s;
for (s = b->sides; s != b->sides + b->nsides; ++s) {
fighter *fig;
if (s->faction == u->faction) {
for (fig = s->fighters; fig; fig = fig->next) {
if (fig->unit == u) {
return fig;
}
}
}
}
return 0;
}
static int join_battle(battle * b, unit * u, bool attack, fighter ** cp) static int join_battle(battle * b, unit * u, bool attack, fighter ** cp)
{ {
side *s; side *s;
@ -3542,7 +3577,7 @@ battle *make_battle(region * r)
else { else {
const unsigned char utf8_bom[4] = { 0xef, 0xbb, 0xbf, 0 }; const unsigned char utf8_bom[4] = { 0xef, 0xbb, 0xbf, 0 };
fwrite(utf8_bom, 1, 3, bdebug); fwrite(utf8_bom, 1, 3, bdebug);
fprintf(bdebug, "In %s findet ein Kampf stattactics:\n", rname(r, fprintf(bdebug, "In %s findet ein Kampf statt:\n", rname(r,
default_locale)); default_locale));
} }
obs_count++; obs_count++;
@ -3600,7 +3635,6 @@ static void free_fighter(fighter * fig)
static void free_battle(battle * b) static void free_battle(battle * b)
{ {
side *s;
int max_fac_no = 0; int max_fac_no = 0;
if (bdebug) { if (bdebug) {
@ -3615,19 +3649,11 @@ static void free_battle(battle * b)
free(bf); free(bf);
} }
for (s = b->sides; s != b->sides + b->nsides; ++s) {
fighter *fnext = s->fighters;
while (fnext) {
fighter *fig = fnext;
fnext = fig->next;
free_fighter(fig);
free(fig);
}
free_side(s);
}
ql_free(b->leaders); ql_free(b->leaders);
ql_foreach(b->meffects, free); ql_foreach(b->meffects, free);
ql_free(b->meffects); ql_free(b->meffects);
battle_free(b);
} }
static int *get_alive(side * s) static int *get_alive(side * s)
@ -3876,7 +3902,7 @@ static void flee(const troop dt)
kill_troop(dt); kill_troop(dt);
} }
static bool init_battle(region * r, battle ** bp) static bool start_battle(region * r, battle ** bp)
{ {
battle *b = NULL; battle *b = NULL;
unit *u; unit *u;
@ -4091,7 +4117,7 @@ static void battle_stats(FILE * F, battle * b)
} }
stat = *slist; stat = *slist;
if (stat == NULL || stat->wtype != wtype || stat->level != level) { if (stat == NULL || stat->wtype != wtype || stat->level != level) {
stat = calloc(1, sizeof(stat_info)); stat = (stat_info*)calloc(1, sizeof(stat_info));
stat->wtype = wtype; stat->wtype = wtype;
stat->level = level; stat->level = level;
stat->next = *slist; stat->next = *slist;
@ -4251,7 +4277,7 @@ void do_battle(region * r)
msg_separator = msg_message("battle::section", ""); msg_separator = msg_message("battle::section", "");
} }
fighting = init_battle(r, &b); fighting = start_battle(r, &b);
if (b == NULL) if (b == NULL)
return; return;
@ -4318,3 +4344,26 @@ void do_battle(region * r)
free(b); free(b);
} }
} }
void battle_init(battle * b) {
assert(b);
memset(b, 0, sizeof(battle));
}
void battle_free(battle * b) {
side *s;
assert(b);
for (s = b->sides; s != b->sides + b->nsides; ++s) {
fighter *fnext = s->fighters;
while (fnext) {
fighter *fig = fnext;
fnext = fig->next;
free_fighter(fig);
free(fig);
}
free_side(s);
}
}

View File

@ -205,6 +205,14 @@ extern "C" {
extern const troop no_troop; extern const troop no_troop;
/* BEGIN battle interface */
void battle_init(battle * b);
void battle_free(battle * b);
side * find_side(battle * b, const struct faction * f, const struct group * g, int flags, const struct faction * stealthfaction);
side * get_side(battle * b, const struct unit * u);
fighter * get_fighter(battle * b, const struct unit * u);
/* END battle interface */
extern void do_battle(struct region *r); extern void do_battle(struct region *r);
/* for combat spells and special attacks */ /* for combat spells and special attacks */

View File

@ -8,8 +8,9 @@
#include "region.h" #include "region.h"
#include "skill.h" #include "skill.h"
#include "unit.h" #include "unit.h"
#include "tests.h"
#include <CuTest.h> #include <CuTest.h>
#include "tests.h"
static void test_make_fighter(CuTest * tc) static void test_make_fighter(CuTest * tc)
{ {

View File

@ -1249,12 +1249,6 @@ int count_maxmigrants(const faction * f)
return migrants; return migrants;
} }
void init_tokens(const struct order *ord)
{
char *cmd = getcommand(ord);
init_tokens_str(cmd, cmd);
}
void void
parse(keyword_t kword, int (*dofun) (unit *, struct order *), bool thisorder) parse(keyword_t kword, int (*dofun) (unit *, struct order *), bool thisorder)
{ {
@ -1953,6 +1947,11 @@ direction_t finddirection(const char *s, const struct locale *lang)
return NODIRECTION; return NODIRECTION;
} }
direction_t getdirection(const struct locale * lang)
{
return finddirection(getstrtoken(), lang);
}
static void init_translations(const struct locale *lang, int ut, const char * (*string_cb)(int i), int maxstrings) static void init_translations(const struct locale *lang, int ut, const char * (*string_cb)(int i), int maxstrings)
{ {
char buffer[256]; char buffer[256];

View File

@ -119,6 +119,8 @@ extern "C" {
int status; int status;
} ally; } ally;
ally * ally_find(const ally *al, const struct faction *f);
void remove_empty_units_in_region(struct region *r); void remove_empty_units_in_region(struct region *r);
void remove_empty_units(void); void remove_empty_units(void);
void remove_empty_factions(void); void remove_empty_factions(void);
@ -165,9 +167,10 @@ extern "C" {
unsigned int getuint(void); unsigned int getuint(void);
int getint(void); int getint(void);
direction_t getdirection(const struct locale *);
extern const char *igetstrtoken(const char *s); extern const char *igetstrtoken(const char *s);
extern void init_tokens(const struct order *ord); /* initialize token parsing */
extern skill_t findskill(const char *s, const struct locale *lang); extern skill_t findskill(const char *s, const struct locale *lang);
extern keyword_t findkeyword(const char *s, const struct locale *lang); extern keyword_t findkeyword(const char *s, const struct locale *lang);

View File

@ -125,7 +125,7 @@ extern "C" {
extern void set_alliance(struct faction *a, struct faction *b, int status); extern void set_alliance(struct faction *a, struct faction *b, int status);
extern int get_alliance(const struct faction *a, const struct faction *b); extern int get_alliance(const struct faction *a, const struct faction *b);
extern struct alliance *f_get_alliance(const struct faction *a); extern struct alliance *f_get_alliance(const struct faction *f);
extern void write_faction_reference(const struct faction *f, extern void write_faction_reference(const struct faction *f,
struct storage *store); struct storage *store);

View File

@ -176,13 +176,6 @@ attrib_type at_speedup = {
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
direction_t getdirection(const struct locale * lang)
{
return finddirection(getstrtoken(), lang);
}
/* ------------------------------------------------------------- */
static attrib_type at_driveweight = { static attrib_type at_driveweight = {
"driveweight", NULL, NULL, NULL, NULL, NULL "driveweight", NULL, NULL, NULL, NULL, NULL
}; };

View File

@ -47,7 +47,6 @@ extern "C" {
** pferde, macht nur noch 100, aber samt eigenem gewicht (40) macht also 140. */ ** pferde, macht nur noch 100, aber samt eigenem gewicht (40) macht also 140. */
int personcapacity(const struct unit *u); int personcapacity(const struct unit *u);
direction_t getdirection(const struct locale *);
void movement(void); void movement(void);
void run_to(struct unit *u, struct region *to); void run_to(struct unit *u, struct region *to);
struct unit *is_guarded(struct region *r, struct unit *u, unsigned int mask); struct unit *is_guarded(struct region *r, struct unit *u, unsigned int mask);

View File

@ -606,3 +606,9 @@ void push_order(order ** ordp, order * ord)
ordp = &(*ordp)->next; ordp = &(*ordp)->next;
*ordp = ord; *ordp = ord;
} }
void init_tokens(const struct order *ord)
{
char *cmd = getcommand(ord);
init_tokens_str(cmd, cmd);
}

View File

@ -57,6 +57,7 @@ extern "C" {
extern bool is_long(const order * ord); extern bool is_long(const order * ord);
extern char *write_order(const order * ord, char *buffer, size_t size); extern char *write_order(const order * ord, char *buffer, size_t size);
extern void init_tokens(const struct order *ord); /* initialize token parsing */
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -628,13 +628,13 @@ int distance(const region * r1, const region * r2)
static direction_t static direction_t
koor_reldirection(int ax, int ay, int bx, int by, const struct plane *pl) koor_reldirection(int ax, int ay, int bx, int by, const struct plane *pl)
{ {
direction_t dir; int dir;
for (dir = 0; dir != MAXDIRECTIONS; ++dir) { for (dir = 0; dir != MAXDIRECTIONS; ++dir) {
int x = ax + delta_x[dir]; int x = ax + delta_x[dir];
int y = ay + delta_y[dir]; int y = ay + delta_y[dir];
pnormalize(&x, &y, pl); pnormalize(&x, &y, pl);
if (bx == x && by == y) if (bx == x && by == y)
return dir; return (direction_t)dir;
} }
return NODIRECTION; return NODIRECTION;
} }
@ -1593,9 +1593,9 @@ void region_set_morale(region * r, int morale, int turn)
void get_neighbours(const region * r, region ** list) void get_neighbours(const region * r, region ** list)
{ {
direction_t dir; int dir;
for (dir = 0; dir != MAXDIRECTIONS; ++dir) { for (dir = 0; dir != MAXDIRECTIONS; ++dir) {
list[dir] = rconnect(r, dir); list[dir] = rconnect(r, (direction_t)dir);
} }
} }

View File

@ -394,10 +394,6 @@ typedef enum {
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
/* Prototypen */ /* Prototypen */
#define ALLIED_TAX 1
#define ALLIED_NOBLOCK 2
#define ALLIED_HELP 4
/* alle vierstelligen zahlen: */ /* alle vierstelligen zahlen: */
#define MAX_UNIT_NR (36*36*36*36-1) #define MAX_UNIT_NR (36*36*36*36-1)
#define MAX_CONTAINER_NR (36*36*36*36-1) #define MAX_CONTAINER_NR (36*36*36*36-1)