/*
* 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 .
*
*/
//Filename : OREBEL.CPP
//Description : Object Rebel
#include
#include
#include
#include
#include
#include
#include
#include
#include
//--------- 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.
//
// unitRecno - recno of the rebel leader
// 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: 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.
//
// unitRecno - recno of the unit going to settle in the town
// 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