<URL: http://bugs.freeciv.org/Ticket/Display.html?id=33876 >

 This adds new module base.[ch]. It contains one function,
base_has_effect(). New function tile_has_base_effect() in tile.c uses
it. tile_has_base_effect() is called from number of places instead of
directly checking if tile contains fortress/airbase.


  - ML

diff -Nurd -X.diff_ignore freeciv/common/aicore/pf_tools.c freeciv/common/aicore/pf_tools.c
--- freeciv/common/aicore/pf_tools.c	2006-07-21 23:18:09.000000000 +0300
+++ freeciv/common/aicore/pf_tools.c	2007-01-17 11:41:01.000000000 +0200
@@ -21,6 +21,7 @@
 #include "log.h"
 #include "mem.h"
 
+#include "base.h"
 #include "game.h"
 #include "movement.h"
 
@@ -571,7 +572,7 @@
     return FALSE;
   }
 
-  if (tile_has_special(ptile, S_AIRBASE)) {
+  if (tile_has_base_effect(ptile, BASE_REFUEL)) {
     /* All airbases are considered non-dangerous, although non-allied ones
      * are inaccessible. */
     return FALSE;
diff -Nurd -X.diff_ignore freeciv/common/base.c freeciv/common/base.c
--- freeciv/common/base.c	1970-01-01 02:00:00.000000000 +0200
+++ freeciv/common/base.c	2007-01-17 11:42:50.000000000 +0200
@@ -0,0 +1,68 @@
+/****************************************************************************
+ Freeciv - Copyright (C) 2004 - The Freeciv Team
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+
+#include "base.h"
+
+/****************************************************************************
+  Check if base provides effect
+****************************************************************************/
+bool base_has_effect(Base_type_id base_type, enum base_effect effect)
+{
+  switch(base_type) {
+  case BASE_TYPE_1:
+    /* Fortress */
+    switch(effect) {
+    case BASE_NOT_AGGRESSIVE:
+    case BASE_DEFENSE_BONUS:
+    case BASE_WATCHTOWER:
+    case BASE_CLAIM_TERRITORY:
+    case BASE_NO_STACK_DEATH:
+    case BASE_DIPLOMAT_DEFENSE:
+      return TRUE;
+
+    case BASE_REFUEL:
+    case BASE_NO_HP_LOSS:
+    case BASE_ATTACK_UNREACHABLE:
+    case BASE_PARADROP_FROM:
+      return FALSE;
+    }
+    break;
+
+  case BASE_TYPE_2:
+    /* Airbase */
+    switch(effect) {
+    case BASE_NO_STACK_DEATH:
+    case BASE_DIPLOMAT_DEFENSE:
+    case BASE_REFUEL:
+    case BASE_NO_HP_LOSS:
+    case BASE_ATTACK_UNREACHABLE:
+    case BASE_PARADROP_FROM:
+      return TRUE;
+
+    case BASE_NOT_AGGRESSIVE:
+    case BASE_DEFENSE_BONUS:
+    case BASE_WATCHTOWER:
+    case BASE_CLAIM_TERRITORY:
+      return FALSE;
+    }
+    break;
+  }
+
+  return FALSE;
+}
diff -Nurd -X.diff_ignore freeciv/common/base.h freeciv/common/base.h
--- freeciv/common/base.h	1970-01-01 02:00:00.000000000 +0200
+++ freeciv/common/base.h	2007-01-17 11:42:28.000000000 +0200
@@ -0,0 +1,38 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+#ifndef FC__BASE_H
+#define FC__BASE_H
+
+#include "fc_types.h"
+
+enum base_type { BASE_TYPE_1, BASE_TYPE_2 };
+
+typedef enum base_type Base_type_id;
+
+enum base_effect {
+  BASE_NOT_AGGRESSIVE,     /* Unit inside are not considered aggressive
+                            * if base is close to city */
+  BASE_DEFENSE_BONUS,      /* Base provides defense bonus for units inside */
+  BASE_NO_STACK_DEATH,     /* Units inside will not die all at once */
+  BASE_WATCHTOWER,         /* Base can act as watchtower */
+  BASE_CLAIM_TERRITORY,    /* Base claims tile ownership */
+  BASE_DIPLOMAT_DEFENSE,   /* Base provides bonus for defending diplomat */
+  BASE_REFUEL,             /* Base refuels units */
+  BASE_NO_HP_LOSS,         /* Units do not lose hitpoints when in base */
+  BASE_ATTACK_UNREACHABLE, /* Unreachable units inside base can be attacked */
+  BASE_PARADROP_FROM       /* Paratroopers can use base for paradrop */
+};
+
+bool base_has_effect(Base_type_id base_type, enum base_effect effect);
+
+#endif  /* FC__BASE_H */
diff -Nurd -X.diff_ignore freeciv/common/combat.c freeciv/common/combat.c
--- freeciv/common/combat.c	2006-07-21 23:18:09.000000000 +0300
+++ freeciv/common/combat.c	2007-01-17 11:44:12.000000000 +0200
@@ -20,6 +20,7 @@
 
 #include "rand.h"
 
+#include "base.h"
 #include "game.h"
 #include "log.h"
 #include "map.h"
@@ -94,7 +95,8 @@
 
   /* 2. Only fighters can attack planes, except in city or airbase attacks */
   if (!unit_flag(punit, F_FIGHTER) && is_air_unit(pdefender)
-      && !(pcity || tile_has_special(dest_tile, S_AIRBASE))) {
+      && !(pcity
+           || tile_has_base_effect(dest_tile, BASE_ATTACK_UNREACHABLE))) {
     return FALSE;
   }
 
@@ -325,14 +327,6 @@
 }
 
 /**************************************************************************
- a wrapper function returns 1 if the unit is on a square with fortress
-**************************************************************************/
-bool unit_on_fortress(const struct unit *punit)
-{
-  return tile_has_special(punit->tile, S_FORTRESS);
-}
-
-/**************************************************************************
   Try defending against nuclear attack, if succed return a city which 
   had enough luck and EFT_NUKE_PROOF.
   If the attack was succesful return NULL.
@@ -460,7 +454,7 @@
     }
   }
 
-  if (tile_has_special(ptile, S_FORTRESS) && !pcity) {
+  if (tile_has_base_effect(ptile, BASE_DEFENSE_BONUS) && !pcity) {
     defensepower +=
 	(defensepower * terrain_control.fortress_defense_bonus) / 100;
   }
@@ -642,7 +636,6 @@
 bool is_stack_vulnerable(const struct tile *ptile)
 {
   return !(ptile->city != NULL
-           || tile_has_special(ptile, S_FORTRESS)
-           || tile_has_special(ptile, S_AIRBASE)
+           || tile_has_base_effect(ptile, BASE_NO_STACK_DEATH)
            || !game.info.killstack);
 }
diff -Nurd -X.diff_ignore freeciv/common/combat.h freeciv/common/combat.h
--- freeciv/common/combat.h	2006-07-17 23:56:44.000000000 +0300
+++ freeciv/common/combat.h	2007-01-17 10:07:07.000000000 +0200
@@ -43,7 +43,6 @@
 		       const struct unit *defender);
 
 bool unit_really_ignores_citywalls(const struct unit *punit);
-bool unit_on_fortress(const struct unit *punit);
 struct city *sdi_try_defend(const struct player *owner,
 			       const struct tile *ptile);
 
diff -Nurd -X.diff_ignore freeciv/common/Makefile.am freeciv/common/Makefile.am
--- freeciv/common/Makefile.am	2006-07-17 23:56:46.000000000 +0300
+++ freeciv/common/Makefile.am	2007-01-17 09:55:19.000000000 +0200
@@ -9,6 +9,8 @@
 ## Above, note -I../intl instead of -I$(top_srcdir/intl) is deliberate.
 
 libcivcommon_a_SOURCES = \
+		base.c		\
+		base.h		\
 		capstr.c	\
 		capstr.h	\
 		city.c		\
diff -Nurd -X.diff_ignore freeciv/common/movement.c freeciv/common/movement.c
--- freeciv/common/movement.c	2006-08-18 10:52:03.000000000 +0300
+++ freeciv/common/movement.c	2007-01-17 11:45:11.000000000 +0200
@@ -22,6 +22,7 @@
 #include "shared.h"
 #include "support.h"
 
+#include "base.h"
 #include "fc_types.h"
 #include "map.h"
 #include "movement.h"
@@ -282,7 +283,7 @@
     return TRUE;
   case AIR_MOVING:
   case HELI_MOVING:
-    return tile_has_special(punit->tile, S_AIRBASE);
+    return tile_has_base_effect(punit->tile, BASE_REFUEL);
   default:
     die("Invalid move type");
   }
diff -Nurd -X.diff_ignore freeciv/common/tile.c freeciv/common/tile.c
--- freeciv/common/tile.c	2006-07-17 23:56:46.000000000 +0300
+++ freeciv/common/tile.c	2007-01-17 11:06:57.000000000 +0200
@@ -99,6 +99,17 @@
 }
 
 /****************************************************************************
+  Check if tile contains base providing effect
+****************************************************************************/
+bool tile_has_base_effect(const struct tile *ptile, enum base_effect effect)
+{
+  return (tile_has_special(ptile, S_FORTRESS)
+          && base_has_effect(BASE_TYPE_1, effect))
+    || (tile_has_special(ptile, S_AIRBASE)
+        && base_has_effect(BASE_TYPE_2, effect));
+}
+
+/****************************************************************************
   Add the given special or specials to the tile.
 
   Note that this does not erase any existing specials already on the tile
diff -Nurd -X.diff_ignore freeciv/common/tile.h freeciv/common/tile.h
--- freeciv/common/tile.h	2006-07-17 23:56:46.000000000 +0300
+++ freeciv/common/tile.h	2007-01-17 11:06:11.000000000 +0200
@@ -14,6 +14,7 @@
 #ifndef FC__TILE_H
 #define FC__TILE_H
 
+#include "base.h"
 #include "fc_types.h"
 #include "player.h"
 #include "terrain.h"
@@ -62,6 +63,7 @@
 		      enum tile_special_type to_test_for);
 bool tile_has_any_specials(const struct tile *ptile);
 void tile_set_special(struct tile *ptile, enum tile_special_type spe);
+bool tile_has_base_effect(const struct tile *ptile, enum base_effect effect);
 const struct resource *tile_get_resource(const struct tile *ptile);
 void tile_set_resource(struct tile *ptile, const struct resource *presource);
 void tile_clear_special(struct tile *ptile, enum tile_special_type spe);
diff -Nurd -X.diff_ignore freeciv/common/unit.c freeciv/common/unit.c
--- freeciv/common/unit.c	2006-07-21 23:18:09.000000000 +0300
+++ freeciv/common/unit.c	2007-01-17 11:43:19.000000000 +0200
@@ -22,6 +22,7 @@
 #include "shared.h"
 #include "support.h"
 
+#include "base.h"
 #include "city.h"
 #include "game.h"
 #include "log.h"
@@ -634,7 +635,7 @@
   if(punit->moves_left < utype->paratroopers_mr_req)
     return FALSE;
 
-  if (tile_has_special(punit->tile, S_AIRBASE)) {
+  if (tile_has_base_effect(punit->tile, BASE_PARADROP_FROM)) {
     return TRUE;
   }
 
@@ -1255,7 +1256,7 @@
     return FALSE;
   }
   if (is_ground_unit(punit) &&
-      tile_has_special(punit->tile, S_FORTRESS)) {
+      tile_has_base_effect(punit->tile, BASE_NOT_AGGRESSIVE)) {
     return !is_unit_near_a_friendly_city (punit);
   }
   
diff -Nurd -X.diff_ignore freeciv/server/airgoto.c freeciv/server/airgoto.c
--- freeciv/server/airgoto.c	2006-08-18 10:51:27.000000000 +0300
+++ freeciv/server/airgoto.c	2007-01-17 11:32:31.000000000 +0200
@@ -162,7 +162,7 @@
 	&& !is_non_allied_unit_tile(ptile, pplayer) ) {
       add_refuel_point(ptile, FUEL_CITY, 
                        MAP_MAX_HEIGHT + MAP_MAX_WIDTH, 0, FALSE);
-    } else if (tile_has_special(ptile, S_AIRBASE)
+    } else if (tile_has_base_effect(ptile, BASE_REFUEL)
                && !is_non_allied_unit_tile(ptile, pplayer)
                && !cities_only) {
       add_refuel_point(ptile, FUEL_AIRBASE, 
diff -Nurd -X.diff_ignore freeciv/server/citytools.c freeciv/server/citytools.c
--- freeciv/server/citytools.c	2006-08-18 10:51:27.000000000 +0300
+++ freeciv/server/citytools.c	2007-01-17 10:18:02.000000000 +0200
@@ -27,6 +27,7 @@
 #include "shared.h"
 #include "support.h"
 
+#include "base.h"
 #include "city.h"
 #include "events.h"
 #include "government.h"
@@ -1006,9 +1007,10 @@
   city_refresh(pcity);
   auto_arrange_workers(pcity);
 
-  /* Put vision back to normal, if fortress acted as a watchtower */
-  if (tile_has_special(ptile, S_FORTRESS)) {
+  /* Put vision back to normal, if base acted as a watchtower */
+  if (tile_has_base_effect(ptile, BASE_WATCHTOWER)) {
     tile_clear_special(ptile, S_FORTRESS);
+    tile_clear_special(ptile, S_AIRBASE);
     unit_list_refresh_vision(ptile->units);
   }
 
diff -Nurd -X.diff_ignore freeciv/server/diplomats.c freeciv/server/diplomats.c
--- freeciv/server/diplomats.c	2007-01-15 01:51:07.000000000 +0200
+++ freeciv/server/diplomats.c	2007-01-17 10:24:08.000000000 +0200
@@ -21,6 +21,7 @@
 #include "log.h"
 #include "rand.h"
 
+#include "base.h"
 #include "events.h"
 #include "game.h"
 #include "government.h"
@@ -1045,8 +1046,7 @@
     chance -= chance * get_city_bonus(pdefender_tile->city,
                                       EFT_SPY_RESISTANT) / 100;
   } else {
-    if (tile_has_special(pdefender_tile, S_FORTRESS)
-       || tile_has_special(pdefender_tile, S_AIRBASE)) {
+    if (tile_has_base_effect(pdefender_tile, BASE_DIPLOMAT_DEFENSE)) {
 	chance -= chance * 25 / 100; /* 25% penalty */
     }
   }
diff -Nurd -X.diff_ignore freeciv/server/maphand.c freeciv/server/maphand.c
--- freeciv/server/maphand.c	2006-07-17 23:56:22.000000000 +0300
+++ freeciv/server/maphand.c	2007-01-17 10:20:20.000000000 +0200
@@ -23,6 +23,7 @@
 #include "rand.h"
 #include "support.h"
 
+#include "base.h"
 #include "events.h"
 #include "game.h"
 #include "map.h"
@@ -1565,7 +1566,8 @@
         && ptile->owner_source
         && ptile->owner_source->owner != ptile->owner
         && (ptile->owner_source->city
-            || tile_has_special(ptile->owner_source, S_FORTRESS))) {
+            || tile_has_base_effect(ptile->owner_source,
+                                    BASE_CLAIM_TERRITORY))) {
       /* Claim ownership of tiles previously owned by someone else */
       map_claim_ownership(ptile, ptile->owner_source->owner, 
                           ptile->owner_source);
@@ -1606,7 +1608,8 @@
             || !ptile->owner->is_alive
             || ptile->owner != ptile->owner_source->owner
             || (!ptile->owner_source->city
-                && !tile_has_special(ptile->owner_source, S_FORTRESS)))) {
+                && !tile_has_base_effect(ptile->owner_source,
+                                         BASE_CLAIM_TERRITORY)))) {
       /* Ownership source gone */
       map_claim_ownership(ptile, NULL, NULL);
     }
