diff -Xfreeciv/diff_ignore -Nur freeciv/ai/aiunit.c freeciv-change/ai/aiunit.c --- freeciv/ai/aiunit.c Fri Aug 24 10:21:59 2001 +++ freeciv-change/ai/aiunit.c Thu Aug 30 03:05:58 2001 @@ -192,8 +192,14 @@ int id = punit->id; /* we can now die because easy AI may accidently stumble on huts it fuzzily ignored */ int best_x = -1, best_y = -1; - int range = get_unit_type(punit->type)->vision_range; int move_rate = unit_move_rate(punit); + int range; + + if (unit_profits_of_watchtower(punit) + && map_get_tile(punit->x, punit->y)->special & S_FORTRESS) + range =get_watchtower_vision(punit); + else + range = get_unit_type(punit->type)->vision_range; if (punit->activity != ACTIVITY_IDLE) handle_unit_activity_request(punit, ACTIVITY_IDLE); diff -Xfreeciv/diff_ignore -Nur freeciv/common/game.c freeciv-change/common/game.c --- freeciv/common/game.c Fri Aug 24 10:22:05 2001 +++ freeciv-change/common/game.c Thu Aug 30 01:28:11 2001 @@ -727,6 +727,8 @@ game.save_compress_level = GAME_NO_COMPRESS_LEVEL; #endif game.randseed=GAME_DEFAULT_RANDSEED; + game.watchtower_vision=GAME_DEFAULT_WATCHTOWER_VISION; + game.watchtower_extra_vision=GAME_DEFAULT_WATCHTOWER_EXTRA_VISION, sz_strlcpy(game.ruleset.techs, GAME_DEFAULT_RULESET); sz_strlcpy(game.ruleset.units, GAME_DEFAULT_RULESET); diff -Xfreeciv/diff_ignore -Nur freeciv/common/game.h freeciv-change/common/game.h --- freeciv/common/game.h Wed Aug 22 23:40:06 2001 +++ freeciv-change/common/game.h Thu Aug 30 01:21:23 2001 @@ -137,6 +137,9 @@ int playable_nation_count; int styles_count; + int watchtower_extra_vision; + int watchtower_vision; + struct { char techs[MAX_LEN_NAME]; char units[MAX_LEN_NAME]; @@ -399,6 +402,14 @@ #define GAME_DEFAULT_REPUTATION 1000 #define GAME_MAX_REPUTATION 1000 #define GAME_REPUTATION_INCR 2 + +#define GAME_DEFAULT_WATCHTOWER_VISION 2 +#define GAME_MIN_WATCHTOWER_VISION 1 +#define GAME_MAX_WATCHTOWER_VISION 3 + +#define GAME_DEFAULT_WATCHTOWER_EXTRA_VISION 0 +#define GAME_MIN_WATCHTOWER_EXTRA_VISION 0 +#define GAME_MAX_WATCHTOWER_EXTRA_VISION 2 #define GAME_START_YEAR -4000 diff -Xfreeciv/diff_ignore -Nur freeciv/common/tech.c freeciv-change/common/tech.c --- freeciv/common/tech.c Thu Aug 23 20:24:59 2001 +++ freeciv-change/common/tech.c Sat Aug 25 01:25:54 2001 @@ -27,7 +27,7 @@ client/packhand.c (for the client) */ static const char *flag_names[] = { - "Bonus_Tech","Boat_Fast","Bridge","Railroad","Fortress", + "Bonus_Tech","Boat_Fast","Bridge","Railroad","Fortress","Watchtower", "Population_Pollution_Inc","Trade_Revenue_Reduce","Airbase","Farmland", "Reduce_Trireme_Loss1", "Reduce_Trireme_Loss2" }; diff -Xfreeciv/diff_ignore -Nur freeciv/common/tech.h freeciv-change/common/tech.h --- freeciv/common/tech.h Thu Aug 23 20:24:59 2001 +++ freeciv-change/common/tech.h Sat Aug 25 01:43:08 2001 @@ -46,6 +46,7 @@ TF_BRIDGE, /* "Settler" unit types can build bridges over rivers */ TF_RAILROAD, /* "Settler" unit types can build rail roads */ TF_FORTRESS, /* "Settler" unit types can build fortress */ + TF_WATCHTOWER, /* Units get enhanced visionrange in a fortress (=fortress acts also as a watchtower) */ TF_POPULATION_POLLUTION_INC, /* Increase the pollution factor created by popultaion by one */ TF_TRADE_REVENUE_REDUCE, /* When known by the player establishing a trade route reduces the initial revenue by cumulative factors of 2/3 */ diff -Xfreeciv/diff_ignore -Nur freeciv/data/default/techs.ruleset freeciv-change/data/default/techs.ruleset --- freeciv/data/default/techs.ruleset Fri Mar 30 01:08:39 2001 +++ freeciv-change/data/default/techs.ruleset Sat Aug 25 01:25:13 2001 @@ -38,6 +38,7 @@ ; "Railroad" = "Settler" unit types can build rail roads ; "Farmland" = "Settler" unit types can build farmland ; "Fortress" = "Settler" unit types can build fortress +; "Watchtower" = Units get enhanced visionrange in a fortress ; "Population_Pollution_Inc" = Increase the pollution factor created by ; popultaion by one ; "Trade_Revenue_Reduce" = When known by the player establishing a trade @@ -271,7 +272,7 @@ name = _("Invention") req1 = "Engineering" req2 = "Literacy" -flags = "" +flags = "Watchtower" [advance_iron_working] name = _("Iron Working") diff -Xfreeciv/diff_ignore -Nur freeciv/server/citytools.c freeciv-change/server/citytools.c --- freeciv/server/citytools.c Fri Aug 24 10:22:07 2001 +++ freeciv-change/server/citytools.c Thu Aug 30 02:25:01 2001 @@ -897,8 +897,19 @@ city_refresh(pcity); city_incite_cost(pcity); + + /* Put vision back to normal, if fortress acted as a watchtower */ + if (player_knows_techs_with_flag(pplayer, TF_WATCHTOWER) + && map_get_tile(x,y)->special & S_FORTRESS) + { + unit_list_iterate (map_get_tile(x,y)->units, punit) + unfog_area(pplayer, punit->x, punit->y, get_unit_type(punit->type)->vision_range); + fog_area(pplayer, punit->x, punit->y, get_watchtower_vision(punit)); + unit_list_iterate_end; + } map_clear_special(x, y, S_FORTRESS); send_tile_info(NULL, x, y); + initialize_infrastructure_cache(pcity); reset_move_costs(x, y); /* I stupidly thought that setting S_ROAD took care of this, but of course diff -Xfreeciv/diff_ignore -Nur freeciv/server/maphand.c freeciv-change/server/maphand.c --- freeciv/server/maphand.c Fri Aug 24 10:22:10 2001 +++ freeciv-change/server/maphand.c Thu Aug 30 02:24:40 2001 @@ -679,14 +679,17 @@ **************************************************************************/ void remove_unit_sight_points(struct unit *punit) { - int x = punit->x, y = punit->y, range = - get_unit_type(punit->type)->vision_range; + int x = punit->x, y = punit->y, range =get_unit_type(punit->type)->vision_range; struct player *pplayer = unit_owner(punit); freelog(LOG_DEBUG, "Removing unit sight points at %i,%i", punit->x, punit->y); - fog_area(pplayer, x, y, range); + if (map_get_special(punit->x, punit->y) & S_FORTRESS + && unit_profits_of_watchtower(punit)) + fog_area(pplayer, x, y, get_watchtower_vision(punit)); + else + fog_area(pplayer, x, y, range); } /************************************************************************** diff -Xfreeciv/diff_ignore -Nur freeciv/server/plrhand.c freeciv-change/server/plrhand.c --- freeciv/server/plrhand.c Sat Jul 21 19:45:36 2001 +++ freeciv-change/server/plrhand.c Mon Aug 27 05:02:12 2001 @@ -259,6 +259,21 @@ upgrade_city_rails(plr, was_discovery); } + /* enhace vision of units inside a fortress */ + if (tech_flag(tech_found,TF_WATCHTOWER)) + { + unit_list_iterate(plr->units, punit) + { + if (map_get_tile(punit->x, punit->y)->special & S_FORTRESS + && is_ground_unit(punit)) + { + unfog_area(plr, punit->x, punit->y, get_watchtower_vision(punit)); + fog_area(plr, punit->x, punit->y, get_unit_type(punit->type)->vision_range); + } + } + unit_list_iterate_end; + } + if (tech_found==plr->ai.tech_goal) plr->ai.tech_goal=A_NONE; diff -Xfreeciv/diff_ignore -Nur freeciv/server/savegame.c freeciv-change/server/savegame.c --- freeciv/server/savegame.c Fri Aug 24 10:22:10 2001 +++ freeciv-change/server/savegame.c Thu Aug 30 02:37:27 2001 @@ -43,6 +43,7 @@ #include "ruleset.h" #include "spacerace.h" #include "srv_main.h" +#include "unittools.h" #include "aicity.h" #include "aiunit.h" @@ -1123,7 +1124,14 @@ } square_iterate_end; } /* allocate the unit's contribution to fog of war */ - unfog_area(unit_owner(punit), punit->x, punit->y, + if (unit_profits_of_watchtower(punit) + && map_get_special(punit->x, punit->y) & S_FORTRESS) + { + unfog_area(unit_owner(punit), punit->x, punit->y, + get_watchtower_vision(punit)); + } + else + unfog_area(unit_owner(punit), punit->x, punit->y, get_unit_type(punit->type)->vision_range); unit_list_insert_back(&plr->units, punit); @@ -1865,6 +1873,11 @@ game.civstyle = secfile_lookup_int_default(file, 0, "game.civstyle"); game.save_nturns = secfile_lookup_int(file, "game.save_nturns"); } + if (game.version >= 11201) + { + game.watchtower_extra_vision = secfile_lookup_int(file, "game.watchtower_extra_vision"); + game.watchtower_vision = secfile_lookup_int(file, "game.watchtower_vision"); + } sz_strlcpy(game.save_name, secfile_lookup_str_default(file, GAME_DEFAULT_SAVE_NAME, @@ -2228,6 +2241,8 @@ secfile_insert_str(file, game.ruleset.cities, "game.ruleset.cities"); secfile_insert_str(file, game.ruleset.game, "game.ruleset.game"); secfile_insert_str(file, game.demography, "game.demography"); + secfile_insert_int(file, game.watchtower_vision, "game.watchtower_vision"); + secfile_insert_int(file, game.watchtower_extra_vision, "game.watchtower_extra_vision"); if (1) { /* Now always save these, so the server options reflect the diff -Xfreeciv/diff_ignore -Nur freeciv/server/stdinhand.c freeciv-change/server/stdinhand.c --- freeciv/server/stdinhand.c Wed Aug 22 21:47:48 2001 +++ freeciv-change/server/stdinhand.c Thu Aug 30 01:59:59 2001 @@ -545,6 +545,27 @@ " 4 = heli\n" " 8 = air") }, + { "wtowervision", &game.watchtower_vision, NULL, NULL, + SSET_RULES, SSET_TO_CLIENT, + GAME_MIN_WATCHTOWER_VISION, GAME_MAX_WATCHTOWER_VISION, GAME_DEFAULT_WATCHTOWER_VISION, + N_("Range of vision for units in a fortress"), + N_("watchtower visionrange: If set to 1, it has no effect.\n" + "If 2 or larger, the vision range of a unit inside a fortress is\n" + "increased to this value, if the necessary invention has been made.\n" + "This invention is determined by the flag 'Watchtower' in the\n" + "techs ruleset. Also see wtowerevision.") }, + + { "wtowerevision", &game.watchtower_extra_vision, NULL, NULL, + SSET_RULES, SSET_TO_CLIENT, + GAME_MIN_WATCHTOWER_EXTRA_VISION, GAME_MAX_WATCHTOWER_EXTRA_VISION, GAME_DEFAULT_WATCHTOWER_EXTRA_VISION, + N_("Alternative range of vision for units in a fortress"), + N_("watchtower extra visionrange: This is the alternative value to\n" + "wtowervision. If set to 0, it has no effect. If larger than 0, the\n" + "visionrange of a unit is raised by this value, if the unit is inside a\n" + "fortress and the invention determined by the flag 'Watchtower' in the\n" + "techs ruleset has been made. Always the larger value of wtowervision\n" + "and wtowerevision will be used. Also see wtowervision.") }, + /* Flexible rules: these can be changed after the game has started. * * The distinction between "rules" and "flexible rules" is not always diff -Xfreeciv/diff_ignore -Nur freeciv/server/unittools.c freeciv-change/server/unittools.c --- freeciv/server/unittools.c Fri Aug 24 10:22:12 2001 +++ freeciv-change/server/unittools.c Thu Aug 30 03:30:04 2001 @@ -822,6 +822,20 @@ send_tile_info(0, punit->x, punit->y); set_unit_activity(punit, ACTIVITY_IDLE); } + + /* If a watchtower has been pillaged, reduce sight to normal */ + if (what == S_FORTRESS + && player_knows_techs_with_flag(pplayer, TF_WATCHTOWER)) + { + freelog(LOG_VERBOSE, "Watchtower pillaged!"); + unit_list_iterate (map_get_tile(punit->x, punit->y)->units, punit2) + if (is_ground_unit(punit2)) + { + unfog_area(pplayer, punit2->x, punit2->y, get_unit_type(punit2->type)->vision_range); + fog_area(pplayer, punit2->x, punit2->y, get_watchtower_vision(punit2)); + } + unit_list_iterate_end; + } } } else if (total_activity_targeted (punit->x, punit->y, @@ -836,7 +850,21 @@ } unit_list_iterate_end; send_tile_info(NULL, punit->x, punit->y); - } + + /* If a watchtower has been pillaged, reduce sight to normal */ + if (what_pillaged == S_FORTRESS + && player_knows_techs_with_flag(pplayer, TF_WATCHTOWER)) + { + freelog(LOG_VERBOSE, "Watchtower(2) pillaged!"); + unit_list_iterate (map_get_tile(punit->x, punit->y)->units, punit2) + if (is_ground_unit(punit2)) + { + unfog_area(pplayer, punit2->x, punit2->y, get_unit_type(punit2->type)->vision_range); + fog_area(pplayer, punit2->x, punit2->y, get_watchtower_vision(punit2)); + } + unit_list_iterate_end; + } + } } if (activity==ACTIVITY_POLLUTION) { @@ -860,6 +888,18 @@ >= map_build_fortress_time(punit->x, punit->y)) { map_set_special(punit->x, punit->y, S_FORTRESS); unit_activity_done = 1; + /* watchtower becomes effective */ + if (player_knows_techs_with_flag(pplayer, TF_WATCHTOWER)) + { + unit_list_iterate(ptile->units, punit) + { + if (is_ground_unit(punit)) + { + fog_area(pplayer, punit->x, punit->y, get_unit_type(punit->type)->vision_range); + unfog_area(pplayer, punit->x, punit->y, get_watchtower_vision(punit)); + } + } unit_list_iterate_end; + } } } @@ -1530,7 +1570,12 @@ void upgrade_unit(struct unit *punit, Unit_Type_id to_unit) { struct player *pplayer = unit_owner(punit); - int range = get_unit_type(punit->type)->vision_range; + int range; + if (map_get_tile(punit->x, punit->y)->special & S_FORTRESS + && unit_profits_of_watchtower(punit)) + range = get_watchtower_vision(punit); + else + range = get_unit_type(punit->type)->vision_range; if (punit->hp==get_unit_type(punit->type)->hp) { punit->hp=get_unit_type(to_unit)->hp; @@ -1538,8 +1583,15 @@ conn_list_do_buffer(&pplayer->connections); punit->type = to_unit; - unfog_area(pplayer,punit->x,punit->y, get_unit_type(to_unit)->vision_range); + + if (map_get_tile(punit->x, punit->y)->special & S_FORTRESS + && unit_profits_of_watchtower(punit)) + unfog_area(pplayer, punit->x, punit->y, get_watchtower_vision(punit)); + else + unfog_area(pplayer,punit->x,punit->y, get_unit_type(to_unit)->vision_range); + fog_area(pplayer,punit->x,punit->y,range); + send_unit_info(0, punit); conn_list_do_unbuffer(&pplayer->connections); } @@ -1642,7 +1694,12 @@ punit->transported_by = -1; punit->pgr = NULL; - unfog_area(pplayer,x,y,get_unit_type(punit->type)->vision_range); + + if (map_get_tile(x, y)->special & S_FORTRESS + && unit_profits_of_watchtower(punit)) + unfog_area(pplayer, punit->x, punit->y, get_watchtower_vision(punit)); + else + unfog_area(pplayer, x, y, get_unit_type(punit->type)->vision_range); send_unit_info(0, punit); maybe_make_first_contact(x, y, punit->owner); wakeup_neighbor_sentries(punit); @@ -2659,10 +2716,16 @@ wake them up if the punit is farther away than 3. */ square_iterate(punit->x, punit->y, 3, x, y) { unit_list_iterate(map_get_tile(x, y)->units, penemy) { - int range = get_unit_type(penemy->type)->vision_range; + int range; enum unit_move_type move_type = get_unit_type(penemy->type)->move_type; enum tile_terrain_type terrain = map_get_terrain(x, y); + if (map_get_tile(x, y)->special & S_FORTRESS + && unit_profits_of_watchtower(penemy)) + range = get_watchtower_vision(penemy); + else + range = get_unit_type(penemy->type)->vision_range; + if (!players_allied(punit->owner, penemy->owner) && penemy->activity == ACTIVITY_SENTRY && map_get_known_and_seen(punit->x, punit->y, penemy->owner) @@ -2892,7 +2955,12 @@ and then fog the old territory. This means that the player gets a chance to see the newly explored territory while the client moves the unit, and both areas are visible during the move */ - unfog_area(pplayer, dest_x, dest_y, get_unit_type(punit->type)->vision_range); + /* Enhace vision if unit steps into a fortress -- for Gregory ;-) */ + if (unit_profits_of_watchtower(punit) + && pdesttile->special & S_FORTRESS) + unfog_area(pplayer, dest_x, dest_y, get_watchtower_vision(punit)); + else + unfog_area(pplayer, dest_x, dest_y, get_unit_type(punit->type)->vision_range); unit_list_unlink(&psrctile->units, punit); punit->x = dest_x; @@ -2915,7 +2983,11 @@ set_unit_activity(punit, ACTIVITY_SENTRY); } send_unit_info_to_onlookers(0, punit, src_x, src_y, 0, 0); - fog_area(pplayer, src_x, src_y, get_unit_type(punit->type)->vision_range); + if (unit_profits_of_watchtower(punit) + && psrctile->special & S_FORTRESS) + fog_area(pplayer, src_x, src_y, get_watchtower_vision(punit)); + else + fog_area(pplayer, src_x, src_y, get_unit_type(punit->type)->vision_range); handle_unit_move_consequences(punit, src_x, src_y, dest_x, dest_y); @@ -2936,8 +3008,13 @@ static int maybe_cancel_patrol_due_to_enemy(struct unit *punit) { int cancel = 0; - int range = get_unit_type(punit->type)->vision_range; - + int range; + if (map_get_tile(punit->x, punit->y)->special & S_FORTRESS + && unit_profits_of_watchtower(punit)) + range = get_watchtower_vision(punit); + else + range = get_unit_type(punit->type)->vision_range; + square_iterate(punit->x, punit->y, range, x, y) { struct unit *penemy = is_non_allied_unit_tile(map_get_tile(x, y), punit->owner); if (penemy && player_can_see_unit(unit_owner(punit), penemy)) { @@ -3077,4 +3154,26 @@ unit_types[punit->type].name); } return 0; +} + +/************************************************************************** +... +**************************************************************************/ +int get_watchtower_vision(struct unit *punit) +{ + int base_vision=get_unit_type(punit->type)->vision_range; + + return MAX(base_vision, + MAX(game.watchtower_vision, base_vision+game.watchtower_extra_vision)); +} + +/************************************************************************** +... +**************************************************************************/ +int unit_profits_of_watchtower(struct unit *punit) +{ + int playerid = punit->owner; + struct player *pplayer = get_player(playerid); + return (is_ground_unit(punit) + && player_knows_techs_with_flag(pplayer, TF_WATCHTOWER)); } diff -Xfreeciv/diff_ignore -Nur freeciv/server/unittools.h freeciv-change/server/unittools.h --- freeciv/server/unittools.h Mon Aug 13 14:25:30 2001 +++ freeciv-change/server/unittools.h Sun Aug 26 16:57:42 2001 @@ -45,6 +45,8 @@ int teleport_unit_to_city(struct unit *punit, struct city *pcity, int move_cost, int verbose); void resolve_unit_stack(int x, int y, int verbose); +int get_watchtower_vision(struct unit *punit); +int unit_profits_of_watchtower(struct unit *punit); /* creation/deletion/upgrading */