From 521519805d89e1179578b071172397d43567de29 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 11 Oct 2015 21:19:38 +0200 Subject: [PATCH] refactor piracy code into a module, separate from move. --- src/CMakeLists.txt | 1 + src/move.c | 171 ++--------------------------------------- src/move.h | 2 + src/piracy.c | 186 +++++++++++++++++++++++++++++++++++++++++++++ src/piracy.h | 21 +++++ 5 files changed, 218 insertions(+), 163 deletions(-) create mode 100644 src/piracy.c create mode 100644 src/piracy.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 10d4b2597..3309a8a28 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -79,6 +79,7 @@ ENDIF() set (ERESSEA_SRC calendar.c move.c + piracy.c spells.c battle.c alchemy.c diff --git a/src/move.c b/src/move.c index f708bfaa7..6d296eb81 100644 --- a/src/move.c +++ b/src/move.c @@ -27,6 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "vortex.h" #include "monster.h" #include "lighthouse.h" +#include "piracy.h" #include #include @@ -55,7 +56,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include #include #include #include @@ -68,7 +68,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* attributes includes */ #include #include -#include #include #include @@ -1770,7 +1769,7 @@ buildingtype_exists(const region * r, const building_type * bt, bool working) /* Prüft, ob Ablegen von einer Küste in eine der erlaubten Richtungen erfolgt. */ -static bool check_takeoff(ship * sh, region * from, region * to) +bool can_takeoff(const ship * sh, const region * from, const region * to) { if (!fval(from->terrain, SEA_REGION) && sh->coast != NODIRECTION) { direction_t coast = sh->coast; @@ -1918,7 +1917,7 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep) } } else { - if (!check_takeoff(sh, current_point, next_point)) { + if (!can_takeoff(sh, current_point, next_point)) { /* Schiff kann nicht ablegen */ cmistake(u, ord, 182, MSG_MOVE); break; @@ -2271,7 +2270,7 @@ static void travel(unit * u, region_list ** routep) } -static void move(unit * u, bool move_on_land) +void move_cmd(unit * u, bool move_on_land) { region_list *route = NULL; @@ -2290,160 +2289,6 @@ static void move(unit * u, bool move_on_land) free_regionlist(route); } -typedef struct piracy_data { - const struct faction *pirate; - const struct faction *target; - direction_t dir; -} piracy_data; - -static void piracy_init(struct attrib *a) -{ - a->data.v = calloc(1, sizeof(piracy_data)); -} - -static void piracy_done(struct attrib *a) -{ - free(a->data.v); -} - -static attrib_type at_piracy_direction = { - "piracy_direction", - piracy_init, - piracy_done, - DEFAULT_AGE, - NO_WRITE, - NO_READ -}; - -static attrib *mk_piracy(const faction * pirate, const faction * target, - direction_t target_dir) -{ - attrib *a = a_new(&at_piracy_direction); - piracy_data *data = a->data.v; - data->pirate = pirate; - data->target = target; - data->dir = target_dir; - return a; -} - -static void piracy_cmd(unit * u, struct order *ord) -{ - region *r = u->region; - ship *sh = u->ship, *sh2; - direction_t dir, target_dir = NODIRECTION; - struct { - const faction *target; - int value; - } aff[MAXDIRECTIONS]; - int saff = 0; - int *il = NULL; - const char *s; - attrib *a; - - if (!sh) { - cmistake(u, ord, 144, MSG_MOVE); - return; - } - - if (!u->ship || u != ship_owner(u->ship)) { - cmistake(u, ord, 146, MSG_MOVE); - return; - } - - /* Feststellen, ob schon ein anderer alliierter Pirat ein - * Ziel gefunden hat. */ - - init_order(ord); - s = getstrtoken(); - if (s != NULL && *s) { - il = intlist_init(); - while (s && *s) { - il = intlist_add(il, atoi36(s)); - s = getstrtoken(); - } - } - - for (a = a_find(r->attribs, &at_piracy_direction); - a && a->type == &at_piracy_direction; a = a->next) { - piracy_data *data = a->data.v; - const faction *p = data->pirate; - const faction *t = data->target; - - if (alliedunit(u, p, HELP_FIGHT)) { - if (il == 0 || (t && intlist_find(il, t->no))) { - target_dir = data->dir; - break; - } - } - } - - /* Wenn nicht, sehen wir, ob wir ein Ziel finden. */ - - if (target_dir == NODIRECTION) { - /* Einheit ist also Kapitän. Jetzt gucken, in wievielen - * Nachbarregionen potentielle Opfer sind. */ - - for (dir = 0; dir < MAXDIRECTIONS; dir++) { - region *rc = rconnect(r, dir); - aff[dir].value = 0; - aff[dir].target = 0; - if (rc && fval(rc->terrain, SWIM_INTO) && check_takeoff(sh, r, rc)) { - - for (sh2 = rc->ships; sh2; sh2 = sh2->next) { - unit *cap = ship_owner(sh2); - if (cap) { - faction *f = visible_faction(cap->faction, cap); - if (alliedunit(u, f, HELP_FIGHT)) - continue; - if (il == 0 || intlist_find(il, cap->faction->no)) { - ++aff[dir].value; - if (rng_int() % aff[dir].value == 0) { - aff[dir].target = f; - } - } - } - } - - /* Und aufaddieren. */ - saff += aff[dir].value; - } - } - - if (saff != 0) { - saff = rng_int() % saff; - for (dir = 0; dir != MAXDIRECTIONS; ++dir) { - if (saff < aff[dir].value) - break; - saff -= aff[dir].value; - } - target_dir = dir; - a = - a_add(&r->attribs, mk_piracy(u->faction, aff[dir].target, target_dir)); - } - } - - free(il); - - /* Wenn kein Ziel gefunden, entsprechende Meldung generieren */ - if (target_dir == NODIRECTION) { - ADDMSG(&u->faction->msgs, msg_message("piratenovictim", - "ship region", sh, r)); - return; - } - - /* Meldung generieren */ - ADDMSG(&u->faction->msgs, msg_message("piratesawvictim", - "ship region dir", sh, r, target_dir)); - - /* Befehl konstruieren */ - set_order(&u->thisorder, create_order(K_MOVE, u->faction->locale, "%s", - LOC(u->faction->locale, directions[target_dir]))); - - /* Bewegung ausführen */ - init_order(u->thisorder); - move(u, true); -} - static void age_traveldir(region * r) { attrib *a = a_find(r->attribs, &at_traveldir); @@ -2549,7 +2394,7 @@ static int follow_ship(unit * u, order * ord) init_tokens_str(command); getstrtoken(); /* NACH ausführen */ - move(u, false); + move_cmd(u, false); return 1; /* true -> Einheitenliste von vorne durchgehen */ } @@ -2656,7 +2501,7 @@ static void move_pirates(void) /* else *up is already the next unit */ } - a_removeall(&r->attribs, &at_piracy_direction); + age_piracy(r); age_traveldir(r); } } @@ -2716,13 +2561,13 @@ void movement(void) if (ships) { if (u->ship && ship_owner(u->ship) == u) { init_order(u->thisorder); - move(u, false); + move_cmd(u, false); } } else { if (!u->ship || ship_owner(u->ship) != u) { init_order(u->thisorder); - move(u, false); + move_cmd(u, false); } } } diff --git a/src/move.h b/src/move.h index 013885564..c0b92d071 100644 --- a/src/move.h +++ b/src/move.h @@ -74,6 +74,8 @@ extern "C" { const struct building_type *bt); bool move_blocked(const struct unit *u, const struct region *src, const struct region *dest); + bool can_takeoff(const struct ship * sh, const struct region * from, const struct region * to); + void move_cmd(struct unit * u, bool move_on_land); #define SA_HARBOUR 2 #define SA_COAST 1 diff --git a/src/piracy.c b/src/piracy.c new file mode 100644 index 000000000..0966317d5 --- /dev/null +++ b/src/piracy.c @@ -0,0 +1,186 @@ +#include +#include +#include "piracy.h" + +#include "direction.h" +#include "keyword.h" +#include "move.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +typedef struct piracy_data { + const struct faction *pirate; + const struct faction *target; + direction_t dir; +} piracy_data; + +static void piracy_init(struct attrib *a) +{ + a->data.v = calloc(1, sizeof(piracy_data)); +} + +static void piracy_done(struct attrib *a) +{ + free(a->data.v); +} + +static attrib_type at_piracy_direction = { + "piracy_direction", + piracy_init, + piracy_done, + DEFAULT_AGE, + NO_WRITE, + NO_READ +}; + +static attrib *mk_piracy(const faction * pirate, const faction * target, + direction_t target_dir) +{ + attrib *a = a_new(&at_piracy_direction); + piracy_data *data = a->data.v; + data->pirate = pirate; + data->target = target; + data->dir = target_dir; + return a; +} + +void piracy_cmd(unit * u, struct order *ord) +{ + region *r = u->region; + ship *sh = u->ship, *sh2; + direction_t dir, target_dir = NODIRECTION; + struct { + const faction *target; + int value; + } aff[MAXDIRECTIONS]; + int saff = 0; + int *il = NULL; + const char *s; + attrib *a; + + if (!sh) { + cmistake(u, ord, 144, MSG_MOVE); + return; + } + + if (!u->ship || u != ship_owner(u->ship)) { + cmistake(u, ord, 146, MSG_MOVE); + return; + } + + /* Feststellen, ob schon ein anderer alliierter Pirat ein + * Ziel gefunden hat. */ + + init_order(ord); + s = getstrtoken(); + if (s != NULL && *s) { + il = intlist_init(); + while (s && *s) { + il = intlist_add(il, atoi36(s)); + s = getstrtoken(); + } + } + + for (a = a_find(r->attribs, &at_piracy_direction); + a && a->type == &at_piracy_direction; a = a->next) { + piracy_data *data = a->data.v; + const faction *p = data->pirate; + const faction *t = data->target; + + if (alliedunit(u, p, HELP_FIGHT)) { + if (il == 0 || (t && intlist_find(il, t->no))) { + target_dir = data->dir; + break; + } + } + } + + /* Wenn nicht, sehen wir, ob wir ein Ziel finden. */ + + if (target_dir == NODIRECTION) { + /* Einheit ist also Kapitän. Jetzt gucken, in wievielen + * Nachbarregionen potentielle Opfer sind. */ + + for (dir = 0; dir < MAXDIRECTIONS; dir++) { + region *rc = rconnect(r, dir); + aff[dir].value = 0; + aff[dir].target = 0; + if (rc && fval(rc->terrain, SWIM_INTO) && can_takeoff(sh, r, rc)) { + + for (sh2 = rc->ships; sh2; sh2 = sh2->next) { + unit *cap = ship_owner(sh2); + if (cap) { + faction *f = visible_faction(cap->faction, cap); + if (alliedunit(u, f, HELP_FIGHT)) + continue; + if (il == 0 || intlist_find(il, cap->faction->no)) { + ++aff[dir].value; + if (rng_int() % aff[dir].value == 0) { + aff[dir].target = f; + } + } + } + } + + /* Und aufaddieren. */ + saff += aff[dir].value; + } + } + + if (saff != 0) { + saff = rng_int() % saff; + for (dir = 0; dir != MAXDIRECTIONS; ++dir) { + if (saff < aff[dir].value) + break; + saff -= aff[dir].value; + } + target_dir = dir; + a = + a_add(&r->attribs, mk_piracy(u->faction, aff[dir].target, target_dir)); + } + } + + free(il); + + /* Wenn kein Ziel gefunden, entsprechende Meldung generieren */ + if (target_dir == NODIRECTION) { + ADDMSG(&u->faction->msgs, msg_message("piratenovictim", + "ship region", sh, r)); + return; + } + + /* Meldung generieren */ + ADDMSG(&u->faction->msgs, msg_message("piratesawvictim", + "ship region dir", sh, r, target_dir)); + + /* Befehl konstruieren */ + set_order(&u->thisorder, create_order(K_MOVE, u->faction->locale, "%s", + LOC(u->faction->locale, directions[target_dir]))); + + /* Bewegung ausführen */ + init_order(u->thisorder); + move_cmd(u, true); +} + +void age_piracy(region *r) { + a_removeall(&r->attribs, &at_piracy_direction); +} diff --git a/src/piracy.h b/src/piracy.h new file mode 100644 index 000000000..b74fbd509 --- /dev/null +++ b/src/piracy.h @@ -0,0 +1,21 @@ +#pragma once + +#ifndef PIRACY_H +#define PIRACY_H + +#ifdef __cplusplus +extern "C" { +#endif + + struct unit; + struct order; + struct region; + + void piracy_cmd(struct unit * u, struct order *ord); + void age_piracy(struct region *r); + +#ifdef __cplusplus +} +#endif + +#endif