diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index cccef8bec..8e24595b3 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -718,7 +718,7 @@ enum { D_WEST, MAXDIRECTIONS, D_PAUSE, - D_SPECIAL, + D_SPECIAL, NODIRECTION = (direction_t) - 1 }; diff --git a/src/common/kernel/movement.c b/src/common/kernel/movement.c index 621da349e..da196ce2f 100644 --- a/src/common/kernel/movement.c +++ b/src/common/kernel/movement.c @@ -1037,10 +1037,87 @@ cap_route(region * r, region_list * route, region_list * route_end, int speed) return iroute; } +static boolean +is_disoriented(unit *u) +{ + static boolean init = false; + static const curse_type * shipconf_ct, * regconf_ct; + if (!init) { + init = true; + regconf_ct = ct_find("disorientationzone"); + shipconf_ct = ct_find("shipdisorientation"); + } + if (u->ship && curse_active(get_curse(u->ship->attribs, shipconf_ct))) + return true; + + if (curse_active(get_curse(u->region->attribs, regconf_ct))) + return true; + + return false; +} + +/** ships regain their orientation + * Das Schiff bekommt seine Orientierung zurück, wenn es: + * a) An Land treibt, + * b) Glück hat, oder + * c) in einer Region mit einem nicht verwirrten alliierten + * Schiff steht. + */ +static void +regain_orientation(region * r) +{ + ship *sh; + static int thismonth = -1; + static const curse_type * shipconf_ct, * regconf_ct; + static boolean init = false; + + if (!init) { + init = true; + regconf_ct = ct_find("disorientationzone"); + shipconf_ct = ct_find("shipdisorientation"); + } + + if (thismonth<0) thismonth = get_gamedate(turn, 0)->month; + + for (sh = r->ships; sh; sh = sh->next) { + unit * u, *cap; + curse * c = get_curse(sh->attribs, shipconf_ct); + if (c==NULL) continue; + + cap = shipowner(sh); + if (cap==NULL) continue; + + if (!fval(r->terrain, SEA_REGION) || rand() % 10 >= storms[thismonth]) { + remove_curse(&sh->attribs, c); + ADDMSG(&cap->faction->msgs, msg_message("shipnoconf", "ship", sh)); + continue; + } + + for (u=r->units; u; u=u->next) { + /* we get help if u helps the faction of cap and isn't disoriented */ + if (u != cap && alliedunit(u, cap->faction, HELP_GUARD) && !is_disoriented(u)) { + remove_curse(&sh->attribs, c); + ADDMSG(&cap->faction->msgs, msg_message("shipnoconf", "ship", sh)); + break; + } + } + } +} + static region * next_region(unit * u, region * current, region * next) { - border * b = get_borders(current, next); + border * b; + + if (is_disoriented(u)) { + direction_t d = reldirection(current, next); + if (dtype->move) { region * rto = b->type->move(b, u, current, next, true); @@ -1064,7 +1141,7 @@ reroute(unit * u, region_list * route, region_list * route_end) while (route!=route_end) { region * next = next_region(u, current, route->data); if (next!=route->data) break; - route=route->next; + route = route->next; } return route; } @@ -2203,67 +2280,6 @@ destroy_damaged_ships(void) } } -#ifdef TODO /* Wenn Feature ausgearbeitet */ - -static boolean -is_disorientated(unit *u) -{ - static boolean init = false; - static const curse_type * shipconf_ct, * regconf_ct; - if (!init) { - init = true; - regconf_ct = ct_find("disorientationzone"); - shipconf_ct = ct_find("shipdisorientation"); - } - if (u->ship && curse_active(get_curse(u->ship->attribs, shipconf_ct))) - return true; - - if (curse_active(get_curse(u->region->attribs, regconf_ct))) - return true; - - return false; -} - -void -regain_orientation(region * r) -{ - ship *sh; - curse *c; - unit *u, *cap; - static int thismonth = get_gamedate(turn, 0)->month; - - for (sh = r->ships; sh; sh = sh->next) { - c = get_curse(sh->attribs, C_DISORIENTATION, 0); - if(!c) continue; - - /* Das Schiff bekommt seine Orientierung zurück, wenn es: - * a) An Land treibt. - * b) Glück hat. - * c) In einer Region mit einem nicht verwirrten alliierten - * Schiff steht. - */ - - cap = shipowner(r, sh); - - if (r->terrain != T_OCEAN || rand() % 10 >= storms[thismonth]) { - remove_curse(&sh->attribs, C_DISORIENTATION, 0); - ADDMSG(&cap->faction->msgs, msg_message("shipnoconf", "ship", sh)); - continue; - } - - for(u=r->units;u;u=u->next) { - if(u != cap - && allied(cap, u->faction, HELP_GUARD) - && is_disorientated(u) == false) { - remove_curse(&sh->attribs, C_DISORIENTATION, 0); - ADDMSG(&cap->faction->msgs, msg_message("shipnoconf", "ship", sh)); - break; - } - } - } -} -#endif - /* Bewegung, Verfolgung, Piraterie */ /** ships that folow other ships @@ -2375,6 +2391,11 @@ movement(void) unit ** up = &r->units; boolean repeat = false; + if (ships==0) { + /* first thing before moving: restore orientation if we can */ + regain_orientation(r); + } + while (*up) { unit *u = *up; keyword_t kword = get_keyword(u->thisorder); diff --git a/src/res/eressea/items.xml b/src/res/eressea/items.xml index ca04dea9c..90e49f2da 100644 --- a/src/res/eressea/items.xml +++ b/src/res/eressea/items.xml @@ -1,10 +1,18 @@ - + - + + + + + + + + + diff --git a/src/res/eressea/races.xml b/src/res/eressea/races.xml index 5faa77c2b..1fd8d7591 100644 --- a/src/res/eressea/races.xml +++ b/src/res/eressea/races.xml @@ -1,9 +1,10 @@ + + fly="no" walk="no" teach="no" getitem="yes"> diff --git a/src/res/races.xml b/src/res/races.xml index d4eae19f6..52954989d 100644 --- a/src/res/races.xml +++ b/src/res/races.xml @@ -1,4 +1,4 @@ - +