forked from github/server
BUG 2168: call sink_ship for ships that take too much damage.
This commit is contained in:
parent
7eb951544a
commit
ad0464ab50
12 changed files with 61 additions and 33 deletions
2
clibs
2
clibs
|
@ -1 +1 @@
|
|||
Subproject commit 9b6e34959f77d7ca3a4ce3826cb487487f557441
|
||||
Subproject commit d86c8525489d7f11b7ba13e101bb59ecf160b871
|
|
@ -517,3 +517,16 @@ function test_buy_sell()
|
|||
assert_equal(4, u:get_item(item))
|
||||
assert_not_equal(0, u:get_item('money'))
|
||||
end
|
||||
|
||||
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')
|
||||
u.ship = sh
|
||||
us:clear_orders()
|
||||
us:add_order('ATTACKIERE ' .. itoa36(u.id))
|
||||
us:set_skill('unarmed', 10)
|
||||
process_orders()
|
||||
write_reports()
|
||||
end
|
||||
|
|
|
@ -26,6 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "move.h"
|
||||
#include "skill.h"
|
||||
#include "study.h"
|
||||
#include "spy.h"
|
||||
|
||||
#include <spells/buildingcurse.h>
|
||||
#include <spells/regioncurse.h>
|
||||
|
@ -2787,10 +2788,12 @@ static void aftermath(battle * b)
|
|||
ship *sh = *sp;
|
||||
freset(sh, SF_DAMAGED);
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
sink_ship(sh);
|
||||
remove_ship(sp, sh);
|
||||
}
|
||||
if (*sp == sh)
|
||||
else {
|
||||
sp = &sh->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -909,8 +909,8 @@ static int tolua_unit_create(lua_State * L)
|
|||
faction *f = (faction *)tolua_tousertype(L, 1, 0);
|
||||
region *r = (region *)tolua_tousertype(L, 2, 0);
|
||||
unit *u;
|
||||
const char *rcname = tolua_tostring(L, 4, NULL);
|
||||
int num = (int)tolua_tonumber(L, 3, 1);
|
||||
const char *rcname = tolua_tostring(L, 4, NULL);
|
||||
const race *rc;
|
||||
|
||||
assert(f && r);
|
||||
|
|
20
src/chaos.c
20
src/chaos.c
|
@ -21,6 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "chaos.h"
|
||||
#include "monsters.h"
|
||||
#include "move.h"
|
||||
#include "spy.h"
|
||||
|
||||
#include <kernel/building.h>
|
||||
#include <kernel/faction.h>
|
||||
|
@ -144,19 +145,20 @@ static void chaos(region * r)
|
|||
break;
|
||||
}
|
||||
if (dir != MAXDIRECTIONS) {
|
||||
ship *sh = r->ships;
|
||||
ship **slist = &r->ships;
|
||||
unit **up;
|
||||
|
||||
while (sh) {
|
||||
ship *nsh = sh->next;
|
||||
double dmg =
|
||||
config_get_flt("rules.ship.damage.atlantis",
|
||||
0.50);
|
||||
damage_ship(sh, dmg);
|
||||
while (*slist) {
|
||||
ship *sh = *slist;
|
||||
|
||||
damage_ship(sh, 0.5);
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
sink_ship(sh);
|
||||
remove_ship(slist, sh);
|
||||
}
|
||||
else {
|
||||
slist = &sh->next;
|
||||
}
|
||||
sh = nsh;
|
||||
}
|
||||
|
||||
for (up = &r->units; *up;) {
|
||||
|
|
|
@ -22,8 +22,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct region;
|
||||
|
||||
void chaos_update(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -124,9 +124,9 @@ extern "C" {
|
|||
extern void write_ship_reference(const struct ship *sh,
|
||||
struct storage *store);
|
||||
|
||||
extern void remove_ship(struct ship **slist, struct ship *s);
|
||||
extern void free_ship(struct ship *s);
|
||||
extern void free_ships(void);
|
||||
void remove_ship(struct ship **slist, struct ship *s);
|
||||
void free_ship(struct ship *s);
|
||||
void free_ships(void);
|
||||
|
||||
const char *ship_getname(const struct ship *sh);
|
||||
void ship_setname(struct ship *self, const char *name);
|
||||
|
|
|
@ -2590,6 +2590,7 @@ void sinkships(struct region * r)
|
|||
}
|
||||
}
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
sink_ship(sh);
|
||||
remove_ship(shp, sh);
|
||||
}
|
||||
if (*shp == sh)
|
||||
|
|
|
@ -47,6 +47,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "laws.h"
|
||||
#include "reports.h"
|
||||
#include "study.h"
|
||||
#include "spy.h"
|
||||
#include "alchemy.h"
|
||||
#include "travelthru.h"
|
||||
#include "vortex.h"
|
||||
|
@ -541,6 +542,7 @@ static ship *do_maelstrom(region * r, unit * u)
|
|||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
ADDMSG(&u->faction->msgs, msg_message("entermaelstrom",
|
||||
"region ship damage sink", r, sh, damage, 1));
|
||||
sink_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -882,12 +884,14 @@ static void drifting_ships(region * r)
|
|||
}
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
msg_to_ship_inmates(sh, &firstu, &lastu, msg_message("shipsink", "ship", sh));
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
sink_ship(sh);
|
||||
remove_ship(shp, sh);
|
||||
}
|
||||
}
|
||||
|
||||
if (*shp == sh)
|
||||
if (*shp == sh) {
|
||||
shp = &sh->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1926,6 +1930,7 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting)
|
|||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
if (sh->region) {
|
||||
ADDMSG(&f->msgs, msg_message("shipsink", "ship", sh));
|
||||
sink_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
sh = NULL;
|
||||
|
|
|
@ -26,6 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "economy.h"
|
||||
#include "monsters.h"
|
||||
#include "move.h"
|
||||
#include "spy.h"
|
||||
#include "study.h"
|
||||
#include "volcano.h"
|
||||
|
||||
|
@ -295,6 +296,7 @@ static void move_iceberg(region * r)
|
|||
ADDMSG(&u->faction->msgs, msg_message("overrun_by_iceberg_des",
|
||||
"ship", sh));
|
||||
}
|
||||
sink_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
else if (u != NULL) {
|
||||
|
@ -421,6 +423,7 @@ static void godcurse(void)
|
|||
ADDMSG(&uo->faction->msgs,
|
||||
msg_message("godcurse_destroy_ship", "ship", sh));
|
||||
}
|
||||
sink_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
sh = shn;
|
||||
|
|
25
src/spy.c
25
src/spy.c
|
@ -392,19 +392,22 @@ static int try_destruction(unit * u, unit * u2, const ship * sh, int skilldiff)
|
|||
return 1; /* success */
|
||||
}
|
||||
|
||||
static void sink_ship(region * r, ship * sh, unit * saboteur)
|
||||
#define OCEAN_SWIMMER_CHANCE 0.1
|
||||
#define COAST_SWIMMER_CHANCE 0.9
|
||||
|
||||
void sink_ship(ship * sh)
|
||||
{
|
||||
unit **ui, *u;
|
||||
region *safety = r;
|
||||
region *r, *safety;
|
||||
int i;
|
||||
direction_t d;
|
||||
double probability = 0.0;
|
||||
message *sink_msg = NULL;
|
||||
faction *f;
|
||||
|
||||
assert(r);
|
||||
assert(sh);
|
||||
assert(saboteur);
|
||||
assert(sh && sh->region);
|
||||
r = sh->region;
|
||||
|
||||
for (f = NULL, u = r->units; u; u = u->next) {
|
||||
/* slight optimization to avoid dereferencing u->faction each time */
|
||||
if (f != u->faction) {
|
||||
|
@ -414,8 +417,9 @@ static void sink_ship(region * r, ship * sh, unit * saboteur)
|
|||
}
|
||||
|
||||
/* figure out what a unit's chances of survival are: */
|
||||
safety = r;
|
||||
if (!(r->terrain->flags & SEA_REGION)) {
|
||||
probability = CANAL_SWIMMER_CHANCE;
|
||||
probability = COAST_SWIMMER_CHANCE;
|
||||
}
|
||||
else {
|
||||
for (d = 0; d != MAXDIRECTIONS; ++d) {
|
||||
|
@ -479,10 +483,9 @@ static void sink_ship(region * r, ship * sh, unit * saboteur)
|
|||
}
|
||||
ui = &u->next;
|
||||
}
|
||||
if (sink_msg)
|
||||
if (sink_msg) {
|
||||
msg_release(sink_msg);
|
||||
/* finally, get rid of the ship */
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
}
|
||||
|
||||
int sabotage_cmd(unit * u, struct order *ord)
|
||||
|
@ -514,7 +517,9 @@ int sabotage_cmd(unit * u, struct order *ord)
|
|||
effskill(u, SK_SPY, 0) - top_skill(u->region, u2->faction, sh, SK_PERCEPTION);
|
||||
}
|
||||
if (try_destruction(u, u2, sh, skdiff)) {
|
||||
sink_ship(u->region, sh, u);
|
||||
sink_ship(sh);
|
||||
/* finally, get rid of the ship */
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -27,6 +27,7 @@ extern "C" {
|
|||
struct strlist;
|
||||
struct order;
|
||||
struct faction;
|
||||
struct ship;
|
||||
|
||||
int setstealth_cmd(struct unit *u, struct order *ord);
|
||||
int spy_cmd(struct unit *u, struct order *ord);
|
||||
|
@ -34,10 +35,7 @@ extern "C" {
|
|||
void spy_message(int spy, const struct unit *u,
|
||||
const struct unit *target);
|
||||
void set_factionstealth(struct unit * u, struct faction * f);
|
||||
|
||||
|
||||
#define OCEAN_SWIMMER_CHANCE 0.1
|
||||
#define CANAL_SWIMMER_CHANCE 0.9
|
||||
void sink_ship(struct ship * sh);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue