123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760 |
- /*
- * 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 : OINFO.CPP
- //Description : Info class
- #include <time.h>
- #include <OVGA.h>
- #include <OIMGRES.h>
- #include <OSPY.h>
- #include <OSTR.h>
- #include <OBUTTON.h>
- #include <OMOUSE.h>
- #include <OFIRM.h>
- #include <OSTR.h>
- #include <ONEWS.h>
- #include <ONATION.h>
- #include <OFONT.h>
- #include <ODATE.h>
- #include <OTOWN.h>
- #include <ODATE.h>
- #include <OGAME.h>
- #include <OGFILE.h>
- #include <OPOWER.h>
- #include <OSITE.h>
- #include <OWALLRES.h>
- #include <OSYS.h>
- #include <OUNIT.h>
- #include <OCOLTBL.h>
- #include <OINFO.h>
- #include <OOPTMENU.h>
- //------------ Define static vars ----------------//
- static char* skill_name_array[] =
- {
- "Combat Skill",
- "Construction Skill",
- "Production Skill"
- };
- //------ define static vars --------//
- static char *save_buf_1 = NULL;
- static char *save_buf_1b = NULL;
- static char *save_buf_2 = NULL;
- static char *save_buf_3 = NULL;
- static char *save_buf_4 = NULL;
- //-------- Begin of function Info::Info --------//
- //
- Info::Info() : report_array(sizeof(short), 50),
- report_array2(sizeof(short), 50),
- talk_msg_disp_array(sizeof(TalkMsgDisp), 50)
- {
- info_background_bitmap = NULL;
- }
- //--------- End of function Info::Info ---------//
- //-------- Begin of function Info::~Info --------//
- //
- Info::~Info()
- {
- deinit();
- err_when( save_buf_1 );
- }
- //--------- End of function Info::~Info ---------//
- //-------- Begin of function Info::init --------//
- //
- void Info::init()
- {
- deinit();
- game_day = 1;
- game_month = 6;
- game_year = 1000;
- game_start_date = date.julian( game_year, game_month, game_day );
- game_date = game_start_date;
- year_day = date.day_year( game_year, game_month, game_day );
- year_passed= 0; // no. of years has been passed since the game begins
- goal_deadline = date.julian( date.year(info.game_start_date)+config.goal_year_limit,
- date.month(info.game_start_date),
- date.day(info.game_start_date) );
- goal_difficulty = 0;
- goal_score_bonus = 0;
- //------ reset report browsers recno -----//
- browse_nation_recno = 0;
- browse_race_recno = 0;
- browse_firm_recno = 0;
- browse_income_recno = 0;
- browse_expense_recno = 0;
- browse_troop_recno = 0;
- browse_unit_recno = 0;
- browse_tech_recno = 0;
- browse_god_recno = 0;
- browse_town_recno = 0;
- browse_spy_recno = 0;
- browse_caravan_recno = 0;
- browse_ship_recno = 0;
- browse_talk_msg_recno= 0;
- browse_news_recno = 0;
- browse_ai_action_recno = 0;
- browse_ai_attack_recno = 0;
- //------ vars of the nation report ------//
- nation_report_mode = NATION_REPORT_INFO;
- player_reply_mode = 0;
- chat_receiver_type = CHAT_RECEIVER_CURRENT;
- //----------------------------------//
- start_play_time = m.get_time(); // the time player start playing the game
- total_play_time = 0; // total time the player has played in all saved games
- // these will be updated during loading game and saving game
- err_when( MAX_REMOTE_CHAT_STR < DISP_NEWS_COUNT ); // it must not fewer then the maximum number of news that can be displayed on the screen at a time.
- }
- //--------- End of function Info::init ---------//
- //-------- Begin of function Info::deinit --------//
- //
- void Info::deinit()
- {
- if( info_background_bitmap )
- {
- mem_del( info_background_bitmap );
- info_background_bitmap = NULL;
- }
- }
- //--------- End of function Info::deinit ---------//
- //------- Begin of function Info::init_random_seed ------//
- //
- // [unsigned] randomSeed - if given, it will be the random seed of the game.
- // random seed. otherwise a random seed will be
- // picked.
- // (default:0)
- //
- void Info::init_random_seed(int randomSeed)
- {
- if( randomSeed )
- random_seed = randomSeed;
- else
- {
- randomSeed = time(NULL);
- randomSeed = (int) _rotr( randomSeed, 4 );
- if( randomSeed < 0 )
- randomSeed = ~randomSeed;
- if( randomSeed == 0 )
- randomSeed = 1;
- random_seed = randomSeed;
- }
- m.set_random_seed(random_seed);
- //------ write random seed --------//
- if( sys.testing_session )
- {
- File fileMapSeed;
- fileMapSeed.file_create( "MAP.RS" );
- String str(m.format(random_seed,1));
- fileMapSeed.file_write(str, str.len());
- }
- }
- //------- End of function Info::init_random_seed ------//
- //-------- Begin of function Info::next_day ---------//
- //
- void Info::next_day()
- {
- if( ++game_day > 30 )
- game_day = 30; // game_day is limited to 1-30 for
- // calculation of e.g. revenue_30days()
- game_date++;
- week_day=game_date%7;
- //-----------------------------------------//
- if( date.month(game_date) != game_month )
- {
- game_day = 1;
- game_month = date.month(game_date);
- firm_array.next_month();
- nation_array.next_month();
- }
- if( date.year(game_date) != game_year )
- {
- game_month = 1;
- game_year = date.year(game_date);
- year_passed++;
- firm_array.next_year();
- nation_array.next_year();
- }
- //-------- set year_day ----------//
- year_day = date.day_year( game_year, game_month, game_day );
- //--- if a spy is viewing secret reports of other nations ---//
- if( viewing_spy_recno )
- process_viewing_spy();
- //-------- deadline approaching message -------//
- if( !game.game_has_ended && config.goal_year_limit_flag )
- {
- int dayLeft = goal_deadline-game_date;
- int yearLeft = dayLeft/365;
- if( dayLeft%365==0 && yearLeft>=1 && yearLeft<=5 )
- news_array.goal_deadline( yearLeft, 0 );
- if( dayLeft==0 ) // deadline arrives, everybody loses the game
- game.game_end(0, 0);
- }
- }
- //---------- End of function Info::next_day --------//
- //-------- Begin of function Info::disp_panel --------//
- //
- void Info::disp_panel()
- {
- image_interface.put_to_buf( &vga_back, "MAINSCR" );
- //------ keep a copy of bitmap of the panel texture -----//
- if( !info_background_bitmap )
- info_background_bitmap = mem_add( 4 + (INFO_X2-INFO_X1+1)*(INFO_Y2-INFO_Y1+1) );
- vga_back.read_bitmap( INFO_X1, INFO_Y1, INFO_X2, INFO_Y2, info_background_bitmap );
- }
- //--------- End of function Info::disp_panel ---------//
- //-------- Begin of function Info::disp --------//
- //
- // Display the side info area.
- //
- void Info::disp()
- {
- // mouse.handle_flicking = 0; // since it will be called by Firm detect functions directly which may have set mouse.handle_flicking to 1 first, so we need to cancel it here
- if( !power.enable_flag )
- return;
- if( sys.signal_exit_flag )
- return;
- if( option_menu.is_active() )
- return;
- vga_back.put_bitmap( INFO_X1, INFO_Y1, info_background_bitmap );
- vga_front.put_bitmap( INFO_X1, INFO_Y1, info_background_bitmap );
- //------- use front buffer -------//
- int saveUseBackBuf = vga.use_back_buf;
- vga.use_front();
- //------ if units/firm selected, display info --------//
- if( firm_array.selected_recno )
- {
- firm_array[firm_array.selected_recno]->disp_info_both(INFO_REPAINT);
- }
- else if( town_array.selected_recno )
- {
- town_array[town_array.selected_recno]->disp_info(INFO_REPAINT);
- }
- else if( site_array.selected_recno )
- {
- site_array[site_array.selected_recno]->disp_info(INFO_REPAINT);
- }
- else if( unit_array.selected_recno )
- {
- unit_array[unit_array.selected_recno]->disp_info(INFO_REPAINT);
- }
- else if( wall_res.selected_x_loc >= 0 )
- {
- wall_res.disp_info(INFO_REPAINT);
- }
- //----- restore use back buffer if it was ----//
- if( saveUseBackBuf )
- vga.use_back();
- }
- //-------- End of function Info::disp --------//
- //-------- Begin of function Info::update --------//
- void Info::update()
- {
- if( !power.enable_flag )
- return;
- if( option_menu.is_active() )
- return;
- //-------------------------------------------//
- disp_heading();
- //------- use front buffer -------//
- int saveUseBackBuf = vga.use_back_buf;
- vga.use_front();
- //-------------------------------------------//
- if( firm_array.selected_recno )
- {
- firm_array[firm_array.selected_recno]->disp_info_both(INFO_UPDATE);
- }
- else if( town_array.selected_recno )
- {
- town_array[town_array.selected_recno]->disp_info(INFO_UPDATE);
- }
- else if( site_array.selected_recno )
- {
- site_array[site_array.selected_recno]->disp_info(INFO_UPDATE);
- }
- else if( unit_array.selected_recno )
- {
- unit_array[unit_array.selected_recno]->disp_info(INFO_UPDATE);
- }
- else if( wall_res.selected_x_loc >= 0 )
- {
- wall_res.disp_info(INFO_UPDATE);
- }
- //----- restore use back buffer if it was ----//
- if( saveUseBackBuf )
- vga.use_back();
- }
- //-------- End of function Info::update --------//
- //-------- Begin of function Info::disp_heading --------//
- void Info::disp_heading()
- {
- //---- display info on the top menu area ----//
- int x=TOP_MENU_X2-250;
- //---------- display date -----------//
- font_mid.use_max_height();
- font_mid.disp( 460, 10, date.date_str(game_date,1), 575);
- font_mid.use_std_height();
- if( !nation_array.player_recno ) // the player has lost the game
- {
- font_mid.disp( 307, 10, "", 445); // clear the display
- font_mid.disp( 305, 30, "", 445);
- // ##### begin Gilbert 4/11 #######//
- image_icon.put_front(447,26, "REPU_DW" );
- // ##### end Gilbert 4/11 #######//
- font_mid.disp( 476, 30, "", 575);
- return;
- }
- String str;
- Nation* nationPtr = ~nation_array;
- //------- display food and net food change --------//
- err_when( vga.use_back_buf );
- char* strPtr = nationPtr->food_str();
- font_mid.disp( 307, 10, strPtr, 445);
- //------- display cash and profit --------//
- strPtr = nationPtr->cash_str();
- font_mid.disp( 305, 30, strPtr, 445);
- //------- display reputation ---------//
- if( nationPtr->reputation >= 0 )
- {
- str = m.format( (int)nationPtr->reputation, 4 ); // format type 4 - no thousand separators
- }
- else
- {
- str = "-";
- str += m.format( (int)-nationPtr->reputation, 4 ); // format type 4 - no thousand separators
- }
- int reputationChange = (int) nationPtr->reputation_change_365days();
- if( reputationChange )
- {
- str += " (";
- if( reputationChange > 0 )
- str += "+";
- else
- str += "-";
- str += abs(reputationChange);
- str += ")";
- }
- image_icon.put_front(447,26, nationPtr->reputation_change_365days() >= (float)0.0 ? (char*)"REPU_UP" : (char*)"REPU_DW" );
- font_mid.disp( 476, 30, str, 575);
- }
- //-------- End of function Info::disp_heading --------//
- //-------- Begin of function Info::detect --------//
- int Info::detect()
- {
- //------------ detect objects ------------//
- if( firm_array.selected_recno )
- {
- firm_array[firm_array.selected_recno]->detect_info_both();
- }
- else if( town_array.selected_recno )
- {
- town_array[town_array.selected_recno]->detect_info();
- }
- else if( site_array.selected_recno )
- {
- site_array[site_array.selected_recno]->detect_info();
- }
- else if( unit_array.selected_recno )
- {
- unit_array[unit_array.selected_recno]->detect_info();
- }
- return 0;
- }
- //-------- End of function Info::detect --------//
- //-------- Begin of function Info::draw_selected --------//
- void Info::draw_selected()
- {
- if( firm_array.selected_recno )
- firm_array[firm_array.selected_recno]->draw_selected();
- else if( town_array.selected_recno )
- town_array[town_array.selected_recno]->draw_selected();
- else if( site_array.selected_recno )
- site_array[site_array.selected_recno]->draw_selected();
- else if( wall_res.selected_x_loc >= 0 )
- wall_res.draw_selected();
- }
- //-------- End of function Info::draw_selected --------//
- //-------- Begin of function Info::get_report_data --------//
- short Info::get_report_data(int recNo)
- {
- err_when( recNo<1 || recNo>report_array.size() );
- return *((short*)report_array.get(recNo));
- }
- //-------- End of function Info::get_report_data --------//
- //-------- Begin of function Info::get_report_data2 --------//
- short Info::get_report_data2(int recNo)
- {
- err_when( recNo<1 || recNo>report_array2.size() );
- return *((short*)report_array2.get(recNo));
- }
- //-------- End of function Info::get_report_data2 --------//
- //-------- Begin of function Info::process_viewing_spy --------//
- void Info::process_viewing_spy()
- {
- //---- check if the viewing spy is still valid ----//
- int isValid=1;
- if( spy_array.is_deleted(viewing_spy_recno) ) // the spy is dead
- {
- isValid = 0;
- }
- else
- {
- Spy* spyPtr = spy_array[viewing_spy_recno];
- //-- check if the spy still stay in the same place --//
- if( spyPtr->spy_place_nation_recno() != info.viewing_nation_recno )
- {
- isValid = 0;
- }
- else
- {
- /*
- //--- on average, a spy will get caught in 5 to 15 days when viewing the secret of its enemy ---//
- if( m2.random(5+spyPtr->spy_skill/5) ) // use m2 to avoid multiplayer sync problem
- {
- spyPtr->set_exposed(COMMAND_PLAYER);
- isValid = 0;
- }
- */
- }
- }
- if( !isValid ) //-- if not valid, set the mode back to normal viewing mode
- sys.set_view_mode(MODE_NORMAL);
- }
- //-------- End of function Info::process_viewing_spy --------//
- //------- Begin of function Info::play_time_str --------//
- //
- char* Info::play_time_str()
- {
- int totalMin = total_play_time / (60*1000);
- int playHour = totalMin / 60;
- int playMin = totalMin - playHour*60;
- static String str;
- str = "";
- if( playHour > 0 )
- {
- str += playHour;
- str += translate.process( playHour>1 ? (char*)" hours" : (char*)" hour" );
- str += translate.process( " and " );
- }
- str += playMin;
- str += translate.process( playMin>1 ? (char*)" minutes" : (char*)" minute" );
- return str;
- }
- //---------- End of function Info::play_time_str ---------//
- //------- Begin of function Info::game_duration_str --------//
- //
- char* Info::game_duration_str()
- {
- //------- get the true game start date --------//
- int gameStartDate;
- //-- For scenarios (whose goal_difficulty are > 0 ), the actual game start date is no info.game_start_date, we must calculate it
- if( info.goal_difficulty )
- {
- gameStartDate = date.julian( date.year(info.goal_deadline)-config.goal_year_limit,
- date.month(info.goal_deadline),
- date.day(info.goal_deadline) );
- }
- else
- {
- gameStartDate = info.game_start_date;
- }
- //---------------------------------------------//
- int totalDay = info.game_date - gameStartDate;
- int playYear = totalDay / 365;
- int playDay = totalDay - playYear*365;
- static String str;
- str = "";
- if( playYear > 0 )
- {
- str += playYear;
- str += translate.process( playYear>1 ? (char*)" years" : (char*)" year" );
- str += translate.process( (char*)" and " );
- }
- str += playDay;
- str += translate.process( playDay>1 ? (char*)" days" : (char*)" day" );
- return str;
- }
- //---------- End of function Info::game_duration_str ---------//
- //------- Begin of function Info::save_game_scr --------//
- //
- void Info::save_game_scr()
- {
- err_when( save_buf_1 );
- // top and buttom
- if( 0 < ZOOM_Y1 )
- {
- save_buf_1 = vga_front.save_area(0, 0, VGA_WIDTH-1, ZOOM_Y1-1);
- save_buf_1b = vga_back.save_area(0, 0, VGA_WIDTH-1, ZOOM_Y1-1); // save the back buffer also as the top area of the back buf is used for font display
- }
- if( ZOOM_Y2 < VGA_HEIGHT-1 )
- save_buf_2 = vga_front.save_area(0, ZOOM_Y2+1, VGA_WIDTH-1, VGA_HEIGHT-1);
- // left and right
- if( 0 < ZOOM_X1 )
- save_buf_3 = vga_front.save_area(0, ZOOM_Y1, ZOOM_X1-1, ZOOM_Y2);
- if( ZOOM_X2 < VGA_WIDTH-1 )
- save_buf_4 = vga_front.save_area(ZOOM_X2+1, ZOOM_Y1, VGA_WIDTH-1, ZOOM_Y2);
- }
- //---------- End of function Info::save_game_scr ---------//
- //------- Begin of function Info::rest_game_scr --------//
- //
- void Info::rest_game_scr()
- {
- // restore area outside front buffer
- if(save_buf_4)
- vga_front.rest_area(save_buf_4, 1);
- if(save_buf_3)
- vga_front.rest_area(save_buf_3, 1);
- if(save_buf_2)
- vga_front.rest_area(save_buf_2, 1);
- if(save_buf_1)
- vga_front.rest_area(save_buf_1, 1);
- if(save_buf_1b)
- vga_back.rest_area(save_buf_1b, 1);
- save_buf_1 = NULL;
- info.disp();
- sys.blt_virtual_buf(); // blt the virtual front buffer to the screen
- }
- //---------- End of function Info::rest_game_scr ---------//
- //------- Begin of function Info::free_game_scr --------//
- //
- void Info::free_game_scr()
- {
- if(save_buf_4)
- mem_del(save_buf_4);
- if(save_buf_3)
- mem_del(save_buf_3);
- if(save_buf_2)
- mem_del(save_buf_2);
- if(save_buf_1)
- mem_del(save_buf_1);
- if(save_buf_1b)
- mem_del(save_buf_1b);
- save_buf_1 = NULL;
- }
- //---------- End of function Info::free_game_scr ---------//
- //------- Begin of function Info::disp_loyalty --------//
- //
- // return: <int> x2 - the ending x position of the loyalty string.
- //
- int Info::disp_loyalty(int x, int y, int x2, int curLoyalty, int targetLoyalty, int nationRecno, int refreshFlag)
- {
- int endX;
- if( x != x2 ) // if x==x2, don't display the field name.
- {
- font_san.field( x, y, "Loyalty", x2, curLoyalty, 1, INFO_X2-2, refreshFlag);
- endX = x2 + 4 + font_san.text_width( m.format(curLoyalty) );
- }
- else
- {
- endX = font_san.put( x2+4, y+2, curLoyalty, 1 );
- }
- if( nation_array[nationRecno]->cash <= 0 ) // if the nation no longer has money to pay the unit
- targetLoyalty = 0;
- if( curLoyalty != targetLoyalty ) // only increase, no decrease. Decrease are caused by events. Increases are made gradually
- {
- int tx = x2+6+font_san.text_width( m.format(curLoyalty) );
- if( targetLoyalty > curLoyalty )
- image_icon.put_front( tx, y+2, "ARROWUP" );
- else if( targetLoyalty < curLoyalty )
- image_icon.put_front( tx, y+2, "ARROWDWN" );
- endX = font_san.put( tx+10, y+2, targetLoyalty, 1 );
- }
- return endX;
- }
- //---------- End of function Info::disp_loyalty ---------//
|