simplicate the sink_ship function, do not rescue units.

This commit is contained in:
Enno Rehling 2018-08-01 11:55:57 +02:00
parent ad0464ab50
commit e89fe69d58
7 changed files with 60 additions and 109 deletions

View File

@ -868,21 +868,6 @@
</type>
</message>
<message name="sink_lost_msg" section="events">
<type>
<arg name="dead" type="int"/>
<arg name="region" type="region"/>
<arg name="unit" type="unit"/>
</type>
</message>
<message name="sink_saved_msg" section="events">
<type>
<arg name="region" type="region"/>
<arg name="unit" type="unit"/>
</type>
</message>
<message name="sink_msg" section="events">
<type>
<arg name="ship" type="ship"/>

View File

@ -2303,9 +2303,6 @@ msgstr "\"$unit($mage) erleidet durch den Tod seines Vertrauten einen Schock.\""
msgid "error269"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Hier kann man nicht zaubern.\""
msgid "sink_saved_msg"
msgstr "\"$unit($unit) überlebt unbeschadet und rettet sich nach $region($region).\""
msgid "race_noregroup"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - $race($race,0) können nicht neu gruppiert werden.\""
@ -2654,9 +2651,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - Die Einheit kan
msgid "analyse_building_noage"
msgstr "\"$unit($mage) fand heraus, dass auf $building($building) der Zauber '$curse($curse)' liegt, dessen Kraft ausreicht, um noch Jahrhunderte bestehen zu bleiben.\""
msgid "sink_lost_msg"
msgstr "\"$int($amount) Personen von $unit($unit) ertrinken.$if($isnull($region),\"\",\" Die Einheit rettet sich nach $region($region).\")\""
msgid "error130"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Syntax: MAGIEGEBIET [1-5].\""

View File

@ -2303,9 +2303,6 @@ msgstr "\"$unit($mage) receives a shock when his familiar dies.\""
msgid "error269"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - You cannot cast spells here.\""
msgid "sink_saved_msg"
msgstr "\"$unit($unit) survives unscathed and makes it to $region($region).\""
msgid "race_noregroup"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - $race($race,0) cannot be regrouped.\""
@ -2654,9 +2651,6 @@ msgstr "\"$unit($unit) in $region($region): '$order($command)' - The unit cannot
msgid "analyse_building_noage"
msgstr "\"$unit($mage) discovers that $building($building) is charmed with '$curse($curse)', which will last for centuries.\""
msgid "sink_lost_msg"
msgstr "\"$int($amount) people of $unit($unit) drown.$if($isnull($region),\"\",\" The unit makes it to $region($region).\")\""
msgid "error130"
msgstr "\"$unit($unit) in $region($region): '$order($command)' - Syntax: MAGIC SPHERE [1-5].\""

View File

@ -522,7 +522,7 @@ function test_seaserpent_attack()
local r = region.create(0, 0, 'ocean')
local sh = ship.create(r, 'boat')
local us = unit.create(get_monsters(), r, 1, 'seaserpent')
local u = unit.create(faction.create('human'), r, 20, 'human')
local u = unit.create(faction.create('human', 'enno@example.com'), r, 20, 'human')
u.ship = sh
us:clear_orders()
us:add_order('ATTACKIERE ' .. itoa36(u.id))

View File

