- Schiffe treiben nicht ab.
  Movement-Routine sail() übersichtlicher gestaltet, und Abtreiben neu implementiert
This commit is contained in:
Enno Rehling 2004-05-31 16:21:03 +00:00
parent 95a8068635
commit 28021ed6a6
14 changed files with 232 additions and 247 deletions

View File

@ -2655,7 +2655,7 @@ sinkships(void)
damage_ship(sh, 0.05);
}
if (sh->damage >= sh->size * DAMAGE_SCALE)
destroy_ship(sh, r);
destroy_ship(sh);
}
list_next(sh);
}

View File

@ -592,7 +592,7 @@ chaos(region * r)
while (sh) {
ship * nsh = sh->next;
damage_ship(sh, 0.50);
if (sh->damage >= sh->size * DAMAGE_SCALE) destroy_ship(sh, r);
if (sh->damage >= sh->size * DAMAGE_SCALE) destroy_ship(sh);
sh = nsh;
}
@ -932,7 +932,7 @@ move_iceberg(region *r)
if (sh->damage>=sh->size * DAMAGE_SCALE) {
if (u) ADDMSG(&u->faction->msgs, new_message(u->faction,
"overrun_by_iceberg_des%h:ship", sh));
destroy_ship(sh, r);
destroy_ship(sh);
} else {
if (u) ADDMSG(&u->faction->msgs, new_message(u->faction,
"overrun_by_iceberg%h:ship", sh));
@ -1034,7 +1034,7 @@ godcurse(void)
unit * u = shipowner(r, sh);
if (u) ADDMSG(&u->faction->msgs,
msg_message("godcurse_destroy_ship", "ship", sh));
destroy_ship(sh, r);
destroy_ship(sh);
}
sh = shn;
}

View File

@ -386,15 +386,18 @@ sink_ship(region * r, ship * sh, const char *name, char spy, unit * saboteur)
vset_init(&survivors);
/* figure out what a unit's chances of survival are: */
if (rterrain(r) != T_OCEAN)
probability = CANAL_SWIMMER_CHANCE;
else
for (d = 0; d != MAXDIRECTIONS; ++d)
if (rterrain(rconnect(r, d)) != T_OCEAN && !move_blocked(NULL, r, d)) {
safety = rconnect(r, d);
probability = OCEAN_SWIMMER_CHANCE;
break;
}
if (rterrain(r) != T_OCEAN) {
probability = CANAL_SWIMMER_CHANCE;
} else {
for (d = 0; d != MAXDIRECTIONS; ++d) {
region * rnext = rconnect(r, d);
if (rterrain(rnext) != T_OCEAN && !move_blocked(NULL, r, rnext)) {
safety = rnext;
probability = OCEAN_SWIMMER_CHANCE;
break;
}
}
}
for (ui = &r->units; *ui; ui = &(*ui)->next) {
unit *u = *ui;
@ -484,7 +487,7 @@ sink_ship(region * r, ship * sh, const char *name, char spy, unit * saboteur)
}
}
/* finally, get rid of the ship */
destroy_ship(sh, r);
destroy_ship(sh);
vset_destroy(&informed);
vset_destroy(&survivors);
}

View File

@ -206,7 +206,7 @@ fleeregion(const unit * u)
for (i = 0; i != MAXDIRECTIONS; ++i) {
region * r2 = rconnect(r, i);
if (r2) {
if (can_survive(u,r2) && !move_blocked(u, r, i))
if (can_survive(u,r2) && !move_blocked(u, r, r2))
neighbours[c++] = r2;
}
}
@ -2569,7 +2569,7 @@ aftermath(battle * b)
ship * sh = *sp;
freset(sh, SF_DAMAGED);
if (sh->damage >= sh->size * DAMAGE_SCALE) {
destroy_ship(sh, r);
destroy_ship(sh);
}
if (*sp==sh) sp=&sh->next;
}

View File

@ -414,7 +414,7 @@ destroy(region * r, unit * u, const char * cmd)
}
add_message(&u->faction->msgs, new_message(
u->faction, "shipdestroy%u:unit%r:region%h:ship", u, r, sh));
destroy_ship(sh, r);
destroy_ship(sh);
} else {
/* partial destroy */
sh->size -= (sh->type->construction->maxsize * n)/100;

View File

@ -82,8 +82,6 @@ void reportevent(struct region * r, char *s);
void shash(struct ship * sh);
void sunhash(struct ship * sh);
void destroy_ship(struct ship * s, struct region * r);
extern int build(struct unit * u, const construction * ctype, int completed, int want);
extern int maxbuild(const struct unit *u, const construction *cons);

View File

@ -2863,7 +2863,7 @@ movewhere(region * r, const unit *u)
return 0;
}
if (move_blocked(u, r, d) == true) {
if (move_blocked(u, r, r2)) {
add_message(&u->faction->msgs,
msg_message("moveblocked", "unit direction", u, d));
return NULL;
@ -2883,18 +2883,23 @@ movewhere(region * r, const unit *u)
}
boolean
move_blocked(const unit * u, const region *r, direction_t dir)
move_blocked(const unit * u, const region *r, const region *r2)
{
region * r2 = NULL;
border * b;
if (dir<MAXDIRECTIONS) r2 = rconnect(r, dir);
if (r2==NULL) return true;
b = get_borders(r, r2);
while (b) {
if (b->type->block && b->type->block(b, u, r)) return true;
b = b->next;
}
return false;
border * b;
curse * c;
static const curse_type * fogtrap_ct = NULL;
if (r2==NULL) return true;
b = get_borders(r, r2);
while (b) {
if (b->type->block && b->type->block(b, u, r)) return true;
b = b->next;
}
if (fogtrap_ct==NULL) fogtrap_ct = ct_find("fogtrap");
c = get_curse(r->attribs, fogtrap_ct);
if (curse_active(c)) return true;
return false;
}
void

View File

@ -1131,7 +1131,7 @@ extern int maxworkingpeasants(const struct region * r);
extern int wage(const struct region *r, const struct unit *u, boolean img);
extern int fwage(const struct region *r, const struct faction *f, boolean img);
extern struct region * movewhere(struct region * r, const struct unit *u);
extern boolean move_blocked(const struct unit * u, const struct region *r, direction_t dir);
extern boolean move_blocked(const struct unit * u, const struct region *src, const struct region *dest);
extern void add_income(struct unit * u, int type, int want, int qty);
extern int month(int offset);

View File

@ -18,8 +18,6 @@
* permission from the authors.
*/
#define SAFE_COASTS /* Schiffe an der Küste treiben nicht ab */
#include <config.h>
#include "eressea.h"
#include "movement.h"
@ -425,29 +423,30 @@ enoughsailors(region * r, ship * sh)
}
/* ------------------------------------------------------------- */
static void
static ship *
do_maelstrom(region *r, unit *u)
{
int damage;
int damage;
damage = rand()%150 - eff_skill(u, SK_SAILING, r)*5;
damage = rand()%150 - eff_skill(u, SK_SAILING, r)*5;
if(damage <= 0) {
add_message(&u->faction->msgs,
new_message(u->faction, "entermaelstrom%r:region%h:ship%i:damage%i:sink", r, u->ship, damage, 1));
return;
}
if(damage <= 0) {
add_message(&u->faction->msgs,
new_message(u->faction, "entermaelstrom%r:region%h:ship%i:damage%i:sink", r, u->ship, damage, 1));
return u->ship;
}
damage_ship(u->ship, 0.01*damage);
damage_ship(u->ship, 0.01*damage);
if (u->ship->damage >= u->ship->size * DAMAGE_SCALE) {
ADDMSG(&u->faction->msgs, msg_message("entermaelstrom",
"region ship damage sink", r, u->ship, damage, 1));
destroy_ship(u->ship, r);
} else {
ADDMSG(&u->faction->msgs, msg_message("entermaelstrom",
"region ship damage sink", r, u->ship, damage, 0));
}
if (u->ship->damage >= u->ship->size * DAMAGE_SCALE) {
ADDMSG(&u->faction->msgs, msg_message("entermaelstrom",
"region ship damage sink", r, u->ship, damage, 1));
destroy_ship(u->ship);
return NULL;
}
ADDMSG(&u->faction->msgs, msg_message("entermaelstrom",
"region ship damage sink", r, u->ship, damage, 0));
return u->ship;
}
/** sets a marker in the region telling that the unit has travelled through it
@ -623,7 +622,7 @@ drifting_ships(region * r)
damage_ship(sh, 0.02);
if (sh->damage>=sh->size * DAMAGE_SCALE) {
destroy_ship(sh, rnext);
destroy_ship(sh);
}
}
@ -632,26 +631,6 @@ drifting_ships(region * r)
}
}
static void
ship_in_storm(unit *cap, region *next_point)
{
int i;
if(is_cursed(cap->ship->attribs, C_SHIP_NODRIFT, 0)) return;
add_message(&cap->faction->msgs,
new_message(cap->faction, "storm%h:ship%r:region%i:sink",
cap->ship, next_point, cap->ship->damage>=cap->ship->size * DAMAGE_SCALE));
/* Veränderung der Drehrichtung */
i = rand()%2==0?1:-1;
#if 0 /* make a temporary attribute for this */
cap->wants += i;
#endif
/* Merken für Sperren des Anlandens. */
if(i) fset(cap, UFL_STORM);
}
static boolean
present(region * r, unit * u)
{
@ -942,13 +921,11 @@ travel(unit * u, region * next, int flucht, region_list ** routep)
region_list **iroute = &route;
static boolean init = false;
static const curse_type * speed_ct;
static const curse_type * fogtrap_ct;
if (routep) *routep = NULL;
if (!init) {
init = true;
speed_ct = ct_find("speed");
fogtrap_ct = ct_find("fogtrap");
}
/* tech:
@ -1094,9 +1071,7 @@ travel(unit * u, region * next, int flucht, region_list ** routep)
else k-=BP_NORMAL;
if (k<0) break;
if ((reldir>=0 && move_blocked(u, current, reldir))
|| curse_active(get_curse(current->attribs, fogtrap_ct)))
{
if (reldir>=0 && move_blocked(u, current, next)) {
ADDMSG(&u->faction->msgs, msg_message("leavefail",
"unit region", u, next));
}
@ -1395,42 +1370,47 @@ check_takeoff(ship *sh, region *from, region *to)
}
static boolean
ship_allowed(const struct ship_type * type, region * r)
flying_ship(const ship * sh)
{
int c = 0;
if (check_working_buildingtype(r, bt_find("harbour"))) return true;
for (c=0;type->coast[c]!=NOTERRAIN;++c) {
if (type->coast[c]==rterrain(r)) return true;
}
return false;
if (sh->type->flags & SFL_FLY) return true;
if (is_cursed(sh->attribs, C_SHIP_FLYING, 0)) return true;
return false;
}
static boolean
ship_allowed(const struct ship_type * type, const region * r)
{
int c = 0;
terrain_t t = rterrain(r);
static const building_type * bt_harbour=NULL;
if (bt_harbour==NULL) bt_harbour=bt_find("harbour");
if (check_working_buildingtype(r, bt_harbour)) return true;
for (c=0;type->coast[c]!=NOTERRAIN;++c) {
if (type->coast[c]==t) return true;
}
return false;
}
static region_list *
sail(unit * u, region * next_point, boolean move_on_land)
{
region * starting_point = u->region;
region *starting_point = u->region;
region *current_point, *last_point;
unit *u2, *hafenmeister;
item * trans = NULL;
int st, first = 1;
int k, step = 0;
int stormchance;
region_list *route = NULL;
region_list **iroute = &route;
static boolean init = false;
static const curse_type * fogtrap_ct;
if (!init) {
init = true;
fogtrap_ct = ct_find("fogtrap");
}
ship * sh = u->ship;
faction * f = u->faction;
if (!ship_ready(starting_point, u))
return NULL;
if (!ship_ready(starting_point, u)) return NULL;
/* Wir suchen so lange nach neuen Richtungen, wie es geht. Diese werden
* dann nacheinander ausgeführt. */
k = shipspeed(u->ship, u);
k = shipspeed(sh, u);
last_point = starting_point;
current_point = starting_point;
@ -1442,145 +1422,153 @@ sail(unit * u, region * next_point, boolean move_on_land)
* Durchlauf schon gesetzt (Parameter!). current_point ist die letzte gültige,
* befahrene Region. */
while (current_point!=next_point && step < k && next_point)
{
while (current_point!=next_point && step < k && next_point) {
terrain_t tthis = rterrain(current_point);
/* these values need to be updated if next_point changes (due to storms): */
terrain_t tnext = rterrain(next_point);
direction_t dir = reldirection(current_point, next_point);
if(terrain[rterrain(next_point)].flags & FORBIDDEN_LAND) {
assert(sh==u->ship || !"ship has sunk, but we didn't notice it");
if (terrain[tnext].flags & FORBIDDEN_LAND) {
plane *pl = getplane(next_point);
if(pl && fval(pl, PFL_NOCOORDS)) {
ADDMSG(&u->faction->msgs, msg_message("sailforbiddendir",
"ship direction", u->ship, dir));
if (pl && fval(pl, PFL_NOCOORDS)) {
ADDMSG(&f->msgs, msg_message("sailforbiddendir",
"ship direction", sh, dir));
} else {
ADDMSG(&u->faction->msgs, msg_message("sailforbidden",
"ship region", u->ship, next_point));
ADDMSG(&f->msgs, msg_message("sailforbidden",
"ship region", sh, next_point));
}
break;
}
if( !is_cursed(u->ship->attribs, C_SHIP_FLYING, 0)
&& !(u->ship->type->flags & SFL_FLY)) {
if (rterrain(current_point) != T_OCEAN
&& rterrain(next_point) != T_OCEAN) {
if (!flying_ship(sh)) {
/* storms should be the first thing we do. */
int stormchance = storms[month(0)] * 5 / shipspeed(sh, u);
if (check_leuchtturm(next_point, NULL)) stormchance /= 3;
if (rand()%10000 < stormchance && next_point->terrain == T_OCEAN) {
if (!is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) {
region * rnext = NULL;
boolean storm = true;
int d_offset = rand() % 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) {
terrain_t t = rterrain(rn);
if (terrain[t].flags & FORBIDDEN_LAND) continue;
if (t!=T_OCEAN) {
storm = false;
break;
}
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, 0.02);
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 = rterrain(next_point);
dir = reldirection(current_point, next_point);
}
}
}
if (tthis != T_OCEAN) {
if (tnext != T_OCEAN) {
if (!move_on_land) {
/* check that you're not traveling from one land region to another. */
plane *pl = getplane(next_point);
if (dir<MAXDIRECTIONS && pl && fval(pl, PFL_NOCOORDS)) {
if (pl!=NULL && fval(pl, PFL_NOCOORDS)) {
/* we don't have that case yet, but hey... */
sprintf(buf, "Die %s entdeckt, daß im %s Festland ist.",
shipname(u->ship), locale_string(u->faction->locale, directions[dir]));
shipname(sh), locale_string(u->faction->locale, directions[dir]));
} else {
sprintf(buf, "Die %s entdeckt, daß (%d,%d) Festland ist.",
shipname(u->ship), region_x(next_point,u->faction),
shipname(sh), region_x(next_point,u->faction),
region_y(next_point,u->faction));
}
addmessage(0, u->faction, buf, MSG_MOVE, ML_WARN);
break;
}
if (!(u->ship->type->flags & SFL_OPENSEA) && rterrain(next_point) == T_OCEAN) {
direction_t d;
for (d=0;d!=MAXDIRECTIONS;++d) {
region * rc = rconnect(next_point, d);
if (rterrain(rc) != T_OCEAN) break;
}
if (d==MAXDIRECTIONS) {
/* Schiff kann nicht aufs offene Meer */
cmistake(u, findorder(u, u->thisorder), 249, MSG_MOVE);
break;
}
} else {
if (check_takeoff(sh, current_point, next_point) == false) {
/* Schiff kann nicht ablegen */
cmistake(u, findorder(u, u->thisorder), 182, MSG_MOVE);
break;
}
if(rterrain(current_point) != T_OCEAN
&& rterrain(next_point) == T_OCEAN) {
if(check_takeoff(u->ship, current_point, next_point) == false) {
/* Schiff kann nicht ablegen */
cmistake(u, findorder(u, u->thisorder), 182, MSG_MOVE);
break;
}
}
}
} else if (tnext==T_OCEAN) {
/* target region is an ocean, and we're not leaving a shore */
if (!(sh->type->flags & SFL_OPENSEA)) {
/* ship can only stay close to shore */
direction_t d;
for (d=0;d!=MAXDIRECTIONS;++d) {
region * rc = rconnect(next_point, d);
if (rterrain(rc) != T_OCEAN) break;
}
if (d==MAXDIRECTIONS) {
/* Schiff kann nicht aufs offene Meer */
cmistake(u, findorder(u, u->thisorder), 249, MSG_MOVE);
break;
}
}
}
if (!ship_allowed(sh->type, next_point)) {
/* for some reason or another, we aren't allowed in there.. */
if (check_leuchtturm(current_point, NULL)) {
ADDMSG(&f->msgs, msg_message("sailnolandingstorm", "ship", sh));
} else {
damage_ship(sh, 0.10);
/* we handle destruction at the end */
}
break;
}
if (move_on_land == false && rterrain(next_point) != T_OCEAN) {
break;
}
if (is_cursed(next_point->attribs, C_MAELSTROM, 0)) {
if (do_maelstrom(next_point, u)==NULL) break;
}
/* Falls Blockade, endet die Seglerei hier */
} /* !flying_ship */
if (move_blocked(u, current_point, dir)
|| curse_active(get_curse(current_point->attribs, fogtrap_ct))) {
add_message(&u->faction->msgs, new_message(u->faction,
"sailfail%h:ship%r:region", u->ship, current_point));
break;
}
if (!ship_allowed(u->ship->type, next_point)) {
if(fval(u, UFL_STORM)) {
if(!check_leuchtturm(current_point, NULL)) {
add_message(&u->faction->msgs, new_message(u->faction,
"sailnolandingstorm%h:ship", u->ship));
damage_ship(u->ship, 0.10);
if (u->ship->damage>=u->ship->size * DAMAGE_SCALE) {
add_message(&u->faction->msgs, new_message(u->faction,
"shipsink%h:ship", u->ship));
}
}
} else {
add_message(&u->faction->msgs, new_message(u->faction,
"sailnolanding%h:ship%r:region", u->ship, next_point));
damage_ship(u->ship, 0.10);
if (u->ship->damage>=u->ship->size * DAMAGE_SCALE) {
add_message(&u->faction->msgs, new_message(u->faction,
"shipsink%h:ship", u->ship));
}
}
break;
}
if(terrain[rterrain(next_point)].flags & FORBIDDEN_LAND) {
plane *pl = getplane(next_point);
if(pl && fval(pl, PFL_NOCOORDS)) {
add_message(&u->faction->msgs, new_message(u->faction,
"sailforbiddendir%h:ship%i:direction",
u->ship, dir));
/* sprintf(buf, "Die Mannschaft der %s weigert sich, in die Feuerwand "
"im %s zu fahren.",
shipname(u->ship), directions[dir]); */
} else {
add_message(&u->faction->msgs, new_message(u->faction,
"sailforbidden%h:ship%r:region", u->ship, next_point));
}
break;
}
/* Falls Blockade, endet die Seglerei hier */
if (move_blocked(u, current_point, next_point)) {
ADDMSG(&u->faction->msgs, msg_message("sailfail", "ship region", sh, current_point));
break;
}
if(is_cursed(next_point->attribs, C_MAELSTROM, 0)) {
do_maelstrom(next_point, u);
}
/* Falls kein Problem, eines weiter ziehen */
fset(sh, SF_MOVED);
add_regionlist(iroute, next_point);
iroute = &(*iroute)->next;
step++;
stormchance = storms[month(0)] * 5 / shipspeed(u->ship, u);
if(check_leuchtturm(next_point, NULL)) stormchance /= 3;
#ifdef SAFE_COASTS
/* Sturm nur, wenn nächste Region Hochsee ist. */
if(rand()%10000 < stormchance) {
direction_t d;
for (d=0;d!=MAXDIRECTIONS;++d) {
region * r = rconnect(next_point, d);
if (rterrain(r)!=T_OCEAN) break;
}
if (d==MAXDIRECTIONS)
ship_in_storm(u, next_point);
}
#else
/* Sturm nur, wenn nächste Region keine Landregion ist. */
if(rand()%10000 < stormchance && next_point->terrain == T_OCEAN) {
ship_in_storm(u, next_point);
}
#endif
} /* endif !flying */
last_point = current_point;
current_point = next_point;
/* Falls kein Problem, eines weiter ziehen */
fset(u->ship, SF_MOVED);
add_regionlist(iroute, next_point);
iroute = &(*iroute)->next;
step++;
if (rterrain(current_point) != T_OCEAN && !is_cursed(sh->attribs, C_SHIP_FLYING, 0)) break;
next_point = movewhere(current_point, u);
}
last_point = current_point;
current_point = next_point;
if (rterrain(current_point) != T_OCEAN && !is_cursed(u->ship->attribs, C_SHIP_FLYING, 0)) break;
next_point = movewhere(current_point, u);
if (sh->damage>=sh->size * DAMAGE_SCALE) {
ADDMSG(&f->msgs, msg_message("shipsink", "ship", sh));
destroy_ship(sh);
sh = NULL;
}
/* Nun enthält current_point die Region, in der das Schiff seine Runde
@ -1589,8 +1577,8 @@ sail(unit * u, region * next_point, boolean move_on_land)
* gekommen ist. Das ist nicht der Fall, wenn er von der Küste ins
* Inland zu segeln versuchte */
if (fval(u->ship, SF_MOVED)) {
ship * sh = u->ship;
if (sh!=NULL && fval(sh, SF_MOVED)) {
unit * hafenmeister;
/* nachdem alle Richtungen abgearbeitet wurden, und alle Einheiten
* transferiert wurden, kann der aktuelle Befehl gelöscht werden. */
cycle_route(u, step);
@ -1626,9 +1614,12 @@ sail(unit * u, region * next_point, boolean move_on_land)
hafenmeister = owner_buildingtyp(current_point, bt_find("harbour"));
if (sh && hafenmeister != NULL) {
item * itm;
assert(trans==NULL);
unit * u2;
boolean first = true;
item * trans = NULL;
for (u2 = current_point->units; u2; u2 = u2->next) {
if (u2->ship == u->ship &&
if (u2->ship == sh &&
!alliedunit(hafenmeister, u->faction, HELP_GUARD)) {
@ -1636,7 +1627,7 @@ sail(unit * u, region * next_point, boolean move_on_land)
for (itm=u2->items; itm; itm=itm->next) {
const luxury_type * ltype = resource2luxury(itm->type->rtype);
if (ltype!=NULL && itm->number>0) {
st = itm->number * effskill(hafenmeister, SK_TRADE) / 50;
int st = itm->number * effskill(hafenmeister, SK_TRADE) / 50;
st = min(itm->number, st);
if (st > 0) {
@ -1652,14 +1643,14 @@ sail(unit * u, region * next_point, boolean move_on_land)
if (trans) {
sprintf(buf, "%s erhielt ", hafenmeister->name);
for (itm = trans; itm; itm=itm->next) {
if (first != 1) {
if (!first) {
if (itm->next!=NULL && itm->next->next==NULL) {
scat(" und ");
} else {
scat(", ");
}
}
first = 0;
first = false;
icat(trans->number);
scat(" ");
if (itm->number == 1) {
@ -2029,7 +2020,7 @@ destroy_damaged_ships(void)
for(sh=r->ships;sh;) {
shn = sh->next;
if (sh->damage>=sh->size * DAMAGE_SCALE) {
destroy_ship(sh, r);
destroy_ship(sh);
}
sh = shn;
}

View File

@ -159,8 +159,6 @@ typdata_t typdata[] = {
(find_fun)unit_find,
(desc_fun)unitname,
(attrib_fun)unit_attribs,
(destroy_fun)destroy_unit,
(deref_fun)unit_deref,
(set_fun)unit_set,
},
/* TYP_REGION */ {
@ -168,8 +166,6 @@ typdata_t typdata[] = {
(find_fun)region_find,
(desc_fun)regionid,
(attrib_fun)region_attribs,
(destroy_fun)cannot_destroy,
(deref_fun)region_deref,
(set_fun)region_set,
},
/* TYP_BUILDING */ {
@ -177,8 +173,6 @@ typdata_t typdata[] = {
(find_fun)building_find,
(desc_fun)buildingname,
(attrib_fun)building_attribs,
(destroy_fun)destroy_building,
(deref_fun)building_deref,
(set_fun)building_set,
},
/* TYP_SHIP */ {
@ -186,8 +180,6 @@ typdata_t typdata[] = {
(find_fun)ship_find,
(desc_fun)shipname,
(attrib_fun)ship_attribs,
(destroy_fun)destroy_ship,
(deref_fun)ship_deref,
(set_fun)ship_set,
},
/* TYP_FACTION */ {
@ -195,8 +187,6 @@ typdata_t typdata[] = {
(find_fun)faction_find,
(desc_fun)notimplemented_desc,
(attrib_fun)faction_attribs,
(destroy_fun)cannot_destroy,
(deref_fun)faction_deref,
(set_fun)faction_set,
},
};

View File

@ -46,8 +46,6 @@ typedef obj_ID (*ID_fun)(void *obj);
typedef void *(*find_fun)(obj_ID id);
typedef char *(*desc_fun)(void *obj);
typedef attrib **(*attrib_fun)(void *obj);
typedef void (*destroy_fun)(void *obj);
typedef void *(*deref_fun)(void *obj);
typedef void (*set_fun)(void *ptrptr, void *obj); /* *ptrptr = obj */
@ -56,8 +54,6 @@ typedef struct {
find_fun find; /* liefert struct unit* zu obj_ID */
desc_fun getname; /* unitname() */
attrib_fun getattribs; /* liefert &u->attribs */
destroy_fun destroy; /* destroy_unit() */
deref_fun ppget; /* liefert struct unit* aus struct unit** */
set_fun ppset; /* setzt *(struct unit **) zu struct unit* */
} typdata_t;

View File

@ -183,20 +183,20 @@ new_ship(const ship_type * stype, region * r)
}
void
destroy_ship(ship * s, region * r)
destroy_ship(ship * sh)
{
unit * u = r->units;
region * r = sh->region;
unit * u = r->units;
if(!findship(s->no)) return;
while (u) {
if (u->ship == s) {
leave_ship(u);
}
u = u->next;
}
sunhash(s);
choplist(&r->ships, s);
handle_event(&s->attribs, "destroy", s);
while (u) {
if (u->ship == sh) {
leave_ship(u);
}
u = u->next;
}
sunhash(sh);
choplist(&r->ships, sh);
handle_event(&sh->attribs, "destroy", sh);
}
const char *

View File

@ -94,6 +94,8 @@ extern const struct ship_type * findshiptype(const char *s, const struct locale
extern void register_ships(void);
extern void destroy_ship(struct ship * s);
#ifdef __cplusplus
}
#endif

View File

@ -1280,7 +1280,7 @@ showunits(region * r)
modified = 1;
for (x = shipregion->units; x; x = x->next)
leave(shipregion, x);
destroy_ship(clipship, shipregion);
destroy_ship(clipship);
clipship = 0;
shipregion = 0;
for (pline = 0, tmp = eh; tmp != pointer; tmp = tmp->next)