OMATRIX.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972
  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.CPP
  21. //Description : Object road direction turn, derived by World, Chain class
  22. #include <ALL.h>
  23. #include <OVGA.h>
  24. #include <OMOUSE.h>
  25. #include <OSYS.h>
  26. #include <OSITE.h>
  27. #include <OFIRM.h>
  28. #include <OTERRAIN.h>
  29. #include <OPLANT.h>
  30. #include <OPOWER.h>
  31. #include <OUNIT.h>
  32. #include <OWORLD.h>
  33. #include <OHILLRES.h>
  34. // --------- define constant ----------//
  35. #define DEFAULT_WALL_TIMEOUT 10
  36. #define WALL_DEFENCE 5
  37. #define MIN_WALL_DAMAGE 3
  38. //----------- Begin of function Matrix::init ----------//
  39. //
  40. // <int> winX1,winY1 = the coordination of the win,
  41. // winX2,winY2 including the scroll bar and up,down panel
  42. //
  43. // <int> areaWidth = width and height of the bitmap area
  44. // areaHeight
  45. //
  46. // <int> locWidth = width and height of each location
  47. // <int> locHeight
  48. //
  49. // <int> maxCargoWidth = max. widht of height of cargo
  50. // maxCargoHeight (unit is Loc, not pixel
  51. //
  52. // <int> saveAreaToBuf = whether save the area to a buffer,
  53. // set it true - when the area will be ruined by
  54. // animation
  55. //
  56. void Matrix::init(int winX1, int winY1, int winX2, int winY2, int areaWidth,
  57. int areaHeight, int locWidth, int locHeight, int saveAreaToBuf )
  58. {
  59. err_when(FULL_VISIBILITY != MAX_BRIGHTNESS_ADJUST_DEGREE * 8 + 7);
  60. win_x1 = winX1; // window area,
  61. win_y1 = winY1; // including scroll bar
  62. win_x2 = winX2;
  63. win_y2 = winY2;
  64. image_width = areaWidth;
  65. image_height = areaHeight;
  66. image_x1 = win_x1; // bitmap area only
  67. image_y1 = win_y1;
  68. image_x2 = image_x1+image_width-1;
  69. image_y2 = image_y1+image_height-1;
  70. loc_width = locWidth;
  71. loc_height = locHeight;
  72. //----------------------------------------------//
  73. if( saveAreaToBuf )
  74. save_image_buf = mem_add( sizeof(short)*2 + image_width * image_height ); // 2 <short> for width & height info
  75. else
  76. save_image_buf = NULL;
  77. just_drawn_flag = 0;
  78. //---------------------------------------------//
  79. loc_matrix = NULL;
  80. top_x_loc = 0;
  81. top_y_loc = 0;
  82. cur_x_loc = -1;
  83. cur_y_loc = -1;
  84. }
  85. //------------- End of function Matrix::init -----------//
  86. //----------- Begin of function Matrix::~Matrix ----------//
  87. Matrix::~Matrix()
  88. {
  89. if( save_image_buf )
  90. mem_del( save_image_buf );
  91. if( own_matrix && loc_matrix ) // the matrix is allocated by us
  92. mem_del( loc_matrix );
  93. }
  94. //------------- End of function Matrix::~Matrix -----------//
  95. //----------- Begin of function Matrix::assign_map -----------//
  96. //
  97. // Instead of loading the map file, we can assign a pre-loaded
  98. // map to it.
  99. //
  100. void Matrix::assign_map(Matrix* matrixPtr)
  101. {
  102. own_matrix = 0;
  103. loc_matrix = matrixPtr->loc_matrix;
  104. max_x_loc = matrixPtr->max_x_loc;
  105. max_y_loc = matrixPtr->max_y_loc;
  106. init_var();
  107. top_x_loc = 0;
  108. top_y_loc = 0;
  109. cur_x_loc = 0;
  110. cur_y_loc = 0;
  111. }
  112. //------------- End of function Matrix::assign_map -----------//
  113. //----------- Begin of function Matrix::assign_map -----------//
  114. //
  115. // Instead of loading the map file, we can assign a pre-loaded
  116. // map to it.
  117. //
  118. void Matrix::assign_map(Location* locMatrix, int maxXLoc, int maxYLoc )
  119. {
  120. own_matrix = 0;
  121. loc_matrix = locMatrix;
  122. max_x_loc = maxXLoc;
  123. max_y_loc = maxYLoc;
  124. init_var();
  125. cur_x_loc = 0;
  126. cur_y_loc = 0;
  127. }
  128. //------------- End of function Matrix::assign_map -----------//
  129. //-------- Begin of function Matrix::init_var ---------//
  130. //
  131. // Called by assign_map() & MatrixMap::set_view_map()
  132. //
  133. void Matrix::init_var()
  134. {
  135. disp_x_loc = image_width/loc_width;
  136. if( disp_x_loc > max_x_loc )
  137. disp_x_loc = max_x_loc;
  138. disp_y_loc = image_height/loc_height;
  139. if( disp_y_loc > max_y_loc )
  140. disp_y_loc = max_y_loc;
  141. }
  142. //------------ End of function Matrix::init_var -----------//
  143. //----------- Begin of function Matrix::paint ------------//
  144. //
  145. // Paint world window and scroll bars
  146. //
  147. void Matrix::paint()
  148. {
  149. }
  150. //----------- End of function Matrix::paint ------------//
  151. //---------- Begin of function Matrix::draw ------------//
  152. //
  153. // Draw world zoom
  154. //
  155. void Matrix::draw()
  156. {
  157. int i=0, x, y, xLoc, yLoc;
  158. Location* locPtr;
  159. int maxXLoc = top_x_loc + disp_x_loc; // divide by 2 for world_info
  160. int maxYLoc = top_y_loc + disp_y_loc;
  161. //----------------------------------------------------//
  162. for( y=image_y1,yLoc=top_y_loc ; yLoc<maxYLoc ; yLoc++, y+=loc_height )
  163. {
  164. if( (i++)%10==0 )
  165. sys.yield();
  166. locPtr = get_loc(top_x_loc,yLoc);
  167. for( x=image_x1,xLoc=top_x_loc ; xLoc<maxXLoc ; xLoc++, x+=loc_width, locPtr++ )
  168. draw_loc( x, y, xLoc, yLoc, locPtr );
  169. }
  170. //---- derived function for ZoomMatrix & MapMatrix ----//
  171. post_draw(); // if they have anything to draw after the basic terrain (e.g.firms)
  172. //---------------------------------------------------//
  173. if( save_image_buf )
  174. {
  175. vga_back.read_bitmap( image_x1, image_y1, image_x2, image_y2, save_image_buf );
  176. just_drawn_flag = 1;
  177. }
  178. }
  179. //------------ End of function Matrix::draw ------------//
  180. //----------- Begin of function Matrix::disp ------------//
  181. //
  182. // Display the drawn world zoom on screen
  183. //
  184. void Matrix::disp()
  185. {
  186. if( !just_drawn_flag ) // if the map has just been drawn in draw()
  187. {
  188. if( save_image_buf )
  189. {
  190. err_when( image_width%4 != 0 );
  191. #ifdef DEBUG_TIMING
  192. unsigned long start_time, elapsed_time;
  193. int i = 0;
  194. start_time = m.get_time();
  195. for( i = 0; i < 10; ++i)
  196. #endif
  197. vga_back.put_bitmap_dw( image_x1, image_y1, save_image_buf );
  198. #ifdef DEBUG_TIMING
  199. elapsed_time = m.get_time() - start_time;
  200. // dummy
  201. start_time = 0;
  202. #endif
  203. }
  204. else
  205. draw();
  206. }
  207. just_drawn_flag=0;
  208. }
  209. //----------- End of function Matrix::disp ------------//
  210. //--------- Begin of function Matrix::refresh ------------//
  211. //
  212. void Matrix::refresh()
  213. {
  214. if( save_image_buf ) // redraw the background, so disp() won't use the old background
  215. draw();
  216. disp();
  217. }
  218. //----------- End of function Matrix::refresh ------------//
  219. //----------- Begin of function Matrix::valid_cur_box ------------//
  220. //
  221. // Validate the position of the zoom area box, scroll window if necessary
  222. // called by detect_area()
  223. //
  224. // Call valid_cur_box() if current highlight box is specified,
  225. // adjust window area to fit it
  226. //
  227. // Call valid_disp_area() if window display area is specified,
  228. // adjust highlight box to fit it
  229. //
  230. // [int] = callRefresh = call refresh() if scrolled
  231. // (default : 1)
  232. //
  233. // return : <int> whether the window is scrolled
  234. //
  235. int Matrix::valid_cur_box(int callRefresh)
  236. {
  237. int scrolledFlag=0;
  238. //------- valid current highlight box first --------//
  239. if( cur_x_loc < 0 )
  240. cur_x_loc = 0;
  241. if( cur_y_loc < 0 )
  242. cur_y_loc = 0;
  243. if( cur_x_loc+cur_cargo_width > max_x_loc )
  244. cur_x_loc = max_x_loc-cur_cargo_width;
  245. if( cur_y_loc+cur_cargo_height > max_y_loc )
  246. cur_y_loc = max_y_loc-cur_cargo_height;
  247. //--- scroll the display area to fit the current highlight ---//
  248. if( cur_x_loc < top_x_loc ||
  249. cur_x_loc >= top_x_loc + disp_x_loc )
  250. {
  251. top_x_loc = cur_x_loc - disp_x_loc/2;
  252. if( top_x_loc < 0 )
  253. top_x_loc = 0;
  254. if( top_x_loc + disp_x_loc > max_x_loc )
  255. top_x_loc = max_x_loc - disp_x_loc;
  256. scrolledFlag=1;
  257. }
  258. if( cur_y_loc < top_y_loc ||
  259. cur_y_loc >= top_y_loc + disp_y_loc )
  260. {
  261. top_y_loc = cur_y_loc - disp_y_loc/2;
  262. if( top_y_loc < 0 )
  263. top_y_loc = 0;
  264. if( top_y_loc + disp_y_loc > max_y_loc )
  265. top_y_loc = max_y_loc - disp_y_loc;
  266. scrolledFlag=1;
  267. }
  268. return scrolledFlag;
  269. }
  270. //----------- End of function Matrix::valid_cur_box ------------//
  271. //--------- Begin of function Matrix::valid_disp_area ------//
  272. //
  273. // Validate the current location, adjust it if it is out of border
  274. //
  275. // Call valid_cur_box() if current highlight box is specified,
  276. // adjust window area to fit it
  277. //
  278. // Call valid_disp_area() if window display area is specified,
  279. // adjust highlight box to fit it
  280. //
  281. // [int] fitInBox = whether must fit in current box into the
  282. // display area (default : 0)
  283. //
  284. void Matrix::valid_disp_area(int fitInBox)
  285. {
  286. //------- valid display area first ---------//
  287. if( top_x_loc < 0 )
  288. top_x_loc = 0;
  289. if( top_y_loc < 0 )
  290. top_y_loc = 0;
  291. if( top_x_loc + disp_x_loc > max_x_loc )
  292. top_x_loc = max_x_loc - disp_x_loc;
  293. if( top_y_loc + disp_y_loc > max_y_loc )
  294. top_y_loc = max_y_loc - disp_y_loc;
  295. //--- if the current highlighted location is outside the display area, then reposition it ----//
  296. if( fitInBox )
  297. {
  298. if( cur_x_loc < top_x_loc )
  299. cur_x_loc = top_x_loc;
  300. if( cur_x_loc >= top_x_loc + disp_x_loc )
  301. cur_x_loc = top_x_loc + disp_x_loc - 1;
  302. if( cur_y_loc < top_y_loc )
  303. cur_y_loc = top_y_loc;
  304. if( cur_y_loc >= top_y_loc + disp_y_loc )
  305. cur_y_loc = top_y_loc + disp_y_loc - 1;
  306. }
  307. }
  308. //--------- End of function Matrix::valid_disp_area ------//
  309. //---------- Begin of function Matrix::scroll -----------//
  310. //
  311. // <int> xScroll - horizontal scroll step (negative:left, positive:right)
  312. // <int> yScroll - vertical scroll step (negative:left, positive:right)
  313. //
  314. void Matrix::scroll(int xScroll, int yScroll)
  315. {
  316. top_x_loc += xScroll;
  317. top_y_loc += yScroll;
  318. valid_disp_area();
  319. }
  320. //----------- End of function Matrix::scroll ------------//
  321. // ------- Begin of function Location::walkable_reset -----/
  322. void Location::walkable_reset()
  323. {
  324. if( loc_flag & LOCATE_BLOCK_MASK )
  325. {
  326. walkable_off();
  327. }
  328. else
  329. {
  330. if( terrain_res[terrain_id]->average_type == TERRAIN_OCEAN)
  331. {
  332. loc_flag |= LOCATE_WALK_SEA;
  333. }
  334. else
  335. {
  336. loc_flag |= LOCATE_WALK_LAND;
  337. }
  338. }
  339. }
  340. // ----------- End of function Location::walkable_reset -------//
  341. // ----------- Begin of function Location::is_plateau ---------//
  342. int Location::is_plateau()
  343. {
  344. return terrain_res[terrain_id]->average_type == TERRAIN_DARK_DIRT; //**BUGHERE, to be changed to TERRAIN_HILL when the no. of terrain type has been reduced to 4 from 7
  345. }
  346. // ----------- End of function Location::is_plateau ---------//
  347. //---------- Begin of function Location::set_site ------------//
  348. //
  349. void Location::set_site(int siteRecno)
  350. {
  351. err_when( !can_build_site() );
  352. loc_flag = loc_flag & ~LOCATE_SITE_MASK | LOCATE_HAS_SITE;
  353. // loc_flag |= LOCATION_HAS_SITE;
  354. extra_para = siteRecno;
  355. }
  356. //------------ End of function Location::set_site ------------//
  357. //---------- Begin of function Location::remove_site ------------//
  358. //
  359. void Location::remove_site()
  360. {
  361. err_when( !has_site() );
  362. loc_flag &= ~LOCATE_SITE_MASK;
  363. extra_para = 0;
  364. }
  365. //------------ End of function Location::remove_site ------------//
  366. //------------ Begin of function Location::set_wall_timeout ------------//
  367. void Location::set_wall_timeout(int initTimeout)
  368. {
  369. err_when((!can_build_site() && !had_wall()) || initTimeout <= 0);
  370. loc_flag = (loc_flag & ~LOCATE_SITE_MASK) | LOCATE_HAD_WALL;
  371. extra_para = (unsigned char) initTimeout;
  372. }
  373. //------------ End of function Location::set_wall_timeout ------------//
  374. //------------ Begin of function Location::dec_wall_timeout ------------//
  375. // return : true if the timeout drop to zero, and is removed
  376. int Location::dec_wall_timeout(int t)
  377. {
  378. err_when( !had_wall() );
  379. if( (extra_para -= t) <= 0)
  380. {
  381. remove_wall_timeout();
  382. return 1;
  383. }
  384. return 0;
  385. }
  386. //------------ End of function Location::dec_wall_timeout ------------//
  387. //------------ Begin of function Location::remove_wall_timeout ------------//
  388. void Location::remove_wall_timeout()
  389. {
  390. err_when( !had_wall() );
  391. loc_flag &= ~LOCATE_SITE_MASK;
  392. extra_para = 0;
  393. }
  394. //------------ End of function Location::remove_wall_timeout ------------//
  395. //---------- Begin of function Location::set_dirt ------------//
  396. //
  397. void Location::set_dirt(int dirtRecno)
  398. {
  399. err_when( !can_add_dirt() );
  400. loc_flag = loc_flag & ~LOCATE_SITE_MASK | LOCATE_HAS_DIRT;
  401. extra_para = dirtRecno;
  402. }
  403. //------------ End of function Location::set_dirt ------------//
  404. //---------- Begin of function Location::remove_dirt ------------//
  405. //
  406. void Location::remove_dirt()
  407. {
  408. err_when( !has_dirt() );
  409. loc_flag &= ~LOCATE_SITE_MASK;
  410. extra_para = 0;
  411. }
  412. //------------ End of function Location::remove_dirt ------------//
  413. //---------- Begin of function Location::set_firm ------------//
  414. //
  415. void Location::set_firm(int firmRecno)
  416. {
  417. // can't check the terrain type here
  418. err_when( !can_build_firm() && !firmRecno );
  419. walkable_off();
  420. loc_flag = (loc_flag & ~LOCATE_BLOCK_MASK) | LOCATE_IS_FIRM;
  421. cargo_recno = firmRecno;
  422. }
  423. //------------ End of function Location::set_firm ------------//
  424. //---------- Begin of function Location::remove_firm ------------//
  425. //
  426. void Location::remove_firm()
  427. {
  428. err_when( !is_firm() );
  429. loc_flag &= ~LOCATE_BLOCK_MASK;
  430. cargo_recno = 0;
  431. walkable_reset();
  432. err_when(is_firm());
  433. }
  434. //------------ End of function Location::remove_firm ------------//
  435. //---------- Begin of function Location::set_town ------------//
  436. //
  437. void Location::set_town(int townRecno)
  438. {
  439. err_when( !can_build_town() || !townRecno );
  440. walkable_off();
  441. loc_flag = loc_flag & ~LOCATE_BLOCK_MASK | LOCATE_IS_TOWN;
  442. cargo_recno = townRecno;
  443. }
  444. //------------ End of function Location::set_town ------------//
  445. //---------- Begin of function Location::remove_town ------------//
  446. //
  447. void Location::remove_town()
  448. {
  449. err_when( !is_town() );
  450. loc_flag &= ~LOCATE_BLOCK_MASK;
  451. cargo_recno = 0;
  452. walkable_reset();
  453. err_when(is_firm());
  454. }
  455. //------------ End of function Location::remove_town ------------//
  456. //---------- Begin of function Location::set_hill ------------//
  457. // set hillId to hill_id1 (cargo_recno) or hill_id2 (extra_para)
  458. // depend on the priority of the hill block
  459. void Location::set_hill(int hillId)
  460. {
  461. err_when( !can_add_hill() || !hillId );
  462. err_when( !hill_res[hillId] );
  463. // clear LOCATE_WALK_LAND and LOCATE_WALK_SEA bits
  464. walkable_off();
  465. if( has_hill() )
  466. {
  467. // already has a hill block
  468. // compare which is on the top, swap if necessary
  469. if(hill_res[cargo_recno]->priority <= hill_res[hillId]->priority)
  470. {
  471. err_when(cargo_recno >= 256);
  472. extra_para = (unsigned char) cargo_recno;
  473. cargo_recno = hillId;
  474. }
  475. else
  476. {
  477. // if two hill blocks there, the lower one get replaced
  478. err_when( hillId >= 256);
  479. extra_para = (unsigned char) hillId;
  480. }
  481. }
  482. else
  483. {
  484. // no existing hill block
  485. loc_flag = loc_flag & ~(LOCATE_BLOCK_MASK | LOCATE_SITE_MASK )
  486. | (LOCATE_IS_HILL | LOCATE_SITE_RESERVED);
  487. cargo_recno = hillId;
  488. extra_para = 0;
  489. }
  490. }
  491. //------------ End of function Location::set_hill ------------//
  492. //---------- Begin of function Location::remove_hill ------------//
  493. void Location::remove_hill()
  494. {
  495. err_when( !has_hill() );
  496. loc_flag &= ~(LOCATE_BLOCK_MASK | LOCATE_SITE_MASK);
  497. extra_para = 0;
  498. cargo_recno = 0;
  499. // err_when(is_firm());
  500. // BUGHERE : need to call walkable_reset();
  501. }
  502. //------------ End of function Location::remove_hill ------------//
  503. //---------- Begin of function Location::set_wall ------------//
  504. //
  505. // <int> wallId = the id. of the wall
  506. // <int> townRecno = recno of the town which the wall belongs to
  507. // <int> hitPoints = hit points remained for the wall
  508. //
  509. void Location::set_wall(int wallId, int townRecno, int hitPoints)
  510. {
  511. err_when( !can_build_wall() || !wallId );
  512. walkable_off();
  513. loc_flag = loc_flag & ~(LOCATE_BLOCK_MASK | LOCATE_SITE_MASK )
  514. | (LOCATE_IS_WALL | LOCATE_SITE_RESERVED);
  515. extra_para = wallId;
  516. cargo_recno = (hitPoints<<8) + townRecno;
  517. }
  518. //------------ End of function Location::set_wall ------------//
  519. //------------ Begin of function Location::set_wall_creating ------------//
  520. void Location::set_wall_creating()
  521. {
  522. err_when( !is_wall() );
  523. int hp = wall_hit_point();
  524. if( hp < 0)
  525. hp = -hp;
  526. cargo_recno = (hp << 8) | wall_town_recno();
  527. }
  528. //------------ End of function Location::set_wall_creating ------------//
  529. //------------ Begin of function Location::set_wall_destructing------------//
  530. void Location::set_wall_destructing()
  531. {
  532. err_when( !is_wall() );
  533. int hp = wall_hit_point();
  534. if( hp > 0)
  535. hp = -hp;
  536. cargo_recno = (hp << 8) | wall_town_recno();
  537. }
  538. //------------ End of function Location::set_wall_desctructing ------------//
  539. //------------ Begin of function Location::inc_wall_hit_point ------------//
  540. int Location::inc_wall_hit_point(int grow)
  541. {
  542. err_when( !is_wall() );
  543. int hp = wall_hit_point();
  544. if( hp < 0 && hp > -grow)
  545. {
  546. hp = 0;
  547. }
  548. else if( hp > 100-grow)
  549. {
  550. hp = 100;
  551. }
  552. else
  553. hp += grow;
  554. cargo_recno = (hp << 8) | wall_town_recno();
  555. return hp;
  556. }
  557. //------------ End of function Location::inc_wall_hit_point ------------//
  558. //------------ Begin of function Location::attack_wall ------------//
  559. //
  560. // attack wall
  561. // int damage damage to a wall
  562. // note : if the return value is 0, call world.correct_wall to
  563. // correct the shape of the adjacent squares
  564. //
  565. int Location::attack_wall(int damage)
  566. {
  567. err_when( !is_wall() );
  568. if(damage >= WALL_DEFENCE + MIN_WALL_DAMAGE) // damage >= 8, damage -= 5
  569. damage -= WALL_DEFENCE;
  570. else if( damage >= MIN_WALL_DAMAGE ) // 3 <= damage < 8, damage = 3
  571. damage = MIN_WALL_DAMAGE;
  572. else if( damage <= 0) // 0 < damage < 3, no change to
  573. return wall_hit_point(); // no change to hit point to damage
  574. int hp = wall_hit_point();
  575. if( hp > 0)
  576. {
  577. hp-= damage;
  578. if( hp <= 0)
  579. {
  580. hp = 0;
  581. remove_wall();
  582. return 0;
  583. }
  584. }
  585. else if( hp < 0)
  586. {
  587. hp+= damage;
  588. if( hp >= 0)
  589. {
  590. hp = 0;
  591. remove_wall();
  592. return 0;
  593. }
  594. }
  595. cargo_recno = (hp << 8) | wall_town_recno();
  596. return hp;
  597. }
  598. //------------ End of function Location::attack_wall ------------//
  599. //---------- Begin of function Location::remove_wall ------------//
  600. //
  601. // <int> setTimeOut call set_wall_timeout to refuse building wall at the same place
  602. // 0 to disable timeout, -1 to take default: 10
  603. //
  604. void Location::remove_wall(int setTimeOut)
  605. {
  606. err_when( !is_wall() );
  607. loc_flag &= ~(LOCATE_BLOCK_MASK | LOCATE_SITE_MASK);
  608. extra_para = 0;
  609. cargo_recno = 0;
  610. walkable_reset();
  611. if( setTimeOut < 0)
  612. set_wall_timeout( DEFAULT_WALL_TIMEOUT );
  613. else if( setTimeOut > 0)
  614. {
  615. err_when( setTimeOut > 255 );
  616. set_wall_timeout( setTimeOut );
  617. }
  618. err_when(is_firm());
  619. }
  620. //------------ End of function Location::remove_wall ------------//
  621. //---------- Begin of function Location::set_plant ------------//
  622. //
  623. void Location::set_plant(int plantId, int offsetX, int offsetY)
  624. {
  625. err_when( !can_add_plant() || !plantId );
  626. walkable_off();
  627. loc_flag = loc_flag & ~(LOCATE_BLOCK_MASK | LOCATE_SITE_MASK )
  628. | (LOCATE_IS_PLANT | LOCATE_SITE_RESERVED);
  629. extra_para = plantId;
  630. cargo_recno = (offsetY<<8) + offsetX;
  631. err_when(cargo_recno==0 || is_firm());
  632. }
  633. //------------ End of function Location::set_plant ------------//
  634. //---------- Begin of function Location::remove_plant ------------//
  635. //
  636. void Location::remove_plant()
  637. {
  638. err_when( !is_plant() );
  639. loc_flag &= ~(LOCATE_BLOCK_MASK | LOCATE_SITE_MASK);
  640. extra_para = 0;
  641. cargo_recno = 0;
  642. walkable_reset();
  643. err_when(is_firm());
  644. }
  645. //------------ End of function Location::remove_plant ------------//
  646. //---------- Begin of function Location::set_rock ------------//
  647. //
  648. void Location::set_rock(short rockArrayRecno)
  649. {
  650. err_when( !can_add_rock(3) || !rockArrayRecno );
  651. walkable_off();
  652. loc_flag = loc_flag & ~LOCATE_BLOCK_MASK | LOCATE_IS_ROCK;
  653. cargo_recno = rockArrayRecno;
  654. }
  655. //------------ End of function Location::set_rock ------------//
  656. //---------- Begin of function Location::remove_rock ------------//
  657. //
  658. void Location::remove_rock()
  659. {
  660. err_when( !is_rock() );
  661. loc_flag &= ~LOCATE_BLOCK_MASK;
  662. cargo_recno = 0;
  663. walkable_reset();
  664. }
  665. //------------ End of function Location::remove_rock ------------//
  666. //-------- Begin of function Location::has_unit --------//
  667. // return 0 or unit recno
  668. int Location::has_unit(int mobileType)
  669. {
  670. switch(mobileType)
  671. {
  672. // #### patch begin Gilbert 5/8 #######//
  673. case UNIT_LAND:
  674. if( walkable() )
  675. return cargo_recno;
  676. break;
  677. case UNIT_SEA:
  678. if( sailable() )
  679. return cargo_recno;
  680. break;
  681. case UNIT_AIR:
  682. return air_cargo_recno;
  683. break;
  684. // #### patch end Gilbert 5/8 #######//
  685. }
  686. return 0;
  687. }
  688. //-------- End of function Location::has_unit --------//
  689. //-------- Begin of function Location::has_any_unit --------//
  690. // <int> mobileType - (default: UNIT_LAND)
  691. //
  692. // return the mobile_type if there is any unit here
  693. // return 0 otherwise
  694. //
  695. int Location::has_any_unit(int mobileType)
  696. {
  697. if(mobileType==UNIT_LAND)
  698. {
  699. if(air_cargo_recno)
  700. return UNIT_AIR;
  701. else if(walkable() && cargo_recno)
  702. return UNIT_LAND;
  703. else if(sailable() && cargo_recno)
  704. return UNIT_SEA;
  705. }
  706. else
  707. {
  708. if(walkable() && cargo_recno)
  709. return UNIT_LAND;
  710. else if(sailable() && cargo_recno)
  711. return UNIT_SEA;
  712. else if(air_cargo_recno)
  713. return UNIT_AIR;
  714. }
  715. return 0;
  716. }
  717. //-------- End of function Location::has_any_unit --------//
  718. //-------- Begin of function Location::get_any_unit --------//
  719. //
  720. // <int&> mobileType - var for returning the mobile type of
  721. // unit in the location.
  722. //
  723. // return: <int> unit recno of the unit.
  724. //
  725. int Location::get_any_unit(int& mobileType)
  726. {
  727. if(air_cargo_recno)
  728. {
  729. mobileType = UNIT_AIR;
  730. return air_cargo_recno;
  731. }
  732. else if(walkable() && cargo_recno)
  733. {
  734. mobileType = UNIT_LAND;
  735. return cargo_recno;
  736. }
  737. else if(sailable() && cargo_recno)
  738. {
  739. mobileType = UNIT_SEA;
  740. return cargo_recno;
  741. }
  742. return 0;
  743. }
  744. //-------- End of function Location::get_any_unit --------//
  745. //-------- Begin of function Location::is_unit_group_accessible --------//
  746. //
  747. // Return whether the location can be accessed by the unit of the specific
  748. // unit group id.
  749. //
  750. // return : <int> whether the location can be accessed by the unit of
  751. // the specific unit group id.
  752. //
  753. int Location::is_unit_group_accessible(int mobileType, DWORD curGroupId)
  754. {
  755. if(is_accessible(mobileType))
  756. {
  757. int unitRecno = unit_recno(mobileType);
  758. return unitRecno==0 || unit_array[unitRecno]->unit_group_id == curGroupId;
  759. }
  760. return 0;
  761. }
  762. //-------- End of function Location::is_unit_group_accessible --------//
  763. //### begin alex 24/6 ###//
  764. //-------- Begin of function Location::set_power_on --------//
  765. void Location::set_power_on()
  766. {
  767. loc_flag &= ~LOCATE_POWER_OFF;
  768. }
  769. //-------- End of function Location::set_power_on --------//
  770. //-------- Begin of function Location::set_power_off --------//
  771. void Location::set_power_off()
  772. {
  773. loc_flag |= LOCATE_POWER_OFF;
  774. }
  775. //-------- End of function Location::set_power_off --------//
  776. //-------- Begin of function Location::is_power_off --------//
  777. int Location::is_power_off()
  778. {
  779. return (loc_flag & LOCATE_POWER_OFF);
  780. }
  781. //-------- End of function Location::is_power_off --------//
  782. //#### end alex 24/6 ####//