/*
* 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 : ONATIONA.CPP
//Description : Object Nation Array
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//### begin alex 22/9 ###//
#ifdef DEBUG
#include
static unsigned long last_nation_ai_profile_time = 0L;
static unsigned long nation_ai_profile_time = 0L;
static unsigned long last_nation_profile_time = 0L;
static unsigned long nation_profile_time = 0L;
#endif
//#### end alex 22/9 ####//
//--------- Begin of function NationArray::NationArray ---------//
//
NationArray::NationArray() : DynArrayB( sizeof(Nation*), MAX_NATION )
{
}
//----------- End of function NationArray::NationArray ---------//
//--------- Begin of function NationArray::~NationArray ---------//
//
NationArray::~NationArray()
{
deinit();
}
//----------- End of function NationArray::~NationArray ---------//
//--------- Begin of function NationArray::init ---------//
//
void NationArray::init()
{
nation_count = 0;
ai_nation_count = 0;
last_del_nation_date = 0;
nation_peace_days = 0;
last_alliance_id = 0;
nation_color_array[0] = (char) V_WHITE; // if nation_recno==0, the color is white
nation_power_color_array[0] = (char) VGA_GRAY+10; // if nation_recno==0, the color is white
nation_power_color_array[MAX_NATION+1] = (char) VGA_GRAY+10; // if Location::power_nation_recno==MAX_NATION+1, this means there are more than one nation have influence over this location.
}
//----------- End of function NationArray::init ---------//
//--------- Begin of function NationArray::deinit ---------//
//
// Called by ~NationArray when game terminate
// and NationArray::read_file() when loading game
//
void NationArray::deinit()
{
int i; // can't call the destructor of Firm, must call deinit()
for( i=size() ; i>0 ; i-- )
{
if( !is_deleted(i) )
del_nation(i);
}
zap(); // clean up the array
}
//----------- End of function NationArray::deinit ---------//
//--------- Begin of function NationArray::new_nation ---------//
//
// nationType = NATION_OWN, NATION_AI, or NATION_REMOTE
// raceId = id. of the race
// colorSchemeId = the color scheme id. of the nation
// [unsigned long] dpPlayerId = DirectPlayer player id. (only for multiplayer game)
//
// return : nationRecno = the recno. of the newly added nation
//
int NationArray::new_nation(int nationType, int raceId, int colorSchemeId, unsigned long dpPlayerId)
{
err_when( info.game_date < last_del_nation_date + NEW_NATION_INTERVAL_DAYS );
//--------------------------------------------------------//
int nationRecno = create_nation();
Nation* nationPtr = nation_array[nationRecno];
if( nationType == NATION_OWN )
{
player_ptr = nationPtr; // for ~nation_array to quick access
player_recno = nationRecno;
info.default_viewing_nation_recno = nationRecno;
info.viewing_nation_recno = nationRecno;
}
//--- we must call init() after setting ai_type & nation_res_id ----//
nationPtr->init(nationType, raceId, colorSchemeId, dpPlayerId);
//--- store the colors of all nations into a single array for later fast access ---//
nation_color_array[nationPtr->nation_recno] = nationPtr->nation_color;
nation_power_color_array[nationPtr->nation_recno] = nationPtr->nation_color; // use a lighter color for the nation power area
//-------------------------------------------//
nation_count++;
if( nationType == NATION_AI )
ai_nation_count++;
last_new_nation_date = info.game_date;
//---------- update statistic ----------//
update_statistic();
return nationRecno;
}
//----------- End of function NationArray::new_nation ---------//
// ######## begin Gilbert 18/8 #########//
//--------- Begin of function NationArray::new_nation ---------//
//
// used in creating human players in multi-player game
// return : nationRecno = the recno. of the newly added nation
//
int NationArray::new_nation(NewNationPara& nationPara)
{
err_when( info.game_date < last_del_nation_date + NEW_NATION_INTERVAL_DAYS );
//--------------------------------------------------------//
int nationRecno = create_nation();
Nation* nationPtr = nation_array[nationRecno];
err_when( nationRecno != nationPara.nation_recno );
err_when( !remote.is_enable() );
char nationType =
nationPara.dp_player_id == remote.self_player_id() ? NATION_OWN : NATION_REMOTE;
if( nationType == NATION_OWN )
{
player_ptr = nationPtr; // for ~nation_array to quick access
player_recno = nationRecno;
info.default_viewing_nation_recno = nationRecno;
info.viewing_nation_recno = nationRecno;
}
//--- we must call init() after setting ai_type & nation_res_id ----//
nationPtr->init(nationType, nationPara.race_id, nationPara.color_scheme, nationPara.dp_player_id);
//--- store the colors of all nations into a single array for later fast access ---//
nation_color_array[nationPtr->nation_recno] = nationPtr->nation_color;
nation_power_color_array[nationPtr->nation_recno] = nationPtr->nation_color; // use a lighter color for the nation power area
//-------------------------------------------//
nation_count++;
if( nationType == NATION_AI )
ai_nation_count++;
//---------- update statistic ----------//
update_statistic();
return nationRecno;
}
//----------- End of function NationArray::new_nation ---------//
// ######## end Gilbert 18/8 #########//
//--------- Begin of function NationArray::create_nation ---------//
//
// nationType = NATION_OWN, NATION_AI
//
// return : nationRecno = the recno. of the newly added nation
//
int NationArray::create_nation()
{
Nation *nationPtr = new Nation; // NATION_OWN, NATION_REMOTE also use
// may be switched to player nation and verse vice
linkin(&nationPtr);
err_when( size() > MAX_NATION );
nationPtr->nation_recno = recno();
return recno();
}
//----------- End of function NationArray::create_nation ---------//
//--------- Begin of function NationArray::nation_class_size ---------//
//
// Return the size of the nation class
//
// nationType = nation type, e.g. NATION_OWN, NATION_AI
//
int NationArray::nation_class_size()
{
return sizeof(Nation); // NATION_OWN, NATION_REMOTE also use
// Nation object because a AI nation
// may be switched to player nation and verse vice
}
//----------- End of function NationArray::nation_class_size ---------//
//--------- Begin of function NationArray::del_nation ---------//
//
// recNo = the no. of the record to be deleted
// (default : current record no.)
//
void NationArray::del_nation(int recNo)
{
//-----------------------------------------//
Nation* nationPtr = nation_array[recNo]; // operator[] will check for deleted nation error, can't use operator() because it use firm_array()->nation_recno
nation_count--;
if( nationPtr->nation_type == NATION_AI )
ai_nation_count--;
last_del_nation_date = info.game_date;
//------ delete and linkout the nation ------//
nationPtr->deinit();
delete nationPtr;
go(recNo);
*( (Nation**) get() ) = NULL; // Nullify the pointer
linkout();
//---- if the nation to be deleted is the player's nation ---//
if( recNo==player_recno )
{
player_ptr = NULL;
player_recno = 0;
if( !sys.signal_exit_flag )
sys.set_view_mode(MODE_NORMAL); // set the view mode to normal mode to prevent possible problems
}
//---------- update statistic ----------//
update_statistic(); // as max_overall_nation_recno and others may be pointing to the deleted nation
}
//----------- End of function NationArray::del_nation ---------//
//--------- Begin of function NationArray::process ---------//
//
void NationArray::process()
{
int i;
Nation *nationPtr;
for( i=size() ; i>0 ; i-- )
{
nationPtr = (Nation*) get_ptr(i);
if( !nationPtr )
continue;
//--------- process nation --------//
if( i%FRAMES_PER_DAY == int(sys.frame_count%FRAMES_PER_DAY) ) // only process each firm once per day
{
//### begin alex 22/9 ###//
#ifdef DEBUG
unsigned long profileStartTime = m.get_time();
#endif
//#### end alex 22/9 ####//
// ###### begin Gilbert 6/9 ######//
LOG_MSG(i);
LOG_MSG("begin next_day");
nationPtr->next_day();
LOG_MSG("end next_day");
LOG_MSG(m.get_random_seed());
// ###### end Gilbert 6/9 ######//
//### begin alex 22/9 ###//
#ifdef DEBUG
nation_profile_time += m.get_time() - profileStartTime;
#endif
//#### end alex 22/9 ####//
if( nation_array.is_deleted(i) )
continue;
// ###### begin Gilbert 6/9 ######//
if( nationPtr->nation_type == NATION_AI )
{
#ifdef DEBUG
unsigned long profileAiStartTime = m.get_time();
#endif
LOG_MSG( "begin process_ai");
nationPtr->process_ai();
LOG_MSG( "end process_ai");
LOG_MSG( m.get_random_seed());
#ifdef DEBUG
nation_profile_time += m.get_time() - profileStartTime;
#endif
}
// ###### end Gilbert 6/9 ######//
}
}
if( sys.frame_count%FRAMES_PER_DAY==0 )
nation_peace_days++;
}
//----------- End of function NationArray::process ---------//
//--------- Begin of function NationArray::next_month ---------//
//
void NationArray::next_month()
{
int i;
Nation *nationPtr;
// ###### begin Gilbert 6/9 ########//
LOG_MSG("begin NationArray::next_month");
for( i=size() ; i>0 ; i-- )
{
nationPtr = (Nation*) get_ptr(i);
if( nationPtr ) // nationPtr == NULL, if it's deleted
{
LOG_MSG(i);
nationPtr->next_month();
LOG_MSG(m.get_random_seed() );
}
}
LOG_MSG("end NationArray::next_month");
// ###### end Gilbert 6/9 ########//
//------- update statistic -----------//
update_statistic();
}
//---------- End of function NationArray::next_month ----------//
//--------- Begin of function NationArray::next_year ---------//
//
void NationArray::next_year()
{
int i;
Nation *nationPtr;
// ###### begin Gilbert 6/9 ########//
LOG_MSG("begin NationArray::next_year");
for( i=size() ; i>0 ; i-- )
{
nationPtr = (Nation*) get_ptr(i);
if( nationPtr ) // nationPtr == NULL, if it's deleted
{
LOG_MSG(i);
nationPtr->next_year();
LOG_MSG(m.get_random_seed() );
}
}
LOG_MSG("end NationArray::next_year");
// ###### end Gilbert 6/9 ########//
}
//---------- End of function NationArray::next_year ----------//
//-------- Begin of function NationArray::random_unused_race --------//
//
// Randomly pick a race id. that hasn't been used by existing nations.
//
int NationArray::random_unused_race()
{
//----- figure out which race has been used, which has not -----//
char usedRaceArray[MAX_RACE];
int usedCount=0;
memset( usedRaceArray, 0, sizeof(usedRaceArray) );
int i;
for( i=1 ; i<=nation_array.size() ; i++ )
{
if( nation_array.is_deleted(i) )
continue;
usedRaceArray[ nation_array[i]->race_id-1 ] = 1;
usedCount++;
}
err_when( usedCount == MAX_RACE );
//----- pick a race randomly from the unused list -----//
int pickedInstance = m.random(MAX_RACE-usedCount)+1;
int usedId=0;
for( i=0 ; icolor_scheme_id-1 ] = 1;
usedCount++;
}
err_when( usedCount == MAX_COLOR_SCHEME );
//----- pick a race randomly from the unused list -----//
int pickedInstance = m.random(MAX_COLOR_SCHEME-usedCount)+1;
int usedId=0;
for( i=0 ; i last_del_nation_date + NEW_NATION_INTERVAL_DAYS &&
info.game_date > last_new_nation_date + NEW_NATION_INTERVAL_DAYS;
}
//--------- End of function NationArray::can_form_new_ai_nation ---------//
//------- Begin of function NationArray::update_statistic ------//
//
void NationArray::update_statistic()
{
//----- reset statistic vars first ------//
int i;
Nation *nationPtr;
for( i=size() ; i>0 ; i-- )
{
if( nation_array.is_deleted(i) )
continue;
nationPtr = nation_array[i];
nationPtr->total_population = 0;
nationPtr->total_jobless_population = 0;
nationPtr->largest_town_recno = 0;
nationPtr->largest_town_pop = 0;
nationPtr->total_spy_count = 0;
nationPtr->total_ship_combat_level = 0;
}
//------ calculate town statistic -------//
independent_town_count = 0;
memset( independent_town_count_race_array, 0, sizeof(independent_town_count_race_array) ); // the no. of independent towns each race has
Town* townPtr;
for( i=town_array.size() ; i>0 ; i-- )
{
if( town_array.is_deleted(i) )
continue;
townPtr = town_array[i];
if( townPtr->nation_recno )
{
Nation* nationPtr = nation_array[townPtr->nation_recno];
nationPtr->total_population += townPtr->population;
nationPtr->total_jobless_population += townPtr->jobless_population;
if( townPtr->population > nationPtr->largest_town_pop )
{
nationPtr->largest_town_pop = townPtr->population;
nationPtr->largest_town_recno = i;
}
}
else
{
independent_town_count++;
//--- the no. of independent towns each race has ---//
for( int j=0 ; jrace_pop_array[j] >= 6 ) // only count it if the pop of the race >= 6
independent_town_count_race_array[j]++;
}
}
}
//------ calculate spy statistic -------//
for( i=spy_array.size() ; i>0 ; i-- )
{
if( spy_array.is_deleted(i) )
continue;
nation_array[ spy_array[i]->true_nation_recno ]->total_spy_count++;
}
//--- update nation rating (this must be called after the above code, which update vars like total_population ---//
for( i=size() ; i>0 ; i-- )
{
if( nation_array.is_deleted(i) )
continue;
nation_array[i]->update_nation_rating();
}
//------ update the military rating of all nations -----//
update_military_rating();
//------ update the total_human_count of all nations -----//
// #ifdef DEBUG
// update_total_human_count(); //**BUGHERE this function to be deleted after checking
// #endif
//--------- update nation maximum ----------//
max_nation_population = 0;
all_nation_population = 0;
max_nation_units = 0;
max_nation_humans = 0;
max_nation_generals = 0;
max_nation_weapons = 0;
max_nation_ships = 0;
max_nation_spies = 0;
max_nation_firms = 0;
max_nation_tech_level = 0;
max_population_rating = -0x7FFF;
max_military_rating = -0x7FFF;
max_economic_rating = -0x7FFF;
max_reputation = -0x7FFF;
max_kill_monster_score = -0x7FFF;
max_overall_rating = -0x7FFF;
max_population_nation_recno = 0;
max_military_nation_recno = 0;
max_economic_nation_recno = 0;
max_reputation_nation_recno = 0;
max_kill_monster_nation_recno = 0;
max_overall_nation_recno = 0;
for( i=size() ; i>0 ; i-- )
{
nationPtr = (Nation*) get_ptr(i);
if( !nationPtr ) // nationPtr == NULL, if it's deleted
continue;
all_nation_population += nationPtr->total_population;
if( nationPtr->total_population > max_nation_population )
max_nation_population = nationPtr->total_population;
if( nationPtr->total_unit_count > max_nation_units )
max_nation_units = nationPtr->total_unit_count;
if( nationPtr->total_human_count > max_nation_humans )
max_nation_humans = nationPtr->total_human_count;
if( nationPtr->total_general_count > max_nation_generals )
max_nation_generals = nationPtr->total_general_count;
if( nationPtr->total_weapon_count > max_nation_weapons )
max_nation_weapons = nationPtr->total_weapon_count;
if( nationPtr->total_ship_count > max_nation_ships )
max_nation_ships = nationPtr->total_ship_count;
if( nationPtr->total_spy_count > max_nation_spies )
max_nation_spies = nationPtr->total_spy_count;
if( nationPtr->total_firm_count > max_nation_firms )
max_nation_firms = nationPtr->total_firm_count;
if( nationPtr->total_tech_level() > max_nation_tech_level )
max_nation_tech_level = nationPtr->total_tech_level();
//----- update maximum nation rating ------//
if( nationPtr->population_rating > max_population_rating )
{
max_population_rating = nationPtr->population_rating;
max_population_nation_recno = i;
}
if( nationPtr->military_rating > max_military_rating )
{
max_military_rating = nationPtr->military_rating;
max_military_nation_recno = i;
}
if( nationPtr->economic_rating > max_economic_rating )
{
max_economic_rating = nationPtr->economic_rating;
max_economic_nation_recno = i;
}
if( (int) nationPtr->reputation > max_reputation )
{
max_reputation = (int) nationPtr->reputation;
max_reputation_nation_recno = i;
}
if( (int) nationPtr->kill_monster_score > max_kill_monster_score )
{
max_kill_monster_score = (int) nationPtr->kill_monster_score;
max_kill_monster_nation_recno = i;
}
if( (int) nationPtr->overall_rating > max_overall_rating )
{
max_overall_rating = (int) nationPtr->overall_rating;
max_overall_nation_recno = i;
}
}
}
//------- End of function NationArray::update_statistic -------//
//------- Begin of function NationArray::update_military_rating ------//
//
void NationArray::update_military_rating()
{
int nationCombatLevelArray[MAX_NATION];
memset( nationCombatLevelArray, 0, sizeof(nationCombatLevelArray) );
//------ calculate firm statistic -------//
Firm* firmPtr;
int i;
for( i=firm_array.size() ; i>0 ; i-- )
{
if( firm_array.is_deleted(i) )
continue;
firmPtr = firm_array[i];
if( firmPtr->nation_recno == 0 ||
firmPtr->firm_id != FIRM_CAMP )
{
continue;
}
nationCombatLevelArray[firmPtr->nation_recno-1] +=
((FirmCamp*)firmPtr)->total_combat_level() +
((firmPtr->overseer_recno>0) + firmPtr->worker_count) * 20; // 20 is the base military points for a unit, so the nation that has many more units can be reflected in the military rating
}
//------ calculate unit statistic -------//
Unit* unitPtr;
for( i=unit_array.size() ; i>0 ; i-- )
{
if( unit_array.is_deleted(i) )
continue;
unitPtr = unit_array[i];
if( unitPtr->nation_recno == 0 )
continue;
//---- if this unit is a ship, increase total_ship_combat_level ----//
if( unit_res[unitPtr->unit_id]->unit_class == UNIT_CLASS_SHIP )
{
nation_array[unitPtr->nation_recno]->total_ship_combat_level += (int) unitPtr->hit_points;
}
//----------------------------------//
if( unitPtr->unit_mode == UNIT_MODE_OVERSEE ) // firm commanders are counted above with firm_array
continue;
int addPoints = (int) unitPtr->hit_points;
UnitInfo* unitInfo = unit_res[unitPtr->unit_id];
if( unitInfo->unit_class == UNIT_CLASS_WEAPON )
addPoints += (unitInfo->weapon_power + unitPtr->get_weapon_version() - 1) * 30;
if( unitPtr->leader_unit_recno && !unit_array.is_deleted(unitPtr->leader_unit_recno) )
addPoints += addPoints * unit_array[unitPtr->leader_unit_recno]->skill.skill_level / 100;
nationCombatLevelArray[unitPtr->nation_recno-1] += addPoints + 20; // 20 is the base military points for a unit, so the nation that has many more units can be reflected in the military rating
}
//------ update nation statistic ------//
for( i=size() ; i>0 ; i-- )
{
if( nation_array.is_deleted(i) )
continue;
nation_array[i]->military_rating = nationCombatLevelArray[i-1]/50;
}
}
//------- End of function NationArray::update_military_rating -------//
//------- Begin of function NationArray::update_total_human_count ------//
//
// Update total human count as there are some bugs in calculation of
// total human count. This function is used for on-fly correcting
// the problem.
//
void NationArray::update_total_human_count()
{
int totalHumanCountArray[MAX_NATION];
memset( totalHumanCountArray, 0, sizeof(totalHumanCountArray) );
//------ calculate firm statistic -------//
Firm* firmPtr;
int i;
for( i=firm_array.size() ; i>0 ; i-- )
{
if( firm_array.is_deleted(i) )
continue;
firmPtr = firm_array[i];
if( firmPtr->nation_recno == 0 )
continue;
if( firmPtr->firm_id == FIRM_CAMP || firmPtr->firm_id == FIRM_BASE )
{
for( int j=firmPtr->worker_count-1 ; j>=0 ; j-- )
{
if( firmPtr->worker_array[j].race_id )
{
totalHumanCountArray[firmPtr->nation_recno-1]++;
}
}
}
}
//------ calculate unit statistic -------//
Unit* unitPtr;
for( i=unit_array.size() ; i>0 ; i-- )
{
if( unit_array.is_truly_deleted(i) )
continue;
unitPtr = unit_array[i];
if( unitPtr->nation_recno && unitPtr->race_id &&
unitPtr->rank_id != RANK_KING ) // does not count kings
{
totalHumanCountArray[unitPtr->nation_recno-1]++;
}
}
//------ update nation statistic ------//
for( i=size() ; i>0 ; i-- )
{
if( nation_array.is_deleted(i) )
continue;
#ifdef DEBUG
err_when( nation_array[i]->total_human_count != totalHumanCountArray[i-1] );
#else
if( nation_array[i]->total_human_count != totalHumanCountArray[i-1] )
nation_array[i]->total_human_count = totalHumanCountArray[i-1];
#endif
}
}
//------- End of function NationArray::update_total_human_count -------//
//-------- Begin of function NationArray::get_human_name --------//
//
// nationNameId - name id. of the nation
// [int] firstWordOnly - whether only return the first word of the name or not.
// (default: 0)
//
char* NationArray::get_human_name(int nationNameId, int firstWordOnly)
{
int nationRecno = -nationNameId;
err_when( nationRecno < 1 || nationRecno > MAX_NATION );
static char humanNameOneWord[HUMAN_NAME_LEN+1];
char* humanName = human_name_array[nationRecno-1];
if( firstWordOnly )
{
int i;
for( i=0 ; i MAX_NATION );
strncpy( human_name_array[nationRecno-1], nameStr, HUMAN_NAME_LEN );
human_name_array[nationRecno-1][HUMAN_NAME_LEN] = NULL;
}
//--------- End of function NationArray::set_human_name ---------//
//------- Begin of function NationArray::disp_nation_color ------//
//
// Display a nation color in a rectangular box.
//
void NationArray::disp_nation_color(int x, int y, int nationColor)
{
vga.active_buf->bar( x, y-2, x+12, y+10, nationColor );
vga.active_buf->rect( x, y-2, x+12, y+10, 1, nationColor+2 );
}
//------- End of function NationArray::disp_nation_color -------//
//------- Begin of function NationBase::should_attack ------//
//
char NationArray::should_attack(short attackingNation, short attackedNation)
{
if( attackingNation == attackedNation )
return 0;
if( attackingNation == 0 || attackedNation == 0 )
return 1;
if( nation_array.is_deleted(attackingNation) || nation_array.is_deleted(attackedNation) )
return 0;
return this->operator[](attackingNation)->get_relation_should_attack(attackedNation);
}
//------- End of function NationBase::should_attack -------//
#ifdef DEBUG
//------- Begin of function NationArray::operator[] -----//
Nation* NationArray::operator[](int recNo)
{
Nation* nationPtr = (Nation*) get_ptr(recNo);
if( !nationPtr )
err.run( "NationArray[] is deleted" );
return nationPtr;
}
//--------- End of function NationArray::operator[] ----//
//------- Begin of function NationArray::operator~ -----//
Nation* NationArray::operator~()
{
if( !player_recno || !player_ptr )
err.run( "~NationArray error" );
return player_ptr;
}
//--------- End of function NationArray::operator~ ----//
#endif
//### begin alex 22/9 ###//
//--------- Begin of function NationArray::draw_profile ---------//
void NationArray::draw_profile()
{
#ifdef DEBUG
static unsigned long lastDrawTime = m.get_time();
if(m.get_time() >= lastDrawTime + 1000)
{
last_nation_ai_profile_time = nation_ai_profile_time;
nation_ai_profile_time = 0L;
last_nation_profile_time = nation_profile_time;
nation_profile_time = 0L;
lastDrawTime = m.get_time();
}
String str;
str = "Nation: ";
font_news.disp( ZOOM_X1+10, ZOOM_Y1+30, str, MAP_X2);
str = "";
str += last_nation_ai_profile_time;
font_news.disp( ZOOM_X1+60, ZOOM_Y1+30, str, MAP_X2);
str = "";
str += last_nation_profile_time;
font_news.disp( ZOOM_X1+100, ZOOM_Y1+30, str, MAP_X2);
#endif
}
//----------- End of function NationArray::draw_profile -----------//
//#### end alex 22/9 ####//