diff -Nur -Xfreecivdiff.ignore freeciv-cvs/ai/aiunit.c freeciv-patched/ai/aiunit.c --- freeciv-cvs/ai/aiunit.c 2003-07-21 13:58:22.000000000 +0100 +++ freeciv-patched/ai/aiunit.c 2003-07-24 17:03:26.000000000 +0100 @@ -370,18 +370,29 @@ Is there a chance that a trireme would be lost, given information that the player actually has. ***************************************************************/ -static bool is_likely_trireme_loss(struct player *pplayer, int x, int y) +static bool is_likely_ship_loss(struct unit *punit, int x, int y) { + struct player *pplayer = unit_owner(punit); + /* * If we are in a city or next to land, we have no chance of losing * the ship. To make this really useful for ai planning purposes, we'd * need to confirm that we can exist/move at the x,y location we are given. */ - if ((likely_ocean(x, y, pplayer) < 50) || - is_likely_coastline(x, y, pplayer) || - (player_owns_active_wonder(pplayer, B_LIGHTHOUSE))) { + if (!unit_flag(punit, F_TRIREME) || likely_ocean(x, y, pplayer) < 50 + || is_likely_coastline(x, y, pplayer)) { return FALSE; } else { + struct eff_iter iter; + struct map_position mp; + mp.x = x; + mp.y = y; + eff_iterator_unit_init(&iter, punit->type, unit_owner(punit), &mp); + while (eff_iterator_next(&iter)) { + if (iter.imeff->type == EFT_NO_SINK_DEEP) { + return FALSE; + } + } return TRUE; } } @@ -424,8 +435,7 @@ * is a city on the tile, or if the tile is not accessible, or if the * tile is on a different continent, or if we're a barbarian and * the tile has a hut, don't go there. */ - if ((unit_flag(punit, F_TRIREME) && - is_likely_trireme_loss(pplayer, x, y)) + if (is_likely_ship_loss(punit, x, y) || map_get_city(x, y) || map_get_continent(x, y) != continent || (is_barbarian(pplayer) && map_has_special(x, y, S_HUT))) { diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/aicore/pf_tools.c freeciv-patched/common/aicore/pf_tools.c --- freeciv-cvs/common/aicore/pf_tools.c 2003-07-22 16:29:32.000000000 +0100 +++ freeciv-patched/common/aicore/pf_tools.c 2003-07-24 17:03:26.000000000 +0100 @@ -322,8 +322,7 @@ parameter->get_zoc = NULL; } - if (unit_flag(punit, F_TRIREME) - && base_trireme_loss_pct(unit_owner(punit)) > 0) { + if (base_ship_loss_pct(punit, NULL) > 0) { parameter->turn_mode = TM_WORST_TIME; parameter->is_pos_dangerous = trireme_is_pos_dangerous; } else { @@ -363,8 +362,7 @@ parameter->get_zoc = NULL; - if (unit_flag(punit, F_TRIREME) - && base_trireme_loss_pct(unit_owner(punit)) > 0) { + if (base_ship_loss_pct(punit, NULL) > 0) { parameter->is_pos_dangerous = trireme_is_pos_dangerous; } else { parameter->is_pos_dangerous = NULL; diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/unit.c freeciv-patched/common/unit.c --- freeciv-cvs/common/unit.c 2003-07-24 17:02:27.000000000 +0100 +++ freeciv-patched/common/unit.c 2003-07-24 17:03:26.000000000 +0100 @@ -1343,9 +1343,9 @@ } /************************************************************************** - Like base_trireme_loss_pct but take the position into account. + Like base_ship_loss_pct but take the position into account. **************************************************************************/ -int trireme_loss_pct(struct player *pplayer, int x, int y) +int ship_loss_pct(struct unit *punit, int x, int y) { /* * If we are in a city or next to land, we have no chance of losing @@ -1353,28 +1353,46 @@ * we'd need to confirm that we can exist/move at the (x, y) * location we are given. */ - if (map_get_terrain(x, y) != T_OCEAN || is_coastline(x, y)) { + if (!unit_flag(punit, F_TRIREME) || map_get_terrain(x, y) != T_OCEAN + || is_coastline(x, y)) { return 0; } else { - return base_trireme_loss_pct(pplayer); + struct map_position mp; + mp.x = x; + mp.y = y; + return base_ship_loss_pct(punit, &mp); } } /************************************************************************** Triremes have a varying loss percentage. based on tech. Seafaring - reduces this to 25%, Navigation to 12.5%. The Lighthouse wonder - reduces this to 0. + reduces this to 25%, Navigation to 12.5%. The No_Sink_Deep improvement + effect (e.g. Lighthouse wonder) reduces this to 0. (Units that are not + Triremes always have a loss percentage of 0.) + mp should point to a map position, or be NULL if this is indeterminate. **************************************************************************/ -int base_trireme_loss_pct(struct player *pplayer) +int base_ship_loss_pct(struct unit *punit, struct map_position *mp) { - if (player_owns_active_wonder(pplayer, B_LIGHTHOUSE)) { + struct player *pplayer = unit_owner(punit); + + if (!unit_flag(punit, F_TRIREME)) { return 0; - } else if (player_knows_techs_with_flag(pplayer, TF_REDUCE_TRIREME_LOSS2)) { - return 12; - } else if (player_knows_techs_with_flag(pplayer, TF_REDUCE_TRIREME_LOSS1)) { - return 25; } else { - return 50; + struct eff_iter iter; + int losspct = 50; + if (player_knows_techs_with_flag(pplayer, TF_REDUCE_TRIREME_LOSS1)) { + losspct = 25; + } + if (player_knows_techs_with_flag(pplayer, TF_REDUCE_TRIREME_LOSS2)) { + losspct = 12; + } + eff_iterator_unit_init(&iter, punit->type, pplayer, mp); + while (eff_iterator_next(&iter)) { + if (iter.imeff->type == EFT_NO_SINK_DEEP) { + return 0; + } + } + return losspct; } } diff -Nur -Xfreecivdiff.ignore freeciv-cvs/common/unit.h freeciv-patched/common/unit.h --- freeciv-cvs/common/unit.h 2003-07-24 17:00:39.000000000 +0100 +++ freeciv-patched/common/unit.h 2003-07-24 17:03:26.000000000 +0100 @@ -262,8 +262,8 @@ struct unit *is_non_attack_unit_tile(struct tile *ptile, struct player *pplayer); -int trireme_loss_pct(struct player *pplayer, int x, int y); -int base_trireme_loss_pct(struct player *pplayer); +int ship_loss_pct(struct unit *punit, int x, int y); +int base_ship_loss_pct(struct unit *punit, struct map_position *mp); bool is_my_zoc(struct player *unit_owner, int x0, int y0); bool unit_being_aggressive(struct unit *punit); diff -Nur -Xfreecivdiff.ignore freeciv-cvs/server/gotohand.c freeciv-patched/server/gotohand.c --- freeciv-cvs/server/gotohand.c 2003-07-22 16:29:32.000000000 +0100 +++ freeciv-patched/server/gotohand.c 2003-07-24 17:03:26.000000000 +0100 @@ -709,8 +709,7 @@ && !same_pos(x1, y1, dest_x, dest_y)) { continue; } - else if (unit_flag(punit, F_TRIREME) - && trireme_loss_pct(unit_owner(punit), x1, y1) > 0) { + else if (ship_loss_pct(punit, x1, y1) > 0) { move_cost = 2*SINGLE_MOVE+1; } else { move_cost = SINGLE_MOVE; diff -Nur -Xfreecivdiff.ignore freeciv-cvs/server/unittools.c freeciv-patched/server/unittools.c --- freeciv-cvs/server/unittools.c 2003-07-24 17:01:33.000000000 +0100 +++ freeciv-patched/server/unittools.c 2003-07-24 17:03:26.000000000 +0100 @@ -530,8 +530,7 @@ } /* 4) Check that triremes are near coastline, otherwise... */ - if (unit_flag(punit, F_TRIREME) - && myrand(100) < trireme_loss_pct(pplayer, punit->x, punit->y)) { + if (myrand(100) < ship_loss_pct(punit, punit->x, punit->y)) { notify_player_ex(pplayer, punit->x, punit->y, E_UNIT_LOST, _("Game: Your %s has been lost on the high seas."), unit_name(punit->type));