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)) {
int stormchance;
int stormyness = 0;
int stormchance = 0;
int reason;
bool storms_enabled = get_param_int(global.parameters, "rules.ship.storms", 1) != 0;
if (storms_enabled) {
int stormyness;
gamedate date;
get_gamedate(turn, &date);
stormyness = storms ? storms[date.month] * 5 : 0;
}
/* storms should be the first thing we do. */
stormchance = stormyness / shipspeed(sh, u);
if (check_leuchtturm(next_point, NULL)) {
int param = get_param_int(global.parameters, "rules.lighthous.stormchancedevisor", 0);
if (param > 0) {
stormchance /= param;
/* storms should be the first thing we do. */
stormchance = stormyness / shipspeed(sh, u);
if (check_leuchtturm(next_point, NULL)) {
int param = get_param_int(global.parameters, "rules.lighthous.stormchancedevisor", 0);
if (param > 0) {
stormchance /= param;
}
else {
stormchance = 0;
}
}
else {
stormchance = 0;
}
}
if (rng_int() % 10000 < stormchance * sh->type->storm
&& fval(current_point->terrain, SEA_REGION)) {
if (!is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) {
region *rnext = NULL;
bool storm = true;
int d_offset = rng_int() % MAXDIRECTIONS;
direction_t d;
/* 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 (rng_int() % 10000 < stormchance * sh->type->storm
&& fval(current_point->terrain, SEA_REGION)) {
if (!is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) {
region *rnext = NULL;
bool storm = true;
int d_offset = rng_int() % MAXDIRECTIONS;
direction_t d;
/* 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 (fval(rn->terrain, FORBIDDEN_REGION))
continue;
if (!fval(rn->terrain, SEA_REGION)) {
storm = false;
break;
if (rn != NULL) {
if (fval(rn->terrain, FORBIDDEN_REGION))
continue;
if (!fval(rn->terrain, SEA_REGION)) {
storm = false;
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(tnext, SEA_REGION)) {
if (!move_on_land) {

View File

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

View File

@ -1,6 +1,8 @@
#include <platform.h>
#include "piracy.h"
#include <kernel/config.h>
#include <kernel/region.h>
#include <kernel/unit.h>
#include <kernel/ship.h>
#include <kernel/terrain.h>
@ -17,34 +19,48 @@
static void setup_piracy(void) {
struct locale *lang;
terrain_type *t_ocean;
ship_type *st_boat;
test_cleanup();
set_param(&global.parameters, "rules.ship.storms", "0");
lang = get_or_create_locale("de");
locale_setstring(lang, directions[D_EAST], "OSTEN");
init_directions(lang);
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) {
faction *f;
region *r;
unit *u, *u2;
order *ord;
terrain_type *t_ocean;
ship_type *st_boat;
setup_piracy();
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));
u_set_ship(u2, test_create_ship(u2->region, 0));
u_set_ship(u2, test_create_ship(u2->region, st_boat));
assert(u2);
u = test_create_unit(f = test_create_faction(0), test_create_region(0, 0, t_ocean));
u_set_ship(u, test_create_ship(u->region, 0));
u = test_create_unit(f = test_create_faction(0), r = test_create_region(0, 0, t_ocean));
set_level(u, SK_SAILING, st_boat->sumskill);
u_set_ship(u, test_create_ship(u->region, st_boat));
assert(f && u);
f->locale = get_or_create_locale("de");
ord = create_order(K_PIRACY, f->locale, "%s", itoa36(u2->faction->no));
assert(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();
}
@ -53,8 +69,10 @@ static void test_piracy_cmd_errors(CuTest * tc) {
faction *f;
unit *u, *u2;
order *ord;
ship_type *st_boat;
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")));
f->locale = get_or_create_locale("de");
ord = create_order(K_PIRACY, f->locale, "");
@ -63,7 +81,7 @@ static void test_piracy_cmd_errors(CuTest * tc) {
piracy_cmd(u, ord);
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);
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 * 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;
return s;
}
@ -134,6 +134,7 @@ ship_type * test_create_shiptype(const char * name)
stype->cptskill = 1;
stype->sumskill = 1;
stype->minskill = 1;
stype->range = 2;
if (!stype->construction) {
stype->construction = calloc(1, sizeof(construction));
stype->construction->maxsize = 5;