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