forked from github/server
refactor piracy code into a module, separate from move.
This commit is contained in:
parent
4984d8e8c5
commit
521519805d
5 changed files with 218 additions and 163 deletions
|
@ -79,6 +79,7 @@ ENDIF()
|
||||||
set (ERESSEA_SRC
|
set (ERESSEA_SRC
|
||||||
calendar.c
|
calendar.c
|
||||||
move.c
|
move.c
|
||||||
|
piracy.c
|
||||||
spells.c
|
spells.c
|
||||||
battle.c
|
battle.c
|
||||||
alchemy.c
|
alchemy.c
|
||||||
|
|
171
src/move.c
171
src/move.c
|
@ -27,6 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include "vortex.h"
|
#include "vortex.h"
|
||||||
#include "monster.h"
|
#include "monster.h"
|
||||||
#include "lighthouse.h"
|
#include "lighthouse.h"
|
||||||
|
#include "piracy.h"
|
||||||
|
|
||||||
#include <kernel/build.h>
|
#include <kernel/build.h>
|
||||||
#include <kernel/building.h>
|
#include <kernel/building.h>
|
||||||
|
@ -55,7 +56,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <util/attrib.h>
|
#include <util/attrib.h>
|
||||||
#include <util/base36.h>
|
#include <util/base36.h>
|
||||||
#include <util/bsdstring.h>
|
#include <util/bsdstring.h>
|
||||||
#include <util/goodies.h>
|
|
||||||
#include <util/language.h>
|
#include <util/language.h>
|
||||||
#include <util/lists.h>
|
#include <util/lists.h>
|
||||||
#include <util/log.h>
|
#include <util/log.h>
|
||||||
|
@ -68,7 +68,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
/* attributes includes */
|
/* attributes includes */
|
||||||
#include <attributes/follow.h>
|
#include <attributes/follow.h>
|
||||||
#include <attributes/movement.h>
|
#include <attributes/movement.h>
|
||||||
#include <attributes/otherfaction.h>
|
|
||||||
#include <attributes/stealth.h>
|
#include <attributes/stealth.h>
|
||||||
#include <attributes/targetregion.h>
|
#include <attributes/targetregion.h>
|
||||||
|
|
||||||
|
@ -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. */
|
/* 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) {
|
if (!fval(from->terrain, SEA_REGION) && sh->coast != NODIRECTION) {
|
||||||
direction_t coast = sh->coast;
|
direction_t coast = sh->coast;
|
||||||
|
@ -1918,7 +1917,7 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!check_takeoff(sh, current_point, next_point)) {
|
if (!can_takeoff(sh, current_point, next_point)) {
|
||||||
/* Schiff kann nicht ablegen */
|
/* Schiff kann nicht ablegen */
|
||||||
cmistake(u, ord, 182, MSG_MOVE);
|
cmistake(u, ord, 182, MSG_MOVE);
|
||||||
break;
|
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;
|
region_list *route = NULL;
|
||||||
|
|
||||||
|
@ -2290,160 +2289,6 @@ static void move(unit * u, bool move_on_land)
|
||||||
free_regionlist(route);
|
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)
|
static void age_traveldir(region * r)
|
||||||
{
|
{
|
||||||
attrib *a = a_find(r->attribs, &at_traveldir);
|
attrib *a = a_find(r->attribs, &at_traveldir);
|
||||||
|
@ -2549,7 +2394,7 @@ static int follow_ship(unit * u, order * ord)
|
||||||
init_tokens_str(command);
|
init_tokens_str(command);
|
||||||
getstrtoken();
|
getstrtoken();
|
||||||
/* NACH ausführen */
|
/* NACH ausführen */
|
||||||
move(u, false);
|
move_cmd(u, false);
|
||||||
return 1; /* true -> Einheitenliste von vorne durchgehen */
|
return 1; /* true -> Einheitenliste von vorne durchgehen */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2656,7 +2501,7 @@ static void move_pirates(void)
|
||||||
/* else *up is already the next unit */
|
/* else *up is already the next unit */
|
||||||
}
|
}
|
||||||
|
|
||||||
a_removeall(&r->attribs, &at_piracy_direction);
|
age_piracy(r);
|
||||||
age_traveldir(r);
|
age_traveldir(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2716,13 +2561,13 @@ void movement(void)
|
||||||
if (ships) {
|
if (ships) {
|
||||||
if (u->ship && ship_owner(u->ship) == u) {
|
if (u->ship && ship_owner(u->ship) == u) {
|
||||||
init_order(u->thisorder);
|
init_order(u->thisorder);
|
||||||
move(u, false);
|
move_cmd(u, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!u->ship || ship_owner(u->ship) != u) {
|
if (!u->ship || ship_owner(u->ship) != u) {
|
||||||
init_order(u->thisorder);
|
init_order(u->thisorder);
|
||||||
move(u, false);
|
move_cmd(u, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,8 @@ extern "C" {
|
||||||
const struct building_type *bt);
|
const struct building_type *bt);
|
||||||
bool move_blocked(const struct unit *u, const struct region *src,
|
bool move_blocked(const struct unit *u, const struct region *src,
|
||||||
const struct region *dest);
|
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_HARBOUR 2
|
||||||
#define SA_COAST 1
|
#define SA_COAST 1
|
||||||
|
|
186
src/piracy.c
Normal file
186
src/piracy.c
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
#include <platform.h>
|
||||||
|
#include <kernel/config.h>
|
||||||
|
#include "piracy.h"
|
||||||
|
|
||||||
|
#include "direction.h"
|
||||||
|
#include "keyword.h"
|
||||||
|
#include "move.h"
|
||||||
|
|
||||||
|
#include <kernel/faction.h>
|
||||||
|
#include <kernel/messages.h>
|
||||||
|
#include <kernel/order.h>
|
||||||
|
#include <kernel/region.h>
|
||||||
|
#include <kernel/ship.h>
|
||||||
|
#include <kernel/terrain.h>
|
||||||
|
#include <kernel/unit.h>
|
||||||
|
|
||||||
|
#include <util/attrib.h>
|
||||||
|
#include <util/base36.h>
|
||||||
|
#include <util/goodies.h>
|
||||||
|
#include <util/language.h>
|
||||||
|
#include <util/parser.h>
|
||||||
|
#include <util/rng.h>
|
||||||
|
#include <util/message.h>
|
||||||
|
|
||||||
|
#include <attributes/otherfaction.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
21
src/piracy.h
Normal file
21
src/piracy.h
Normal file
|
@ -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
|
Loading…
Reference in a new issue