@@ -1617,7 +1620,8 @@
    * to better visually display expansion. */
   whole_map_iterate(ptile) {
     if (ptile->owner
-        && (ptile->city || tile_has_special(ptile, S_FORTRESS))) {
+        && (ptile->city
+            || tile_has_base_effect(ptile, BASE_CLAIM_TERRITORY))) {
       /* We have an ownership source */
       int expand_range = 99;
       int found_unclaimed = 99;
diff -Nurd -X.diff_ignore freeciv/server/unithand.c freeciv/server/unithand.c
--- freeciv/server/unithand.c	2007-01-15 01:51:07.000000000 +0200
+++ freeciv/server/unithand.c	2007-01-17 11:40:01.000000000 +0200
@@ -700,7 +700,7 @@
     }
 
     if (!is_air_unit(pdefender)
-	|| (pcity || tile_has_special(ptile, S_AIRBASE))) {
+	|| (pcity || tile_has_base_effect(ptile, BASE_ATTACK_UNREACHABLE))) {
       see_combat(punit, pdefender);
 
       unit_versus_unit(punit, pdefender, TRUE);
diff -Nurd -X.diff_ignore freeciv/server/unittools.c freeciv/server/unittools.c
--- freeciv/server/unittools.c	2007-01-15 03:20:52.000000000 +0200
+++ freeciv/server/unittools.c	2007-01-17 11:47:47.000000000 +0200
@@ -27,6 +27,7 @@
 #include "shared.h"
 #include "support.h"
 
+#include "base.h"
 #include "city.h"
 #include "combat.h"
 #include "events.h"
@@ -471,7 +472,7 @@
   /* Bonus recovery HP (traditionally from the United Nations) */
   punit->hp += get_unit_bonus(punit, EFT_UNIT_RECOVER);
 
-  if (!pcity && !tile_has_special(punit->tile, S_AIRBASE)
+  if (!pcity && !tile_has_base_effect(punit->tile, BASE_NO_HP_LOSS)
       && punit->transported_by == -1) {
     punit->hp -= unit_type(punit)->hp * class->hp_loss_pct / 100;
   }
@@ -604,6 +605,7 @@
   enum unit_activity activity = punit->activity;
   struct tile *ptile = punit->tile;
   bool check_adjacent_units = FALSE;
+  bool new_base = FALSE;
   
   if (activity != ACTIVITY_IDLE && activity != ACTIVITY_FORTIFIED
       && activity != ACTIVITY_GOTO && activity != ACTIVITY_EXPLORE) {
@@ -703,10 +705,7 @@
       tile_set_special(ptile, S_FORTRESS);
       map_claim_ownership(ptile, unit_owner(punit), ptile);
       unit_activity_done = TRUE;
-
-      /* watchtower becomes effective
-       * FIXME: Reqs on other specials will not be updated immediately. */
-      unit_list_refresh_vision(ptile->units);
+      new_base = TRUE;
     }
   }
 
@@ -715,6 +714,7 @@
 	>= tile_activity_time(ACTIVITY_AIRBASE, ptile)) {
       tile_set_special(ptile, S_AIRBASE);
       unit_activity_done = TRUE;
+      new_base = TRUE;
     }
   }
   
