<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
[email protected]
https://mail.gna.org/listinfo/freeciv-dev