Schiffe können, wenn CHECK_OVERLOAD_ON_ENTER defined ist, nicht betreten werden wenn das die Kapazität sprengt.

This commit is contained in:
Enno Rehling 2002-11-25 15:30:51 +00:00
parent 69dcc7c17b
commit 76b0371100
11 changed files with 130 additions and 104 deletions

View File

@ -837,7 +837,7 @@ dogive(region * r, unit * u, strlist * S, boolean liefere, int mode)
cmistake(u, S->s, notfound_error, MSG_COMMERCE); cmistake(u, S->s, notfound_error, MSG_COMMERCE);
return; return;
} }
if (u == u2){ if (u == u2) {
cmistake(u, S->s, 8, MSG_COMMERCE); cmistake(u, S->s, 8, MSG_COMMERCE);
return; return;
} }

View File

@ -127,7 +127,7 @@ can_contact(const region * r, const unit * u, const unit * u2)
static void static void
set_contact(const region * r, unit * u, char try) set_contact(const region * r, unit * u, boolean try)
{ {
/* unit u kontaktiert unit u2. Dies setzt den contact einfach auf 1 - /* unit u kontaktiert unit u2. Dies setzt den contact einfach auf 1 -
@ -1027,10 +1027,10 @@ mayenter(region * r, unit * u, building * b)
} }
static int static int
mayboard(region * r, unit * u, ship * sh) mayboard(const unit * u, const ship * sh)
{ {
unit *u2; unit *u2;
u2 = shipowner(r, sh); u2 = shipowner(sh->region, sh);
return (!u2 return (!u2
|| ucontact(u2, u) || ucontact(u2, u)
@ -1091,15 +1091,57 @@ do_leave(void)
} }
} }
static boolean
entership(unit * u, ship * sh, const char * cmd, boolean lasttry)
{
/* Muß abgefangen werden, sonst könnten Schwimmer an
* Bord von Schiffen an Land gelangen. */
if( !fval(u->race, RCF_WALK) &&
!fval(u->race, RCF_FLY)) {
cmistake(u, cmd, 233, MSG_MOVE);
return false;
}
if (!sh) {
if (lasttry) cmistake(u, cmd, 20, MSG_MOVE);
return false;
}
if (!mayboard(u, sh)) {
if (lasttry) cmistake(u, cmd, 34, MSG_MOVE);
return false;
}
#ifdef CHECK_OVERLOAD_ON_ENTER
{
int sweight, scabins;
getshipweight(sh, &sweight, &scabins);
sweight += weight(u);
scabins += u->number;
if (sweight > shipcapacity(sh) || scabins > sh->type->cabins) {
if (lasttry) cmistake(u, cmd, 34, MSG_MOVE);
return false;
}
}
#endif
leave(u->region, u);
u->ship = sh;
if (shipowner(u->region, sh) == 0) {
fset(u, FL_OWNER);
}
return true;
}
void void
do_misc(char try) do_misc(boolean lasttry)
{ {
region *r; region *r;
strlist *S, *Snext; strlist *S, *Snext;
ship *sh; ship *sh;
building *b; building *b;
/* try: Fehler nur im zweiten Versuch melden. Sonst konfus. */ /* lasttry: Fehler nur im zweiten Versuch melden. Sonst konfus. */
for (r = regions; r; r = r->next) { for (r = regions; r; r = r->next) {
unit *u; unit *u;
@ -1108,7 +1150,7 @@ do_misc(char try)
for (S = u->orders; S; S = S->next) { for (S = u->orders; S; S = S->next) {
switch (igetkeyword(S->s, u->faction->locale)) { switch (igetkeyword(S->s, u->faction->locale)) {
case K_CONTACT: case K_CONTACT:
set_contact(r, u, try); set_contact(r, u, lasttry);
break; break;
} }
} }
@ -1129,7 +1171,7 @@ do_misc(char try)
* auf dem Ozean */ * auf dem Ozean */
if( !fval(u->race, RCF_WALK) && !fval(u->race, RCF_FLY)) { if( !fval(u->race, RCF_WALK) && !fval(u->race, RCF_FLY)) {
if (rterrain(r) != T_OCEAN){ if (rterrain(r) != T_OCEAN){
if (try) cmistake(u, S->s, 232, MSG_MOVE); if (lasttry) cmistake(u, S->s, 232, MSG_MOVE);
break; break;
} }
} }
@ -1137,17 +1179,17 @@ do_misc(char try)
b = getbuilding(r); b = getbuilding(r);
if (!b) { if (!b) {
if(try) cmistake(u, S->s, 6, MSG_MOVE); if(lasttry) cmistake(u, S->s, 6, MSG_MOVE);
break; break;
} }
/* Gebäude auf dem Ozean sollte man betreten dürfen /* Gebäude auf dem Ozean sollte man betreten dürfen
if(rterrain(r) == T_OCEAN) { if(rterrain(r) == T_OCEAN) {
if (try) cmistake(u, S->s, 297, MSG_MOVE); if (lasttry) cmistake(u, S->s, 297, MSG_MOVE);
break; break;
} }
*/ */
if (!mayenter(r, u, b)) { if (!mayenter(r, u, b)) {
if(try) { if(lasttry) {
sprintf(buf, "Der Eintritt in %s wurde verwehrt", sprintf(buf, "Der Eintritt in %s wurde verwehrt",
buildingname(b)); buildingname(b));
mistake(u, S->s, buf, MSG_MOVE); mistake(u, S->s, buf, MSG_MOVE);
@ -1155,7 +1197,7 @@ do_misc(char try)
break; break;
} }
if (!slipthru(r, u, b)) { if (!slipthru(r, u, b)) {
if(try) { if(lasttry) {
sprintf(buf, "%s wird belagert", buildingname(b)); sprintf(buf, "%s wird belagert", buildingname(b));
mistake(u, S->s, buf, MSG_MOVE); mistake(u, S->s, buf, MSG_MOVE);
} }
@ -1175,44 +1217,17 @@ do_misc(char try)
break; break;
case P_SHIP: case P_SHIP:
/* Muß abgefangen werden, sonst könnten Schwimmer an
* Bord von Schiffen an Land gelangen. */
if( !fval(u->race, RCF_WALK) &&
!fval(u->race, RCF_FLY)) {
cmistake(u, S->s, 233, MSG_MOVE);
S = Snext;
continue;
}
sh = getship(r); sh = getship(r);
if (entership(u, sh, S->s, lasttry)) {
if (!sh) { /* Wenn wir hier angekommen sind, war der Befehl
if(try) cmistake(u, S->s, 20, MSG_MOVE); * erfolgreich und wir löschen ihn, damit er im
break; * zweiten Versuch nicht nochmal ausgeführt wird. */
} removelist(&u->orders, S);
if (!mayboard(r, u, sh)) {
if(try) cmistake(u, S->s, 34, MSG_MOVE);
break;
}
/* Wenn wir hier angekommen sind, war der Befehl
* erfolgreich und wir löschen ihn, damit er im
* zweiten Versuch nicht nochmal ausgeführt wird. */
removelist(&u->orders, S);
leave(r, u);
u->ship = sh;
/* Wozu sollte das gut sein? */
/* freset(u, FL_LEFTSHIP); */
if (shipowner(r, sh) == 0) {
fset(u, FL_OWNER);
} }
break; break;
default: default:
if(try) cmistake(u, S->s, 79, MSG_MOVE); if(lasttry) cmistake(u, S->s, 79, MSG_MOVE);
} }
} }

View File

@ -72,7 +72,7 @@ struct ship *getship(const struct region * r);
void remove_contacts(void); void remove_contacts(void);
void do_leave(void); void do_leave(void);
void do_misc(char try); void do_misc(boolean try);
void reportevent(struct region * r, char *s); void reportevent(struct region * r, char *s);

View File

@ -178,11 +178,11 @@ ct_find(const char *c)
if (!strncasecmp(c, ctl->type->cname, k)) return ctl->type; if (!strncasecmp(c, ctl->type->cname, k)) return ctl->type;
ctl = ctl->next; ctl = ctl->next;
} }
/* disable this assert to be able to remoce certain curses from the game /* disable this assert to be able to remoce certain curses from the game
* make sure that all locations using that curse can deal with a NULL * make sure that all locations using that curse can deal with a NULL
* return value. * return value.
*/ */
assert(!"unknown cursetype"); assert(!"unknown cursetype");
return NULL; return NULL;
} }
@ -409,7 +409,7 @@ get_cursedmen(unit *u, curse *c)
curse_unit * cc = (curse_unit*)c->data; curse_unit * cc = (curse_unit*)c->data;
cursedmen = cc->cursedmen; cursedmen = cc->cursedmen;
} }
return min(u->number, cursedmen); return min(u->number, cursedmen);
} }
@ -512,7 +512,7 @@ create_curse(unit *magician, attrib **ap, const curse_type *ct, int vigour,
return NULL; return NULL;
} }
assert(c==NULL || ct==c->type); assert(c==NULL || ct==c->type);
/* es gibt schon eins diese Typs */ /* es gibt schon eins diese Typs */
if (c && ct->mergeflags != NO_MERGE) { if (c && ct->mergeflags != NO_MERGE) {
if(ct->mergeflags & M_DURATION){ if(ct->mergeflags & M_DURATION){
@ -673,17 +673,17 @@ is_cursed_with(attrib *ap, curse *c)
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
/* cursedata */ /* cursedata */
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
/* /*
* typedef struct curse_type { * typedef struct curse_type {
* const char *cname; (Name der Zauberwirkung, Identifizierung des curse) * const char *cname; (Name der Zauberwirkung, Identifizierung des curse)
* int typ; * int typ;
* spread_t spread; * spread_t spread;
* unsigned int mergeflags; * unsigned int mergeflags;
* const char *info_str; Wirkung des curse, wird bei einer gelungenen Zauberanalyse angezeigt * const char *info_str; Wirkung des curse, wird bei einer gelungenen Zauberanalyse angezeigt
* int (*curseinfo)(const struct locale*, const void*, int, curse*, int); * int (*curseinfo)(const struct locale*, const void*, int, curse*, int);
* void (*change_vigour)(curse*, int); * void (*change_vigour)(curse*, int);
* int (*read)(FILE * F, curse * c); * int (*read)(FILE * F, curse * c);
* int (*write)(FILE * F, const curse * c); * int (*write)(FILE * F, const curse * c);
* } curse_type; * } curse_type;
*/ */
@ -757,7 +757,7 @@ static const char * oldnames[MAXCURSE] = {
"skillmod" "skillmod"
}; };
const char * const char *
oldcursename(int id) oldcursename(int id)
{ {
return oldnames[id]; return oldnames[id];

View File

@ -85,7 +85,7 @@ FILE *updatelog;
const struct race * new_race[MAXRACES]; const struct race * new_race[MAXRACES];
boolean sqlpatch = false; boolean sqlpatch = false;
race_t race_t
old_race(const struct race * rc) old_race(const struct race * rc)
{ {
race_t i; race_t i;
@ -361,28 +361,6 @@ count_skill(faction * f, skill_t sk)
return n; return n;
} }
int
shipcapacity (const ship * sh)
{
int i;
/* sonst ist construction:: size nicht ship_type::maxsize */
assert(!sh->type->construction || sh->type->construction->improvement==NULL);
if (sh->type->construction && sh->size!=sh->type->construction->maxsize)
return 0;
#ifdef SHIPDAMAGE
i = ((sh->size * DAMAGE_SCALE - sh->damage) / DAMAGE_SCALE)
* sh->type->cargo / sh->size;
i += ((sh->size * DAMAGE_SCALE - sh->damage) % DAMAGE_SCALE)
* sh->type->cargo / (sh->size*DAMAGE_SCALE);
#else
i = sh->type->cargo;
#endif
return i;
}
int quiet = 0; int quiet = 0;
FILE *debug; FILE *debug;
@ -393,9 +371,9 @@ shipspeed (ship * sh, const unit * u)
int k = sh->type->range; int k = sh->type->range;
static const curse_type * stormwind_ct, * nodrift_ct; static const curse_type * stormwind_ct, * nodrift_ct;
static boolean init; static boolean init;
if (!init) { if (!init) {
init = true; init = true;
stormwind_ct = ct_find("stormwind"); stormwind_ct = ct_find("stormwind");
nodrift_ct = ct_find("nodrift"); nodrift_ct = ct_find("nodrift");
} }
@ -739,7 +717,7 @@ unit_has_cursed_item(unit *u)
return false; return false;
} }
static int static int
autoalliance(const plane * pl, const faction * sf, const faction * f2) autoalliance(const plane * pl, const faction * sf, const faction * f2)
{ {
int mode = 0; int mode = 0;
@ -773,7 +751,7 @@ alliance(const ally * sf, const faction * f, int mode)
return nmode; return nmode;
} }
int int
alliedgroup(const struct plane * pl, const struct faction * f, const struct ally * sf, const struct faction * f2, int mode) alliedgroup(const struct plane * pl, const struct faction * f, const struct ally * sf, const struct faction * f2, int mode)
{ {
return alliance(sf, f2, mode) | (mode & autoalliance(pl, f, f2)); return alliance(sf, f2, mode) | (mode & autoalliance(pl, f, f2));
@ -841,7 +819,7 @@ cansee(const faction * f, const region * r, const unit * u, int modifier)
} else { } else {
return false; return false;
} }
} }
n = eff_stealth(u, r) - modifier; n = eff_stealth(u, r) - modifier;
for (u2 = r->units; u2; u2 = u2->next) { for (u2 = r->units; u2; u2 = u2->next) {
if (u2->faction == f) { if (u2->faction == f) {
@ -1175,7 +1153,7 @@ get_lnames(const struct locale * lang)
return lnames; return lnames;
} }
const struct race * const struct race *
findrace(const char * s, const struct locale * lang) findrace(const char * s, const struct locale * lang)
{ {
struct lstr * lnames = get_lnames(lang); struct lstr * lnames = get_lnames(lang);
@ -2105,7 +2083,7 @@ const char * localenames[] = {
static int read_xml(const char * filename, struct xml_stack *stack); static int read_xml(const char * filename, struct xml_stack *stack);
static int static int
parse_tagbegin(struct xml_stack *stack) parse_tagbegin(struct xml_stack *stack)
{ {
const xml_tag * tag = stack->tag; const xml_tag * tag = stack->tag;
@ -2171,7 +2149,7 @@ int
init_data(const char * filename) init_data(const char * filename)
{ {
int l; int l;
xml_register(&xml_eressea, "eressea", 0); xml_register(&xml_eressea, "eressea", 0);
xml_register(&xml_eressea, "eressea include", XML_CB_IGNORE); xml_register(&xml_eressea, "eressea include", XML_CB_IGNORE);
@ -2417,8 +2395,8 @@ remove_empty_factions(boolean writedropouts)
*fp = f->next; *fp = f->next;
/* stripfaction(f); /* stripfaction(f);
* free(f); * free(f);
* Wir können die nicht löschen, weil sie evtl. noch in attributen * Wir können die nicht löschen, weil sie evtl. noch in attributen
* referenziert sind ! */ * referenziert sind ! */
} }
else fp = &(*fp)->next; else fp = &(*fp)->next;
@ -2727,10 +2705,10 @@ wage(const region *r, const unit *u, boolean img)
attrib *a; attrib *a;
static const curse_type * drought_ct, * blessedharvest_ct; static const curse_type * drought_ct, * blessedharvest_ct;
static boolean init; static boolean init;
if (!init) { if (!init) {
init = true; init = true;
drought_ct = ct_find("drought"); drought_ct = ct_find("drought");
blessedharvest_ct = ct_find("blessedharvest"); blessedharvest_ct = ct_find("blessedharvest");
} }
if (b) esize = buildingeffsize(b, img); if (b) esize = buildingeffsize(b, img);

View File

@ -735,7 +735,6 @@ enum {
#define MAXSPEED 21 #define MAXSPEED 21
int shipcapacity(const struct ship * sh);
int shipspeed(struct ship * sh, const struct unit * u); int shipspeed(struct ship * sh, const struct unit * u);
/* MAXSPEED setzt die groesse fuer den Array, der die Kuesten Beschreibungen /* MAXSPEED setzt die groesse fuer den Array, der die Kuesten Beschreibungen

View File

@ -355,18 +355,13 @@ boolean
cansail(const region * r, ship * sh) cansail(const region * r, ship * sh)
{ {
int n = 0, p = 0; int n = 0, p = 0;
unit *u;
/* sonst ist construction:: size nicht ship_type::maxsize */ /* sonst ist construction:: size nicht ship_type::maxsize */
assert(!sh->type->construction || sh->type->construction->improvement==NULL); assert(!sh->type->construction || sh->type->construction->improvement==NULL);
if (sh->type->construction && sh->size!=sh->type->construction->maxsize) if (sh->type->construction && sh->size!=sh->type->construction->maxsize)
return false; return false;
for (u = r->units; u; u = u->next) getshipweight(sh, &n, &p);
if (u->ship == sh) {
n += weight(u);
p += u->number;
}
if( is_cursed(sh->attribs, C_SHIP_FLYING, 0) ) { if( is_cursed(sh->attribs, C_SHIP_FLYING, 0) ) {
if (sh->type->cargo>500*100) if (sh->type->cargo>500*100)

View File

@ -798,7 +798,7 @@ read_ugroups(FILE *file)
#endif #endif
#ifdef ALLIANCES #ifdef ALLIANCES
void void
read_alliances(FILE * F) read_alliances(FILE * F)
{ {
char pbuf[32]; char pbuf[32];

View File

@ -195,6 +195,41 @@ shipname(const ship * sh)
return buf; return buf;
} }
int
shipcapacity (const ship * sh)
{
int i;
/* sonst ist construction:: size nicht ship_type::maxsize */
assert(!sh->type->construction || sh->type->construction->improvement==NULL);
if (sh->type->construction && sh->size!=sh->type->construction->maxsize)
return 0;
#ifdef SHIPDAMAGE
i = ((sh->size * DAMAGE_SCALE - sh->damage) / DAMAGE_SCALE)
* sh->type->cargo / sh->size;
i += ((sh->size * DAMAGE_SCALE - sh->damage) % DAMAGE_SCALE)
* sh->type->cargo / (sh->size*DAMAGE_SCALE);
#else
i = sh->type->cargo;
#endif
return i;
}
void
getshipweight(const ship * sh, int *sweight, int *scabins)
{
unit * u;
*sweight = 0;
*scabins = 0;
for (u = sh->region->units; u; u = u->next)
if (u->ship == sh) {
*sweight += weight(u);
*scabins += u->number;
}
}
unit * unit *
shipowner(const region * r, const ship * sh) shipowner(const region * r, const ship * sh)
{ {

View File

@ -81,6 +81,8 @@ typedef struct ship {
extern void damage_ship(ship *sh, double percent); extern void damage_ship(ship *sh, double percent);
extern struct unit *captain(ship *sh, struct region *r); extern struct unit *captain(ship *sh, struct region *r);
extern struct unit *shipowner(const struct region * r, const struct ship * sh); extern struct unit *shipowner(const struct region * r, const struct ship * sh);
extern int shipcapacity(const struct ship * sh);
extern void getshipweight(const struct ship * sh, int *weight, int *cabins);
extern ship *new_ship(const struct ship_type * stype, struct region * r); extern ship *new_ship(const struct ship_type * stype, struct region * r);
extern const char *shipname(const struct ship * sh); extern const char *shipname(const struct ship * sh);

View File

@ -6,7 +6,7 @@
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de> | | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
+-------------------+ Stefan Reich <reich@halbling.de> +-------------------+ Stefan Reich <reich@halbling.de>
This program may not be used, modified or distributed This program may not be used, modified or distributed
without prior permission by the authors of Eressea. without prior permission by the authors of Eressea.
*/ */
@ -41,6 +41,8 @@
#define TEACHDIFFERENCE 2 #define TEACHDIFFERENCE 2
#define GIVERESTRICTION 3 #define GIVERESTRICTION 3
#undef CHECK_OVERLOAD_ON_ENTER
#define MUSEUM_MODULE #define MUSEUM_MODULE
#define ARENA_MODULE #define ARENA_MODULE