From 28021ed6a65ab5e3f1281d66701e9230ad2bc11a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 31 May 2004 16:21:03 +0000 Subject: [PATCH] =?UTF-8?q?http://eressea.upb.de/mantis/bug=5Fview=5Fpage.?= =?UTF-8?q?php=3Fbug=5Fid=3D0000110=20-=20Schiffe=20treiben=20nicht=20ab.?= =?UTF-8?q?=20=20=20Movement-Routine=20sail()=20=C3=BCbersichtlicher=20ges?= =?UTF-8?q?taltet,=20und=20Abtreiben=20neu=20implementiert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/gamecode/laws.c | 2 +- src/common/gamecode/randenc.c | 6 +- src/common/gamecode/spy.c | 23 ++- src/common/kernel/battle.c | 4 +- src/common/kernel/build.c | 2 +- src/common/kernel/build.h | 2 - src/common/kernel/eressea.c | 29 +-- src/common/kernel/eressea.h | 2 +- src/common/kernel/movement.c | 367 +++++++++++++++++----------------- src/common/kernel/objtypes.c | 10 - src/common/kernel/objtypes.h | 4 - src/common/kernel/ship.c | 24 +-- src/common/kernel/ship.h | 2 + src/mapper/map_units.c | 2 +- 14 files changed, 232 insertions(+), 247 deletions(-) diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index c0960c1b0..4b956c977 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -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); } diff --git a/src/common/gamecode/randenc.c b/src/common/gamecode/randenc.c index 1ff4767da..0341dd79e 100644 --- a/src/common/gamecode/randenc.c +++ b/src/common/gamecode/randenc.c @@ -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; } diff --git a/src/common/gamecode/spy.c b/src/common/gamecode/spy.c index ceda5d5ec..0a3be05e1 100644 --- a/src/common/gamecode/spy.c +++ b/src/common/gamecode/spy.c @@ -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); } diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index cb66f5145..308c948ce 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -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; } diff --git a/src/common/kernel/build.c b/src/common/kernel/build.c index 6cc66b475..cb97828dd 100644 --- a/src/common/kernel/build.c +++ b/src/common/kernel/build.c @@ -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; diff --git a/src/common/kernel/build.h b/src/common/kernel/build.h index 79e037c76..c42fe6155 100644 --- a/src/common/kernel/build.h +++ b/src/common/kernel/build.h @@ -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); diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index 8e3e74ce7..3bd6ef07d 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -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 (dirtype->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 diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index bee192877..de8a58dd7 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -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); diff --git a/src/common/kernel/movement.c b/src/common/kernel/movement.c index 89d657013..26d868712 100644 --- a/src/common/kernel/movement.c +++ b/src/common/kernel/movement.c @@ -18,8 +18,6 @@ * permission from the authors. */ -#define SAFE_COASTS /* Schiffe an der Küste treiben nicht ab */ - #include #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 (dirship), 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; } diff --git a/src/common/kernel/objtypes.c b/src/common/kernel/objtypes.c index 05a89dacd..5b88824b8 100644 --- a/src/common/kernel/objtypes.c +++ b/src/common/kernel/objtypes.c @@ -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, }, }; diff --git a/src/common/kernel/objtypes.h b/src/common/kernel/objtypes.h index 415ba406a..2c1ee1cb3 100644 --- a/src/common/kernel/objtypes.h +++ b/src/common/kernel/objtypes.h @@ -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; diff --git a/src/common/kernel/ship.c b/src/common/kernel/ship.c index 5b44905d9..8e90faf9c 100644 --- a/src/common/kernel/ship.c +++ b/src/common/kernel/ship.c @@ -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 * diff --git a/src/common/kernel/ship.h b/src/common/kernel/ship.h index 8f80bfbbb..f3061c24e 100644 --- a/src/common/kernel/ship.h +++ b/src/common/kernel/ship.h @@ -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 diff --git a/src/mapper/map_units.c b/src/mapper/map_units.c index f505d5401..dcf7a3aaa 100644 --- a/src/mapper/map_units.c +++ b/src/mapper/map_units.c @@ -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)