OMATRIX.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /*
  2. * Seven Kingdoms: Ancient Adversaries
  3. *
  4. * Copyright 1997,1998 Enlight Software Ltd.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. //Filename : OMATRIX.H
  21. //Description : Object road direction turn
  22. #ifndef __OMATRIX_H
  23. #define __OMATRIX_H
  24. #ifndef __OUNITRES_H
  25. #include <OUNITRES.h>
  26. #endif
  27. #include <OREGION.h>
  28. //----- Define bit meanings Location::flag ------//
  29. #define LOCATE_WALK_LAND 0x01
  30. #define LOCATE_WALK_SEA 0x02
  31. #define LOCATE_COAST 0x08
  32. // ----- govern the usage of extra_para ---------//
  33. #define LOCATE_SITE_MASK 0xf0
  34. #define LOCATE_HAS_SITE 0x10
  35. #define LOCATE_HAD_WALL 0x20
  36. #define LOCATE_HAS_DIRT 0x30
  37. #define LOCATE_SITE_RESERVED 0xf0
  38. // occupied by other block such as hill, plant
  39. // ----- govern the usage of cargo_recno -------//
  40. #define LOCATE_BLOCK_MASK 0xf00
  41. #define LOCATE_IS_HILL 0x100
  42. #define LOCATE_IS_PLANT 0x200
  43. #define LOCATE_IS_TOWN 0x300
  44. #define LOCATE_IS_FIRM 0x400
  45. #define LOCATE_IS_WALL 0x500
  46. #define LOCATE_IS_ROCK 0xf00
  47. #define LOCATE_POWER_OFF 0x1000 // true if no power_nation_recno can be set in this location
  48. #define LOCATE_HARBOR_BIT 0x2000 // true if the terrain is suitable to build harbor (x,y) to (x+2,y+2)
  49. // ------- constant on visibility ----------//
  50. // const unsigned char FULL_VISIBILITY = MAX_BRIGHTNESS_ADJUST_DEGREE * 8 + 7;
  51. const unsigned char FULL_VISIBILITY = 87;
  52. // if a location has not been explored, visibility = 0
  53. // if a location has been explored, visibility is bewtween 36-87
  54. const unsigned char EXPLORED_VISIBILITY = 30; // don't see this to multiple of 8
  55. const unsigned char MAX_VISIT_LEVEL = FULL_VISIBILITY;
  56. //------- Define structure Location -------//
  57. #pragma pack(1)
  58. struct Location
  59. {
  60. public:
  61. unsigned short loc_flag;
  62. short terrain_id;
  63. short cargo_recno;
  64. short air_cargo_recno;
  65. unsigned char extra_para;
  66. //------------------------------------------------//
  67. // when (loc_flag & LOCATE_SITE_MASK) == LOCATE_HAS_SITE
  68. // > extra_para = raw recno
  69. //
  70. // when (loc_flag & LOCATE_SITE_MASK) == LOCATE_HAD_WALL
  71. // > extra_para = time remained that can't build wall
  72. //
  73. // when (loc_flag & LOCATE_SITE_MASK) == LOCATE_HAS_DIRT
  74. // > extra_para = dirt recno
  75. //
  76. // when (loc_flag & LOCATE_BLOCK_MASK) == LOCATE_IS_HILL
  77. // > cargo_recno = top hill block id
  78. // > extra_para = bottom hill block id
  79. //
  80. // when (loc_flag & LOCATE_BLOCK_MASK) == LOCATE_IS_FIRM
  81. // > cargo_recno = firm recno
  82. //
  83. // when (loc_flag & LOCATE_BLOCK_MASK) == LOCATE_IS_TOWN
  84. // > cargo_recno = town zone recno
  85. //
  86. // when (loc_flag & LOCATE_BLOCK_MASK) == LOCATE_IS_PLANT
  87. // > extra_para = id. of the plant bitmap
  88. // > cargo_recno = low byte - inner x, high byte - inner y
  89. //
  90. // when (loc_flag & LOCATE_BLOCK_MASK) == LOCATION_IS_WALL
  91. // > extra_para = id. of the city wall bitmap
  92. // > high byte of cargo_recno = hit points remained for the wall
  93. //
  94. // when (loc_flag & LOCATE_BLOCK_MASK) == LOCATION_IS_ROCK
  95. // > cargo_recno = rock recno in rock_array
  96. //
  97. // when (loc_flag & LOCATE_BLOCK_MASK) == 0 and cargo_recno != 0
  98. // > carge_recno = unit id
  99. //------------------------------------------------//
  100. char fire_level; // -100 to 100, current fire level
  101. char flammability; // -100 to 100, likelihood of fire
  102. char power_nation_recno; // 0-no nation has power over this location
  103. unsigned char region_id;
  104. unsigned char visit_level; // drop from FULL_VISIBILITY to 0
  105. public:
  106. //------ functions that check the type of the location ------//
  107. int walkable() { return loc_flag & LOCATE_WALK_LAND; }
  108. int sailable() { return loc_flag & LOCATE_WALK_SEA; }
  109. int walkable(int teraMask)
  110. { return loc_flag & teraMask; }
  111. void walkable_reset();
  112. // void walkable_on() { loc_flag |= LOCATE_WALK_LAND; }
  113. void walkable_off() { loc_flag &= ~(LOCATE_WALK_LAND | LOCATE_WALK_SEA); }
  114. void walkable_on(int teraMask) { loc_flag |= teraMask; }
  115. void walkable_off(int teraMask) { loc_flag &= ~teraMask; }
  116. int is_coast() { return loc_flag & LOCATE_COAST; }
  117. // int explored() { return loc_flag & LOCATE_EXPLORED; }
  118. // void explored_on() { loc_flag |= LOCATE_EXPLORED; }
  119. // void explored_off() { loc_flag &= (~LOCATE_EXPLORED); }
  120. int explored() { return visit_level > 0; }
  121. void explored_on() { if( visit_level < EXPLORED_VISIBILITY*2) visit_level = EXPLORED_VISIBILITY*2; }
  122. void explored_off() { visit_level = 0; }
  123. // ---------- visibility --------//
  124. unsigned char visibility() { return visit_level/2; }
  125. void dec_visibility() { if( visit_level > EXPLORED_VISIBILITY*2) --visit_level; }
  126. void set_visited() { visit_level = MAX_VISIT_LEVEL*2; }
  127. void set_visited(unsigned char v) { if( visit_level < v*2) visit_level = v*2; }
  128. int is_plateau();
  129. // ----------- site -------------//
  130. int can_build_site(int teraMask=LOCATE_WALK_LAND)
  131. { return (loc_flag & teraMask) && !(loc_flag & LOCATE_SITE_MASK) && !has_site(); }
  132. void set_site(int siteRecno);
  133. int has_site() { return (loc_flag & LOCATE_SITE_MASK) == LOCATE_HAS_SITE; }
  134. int site_recno() { if( has_site() ) return extra_para; else return 0; }
  135. void remove_site();
  136. // ------------ wall timeout ----------//
  137. int had_wall() { return (loc_flag & LOCATE_SITE_MASK) == LOCATE_HAD_WALL; }
  138. // after wall destructed, cannot build wall again for some time
  139. // the decrease time
  140. // (LOCATE_HAD_WALL)
  141. void set_wall_timeout(int initTimeout);
  142. int wall_timeout() { return extra_para; }
  143. int dec_wall_timeout(int=1);
  144. void remove_wall_timeout();
  145. // ----------- dirt -------------//
  146. int can_add_dirt()
  147. { return !(loc_flag & LOCATE_SITE_MASK); }
  148. void set_dirt(int dirtRecno);
  149. int has_dirt() { return (loc_flag & LOCATE_SITE_MASK) == LOCATE_HAS_DIRT; }
  150. int dirt_recno() { if( has_dirt() ) return extra_para; else return 0; }
  151. void remove_dirt();
  152. // ---------- firm ----------//
  153. int is_firm() { return (loc_flag & LOCATE_BLOCK_MASK) == LOCATE_IS_FIRM; }
  154. int can_build_firm(int teraMask = LOCATE_WALK_LAND)
  155. { return !cargo_recno && (loc_flag & teraMask) && !(loc_flag & LOCATE_BLOCK_MASK) && !is_power_off(); }
  156. // ####### begin Gilbert 17/7 ###########//
  157. int can_build_harbor(int teraMask = LOCATE_WALK_LAND)
  158. { return !cargo_recno && (loc_flag & teraMask) && !(loc_flag & LOCATE_BLOCK_MASK); }
  159. // ####### end Gilbert 17/7 ###########//
  160. void set_firm(int firmRecno);
  161. int firm_recno() { if( is_firm() ) return cargo_recno; else return 0; }
  162. void remove_firm();
  163. // ---------- town ------------//
  164. int is_town() { return (loc_flag & LOCATE_BLOCK_MASK) == LOCATE_IS_TOWN; }
  165. void set_town(int townRecno);
  166. int can_build_town()
  167. { return !cargo_recno && (loc_flag & LOCATE_WALK_LAND) && !(loc_flag & LOCATE_BLOCK_MASK) && !has_site() && !is_power_off(); }
  168. int town_recno() { if( is_town() ) return cargo_recno; else return 0; }
  169. void remove_town();
  170. // ---------- hill -------------//
  171. int has_hill() { return (loc_flag & LOCATE_BLOCK_MASK) == LOCATE_IS_HILL; }
  172. int can_add_hill() // exception : it has already a hill
  173. { return has_hill() || // (loc_flag & LOCATE_WALK_LAND) &&
  174. !cargo_recno && !(loc_flag & (LOCATE_BLOCK_MASK | LOCATE_SITE_MASK)); }
  175. void set_hill(int hillId);
  176. int hill_id1() { return cargo_recno; }
  177. int hill_id2() { return extra_para; }
  178. void remove_hill();
  179. // ---------- wall ------------//
  180. int is_wall() { return (loc_flag & LOCATE_BLOCK_MASK) == LOCATE_IS_WALL; }
  181. int can_build_wall()
  182. { return !cargo_recno && (loc_flag & LOCATE_WALK_LAND) &&
  183. !(loc_flag & (LOCATE_BLOCK_MASK | LOCATE_SITE_MASK)) && !has_site(); }
  184. void set_wall(int wallId, int townRecno, int hitPoints);
  185. void set_wall_creating();
  186. void set_wall_destructing();
  187. void chg_wall_id( int wallId) { extra_para = wallId; }
  188. int wall_id() { if( is_wall() ) return extra_para; else return 0; }
  189. int wall_nation_recno() { return power_nation_recno; }
  190. int wall_hit_point() { return cargo_recno >> 8; }
  191. int wall_town_recno() { return cargo_recno || 0xFF; }
  192. //---------------------------------------------------//
  193. // initial 0, 1 to 100:creating, -1 to -100: destructing
  194. // except 0 or 100, hit point slowly increase by 1
  195. //---------------------------------------------------//
  196. int wall_abs_hit_point() { return wall_hit_point() >= 0? wall_hit_point() : -wall_hit_point(); }
  197. int inc_wall_hit_point(int grow=1);
  198. int attack_wall(int damage=1);
  199. int wall_grade() { return wall_hit_point() >= 0 ? (wall_hit_point()+24) / 25 : (wall_hit_point()-24)/25;}
  200. int is_wall_creating() { return wall_hit_point() > 0; }
  201. int is_wall_destructing() { return wall_hit_point() < 0; }
  202. void remove_wall(int setTimeOut=-1);
  203. // ---------- plant -----------//
  204. int is_plant() { return (loc_flag & LOCATE_BLOCK_MASK) == LOCATE_IS_PLANT; }
  205. int can_add_plant(int teraMask = LOCATE_WALK_LAND)
  206. { return !cargo_recno && (loc_flag & teraMask) && !(loc_flag & (LOCATE_BLOCK_MASK | LOCATE_SITE_MASK)) && !has_site(); }
  207. void set_plant(int plantId, int offsetX, int offsetY);
  208. int plant_id() { if( is_plant() ) return extra_para; else return 0; }
  209. int plant_inner_x() { return cargo_recno & 0xFF; }
  210. int plant_inner_y() { return cargo_recno >> 8; }
  211. void grow_plant() { extra_para++; }
  212. void remove_plant();
  213. // ---------- rock ------------//
  214. int is_rock() { return (loc_flag & LOCATE_BLOCK_MASK) == LOCATE_IS_ROCK; }
  215. int can_add_rock(int teraMask = LOCATE_WALK_LAND)
  216. { return !cargo_recno && (loc_flag & teraMask) && !(loc_flag & LOCATE_BLOCK_MASK); }
  217. void set_rock(short rockArrayRecno);
  218. short rock_array_recno() { if( is_rock() ) return cargo_recno; else return 0; }
  219. void remove_rock();
  220. // call region_type only when generating region number
  221. RegionType region_type() { return walkable()?REGION_LAND:(sailable()?REGION_SEA:REGION_INPASSABLE); }
  222. // --------- functions on fire ---------//
  223. char fire_str() { return fire_level; }
  224. char fire_src() { return flammability; }
  225. void set_fire_str(char str) { fire_level = str; }
  226. void set_fire_src(char src) { flammability = src; }
  227. void add_fire_str(char str) { fire_level += str; }
  228. void add_fire_src(char src) { flammability += src; }
  229. int can_set_fire() { return flammability >= -50; }
  230. //----- functions whose results affected by mobile_type -----//
  231. //int is_blocked(int mobileType) { return mobileType==UNIT_AIR ? air_cargo_recno : cargo_recno; } // return 1 or 0 (although both are the same)
  232. int unit_recno(int mobileType) { return mobileType==UNIT_AIR ? air_cargo_recno : cargo_recno; } // return the exact cargo recno
  233. int has_unit(int mobileType);
  234. int has_any_unit(int mobileType = UNIT_LAND);
  235. int get_any_unit(int& mobileType);
  236. int is_accessible(int mobileType); // whether the location is accessible to the unit of the specific mobile type
  237. int is_unit_group_accessible(int mobileType, DWORD curGroupId);
  238. //int can_move(int mobileType) { return is_accessible(mobileType) && cargo_recno==0; }
  239. int can_move(int mobileType) { return is_accessible(mobileType) && (mobileType==UNIT_AIR ? !air_cargo_recno : !cargo_recno); }
  240. //### begin alex 24/6 ###//
  241. //------------ power --------------//
  242. void set_power_on();
  243. void set_power_off();
  244. int is_power_off();
  245. //#### end alex 24/6 ####//
  246. //----------- harbor bit -----------//
  247. void set_harbor_bit() { loc_flag |= LOCATE_HARBOR_BIT; }
  248. void clear_harbor_bit() { loc_flag &= ~LOCATE_HARBOR_BIT; }
  249. int can_build_whole_harbor() { return loc_flag & LOCATE_HARBOR_BIT; }
  250. };
  251. #pragma pack()
  252. //------------ Define class Matrix -----------//
  253. class World;
  254. class Matrix
  255. {
  256. friend class World;
  257. public:
  258. int max_x_loc, max_y_loc; // read from map file
  259. Location *loc_matrix;
  260. int top_x_loc, top_y_loc; // the top left location of current zoom window
  261. int cur_x_loc, cur_y_loc;
  262. int cur_cargo_width, cur_cargo_height; // cur_x2_loc = cur_x_loc + cur_cargo_width
  263. int disp_x_loc, disp_y_loc; // calculated in Matrix()
  264. int loc_width, loc_height; // passed as para in Matrix()
  265. int win_x1, win_y1, win_x2, win_y2;
  266. int image_x1, image_y1, image_x2, image_y2;
  267. int image_width, image_height;
  268. char own_matrix;
  269. char *save_image_buf;
  270. char just_drawn_flag; // whether the matrix has just been drawn by draw()
  271. public:
  272. virtual ~Matrix();
  273. void init(int,int,int,int,int,int,int,int,int);
  274. void assign_map(Matrix*);
  275. void assign_map(Location*,int,int);
  276. virtual void paint();
  277. virtual void draw();
  278. virtual void disp();
  279. virtual int detect() {return 0;}
  280. virtual void refresh();
  281. virtual void scroll(int,int);
  282. Location* get_loc(int xLoc,int yLoc)
  283. { return loc_matrix+yLoc * max_x_loc + xLoc; }
  284. protected:
  285. virtual void post_draw() {;}
  286. virtual void draw_loc(int x,int y,int xLoc,int yLoc,Location* locPtr) {;}
  287. void init_var();
  288. int valid_cur_box(int=1);
  289. void valid_disp_area(int=0);
  290. };
  291. //--------- Define inline functions ----------//
  292. //-------- Begin of function Location::is_accessible --------//
  293. inline int Location::is_accessible(int mobileType)
  294. {
  295. switch(mobileType)
  296. {
  297. case UNIT_LAND:
  298. return walkable();
  299. break;
  300. case UNIT_SEA:
  301. return sailable();
  302. break;
  303. case UNIT_AIR:
  304. return 1;
  305. break;
  306. }
  307. return 0;
  308. }
  309. //-------- End of function Location::is_accessible --------//
  310. #endif