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    : OSPY.CPP
22 //Description : Object Spy
23 
24 #include <OPOWER.h>
25 #include <OGAME.h>
26 #include <ODATE.h>
27 #include <ONEWS.h>
28 #include <OFONT.h>
29 #include <OUNIT.h>
30 #include <OWORLD.h>
31 #include <OBUTTON.h>
32 #include <OFIRM.h>
33 #include <OTOWN.h>
34 #include <ONATION.h>
35 #include <ORACERES.h>
36 #include <OSYS.h>
37 #include <OSPY.h>
38 #include <vga_util.h>
39 #include "gettext.h"
40 
41 //----- Define constants for viewing secret menu ------//
42 
43 #define SECRET_REPORT_COUNT 7
44 
45 static const char* 	secret_report_str_array[] = { N_("Kingdoms"), N_("Villages"), N_("Economy"), N_("Trade"), N_("Military"), N_("Technology"), N_("Espionage") };
46 static char	 	secret_view_mode_array[]  = { MODE_NATION, MODE_TOWN, MODE_ECONOMY, MODE_TRADE, MODE_MILITARY, MODE_TECH, MODE_SPY };
47 static char	 	secret_view_skill_array[] = { 40, 20, 30, 30, 50, 40, 90 };
48 
49 static Button	button_secret_report_array[SECRET_REPORT_COUNT];
50 static Button	button_secret_report_cancel;
51 
52 
53 //--------- Begin of function SpyArray::SpyArray ----------//
54 
SpyArray()55 SpyArray::SpyArray() : DynArrayB(sizeof(Spy), 10)
56 {
57 }
58 //--------- End of function SpyArray::SpyArary ----------//
59 
60 
61 //------- Begin of function SpyArray::~SpyArray ----------//
62 //
~SpyArray()63 SpyArray::~SpyArray()
64 {
65 	deinit();
66 }
67 //--------- End of function SpyArray::~SpyArray ----------//
68 
69 
70 //--------- Begin of function SpyArray::init ----------//
71 //
init()72 void SpyArray::init()
73 {
74 }
75 //---------- End of function SpyArray::init ----------//
76 
77 
78 //--------- Begin of function SpyArray::deinit ----------//
79 //
deinit()80 void SpyArray::deinit()
81 {
82 	if( size()==0 )
83 		return;
84 
85 	//-------- zap the array -----------//
86 
87 	zap();
88 }
89 //---------- End of function SpyArray::deinit ----------//
90 
91 
92 //--------- Begin of function SpyArray::add_spy ----------//
93 //
94 // <int> unitRecno - unit recno of the spy
95 // <int> spySkill  - spying skill of the unit
96 //
97 // return: <int> recno of the spy record added
98 //
add_spy(int unitRecno,int spySkill)99 int SpyArray::add_spy(int unitRecno, int spySkill)
100 {
101 	Spy 	spy;
102 	Unit* unitPtr = unit_array[unitRecno];
103 
104 	memset( &spy, 0, sizeof(spy) );
105 
106 	spy.spy_place 			= SPY_MOBILE;
107 	spy.spy_place_para	= unitRecno;
108 	spy.spy_skill 			= spySkill;
109 	spy.spy_loyalty 		= unitPtr->loyalty;
110 	spy.race_id			   = unitPtr->race_id;
111 	spy.name_id				= unitPtr->name_id;
112 
113 	err_when( unitPtr->race_id < 1 || unitPtr->race_id > MAX_RACE );
114 
115 	err_when( nation_array.is_deleted(unitPtr->nation_recno) );
116 
117 	spy.true_nation_recno    = unitPtr->nation_recno;
118 	spy.cloaked_nation_recno = unitPtr->nation_recno;
119 
120 	//--- spies hold a use right of the name id even though the unit itself will register the usage right of the name already ---//
121 
122 	race_res[spy.race_id]->use_name_id(spy.name_id);		// the spy will free it up in deinit(). Keep an additional right because when a spy is assigned to a town, the normal program will free up the name id., so we have to keep an additional copy
123 
124 	//------- link in the spy_array -------//
125 
126 	linkin( &spy );
127 
128 	((Spy*)get())->spy_recno = recno();
129 
130 	return recno();
131 }
132 //---------- End of function SpyArray::add_spy ----------//
133 
134 
135 //--------- Begin of function SpyArray::add_spy ----------//
136 //
137 // This overloaded version of add_spy() just add a spy without
138 // setting parameters of the Spy.
139 //
140 // return: <int> recno of the spy record added
141 //
add_spy()142 int SpyArray::add_spy()
143 {
144 	Spy spy;
145 
146 	memset( &spy, 0, sizeof(spy) );
147 
148 	linkin( &spy );
149 
150 	((Spy*)get())->spy_recno = recno();
151 
152 	return recno();
153 }
154 //---------- End of function SpyArray::add_spy ----------//
155 
156 
157 //--------- Begin of function SpyArray::del_spy ----------//
158 //
159 // <int> spyRecno - recno of the spy to be deleted
160 //
del_spy(int spyRecno)161 void SpyArray::del_spy(int spyRecno)
162 {
163 	spy_array[spyRecno]->deinit();
164 
165 	linkout(spyRecno);
166 }
167 //---------- End of function SpyArray::del_spy ----------//
168 
169 
170 //--------- Begin of function SpyArray::next_day ----------//
171 //
next_day()172 void SpyArray::next_day()
173 {
174 	int  spyCount = size();
175 	Spy* spyPtr;
176 
177 	for( int i=1 ; i<=spyCount ; i++ )
178 	{
179 		if( spy_array.is_deleted(i) )
180 			continue;
181 
182 		spyPtr = spy_array[i];
183 
184 		spyPtr->next_day();
185 
186 		if( spy_array.is_deleted(i) )
187 			continue;
188 
189 		if( nation_array[spyPtr->true_nation_recno]->is_ai() )
190 		{
191 			SpyProcess spyProcess(i);
192 			spyProcess.process_ai();
193 		}
194 	}
195 
196 	//---------- update Firm::sabotage_level ----------//
197 
198 	if( info.game_date%15==0 )
199 		process_sabotage();
200 }
201 //---------- End of function SpyArray::next_day ----------//
202 
203 
204 //--------- Begin of function SpyArray::find_town_spy ----------//
205 //
206 // Find a spy meeting the specific criteria
207 //
208 // <int> townRecno - town recno of the spy to find
209 // <int> raceId    - race id. of the spy to find
210 // <int> spySeq	 - sequence id. of the spy in spy_array
211 //
212 // return: <int> recno of the spy found
213 //
find_town_spy(int townRecno,int raceId,int spySeq)214 int SpyArray::find_town_spy(int townRecno, int raceId, int spySeq)
215 {
216 	int  spyCount=size(), matchCount=0;
217 	Spy* spyPtr;
218 
219 	for( int i=1 ; i<=spyCount ; i++ )
220 	{
221 		if( spy_array.is_deleted(i) )
222 			continue;
223 
224 		spyPtr = spy_array[i];
225 
226 		if( spyPtr->spy_place==SPY_TOWN &&
227 			 spyPtr->spy_place_para==townRecno &&
228 			 spyPtr->race_id==raceId )
229 		{
230 
231 			if( ++matchCount == spySeq )
232 				return i;
233 		}
234 	}
235 
236 	return 0;
237 }
238 //---------- End of function SpyArray::find_town_spy ----------//
239 
240 
241 //--------- Begin of function SpyArray::process_sabotage ----------//
242 //
process_sabotage()243 void SpyArray::process_sabotage()
244 {
245 	Spy*  spyPtr;
246 	Firm* firmPtr;
247 
248 	//-------- reset firms' sabotage_level -------//
249 
250 	int i;
251 	for( i=firm_array.size() ; i>0 ; i-- )
252 	{
253 		if( firm_array.is_deleted(i) )
254 			continue;
255 
256 		firm_array[i]->sabotage_level = 0;
257 	}
258 
259 	//------- increase firms' sabotage_level -----//
260 
261 	for( i=spy_array.size() ; i>0 ; i-- )
262 	{
263 		if( spy_array.is_deleted(i) )
264 			continue;
265 
266 		spyPtr = spy_array[i];
267 
268 		if( spyPtr->action_mode == SPY_SABOTAGE )
269 		{
270 			err_when( spyPtr->spy_place != SPY_FIRM );
271 
272 			firmPtr = firm_array[spyPtr->spy_place_para];
273 
274 			firmPtr->sabotage_level += spyPtr->spy_skill/5;
275 
276 			if( firmPtr->sabotage_level > 100 )
277 				firmPtr->sabotage_level = 100;
278 		}
279 	}
280 }
281 //---------- End of function SpyArray::process_sabotage ----------//
282 
283 
284 //--------- Begin of function SpyArray::mobilize_all_spy ----------//
285 //
286 // Mobilize all spies of the specific nation in the specific place.
287 //
288 // <int> spyPlace     - place id. of the spy
289 // <int> spyPlacePara - town or firm recno of the spy's staying
290 // <int> nationRecno	 - recno of the nation which the spy should
291 //							   be mobilized.
292 //
mobilize_all_spy(int spyPlace,int spyPlacePara,int nationRecno)293 void SpyArray::mobilize_all_spy(int spyPlace, int spyPlacePara, int nationRecno)
294 {
295 	Spy* spyPtr;
296 
297 	for( int i=size() ; i>0 ; i-- )
298 	{
299 		if( spy_array.is_deleted(i) )
300 			continue;
301 
302 		spyPtr = spy_array[i];
303 
304 		if( spyPtr->spy_place == spyPlace &&
305 			 spyPtr->spy_place_para == spyPlacePara &&
306 			 spyPtr->true_nation_recno == nationRecno )
307 		{
308 			if( spyPtr->spy_place == SPY_TOWN )
309 				spyPtr->mobilize_town_spy();
310 
311 			else if( spyPtr->spy_place == SPY_FIRM )
312 				spyPtr->mobilize_firm_spy();
313 		}
314 	}
315 }
316 //---------- End of function SpyArray::mobilize_all_spy ----------//
317 
318 
319 //--------- Begin of function SpyArray::disp_view_secret_menu ---------//
320 //
disp_view_secret_menu(int spyRecno,int refreshFlag)321 void SpyArray::disp_view_secret_menu(int spyRecno, int refreshFlag)
322 {
323 	if( refreshFlag != INFO_REPAINT )
324 		return;
325 
326 	//------------------------------------//
327 
328 	vga_util.d3_panel_up( INFO_X1, INFO_Y1, INFO_X2, INFO_Y1+42 );
329 
330 	font_san.put_paragraph( INFO_X1+7, INFO_Y1+5, INFO_X2-7, INFO_Y2-5,
331 									_("Steal which type of secrets?") );
332 
333 	//------------------------------------//
334 
335 	int  y=INFO_Y1+45;
336 
337 	err_when( spy_array.is_deleted(spyRecno) );
338 
339 	Spy* spyPtr = spy_array[spyRecno];
340 
341 	for( int i=0 ; i<SECRET_REPORT_COUNT ; i++ )
342 	{
343 		if( spyPtr->spy_skill >= secret_view_skill_array[i] )
344 		{
345 			button_secret_report_array[i].paint_text( INFO_X1, y, INFO_X2, y+21, _(secret_report_str_array[i]) );
346 			y+=23;
347 		}
348 		else
349 		{
350 			button_secret_report_array[i].reset();
351 		}
352 	}
353 
354 	button_secret_report_cancel.paint_text( INFO_X1, y, INFO_X2, y+22, _("Cancel") );
355 }
356 //----------- End of function SpyArray::disp_view_secret_menu -----------//
357 
358 
359 //--------- Begin of function SpyArray::detect_view_secret_menu ---------//
360 //
361 // <int> spyRecno    - recno of the spy to view secret info.
362 // <int> nationRecno - recno of the nation which this spy is going to investigate
363 //
detect_view_secret_menu(int spyRecno,int nationRecno)364 int SpyArray::detect_view_secret_menu(int spyRecno, int nationRecno)
365 {
366 	//---- detect secret report button ----//
367 
368 	int rc=0;
369 
370 	for( int i=0 ; i<SECRET_REPORT_COUNT ; i++ )
371 	{
372 		if( button_secret_report_array[i].detect() )
373 		{
374 			sys.set_view_mode( secret_view_mode_array[i], nationRecno, spyRecno );
375 			rc=1;
376 			break;
377 		}
378 	}
379 
380 	//-------- detect cancel button --------//
381 
382 	if( button_secret_report_cancel.detect() )
383 		rc = 1;
384 
385 	return rc;
386 }
387 //----------- End of function SpyArray::detect_view_secret_menu -----------//
388 
389 
390 //--------- Begin of function SpyArray::update_firm_spy_count ---------//
391 //
392 // Update the player_spy_count of this firm. This function is called
393 // when the firm change its nation.
394 //
395 // <int> firmRecno - recno of the firm to be updated.
396 //
update_firm_spy_count(int firmRecno)397 void SpyArray::update_firm_spy_count(int firmRecno)
398 {
399 	//---- recalculate Firm::player_spy_count -----//
400 
401 	Spy*  spyPtr;
402 	Firm* firmPtr = firm_array[firmRecno];
403 
404 	firmPtr->player_spy_count = 0;
405 
406 	for( int i=spy_array.size() ; i>0 ; i-- )
407 	{
408 		if( spy_array.is_deleted(i) )
409 			continue;
410 
411 		spyPtr = spy_array[i];
412 
413 		if( spyPtr->spy_place == SPY_FIRM &&
414 			 spyPtr->spy_place_para == firmRecno &&
415 			 spyPtr->true_nation_recno == nation_array.player_recno )
416 		{
417 			firmPtr->player_spy_count++;
418 		}
419 	}
420 }
421 //----------- End of function SpyArray::update_firm_spy_count -----------//
422 
423 
424 //--------- Begin of function SpyArray::change_cloaked_nation ---------//
425 //
426 // Change the cloak of all the spies in the specific place.
427 //
428 // This function is called when a firm or town change nation.
429 //
430 // <int> spyPlace        - spy place
431 // <int> spyPlacePara    - spy place para
432 // <int> fromNationRecno - change any spies in the place whose cloaked_nation_recno
433 // <int> toNationRecno     is fromNationRecno to toNationRecno.
434 //
change_cloaked_nation(int spyPlace,int spyPlacePara,int fromNationRecno,int toNationRecno)435 void SpyArray::change_cloaked_nation(int spyPlace, int spyPlacePara, int fromNationRecno, int toNationRecno)
436 {
437 	Spy* spyPtr;
438 
439 	for( int i=spy_array.size() ; i>0 ; i-- )
440 	{
441 		if( spy_array.is_deleted(i) )
442 			continue;
443 
444 		spyPtr = spy_array[i];
445 
446 		if( spyPtr->cloaked_nation_recno != fromNationRecno )
447 			continue;
448 
449 		if( spyPtr->spy_place != spyPlace )
450 			continue;
451 
452 		//--- check if the spy is in the specific firm or town ---//
453 
454 		if( spyPlace == SPY_FIRM || spyPlace == SPY_TOWN )  // only check spy_place_para when spyPlace is SPY_TOWN or SPY_FIRM
455 		{
456 			if( spyPtr->spy_place_para != spyPlacePara )
457 				continue;
458 		}
459 
460 		if(spyPlace==spyPtr->spy_place && spyPlacePara==spyPtr->spy_place_para &&
461 			spyPtr->true_nation_recno==toNationRecno)
462 			spyPtr->set_action_mode(SPY_IDLE);
463 
464 		//----- if the spy is associated with a unit (mobile or firm overseer), we call Unit::spy_chnage_nation() ---//
465 
466 		if( spyPlace == SPY_FIRM )
467 		{
468 			int firmOverseerRecno = firm_array[spyPtr->spy_place_para]->overseer_recno;
469 
470 			if( firmOverseerRecno && unit_array[firmOverseerRecno]->spy_recno == i )
471 			{
472 				unit_array[firmOverseerRecno]->spy_change_nation(toNationRecno, COMMAND_AUTO);
473 				continue;
474 			}
475 		}
476 		else if( spyPlace == SPY_MOBILE )
477 		{
478 			unit_array[spyPtr->spy_place_para]->spy_change_nation(toNationRecno, COMMAND_AUTO);
479 			continue;
480 		}
481 
482 		//---- otherwise, just change the spy cloak ----//
483 
484 		spyPtr->cloaked_nation_recno = toNationRecno;
485 	}
486 }
487 //----------- End of function SpyArray::change_cloaked_nation -----------//
488 
489 
490 //--------- Begin of function SpyArray::total_spy_skill_level ---------//
491 //
492 // Calculate the combined skill levels of all the spies of the
493 // specific nation in the specific place.
494 //
495 // <int> spyPlace        - spy place
496 // <int> spyPlacePara    - spy place para
497 // <int> spyNationRecno  - nation recno
498 // <int&> spyCount		 - the total no. of spies meeting the criteria.
499 //
total_spy_skill_level(int spyPlace,int spyPlacePara,int spyNationRecno,int & spyCount)500 int SpyArray::total_spy_skill_level(int spyPlace, int spyPlacePara, int spyNationRecno, int& spyCount)
501 {
502 	int  totalSpyLevel=0;
503 	Spy* spyPtr;
504 
505 	spyCount = 0;
506 
507 	for( int i=spy_array.size() ; i>0 ; i-- )
508 	{
509 		if( spy_array.is_deleted(i) )
510 			continue;
511 
512 		spyPtr = spy_array[i];
513 
514 		if( spyPtr->true_nation_recno != spyNationRecno )
515 			continue;
516 
517 		if( spyPtr->spy_place != spyPlace )
518 			continue;
519 
520 		if( spyPtr->spy_place_para != spyPlacePara )
521 			continue;
522 
523 		spyCount++;
524 
525 		totalSpyLevel += spyPtr->spy_skill;
526 	}
527 
528 	return totalSpyLevel;
529 }
530 //----------- End of function SpyArray::total_spy_skill_level -----------//
531 
532 
533 //-------- Begin of function SpyArray::catch_spy ------//
534 //
535 // <int> spyPlace - either SPY_TOWN or SPY_FIRM
536 // <int> spyPlacePara - town_recno or firm_recno
537 //
catch_spy(int spyPlace,int spyPlacePara)538 int SpyArray::catch_spy(int spyPlace, int spyPlacePara)
539 {
540 	int nationRecno, totalPop;
541 
542 	if( spyPlace == SPY_TOWN )
543 	{
544 		Town* townPtr = town_array[spyPlacePara];
545 
546 		nationRecno = townPtr->nation_recno;
547 		totalPop    = townPtr->population;
548 	}
549 	else if( spyPlace == SPY_FIRM )
550 	{
551 		Firm* firmPtr = firm_array[spyPlacePara];
552 
553 		nationRecno = firmPtr->nation_recno;
554 		totalPop    = firmPtr->worker_count + (firmPtr->overseer_recno>0);
555 	}
556 	else
557 		err_here();
558 
559 	//--- calculate the total of anti-spy skill in this town ----//
560 
561 	int enemySpyCount=0, counterSpySkill=0;
562 	Spy* spyPtr;
563 
564 	int i;
565 	for( i=size() ; i>0 ; i-- )
566 	{
567 		if( is_deleted(i) )
568 			continue;
569 
570 		spyPtr = spy_array[i];
571 
572 		if( spyPtr->spy_place == spyPlace &&
573 			 spyPtr->spy_place_para == spyPlacePara )
574 		{
575 			if( spyPtr->true_nation_recno == nationRecno )
576 				counterSpySkill += spyPtr->spy_skill;
577 			else
578 				enemySpyCount++;
579 		}
580 	}
581 
582 	//----- if all villagers are enemy spies ----//
583 
584 	if( enemySpyCount == totalPop )
585 		return 0;
586 
587 	err_when( enemySpyCount > totalPop );
588 
589 	//-------- try to catch enemy spies now ------//
590 
591 	for( i=spy_array.size() ; i>0 ; i-- )
592 	{
593 		if( spy_array.is_deleted(i) )
594 			continue;
595 
596 		spyPtr = spy_array[i];
597 
598 		if( spyPtr->action_mode == SPY_IDLE )		// it is very hard to get caught in sleep mode
599 			continue;
600 
601 		if( spyPtr->spy_place == spyPlace &&
602 			 spyPtr->spy_place_para == spyPlacePara &&
603 			 spyPtr->true_nation_recno != nationRecno )	// doesn't get caught in sleep mode
604 		{
605 			int escapeChance = 100 + spyPtr->spy_skill - counterSpySkill;
606 
607 			escapeChance = MAX( spyPtr->spy_skill/10, escapeChance );
608 
609 			if( misc.random(escapeChance) == 0 )
610 			{
611 				spyPtr->get_killed(); 		// only catch one spy per calling
612 				return 1;
613 			}
614 		}
615 	}
616 
617 	return 0;
618 }
619 //---------- End of function SpyArray::catch_spy --------//
620 
621 
622 //--------- Begin of function SpyArray::set_action_mode ----------//
623 //
624 // Set all spies in the given place to the specific action mode.
625 //
set_action_mode(int spyPlace,int spyPlacePara,int actionMode)626 void SpyArray::set_action_mode(int spyPlace, int spyPlacePara, int actionMode)
627 {
628 	int  spyCount=size();
629 	Spy* spyPtr;
630 
631 	for( int i=1 ; i<=spyCount ; i++ )
632 	{
633 		if( spy_array.is_deleted(i) )
634 			continue;
635 
636 		spyPtr = spy_array[i];
637 
638 		if( spyPtr->spy_place==spyPlace &&
639 			 spyPtr->spy_place_para==spyPlacePara )
640 		{
641 			spyPtr->set_action_mode(actionMode);
642 		}
643 	}
644 }
645 //---------- End of function SpyArray::set_action_mode ----------//
646 
647 
648 //--------- Begin of function SpyArray::ai_spy_town_rebel ----------//
649 //
650 // Tell the AI spies in the town that a rebellion is happening.
651 //
652 // When a rebellion happens, all the AI spies in the village will mobilize
653 // and turn its cloak back to a nation that is not at war with the enemy
654 // (and notification flag should be off.) and move to a safe place
655 // (near to one of your towns). Then the spy reaches thedestination, it will
656 // become idle and then the AI processing function on idle spy will be
657 // called and handle the spy.
658 //
659 // <int> townRecno - recno of the town with rebellion happening.
660 //
ai_spy_town_rebel(int townRecno)661 void SpyArray::ai_spy_town_rebel(int townRecno)
662 {
663 	int  spyCount=size();
664 	Spy* spyPtr;
665 
666 	for( int i=1 ; i<=spyCount ; i++ )
667 	{
668 		if( spy_array.is_deleted(i) )
669 			continue;
670 
671 		spyPtr = spy_array[i];
672 
673 		if( spyPtr->spy_place==SPY_TOWN &&
674 			 spyPtr->spy_place_para==townRecno &&
675 			 nation_array[spyPtr->true_nation_recno]->is_ai() )
676 		{
677 			//-------- mobilize the spy ----------//
678 
679 			int unitRecno = spyPtr->mobilize_town_spy();
680 
681 			//----- think new action for the spy ------//
682 
683 			if( unitRecno )
684 			{
685 				SpyProcess spyProcess(i);
686 				spyProcess.think_mobile_spy_new_action();
687 			}
688 		}
689 	}
690 }
691 //---------- End of function SpyArray::ai_spy_town_rebel ----------//
692 
693 
694 //--------- Begin of function SpyArray::needed_view_secret_skill ----------//
695 //
needed_view_secret_skill(int viewMode)696 int SpyArray::needed_view_secret_skill(int viewMode)
697 {
698 	for( int i=0 ; i<SECRET_REPORT_COUNT ; i++ )
699 	{
700 		if( secret_view_mode_array[i] == viewMode )
701 			return secret_view_skill_array[i];
702 	}
703 
704 	return 0;
705 }
706 //---------- End of function SpyArray::needed_view_secret_skill ----------//
707 
708 
709 #ifdef DYNARRAY_DEBUG_ELEMENT_ACCESS
710 
711 //------- Begin of function SpyArray::operator[] -----//
712 
operator [](int recNo)713 Spy* SpyArray::operator[](int recNo)
714 {
715 	Spy* spyPtr = (Spy*) get(recNo);
716 
717 	if( !spyPtr || spyPtr->spy_recno==0 )
718 		err.run( "SpyArray[] is deleted" );
719 
720 	return spyPtr;
721 }
722 
723 //--------- End of function SpyArray::operator[] ----//
724 
725 #endif
726