@@ -770,6 +770,12 @@
     }
   }
 
+  if (new_base) {
+    /* watchtower becomes effective
+     * FIXME: Reqs on other specials will not be updated immediately. */
+    unit_list_refresh_vision(ptile->units);
+  }
+
   if (unit_activity_done) {
     update_tile_knowledge(ptile);
     unit_list_iterate (ptile->units, punit2) {
@@ -1191,7 +1197,7 @@
 {
   return (punit->transported_by != -1                   /* Carrier */
           || punit->tile->city                          /* City    */
-          || tile_has_special(punit->tile, S_AIRBASE)); /* Airbase */
+          || tile_has_base_effect(punit->tile, BASE_REFUEL)); /* Airbase */
 }
 
 /**************************************************************************
@@ -1206,7 +1212,10 @@
 
   if ((is_allied_city_tile(ptile, pplayer)
        && !is_non_allied_unit_tile(ptile, pplayer))
-      || (contains_special(plrtile->special, S_AIRBASE)
+      || (((contains_special(plrtile->special, S_FORTRESS)
+            && base_has_effect(BASE_TYPE_1, BASE_REFUEL))
+           || (contains_special(plrtile->special, S_AIRBASE)
+               && base_has_effect(BASE_TYPE_2, BASE_REFUEL)))
 	  && !is_non_allied_unit_tile(ptile, pplayer)))
     return TRUE;
 
@@ -2618,10 +2627,10 @@
     if (homecity) {
       if ((game.info.happyborders > 0 && src_tile->owner != dst_tile->owner)
           ||
-	  (tile_has_special(dst_tile, S_FORTRESS)
+	  (tile_has_base_effect(dst_tile, BASE_NOT_AGGRESSIVE)
 	   && is_friendly_city_near(unit_owner(punit), dst_tile))
 	  ||
-          (tile_has_special(src_tile, S_FORTRESS) 
+          (tile_has_base_effect(src_tile, BASE_NOT_AGGRESSIVE)
 	   && is_friendly_city_near(unit_owner(punit), src_tile))) {
         refresh_homecity = TRUE;
       }
@@ -2746,7 +2755,7 @@
   } vision_layer_iterate_end;
 
   /* Claim ownership of fortress? */
-  if (tile_has_special(pdesttile, S_FORTRESS)
+  if (tile_has_base_effect(pdesttile, BASE_CLAIM_TERRITORY)
       && (!pdesttile->owner || pplayers_at_war(pdesttile->owner, pplayer))) {
     map_claim_ownership(pdesttile, pplayer, pdesttile);
   }
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to