1 /********************************************************************** 2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation; either version 2, or (at your option) 6 any later version. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 ***********************************************************************/ 13 #ifndef FC__VISION_H 14 #define FC__VISION_H 15 16 #ifdef __cplusplus 17 extern "C" { 18 #endif /* __cplusplus */ 19 20 #include "fc_types.h" 21 22 #include "improvement.h" /* bv_imprs */ 23 24 /**************************************************************************** 25 Vision for cities and units: 26 27 A vision source has a fixed owner and tile; it changes only in range. 28 Vision range is given in radius squared; most such values will come from 29 the ruleset. All vision is circular. 30 31 A vision source is created using vision_new; this creates the source 32 without any sight points. Call vision_change_sight to change the sight 33 points of a vision source (generally called from city_refresh_vision 34 and unit_refresh vision; this can be called liberally to do updates after 35 an effect may have changed the source's vision range). Clear the sight 36 using vision_clear_sight before freeing it with vision_free. 37 38 vision_get_sight returns the sight points of the source. This should 39 only rarely be necessary since all fogging and unfogging operations 40 are taken care of internally. 41 42 vision_reveal_tiles() controls whether the vision source can discover 43 new (unknown) tiles or simply maintain vision on already-known tiles. 44 By default, cities should pass FALSE for this since they cannot 45 discover new tiles. 46 47 ***** IMPORTANT ***** 48 To change any of the parameters given to vision_new - that is, to change 49 the vision source's position (tile) or owner - you must create a new 50 vision and then clear and free the old vision. Order is very important 51 here since you do not want to fog tiles intermediately. You must store 52 a copy of the old vision source, then create and attach and fill out the 53 sight for a new vision source, and only then may you clear and free the 54 old vision source. In most operations you'll want to stick some other 55 code in between so that for the bulk of the operation all tiles are 56 visible. For instance to move a unit: 57 58 old_vision = punit->server.vision; 59 punit->server.vision = vision_new(unit_owner(punit), dest_tile); 60 vision_change_sight(punit->server.vision, 61 get_unit_vision_at(punit, dest_tile)); 62 63 ...then do all the work of moving the unit... 64 65 vision_clear_sight(old_vision); 66 vision_free(old_vision); 67 68 note that for all the code in the middle both the new and the old 69 vision sources are active. The same process applies when transferring 70 a unit or city between players, etc. 71 ****************************************************************************/ 72 73 /* Invariants: V_MAIN vision ranges must always be more than V_INVIS 74 * ranges. */ 75 enum vision_layer { 76 V_MAIN, 77 V_INVIS, 78 V_COUNT 79 }; 80 81 #define vision_layer_iterate(v) { \ 82 enum vision_layer v; \ 83 for (v = 0; v < V_COUNT; v++) { 84 #define vision_layer_iterate_end }} 85 86 87 typedef short int v_radius_t[V_COUNT]; 88 89 struct vision { 90 /* These values cannot be changed after initialization. */ 91 struct player *player; 92 struct tile *tile; 93 bool can_reveal_tiles; 94 95 /* The radius of the vision source. */ 96 v_radius_t radius_sq; 97 }; 98 99 /* Initialize a vision radius array. */ 100 #define V_RADIUS(main_sq, invis_sq) { (main_sq), (invis_sq) } 101 102 #define ASSERT_VISION(v) \ 103 do { \ 104 fc_assert((v)->radius_sq[V_MAIN] >= (v)->radius_sq[V_INVIS]); \ 105 } while(FALSE); 106 107 struct vision *vision_new(struct player *pplayer, struct tile *ptile); 108 void vision_free(struct vision *vision); 109 110 bool vision_reveal_tiles(struct vision *vision, bool reveal_tiles); 111 112 /* This is copied in maphand.c really_give_tile_info_from_player_to_player(), 113 * so be careful with pointers! 114 */ 115 struct vision_site { 116 char name[MAX_LEN_NAME]; 117 struct tile *location; /* Cannot be NULL */ 118 struct player *owner; /* May be NULL, always check! */ 119 120 int identity; /* city > IDENTITY_NUMBER_ZERO */ 121 citizens size; /* city size (0 <= size <= MAX_CITY_SIZE) */ 122 123 bool occupied; 124 bool walls; 125 bool happy; 126 bool unhappy; 127 int style; 128 int city_image; 129 130 bv_imprs improvements; 131 }; 132 133 #define vision_site_owner(v) ((v)->owner) 134 void vision_site_destroy(struct vision_site *psite); 135 struct vision_site *vision_site_new(int identity, struct tile *location, 136 struct player *owner); 137 struct vision_site *vision_site_new_from_city(const struct city *pcity); 138 void vision_site_update_from_city(struct vision_site *psite, 139 const struct city *pcity); 140 141 citizens vision_site_size_get(const struct vision_site *psite); 142 void vision_site_size_set(struct vision_site *psite, citizens size); 143 144 #ifdef __cplusplus 145 } 146 #endif /* __cplusplus */ 147 148 #endif /* FC__VISION_H */ 149