<URL: http://bugs.freeciv.org/Ticket/Display.html?id=34336 >
On 1/26/07, Marko Lindqvist <[EMAIL PROTECTED]> wrote:
>
> On 1/22/07, Marko Lindqvist <[EMAIL PROTECTED]> wrote:
> >
> > This introduces several new base related helper functions hiding the
> > fact that bases are actually bits in specials bitvector. Used them
> > where appropriate.
>
> Fixed a bug that tile_has_base_flag() never returned TRUE.
Updated against latest version of #34205
- ML
diff -Nurd -X.diff_ignore freeciv/client/tilespec.c freeciv/client/tilespec.c
--- freeciv/client/tilespec.c 2007-01-22 22:58:41.000000000 +0200
+++ freeciv/client/tilespec.c 2007-01-27 19:16:22.000000000 +0200
@@ -3932,6 +3932,11 @@
int tileno, dir;
struct drawn_sprite *save_sprs = sprs;
struct player *owner = NULL;
+ struct base_type *pbase = NULL;
+
+ if (ptile != NULL) {
+ pbase = tile_get_base(ptile);
+ }
/* Unit drawing is disabled if the view options is turned off, but only
* if we're drawing on the mapview. */
@@ -4050,7 +4055,8 @@
}
}
- if (draw_fortress_airbase && contains_special(tspecial, S_FORTRESS)
+ if (draw_fortress_airbase
+ && pbase != NULL && pbase->id == BASE_FORTRESS
&& t->sprites.tx.fortress_back) {
ADD_SPRITE_FULL(t->sprites.tx.fortress_back);
}
@@ -4104,7 +4110,8 @@
case LAYER_SPECIAL2:
if (ptile && client_tile_get_known(ptile) != TILE_UNKNOWN) {
- if (draw_fortress_airbase && contains_special(tspecial, S_AIRBASE)) {
+ if (draw_fortress_airbase
+ && pbase != NULL && pbase->id == BASE_AIRBASE) {
ADD_SPRITE_FULL(t->sprites.tx.airbase);
}
@@ -4153,7 +4160,7 @@
case LAYER_SPECIAL3:
if (ptile && client_tile_get_known(ptile) != TILE_UNKNOWN) {
if (t->is_isometric && draw_fortress_airbase
- && contains_special(tspecial, S_FORTRESS)) {
+ && pbase != NULL && pbase->id == BASE_FORTRESS) {
/* Draw fortress front in iso-view (non-iso view only has a fortress
* back). */
ADD_SPRITE_FULL(t->sprites.tx.fortress);
diff -Nurd -X.diff_ignore freeciv/common/base.c freeciv/common/base.c
--- freeciv/common/base.c 2007-01-27 19:18:36.000000000 +0200
+++ freeciv/common/base.c 2007-01-27 19:16:22.000000000 +0200
@@ -43,6 +43,21 @@
return pbase->name;
}
+/****************************************************************************
+ Determine base type from specials. Returns NULL if there is no base
+****************************************************************************/
+struct base_type *base_type_get_from_special(bv_special spe)
+{
+ if (contains_special(spe, S_FORTRESS)) {
+ return base_type_get_by_id(BASE_FORTRESS);
+ }
+ if (contains_special(spe, S_AIRBASE)) {
+ return base_type_get_by_id(BASE_AIRBASE);
+ }
+
+ return NULL;
+}
+
/**************************************************************************
Convert base flag names to enum; case insensitive;
returns BF_LAST if can't match.
diff -Nurd -X.diff_ignore freeciv/common/base.h freeciv/common/base.h
--- freeciv/common/base.h 2007-01-27 19:18:36.000000000 +0200
+++ freeciv/common/base.h 2007-01-27 19:17:09.000000000 +0200
@@ -14,13 +14,14 @@
#define FC__BASE_H
#include "fc_types.h"
+#include "terrain.h"
enum base_type_id { BASE_FORTRESS = 0, BASE_AIRBASE, BASE_LAST };
typedef enum base_type_id Base_type_id;
enum base_flag_id {
- BF_NOT_AGGRESSIVE, /* Unit inside are not considered aggressive
+ BF_NOT_AGGRESSIVE = 0, /* Unit inside are not considered aggressive
* if base is close to city */
BF_DEFENSE_BONUS, /* Base provides defense bonus for units inside */
BF_NO_STACK_DEATH, /* Units inside will not die all at once */
@@ -46,6 +47,8 @@
bool base_flag(const struct base_type *pbase, enum base_flag_id flag);
const char *base_name(const struct base_type *pbase);
+struct base_type *base_type_get_from_special(bv_special spe);
+
enum base_flag_id base_flag_from_str(const char *s);
struct base_type *base_type_get_by_id(Base_type_id id);
diff -Nurd -X.diff_ignore freeciv/common/terrain.c freeciv/common/terrain.c
--- freeciv/common/terrain.c 2007-01-27 19:18:36.000000000 +0200
+++ freeciv/common/terrain.c 2007-01-27 19:18:04.000000000 +0200
@@ -468,6 +468,7 @@
{
static char s[256];
char *p;
+ struct base_type *pbase;
s[0] = '\0';
@@ -489,14 +490,10 @@
cat_snprintf(s, sizeof(s), "%s/", _("Mine"));
}
- if (contains_special(spe, S_FORTRESS)) {
- cat_snprintf(s, sizeof(s), "%s/",
- base_name(base_type_get_by_id(BASE_FORTRESS)));
- }
+ pbase = base_type_get_from_special(spe);
- if (contains_special(spe, S_AIRBASE)) {
- cat_snprintf(s, sizeof(s), "%s/",
- base_name(base_type_get_by_id(BASE_AIRBASE)));
+ if (pbase != NULL) {
+ cat_snprintf(s, sizeof(s), "%s/", base_name(pbase));
}
p = s + strlen(s) - 1;
diff -Nurd -X.diff_ignore freeciv/common/tile.c freeciv/common/tile.c
--- freeciv/common/tile.c 2007-01-26 16:37:21.000000000 +0200
+++ freeciv/common/tile.c 2007-01-27 19:16:22.000000000 +0200
@@ -17,6 +17,7 @@
#include <assert.h>
+#include "log.h"
#include "support.h"
#include "tile.h"
@@ -99,14 +100,59 @@
}
/****************************************************************************
+ Returns base at tile or NULL if no base
+****************************************************************************/
+struct base_type *tile_get_base(const struct tile *ptile)
+{
+ return base_type_get_from_special(ptile->special);
+}
+
+/****************************************************************************
+ Adds base to tile.
+ FIXME: Currently this asserts that tile contains no old base.
+ Instead should remove old base and return bool indicating that.
+****************************************************************************/
+void tile_add_base(struct tile *ptile, const struct base_type *pbase)
+{
+ assert(pbase != NULL);
+
+ if (pbase->id == BASE_FORTRESS) {
+ assert(!tile_has_special(ptile, S_AIRBASE));
+ tile_set_special(ptile, S_FORTRESS);
+ } else if (pbase->id == BASE_AIRBASE) {
+ assert(!tile_has_special(ptile, S_FORTRESS));
+ tile_set_special(ptile, S_AIRBASE);
+ } else {
+ freelog(LOG_ERROR, "Impossible base type %d in tile_set_base()",
+ pbase->id);
+ }
+}
+
+/****************************************************************************
+ Removes base from tile if such exist
+****************************************************************************/
+void tile_remove_base(struct tile *ptile)
+{
+ tile_clear_special(ptile, S_FORTRESS);
+ tile_clear_special(ptile, S_AIRBASE);
+}
+
+/****************************************************************************
Check if tile contains base providing effect
****************************************************************************/
bool tile_has_base_flag(const struct tile *ptile, enum base_flag_id flag)
{
- return (tile_has_special(ptile, S_FORTRESS)
- && base_flag(base_type_get_by_id(BASE_FORTRESS), flag))
- || (tile_has_special(ptile, S_AIRBASE)
- && base_flag(base_type_get_by_id(BASE_AIRBASE), flag));
+ struct base_type *pbase;
+
+ pbase = tile_get_base(ptile);
+
+ if (pbase != NULL) {
+ /* Some base at tile, check its flags */
+ return base_flag(pbase, flag);
+ }
+
+ /* No base at tile */
+ return FALSE;
}
/****************************************************************************
diff -Nurd -X.diff_ignore freeciv/common/tile.h freeciv/common/tile.h
--- freeciv/common/tile.h 2007-01-22 17:18:36.000000000 +0200
+++ freeciv/common/tile.h 2007-01-27 19:16:22.000000000 +0200
@@ -63,6 +63,9 @@
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);
+struct base_type *tile_get_base(const struct tile *ptile);
+void tile_add_base(struct tile *ptile, const struct base_type *pbase);
+void tile_remove_base(struct tile *ptile);
bool tile_has_base_flag(const struct tile *ptile, enum base_flag_id flag);
const struct resource *tile_get_resource(const struct tile *ptile);
void tile_set_resource(struct tile *ptile, const struct resource *presource);
diff -Nurd -X.diff_ignore freeciv/common/unit.c freeciv/common/unit.c
--- freeciv/common/unit.c 2007-01-25 17:59:51.000000000 +0200
+++ freeciv/common/unit.c 2007-01-27 19:16:22.000000000 +0200
@@ -726,6 +726,7 @@
{
struct player *pplayer = unit_owner(punit);
struct terrain *pterrain = ptile->terrain;
+ struct base_type *pbase;
switch(activity) {
case ACTIVITY_IDLE:
@@ -815,16 +816,18 @@
return FALSE;
case ACTIVITY_FORTRESS:
+ pbase = tile_get_base(ptile);
return (unit_flag(punit, F_SETTLERS)
&& !tile_get_city(ptile)
&& player_knows_techs_with_flag(pplayer, TF_FORTRESS)
- && !tile_has_special(ptile, S_FORTRESS)
+ && (pbase == NULL || pbase->id != BASE_FORTRESS)
&& !is_ocean(ptile->terrain));
case ACTIVITY_AIRBASE:
+ pbase = tile_get_base(ptile);
return (unit_flag(punit, F_AIRBASE)
&& player_knows_techs_with_flag(pplayer, TF_AIRBASE)
- && !tile_has_special(ptile, S_AIRBASE)
+ && (pbase == NULL || pbase->id != BASE_AIRBASE)
&& !is_ocean(ptile->terrain));
case ACTIVITY_SENTRY:
diff -Nurd -X.diff_ignore freeciv/server/citytools.c freeciv/server/citytools.c
--- freeciv/server/citytools.c 2007-01-27 13:37:22.000000000 +0200
+++ freeciv/server/citytools.c 2007-01-27 19:16:22.000000000 +0200
@@ -1009,8 +1009,7 @@
/* Put vision back to normal, if base acted as a watchtower */
if (tile_has_base_flag(ptile, BF_WATCHTOWER)) {
- tile_clear_special(ptile, S_FORTRESS);
- tile_clear_special(ptile, S_AIRBASE);
+ tile_remove_base(ptile);
unit_list_refresh_vision(ptile->units);
}
diff -Nurd -X.diff_ignore freeciv/server/unittools.c freeciv/server/unittools.c
--- freeciv/server/unittools.c 2007-01-26 22:51:04.000000000 +0200
+++ freeciv/server/unittools.c 2007-01-27 19:16:22.000000000 +0200
@@ -707,6 +707,9 @@
punit->activity_target) >= 1) {
enum tile_special_type what_pillaged = punit->activity_target;
+ /* FIXME: If pillaging some kind of base, should not
+ * touch specials directly but to use base related
+ * functions. */
tile_clear_special(ptile, what_pillaged);
unit_list_iterate (ptile->units, punit2) {
if ((punit2->activity == ACTIVITY_PILLAGE) &&
@@ -743,7 +746,7 @@
if (activity == ACTIVITY_FORTRESS) {
if (total_activity (ptile, ACTIVITY_FORTRESS)
>= tile_activity_time(ACTIVITY_FORTRESS, ptile)) {
- tile_set_special(ptile, S_FORTRESS);
+ tile_add_base(ptile, base_type_get_by_id(BASE_FORTRESS));
map_claim_ownership(ptile, unit_owner(punit), ptile);
unit_activity_done = TRUE;
new_base = TRUE;
@@ -753,7 +756,7 @@
if (activity == ACTIVITY_AIRBASE) {
if (total_activity (ptile, ACTIVITY_AIRBASE)
>= tile_activity_time(ACTIVITY_AIRBASE, ptile)) {
- tile_set_special(ptile, S_AIRBASE);
+ tile_add_base(ptile, base_type_get_by_id(BASE_AIRBASE));
unit_activity_done = TRUE;
new_base = TRUE;
}
@@ -1250,13 +1253,11 @@
{
int cap;
struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
+ struct base_type *pbase = base_type_get_from_special(plrtile->special);
if ((is_allied_city_tile(ptile, pplayer)
&& !is_non_allied_unit_tile(ptile, pplayer))
- || (((contains_special(plrtile->special, S_FORTRESS)
- && base_flag(base_type_get_by_id(BASE_FORTRESS), BF_REFUEL))
- || (contains_special(plrtile->special, S_AIRBASE)
- && base_flag(base_type_get_by_id(BASE_AIRBASE), BF_REFUEL)))
+ || ((pbase != NULL && base_flag(pbase, BF_REFUEL))
&& !is_non_allied_unit_tile(ptile, pplayer)))
return TRUE;
_______________________________________________
Freeciv-dev mailing list
[email protected]
https://mail.gna.org/listinfo/freeciv-dev