#ifndef H_KRNL_BATTLE #define H_KRNL_BATTLE #include #include #ifdef __cplusplus extern "C" { #endif struct message; struct selist; union variant; /** more defines **/ #define FS_ENEMY 1 #define FS_HELP 2 /***** Verteidigungslinien. * Eressea hat 4 Verteidigungslinien. 1 ist vorn, 5. enthaelt Summen */ #define NUMROWS 5 #define SUM_ROW 0 #define FIGHT_ROW 1 #define BEHIND_ROW 2 #define AVOID_ROW 3 #define FLEE_ROW 4 #define FIRST_ROW FIGHT_ROW #define LAST_ROW FLEE_ROW #define MAXSIDES 192 /* if there are ever more than this, we're fucked. */ typedef struct bfaction { struct bfaction *next; struct side *sides; struct faction *faction; bool attacker; } bfaction; typedef struct tactics { struct selist *fighters; int value; } tactics; #define SIDE_STEALTH 1<<0 #define SIDE_HASGUARDS 1<<1 typedef struct side { struct side *nextF; /* next army of same faction */ struct battle *battle; struct bfaction *bf; /* battle info that goes with the faction */ struct faction *faction; /* cache optimization for bf->faction */ const struct group *group; struct tactics leader; /* this army's best tactician */ # define E_ENEMY 1 # define E_FRIEND 2 # define E_ATTACKING 4 unsigned char relations[MAXSIDES]; struct side *enemies[MAXSIDES]; struct fighter *fighters; unsigned int index; /* Eintrag der Fraktion in b->matrix/b->enemies */ int size[NUMROWS]; /* Anzahl Personen in Reihe X. 0 = Summe */ int nonblockers[NUMROWS]; /* Anzahl nichtblockierender Kaempfer, z.B. Schattenritter. */ int alive; /* Die Partei hat den Kampf verlassen */ int removed; /* stoned */ int flee; int dead; int casualties; /* those dead that were real people, not undead! */ int healed; unsigned int flags; const struct faction *stealthfaction; } side; typedef struct battle { struct selist *leaders; struct region *region; struct plane *plane; bfaction *factions; int nfactions; int nfighters; side sides[MAXSIDES]; int nsides; struct selist *meffects; int max_tactics; unsigned char turn; signed char keeploot; /* keep (50 + keeploot) percent of items as loot */ bool has_tactics_turn; bool reelarrow; int alive; struct { const struct side *as; const struct side *vs; int alive; int row; int result; } rowcache; struct { struct side *side; int status; int alive; int minrow, maxrow; int enemies[8]; } fast; } battle; typedef struct weapon { const struct weapon_type *type; int attackskill; int defenseskill; } weapon; /*** fighter::person::flags ***/ #define FL_TIRED 1 #define FL_DAZZLED 2 /* durch Untote oder Daemonen eingeschuechtert */ #define FL_PANICED 4 #define FL_COURAGE 8 /* Helden fliehen nie */ #define FL_SLEEPING 16 #define FL_STUNNED 32 /* eine Runde keinen Angriff */ #define FL_HIT 64 /* the person at attacked */ #define FL_HEALING_USED 128 /* has used a healing potion */ typedef struct troop { struct fighter *fighter; int index; } troop; typedef struct armor { struct armor *next; /* TODO: make this an array, not a list, like weapon */ const struct armor_type *atype; int count; } armor; /*** fighter::flags ***/ #define FIG_ATTACKER 1<<0 #define FIG_NOLOOT 1<<1 typedef struct fighter { struct fighter *next; struct side *side; struct unit *unit; /* Die Einheit, die hier kaempft */ struct building *building; /* Gebaeude, in dem die Einheit evtl. steht */ status_t status; /* Kampfstatus */ struct weapon *weapons; struct armor *armors; /* Anzahl Ruestungen jeden Typs */ int alive; /* Anzahl der noch nicht Toten in der Einheit */ int fighting; /* Anzahl der Kaempfer in der aktuellen Runde */ int removed; /* Anzahl Kaempfer, die nicht tot sind, aber aus dem Kampf raus sind (zB weil sie versteinert wurden). Diese werden auch in alive noch mitgezaehlt! */ int magic; /* Magietalent der Einheit */ int horses; /* Anzahl brauchbarer Pferde der Einheit */ int elvenhorses; /* Anzahl brauchbarer Elfenpferde der Einheit */ struct item *loot; int catmsg; /* Merkt sich, ob Katapultmessage schon generiert. */ struct person { int hp; /* Trefferpunkte der Personen */ int flags; int attack; /* weapon skill bonus for attacker */ int defense; /* weapon skill bonus for defender */ char damage; /* bonus damage for melee attacks (e.g. troll belt) */ unsigned char speed; unsigned char reload; unsigned char last_action; struct weapon *missile; /* missile weapon */ struct weapon *melee; /* melee weapon */ } *person; unsigned int flags; struct { int number; /* number of people who fled */ int hp; /* accumulated hp of fleeing people */ } run; int kills; int hits; } fighter; /* schilde */ enum { SHIELD_REDUCE, SHIELD_ARMOR, SHIELD_WIND, SHIELD_BLOCK, SHIELD_MAX }; typedef struct meffect { fighter *magician; /* Der Zauberer, der den Schild gezaubert hat */ int typ; /* Wirkungsweise des Schilds */ int effect; int duration; } meffect; extern const troop no_troop; /* BEGIN battle interface */ side * find_side(battle * b, const struct faction * f, const struct group * g, unsigned int flags, const struct faction * stealthfaction); side * get_side(battle * b, const struct unit * u); /* END battle interface */ void do_battles(void); /* for combat spells and special attacks */ enum { SELECT_ADVANCE = 0x1, SELECT_DISTANCE = 0x2, SELECT_FIND = 0x4 }; enum { ALLY_SELF, ALLY_ANY }; int get_unitrow(const fighter * af, const side * vs); troop select_enemy(struct fighter *af, int minrow, int maxrow, int select); troop select_ally(struct fighter *af, int minrow, int maxrow, int allytype); int count_enemies(struct battle *b, const struct fighter *af, int minrow, int maxrow, int select); int natural_armor(struct unit * u); const struct armor_type *select_armor(struct troop t, bool shield); struct weapon *select_weapon(const struct troop t, bool attacking, bool ismissile); int calculate_armor(troop dt, const struct weapon_type *dwtype, const struct weapon_type *awtype, const struct armor_type *armor, const struct armor_type *shield, bool magic); int apply_resistance(int damage, struct troop dt, const struct weapon_type *dwtype, const struct armor_type *armor, const struct armor_type *shield, bool magic); bool terminate(troop dt, troop at, int type, const char *damage, bool missile); void message_all(battle * b, struct message *m); int hits(troop at, troop dt, weapon * awp); void damage_building(struct battle *b, struct building *bldg, int damage_abs); typedef bool(*select_fun)(const struct side *vs, const struct fighter *fig, void *cbdata); struct selist *select_fighters(struct battle *b, const struct side *vs, int mask, select_fun cb, void *cbdata); struct selist *fighters(struct battle *b, const struct side *vs, int minrow, int maxrow, int mask); int count_allies(const struct side *as, int minrow, int maxrow, int select, int allytype); bool helping(const struct side *as, const struct side *ds); void rmfighter(fighter * df, int i); struct fighter *select_corpse(struct battle *b, struct fighter *af); int statusrow(int status); void drain_exp(struct unit *u, int d); void kill_troop(troop dt); void remove_troop(troop dt); /* not the same as the badly named rmtroop */ bool is_attacker(const fighter * fig); struct battle *make_battle(struct region * r); void free_battle(struct battle * b); struct fighter *make_fighter(struct battle *b, struct unit *u, struct side * s, bool attack); int join_battle(struct battle * b, struct unit * u, bool attack, struct fighter ** cp); struct side *make_side(struct battle * b, const struct faction * f, const struct group * g, unsigned int flags, const struct faction * stealthfaction); int skilldiff(troop at, troop dt, int dist); void force_leave(struct region *r, struct battle *b); bool seematrix(const struct faction * f, const struct side * s); const char *sidename(const struct side * s); void battle_message_faction(struct battle * b, struct faction * f, struct message *m); double tactics_chance(const struct unit *u, int skilldiff); #ifdef __cplusplus } #endif #endif