123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931 |
- /*
- * 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 : OBATTLE.CPP
- //Description : Battle Object
- #include <OSYS.h>
- #include <OWORLD.h>
- #include <OPOWER.h>
- #include <OCONFIG.h>
- #include <OSPY.h>
- #include <OMOUSE.h>
- #include <OMUSIC.h>
- #include <OSITE.h>
- #include <ORACERES.h>
- #include <OGODRES.h>
- #include <OTECHRES.h>
- #include <OCONFIG.h>
- #include <OREMOTE.h>
- #include <OTOWN.h>
- #include <OFIRM.h>
- #include <ONEWS.h>
- #include <ONATION.h>
- #include <OMONSRES.h>
- #include <OWALLRES.h>
- #include <OINFO.h>
- #include <OUNITALL.h>
- #include <OGAME.h>
- #include <OBATTLE.h>
- #include <OMOUSECR.h>
- //---------- define static functions -------------//
- static int is_space(int xLoc1, int yLoc1, int xLoc2, int yLoc2, char mobileType);
- //-------- Begin of function Battle::init --------//
- //
- void Battle::init()
- {
- }
- //-------- End of function Battle::init --------//
- //-------- Begin of function Battle::deinit --------//
- //
- void Battle::deinit()
- {
- }
- //-------- End of function Battle::deinit --------//
- //-------- Begin of function Battle::run --------//
- //
- // <int> mpGame - whether this is a multiplayer game or not.
- //
- void Battle::run(NewNationPara *mpGame, int mpPlayerCount)
- {
- int oldCursor = mouse_cursor.get_icon();
- mouse_cursor.set_icon(CURSOR_WAITING);
- #ifdef DEBUG
- debug_sim_game_type = (m.is_file_exist("sim.sys")) ? 2 : 0;
- if(debug_sim_game_type)
- {
- run_sim();
- return;
- }
- #endif
- // ####### begin Gilbert 24/10 #######//
- //-- random seed is initalized at connecting multiplayer --//
- //if( !mpGame )
- // info.init_random_seed(0);
- // ####### end Gilbert 24/10 #######//
- //----------- save the current seed for generating map -----------//
- #ifdef DEBUG2
- File seedFile;
- char *chPtr = m.format(m.get_random_seed());
- seedFile.file_create("mapseed.rs");
- seedFile.file_write(chPtr, strlen(chPtr));
- seedFile.file_close();
- #endif
- world.generate_map();
- //------- create player nation --------//
- if( !mpGame )
- {
- // if config.race_id == 0, select a random race, but don't call m.random
- int nationRecno = nation_array.new_nation( NATION_OWN,
- config.race_id ? config.race_id : 1+m.get_time() % MAX_RACE,
- config.player_nation_color );
- nation_array.set_human_name( nationRecno, config.player_name );
- }
- else
- {
- for( int i = 0; i < mpPlayerCount; ++i )
- {
- int nationRecno = nation_array.new_nation(mpGame[i]);
- if( nationRecno != mpGame[i].nation_recno )
- err.run( "Unexpected nation recno created" );
- nation_array.set_human_name( nationRecno, mpGame[i].player_name );
- }
- }
- //--------- create ai nations --------//
- if( mpGame )
- {
- int aiToCreate = config.ai_nation_count;
- if( aiToCreate + mpPlayerCount > MAX_NATION )
- aiToCreate = MAX_NATION - mpPlayerCount;
- err_when( aiToCreate < 0 );
- create_ai_nation(aiToCreate);
- }
- else
- {
- create_ai_nation(config.ai_nation_count);
- }
- //------ create pregame objects ------//
- create_pregame_object();
- //------- update nation statistic -------//
- nation_array.update_statistic();
- //--- highlight the player's town in the beginning of the game ---//
- Town* townPtr;
- for( int i=1 ; i<=town_array.size() ; i++ )
- {
- townPtr = town_array[i];
- if( townPtr->nation_recno == nation_array.player_recno )
- {
- world.go_loc( townPtr->loc_x1, townPtr->loc_y1 );
- break;
- }
- }
- //---- reset config parameter ----//
- sys.set_speed(12); // set the speed to normal.
- //---- reset cheats ----//
- config.fast_build = 0;
- config.king_undie_flag = sys.testing_session && !mpGame;
- config.blacken_map = 1;
- config.disable_ai_flag = 0;
- if( sys.testing_session )
- config.show_unit_path = 3;
- // ######## begin Gilbert 11/11 #######//
- // enable tech and god, useful for multi-player
- #if(0)
- for( i = 1; i < nation_array.size(); ++i )
- {
- if( !nation_array.is_deleted(i) && !nation_array[i]->is_ai() )
- {
- tech_res.inc_all_tech_level(i);
- god_res.enable_know_all(i);
- }
- }
- #endif
- // ######## end Gilbert 11/11 #######//
- //------- enable/disable sound effects -------//
- #ifdef AMPLUS
- int songId = (~nation_array)->race_id <= 7 ? (~nation_array)->race_id+1 : music.random_bgm_track();
- music.play(songId, sys.cdrom_drive ? MUSIC_CD_THEN_WAV : 0 );
- #else
- music.play((~nation_array)->race_id +1, sys.cdrom_drive ? MUSIC_CD_THEN_WAV : 0 );
- #endif
- mouse_cursor.restore_icon(oldCursor);
- //--- give the control to the system main loop, start the game now ---//
- sys.run();
- }
- //--------- End of function Battle::run ---------//
- //-------- Begin of function Battle::run_sim --------//
- // run simulation
- //
- #ifdef DEBUG
- void Battle::run_sim()
- {
- err_when(!debug_sim_game_type);
- info.disp_panel();
- //info.init_random_seed(0);
- //info.init_random_seed(869451513); // for testing marine
- info.init_random_seed(869639665); // for testing marine
- //info.init_random_seed(866608391);
- //info.init_random_seed(866621716);
- //info.init_random_seed(867299236);
- world.generate_map();
- //--------- refresh world ---------//
- world.refresh();
- vga.blt_buf(0, 0, VGA_WIDTH-1, VGA_HEIGHT-1);
- world.paint();
- //------- create player nation --------//
- // if config.race_id == 0, select a random race, but don't call m.random
- nation_array.new_nation( NATION_OWN,
- config.race_id ? config.race_id : 1+m.get_time() % MAX_RACE,
- config.player_nation_color );
- //--------- create ai nations --------//
- create_ai_nation(config.ai_nation_count);
- //------ create pregame objects ------//
- create_pregame_object();
- //--- highlight the player's town in the beginning of the game ---//
- Town* townPtr;
- for( int i=1 ; i<=town_array.size() ; i++ )
- {
- townPtr = town_array[i];
- if( townPtr->nation_recno == nation_array.player_recno )
- {
- world.go_loc( townPtr->loc_x1, townPtr->loc_y1 );
- break;
- }
- }
- //-*************** create units, objects *****************-//
- int maxNationCount = 2;
- int unitId = UNIT_DRAGON;
- int nationCount;
- SpriteInfo *spriteInfo;
- char teraMask;
- int unitRecno, x, y, xLoc, yLoc;
- //--------- create dragon ---------//
- spriteInfo = sprite_res[unit_res[unitId]->sprite_id];
- teraMask = UnitRes::mobile_type_to_mask(unit_res[unitId]->mobile_type);
- for(nationCount=1; nationCount<=maxNationCount; nationCount++)
- {
- xLoc = 0;
- yLoc = min(20*nationCount, 180);
- for(int createCount=0; createCount<10; createCount++, xLoc+=4) // createCount<50
- {
- for(y=0; y<4; y+=2)
- {
- for(x=0; x<4; x+=2)
- {
- unitRecno = unit_array.add_unit(unitId, nationCount, RANK_SOLDIER, 100, xLoc+x, yLoc+y);
- unit_array[unitRecno]->set_combat_level(100);
- ((UnitGod*)unit_array[unitRecno])->god_id = 1;
- }
- }
- }
- }
- //--------- create marine units ---------//
- unitId = UNIT_CARAVEL;
- spriteInfo = sprite_res[unit_res[unitId]->sprite_id];
- teraMask = UnitRes::mobile_type_to_mask(unit_res[unitId]->mobile_type);
- for(nationCount=1; nationCount<=maxNationCount; nationCount++)
- {
- for(int t=0; t<30; t++)
- {
- xLoc=0;
- yLoc=0;
- if(world.locate_space_random(xLoc, yLoc, MAX_WORLD_X_LOC-1,
- MAX_WORLD_Y_LOC-1, spriteInfo->loc_width*4, spriteInfo->loc_height*4,
- MAX_WORLD_X_LOC*MAX_WORLD_Y_LOC, 0, 0, teraMask))
- {
- if(xLoc%2)
- xLoc++;
- if(yLoc%2)
- yLoc++;
- for(y=0; y<2; y++)
- {
- for(x=0; x<2; x++)
- {
- //world.get_loc(startXLoc, startYLoc)->can_move(unit_res[unit_id]->mobile_type)
- unitRecno = unit_array.add_unit(unitId, nationCount, RANK_SOLDIER, 100, xLoc+x*2, yLoc+y*2);
- unit_array[unitRecno]->set_combat_level(100);
- }
- }
- }
- }
- }
- //--------- create land units ---------//
- for(nationCount=1; nationCount<=maxNationCount; nationCount++)
- {
- for(unitId=UNIT_NORMAN; unitId<=UNIT_JAPANESE; unitId++)
- {
- spriteInfo = sprite_res[unit_res[unitId]->sprite_id];
- teraMask = UnitRes::mobile_type_to_mask(unit_res[unitId]->mobile_type);
- for(int t=0; t<5; t++)
- {
- xLoc=0;
- yLoc=0;
- if(world.locate_space_random(xLoc, yLoc, MAX_WORLD_X_LOC-1,
- MAX_WORLD_Y_LOC-1, spriteInfo->loc_width*2, spriteInfo->loc_height*2,
- MAX_WORLD_X_LOC*MAX_WORLD_Y_LOC, 0, 0, teraMask))
- {
- for(y=0; y<2; y++)
- {
- for(x=0; x<2; x++)
- {
- //world.get_loc(startXLoc, startYLoc)->can_move(unit_res[unit_id]->mobile_type)
- unitRecno = unit_array.add_unit(unitId, nationCount, RANK_SOLDIER, 100, xLoc+x, yLoc+y);
- unit_array[unitRecno]->set_combat_level(100);
- }
- }
- }
- }
- }
- }
- //-- enable power after the game objets has been initialized --//
- power.enable(); // enable power, which handle mouse inputs
- //--- give the control to the system main loop, start the game now ---//
- sys.run();
- }
- #endif
- //--------- End of function Battle::run_sim ---------//
- //-------- Begin of function Battle::create_ai_nation --------//
- //
- // Create AI nations.
- //
- void Battle::create_ai_nation(int aiNationCount)
- {
- int raceId;
- for( int i=0 ; i<aiNationCount ; i++ )
- {
- err_when( nation_array.size() == MAX_NATION );
- if( config.random_start_up )
- raceId = m.random(MAX_RACE)+1;
- else
- raceId = nation_array.random_unused_race();
- err_when( raceId < 1 || raceId > MAX_RACE );
- int nationRecno;
- nationRecno = nation_array.new_nation( NATION_AI, raceId, nation_array.random_unused_color() ); // 2nd parameter = the race id., 3rd parameters = color scheme id.
- }
- }
- //--------- End of function Battle::create_ai_nation ---------//
- //-------- Begin of function Battle::create_pregame_object --------//
- //
- // Initialize pre-game objects - towns, sites, independent towns.
- //
- void Battle::create_pregame_object()
- {
- #define CREATE_UNIT_AREA_WIDTH 16
- #define CREATE_UNIT_AREA_HEIGHT 16
- // ###### begin Gilbert 24/10 ######//
- const int dispProgress = 1;
- const int maxGenMapSteps = 100;
- const int newWorldSection = 1;
- vga_front.unlock_buf();
- int curGenMapSteps = 0;
- if( dispProgress )
- {
- vga_front.lock_buf();
- game.disp_gen_map_status( curGenMapSteps, maxGenMapSteps, newWorldSection);
- vga_front.unlock_buf();
- }
- // ###### end Gilbert 24/10 ######//
- //------- create nation and units --------//
- int nationRecno, unitId, rankId, xLoc, yLoc, townRecno;
- int kingUnitRecno;
- int noSpaceFlag=0;
- Nation* nationPtr;
- for( nationRecno=1 ; nationRecno<=nation_array.size() ; nationRecno++ )
- {
- if( nation_array.is_deleted(nationRecno) )
- continue;
- nationPtr = nation_array[nationRecno];
- //--------- create town -----------//
- townRecno = create_town( nationRecno, nationPtr->race_id, xLoc, yLoc );
- if( !townRecno )
- {
- noSpaceFlag = 1;
- break;
- }
- //------- create military camp -------//
- Town* townPtr = town_array[townRecno];
- int firmRecno = firm_array.build_firm(townPtr->loc_x1+6, townPtr->loc_y1,
- nationRecno, FIRM_CAMP, race_res[nationPtr->race_id]->code);
- if( !firmRecno )
- {
- noSpaceFlag = 1;
- break;
- }
- firm_array[firmRecno]->complete_construction();
- //--------- create units ----------//
- unitId = race_res[nationPtr->race_id]->basic_unit_id;
- kingUnitRecno = create_unit(townRecno, unitId, RANK_KING);
- if( kingUnitRecno )
- {
- nation_array[nationRecno]->set_king(kingUnitRecno, 1); // 1-this is the first king of the nation
- firm_array[firmRecno]->assign_overseer(kingUnitRecno); // assign the king as the overseer of the command base
- }
- else
- {
- noSpaceFlag = 1;
- break;
- }
- //----- create skilled units if config.random_start_up is 1 -----//
- if( config.random_start_up )
- {
- int createCount = (50-townPtr->population)/3; // the less population the villager has the more mobile units will be created
- for( int i=0 ; i<createCount ; i++ )
- {
- if( m.random(2)==0 )
- unitId = race_res[nationPtr->race_id]->basic_unit_id;
- else
- unitId = race_res[ m.random(MAX_RACE)+1 ]->basic_unit_id;
- if( m.random(3)==0 )
- rankId = RANK_GENERAL;
- else
- rankId = RANK_SOLDIER;
- if( !create_unit(townRecno, unitId, rankId) )
- break;
- }
- }
- //------ create mines near towns in the beginning -----//
- if( config.start_up_has_mine_nearby && !nationPtr->is_ai() )
- site_array.create_raw_site(0, townRecno);
- }
- //--- if there is no space for creating new town/firm or unit, delete the unprocessed nations ---//
- if( noSpaceFlag )
- {
- for( ; nationRecno<=nation_array.size() ; nationRecno++ )
- nation_array.del_nation(nationRecno); // no space for creating a town for the nation, so we have to delete the nation
- }
- // ###### begin Gilbert 24/10 ########//
- curGenMapSteps += 10; // 10
- if( dispProgress )
- {
- vga_front.lock_buf();
- game.disp_gen_map_status( curGenMapSteps, maxGenMapSteps, newWorldSection);
- vga_front.unlock_buf();
- }
- // ###### end Gilbert 24/10 ######//
- //---- init the type of active monsters in this game ----//
- monster_res.init_active_monster();
- // ###### begin Gilbert 24/10 ########//
- curGenMapSteps += 5; // 15
- if( dispProgress )
- {
- vga_front.lock_buf();
- game.disp_gen_map_status( curGenMapSteps, maxGenMapSteps, newWorldSection);
- vga_front.unlock_buf();
- }
- // ###### end Gilbert 24/10 ######//
- //------ create independent towns -------//
- //### begin alex 27/8 ###//
- int startUpIndependentTown = config.start_up_independent_town;
- //int startUpRawSite = config.start_up_raw_site;
- int startUpMonsterFirm = 10;
- int i, j, raceId;
- site_array.generate_raw_site(config.start_up_raw_site);
- // ###### begin Gilbert 24/10 ########//
- curGenMapSteps += 10; // 25
- if( dispProgress )
- {
- vga_front.lock_buf();
- game.disp_gen_map_status( curGenMapSteps, maxGenMapSteps, newWorldSection);
- vga_front.unlock_buf();
- }
- int targetStep = maxGenMapSteps;
- // ###### end Gilbert 24/10 ######//
- int maxLoopCount = startUpIndependentTown + startUpMonsterFirm;
- for(j=0, i=1; j<maxLoopCount; j++, i++)
- {
- if(startUpIndependentTown)
- {
- //------ create independent towns -------//
- raceId = i%MAX_RACE+1;
- if(!create_town( 0, raceId, xLoc, yLoc ) )
- {
- startUpIndependentTown = 0;
- break;
- }
- // ##### begin Gilbert 24/10 #######//
- else
- startUpIndependentTown--;
- // ###### end Gilbert 24/10 ########//
- }
- if(startUpMonsterFirm)
- {
- //------- create mosnters --------//
- if(config.monster_type != OPTION_MONSTER_NONE)
- {
- monster_res.generate(1);
- startUpMonsterFirm--;
- }
- else
- startUpMonsterFirm = 0;
- }
- if(!(startUpIndependentTown+startUpMonsterFirm))
- break;
- // ###### begin Gilbert 24/10 ########//
- if( dispProgress )
- {
- vga_front.lock_buf();
- game.disp_gen_map_status( curGenMapSteps + j*(targetStep-curGenMapSteps)/maxLoopCount, maxGenMapSteps, newWorldSection);
- vga_front.unlock_buf();
- }
- // ###### end Gilbert 24/10 ######//
- }
- //#### end alex 27/8 ####//
- // ###### begin Gilbert 24/10 ########//
- // finish
- curGenMapSteps = targetStep; // 100
- if( dispProgress )
- {
- vga_front.lock_buf();
- game.disp_gen_map_status( curGenMapSteps, maxGenMapSteps, newWorldSection);
- vga_front.unlock_buf();
- }
- // ###### end Gilbert 24/10 ######//
- vga_front.lock_buf();
- }
- //--------- End of function Battle::create_pregame_object ---------//
- //-------- Begin of function Battle::run_loaded --------//
- //
- void Battle::run_loaded()
- {
- //-------- play music ---------//
- char kingRace = 0;
- if( !nation_array.is_deleted(nation_array.player_recno) )
- {
- if( !unit_array.is_deleted((~nation_array)->king_unit_recno) )
- // if there is king in the nation take his race
- kingRace = unit_array[(~nation_array)->king_unit_recno]->race_id;
- else
- // if king is killed, get the original nation
- kingRace = (~nation_array)->race_id;
- }
- #ifdef AMPLUS
- int songId = kingRace <= 7 ? kingRace+1 : music.random_bgm_track();
- music.play(songId, sys.cdrom_drive ? MUSIC_CD_THEN_WAV : 0 );
- #else
- music.play( kingRace+1, sys.cdrom_drive ? MUSIC_CD_THEN_WAV : 0 );
- #endif
- //--- give the control to the system main loop, start the game now ---//
- sys.run(1);
- }
- //--------- End of function Battle::run_loaded ---------//
- //-------- Begin of function Battle::run_test --------//
- //
- void Battle::run_test()
- {
- info.disp_panel();
- info.init_random_seed(153542);
- world.generate_map();
- //--------- refresh world ---------//
- world.refresh();
- vga.blt_buf(0, 0, VGA_WIDTH-1, VGA_HEIGHT-1);
- world.paint();
- //-------- create nation and units --------//
- nation_array.new_nation( NATION_OWN, 1, 1 ); // 2nd parameter = the race id. 3rd parameters = color scheme id.
- nation_array.new_nation( NATION_AI , 2, 2 ); // 2nd parameter = the race id. 3rd parameters = color scheme id.
- tech_res.inc_all_tech_level(1); // set all tech of nation 1 to level 1
- tech_res.inc_all_tech_level(2); // set all tech of nation 2 to level 1
- create_test_unit(1);
- create_test_unit(2);
- //-- enable power after the game objets has been initialized --//
- power.enable(); // enable power, which handle mouse inputs
- //--- give the control to the system main loop, start the game now ---//
- sys.run();
- }
- //--------- End of function Battle::run_test ---------//
- //-------- Begin of function Battle::create_test_unit --------//
- //
- void Battle::create_test_unit(int nationRecno)
- {
- int x, y, unitId, xLoc, yLoc;
- SpriteInfo* spriteInfo;
- for( unitId=1 ; unitId<=MAX_UNIT_TYPE ; unitId++ )
- {
- if( unitId == UNIT_CARAVAN ) // caravan cannot be created independently without market places
- continue;
- xLoc=0;
- yLoc=0;
- spriteInfo = sprite_res[ unit_res[unitId]->sprite_id ];
- char teraMask = UnitRes::mobile_type_to_mask(unit_res[unitId]->mobile_type);
- if( world.locate_space_random(xLoc, yLoc, MAX_WORLD_X_LOC-1,
- MAX_WORLD_Y_LOC-1, spriteInfo->loc_width*4, spriteInfo->loc_height*4,
- MAX_WORLD_X_LOC*MAX_WORLD_Y_LOC, 0, 0, teraMask) )
- {
- for( y=spriteInfo->loc_height ; y<spriteInfo->loc_height*4 ; y+=spriteInfo->loc_height*2 )
- {
- for( x=spriteInfo->loc_width ; x<spriteInfo->loc_width*4 ; x+=spriteInfo->loc_width*2 )
- {
- // force the location to be even number
- int unitRecno = unit_array.add_unit( unitId, nationRecno, RANK_SOLDIER, 100, (xLoc+x)& ~1, (yLoc+y) & ~1 );
- unit_array[unitRecno]->set_combat_level(100);
- }
- }
- }
- }
- }
- //--------- End of function Battle::create_test_unit ---------//
- //-------- Begin of function Battle::create_town --------//
- //
- // <int> nationRecno = the nation recno of the town
- // <int> raceId = the race id. of the town
- //
- // <int&> xLoc = for the starting location of the town
- // <int&> yLoc = for the starting location of the town
- //
- // return: <int> townRecno - >0 the recno of the town created
- // ==0 no town created
- //
- int Battle::create_town(int nationRecno, int raceId, int& xLoc, int& yLoc)
- {
- //------- locate for a space to build the town ------//
- if( !town_array.think_town_loc(MAX_WORLD_X_LOC*MAX_WORLD_Y_LOC, xLoc, yLoc) )
- return 0;
- //--------------- create town ---------------//
- int townRecno = town_array.add_town(nationRecno, raceId, xLoc, yLoc);
- Town* townPtr = town_array[townRecno];
- //--------- no. of mixed races ---------//
- if( nationRecno )
- {
- int initPop;
- if( config.random_start_up )
- initPop = 25 + m.random(26); // 25 to 50
- else
- initPop = 40;
- Town* townPtr = town_array[townRecno];
- townPtr->init_pop( raceId, initPop, 100, 0, 1 ); // 100-startup loyalty, last 1-first initialization at the beginning of the game
- }
- else
- {
- int mixedRaceCount;
- if( nationRecno )
- mixedRaceCount = 1;
- else
- mixedRaceCount= m.random(3)+1; // 1 to 3 mixed races
- int curPop, totalPop=0, townResistance;
- for( int i=0 ; i<mixedRaceCount ; i++ )
- {
- if(totalPop>=MAX_TOWN_POPULATION)
- break;
- townResistance = town_array.independent_town_resistance();
- if( i==0 )
- {
- curPop = 15/mixedRaceCount + m.random(15/mixedRaceCount);
- if(curPop>=MAX_TOWN_POPULATION)
- curPop = MAX_TOWN_POPULATION;
- err_when(curPop==0);
- townPtr->init_pop( raceId, curPop, townResistance, 0, 1 ); // last 1-first initialization at the beginning of the game
- totalPop += curPop;
- }
- else
- {
- curPop = 10/mixedRaceCount + m.random(10/mixedRaceCount);
- if(curPop>=MAX_TOWN_POPULATION-totalPop)
- curPop = MAX_TOWN_POPULATION-totalPop;
- err_when(curPop==0);
- townPtr->init_pop( m.random(MAX_RACE)+1, curPop, townResistance, 0, 1 );
- totalPop += curPop;
- }
- }
- }
- //---------- set town layout -----------//
- townPtr->auto_set_layout();
- return townRecno;
- }
- //--------- End of function Battle::create_town ---------//
- //-------- Begin of function Battle::create_unit --------//
- //
- // Add a specific no. of units within a given area
- //
- // <int> townRecno - create units around this town.
- // <int> unitId - id. of the units to be added
- // <int> rankId - rank id. of the unit
- //
- // return: <int> recno of the unit created.
- //
- int Battle::create_unit(int townRecno, int unitId, int rankId)
- {
- SpriteInfo* spriteInfo = sprite_res[ unit_res[unitId]->sprite_id ];
- Town* townPtr = town_array[townRecno];
- //------ locate space for the unit ------//
- int xLoc = townPtr->loc_x1;
- int yLoc = townPtr->loc_y1;
- if( !world.locate_space( xLoc, yLoc, xLoc+STD_TOWN_LOC_WIDTH-1, yLoc+STD_TOWN_LOC_HEIGHT-1,
- spriteInfo->loc_width, spriteInfo->loc_height ) )
- {
- return 0;
- }
- //---------- create the unit --------//
- int unitLoyalty = 80 + m.random(20);
- int unitRecno = unit_array.add_unit( unitId, townPtr->nation_recno, rankId, unitLoyalty, xLoc, yLoc );
- if( !unitRecno )
- return 0;
- Unit* unitPtr = unit_array[unitRecno];
- //----------- set skill -------------//
- switch( rankId )
- {
- case RANK_KING:
- unitPtr->skill.set_skill(SKILL_LEADING);
- unitPtr->skill.skill_level = 100;
- unitPtr->set_combat_level(100);
- break;
- case RANK_GENERAL:
- unitPtr->skill.set_skill(SKILL_LEADING);
- unitPtr->skill.skill_level = 40 + m.random(50); // 40 to 90
- unitPtr->set_combat_level(30 + m.random(70)); // 30 to 100
- break;
- case RANK_SOLDIER:
- {
- int skillId = m.random(MAX_TRAINABLE_SKILL)+1;
- int spyFlag = 0;
- if( skillId == SKILL_SPYING )
- {
- spyFlag = 1;
- unitPtr->set_combat_level(10+m.random(10));
- }
- else
- {
- unitPtr->skill.skill_id = skillId;
- unitPtr->skill.skill_level = 30+m.random(70);
- if( skillId == SKILL_LEADING )
- unitPtr->set_combat_level(30+m.random(70));
- else
- unitPtr->set_combat_level(10+m.random(10));
- if( m.random(5)==0 )
- spyFlag = 1;
- }
- if( spyFlag )
- {
- int spySkill = 20 + m.random(80); // 20 to 100
- unitPtr->spy_recno = spy_array.add_spy(unitRecno, spySkill);
- }
- break;
- }
- default:
- err_here();
- }
- return unitRecno;
- }
- //--------- End of function Battle::create_unit ---------//
- //-------- Begin of static function is_space --------//
- //
- // Check whether all locations in the given area are space
- //
- // return : <int> 1 - all are space
- // 0 - not all are space
- //
- static int is_space(int xLoc1, int yLoc1, int xLoc2, int yLoc2, char mobileType)
- {
- int xLoc, yLoc;
- Location* locPtr;
- for( yLoc=yLoc1 ; yLoc<=yLoc2 ; yLoc++ )
- {
- locPtr = world.get_loc(xLoc1, yLoc);
- for( xLoc=xLoc1 ; xLoc<=xLoc2 ; xLoc++, locPtr++ )
- {
- if( !locPtr->can_move(mobileType) )
- return 0;
- }
- }
- return 1;
- }
- //--------- End of static function is_space ---------//
|