123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116 |
- /*
- * Seven Kingdoms: Ancient Adversaries
- *
- * Copyright 1997,1998 Enlight Software Ltd.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- //Filename : OREBEL.CPP
- //Description : Object Rebel
- #include <OPOWER.h>
- #include <OGAME.h>
- #include <OUNIT.h>
- #include <OFIRM.h>
- #include <OTOWN.h>
- #include <ONEWS.h>
- #include <OREBEL.h>
- #include <ORACERES.h>
- #include <ONATION.h>
- //--------- Begin of function RebelArray::RebelArray ----------//
- RebelArray::RebelArray() : DynArrayB(sizeof(Rebel*), 10, DEFAULT_REUSE_INTERVAL_DAYS)
- {
- }
- //--------- End of function RebelArray::RebelArary ----------//
- //------- Begin of function RebelArray::~RebelArray ----------//
- //
- RebelArray::~RebelArray()
- {
- deinit();
- }
- //--------- End of function RebelArray::~RebelArray ----------//
- //--------- Begin of function RebelArray::init ----------//
- //
- void RebelArray::init()
- {
- }
- //---------- End of function RebelArray::init ----------//
- //--------- Begin of function RebelArray::deinit ----------//
- //
- void RebelArray::deinit()
- {
- if( size()==0 )
- return;
- //----- delete Rebel objects ------//
- Rebel* rebelPtr;
- for( int i=1 ; i<=size() ; i++ )
- {
- rebelPtr = (Rebel*) get_ptr(i);
- if( rebelPtr )
- delete rebelPtr;
- }
- //-------- zap the array -----------//
- zap();
- }
- //---------- End of function RebelArray::deinit ----------//
- //------- Begin of function RebelArray::create_rebel ---------//
- //
- // Create a rebel group. If there are a rebel group nearby
- // with the same objectives, join the rebel group without
- // creating a new one.
- //
- // <int> unitRecno - recno of the rebel leader
- // <int> hostileNationRecno - the recno of the now hostile nation which
- // the people rebels from.
- // [int] actionMode - rebel action mode (default: REBEL_IDLE)
- // [int] actionPara - action parameters (default: 0)
- //
- // return: <int> rebelRecno - recno of the rebel group
- //
- int RebelArray::create_rebel(int unitRecno, int hostileNationRecno, int actionMode, int actionPara)
- {
- //------------------------------------------//
- // See if there are a rebel group nearby
- // with the same objectives, join the rebel
- // group without creating a new one.
- //------------------------------------------//
- int rebelRecno = m.random(rebel_array.size())+1;
- Rebel* rebelPtr;
- for( int i=size() ; i>=1 ; i-- )
- {
- if( ++rebelRecno > rebel_array.size() )
- rebelRecno = 1;
- if( rebel_array.is_deleted(rebelRecno) )
- continue;
- rebelPtr = rebel_array[rebelRecno];
- if( rebelPtr->action_mode == actionMode &&
- rebelPtr->action_para == actionPara )
- {
- rebelPtr->join(unitRecno); // join the rebel group
- return rebelRecno;
- }
- }
- //-------- create a new rebel group ---------//
- rebelPtr = new Rebel;
- rebelPtr->leader_unit_recno = unitRecno;
- rebelPtr->action_mode = actionMode;
- rebelPtr->action_para = actionPara;
- rebelPtr->mobile_rebel_count = 1;
- rebelPtr->set_hostile_nation(hostileNationRecno);
-
- linkin(&rebelPtr);
- rebelPtr->rebel_recno = recno();
- unit_array[unitRecno]->set_mode( UNIT_MODE_REBEL, recno() );
- return recno();
- }
- //-------- End of function RebelArray::create_rebel ---------//
- //------- Begin of function RebelArray::del_rebel ---------//
- //
- void RebelArray::del_rebel(int rebelRecno)
- {
- Rebel* rebelPtr = operator[](rebelRecno);
- delete rebelPtr;
- linkout(rebelRecno);
- }
- //-------- End of function RebelArray::del_rebel ---------//
- //--------- Begin of function RebelArray::stop_attack_town ---------//
- void RebelArray::stop_attack_town(short townRecno)
- {
- Rebel *rebelPtr;
- for(int i=size(); i>0; --i)
- {
- rebelPtr = (Rebel*) get_ptr(i);
-
- if(rebelPtr && rebelPtr->action_mode==REBEL_ATTACK_TOWN)
- {
- if(rebelPtr->action_para==townRecno)
- {
- rebelPtr->set_action(REBEL_IDLE);
- rebelPtr->stop_all_rebel_unit();
- break;
- }
- }
- }
- }
- //-------- End of function RebelArray::stop_attack_town ---------//
- //--------- Begin of function RebelArray::stop_attack_firm ---------//
- void RebelArray::stop_attack_firm(short firmRecno)
- {
- Rebel *rebelPtr;
- for(int i=size(); i>0; --i)
- {
- rebelPtr = (Rebel*) get_ptr(i);
- if(rebelPtr && rebelPtr->action_mode==REBEL_ATTACK_FIRM)
- {
- if(rebelPtr->action_para==firmRecno)
- {
- rebelPtr->set_action(REBEL_IDLE);
- rebelPtr->stop_all_rebel_unit();
- return;
- }
- }
- }
- }
- //-------- End of function RebelArray::stop_attack_firm ---------//
- //### begin alex 20/8 ###//
- //--------- Begin of function RebelArray::stop_attack_nation ---------//
- void RebelArray::stop_attack_nation(short nationRecno)
- {
- Rebel *rebelPtr;
- for(int i=size(); i>0; i--)
- {
- rebelPtr = (Rebel*) get_ptr(i);
- if(rebelPtr)
- rebelPtr->reset_hostile_nation(nationRecno);
- }
- }
- //-------- End of function RebelArray::stop_attack_nation ---------//
- //#### end alex 20/8 ####//
- //--------- Begin of function RebelArray::next_day ---------//
- //
- void RebelArray::next_day()
- {
- int i;
- Rebel *rebelPtr;
- for( i=size() ; i>0 ; i-- )
- {
- rebelPtr = (Rebel*) get_ptr(i);
- if( rebelPtr )
- rebelPtr->next_day();
- }
- }
- //----------- End of function RebelArray::next_day ---------//
- //--------- Begin of function RebelArray::drop_rebel_identity -------//
- //
- // 4 fates for a rebel unit:
- //
- // - the rebel gets killed
- // - the rebel group settles down in a town
- // - the rebel surrender a nation
- // - the rebel group merges with another rebel group
- //
- // This function handle the fate that the unit gets killed.
- //
- void RebelArray::drop_rebel_identity(int unitRecno)
- {
- Unit* unitPtr = unit_array[unitRecno];
- err_when( unitPtr->unit_mode != UNIT_MODE_REBEL );
- err_when( rebel_array.is_deleted(unitPtr->unit_mode_para) );
- //---- decrease the unit count of the rebel group ----//
- int rebelRecno = unitPtr->unit_mode_para;
- Rebel* rebelPtr = rebel_array[rebelRecno];
- rebelPtr->mobile_rebel_count--;
- unitPtr->set_mode(0); // drop its rebel identity
- //----- if all rebels are dead and the rebel doesn't occupy a town, del the rebel group ----//
- if( rebelPtr->mobile_rebel_count==0 && rebelPtr->town_recno==0 )
- {
- del_rebel(rebelRecno);
- return;
- }
- //----- when the rebel leader is killed -----//
- if( rebelPtr->leader_unit_recno == unitRecno )
- rebelPtr->process_leader_quit();
- }
- //----------- End of function RebelArray::drop_rebel_identity --------//
- //--------- Begin of function Rebel::process_leader_quit -------//
- //
- void Rebel::process_leader_quit()
- {
- //-------------------------------------------//
- //
- // When the rebel leader gets killed, a new rebel unit
- // in the group is elected as the new leader.
- //
- // Some the rebel units leave the rebel group to:
- // surrender to a nation (moving into a town as town people)
- //
- //-------------------------------------------//
- //----- select a new unit as the leader ------//
- leader_unit_recno = 0;
- if( mobile_rebel_count>0 ) // it must at least be 2: the dying leader + one rebel soldier
- {
- select_new_leader();
- }
- else
- {
- err_when( !town_recno ); // if mobile_label_count is 0, the rebel group must have a town
- // if the rebel has a town, leader_unit_recno can be 0
- }
- //------ some the rebel units leave the rebel group -----//
- if( mobile_rebel_count>1 )
- {
- //---- surrender to a nation ----//
- int maxReputation=0, bestNationRecno=0;
- Nation* nationPtr;
- int i;
- for( i=nation_array.size() ; i>0 ; i-- )
- {
- if( nation_array.is_deleted(i) )
- continue;
- nationPtr = nation_array[i];
- if( nationPtr->reputation > maxReputation )
- {
- maxReputation = (int) nationPtr->reputation;
- bestNationRecno = i;
- }
- }
- if( !bestNationRecno ) // no nation has a positive reputation
- return;
- //------- process the rebel units -------//
- Unit* unitPtr;
- for( i=unit_array.size() ; i>0 ; i-- )
- {
- if( unit_array.is_deleted(i) )
- continue;
- unitPtr = unit_array[i];
- if( unitPtr->unit_mode == UNIT_MODE_REBEL &&
- unitPtr->unit_mode_para == leader_unit_recno )
- {
- unitPtr->set_mode(0);
- unitPtr->change_nation(bestNationRecno);
- }
- }
- }
- }
- //-------- End of function Rebel::process_leader_quit --------//
- //--------- Begin of function Rebel::select_new_leader -------//
- //
- int Rebel::select_new_leader()
- {
- if( mobile_rebel_count==0 )
- return 0;
- Unit* unitPtr;
- int i;
- for( i=unit_array.size() ; i>0 ; i-- )
- {
- if( unit_array.is_deleted(i) )
- continue;
- unitPtr = unit_array[i];
- if( unitPtr->unit_mode==UNIT_MODE_REBEL &&
- unitPtr->unit_mode_para == rebel_recno )
- {
- err_when( unitPtr->hit_points<=0 );
- unitPtr->set_rank(RANK_GENERAL);
- leader_unit_recno = i;
- break;
- }
- }
- if( !leader_unit_recno )
- return 0;
- //--- update the leader_unit_renco of all units in this rebel group ---//
- for( i=unit_array.size() ; i>0 ; i-- )
- {
- if( unit_array.is_deleted(i) )
- continue;
- unitPtr = unit_array[i];
- if( unitPtr->unit_mode==UNIT_MODE_REBEL &&
- unitPtr->unit_mode_para == rebel_recno )
- {
- unitPtr->leader_unit_recno = leader_unit_recno;
- }
- }
- return 0;
- }
- //-------- End of function Rebel::select_new_leader --------//
- //-------- Begin of function RebelArray::settle_town -------//
- //
- // A unit settle_towns from its rebel group.
- //
- // <int> unitRecno - recno of the unit going to settle in the town
- // <int> townRecno - recno of the town this unit settles
- //
- void RebelArray::settle_town(int unitRecno, int townRecno)
- {
- Unit* unitPtr = unit_array[unitRecno];
- err_when( unitPtr->unit_mode != UNIT_MODE_REBEL );
- err_when( rebel_array.is_deleted(unitPtr->unit_mode_para) );
- //---- decrease the unit count of the rebel group ----//
- int rebelRecno = unitPtr->unit_mode_para;
- Rebel* rebelPtr = rebel_array[rebelRecno];
- rebelPtr->mobile_rebel_count--;
- //--------- settle in a town ----------//
- // err_when( rebelPtr->town_recno && rebelPtr->town_recno != townRecno ); // one rebel group only allow settle in a town, error when trying to settle in more than one town
- Town* townPtr = town_array[townRecno];
- if( rebelPtr->town_recno==0 && townPtr->rebel_recno==0 )
- {
- rebelPtr->town_recno = townRecno;
- townPtr->rebel_recno = rebelRecno;
- }
- }
- //----------- End of function RebelArray::settle_town --------//
- //--------- Begin of function Rebel::Rebel --------//
- //
- Rebel::Rebel()
- {
- memset( this, 0, sizeof(Rebel) );
- hostile_nation_bits = 0;
- }
- //----------- End of function Rebel::Rebel ---------//
- //--------- Begin of function Rebel::~Rebel --------//
- //
- Rebel::~Rebel()
- {
- Unit* unitPtr;
- for( int i=unit_array.size() ; i>0 ; i-- )
- {
- if( unit_array.is_deleted(i) )
- continue;
- unitPtr = unit_array[i];
- if( unitPtr->unit_mode == UNIT_MODE_REBEL &&
- unitPtr->unit_mode_para == rebel_recno )
- {
- unitPtr->set_mode(0);
- }
- }
- }
- //----------- End of function Rebel::~Rebel ---------//
- //--------- Begin of function Rebel::join ---------//
- //
- // A unit joins this rebel group as a rebel member.
- // The rebel leader exists since the creation of this rebel group.
- //
- void Rebel::join(int unitRecno)
- {
- Unit* unitPtr = unit_array[unitRecno];
- err_when( unitPtr->nation_recno );
- err_when( unitPtr->spy_recno );
- unitPtr->set_mode( UNIT_MODE_REBEL, rebel_recno );
- mobile_rebel_count++;
- }
- //----------- End of function Rebel::join ---------//
- //--------- Begin of function Rebel::think_cur_action ---------//
- //
- void Rebel::think_cur_action()
- {
- //------ if the rebel is attacking a town -------//
- if( action_mode == REBEL_ATTACK_TOWN )
- {
- //----- the town has already been captured -----//
- if( town_array.is_deleted(action_para) || town_array[action_para]->nation_recno == 0 )
- {
- //--- stop all units that are still attacking the town ---//
- stop_all_rebel_unit();
- set_action(REBEL_IDLE);
- }
- }
- //----- if the rebel should be attacking a firm -----//
- if( action_mode == REBEL_ATTACK_FIRM )
- {
- if( firm_array.is_deleted(action_para) || firm_array[action_para]->nation_recno == 0 )
- {
- //--- stop all units that are still attacking the firm ---//
- stop_all_rebel_unit();
- set_action(REBEL_IDLE);
- }
- }
- }
- //----------- End of function Rebel::think_cur_action ---------//
- //--------- Begin of function Rebel::next_day ---------//
- //
- void Rebel::next_day()
- {
- //---- if the rebels has a town and this rebel is a defender from a town ----//
- if( town_recno )
- {
- //--- check if the rebel town is destroyed ----//
- if( town_array.is_deleted(town_recno) )
- {
- town_recno = 0;
- //--- if the town has been destroyed, the rebel group becomes mobile again, and a new leader needs to be selected.
- if( mobile_rebel_count>0 && leader_unit_recno==0 )
- {
- select_new_leader();
- }
- }
- err_when( town_recno && town_array[town_recno]->rebel_recno != rebel_recno );
- return; // don't think new action as this rebel defender need to go back to its town.
- }
- //------- no rebels left in the group --------//
- if( town_recno==0 && mobile_rebel_count==0 )
- {
- rebel_array.del_rebel(rebel_recno);
- return;
- }
- //---------------------------------------------//
- err_when( mobile_rebel_count==0 && town_recno==0 ); // if both are zero, this rebel group should have been deleted.
- if( mobile_rebel_count > 0 ) // if there are mobile rebel units on the map
- {
- if( action_mode==REBEL_IDLE )
- think_new_action(); // think about a new action
- else
- think_cur_action(); // think if there should be any changes to the current action
- }
- else // if there are no mobile rebel units
- {
- if( town_recno > 0 )
- {
- if( info.game_date%30 == rebel_recno%30 ) // if the rebel has a town
- think_town_action();
- }
- }
- }
- //----------- End of function Rebel::next_day ---------//
- //--------- Begin of function Rebel::think_new_action ---------//
- //
- void Rebel::think_new_action()
- {
- if(unit_array.is_deleted(leader_unit_recno))
- return;
- int rc;
- switch( m.random(4) )
- {
- case 0:
- rc = think_settle_new();
- break;
- case 1:
- rc = think_settle_to();
- break;
- case 2:
- rc = think_capture_attack_town();
- break;
- case 3:
- rc = think_attack_firm();
- break;
- }
- if( rc )
- execute_new_action();
- }
- //----------- End of function Rebel::think_new_action ---------//
- //--------- Begin of function Rebel::think_settle_new ---------//
- //
- int Rebel::think_settle_new()
- {
- //------- get the leader unit's info -----------//
- Unit* leaderUnit = unit_array[leader_unit_recno];
- int leaderXLoc=leaderUnit->cur_x_loc(), leaderYLoc=leaderUnit->cur_y_loc();
- //----------------------------------------------//
- int xLoc2 = leaderXLoc + STD_TOWN_LOC_WIDTH - 1;
- int yLoc2 = leaderYLoc + STD_TOWN_LOC_HEIGHT - 1;
- if( xLoc2 >= MAX_WORLD_X_LOC )
- {
- xLoc2 = MAX_WORLD_X_LOC - 1;
- leaderXLoc = xLoc2 - STD_TOWN_LOC_WIDTH + 1;
- }
- if( yLoc2 >= MAX_WORLD_Y_LOC )
- {
- yLoc2 = MAX_WORLD_Y_LOC - 1;
- leaderYLoc = yLoc2 - STD_TOWN_LOC_HEIGHT + 1;
- }
- int regionId = world.get_region_id( leaderXLoc, leaderYLoc );
- if( world.locate_space( leaderXLoc, leaderYLoc, xLoc2, yLoc2, STD_TOWN_LOC_WIDTH, STD_TOWN_LOC_HEIGHT, UNIT_LAND, regionId, 1 ) )
- {
- action_mode = REBEL_SETTLE_NEW;
- action_para = leaderXLoc;
- action_para2 = leaderYLoc;
- return 1;
- }
- return 0;
- }
- //----------- End of function Rebel::think_settle_new ---------//
- //--------- Begin of function Rebel::think_settle_to ---------//
- //
- // Think about settling to an existing rebel town.
- //
- int Rebel::think_settle_to()
- {
- int i, townRecno;
- Town* townPtr;
- Unit* leaderUnit = unit_array[leader_unit_recno];
- int curRegionId = world.get_region_id(leaderUnit->cur_x_loc(), leaderUnit->cur_y_loc());
- townRecno = m.random(town_array.size())+1;
- for( i=1 ; i<=town_array.size() ; i++ )
- {
- if( ++townRecno > town_array.size() )
- townRecno = 1;
- if( town_array.is_deleted(townRecno) )
- continue;
- townPtr = town_array[townRecno];
- if( !townPtr->rebel_recno )
- continue;
- if( world.get_region_id(townPtr->loc_x1, townPtr->loc_y1) != curRegionId )
- continue;
- if( leaderUnit->race_id == townPtr->majority_race() )
- {
- action_mode = REBEL_SETTLE_TO;
- action_para = townPtr->loc_x1;
- action_para2 = townPtr->loc_y1;
- return 1;
- }
- }
- return 0;
- }
- //----------- End of function Rebel::think_settle_to ---------//
- //--------- Begin of function Rebel::think_capture_attack_town ---------//
- //
- int Rebel::think_capture_attack_town()
- {
- //------- get the leader unit's info -----------//
- Unit* leaderUnit = unit_array[leader_unit_recno];
- int leaderXLoc = leaderUnit->cur_x_loc(), leaderYLoc=leaderUnit->cur_y_loc();
- int curRegionId = world.get_region_id(leaderUnit->cur_x_loc(), leaderUnit->cur_y_loc());
- //----------------------------------------------//
- int actionMode = REBEL_ATTACK_TOWN;
- int townRecno, bestTownRecno=0;
- int townDistance, closestTownDistance=0x7FFF;
- Town* townPtr;
- for( int i=town_array.size() ; i>0 ; i-- )
- {
- townRecno = m.random(town_array.size())+1;
- if( town_array.is_deleted(townRecno) )
- continue;
- townPtr = town_array[townRecno];
- if( !is_hostile_nation(townPtr->nation_recno) )
- continue;
- if( world.get_region_id(townPtr->loc_x1, townPtr->loc_y1) != curRegionId )
- continue;
- townDistance = m.points_distance( leaderXLoc, leaderYLoc,
- townPtr->center_x, townPtr->center_y );
- if( townDistance < closestTownDistance )
- {
- closestTownDistance = townDistance;
- bestTownRecno = townRecno;
- }
- }
- if( bestTownRecno )
- {
- action_mode = actionMode;
- action_para = bestTownRecno; // attack this town
- return 1;
- }
- return 0;
- }
- //----------- End of function Rebel::think_capture_attack_town ---------//
- //--------- Begin of function Rebel::think_attack_firm ---------//
- //
- int Rebel::think_attack_firm()
- {
- //------- get the leader unit's info -----------//
- Unit* leaderUnit = unit_array[leader_unit_recno];
- int leaderXLoc=leaderUnit->cur_x_loc(), leaderYLoc=leaderUnit->cur_y_loc();
- int curRegionId = world.get_region_id(leaderUnit->cur_x_loc(), leaderUnit->cur_y_loc());
- //----------------------------------------------//
- int firmRecno, bestFirmRecno=0;
- int firmDistance, closestFirmDistance=0x7FFF;
- Firm* firmPtr;
- for( int i=firm_array.size() ; i>0 ; i-- )
- {
- firmRecno = m.random(firm_array.size())+1;
- if( firm_array.is_deleted(firmRecno) )
- continue;
- firmPtr = firm_array[firmRecno];
- if( !is_hostile_nation(firmPtr->nation_recno) )
- continue;
- if( world.get_region_id(firmPtr->loc_x1, firmPtr->loc_y1) != curRegionId )
- continue;
- firmDistance = m.points_distance( leaderXLoc, leaderYLoc,
- firmPtr->center_x, firmPtr->center_y );
- if( firmDistance < closestFirmDistance )
- {
- closestFirmDistance = firmDistance;
- bestFirmRecno = firmRecno;
- }
- }
- if( bestFirmRecno )
- {
- action_mode = REBEL_ATTACK_FIRM;
- action_para = bestFirmRecno; // attack this town
- return 1;
- }
- return 0;
- }
- //----------- End of function Rebel::think_attack_firm ---------//
- //--------- Begin of function Rebel::execute_new_action -------//
- //
- // Called by think_new_action(), execute the action immediately right
- // after a new action has been decided.
- //
- void Rebel::execute_new_action()
- {
- //----- create an recno array of the rebel units ----//
- short* rebelRecnoArray = (short*) mem_add( mobile_rebel_count * sizeof(short) );
- Unit* unitPtr;
- int rebelCount=0;
- #ifdef DEBUG
- int dieUnit = 0;
- #endif
- for( int i=unit_array.size() ; i>=1 ; i-- )
- {
- if( unit_array.is_deleted(i) )
- {
- #ifdef DEBUG
- if(!unit_array.SpriteArray::is_deleted(i))
- dieUnit++;
- #endif
- continue;
- }
- unitPtr = unit_array[i];
- if( unitPtr->unit_mode == UNIT_MODE_REBEL &&
- unitPtr->unit_mode_para == rebel_recno )
- {
- err_when( rebelCount >= mobile_rebel_count );
- rebelRecnoArray[rebelCount++] = i;
- }
- }
- #ifdef DEBUG
- if(rebelCount+dieUnit != mobile_rebel_count)
- int debug = 0;
- #endif
- if( !rebelCount )
- {
- mem_del( rebelRecnoArray );
- return; // all rebel units are dead
- }
- //-------- execute the new action now --------//
- Town* townPtr;
- Firm* firmPtr;
- switch( action_mode )
- {
- case REBEL_ATTACK_TOWN:
- err_when( town_array.is_deleted(action_para) || town_array[action_para]->nation_recno==0 ); // these should have been checked before calling this function
- townPtr = town_array[action_para];
- // ##### patch begin Gilbert 5/8 ######//
- unit_array.attack( townPtr->loc_x1, townPtr->loc_y1, 0, rebelRecnoArray, rebelCount, COMMAND_AI, 0 );
- // ##### patch end Gilbert 5/8 ######//
- break;
- case REBEL_ATTACK_FIRM:
- err_when( firm_array.is_deleted(action_para) || firm_array[action_para]->nation_recno==0 ); // these should have been checked before calling this function
- firmPtr = firm_array[action_para];
- // ##### patch begin Gilbert 5/8 ######//
- unit_array.attack( firmPtr->loc_x1, firmPtr->loc_y1, 0, rebelRecnoArray, rebelCount, COMMAND_AI, 0 );
- // ##### patch end Gilbert 5/8 ######//
- break;
- case REBEL_SETTLE_NEW:
- unit_array.settle( action_para, action_para2, 0, 1, rebelRecnoArray, rebelCount ); // action_para & action_para2 is the destination location
- break;
- case REBEL_SETTLE_TO:
- unit_array.assign( action_para, action_para2, 0, 1, rebelRecnoArray, rebelCount);
- break;
- }
- mem_del( rebelRecnoArray );
- }
- //-------- End of function Rebel::execute_new_action ---------//
- //--------- Begin of function Rebel::think_town_action ---------//
- //
- // Call this function to think about the new actions of this
- // rebel group when all members of the rebel has settled down
- // into a town.
- //
- void Rebel::think_town_action()
- {
- if( town_recno==0 || mobile_rebel_count>0 ) // only when all rebel units has settled in the town
- return;
- //----- neutralize to an independent town -----//
- if( m.random(10)==0 )
- {
- turn_indepedent();
- }
- //---------- form a nation ---------//
- else if( m.random(10)==0 )
- {
- if( town_array[town_recno]->population >= 20 &&
- nation_array.can_form_new_ai_nation() )
- {
- town_array[town_recno]->form_new_nation();
- }
- }
- }
- //----------- End of function Rebel::think_town_action ---------//
- //--------- Begin of function Rebel::turn_indepedent ---------//
- //
- // The rebel town turns into an indepedent town.
- //
- void Rebel::turn_indepedent()
- {
- err_when( town_recno==0 || mobile_rebel_count>0 ); // only when all rebel units has settled in the town
- town_array[town_recno]->rebel_recno = 0;
- //------ remove this rebel group from rebel_array ------//
- rebel_array.del_rebel(rebel_recno);
- }
- //----------- End of function Rebel::turn_indepedent ---------//
- //--------- Begin of function Rebel::stop_all_rebel_unit ---------//
- //
- void Rebel::stop_all_rebel_unit()
- {
- Unit* unitPtr;
- for( int i=unit_array.size() ; i>=1 ; i-- )
- {
- if( unit_array.is_deleted(i) )
- continue;
- unitPtr = unit_array[i];
- if( unitPtr->unit_mode == UNIT_MODE_REBEL &&
- unitPtr->unit_mode_para == rebel_recno )
- {
- unitPtr->stop();
- }
- }
- }
- //----------- End of function Rebel::stop_all_rebel_unit ---------//
- //--------- Begin of function Rebel::town_being_attacked ---------//
- //
- // This rebel group's town is being attacked.
- //
- void Rebel::town_being_attacked(int attackerUnitRecno)
- {
- err_when( !town_recno );
- //----------------------------------------------//
- //
- // Set the hostile_nation_recno. So that if the rebel
- // town is destroyed and there are rebel units left,
- // they can form a rebel group again and battle with
- // the attacking nation.
- //
- //----------------------------------------------//
- set_hostile_nation(unit_array[attackerUnitRecno]->nation_recno);
- }
- //----------- End of function Rebel::town_being_attacked ---------//
- //--------- Begin of function Rebel::set_hostile_nation ---------//
- void Rebel::set_hostile_nation(short nationRecno)
- {
- if(nationRecno==0)
- return;
- err_when(nationRecno>7); // only 8 bits
- hostile_nation_bits |= (0x1 << nationRecno);
- }
- //----------- End of function Rebel::set_hostile_nation ---------//
- //--------- Begin of function Rebel::reset_hostile_nation ---------//
- void Rebel::reset_hostile_nation(short nationRecno)
- {
- if(nationRecno==0)
- return;
- err_when(nationRecno>7); // only 8 bits
- hostile_nation_bits &= ~(0x1 << nationRecno);
- }
- //----------- End of function Rebel::reset_hostile_nation ---------//
- //--------- Begin of function Rebel::is_hostile_nation ---------//
- // return 1 for hostile nation
- // return 0 otherwise
- //
- int Rebel::is_hostile_nation(short nationRecno)
- {
- if(nationRecno==0)
- return 0;
- err_when(nationRecno>7); // only 8 bits
- return (hostile_nation_bits & (0x1 << nationRecno));
- }
- //----------- End of function Rebel::is_hostile_nation ---------//
- //--------- Begin of function Unit::process_rebel ---------//
- //
- // Note: this is a Unit member function, not a Rebel member function,
- // it is called by Unit::process_idle();
- //
- void Unit::process_rebel()
- {
- Rebel* rebelPtr = rebel_array[unit_mode_para];
- switch( rebelPtr->action_mode )
- {
- case REBEL_ATTACK_TOWN:
- if( town_array.is_deleted(rebelPtr->action_para) ) // if the town has been destroyed.
- rebelPtr->set_action(REBEL_IDLE);
- else
- {
- Town* townPtr = town_array[rebelPtr->action_para];
- attack_town( townPtr->loc_x1, townPtr->loc_y1 );
- }
- break;
- case REBEL_SETTLE_NEW:
- if( !world.can_build_town(rebelPtr->action_para, rebelPtr->action_para2, sprite_recno) )
- {
- Location* locPtr = world.get_loc(rebelPtr->action_para, rebelPtr->action_para2);
- if( locPtr->is_town() &&
- town_array[locPtr->town_recno()]->rebel_recno == rebelPtr->rebel_recno )
- {
- rebelPtr->action_mode = REBEL_SETTLE_TO;
- }
- else
- {
- rebelPtr->action_mode = REBEL_IDLE;
- }
- }
- else
- {
- settle( rebelPtr->action_para, rebelPtr->action_para2 );
- }
- break;
- case REBEL_SETTLE_TO:
- assign( rebelPtr->action_para, rebelPtr->action_para2 );
- break;
- }
- }
- //----------- End of function Unit::process_rebel -----------//
- #ifdef DEBUG
- //------- Begin of function RebelArray::operator[] -----//
- Rebel* RebelArray::operator[](int recNo)
- {
- Rebel* rebelPtr = (Rebel*) get_ptr(recNo);
- if( !rebelPtr )
- err.run( "RebelArray[] is deleted" );
- return rebelPtr;
- }
- //--------- End of function RebelArray::operator[] ----//
- #endif
|