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);
|
damage_ship(sh, 0.05);
|
||||||
}
|
}
|
||||||
if (sh->damage >= sh->size * DAMAGE_SCALE)
|
if (sh->damage >= sh->size * DAMAGE_SCALE)
|
||||||
destroy_ship(sh, r);
|
destroy_ship(sh);
|
||||||
}
|
}
|
||||||
list_next(sh);
|
list_next(sh);
|
||||||
}
|
}
|
||||||
|
|
|
@ -592,7 +592,7 @@ chaos(region * r)
|
||||||
while (sh) {
|
while (sh) {
|
||||||
ship * nsh = sh->next;
|
ship * nsh = sh->next;
|
||||||
damage_ship(sh, 0.50);
|
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;
|
sh = nsh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,7 +932,7 @@ move_iceberg(region *r)
|
||||||
if (sh->damage>=sh->size * DAMAGE_SCALE) {
|
if (sh->damage>=sh->size * DAMAGE_SCALE) {
|
||||||
if (u) ADDMSG(&u->faction->msgs, new_message(u->faction,
|
if (u) ADDMSG(&u->faction->msgs, new_message(u->faction,
|
||||||
"overrun_by_iceberg_des%h:ship", sh));
|
"overrun_by_iceberg_des%h:ship", sh));
|
||||||
destroy_ship(sh, r);
|
destroy_ship(sh);
|
||||||
} else {
|
} else {
|
||||||
if (u) ADDMSG(&u->faction->msgs, new_message(u->faction,
|
if (u) ADDMSG(&u->faction->msgs, new_message(u->faction,
|
||||||
"overrun_by_iceberg%h:ship", sh));
|
"overrun_by_iceberg%h:ship", sh));
|
||||||
|
@ -1034,7 +1034,7 @@ godcurse(void)
|
||||||
unit * u = shipowner(r, sh);
|
unit * u = shipowner(r, sh);
|
||||||
if (u) ADDMSG(&u->faction->msgs,
|
if (u) ADDMSG(&u->faction->msgs,
|
||||||
msg_message("godcurse_destroy_ship", "ship", sh));
|
msg_message("godcurse_destroy_ship", "ship", sh));
|
||||||
destroy_ship(sh, r);
|
destroy_ship(sh);
|
||||||
}
|
}
|
||||||
sh = shn;
|
sh = shn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -386,15 +386,18 @@ sink_ship(region * r, ship * sh, const char *name, char spy, unit * saboteur)
|
||||||
vset_init(&survivors);
|
vset_init(&survivors);
|
||||||
|
|
||||||
/* figure out what a unit's chances of survival are: */
|
/* figure out what a unit's chances of survival are: */
|
||||||
if (rterrain(r) != T_OCEAN)
|
if (rterrain(r) != T_OCEAN) {
|
||||||
probability = CANAL_SWIMMER_CHANCE;
|
probability = CANAL_SWIMMER_CHANCE;
|
||||||
else
|
} else {
|
||||||
for (d = 0; d != MAXDIRECTIONS; ++d)
|
for (d = 0; d != MAXDIRECTIONS; ++d) {
|
||||||
if (rterrain(rconnect(r, d)) != T_OCEAN && !move_blocked(NULL, r, d)) {
|
region * rnext = rconnect(r, d);
|
||||||
safety = rconnect(r, d);
|
if (rterrain(rnext) != T_OCEAN && !move_blocked(NULL, r, rnext)) {
|
||||||
probability = OCEAN_SWIMMER_CHANCE;
|
safety = rnext;
|
||||||
break;
|
probability = OCEAN_SWIMMER_CHANCE;
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for (ui = &r->units; *ui; ui = &(*ui)->next) {
|
for (ui = &r->units; *ui; ui = &(*ui)->next) {
|
||||||
unit *u = *ui;
|
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 */
|
/* finally, get rid of the ship */
|
||||||
destroy_ship(sh, r);
|
destroy_ship(sh);
|
||||||
vset_destroy(&informed);
|
vset_destroy(&informed);
|
||||||
vset_destroy(&survivors);
|
vset_destroy(&survivors);
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,7 +206,7 @@ fleeregion(const unit * u)
|
||||||
for (i = 0; i != MAXDIRECTIONS; ++i) {
|
for (i = 0; i != MAXDIRECTIONS; ++i) {
|
||||||
region * r2 = rconnect(r, i);
|
region * r2 = rconnect(r, i);
|
||||||
if (r2) {
|
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;
|
neighbours[c++] = r2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2569,7 +2569,7 @@ aftermath(battle * b)
|
||||||
ship * sh = *sp;
|
ship * sh = *sp;
|
||||||
freset(sh, SF_DAMAGED);
|
freset(sh, SF_DAMAGED);
|
||||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||||
destroy_ship(sh, r);
|
destroy_ship(sh);
|
||||||
}
|
}
|
||||||
if (*sp==sh) sp=&sh->next;
|
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(
|
add_message(&u->faction->msgs, new_message(
|
||||||
u->faction, "shipdestroy%u:unit%r:region%h:ship", u, r, sh));
|
u->faction, "shipdestroy%u:unit%r:region%h:ship", u, r, sh));
|
||||||
destroy_ship(sh, r);
|
destroy_ship(sh);
|
||||||
} else {
|
} else {
|
||||||
/* partial destroy */
|
/* partial destroy */
|
||||||
sh->size -= (sh->type->construction->maxsize * n)/100;
|
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 shash(struct ship * sh);
|
||||||
void sunhash(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 build(struct unit * u, const construction * ctype, int completed, int want);
|
||||||
extern int maxbuild(const struct unit *u, const construction *cons);
|
extern int maxbuild(const struct unit *u, const construction *cons);
|
||||||
|
|
||||||
|
|
|
@ -2863,7 +2863,7 @@ movewhere(region * r, const unit *u)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (move_blocked(u, r, d) == true) {
|
if (move_blocked(u, r, r2)) {
|
||||||
add_message(&u->faction->msgs,
|
add_message(&u->faction->msgs,
|
||||||
msg_message("moveblocked", "unit direction", u, d));
|
msg_message("moveblocked", "unit direction", u, d));
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2883,18 +2883,23 @@ movewhere(region * r, const unit *u)
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean
|
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;
|
||||||
border * b;
|
curse * c;
|
||||||
if (dir<MAXDIRECTIONS) r2 = rconnect(r, dir);
|
static const curse_type * fogtrap_ct = NULL;
|
||||||
if (r2==NULL) return true;
|
|
||||||
b = get_borders(r, r2);
|
if (r2==NULL) return true;
|
||||||
while (b) {
|
b = get_borders(r, r2);
|
||||||
if (b->type->block && b->type->block(b, u, r)) return true;
|
while (b) {
|
||||||
b = b->next;
|
if (b->type->block && b->type->block(b, u, r)) return true;
|
||||||
}
|
b = b->next;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
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
|
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 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 int fwage(const struct region *r, const struct faction *f, boolean img);
|
||||||
extern struct region * movewhere(struct region * r, const struct unit *u);
|
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 void add_income(struct unit * u, int type, int want, int qty);
|
||||||
|
|
||||||
extern int month(int offset);
|
extern int month(int offset);
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
* permission from the authors.
|
* permission from the authors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SAFE_COASTS /* Schiffe an der Küste treiben nicht ab */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include "eressea.h"
|
#include "eressea.h"
|
||||||
#include "movement.h"
|
#include "movement.h"
|
||||||
|
@ -425,29 +423,30 @@ enoughsailors(region * r, ship * sh)
|
||||||
}
|
}
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
||||||
static void
|
static ship *
|
||||||
do_maelstrom(region *r, unit *u)
|
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) {
|
if(damage <= 0) {
|
||||||
add_message(&u->faction->msgs,
|
add_message(&u->faction->msgs,
|
||||||
new_message(u->faction, "entermaelstrom%r:region%h:ship%i:damage%i:sink", r, u->ship, damage, 1));
|
new_message(u->faction, "entermaelstrom%r:region%h:ship%i:damage%i:sink", r, u->ship, damage, 1));
|
||||||
return;
|
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) {
|
if (u->ship->damage >= u->ship->size * DAMAGE_SCALE) {
|
||||||
ADDMSG(&u->faction->msgs, msg_message("entermaelstrom",
|
ADDMSG(&u->faction->msgs, msg_message("entermaelstrom",
|
||||||
"region ship damage sink", r, u->ship, damage, 1));
|
"region ship damage sink", r, u->ship, damage, 1));
|
||||||
destroy_ship(u->ship, r);
|
destroy_ship(u->ship);
|
||||||
} else {
|
return NULL;
|
||||||
ADDMSG(&u->faction->msgs, msg_message("entermaelstrom",
|
}
|
||||||
"region ship damage sink", r, u->ship, damage, 0));
|
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
|
/** 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);
|
damage_ship(sh, 0.02);
|
||||||
|
|
||||||
if (sh->damage>=sh->size * DAMAGE_SCALE) {
|
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
|
static boolean
|
||||||
present(region * r, unit * u)
|
present(region * r, unit * u)
|
||||||
{
|
{
|
||||||
|
@ -942,13 +921,11 @@ travel(unit * u, region * next, int flucht, region_list ** routep)
|
||||||
region_list **iroute = &route;
|
region_list **iroute = &route;
|
||||||
static boolean init = false;
|
static boolean init = false;
|
||||||
static const curse_type * speed_ct;
|
static const curse_type * speed_ct;
|
||||||
static const curse_type * fogtrap_ct;
|
|
||||||
|
|
||||||
if (routep) *routep = NULL;
|
if (routep) *routep = NULL;
|
||||||
if (!init) {
|
if (!init) {
|
||||||
init = true;
|
init = true;
|
||||||
speed_ct = ct_find("speed");
|
speed_ct = ct_find("speed");
|
||||||
fogtrap_ct = ct_find("fogtrap");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tech:
|
/* tech:
|
||||||
|
@ -1094,9 +1071,7 @@ travel(unit * u, region * next, int flucht, region_list ** routep)
|
||||||
else k-=BP_NORMAL;
|
else k-=BP_NORMAL;
|
||||||
if (k<0) break;
|
if (k<0) break;
|
||||||
|
|
||||||
if ((reldir>=0 && move_blocked(u, current, reldir))
|
if (reldir>=0 && move_blocked(u, current, next)) {
|
||||||
|| curse_active(get_curse(current->attribs, fogtrap_ct)))
|
|
||||||
{
|
|
||||||
ADDMSG(&u->faction->msgs, msg_message("leavefail",
|
ADDMSG(&u->faction->msgs, msg_message("leavefail",
|
||||||
"unit region", u, next));
|
"unit region", u, next));
|
||||||
}
|
}
|
||||||
|
@ -1395,42 +1370,47 @@ check_takeoff(ship *sh, region *from, region *to)
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
ship_allowed(const struct ship_type * type, region * r)
|
flying_ship(const ship * sh)
|
||||||
{
|
{
|
||||||
int c = 0;
|
if (sh->type->flags & SFL_FLY) return true;
|
||||||
if (check_working_buildingtype(r, bt_find("harbour"))) return true;
|
if (is_cursed(sh->attribs, C_SHIP_FLYING, 0)) return true;
|
||||||
for (c=0;type->coast[c]!=NOTERRAIN;++c) {
|
return false;
|
||||||
if (type->coast[c]==rterrain(r)) 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 *
|
static region_list *
|
||||||
sail(unit * u, region * next_point, boolean move_on_land)
|
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;
|
region *current_point, *last_point;
|
||||||
unit *u2, *hafenmeister;
|
|
||||||
item * trans = NULL;
|
|
||||||
int st, first = 1;
|
|
||||||
int k, step = 0;
|
int k, step = 0;
|
||||||
int stormchance;
|
|
||||||
region_list *route = NULL;
|
region_list *route = NULL;
|
||||||
region_list **iroute = &route;
|
region_list **iroute = &route;
|
||||||
static boolean init = false;
|
ship * sh = u->ship;
|
||||||
static const curse_type * fogtrap_ct;
|
faction * f = u->faction;
|
||||||
if (!init) {
|
|
||||||
init = true;
|
|
||||||
fogtrap_ct = ct_find("fogtrap");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ship_ready(starting_point, u))
|
if (!ship_ready(starting_point, u)) return NULL;
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Wir suchen so lange nach neuen Richtungen, wie es geht. Diese werden
|
/* Wir suchen so lange nach neuen Richtungen, wie es geht. Diese werden
|
||||||
* dann nacheinander ausgeführt. */
|
* dann nacheinander ausgeführt. */
|
||||||
|
|
||||||
k = shipspeed(u->ship, u);
|
k = shipspeed(sh, u);
|
||||||
|
|
||||||
last_point = starting_point;
|
last_point = starting_point;
|
||||||
current_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,
|
* Durchlauf schon gesetzt (Parameter!). current_point ist die letzte gültige,
|
||||||
* befahrene Region. */
|
* 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);
|
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);
|
plane *pl = getplane(next_point);
|
||||||
if(pl && fval(pl, PFL_NOCOORDS)) {
|
if (pl && fval(pl, PFL_NOCOORDS)) {
|
||||||
ADDMSG(&u->faction->msgs, msg_message("sailforbiddendir",
|
ADDMSG(&f->msgs, msg_message("sailforbiddendir",
|
||||||
"ship direction", u->ship, dir));
|
"ship direction", sh, dir));
|
||||||
} else {
|
} else {
|
||||||
ADDMSG(&u->faction->msgs, msg_message("sailforbidden",
|
ADDMSG(&f->msgs, msg_message("sailforbidden",
|
||||||
"ship region", u->ship, next_point));
|
"ship region", sh, next_point));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !is_cursed(u->ship->attribs, C_SHIP_FLYING, 0)
|
if (!flying_ship(sh)) {
|
||||||
&& !(u->ship->type->flags & SFL_FLY)) {
|
|
||||||
if (rterrain(current_point) != T_OCEAN
|
/* storms should be the first thing we do. */
|
||||||
&& rterrain(next_point) != T_OCEAN) {
|
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);
|
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.",
|
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 {
|
} else {
|
||||||
sprintf(buf, "Die %s entdeckt, daß (%d,%d) Festland ist.",
|
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));
|
region_y(next_point,u->faction));
|
||||||
}
|
}
|
||||||
addmessage(0, u->faction, buf, MSG_MOVE, ML_WARN);
|
addmessage(0, u->faction, buf, MSG_MOVE, ML_WARN);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!(u->ship->type->flags & SFL_OPENSEA) && rterrain(next_point) == T_OCEAN) {
|
} else {
|
||||||
direction_t d;
|
if (check_takeoff(sh, current_point, next_point) == false) {
|
||||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
/* Schiff kann nicht ablegen */
|
||||||
region * rc = rconnect(next_point, d);
|
cmistake(u, findorder(u, u->thisorder), 182, MSG_MOVE);
|
||||||
if (rterrain(rc) != T_OCEAN) break;
|
break;
|
||||||
}
|
|
||||||
if (d==MAXDIRECTIONS) {
|
|
||||||
/* Schiff kann nicht aufs offene Meer */
|
|
||||||
cmistake(u, findorder(u, u->thisorder), 249, MSG_MOVE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(rterrain(current_point) != T_OCEAN
|
}
|
||||||
&& rterrain(next_point) == T_OCEAN) {
|
} else if (tnext==T_OCEAN) {
|
||||||
if(check_takeoff(u->ship, current_point, next_point) == false) {
|
/* target region is an ocean, and we're not leaving a shore */
|
||||||
/* Schiff kann nicht ablegen */
|
if (!(sh->type->flags & SFL_OPENSEA)) {
|
||||||
cmistake(u, findorder(u, u->thisorder), 182, MSG_MOVE);
|
/* ship can only stay close to shore */
|
||||||
break;
|
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) {
|
if (is_cursed(next_point->attribs, C_MAELSTROM, 0)) {
|
||||||
break;
|
if (do_maelstrom(next_point, u)==NULL) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Falls Blockade, endet die Seglerei hier */
|
} /* !flying_ship */
|
||||||
|
|
||||||
if (move_blocked(u, current_point, dir)
|
/* Falls Blockade, endet die Seglerei hier */
|
||||||
|| curse_active(get_curse(current_point->attribs, fogtrap_ct))) {
|
if (move_blocked(u, current_point, next_point)) {
|
||||||
add_message(&u->faction->msgs, new_message(u->faction,
|
ADDMSG(&u->faction->msgs, msg_message("sailfail", "ship region", sh, current_point));
|
||||||
"sailfail%h:ship%r:region", u->ship, current_point));
|
break;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(is_cursed(next_point->attribs, C_MAELSTROM, 0)) {
|
/* Falls kein Problem, eines weiter ziehen */
|
||||||
do_maelstrom(next_point, u);
|
fset(sh, SF_MOVED);
|
||||||
}
|
add_regionlist(iroute, next_point);
|
||||||
|
iroute = &(*iroute)->next;
|
||||||
|
step++;
|
||||||
|
|
||||||
stormchance = storms[month(0)] * 5 / shipspeed(u->ship, u);
|
last_point = current_point;
|
||||||
if(check_leuchtturm(next_point, NULL)) stormchance /= 3;
|
current_point = next_point;
|
||||||
#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 */
|
|
||||||
|
|
||||||
/* Falls kein Problem, eines weiter ziehen */
|
if (rterrain(current_point) != T_OCEAN && !is_cursed(sh->attribs, C_SHIP_FLYING, 0)) break;
|
||||||
fset(u->ship, SF_MOVED);
|
next_point = movewhere(current_point, u);
|
||||||
add_regionlist(iroute, next_point);
|
}
|
||||||
iroute = &(*iroute)->next;
|
|
||||||
step++;
|
|
||||||
|
|
||||||
last_point = current_point;
|
if (sh->damage>=sh->size * DAMAGE_SCALE) {
|
||||||
current_point = next_point;
|
ADDMSG(&f->msgs, msg_message("shipsink", "ship", sh));
|
||||||
|
destroy_ship(sh);
|
||||||
if (rterrain(current_point) != T_OCEAN && !is_cursed(u->ship->attribs, C_SHIP_FLYING, 0)) break;
|
sh = NULL;
|
||||||
next_point = movewhere(current_point, u);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nun enthält current_point die Region, in der das Schiff seine Runde
|
/* 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
|
* gekommen ist. Das ist nicht der Fall, wenn er von der Küste ins
|
||||||
* Inland zu segeln versuchte */
|
* Inland zu segeln versuchte */
|
||||||
|
|
||||||
if (fval(u->ship, SF_MOVED)) {
|
if (sh!=NULL && fval(sh, SF_MOVED)) {
|
||||||
ship * sh = u->ship;
|
unit * hafenmeister;
|
||||||
/* nachdem alle Richtungen abgearbeitet wurden, und alle Einheiten
|
/* nachdem alle Richtungen abgearbeitet wurden, und alle Einheiten
|
||||||
* transferiert wurden, kann der aktuelle Befehl gelöscht werden. */
|
* transferiert wurden, kann der aktuelle Befehl gelöscht werden. */
|
||||||
cycle_route(u, step);
|
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"));
|
hafenmeister = owner_buildingtyp(current_point, bt_find("harbour"));
|
||||||
if (sh && hafenmeister != NULL) {
|
if (sh && hafenmeister != NULL) {
|
||||||
item * itm;
|
item * itm;
|
||||||
assert(trans==NULL);
|
unit * u2;
|
||||||
|
boolean first = true;
|
||||||
|
item * trans = NULL;
|
||||||
|
|
||||||
for (u2 = current_point->units; u2; u2 = u2->next) {
|
for (u2 = current_point->units; u2; u2 = u2->next) {
|
||||||
if (u2->ship == u->ship &&
|
if (u2->ship == sh &&
|
||||||
!alliedunit(hafenmeister, u->faction, HELP_GUARD)) {
|
!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) {
|
for (itm=u2->items; itm; itm=itm->next) {
|
||||||
const luxury_type * ltype = resource2luxury(itm->type->rtype);
|
const luxury_type * ltype = resource2luxury(itm->type->rtype);
|
||||||
if (ltype!=NULL && itm->number>0) {
|
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);
|
st = min(itm->number, st);
|
||||||
|
|
||||||
if (st > 0) {
|
if (st > 0) {
|
||||||
|
@ -1652,14 +1643,14 @@ sail(unit * u, region * next_point, boolean move_on_land)
|
||||||
if (trans) {
|
if (trans) {
|
||||||
sprintf(buf, "%s erhielt ", hafenmeister->name);
|
sprintf(buf, "%s erhielt ", hafenmeister->name);
|
||||||
for (itm = trans; itm; itm=itm->next) {
|
for (itm = trans; itm; itm=itm->next) {
|
||||||
if (first != 1) {
|
if (!first) {
|
||||||
if (itm->next!=NULL && itm->next->next==NULL) {
|
if (itm->next!=NULL && itm->next->next==NULL) {
|
||||||
scat(" und ");
|
scat(" und ");
|
||||||
} else {
|
} else {
|
||||||
scat(", ");
|
scat(", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
first = 0;
|
first = false;
|
||||||
icat(trans->number);
|
icat(trans->number);
|
||||||
scat(" ");
|
scat(" ");
|
||||||
if (itm->number == 1) {
|
if (itm->number == 1) {
|
||||||
|
@ -2029,7 +2020,7 @@ destroy_damaged_ships(void)
|
||||||
for(sh=r->ships;sh;) {
|
for(sh=r->ships;sh;) {
|
||||||
shn = sh->next;
|
shn = sh->next;
|
||||||
if (sh->damage>=sh->size * DAMAGE_SCALE) {
|
if (sh->damage>=sh->size * DAMAGE_SCALE) {
|
||||||
destroy_ship(sh, r);
|
destroy_ship(sh);
|
||||||
}
|
}
|
||||||
sh = shn;
|
sh = shn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,8 +159,6 @@ typdata_t typdata[] = {
|
||||||
(find_fun)unit_find,
|
(find_fun)unit_find,
|
||||||
(desc_fun)unitname,
|
(desc_fun)unitname,
|
||||||
(attrib_fun)unit_attribs,
|
(attrib_fun)unit_attribs,
|
||||||
(destroy_fun)destroy_unit,
|
|
||||||
(deref_fun)unit_deref,
|
|
||||||
(set_fun)unit_set,
|
(set_fun)unit_set,
|
||||||
},
|
},
|
||||||
/* TYP_REGION */ {
|
/* TYP_REGION */ {
|
||||||
|
@ -168,8 +166,6 @@ typdata_t typdata[] = {
|
||||||
(find_fun)region_find,
|
(find_fun)region_find,
|
||||||
(desc_fun)regionid,
|
(desc_fun)regionid,
|
||||||
(attrib_fun)region_attribs,
|
(attrib_fun)region_attribs,
|
||||||
(destroy_fun)cannot_destroy,
|
|
||||||
(deref_fun)region_deref,
|
|
||||||
(set_fun)region_set,
|
(set_fun)region_set,
|
||||||
},
|
},
|
||||||
/* TYP_BUILDING */ {
|
/* TYP_BUILDING */ {
|
||||||
|
@ -177,8 +173,6 @@ typdata_t typdata[] = {
|
||||||
(find_fun)building_find,
|
(find_fun)building_find,
|
||||||
(desc_fun)buildingname,
|
(desc_fun)buildingname,
|
||||||
(attrib_fun)building_attribs,
|
(attrib_fun)building_attribs,
|
||||||
(destroy_fun)destroy_building,
|
|
||||||
(deref_fun)building_deref,
|
|
||||||
(set_fun)building_set,
|
(set_fun)building_set,
|
||||||
},
|
},
|
||||||
/* TYP_SHIP */ {
|
/* TYP_SHIP */ {
|
||||||
|
@ -186,8 +180,6 @@ typdata_t typdata[] = {
|
||||||
(find_fun)ship_find,
|
(find_fun)ship_find,
|
||||||
(desc_fun)shipname,
|
(desc_fun)shipname,
|
||||||
(attrib_fun)ship_attribs,
|
(attrib_fun)ship_attribs,
|
||||||
(destroy_fun)destroy_ship,
|
|
||||||
(deref_fun)ship_deref,
|
|
||||||
(set_fun)ship_set,
|
(set_fun)ship_set,
|
||||||
},
|
},
|
||||||
/* TYP_FACTION */ {
|
/* TYP_FACTION */ {
|
||||||
|
@ -195,8 +187,6 @@ typdata_t typdata[] = {
|
||||||
(find_fun)faction_find,
|
(find_fun)faction_find,
|
||||||
(desc_fun)notimplemented_desc,
|
(desc_fun)notimplemented_desc,
|
||||||
(attrib_fun)faction_attribs,
|
(attrib_fun)faction_attribs,
|
||||||
(destroy_fun)cannot_destroy,
|
|
||||||
(deref_fun)faction_deref,
|
|
||||||
(set_fun)faction_set,
|
(set_fun)faction_set,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -46,8 +46,6 @@ typedef obj_ID (*ID_fun)(void *obj);
|
||||||
typedef void *(*find_fun)(obj_ID id);
|
typedef void *(*find_fun)(obj_ID id);
|
||||||
typedef char *(*desc_fun)(void *obj);
|
typedef char *(*desc_fun)(void *obj);
|
||||||
typedef attrib **(*attrib_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 */
|
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 */
|
find_fun find; /* liefert struct unit* zu obj_ID */
|
||||||
desc_fun getname; /* unitname() */
|
desc_fun getname; /* unitname() */
|
||||||
attrib_fun getattribs; /* liefert &u->attribs */
|
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* */
|
set_fun ppset; /* setzt *(struct unit **) zu struct unit* */
|
||||||
} typdata_t;
|
} typdata_t;
|
||||||
|
|
||||||
|
|
|
@ -183,20 +183,20 @@ new_ship(const ship_type * stype, region * r)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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) {
|
||||||
while (u) {
|
if (u->ship == sh) {
|
||||||
if (u->ship == s) {
|
leave_ship(u);
|
||||||
leave_ship(u);
|
}
|
||||||
}
|
u = u->next;
|
||||||
u = u->next;
|
}
|
||||||
}
|
sunhash(sh);
|
||||||
sunhash(s);
|
choplist(&r->ships, sh);
|
||||||
choplist(&r->ships, s);
|
handle_event(&sh->attribs, "destroy", sh);
|
||||||
handle_event(&s->attribs, "destroy", s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
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 register_ships(void);
|
||||||
|
|
||||||
|
extern void destroy_ship(struct ship * s);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1280,7 +1280,7 @@ showunits(region * r)
|
||||||
modified = 1;
|
modified = 1;
|
||||||
for (x = shipregion->units; x; x = x->next)
|
for (x = shipregion->units; x; x = x->next)
|
||||||
leave(shipregion, x);
|
leave(shipregion, x);
|
||||||
destroy_ship(clipship, shipregion);
|
destroy_ship(clipship);
|
||||||
clipship = 0;
|
clipship = 0;
|
||||||
shipregion = 0;
|
shipregion = 0;
|
||||||
for (pline = 0, tmp = eh; tmp != pointer; tmp = tmp->next)
|
for (pline = 0, tmp = eh; tmp != pointer; tmp = tmp->next)
|
||||||
|
|
Loading…
Reference in New Issue