forked from github/server
- Schiffe treiben nicht ab. Movement-Routine sail() übersichtlicher gestaltet, und Abtreiben neu implementiert
This commit is contained in:
parent
95a8068635
commit
28021ed6a6
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue