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 : OSITE.CPP
22 //Description : Object Site
23
24 #include <OINFO.h>
25 #include <OWORLD.h>
26 #include <OTOWN.h>
27 #include <OFIRM.h>
28 #include <OUNIT.h>
29 #include <ONEWS.h>
30 #include <OGODRES.h>
31 #include <ONATION.h>
32 #include <OSITE.h>
33 #include <OPOWER.h>
34
35 //-------------- Define constant -----------//
36
37 #define EXIST_RAW_RESERVE_QTY (MAX_RAW_RESERVE_QTY / 20) // only sites with reserve qty >= 5% of MAX_RAW_RESERVE_QTY are counted as raw sites
38
39 //--------- Begin of function SiteArray::SiteArray -------//
40
SiteArray()41 SiteArray::SiteArray() : DynArrayB(sizeof(Site), 50, DEFAULT_REUSE_INTERVAL_DAYS)
42 {
43 }
44 //----------- End of function SiteArray::SiteArray -------//
45
46
47 //--------- Begin of function SiteArray::~SiteArray -------//
48
~SiteArray()49 SiteArray::~SiteArray()
50 {
51 deinit();
52 }
53 //----------- End of function SiteArray::~SiteArray -------//
54
55
56 //--------- Begin of function SiteArray::init -------//
57
init()58 void SiteArray::init()
59 {
60 untapped_raw_count = 0;
61 std_raw_site_count = 0;
62 }
63 //----------- End of function SiteArray::init -------//
64
65
66 //--------- Begin of function SiteArray::deinit -------//
67
deinit()68 void SiteArray::deinit()
69 {
70 if( size()==0 )
71 return;
72
73 zap(); // zap the DynArrayB
74
75 untapped_raw_count = 0;
76 }
77 //----------- End of function SiteArray::deinit -------//
78
79
80 //--------- Begin of function SiteArray::add_site ---------//
81 //
82 // Add a raw item to the site array
83 //
84 // Return : 1 - the raw is added
85 // 0 - duplicated, not added
86 //
add_site(int xLoc,int yLoc,int siteType,int objectId,int reserveQty)87 int SiteArray::add_site(int xLoc, int yLoc, int siteType, int objectId, int reserveQty)
88 {
89 //----- linkin the raw and update raw attribute ----//
90
91 Site site;
92
93 linkin(&site);
94
95 Site* sitePtr = (Site*) get(recno());
96
97 sitePtr->init(recno(), siteType, xLoc, yLoc);
98
99 sitePtr->object_id = objectId;
100 sitePtr->reserve_qty = reserveQty;
101
102 switch( siteType )
103 {
104 case SITE_RAW:
105 untapped_raw_count++;
106 break;
107
108 case SITE_SCROLL:
109 scroll_count++;
110 break;
111
112 case SITE_GOLD_COIN:
113 gold_coin_count++;
114 break;
115 }
116
117 return 1;
118 }
119 //----------- End of function SiteArray::add_site ----------//
120
121
122 //--------- Begin of function SiteArray::del_site ----------//
123 //
124 // Delete a specified site.
125 //
126 // <int> siteRecno = the record no. of the site to be deleted
127 //
del_site(int siteRecno)128 void SiteArray::del_site(int siteRecno)
129 {
130 err_if( siteRecno == 0 )
131 err_now( "SiteArray::del_site" );
132
133 Site* sitePtr = site_array[siteRecno];
134
135 switch( sitePtr->site_type )
136 {
137 case SITE_RAW:
138 untapped_raw_count--;
139 break;
140
141 case SITE_SCROLL:
142 scroll_count--;
143 break;
144
145 case SITE_GOLD_COIN:
146 gold_coin_count--;
147 break;
148 }
149
150 //-------------------------------//
151
152 sitePtr->deinit();
153
154 linkout(siteRecno);
155
156 if( siteRecno == site_array.selected_recno )
157 site_array.selected_recno = 0;
158 }
159 //--------- End of function SiteArray::del_site ----------//
160
161
162 //--------- Begin of function SiteArray::generate_raw_site ----------//
163 //
164 // Generate raw sites. This function is both called at the beginning
165 // of a game and when existing raw sites are being used up.
166 //
167 // [int] rawGenCount - no. of raw sites to be generated.
168 // (if this is not given, it will use the existing std_raw_site_count)
169 //
generate_raw_site(int rawGenCount)170 void SiteArray::generate_raw_site(int rawGenCount)
171 {
172 if( rawGenCount )
173 std_raw_site_count = rawGenCount; // use this number for determing whether new sites should emerge in the future
174
175 #define MAX_RAW_REGION 3 // maximum no. of regions that has raw sites
176 #define SMALLEST_RAW_REGION 50 // only put raw on the region if its size is larger than this
177 #define REGION_SIZE_PER_RAW 100
178
179 //----- count the no. of existing raw sites -------//
180
181 Site* sitePtr;
182 int existRawSiteCount=0;
183
184 int i;
185 for( i=size() ; i>0 ; i-- )
186 {
187 if( site_array.is_deleted(i) )
188 continue;
189
190 sitePtr = site_array[i];
191
192 if( sitePtr->site_type == SITE_RAW &&
193 sitePtr->reserve_qty >= EXIST_RAW_RESERVE_QTY )
194 {
195 existRawSiteCount++;
196 }
197 }
198
199 if( existRawSiteCount >= std_raw_site_count )
200 return;
201
202 //----- check which regions are valid for raw sites -----//
203
204 int regionCount = MIN( MAX_RAW_REGION, region_array.region_info_count );
205 int validRegionCount, totalValidSize=0;
206 RegionInfo* regionInfo;
207
208 for( validRegionCount=0 ; validRegionCount<regionCount ; validRegionCount++ )
209 {
210 regionInfo = region_array.get_sorted_region(validRegionCount+1);
211
212 if( regionInfo->region_type != REGION_LAND )
213 continue;
214
215 if( regionInfo->region_size < SMALLEST_RAW_REGION )
216 break;
217
218 totalValidSize += regionInfo->region_size;
219 }
220
221 if( validRegionCount==0 ) // valid regions are those that are big enough to put raw sites
222 return;
223
224 //----- count the no. of existing raw sites in each ragion ------//
225
226 int regionId;
227 char regionRawCountArray[MAX_REGION];
228
229 memset( regionRawCountArray, 0, sizeof(regionRawCountArray) );
230
231 for( i=size() ; i>0 ; i-- )
232 {
233 if( site_array.is_deleted(i) )
234 continue;
235
236 sitePtr = site_array[i];
237
238 if( sitePtr->site_type == SITE_RAW &&
239 sitePtr->reserve_qty >= EXIST_RAW_RESERVE_QTY )
240 {
241 regionId = world.get_region_id(sitePtr->map_x_loc, sitePtr->map_y_loc);
242
243 regionRawCountArray[regionId-1]++;
244
245 }
246 }
247
248 //--------- generate raw sites now ----------//
249
250 int avgValidSize = MIN( 10000, totalValidSize / std_raw_site_count );
251 int j, createCount;
252
253 err_when( validRegionCount > region_array.region_info_count || validRegionCount > MAX_RAW_REGION );
254
255 for( int k=0 ; k<10 ; k++ ) // one loop may not be enough to generate all raw sites, have more loops to make sure all are generated
256 {
257 for( i=0 ; i<regionCount ; i++ )
258 {
259 regionInfo = region_array.get_sorted_region(i+1);
260
261 if( regionInfo->region_type != REGION_LAND )
262 continue;
263
264 if( regionInfo->region_size < SMALLEST_RAW_REGION )
265 break;
266
267 createCount = regionInfo->region_size / avgValidSize;
268 createCount = MAX(1, createCount);
269
270 //--------- create now --------//
271
272 for( j=regionRawCountArray[regionInfo->region_id-1] ; j<createCount ; j++ ) // if currently there are already some, don't create new ones
273 {
274 if( create_raw_site(regionInfo->region_id) )
275 {
276 if( ++existRawSiteCount == std_raw_site_count )
277 return;
278 }
279 }
280 }
281 }
282 }
283 //--------- End of function SiteArray::generate_raw_site ----------//
284
285
286 //--------- Begin of function SiteArray::create_raw_site ----------//
287 //
288 // <int> regionId - if this parameter is given, the raw site
289 // will be built on this region.
290 // [int] townRecno - if this parameter is given, the raw site
291 // will be built near this town.
292 //
create_raw_site(int regionId,int townRecno)293 int SiteArray::create_raw_site(int regionId, int townRecno)
294 {
295 //-------- count the no. of each raw material -------//
296
297 Site* sitePtr;
298 short rawCountArray[MAX_RAW];
299
300 memset( rawCountArray, 0, sizeof(rawCountArray) );
301
302 int i;
303 for( i=size(); i>0 ; i-- )
304 {
305 if( site_array.is_deleted(i) )
306 continue;
307
308 sitePtr = site_array[i];
309
310 if( sitePtr->site_type == SITE_RAW )
311 {
312 err_when( sitePtr->object_id < 1 || sitePtr->object_id > MAX_RAW );
313
314 rawCountArray[ sitePtr->object_id-1 ]++;
315 }
316 }
317
318 //---- find the minimum raw count ----//
319
320 int minCount=0xFFFF;
321
322 for( i=0 ; i<MAX_RAW ; i++ )
323 {
324 if( rawCountArray[i] < minCount )
325 minCount = rawCountArray[i];
326 }
327
328 //----- pick a raw material type -----//
329
330 int rawId = misc.random(MAX_RAW)+1;
331
332 for( i=0 ; i<MAX_RAW ; i++ )
333 {
334 if( ++rawId > MAX_RAW )
335 rawId = 1;
336
337 if( rawCountArray[rawId-1] == minCount ) // don't use this raw type unless it is one of the less available ones.
338 break;
339 }
340
341 //--------- create the raw site now ------//
342
343 int locX1, locY1, locX2, locY2;
344 int maxTries;
345
346 if( townRecno )
347 {
348 #define MAX_TOWN_SITE_DISTANCE 10
349
350 Town* townPtr = town_array[townRecno];
351
352 locX1 = townPtr->center_x - MAX_TOWN_SITE_DISTANCE;
353 locX2 = townPtr->center_x + MAX_TOWN_SITE_DISTANCE;
354 locY1 = townPtr->center_y - MAX_TOWN_SITE_DISTANCE;
355 locY2 = townPtr->center_y + MAX_TOWN_SITE_DISTANCE;
356
357 if(locX1<0)
358 locX1 = 0;
359 else if(locX2>=MAX_WORLD_X_LOC)
360 locX2 = MAX_WORLD_X_LOC-1;
361
362 if(locY1<0)
363 locY1 = 0;
364 else if(locY2>=MAX_WORLD_Y_LOC)
365 locY2 = MAX_WORLD_Y_LOC-1;
366
367 maxTries = (locX2-locX1+1)*(locY2-locY1+1);
368 regionId = townPtr->region_id;
369 }
370 else
371 {
372 locX1 = 0;
373 locY1 = 0;
374 locX2 = MAX_WORLD_X_LOC-1;
375 locY2 = MAX_WORLD_Y_LOC-1;
376
377 maxTries = 10000;
378 }
379
380 //----- randomly locate a space to add the site -----//
381
382 if( world.locate_space_random(locX1, locY1, locX2, locY2,
383 5, 5, maxTries, regionId, 1) ) // 5,5 are the size of the raw site, it must be large enough for a mine to build and 1 location for the edges. The last para 1 = site building mode
384 {
385 int reserveQty = MAX_RAW_RESERVE_QTY * (50 + misc.random(50)) / 100;
386
387 add_site( locX1+2, locY1+2, SITE_RAW, rawId, reserveQty ); // xLoc+1 & yLoc+1 as the located size is 3x3, the raw site is at the center of it
388
389 return 1;
390 }
391 else
392 {
393 return 0;
394 }
395 }
396 //--------- End of function SiteArray::create_raw_site ----------//
397
398
399 //--------- Begin of function SiteArray::scan_site ----------//
400 //
401 // Scan for the a site that is closest the given location.
402 //
403 // <int> xLoc, yLoc - the location given.
404 // [int] siteType - if given, only scan for this site (default: 0)
405 //
406 // return: <int> nearestSiteRecno - the recno of the raw materials
407 // that is nearest to the given location.
408 //
scan_site(int xLoc,int yLoc,int siteType)409 int SiteArray::scan_site(int xLoc, int yLoc, int siteType)
410 {
411 Site* sitePtr;
412 int siteDis, minDis=0x7FFFFFFF, nearestSiteRecno=0;
413
414 for( int i=site_array.size() ; i>0 ; i-- )
415 {
416 if( site_array.is_deleted(i) )
417 continue;
418
419 sitePtr = site_array[i];
420
421 if( siteType==0 || sitePtr->site_type==siteType )
422 {
423 siteDis = misc.points_distance( xLoc, yLoc, sitePtr->map_x_loc, sitePtr->map_y_loc );
424
425 if( siteDis < minDis )
426 {
427 minDis = siteDis;
428 nearestSiteRecno = i;
429 }
430 }
431 }
432
433 return nearestSiteRecno;
434 }
435 //---------- End of function SiteArray::scan_site -----------//
436
437
438 //--------- Begin of function SiteArray::next_day ----------//
439 //
next_day()440 void SiteArray::next_day()
441 {
442 if( info.game_date%30 == 0 )
443 {
444 generate_raw_site(); // check if we need to generate existing raw sites are being used up and if we need to generate new ones
445 }
446
447 //-- if there is any scroll or gold coins available, ask AI to get them --//
448
449 if(scroll_count || gold_coin_count)
450 {
451 int aiGetSiteObject = (info.game_date%5 == 0);
452
453 Site* sitePtr;
454 Location *locPtr;
455
456 for(int i=size(); i; i--)
457 {
458 if(is_deleted(i))
459 continue;
460
461 sitePtr = site_array[i];
462
463 switch(sitePtr->site_type)
464 {
465 case SITE_SCROLL:
466 case SITE_GOLD_COIN:
467 locPtr = world.get_loc(sitePtr->map_x_loc, sitePtr->map_y_loc);
468
469 //---- if the unit is standing on a scroll site -----//
470
471 if(locPtr->has_unit(UNIT_LAND))
472 {
473 sitePtr->get_site_object( locPtr->unit_recno(UNIT_LAND) );
474 }
475 else if(aiGetSiteObject)
476 {
477 sitePtr->ai_get_site_object();
478 }
479 break;
480 }
481 }
482 }
483
484 //-------- debug testing --------//
485
486 #ifdef DEBUG
487
488 if( info.game_date%10 == 0 )
489 {
490 Site* sitePtr;
491 Location* locPtr;
492
493 for( int i=1 ; i<=size() ; i++ )
494 {
495 if( site_array.is_deleted(i) )
496 continue;
497
498 sitePtr = site_array[i];
499
500 locPtr = world.get_loc( sitePtr->map_x_loc, sitePtr->map_y_loc );
501
502 err_when( !locPtr->has_site() );
503 err_when( locPtr->site_recno() != i );
504
505 if( sitePtr->has_mine )
506 {
507 err_when( !locPtr->is_firm() );
508 err_when( firm_array[locPtr->firm_recno()]->firm_id != FIRM_MINE );
509 }
510 else
511 {
512 err_when( locPtr->is_firm() || locPtr->is_town() );
513 }
514 }
515 }
516 #endif
517 }
518 //--------- End of function SiteArray::next_day ----------//
519
520
521 //--------- Begin of function SiteArray::ai_get_site_object -------//
522 //
523 // Notify AI units to acquire scrolls or gold coins available on the
524 // map.
525 //
ai_get_site_object()526 void SiteArray::ai_get_site_object()
527 {
528 Site* sitePtr;
529
530 for( int i=1 ; i<=size() ; i++ )
531 {
532 if( site_array.is_deleted(i) )
533 continue;
534
535 sitePtr = site_array[i];
536
537 if( sitePtr->site_type == SITE_SCROLL ||
538 sitePtr->site_type == SITE_GOLD_COIN )
539 {
540 sitePtr->ai_get_site_object();
541 }
542 }
543 }
544 //----------- End of function SiteArray::ai_get_site_object -------//
545
546
547 //------- Begin of function Site::ai_get_site_object -------//
548 //
549 // Ask AI units around to get the object on this site.
550 //
ai_get_site_object()551 int Site::ai_get_site_object()
552 {
553 #define NOTIFY_GET_RANGE 30 // only notify units within this range
554 #define MAX_UNIT_TO_ORDER 5
555
556 int xOffset, yOffset;
557 int xLoc, yLoc;
558 Location* locPtr;
559 Unit* unitPtr;
560 int unitOrderedCount=0;
561 int siteRaceId = 0;
562
563 if( site_type == SITE_SCROLL )
564 siteRaceId = god_res[object_id]->race_id;
565
566 for( int i=2 ; i<NOTIFY_GET_RANGE*NOTIFY_GET_RANGE ; i++ )
567 {
568 misc.cal_move_around_a_point(i, NOTIFY_GET_RANGE, NOTIFY_GET_RANGE, xOffset, yOffset);
569
570 xLoc = map_x_loc + xOffset;
571 yLoc = map_y_loc + yOffset;
572
573 xLoc = MAX(0, xLoc);
574 xLoc = MIN(MAX_WORLD_X_LOC-1, xLoc);
575
576 yLoc = MAX(0, yLoc);
577 yLoc = MIN(MAX_WORLD_Y_LOC-1, yLoc);
578
579 locPtr = world.get_loc(xLoc, yLoc);
580
581 if( !locPtr->has_unit(UNIT_LAND) )
582 continue;
583
584 //------------------------------//
585
586 int unitRecno = locPtr->unit_recno(UNIT_LAND);
587
588 if( unit_array.is_deleted(unitRecno) )
589 continue;
590
591 unitPtr = unit_array[unitRecno];
592
593 if( !unitPtr->race_id || !unitPtr->ai_unit || unitPtr->ai_action_id )
594 continue;
595
596 if( siteRaceId && siteRaceId != unitPtr->race_id )
597 continue;
598
599 unitPtr->move_to(map_x_loc, map_y_loc);
600
601 //--- if the unit is just standing next to the site ---//
602
603 if( abs(map_x_loc-xLoc)<=1 && abs(map_y_loc-yLoc)<=1 )
604 {
605 return 1;
606 }
607 else // order more than one unit to get the site at the same time
608 {
609 if( ++unitOrderedCount >= MAX_UNIT_TO_ORDER )
610 return 1;
611 }
612 }
613
614 return 0;
615 }
616 //-------- End of function Site::ai_get_site_object -------//
617
618
619 //--------- Begin of function SiteArray::go_to_a_raw_site -------//
620 //
621 // Go to an untapped raw site.
622 //
go_to_a_raw_site()623 void SiteArray::go_to_a_raw_site()
624 {
625 //----- try to locate an untapped raw site -----//
626
627 Site* sitePtr;
628 //### begin alex 22/10 ###//
629 int arraySize = size();
630 int i = selected_recno ? selected_recno : 0;
631 //#### end alex 22/10 ####//
632
633 //### begin alex 22/10 ###//
634 //for( int i=1 ; i<=size() ; i++ )
635 //{
636 int j;
637 for( j=1 ; j<=arraySize ; j++ )
638 {
639 if(++i > arraySize)
640 i = 1;
641 //#### end alex 22/10 ####//
642 if( site_array.is_deleted(i) )
643 continue;
644
645 sitePtr = site_array[i];
646
647 if( !sitePtr->has_mine )
648 {
649 if( world.get_loc(sitePtr->map_x_loc, sitePtr->map_y_loc)->explored() )
650 {
651 world.go_loc( sitePtr->map_x_loc, sitePtr->map_y_loc, 1 ); // 1-select the object on the location
652 return;
653 }
654 }
655 }
656
657 //---- if no untapped raw sites left, jump to built mines ----//
658 //### begin alex 22/10 ###//
659 i = 1;
660 if(firm_array.selected_recno)
661 {
662 //------- get the site_recno if a mine is selected ---------//
663 Firm *firmPtr = firm_array[firm_array.selected_recno];
664 if(firmPtr->firm_id==FIRM_MINE)
665 {
666 int x1 = firmPtr->loc_x1;
667 int y1 = firmPtr->loc_y1;
668 int x2 = firmPtr->loc_x2;
669 int y2 = firmPtr->loc_y2;
670
671 for(int count=1; count<=arraySize; ++count)
672 {
673 if(site_array.is_deleted(count))
674 continue;
675
676 sitePtr = site_array[count];
677 if(sitePtr->map_x_loc>=x1 && sitePtr->map_x_loc<=x2 && sitePtr->map_y_loc>=y1 && sitePtr->map_y_loc<=y2)
678 {
679 i = count;
680 break;
681 }
682 }
683 }
684 }
685 //#### end alex 22/10 ####//
686
687 //### begin alex 22/10 ###//
688 //for( i=1 ; i<=size() ; i++ )
689 //{
690 for( j=1 ; j<=arraySize ; j++ )
691 {
692 if(++i > arraySize)
693 i = 1;
694 //#### end alex 22/10 ####//
695
696 if( site_array.is_deleted(i) )
697 continue;
698
699 sitePtr = site_array[i];
700
701 if( world.get_loc(sitePtr->map_x_loc, sitePtr->map_y_loc)->explored() )
702 {
703 world.go_loc( sitePtr->map_x_loc, sitePtr->map_y_loc, 1 ); // 1-select the object on the location
704 return;
705 }
706 }
707 }
708 //----------- End of function SiteArray::go_to_a_raw_site -------//
709
710
711 //--------- Begin of function Site::init ----------//
712 //
init(int siteRecno,int siteType,int xLoc,int yLoc)713 void Site::init(int siteRecno, int siteType, int xLoc, int yLoc)
714 {
715 site_recno = siteRecno;
716 site_type = siteType;
717 map_x_loc = xLoc;
718 map_y_loc = yLoc;
719 has_mine = 0;
720
721 //------- set world's location --------//
722
723 Location* locPtr = world.get_loc(xLoc, yLoc);
724
725 locPtr->set_site(siteRecno);
726
727 region_id = locPtr->region_id;
728 }
729 //---------- End of function Site::init -----------//
730
731
732 //--------- Begin of function Site::deinit ----------//
733 //
deinit()734 void Site::deinit()
735 {
736 //------ reset world's location ---------//
737
738 world.get_loc(map_x_loc, map_y_loc)->remove_site();
739 }
740 //---------- End of function Site::deinit -----------//
741
742
743 //--------- Begin of function Site::get_site_object ----------//
744 //
745 // An unit takes the object from the site
746 //
747 // <int> unitRecno - recno of the unit that takes the object on the site.
748 //
get_site_object(int unitRecno)749 int Site::get_site_object(int unitRecno)
750 {
751 Unit* unitPtr = unit_array[unitRecno];
752 int objectTaken=0;
753
754 if( !unitPtr->nation_recno )
755 return 0;
756
757 //----- if this is a scroll site ------//
758
759 if( site_type == SITE_SCROLL )
760 {
761 if( god_res[object_id]->race_id == unitPtr->race_id )
762 {
763 god_res[object_id]->enable_know(unitPtr->nation_recno);
764
765 objectTaken = 1;
766
767 news_array.scroll_acquired(unitPtr->nation_recno, god_res[object_id]->race_id );
768 }
769 }
770
771 //------ if there are gold coins on this site -----//
772
773 if( site_type == SITE_GOLD_COIN )
774 {
775 nation_array[unitPtr->nation_recno]->add_income(INCOME_TREASURE, object_id);
776 objectTaken = 1;
777
778 if( unitPtr->nation_recno == nation_array.player_recno )
779 news_array.monster_gold_acquired(object_id);
780 }
781
782 //---- if the object has been taken by the unit ----//
783
784 if( objectTaken )
785 {
786 site_array.del_site(site_recno);
787 return 1;
788 }
789
790 return 0;
791 }
792 //---------- End of function Site::get_site_object -----------//
793
794
795 //------- Begin of function SiteArray::is_deleted -----//
796
is_deleted(int recNo)797 int SiteArray::is_deleted(int recNo)
798 {
799 Site* sitePtr = (Site*) get(recNo);
800
801 return !sitePtr || sitePtr->site_type==0;
802 }
803 //--------- End of function SiteArray::is_deleted ----//
804
805 #ifdef DYNARRAY_DEBUG_ELEMENT_ACCESS
806
807 //------- Begin of function SiteArray::operator[] -----//
808
operator [](int recNo)809 Site* SiteArray::operator[](int recNo)
810 {
811 Site* sitePtr = (Site*) get(recNo);
812
813 if( !sitePtr || sitePtr->site_type==0 )
814 err.run( "SiteArray[] is deleted" );
815
816 return sitePtr;
817 }
818 //--------- End of function SiteArray::operator[] ----//
819
820
821 //------- Begin of function SiteArray::operator() -----//
822
operator ()()823 Site* SiteArray::operator()()
824 {
825 Site* sitePtr = (Site*) get();
826
827 if( !sitePtr || sitePtr->site_type==0 )
828 err.run( "SiteArray[recno()] is deleted" );
829
830 return sitePtr;
831 }
832 //--------- End of function SiteArray::operator() ----//
833
834 #endif
835
836
837 //--------- Begin of function SiteArray::disp_next --------//
838 //
839 // Display the next object of the same type.
840 //
841 // <int> seekDir : -1 - display the previous one in the list.
842 // 1 - display the next one in the list.
843 //
844 // <int> sameNation - whether display the next object of the same
845 // nation only or of any nation.
846 //
disp_next(int seekDir,int sameNation)847 void SiteArray::disp_next(int seekDir, int sameNation)
848 {
849 if( !selected_recno )
850 return;
851
852 int siteRecno = selected_recno;
853 Site* sitePtr = (*this)[selected_recno];
854 int siteType = sitePtr->site_type;
855
856 while(1)
857 {
858 if( seekDir < 0 )
859 {
860 siteRecno--;
861
862 if( siteRecno < 1 )
863 siteRecno = size();
864 }
865 else
866 {
867 siteRecno++;
868
869 if( siteRecno > size() )
870 siteRecno = 1;
871 }
872
873 if( is_deleted(siteRecno) )
874 continue;
875
876 sitePtr = (*this)[siteRecno];
877
878 //--- check if the location of this site has been explored ---//
879
880 if( !world.get_loc(sitePtr->map_x_loc, sitePtr->map_y_loc)->explored() )
881 continue;
882
883 //---------------------------------//
884
885 if( sitePtr->site_type == siteType )
886 {
887 power.reset_selection();
888 selected_recno = siteRecno;
889
890 world.go_loc( sitePtr->map_x_loc, sitePtr->map_y_loc );
891 return;
892 }
893
894 //--- if the recno loops back to the starting one ---//
895
896 if( siteRecno == selected_recno )
897 break;
898 }
899 }
900 //----------- End of function SiteArray::disp_next --------//
901