test for actual piracy ship movement

refactor storm check, run less code when disabled
fix ship creation in tests
This commit is contained in:
Enno Rehling 2015-10-12 19:40:20 +02:00
parent d252286f4c
commit 7e2364c296
4 changed files with 73 additions and 54 deletions

View File

@ -1847,66 +1847,65 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
} }
if (!flying_ship(sh)) { if (!flying_ship(sh)) {
int stormchance; int stormchance = 0;
int stormyness = 0;
int reason; int reason;
bool storms_enabled = get_param_int(global.parameters, "rules.ship.storms", 1) != 0; bool storms_enabled = get_param_int(global.parameters, "rules.ship.storms", 1) != 0;
if (storms_enabled) { if (storms_enabled) {
int stormyness;
gamedate date; gamedate date;
get_gamedate(turn, &date); get_gamedate(turn, &date);
stormyness = storms ? storms[date.month] * 5 : 0; stormyness = storms ? storms[date.month] * 5 : 0;
}
/* storms should be the first thing we do. */ /* storms should be the first thing we do. */
stormchance = stormyness / shipspeed(sh, u); stormchance = stormyness / shipspeed(sh, u);
if (check_leuchtturm(next_point, NULL)) { if (check_leuchtturm(next_point, NULL)) {
int param = get_param_int(global.parameters, "rules.lighthous.stormchancedevisor", 0); int param = get_param_int(global.parameters, "rules.lighthous.stormchancedevisor", 0);
if (param > 0) { if (param > 0) {
stormchance /= param; stormchance /= param;
}
else {
stormchance = 0;
}
} }
else { if (rng_int() % 10000 < stormchance * sh->type->storm
stormchance = 0; && fval(current_point->terrain, SEA_REGION)) {
} if (!is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) {
} region *rnext = NULL;
if (rng_int() % 10000 < stormchance * sh->type->storm bool storm = true;
&& fval(current_point->terrain, SEA_REGION)) { int d_offset = rng_int() % MAXDIRECTIONS;
if (!is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) { direction_t d;
region *rnext = NULL; /* Sturm nur, wenn nächste Region Hochsee ist. */
bool storm = true; for (d = 0; d != MAXDIRECTIONS; ++d) {
int d_offset = rng_int() % MAXDIRECTIONS; direction_t dnext = (direction_t)((d + d_offset) % MAXDIRECTIONS);
direction_t d; region *rn = rconnect(current_point, dnext);
/* Sturm nur, wenn nächste Region Hochsee ist. */
for (d = 0; d != MAXDIRECTIONS; ++d) {
direction_t dnext = (direction_t)((d + d_offset) % MAXDIRECTIONS);
region *rn = rconnect(current_point, dnext);
if (rn != NULL) { if (rn != NULL) {
if (fval(rn->terrain, FORBIDDEN_REGION)) if (fval(rn->terrain, FORBIDDEN_REGION))
continue; continue;
if (!fval(rn->terrain, SEA_REGION)) { if (!fval(rn->terrain, SEA_REGION)) {
storm = false; storm = false;
break; break;
}
if (rn != next_point)
rnext = rn;
} }
if (rn != next_point) }
rnext = rn; if (storm && rnext != NULL) {
ADDMSG(&f->msgs, msg_message("storm", "ship region sink",
sh, current_point, sh->damage >= sh->size * DAMAGE_SCALE));
/* damage the ship. we handle destruction in the end */
damage_ship(sh, damage_drift());
if (sh->damage >= sh->size * DAMAGE_SCALE)
break;
next_point = rnext;
/* these values need to be updated if next_point changes (due to storms): */
tnext = next_point->terrain;
} }
} }
if (storm && rnext != NULL) {
ADDMSG(&f->msgs, msg_message("storm", "ship region sink",
sh, current_point, sh->damage >= sh->size * DAMAGE_SCALE));
/* damage the ship. we handle destruction in the end */
damage_ship(sh, damage_drift());
if (sh->damage >= sh->size * DAMAGE_SCALE)
break;
next_point = rnext;
/* these values need to be updated if next_point changes (due to storms): */
tnext = next_point->terrain;
}
} }
} } // storms_enabled
if (!fval(tthis, SEA_REGION)) { if (!fval(tthis, SEA_REGION)) {
if (!fval(tnext, SEA_REGION)) { if (!fval(tnext, SEA_REGION)) {
if (!move_on_land) { if (!move_on_land) {

View File

@ -115,7 +115,7 @@ void piracy_cmd(unit * u, order *ord)
{ {
region *r = u->region; region *r = u->region;
ship *sh = u->ship, *sh2; ship *sh = u->ship, *sh2;
direction_t dir, target_dir; direction_t target_dir;
struct { struct {
const faction *target; const faction *target;
int value; int value;
@ -136,6 +136,7 @@ void piracy_cmd(unit * u, order *ord)
/* Wenn nicht, sehen wir, ob wir ein Ziel finden. */ /* Wenn nicht, sehen wir, ob wir ein Ziel finden. */
if (target_dir == NODIRECTION) { if (target_dir == NODIRECTION) {
direction_t dir;
/* Einheit ist also Kapitän. Jetzt gucken, in wievielen /* Einheit ist also Kapitän. Jetzt gucken, in wievielen
* Nachbarregionen potentielle Opfer sind. */ * Nachbarregionen potentielle Opfer sind. */

View File

@ -1,6 +1,8 @@
#include <platform.h> #include <platform.h>
#include "piracy.h" #include "piracy.h"
#include <kernel/config.h>
#include <kernel/region.h>
#include <kernel/unit.h> #include <kernel/unit.h>
#include <kernel/ship.h> #include <kernel/ship.h>
#include <kernel/terrain.h> #include <kernel/terrain.h>
@ -17,34 +19,48 @@
static void setup_piracy(void) { static void setup_piracy(void) {
struct locale *lang; struct locale *lang;
terrain_type *t_ocean; terrain_type *t_ocean;
ship_type *st_boat;
test_cleanup(); test_cleanup();
set_param(&global.parameters, "rules.ship.storms", "0");
lang = get_or_create_locale("de"); lang = get_or_create_locale("de");
locale_setstring(lang, directions[D_EAST], "OSTEN"); locale_setstring(lang, directions[D_EAST], "OSTEN");
init_directions(lang); init_directions(lang);
t_ocean = test_create_terrain("ocean", SAIL_INTO | SEA_REGION); t_ocean = test_create_terrain("ocean", SAIL_INTO | SEA_REGION);
st_boat = test_create_shiptype("boat");
st_boat->cargo = 1000;
} }
static void test_piracy_cmd(CuTest * tc) { static void test_piracy_cmd(CuTest * tc) {
faction *f; faction *f;
region *r;
unit *u, *u2; unit *u, *u2;
order *ord; order *ord;
terrain_type *t_ocean; terrain_type *t_ocean;
ship_type *st_boat;
setup_piracy(); setup_piracy();
t_ocean = get_or_create_terrain("ocean"); t_ocean = get_or_create_terrain("ocean");
st_boat = st_get_or_create("boat");
u2 = test_create_unit(test_create_faction(0), test_create_region(1, 0, t_ocean)); u2 = test_create_unit(test_create_faction(0), test_create_region(1, 0, t_ocean));
u_set_ship(u2, test_create_ship(u2->region, 0)); u_set_ship(u2, test_create_ship(u2->region, st_boat));
assert(u2); assert(u2);
u = test_create_unit(f = test_create_faction(0), test_create_region(0, 0, t_ocean)); u = test_create_unit(f = test_create_faction(0), r = test_create_region(0, 0, t_ocean));
u_set_ship(u, test_create_ship(u->region, 0)); set_level(u, SK_SAILING, st_boat->sumskill);
u_set_ship(u, test_create_ship(u->region, st_boat));
assert(f && u); assert(f && u);
f->locale = get_or_create_locale("de"); f->locale = get_or_create_locale("de");
ord = create_order(K_PIRACY, f->locale, "%s", itoa36(u2->faction->no)); ord = create_order(K_PIRACY, f->locale, "%s", itoa36(u2->faction->no));
assert(ord); assert(ord);
piracy_cmd(u, ord); piracy_cmd(u, ord);
CuAssertPtrNotNullMsg(tc, "successful PIRACY", test_find_messagetype(f->msgs, "piratesawvictim")); CuAssertPtrEquals(tc, 0, u->thisorder);
CuAssertTrue(tc, u->region != r);
CuAssertPtrEquals(tc, u2->region, u->region);
CuAssertPtrEquals(tc, u2->region, u->ship->region);
CuAssertPtrNotNullMsg(tc, "successful PIRACY sets attribute", r->attribs); // FIXME: this is testing implementation, not interface
CuAssertPtrNotNullMsg(tc, "successful PIRACY message", test_find_messagetype(f->msgs, "piratesawvictim"));
CuAssertPtrNotNullMsg(tc, "successful PIRACY movement", test_find_messagetype(f->msgs, "shipsail"));
test_cleanup(); test_cleanup();
} }
@ -53,8 +69,10 @@ static void test_piracy_cmd_errors(CuTest * tc) {
faction *f; faction *f;
unit *u, *u2; unit *u, *u2;
order *ord; order *ord;
ship_type *st_boat;
setup_piracy(); setup_piracy();
st_boat = st_get_or_create("boat");
u = test_create_unit(f = test_create_faction(0), test_create_region(0, 0, get_or_create_terrain("ocean"))); u = test_create_unit(f = test_create_faction(0), test_create_region(0, 0, get_or_create_terrain("ocean")));
f->locale = get_or_create_locale("de"); f->locale = get_or_create_locale("de");
ord = create_order(K_PIRACY, f->locale, ""); ord = create_order(K_PIRACY, f->locale, "");
@ -63,7 +81,7 @@ static void test_piracy_cmd_errors(CuTest * tc) {
piracy_cmd(u, ord); piracy_cmd(u, ord);
CuAssertPtrNotNullMsg(tc, "must be on a ship for PIRACY", test_find_messagetype(f->msgs, "error144")); CuAssertPtrNotNullMsg(tc, "must be on a ship for PIRACY", test_find_messagetype(f->msgs, "error144"));
u_set_ship(u, test_create_ship(u->region, 0)); u_set_ship(u, test_create_ship(u->region, st_boat));
u2 = test_create_unit(u->faction, u->region); u2 = test_create_unit(u->faction, u->region);
u_set_ship(u2, u->ship); u_set_ship(u2, u->ship);

View File

@ -123,7 +123,7 @@ building * test_create_building(region * r, const building_type * btype)
ship * test_create_ship(region * r, const ship_type * stype) ship * test_create_ship(region * r, const ship_type * stype)
{ {
ship * s = new_ship(stype ? stype : st_get_or_create("boat"), r, default_locale); ship * s = new_ship(stype ? stype : test_create_shiptype("boat"), r, default_locale);
s->size = s->type->construction ? s->type->construction->maxsize : 1; s->size = s->type->construction ? s->type->construction->maxsize : 1;
return s; return s;
} }
@ -134,6 +134,7 @@ ship_type * test_create_shiptype(const char * name)
stype->cptskill = 1; stype->cptskill = 1;
stype->sumskill = 1; stype->sumskill = 1;
stype->minskill = 1; stype->minskill = 1;
stype->range = 2;
if (!stype->construction) { if (!stype->construction) {
stype->construction = calloc(1, sizeof(construction)); stype->construction = calloc(1, sizeof(construction));
stype->construction->maxsize = 5; stype->construction->maxsize = 5;