forked from github/server
Merge branch 'develop' of github.com:badgerman/eressea into develop
This commit is contained in:
commit
221c83365d
6 changed files with 143 additions and 47 deletions
|
@ -435,13 +435,25 @@ void write_ship_reference(const struct ship *sh, struct storage *store)
|
|||
void ship_setname(ship * self, const char *name)
|
||||
{
|
||||
free(self->name);
|
||||
if (name)
|
||||
self->name = _strdup(name);
|
||||
else
|
||||
self->name = NULL;
|
||||
self->name = name ? _strdup(name) : 0;
|
||||
}
|
||||
|
||||
const char *ship_getname(const ship * self)
|
||||
{
|
||||
return self->name;
|
||||
}
|
||||
|
||||
unit *get_captain(const ship * sh)
|
||||
{
|
||||
const region *r = sh->region;
|
||||
unit *u;
|
||||
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->ship == sh && u->number
|
||||
&& eff_skill(u, SK_SAILING, r) >= sh->type->cptskill)
|
||||
return u;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,9 +121,10 @@ extern "C" {
|
|||
extern void free_ship(struct ship *s);
|
||||
extern void free_ships(void);
|
||||
|
||||
extern const char *ship_getname(const struct ship *self);
|
||||
extern void ship_setname(struct ship *self, const char *name);
|
||||
const char *ship_getname(const struct ship *self);
|
||||
void ship_setname(struct ship *self, const char *name);
|
||||
int shipspeed(const struct ship *sh, const struct unit *u);
|
||||
struct unit *get_captain(const struct ship *sh);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
14
src/move.c
14
src/move.c
|
@ -2130,20 +2130,6 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
|
|||
}
|
||||
}
|
||||
|
||||
unit *get_captain(const ship * sh)
|
||||
{
|
||||
const region *r = sh->region;
|
||||
unit *u;
|
||||
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->ship == sh && u->number
|
||||
&& eff_skill(u, SK_SAILING, r) >= sh->type->cptskill)
|
||||
return u;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Segeln, Wandern, Reiten
|
||||
* when this routine returns a non-zero value, movement for the region needs
|
||||
* to be done again because of followers that got new MOVE orders.
|
||||
|
|
|
@ -64,7 +64,6 @@ extern "C" {
|
|||
int enoughsailors(const struct ship *sh, const struct region *r);
|
||||
bool canswim(struct unit *u);
|
||||
bool canfly(struct unit *u);
|
||||
struct unit *get_captain(const struct ship *sh);
|
||||
void travelthru(const struct unit *u, struct region *r);
|
||||
struct ship *move_ship(struct ship *sh, struct region *from,
|
||||
struct region *to, struct region_list *route);
|
||||
|
|
38
src/spy.c
38
src/spy.c
|
@ -53,6 +53,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* in spy steht der Unterschied zwischen Wahrnehmung des Opfers und
|
||||
* Spionage des Spions */
|
||||
|
@ -394,7 +395,7 @@ static int try_destruction(unit * u, unit * u2, const ship * sh, int skilldiff)
|
|||
return 1; /* success */
|
||||
}
|
||||
|
||||
static void sink_ship(region * r, ship * sh, const char *name, unit * saboteur)
|
||||
static void sink_ship(region * r, ship * sh, unit * saboteur)
|
||||
{
|
||||
unit **ui, *u;
|
||||
region *safety = r;
|
||||
|
@ -404,6 +405,9 @@ static void sink_ship(region * r, ship * sh, const char *name, unit * saboteur)
|
|||
message *sink_msg = NULL;
|
||||
faction *f;
|
||||
|
||||
assert(r);
|
||||
assert(sh);
|
||||
assert(saboteur);
|
||||
for (f = NULL, u = r->units; u; u = u->next) {
|
||||
/* slight optimization to avoid dereferencing u->faction each time */
|
||||
if (f != u->faction) {
|
||||
|
@ -426,7 +430,7 @@ static void sink_ship(region * r, ship * sh, const char *name, unit * saboteur)
|
|||
}
|
||||
}
|
||||
}
|
||||
for (ui = &r->units; *ui; ui = &(*ui)->next) {
|
||||
for (ui = &r->units; *ui;) {
|
||||
unit *u = *ui;
|
||||
|
||||
/* inform this faction about the sinking ship: */
|
||||
|
@ -471,13 +475,14 @@ static void sink_ship(region * r, ship * sh, const char *name, unit * saboteur)
|
|||
add_message(&u->faction->msgs, msg);
|
||||
msg_release(msg);
|
||||
if (dead == u->number) {
|
||||
/* the poor creature, she dies */
|
||||
if (remove_unit(ui, u) != 0) {
|
||||
if (remove_unit(ui, u) == 0) {
|
||||
/* ui is already pointing at u->next */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
ui = &u->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sink_msg)
|
||||
msg_release(sink_msg);
|
||||
/* finally, get rid of the ship */
|
||||
|
@ -487,19 +492,21 @@ static void sink_ship(region * r, ship * sh, const char *name, unit * saboteur)
|
|||
int sabotage_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
const char *s;
|
||||
int i;
|
||||
param_t p;
|
||||
ship *sh;
|
||||
unit *u2;
|
||||
char buffer[DISPLAYSIZE];
|
||||
region *r = u->region;
|
||||
int skdiff;
|
||||
region *r;
|
||||
int skdiff = INT_MAX;
|
||||
|
||||
assert(u);
|
||||
assert(ord);
|
||||
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
|
||||
i = findparam(s, u->faction->locale);
|
||||
p = findparam(s, u->faction->locale);
|
||||
|
||||
switch (i) {
|
||||
switch (p) {
|
||||
case P_SHIP:
|
||||
sh = u->ship;
|
||||
if (!sh) {
|
||||
|
@ -507,10 +514,13 @@ int sabotage_cmd(unit * u, struct order *ord)
|
|||
return 0;
|
||||
}
|
||||
u2 = ship_owner(sh);
|
||||
r = u->region;
|
||||
if (u2->faction != u->faction) {
|
||||
skdiff =
|
||||
eff_skill(u, SK_SPY, r) - crew_skill(r, u2->faction, sh, SK_PERCEPTION);
|
||||
}
|
||||
if (try_destruction(u, u2, sh, skdiff)) {
|
||||
sink_ship(r, sh, buffer, u);
|
||||
sink_ship(r, sh, u);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -5,9 +5,12 @@
|
|||
#include <kernel/region.h>
|
||||
#include <kernel/unit.h>
|
||||
#include <kernel/faction.h>
|
||||
#include <kernel/ship.h>
|
||||
#include <kernel/order.h>
|
||||
#include <kernel/item.h>
|
||||
#include <kernel/messages.h>
|
||||
#include <util/attrib.h>
|
||||
#include <util/language.h>
|
||||
#include <util/message.h>
|
||||
#include <util/crmessage.h>
|
||||
#include <tests.h>
|
||||
|
@ -16,6 +19,7 @@
|
|||
|
||||
#include "spy.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <CuTest.h>
|
||||
|
@ -98,12 +102,96 @@ static void test_all_spy_message(CuTest *tc) {
|
|||
test_cleanup();
|
||||
}
|
||||
|
||||
static void setup_sabotage(void) {
|
||||
struct locale *lang;
|
||||
|
||||
test_cleanup();
|
||||
lang = get_or_create_locale("de");
|
||||
locale_setstring(lang, parameters[P_SHIP], "SCHIFF");
|
||||
test_create_world();
|
||||
init_locales();
|
||||
}
|
||||
|
||||
static void test_sabotage_self(CuTest *tc) {
|
||||
unit *u;
|
||||
region *r;
|
||||
order *ord;
|
||||
|
||||
setup_sabotage();
|
||||
r = test_create_region(0, 0, NULL);
|
||||
assert(r);
|
||||
u = test_create_unit(test_create_faction(NULL), r);
|
||||
assert(u && u->faction && u->region == r);
|
||||
u->ship = test_create_ship(r, test_create_shiptype("boat"));
|
||||
assert(u->ship);
|
||||
ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF");
|
||||
assert(ord);
|
||||
CuAssertIntEquals(tc, 0, sabotage_cmd(u, ord));
|
||||
CuAssertPtrEquals(tc, 0, r->ships);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
||||
static void test_sabotage_other_fail(CuTest *tc) {
|
||||
unit *u, *u2;
|
||||
region *r;
|
||||
order *ord;
|
||||
message *msg;
|
||||
|
||||
setup_sabotage();
|
||||
r = test_create_region(0, 0, NULL);
|
||||
assert(r);
|
||||
u = test_create_unit(test_create_faction(NULL), r);
|
||||
u2 = test_create_unit(test_create_faction(NULL), r);
|
||||
assert(u && u2);
|
||||
u2->ship = test_create_ship(r, test_create_shiptype("boat"));
|
||||
assert(u2->ship);
|
||||
u->ship = u2->ship;
|
||||
ship_update_owner(u->ship);
|
||||
assert(ship_owner(u->ship) == u);
|
||||
ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF");
|
||||
assert(ord);
|
||||
CuAssertIntEquals(tc, 0, sabotage_cmd(u2, ord));
|
||||
msg = test_get_last_message(u2->faction->msgs);
|
||||
CuAssertStrEquals(tc, "destroy_ship_1", test_get_messagetype(msg));
|
||||
msg = test_get_last_message(u->faction->msgs);
|
||||
CuAssertStrEquals(tc, "destroy_ship_3", test_get_messagetype(msg));
|
||||
CuAssertPtrNotNull(tc, r->ships);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
||||
static void test_sabotage_other_success(CuTest *tc) {
|
||||
unit *u, *u2;
|
||||
region *r;
|
||||
order *ord;
|
||||
|
||||
setup_sabotage();
|
||||
r = test_create_region(0, 0, NULL);
|
||||
assert(r);
|
||||
u = test_create_unit(test_create_faction(NULL), r);
|
||||
u2 = test_create_unit(test_create_faction(NULL), r);
|
||||
assert(u && u2);
|
||||
u2->ship = test_create_ship(r, test_create_shiptype("boat"));
|
||||
assert(u2->ship);
|
||||
u->ship = u2->ship;
|
||||
ship_update_owner(u->ship);
|
||||
assert(ship_owner(u->ship) == u);
|
||||
ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF");
|
||||
assert(ord);
|
||||
set_level(u2, SK_SPY, 1);
|
||||
CuAssertIntEquals(tc, 0, sabotage_cmd(u2, ord));
|
||||
CuAssertPtrEquals(tc, 0, r->ships);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
CuSuite *get_spy_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
SUITE_ADD_TEST(suite, test_simple_spy_message);
|
||||
SUITE_ADD_TEST(suite, test_all_spy_message);
|
||||
SUITE_ADD_TEST(suite, test_sabotage_self);
|
||||
SUITE_ADD_TEST(suite, test_sabotage_other_fail);
|
||||
SUITE_ADD_TEST(suite, test_sabotage_other_success);
|
||||
return suite;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue