/*
* 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 : OGFILE3.CPP
//Description : Object Game file, save game and restore game, part 3
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//------- declare static functions -------//
static char* create_monster_func();
static char* create_rebel_func();
static void write_ai_info(File* filePtr, short* aiInfoArray, short aiInfoCount, short aiInfoSize);
static void read_ai_info(File* filePtr, short** aiInfoArrayPtr, short& aiInfoCount, short& aiInfoSize);
//-------- Start of function UnitArray::write_file -------------//
//
int UnitArray::write_file(File* filePtr)
{
int i;
Unit *unitPtr;
filePtr->file_put_short(restart_recno); // variable in SpriteArray
filePtr->file_put_short( size() ); // no. of units in unit_array
filePtr->file_put_short( selected_recno );
filePtr->file_put_short( selected_count );
filePtr->file_put_long ( cur_group_id );
filePtr->file_put_long ( cur_team_id );
filePtr->file_put_short(idle_blocked_unit_reset_count);
filePtr->file_put_long (unit_search_tries);
filePtr->file_put_short(unit_search_tries_flag);
filePtr->file_put_short(visible_unit_count);
filePtr->file_put_short(mp_first_frame_to_select_caravan);
filePtr->file_put_short(mp_first_frame_to_select_ship);
filePtr->file_put_short(mp_pre_selected_caravan_recno);
filePtr->file_put_short(mp_pre_selected_ship_recno);
for( i=1; i<=size() ; i++ )
{
unitPtr = (Unit*) get_ptr(i);
//----- write unitId or 0 if the unit is deleted -----//
if( !unitPtr ) // the unit is deleted
{
filePtr->file_put_short(0);
}
else
{
//--------- write unit_id -------------//
filePtr->file_put_short(unitPtr->unit_id);
//------ write data in the base class ------//
if( !unitPtr->write_file(filePtr) )
return 0;
//------ write data in the derived class ------//
if( !unitPtr->write_derived_file(filePtr) )
return 0;
}
}
//------- write empty room array --------//
write_empty_room(filePtr);
return 1;
}
//--------- End of function UnitArray::write_file ---------------//
//-------- Start of function UnitArray::read_file -------------//
//
int UnitArray::read_file(File* filePtr)
{
Unit* unitPtr;
int i, unitId, emptyRoomCount=0;
restart_recno = filePtr->file_get_short();
int unitCount = filePtr->file_get_short(); // get no. of units from file
selected_recno = filePtr->file_get_short();
selected_count = filePtr->file_get_short();
cur_group_id = filePtr->file_get_long();
cur_team_id = filePtr->file_get_long();
idle_blocked_unit_reset_count = filePtr->file_get_short();
unit_search_tries = filePtr->file_get_long ();
unit_search_tries_flag = (char) filePtr->file_get_short();
visible_unit_count = filePtr->file_get_short();
mp_first_frame_to_select_caravan = (char) filePtr->file_get_short();
mp_first_frame_to_select_ship = (char) filePtr->file_get_short();
mp_pre_selected_caravan_recno = filePtr->file_get_short();
mp_pre_selected_ship_recno = filePtr->file_get_short();
for( i=1 ; i<=unitCount ; i++ )
{
unitId = filePtr->file_get_short();
if( unitId==0 ) // the unit has been deleted
{
add_blank(1); // it's a DynArrayB function
emptyRoomCount++;
}
else
{
//----- create unit object -----------//
unitPtr = create_unit( unitId );
unitPtr->unit_id = unitId;
//---- read data in base class -----//
if( !unitPtr->read_file( filePtr ) )
return 0;
//----- read data in derived class -----//
if( !unitPtr->read_derived_file( filePtr ) )
return 0;
}
}
//-------- linkout() those record added by add_blank() ----------//
//-- So they will be marked deleted in DynArrayB and can be -----//
//-- undeleted and used when a new record is going to be added --//
for( i=size() ; i>0 ; i-- )
{
DynArrayB::go(i); // since UnitArray has its own go() which will call GroupArray::go()
if( get_ptr() == NULL ) // add_blank() record
linkout();
}
//------- read empty room array --------//
read_empty_room(filePtr);
//------- verify the empty_room_array loading -----//
#ifdef DEBUG
err_when( empty_room_count != emptyRoomCount );
for( i=0 ; ifile_write( this, sizeof(Unit) ) )
return 0;
//--------------- write memory data ----------------//
if( result_node_array )
{
if( !filePtr->file_write( result_node_array, sizeof(ResultNode) * result_node_count ) )
return 0;
}
//### begin alex 15/10 ###//
if(way_point_array)
{
err_when(way_point_array_size==0 || way_point_array_sizefile_write(way_point_array, sizeof(ResultNode)*way_point_array_size))
return 0;
}
//#### end alex 15/10 ####//
if( team_info )
{
if( !filePtr->file_write( team_info, sizeof(TeamInfo) ) )
return 0;
}
return 1;
}
//----------- End of function Unit::write_file ---------//
//--------- Begin of function Unit::read_file ---------//
//
int Unit::read_file(File* filePtr)
{
char* vfPtr = *((char**)this); // save the virtual function table pointer
if( !filePtr->file_read( this, sizeof(Unit) ) )
return 0;
*((char**)this) = vfPtr;
//--------------- read in memory data ----------------//
if( result_node_array )
{
result_node_array = (ResultNode*) mem_add( sizeof(ResultNode) * result_node_count );
if( !filePtr->file_read( result_node_array, sizeof(ResultNode) * result_node_count ) )
return 0;
}
//### begin alex 15/10 ###//
if(way_point_array)
{
way_point_array = (ResultNode*) mem_add(sizeof(ResultNode) * way_point_array_size);
if(!filePtr->file_read(way_point_array, sizeof(ResultNode)*way_point_array_size))
return 0;
}
//#### end alex 15/10 ####//
if( team_info )
{
team_info = (TeamInfo*) mem_add( sizeof(TeamInfo) );
if( !filePtr->file_read( team_info, sizeof(TeamInfo) ) )
return 0;
}
//----------- post-process the data read ----------//
// attack_info_array = unit_res.attack_info_array+unit_res[unit_id]->first_attack-1;
sprite_info = sprite_res[sprite_id];
sprite_info->load_bitmap_res();
//--------- special process of UNIT_MARINE --------//
// move to read_derived_file
//if( unit_res[unit_id]->unit_class == UNIT_CLASS_SHIP )
//{
// ((UnitMarine*)this)->splash.sprite_info = sprite_res[sprite_id];
// ((UnitMarine*)this)->splash.sprite_info->load_bitmap_res();
//}
return 1;
}
//----------- End of function Unit::read_file ---------//
//--------- Begin of function Unit::write_derived_file ---------//
//
int Unit::write_derived_file(File* filePtr)
{
//--- write data in derived class -----//
int writeSize = unit_array.unit_class_size(unit_id)-sizeof(Unit);
if( writeSize > 0 )
{
if( !filePtr->file_write( (char*) this + sizeof(Unit), writeSize ) )
return 0;
}
return 1;
}
//----------- End of function Unit::write_derived_file ---------//
//--------- Begin of function Unit::read_derived_file ---------//
//
int Unit::read_derived_file(File* filePtr)
{
//--- read data in derived class -----//
int readSize = unit_array.unit_class_size(unit_id) - sizeof(Unit);
if( readSize > 0 )
{
if( !filePtr->file_read( (char*) this + sizeof(Unit), readSize ) )
return 0;
}
// ###### begin Gilbert 13/8 #######//
fix_attack_info();
// ###### end Gilbert 13/8 #######//
return 1;
}
//----------- End of function Unit::read_derived_file ---------//
//--------- Begin of function UnitMarine::read_derived_file ---------//
int UnitMarine::read_derived_file(File* filePtr)
{
//---- backup virtual functions table pointer of splash ----//
char* splashVfPtr = *((char **)&splash);
//--------- read file --------//
if( !Unit::read_derived_file(filePtr) )
return 0;
// -------- restore virtual function table pointer -------//
*((char **)&splash) = splashVfPtr ;
// ------- post-process the data read --------//
splash.sprite_info = sprite_res[splash.sprite_id];
splash.sprite_info->load_bitmap_res();
return 1;
}
//--------- End of function UnitMarine::read_derived_file ---------//
//*****//
//-------- Start of function BulletArray::write_file -------------//
//
int BulletArray::write_file(File* filePtr)
{
filePtr->file_put_short(restart_recno); // variable in SpriteArray
int i, emptyRoomCount=0;;
Bullet *bulletPtr;
filePtr->file_put_short( size() ); // no. of bullets in bullet_array
for( i=1; i<=size() ; i++ )
{
bulletPtr = (Bullet*) get_ptr(i);
//----- write bulletId or 0 if the bullet is deleted -----//
if( !bulletPtr ) // the bullet is deleted
{
filePtr->file_put_short(0);
emptyRoomCount++;
}
else
{
filePtr->file_put_short(bulletPtr->sprite_id); // there is a bullet in this record
//------ write data in the base class ------//
if( !bulletPtr->write_file(filePtr) )
return 0;
//------ write data in the derived class -------//
if( !bulletPtr->write_derived_file(filePtr) )
return 0;
}
}
//------- write empty room array --------//
write_empty_room(filePtr);
//------- verify the empty_room_array loading -----//
#ifdef DEBUG
err_when( empty_room_count != emptyRoomCount );
for( i=0 ; ifile_get_short();
int i, bulletRecno, bulletCount, emptyRoomCount=0, spriteId;
Bullet* bulletPtr;
bulletCount = filePtr->file_get_short(); // get no. of bullets from file
for( i=1 ; i<=bulletCount ; i++ )
{
spriteId = filePtr->file_get_short();
if( spriteId == 0 )
{
add_blank(1); // it's a DynArrayB function
emptyRoomCount++;
}
else
{
//----- create bullet object -----------//
bulletRecno = create_bullet(spriteId);
bulletPtr = bullet_array[bulletRecno];
//----- read data in base class --------//
if( !bulletPtr->read_file( filePtr ) )
return 0;
//----- read data in derived class -----//
if( !bulletPtr->read_derived_file( filePtr ) )
return 0;
}
}
//-------- linkout() those record added by add_blank() ----------//
//-- So they will be marked deleted in DynArrayB and can be -----//
//-- undeleted and used when a new record is going to be added --//
for( i=1 ; i<=size() ; i++ )
{
DynArrayB::go(i); // since BulletArray has its own go() which will call GroupArray::go()
if( get_ptr() == NULL ) // add_blank() record
linkout();
}
//------- read empty room array --------//
read_empty_room(filePtr);
//------- verify the empty_room_array loading -----//
#ifdef DEBUG
err_when( empty_room_count != emptyRoomCount );
for( i=0 ; ifile_write( this, sizeof(Bullet) ) )
return 0;
return 1;
}
//----------- End of function Bullet::write_file ---------//
//--------- Begin of function Bullet::read_file ---------//
//
int Bullet::read_file(File* filePtr)
{
char* vfPtr = *((char**)this); // save the virtual function table pointer
if( !filePtr->file_read( this, sizeof(Bullet) ) )
return 0;
*((char**)this) = vfPtr;
//------------ post-process the data read ----------//
sprite_info = sprite_res[sprite_id];
sprite_info->load_bitmap_res();
return 1;
}
//----------- End of function Bullet::read_file ---------//
//----------- Begin of function Bullet::write_derived_file ---------//
int Bullet::write_derived_file(File *filePtr)
{
//--- write data in derived class -----//
int writeSize = bullet_array.bullet_class_size(sprite_id)-sizeof(Bullet);
if( writeSize > 0 )
{
if( !filePtr->file_write( (char*) this + sizeof(Bullet), writeSize ) )
return 0;
}
return 1;
}
//----------- End of function Bullet::write_derived_file ---------//
//----------- Begin of function Bullet::read_derived_file ---------//
int Bullet::read_derived_file(File *filePtr)
{
//--- read data in derived class -----//
int readSize = bullet_array.bullet_class_size(sprite_id) - sizeof(Bullet);
if( readSize > 0 )
{
if( !filePtr->file_read( (char*) this + sizeof(Bullet), readSize ) )
return 0;
}
return 1;
}
//----------- End of function Bullet::read_derived_file ---------//
//----------- Begin of function Projectile::read_derived_file ---------//
int Projectile::read_derived_file(File *filePtr)
{
//--- backup virtual function table pointer of act_bullet and bullet_shadow ---//
char* actBulletVfPtr = *((char**)&act_bullet);
char* bulletShadowVfPtr = *((char**)&bullet_shadow);
//---------- read file ----------//
if( !Bullet::read_derived_file(filePtr) )
return 0;
//------ restore virtual function table pointer --------//
*((char**)&act_bullet) = actBulletVfPtr;
*((char**)&bullet_shadow) = bulletShadowVfPtr;
//----------- post-process the data read ----------//
act_bullet.sprite_info = sprite_res[act_bullet.sprite_id];
act_bullet.sprite_info->load_bitmap_res();
bullet_shadow.sprite_info = sprite_res[bullet_shadow.sprite_id];
bullet_shadow.sprite_info->load_bitmap_res();
return 1;
}
//----------- End of function Projectile::read_derived_file ---------//
//*****//
//-------- Start of function FirmArray::write_file -------------//
//
int FirmArray::write_file(File* filePtr)
{
int i;
Firm *firmPtr;
filePtr->file_put_short( size() ); // no. of firms in firm_array
filePtr->file_put_short( process_recno );
filePtr->file_put_short( selected_recno );
filePtr->file_put_short( Firm::firm_menu_mode );
filePtr->file_put_short( Firm::action_spy_recno );
filePtr->file_put_short( Firm::bribe_result );
filePtr->file_put_short( Firm::assassinate_result );
for( i=1; i<=size() ; i++ )
{
firmPtr = (Firm*) get_ptr(i);
//----- write firmId or 0 if the firm is deleted -----//
if( !firmPtr ) // the firm is deleted
{
filePtr->file_put_short(0);
}
else
{
//--------- write firm_id -------------//
filePtr->file_put_short(firmPtr->firm_id);
//------ write data in base class --------//
if( !filePtr->file_write( firmPtr, sizeof(Firm) ) )
return 0;
//--------- write worker_array ---------//
if( firmPtr->worker_array )
{
if( !filePtr->file_write( firmPtr->worker_array, MAX_WORKER*sizeof(Worker) ) )
return 0;
}
//------ write data in derived class ------//
if( !firmPtr->write_derived_file(filePtr) )
return 0;
}
}
//------- write empty room array --------//
write_empty_room(filePtr);
return 1;
}
//--------- End of function FirmArray::write_file ---------------//
//-------- Start of function FirmArray::read_file -------------//
//
int FirmArray::read_file(File* filePtr)
{
Firm* firmPtr;
char* vfPtr;
int i, firmId, firmRecno;
int firmCount = filePtr->file_get_short(); // get no. of firms from file
process_recno = filePtr->file_get_short();
selected_recno = filePtr->file_get_short();
Firm::firm_menu_mode = (char) filePtr->file_get_short();
Firm::action_spy_recno = filePtr->file_get_short();
Firm::bribe_result = (char) filePtr->file_get_short();
Firm::assassinate_result = (char) filePtr->file_get_short();
for( i=1 ; i<=firmCount ; i++ )
{
firmId = filePtr->file_get_short();
if( firmId==0 ) // the firm has been deleted
{
add_blank(1); // it's a DynArrayB function
}
else
{
//----- create firm object -----------//
firmRecno = create_firm( firmId );
firmPtr = firm_array[firmRecno];
//---- read data in base class -----//
vfPtr = *((char**)firmPtr); // save the virtual function table pointer
if( !filePtr->file_read( firmPtr, sizeof(Firm) ) )
return 0;
#ifdef AMPLUS
if(!game_file_array.same_version && firmPtr->firm_id > FIRM_BASE)
firmPtr->firm_build_id += MAX_RACE - VERSION_1_MAX_RACE;
#endif
*((char**)firmPtr) = vfPtr;
//--------- read worker_array ---------//
if( firm_res[firmId]->need_worker )
{
firmPtr->worker_array = (Worker*) mem_add( MAX_WORKER*sizeof(Worker) );
if( !filePtr->file_read( firmPtr->worker_array, MAX_WORKER*sizeof(Worker) ) )
return 0;
}
//----- read data in derived class -----//
if( !firmPtr->read_derived_file( filePtr ) )
return 0;
}
}
//-------- linkout() those record added by add_blank() ----------//
//-- So they will be marked deleted in DynArrayB and can be -----//
//-- undeleted and used when a new record is going to be added --//
for( i=size() ; i>0 ; i-- )
{
DynArrayB::go(i); // since FirmArray has its own go() which will call GroupArray::go()
if( get_ptr() == NULL ) // add_blank() record
linkout();
}
//------- read empty room array --------//
read_empty_room(filePtr);
return 1;
}
//--------- End of function FirmArray::read_file ---------------//
//--------- Begin of function Firm::write_derived_file ---------//
//
// Write data in derived class.
//
// If the derived Firm don't have any special data,
// just use Firm::write_file(), otherwise make its own derived copy of write_file()
//
int Firm::write_derived_file(File* filePtr)
{
//--- write data in derived class -----//
int writeSize = firm_array.firm_class_size(firm_id)-sizeof(Firm);
if( writeSize > 0 )
{
if( !filePtr->file_write( (char*) this + sizeof(Firm), writeSize ) )
return 0;
}
return 1;
}
//----------- End of function Firm::write_derived_file ---------//
//--------- Begin of function Firm::read_derived_file ---------//
//
// Read data in derived class.
//
// If the derived Firm don't have any special data,
// just use Firm::read_file(), otherwise make its own derived copy of read_file()
//
int Firm::read_derived_file(File* filePtr)
{
//--- read data in derived class -----//
int readSize = firm_array.firm_class_size(firm_id)-sizeof(Firm);
if( readSize > 0 )
{
if( !filePtr->file_read( (char*) this + sizeof(Firm), readSize ) )
return 0;
}
return 1;
}
//----------- End of function Firm::read_derived_file ---------//
//*****//
//-------- Start of function SiteArray::write_file -------------//
//
int SiteArray::write_file(File* filePtr)
{
filePtr->file_put_short(selected_recno);
filePtr->file_put_short(untapped_raw_count);
filePtr->file_put_short(scroll_count);
filePtr->file_put_short(gold_coin_count);
filePtr->file_put_short(std_raw_site_count);
return DynArrayB::write_file( filePtr );
}
//--------- End of function SiteArray::write_file ---------------//
//-------- Start of function SiteArray::read_file -------------//
//
int SiteArray::read_file(File* filePtr)
{
selected_recno = filePtr->file_get_short();
untapped_raw_count = filePtr->file_get_short();
scroll_count = filePtr->file_get_short();
gold_coin_count = filePtr->file_get_short();
std_raw_site_count = filePtr->file_get_short();
return DynArrayB::read_file( filePtr );
}
//--------- End of function SiteArray::read_file ---------------//
//*****//
//-------- Start of function TownArray::write_file -------------//
//
int TownArray::write_file(File* filePtr)
{
int i;
Town *townPtr;
filePtr->file_put_short( size() ); // no. of towns in town_array
filePtr->file_put_short( selected_recno );
filePtr->file_write( race_wander_pop_array, sizeof(race_wander_pop_array) );
filePtr->file_put_short( Town::if_town_recno );
//-----------------------------------------//
for( i=1; i<=size() ; i++ )
{
townPtr = (Town*) get_ptr(i);
//----- write townId or 0 if the town is deleted -----//
if( !townPtr ) // the town is deleted
{
filePtr->file_put_short(0);
}
else
{
#ifdef DEBUG
townPtr->verify_slot_object_id_array(); // for debugging only
#endif
filePtr->file_put_short(1); // the town exists
if( !filePtr->file_write( townPtr, sizeof(Town) ) )
return 0;
}
}
//------- write empty room array --------//
write_empty_room(filePtr);
return 1;
}
//--------- End of function TownArray::write_file ---------------//
//-------- Start of function TownArray::read_file -------------//
//
int TownArray::read_file(File* filePtr)
{
Town* townPtr;
int i;
int townCount = filePtr->file_get_short(); // get no. of towns from file
selected_recno = filePtr->file_get_short();
#ifdef AMPLUS
if(!game_file_array.same_version)
{
memset(race_wander_pop_array, 0, sizeof(race_wander_pop_array));
filePtr->file_read( race_wander_pop_array, sizeof(race_wander_pop_array[0])*VERSION_1_MAX_RACE );
}
else
filePtr->file_read( race_wander_pop_array, sizeof(race_wander_pop_array) );
#else
filePtr->file_read( race_wander_pop_array, sizeof(race_wander_pop_array) );
#endif
Town::if_town_recno = filePtr->file_get_short();
//------------------------------------------//
for( i=1 ; i<=townCount ; i++ )
{
if( filePtr->file_get_short()==0 ) // the town has been deleted
{
add_blank(1); // it's a DynArrayB function
}
else
{
townPtr = town_array.create_town();
#ifdef AMPLUS
if(!game_file_array.same_version)
{
Version_1_Town *oldTown = (Version_1_Town*) mem_add(sizeof(Version_1_Town));
if(!filePtr->file_read(oldTown, sizeof(Version_1_Town)))
{
mem_del(oldTown);
return 0;
}
oldTown->convert_to_version_2(townPtr);
mem_del(oldTown);
}
else
{
if( !filePtr->file_read( townPtr, sizeof(Town) ) )
return 0;
}
#else
if( !filePtr->file_read( townPtr, sizeof(Town) ) )
return 0;
#endif
#ifdef DEBUG
townPtr->verify_slot_object_id_array(); // for debugging only
#endif
}
}
//-------- linkout() those record added by add_blank() ----------//
//-- So they will be marked deleted in DynArrayB and can be -----//
//-- undeleted and used when a new record is going to be added --//
for( i=size() ; i>0 ; i-- )
{
DynArrayB::go(i); // since TownArray has its own go() which will call GroupArray::go()
if( get_ptr() == NULL ) // add_blank() record
linkout();
}
//------- read empty room array --------//
read_empty_room(filePtr);
return 1;
}
//--------- End of function TownArray::read_file ---------------//
//*****//
//-------- Start of function NationArray::write_file -------------//
//
int NationArray::write_file(File* filePtr)
{
//------ write info in NationArray ------//
if( !filePtr->file_write( (char*) this + sizeof(DynArrayB), sizeof(NationArray)-sizeof(DynArrayB) ) )
return 0;
//---------- write Nations --------------//
int i;
Nation *nationPtr;
filePtr->file_put_short( size() ); // no. of nations in nation_array
for( i=1; i<=size() ; i++ )
{
nationPtr = (Nation*) get_ptr(i);
//----- write nationId or 0 if the nation is deleted -----//
if( !nationPtr ) // the nation is deleted
{
filePtr->file_put_short(0);
}
else
{
filePtr->file_put_short(1); // there is a nation in this record
//------ write data in the base class ------//
if( !nationPtr->write_file(filePtr) )
return 0;
}
}
//------- write empty room array --------//
write_empty_room(filePtr);
return 1;
}
//--------- End of function NationArray::write_file -------------//
//-------- Start of function NationArray::read_file -------------//
//
int NationArray::read_file(File* filePtr)
{
//------ read info in NationArray ------//
#ifdef AMPLUS
if(!game_file_array.same_version)
{
Version_1_NationArray *oldNationArrayPtr = (Version_1_NationArray*) mem_add(sizeof(Version_1_NationArray));
//if( !filePtr->file_read( (char*) oldNationArrayPtr + sizeof(DynArrayB), sizeof(Version_1_NationArray)-sizeof(DynArrayB) ) )
if( !filePtr->file_read( (char*) oldNationArrayPtr, sizeof(Version_1_NationArray) ) )
{
mem_del(oldNationArrayPtr);
return 0;
}
oldNationArrayPtr->convert_to_version_2(this);
mem_del(oldNationArrayPtr);
}
else
{
if( !filePtr->file_read( (char*) this + sizeof(DynArrayB), sizeof(NationArray)-sizeof(DynArrayB) ) )
return 0;
}
#else
if( !filePtr->file_read( (char*) this + sizeof(DynArrayB), sizeof(NationArray)-sizeof(DynArrayB) ) )
return 0;
#endif
//---------- read Nations --------------//
int i, nationRecno, nationCount;
Nation* nationPtr;
nationCount = filePtr->file_get_short(); // get no. of nations from file
for( i=1 ; i<=nationCount ; i++ )
{
if( filePtr->file_get_short() == 0 )
{
add_blank(1); // it's a DynArrayB function
}
else
{
//----- create nation object -----------//
nationRecno = create_nation();
nationPtr = nation_array[nationRecno];
//----- read data in base class --------//
if( !nationPtr->read_file( filePtr ) )
return 0;
}
}
//-------- linkout() those record added by add_blank() ----------//
//-- So they will be marked deleted in DynArrayB and can be -----//
//-- undeleted and used when a new record is going to be added --//
for( i=size() ; i>0 ; i-- )
{
DynArrayB::go(i); // since NationArray has its own go() which will call GroupArray::go()
if( get_ptr() == NULL ) // add_blank() record
linkout();
}
//-------- set NationArray::player_ptr -----------//
player_ptr = nation_array[player_recno];
//------- read empty room array --------//
read_empty_room(filePtr);
return 1;
}
//--------- End of function NationArray::read_file ---------------//
//--------- Begin of function Nation::write_file ---------//
//
int Nation::write_file(File* filePtr)
{
if( !filePtr->file_write( this, sizeof(Nation) ) )
return 0;
//----------- write AI Action Array ------------//
action_array.write_file(filePtr);
//------ write AI info array ---------//
write_ai_info(filePtr, ai_town_array, ai_town_count, ai_town_size);
write_ai_info(filePtr, ai_base_array, ai_base_count, ai_base_size);
write_ai_info(filePtr, ai_mine_array, ai_mine_count, ai_mine_size);
write_ai_info(filePtr, ai_factory_array, ai_factory_count, ai_factory_size);
write_ai_info(filePtr, ai_market_array, ai_market_count, ai_market_size);
write_ai_info(filePtr, ai_inn_array, ai_inn_count, ai_inn_size);
write_ai_info(filePtr, ai_camp_array, ai_camp_count, ai_camp_size);
write_ai_info(filePtr, ai_research_array, ai_research_count, ai_research_size);
write_ai_info(filePtr, ai_war_array, ai_war_count, ai_war_size);
write_ai_info(filePtr, ai_harbor_array, ai_harbor_count, ai_harbor_size);
write_ai_info(filePtr, ai_caravan_array, ai_caravan_count, ai_caravan_size);
write_ai_info(filePtr, ai_ship_array, ai_ship_count, ai_ship_size);
write_ai_info(filePtr, ai_general_array, ai_general_count, ai_general_size);
return 1;
}
//----------- End of function Nation::write_file ---------//
//--------- Begin of static function write_ai_info ---------//
//
static void write_ai_info(File* filePtr, short* aiInfoArray, short aiInfoCount, short aiInfoSize)
{
filePtr->file_put_short( aiInfoCount );
filePtr->file_put_short( aiInfoSize );
filePtr->file_write( aiInfoArray, sizeof(short) * aiInfoCount );
}
//----------- End of static function write_ai_info ---------//
//--------- Begin of function Nation::read_file ---------//
//
int Nation::read_file(File* filePtr)
{
char* vfPtr = *((char**)this); // save the virtual function table pointer
//---- save the action_array first before loading in the whole Nation class ----//
char* saveActionArray = (char*) mem_add( sizeof(DynArray) );
memcpy( saveActionArray, &action_array, sizeof(DynArray) );
//--------------------------------------------------//
#ifdef AMPLUS
if(!game_file_array.same_version)
{
Version_1_Nation *oldNationPtr = (Version_1_Nation*) mem_add(sizeof(Version_1_Nation));
if(!filePtr->file_read(oldNationPtr, sizeof(Version_1_Nation)))
{
mem_del(oldNationPtr);
return 0;
}
oldNationPtr->convert_to_version_2(this);
mem_del(oldNationPtr);
}
else
{
if( !filePtr->file_read( this, sizeof(Nation) ) )
return 0;
}
#else
if( !filePtr->file_read( this, sizeof(Nation) ) )
return 0;
#endif
*((char**)this) = vfPtr;
//---------- restore action_array ------------//
memcpy( &action_array, saveActionArray, sizeof(DynArray) );
mem_del( saveActionArray );
//-------------- read AI Action Array --------------//
action_array.read_file(filePtr);
//------ write AI info array ---------//
read_ai_info(filePtr, &ai_town_array, ai_town_count, ai_town_size);
read_ai_info(filePtr, &ai_base_array, ai_base_count, ai_base_size);
read_ai_info(filePtr, &ai_mine_array, ai_mine_count, ai_mine_size);
read_ai_info(filePtr, &ai_factory_array, ai_factory_count, ai_factory_size);
read_ai_info(filePtr, &ai_market_array, ai_market_count, ai_market_size);
read_ai_info(filePtr, &ai_inn_array, ai_inn_count, ai_inn_size);
read_ai_info(filePtr, &ai_camp_array, ai_camp_count, ai_camp_size);
read_ai_info(filePtr, &ai_research_array, ai_research_count, ai_research_size);
read_ai_info(filePtr, &ai_war_array, ai_war_count, ai_war_size);
read_ai_info(filePtr, &ai_harbor_array, ai_harbor_count, ai_harbor_size);
read_ai_info(filePtr, &ai_caravan_array, ai_caravan_count, ai_caravan_size);
read_ai_info(filePtr, &ai_ship_array, ai_ship_count, ai_ship_size);
read_ai_info(filePtr, &ai_general_array, ai_general_count, ai_general_size);
return 1;
}
//----------- End of function Nation::read_file ---------//
//--------- Begin of static function read_ai_info ---------//
//
static void read_ai_info(File* filePtr, short** aiInfoArrayPtr, short& aiInfoCount, short& aiInfoSize)
{
aiInfoCount = filePtr->file_get_short();
aiInfoSize = filePtr->file_get_short();
*aiInfoArrayPtr = (short*) mem_add( aiInfoSize * sizeof(short) );
filePtr->file_read( *aiInfoArrayPtr, sizeof(short) * aiInfoCount );
}
//----------- End of static function read_ai_info ---------//
//*****//
//-------- Start of function TornadoArray::write_file -------------//
//
int TornadoArray::write_file(File* filePtr)
{
filePtr->file_put_short(restart_recno); // variable in SpriteArray
int i;
Tornado *tornadoPtr;
filePtr->file_put_short( size() ); // no. of tornados in tornado_array
for( i=1; i<=size() ; i++ )
{
tornadoPtr = (Tornado*) get_ptr(i);
//----- write tornadoId or 0 if the tornado is deleted -----//
if( !tornadoPtr ) // the tornado is deleted
{
filePtr->file_put_short(0);
}
else
{
filePtr->file_put_short(1); // there is a tornado in this record
//------ write data in the base class ------//
if( !tornadoPtr->write_file(filePtr) )
return 0;
}
}
//------- write empty room array --------//
write_empty_room(filePtr);
return 1;
}
//--------- End of function TornadoArray::write_file -------------//
//-------- Start of function TornadoArray::read_file -------------//
//
int TornadoArray::read_file(File* filePtr)
{
restart_recno = filePtr->file_get_short();
int i, tornadoRecno, tornadoCount;
Tornado* tornadoPtr;
tornadoCount = filePtr->file_get_short(); // get no. of tornados from file
for( i=1 ; i<=tornadoCount ; i++ )
{
if( filePtr->file_get_short() == 0 )
{
add_blank(1); // it's a DynArrayB function
}
else
{
//----- create tornado object -----------//
tornadoRecno = tornado_array.create_tornado();
tornadoPtr = tornado_array[tornadoRecno];
//----- read data in base class --------//
if( !tornadoPtr->read_file( filePtr ) )
return 0;
}
}
//-------- linkout() those record added by add_blank() ----------//
//-- So they will be marked deleted in DynArrayB and can be -----//
//-- undeleted and used when a new record is going to be added --//
for( i=size() ; i>0 ; i-- )
{
DynArrayB::go(i); // since TornadoArray has its own go() which will call GroupArray::go()
if( get_ptr() == NULL ) // add_blank() record
linkout();
}
//------- read empty room array --------//
read_empty_room(filePtr);
return 1;
}
//--------- End of function TornadoArray::read_file ---------------//
//--------- Begin of function Tornado::write_file ---------//
//
int Tornado::write_file(File* filePtr)
{
if( !filePtr->file_write( this, sizeof(Tornado) ) )
return 0;
return 1;
}
//----------- End of function Tornado::write_file ---------//
//--------- Begin of function Tornado::read_file ---------//
//
int Tornado::read_file(File* filePtr)
{
char* vfPtr = *((char**)this); // save the virtual function table pointer
if( !filePtr->file_read( this, sizeof(Tornado) ) )
return 0;
*((char**)this) = vfPtr;
//------------ post-process the data read ----------//
sprite_info = sprite_res[sprite_id];
sprite_info->load_bitmap_res();
return 1;
}
//----------- End of function Tornado::read_file ---------//
//*****//
//-------- Start of function RebelArray::write_file -------------//
//
int RebelArray::write_file(File* filePtr)
{
return write_ptr_array(filePtr, sizeof(Rebel));
}
//--------- End of function RebelArray::write_file ---------------//
//-------- Start of function RebelArray::read_file -------------//
//
int RebelArray::read_file(File* filePtr)
{
return read_ptr_array(filePtr, sizeof(Rebel), create_rebel_func);
}
//--------- End of function RebelArray::read_file ---------------//
//-------- Start of static function create_rebel_func ---------//
//
static char* create_rebel_func()
{
Rebel *rebelPtr = new Rebel;
rebel_array.linkin(&rebelPtr);
return (char*) rebelPtr;
}
//--------- End of static function create_rebel_func ----------//
//*****//
//-------- Start of function SpyArray::write_file -------------//
//
int SpyArray::write_file(File* filePtr)
{
return DynArrayB::write_file( filePtr );
}
//--------- End of function SpyArray::write_file ---------------//
//-------- Start of function SpyArray::read_file -------------//
//
int SpyArray::read_file(File* filePtr)
{
return DynArrayB::read_file( filePtr );
}
//--------- End of function SpyArray::read_file ---------------//
//*****//
//-------- Start of function SnowGroundArray::write_file -------------//
//
int SnowGroundArray::write_file(File* filePtr)
{
if( !filePtr->file_write( this, sizeof(SnowGroundArray)) )
return 0;
return 1;
}
//--------- End of function SnowGroundArray::write_file ---------------//
//-------- Start of function SnowGroundArray::read_file -------------//
//
int SnowGroundArray::read_file(File* filePtr)
{
if( !filePtr->file_read( this, sizeof(SnowGroundArray)) )
return 0;
return 1;
}
//--------- End of function SnowGroundArray::read_file ---------------//
//*****//
//-------- Start of function RegionArray::write_file -------------//
//
int RegionArray::write_file(File* filePtr)
{
if( !filePtr->file_write( this, sizeof(RegionArray)) )
return 0;
if( !filePtr->file_write( region_info_array, sizeof(RegionInfo)*region_info_count ) )
return 0;
//-------- write RegionStat ----------//
filePtr->file_put_short( region_stat_count );
if( !filePtr->file_write( region_stat_array, sizeof(RegionStat)*region_stat_count ) )
return 0;
//--------- write connection bits ----------//
int connectBit = (region_info_count -1) * (region_info_count) /2;
int connectByte = (connectBit +7) /8;
if( connectByte > 0)
{
if( !filePtr->file_write(connect_bits, connectByte) )
return 0;
}
return 1;
}
//--------- End of function RegionArray::write_file ---------------//
//-------- Start of function RegionArray::read_file -------------//
//
int RegionArray::read_file(File* filePtr)
{
if( !filePtr->file_read( this, sizeof(RegionArray)) )
return 0;
if( region_info_count > 0 )
region_info_array = (RegionInfo *) mem_add(sizeof(RegionInfo)*region_info_count);
else
region_info_array = NULL;
if( !filePtr->file_read( region_info_array, sizeof(RegionInfo)*region_info_count))
return 0;
//-------- read RegionStat ----------//
region_stat_count = filePtr->file_get_short();
region_stat_array = (RegionStat*) mem_add( region_stat_count * sizeof(RegionStat) );
if( !filePtr->file_read( region_stat_array, sizeof(RegionStat)*region_stat_count ) )
return 0;
//--------- read connection bits ----------//
int connectBit = (region_info_count -1) * (region_info_count) /2;
int connectByte = (connectBit +7) /8;
if( connectByte > 0)
{
connect_bits = (unsigned char *)mem_add(connectByte);
if( !filePtr->file_read(connect_bits, connectByte) )
return 0;
}
else
{
connect_bits = NULL;
}
return 1;
}
//--------- End of function RegionArray::read_file ---------------//
//*****//
//-------- Start of function NewsArray::write_file -------------//
//
int NewsArray::write_file(File* filePtr)
{
//----- save news_array parameters -----//
filePtr->file_write( news_type_option, sizeof(news_type_option) );
filePtr->file_put_short(news_who_option);
filePtr->file_put_long (last_clear_recno);
//---------- save news data -----------//
return DynArray::write_file(filePtr);
}
//--------- End of function NewsArray::write_file ---------------//
//-------- Start of function NewsArray::read_file -------------//
//
int NewsArray::read_file(File* filePtr)
{
//----- read news_array parameters -----//
filePtr->file_read( news_type_option, sizeof(news_type_option) );
news_who_option = (char) filePtr->file_get_short();
last_clear_recno = filePtr->file_get_long();
//---------- read news data -----------//
return DynArray::read_file(filePtr);
}
//--------- End of function NewsArray::read_file ---------------//