@ -287,6 +287,9 @@ void setup_drift (struct drift_fixture *fix) {
u_set_ship(fix->u, fix->sh = test_create_ship(fix->u->region, fix->st_boat));
assert(fix->sh);
mt_create_va(mt_new("sink_msg", NULL),
"ship:ship", "region:region", MT_NEW_END);
mt_create_va(mt_new("ship_drift", NULL),
"ship:ship", "dir:int", MT_NEW_END);
mt_create_va(mt_new("shipsink", NULL),

View File

@ -392,16 +392,10 @@ static int try_destruction(unit * u, unit * u2, const ship * sh, int skilldiff)
return 1; /* success */
}
#define OCEAN_SWIMMER_CHANCE 0.1
#define COAST_SWIMMER_CHANCE 0.9
void sink_ship(ship * sh)
{
unit **ui, *u;
region *r, *safety;
int i;
direction_t d;
double probability = 0.0;
unit *u;
region *r;
message *sink_msg = NULL;
faction *f;
@ -416,72 +410,23 @@ void sink_ship(ship * sh)
}
}
/* figure out what a unit's chances of survival are: */
safety = r;
if (!(r->terrain->flags & SEA_REGION)) {
probability = COAST_SWIMMER_CHANCE;
}
else {
for (d = 0; d != MAXDIRECTIONS; ++d) {
region *rn = rconnect(r, d);
if (rn && !(rn->terrain->flags & SEA_REGION) && !move_blocked(NULL, r, rn)) {
safety = rn;
probability = OCEAN_SWIMMER_CHANCE;
break;
}
}
}
for (ui = &r->units; *ui;) {
for (f = NULL, u = r->units; u; u = u->next) {
/* inform this faction about the sinking ship: */
u = *ui;
if (!(u->faction->flags & FFL_SELECT)) {
fset(u->faction, FFL_SELECT);
if (sink_msg == NULL) {
sink_msg = msg_message("sink_msg", "ship region", sh, r);
}
add_message(&f->msgs, sink_msg);
}
if (u->ship == sh) {
int dead = 0;
message *msg;
/* if this fails, I misunderstood something: */
for (i = 0; i != u->number; ++i)
if (chance(probability))
++dead;
if (dead != u->number) {
/* she will live. but her items get stripped */
if (dead > 0) {
msg =
msg_message("sink_lost_msg", "dead region unit", dead, safety, u);
}
else {
msg = msg_message("sink_saved_msg", "region unit", safety, u);
}
leave_ship(u);
if (r != safety) {
setguard(u, false);
}
while (u->items) {
i_remove(&u->items, u->items);
}
move_unit(u, safety, NULL);
}
else {
msg = msg_message("sink_lost_msg", "dead region unit", dead, (region *)NULL, u);
}
add_message(&u->faction->msgs, msg);
msg_release(msg);
if (dead == u->number) {
if (remove_unit(ui, u) == 0) {
/* ui is already pointing at u->next */
continue;
if (f != u->faction) {
f = u->faction;
if (!(f->flags & FFL_SELECT)) {
f->flags |= FFL_SELECT;
if (sink_msg == NULL) {
sink_msg = msg_message("sink_msg", "ship region", sh, r);
}
add_message(&f->msgs, sink_msg);
}
}
}
ui = &u->next;
else if (f != NULL) {
break;
}
}
if (sink_msg) {
msg_release(sink_msg);

View File

@ -55,10 +55,6 @@ static void setup_spy(spy_fixture *fix) {
"ship:ship", MT_NEW_END);
mt_create_va(mt_new("sink_msg", NULL),
"ship:ship", "region:region", MT_NEW_END);
mt_create_va(mt_new("sink_lost_msg", NULL),
"unit:unit", "region:region", "dead:int", MT_NEW_END);
mt_create_va(mt_new("sink_saved_msg", NULL),
"unit:unit", "region:region", MT_NEW_END);
if (fix) {
fix->r = test_create_region(0, 0, NULL);
@ -112,6 +108,7 @@ static void test_sabotage_self(CuTest *tc) {
unit *u;
region *r;
order *ord;
message *msg;
test_setup();
setup_spy(NULL);
@ -119,17 +116,49 @@ static void test_sabotage_self(CuTest *tc) {
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"));
u->ship = test_create_ship(r, NULL);
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);
CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "sink_msg"));
CuAssertPtrEquals(tc, NULL, r->ships);
CuAssertPtrNotNull(tc, msg = test_find_messagetype(u->faction->msgs, "sink_msg"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype_ex(u->faction->msgs, "sink_msg", msg));
free_order(ord);
test_teardown();
}
static void test_sink_ship(CuTest *tc) {
ship *sh;
unit *u1, *u2, *u3;
region *r;
message *msg;
test_setup();
setup_spy(NULL);
r = test_create_ocean(0, 0);
u1 = test_create_unit(test_create_faction(NULL), r);
u2 = test_create_unit(u1->faction, r);
u3 = test_create_unit(test_create_faction(NULL), r);
u1->ship = u2->ship = u3->ship = sh = test_create_ship(r, NULL);
sink_ship(sh);
CuAssertPtrEquals(tc, r, sh->region);
CuAssertPtrEquals(tc, sh, r->ships);
CuAssertPtrNotNull(tc, msg = test_find_messagetype(u1->faction->msgs, "sink_msg"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype_ex(u1->faction->msgs, "sink_msg", msg));
CuAssertPtrNotNull(tc, msg = test_find_messagetype(u3->faction->msgs, "sink_msg"));
CuAssertPtrEquals(tc, NULL, test_find_messagetype_ex(u3->faction->msgs, "sink_msg", msg));
remove_ship(&r->ships, sh);
CuAssertPtrEquals(tc, NULL, sh->region);
CuAssertPtrEquals(tc, NULL, r->ships);
CuAssertPtrEquals(tc, NULL, u1->ship);
CuAssertPtrEquals(tc, NULL, u2->ship);
CuAssertPtrEquals(tc, NULL, u3->ship);
test_teardown();
}
static void test_sabotage_other_fail(CuTest *tc) {
unit *u, *u2;
@ -145,7 +174,7 @@ static void test_sabotage_other_fail(CuTest *tc) {
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"));
u2->ship = test_create_ship(r, NULL);
assert(u2->ship);
u->ship = u2->ship;
ship_update_owner(u->ship);
@ -167,7 +196,7 @@ static void test_setstealth_cmd(CuTest *tc) {
const struct locale *lang;
test_setup();
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0));
lang = u->faction->locale;
u->flags = UFL_ANON_FACTION | UFL_SIEGE;
u->thisorder = create_order(K_SETSTEALTH, lang, "%s %s",
@ -191,7 +220,7 @@ static void test_setstealth_demon(CuTest *tc) {
test_setup();
lang = test_create_locale();
rc = test_create_race("demon");
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL));
u = test_create_unit(test_create_faction(rc), test_create_plain(0, 0));
rc = test_create_race("dwarf");
init_races(lang);
u->thisorder = create_order(K_SETSTEALTH, lang, racename(lang, u, rc));
@ -208,7 +237,7 @@ static void test_setstealth_demon_bad(CuTest *tc) {
test_setup();
lang = test_create_locale();
rc = test_create_race("demon");
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL));
u = test_create_unit(test_create_faction(rc), test_create_plain(0, 0));
rc = test_create_race("smurf");
rc->flags &= ~RCF_PLAYABLE;
@ -232,7 +261,7 @@ static void test_sabotage_other_success(CuTest *tc) {
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"));
u2->ship = test_create_ship(r, NULL);
assert(u2->ship);
u->ship = u2->ship;
ship_update_owner(u->ship);
@ -251,6 +280,7 @@ 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_sink_ship);
SUITE_ADD_TEST(suite, test_sabotage_self);
SUITE_ADD_TEST(suite, test_setstealth_cmd);
SUITE_ADD_TEST(suite, test_setstealth_demon);