/* * 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 : ONEWS.CPP //Description : Object News #include #include #include #include #include #include #include #include #include #include #include #include #include //------- define screen coordinations -------// enum { NEWS_HEIGHT = 20, NEWS_X1 = ZOOM_X1+8, NEWS_X2 = ZOOM_X2-16, NEWS_Y2 = ZOOM_Y2-5, }; //--------- define static vars --------------// static Font* news_font_ptr = &font_news; //------ Begin of function NewsArray::NewsArray -----// NewsArray::NewsArray() : DynArray(sizeof(News), 100) { } //-------- End of function NewsArray::NewsArray -----// //------ Begin of function NewsArray::init -----// // void NewsArray::init() { reset(); set_font(&font_san); // use black font } //------- End of function NewsArray::init -----// //------ Begin of function NewsArray::deinit -----// // void NewsArray::deinit() { reset(); } //------- End of function NewsArray::deinit -----// //------ Begin of function NewsArray::reset -----// // // Reset all news display options and clear all news in the log // void NewsArray::reset() { zap(); // clear all news in the log last_clear_recno = 0; news_add_flag = 1; default_setting(); } //------- End of function NewsArray::reset -----// //------ Begin of function NewsArray::default_setting -----// // // Reset all news display options // void NewsArray::default_setting() { news_type_option[NEWS_NORMAL]=1; news_who_option = NEWS_DISP_PLAYER; // default display news of groups controlled by the player } //------- End of function NewsArray::default_setting -----// //------ Begin of function NewsArray::set_font -----// // void NewsArray::set_font(Font* fontPtr) { news_font_ptr = fontPtr; } //------- End of function NewsArray::set_font -----// //------ Begin of function NewsArray::disp -----// // void NewsArray::disp() { //-- only display news in normal view and diplomatic/chat option screen ---// int rc=0; switch( sys.view_mode ) { case MODE_NORMAL: rc = 1; break; case MODE_NATION: rc = info.nation_report_mode==NATION_REPORT_TALK || info.nation_report_mode==NATION_REPORT_CHAT; break; } if( rc ) { put(0); // 0-not a detect action } } //------- End of function NewsArray::disp -----// //------ Begin of function NewsArray::detect -----// // int NewsArray::detect() { //-- only display news in normal view and diplomatic option screen ---// if( sys.view_mode == MODE_NORMAL || (sys.view_mode == MODE_NATION && (info.nation_report_mode==NATION_REPORT_TALK || info.nation_report_mode==NATION_REPORT_CHAT) ) ) { return put(1); // 1-is a detect action } return 0; } //------- End of function NewsArray::detect -----// //------ Begin of function NewsArray::put -----// // // Display or detect news messages. // // detectAction - 1 if this is a detect action. // int NewsArray::put(int detectAction) { int i, y; News* newsPtr; vga.use_back(); //--- count the no. of recent news which should be displayed ---// int dispCount=0; for( i=size() ; i>=max(1,last_clear_recno+1) ; i-- ) { newsPtr = (News*) get(i); //----- if display major news only ------// if( config.disp_news_flag == OPTION_DISPLAY_MAJOR_NEWS || game.game_mode == GAME_TUTORIAL ) // only display major news in the tutorial { if( !newsPtr->is_major() ) continue; } //---------------------------------------// if( info.game_date < newsPtr->news_date + DISP_NEWS_DAYS ) { if( ++dispCount >= DISP_NEWS_COUNT ) break; } else break; } //----- display news messages from the bottom up ------// y = NEWS_Y2 - NEWS_HEIGHT; int newsRecno, newsHeight; for( i=dispCount ; i>0 ; i-- ) { newsRecno = size()-i+1; newsPtr = (News*) get(newsRecno); //----- if display major news only ------// if( config.disp_news_flag == OPTION_DISPLAY_MAJOR_NEWS || game.game_mode == GAME_TUTORIAL ) // only display major news in the tutorial { if( !newsPtr->is_major() ) continue; } //---- if it's a diplomatic message, check if it's still valid ----// if( newsPtr->id == NEWS_DIPLOMACY ) { err_when( talk_res.is_talk_msg_deleted(newsPtr->short_para1) ); // it shouldn't have been deleted as when it's deleted in TalkRes(), it will be removed from news_array immediately TalkMsg* talkMsgPtr = talk_res.get_talk_msg(newsPtr->short_para1); //--- if it is no longer valid, delete it ---// if( talkMsgPtr->reply_type==REPLY_WAITING && !talkMsgPtr->is_valid_to_reply() ) { news_array.linkout(newsRecno); continue; } } //----- display the new message now -----// if( newsPtr->put( y, detectAction, newsHeight ) ) // return 1 if reply diplomatic message return 1; y -= newsHeight; } //------- display buttons -------// if( !detectAction ) { image_icon.put_back(NEWS_X2+3, NEWS_Y2-12, "NEWS_LOG"); // news log report if( dispCount > 0 ) // clear news button image_icon.put_back(NEWS_X2+3, NEWS_Y2-26, "NEWS_CLR"); } //------- detect buttons -------// else { //--- detect news log report ---// help.set_help( NEWS_X2+3, NEWS_Y2-12, NEWS_X2+12, NEWS_Y2-3, "NEWSLOG" ); if( mouse.single_click( NEWS_X2+3, NEWS_Y2-12, NEWS_X2+12, NEWS_Y2-3 ) ) sys.set_view_mode(MODE_NEWS_LOG); if( dispCount > 0 ) // clear news button { help.set_help( NEWS_X2+3, NEWS_Y2-26, NEWS_X2+12, NEWS_Y2-17, "CLRNEWS" ); if( mouse.single_click( NEWS_X2+3, NEWS_Y2-26, NEWS_X2+12, NEWS_Y2-17 ) ) clear_news_disp(); } } //-------------------------------// vga.use_front(); return 0; } //------- End of function NewsArray::put -----// //------ Begin of function NewsArray::clear_news_disp -----// // // Clear all news on the screen. // void NewsArray::clear_news_disp() { last_clear_recno = size(); } //------- End of function NewsArray::clear_news_disp -----// //------ Begin of function News::put -----// // // y - the y display location of the news message // detectAction - whether it's a detect action // newsHeight - for returning the height of the news message displayed // // return: 1 - if detect pressing on the news // 0 - not detected or it's a display action // int News::put(int y, int detectAction, int& newsHeight) { //------- get the height of the message -------// #define NEWS_LINE_SPACE 2 #define NEWS_SECOND_LINE_HEIGHT 16 #define NEWS_ICON_WIDTH 17 String msgStr(msg()); char* dateStr = date.date_str(news_date,1); int dateWidth = news_font_ptr->text_width(dateStr) + 5; // 5 is the space between the date and the text newsHeight = NEWS_HEIGHT; if( NEWS_ICON_WIDTH + dateWidth + news_font_ptr->text_width(msgStr) > NEWS_X2-NEWS_X1+1 ) { y -= NEWS_SECOND_LINE_HEIGHT; // two line messages. newsHeight += NEWS_SECOND_LINE_HEIGHT; } //---- brighten the area for display in non-standard terrain set ---// vga.active_buf->adjust_brightness(ZOOM_X1, y-3, NEWS_X2+1, y+newsHeight-4, 6); //------ if it's a detect action --------// if( detectAction ) { help.set_help( NEWS_X1, y, NEWS_X1+10, y+10, "REPLYDIP" ); if( mouse.single_click( NEWS_X1, y, NEWS_X1+10, y+10 ) ) { if( id == NEWS_DIPLOMACY ) { err_when( talk_res.is_talk_msg_deleted(short_para1) ); // it shouldn't have been deleted as when it's deleted in TalkRes(), it will be removed from news_array immediately TalkMsg* talkMsgPtr = talk_res.get_talk_msg(short_para1); if( talkMsgPtr->reply_type == REPLY_WAITING ) // currently waiting a reply from the player { vga.use_front(); talk_res.player_reply(short_para1); return 1; } } else if( id == NEWS_CHAT_MSG ) { int fromNationRecno = info.remote_chat_array[short_para1-1].from_nation_recno; if( !nation_array.is_deleted(fromNationRecno) ) { vga.use_front(); info.player_reply_chat(fromNationRecno); return 1; } } else if( is_loc_valid() ) { vga.use_front(); world.go_loc( loc_x, loc_y, 1 ); // 1-select object on the location if there is any return 1; } } return 0; } //---- display the color of the sender nation ----// if( id==NEWS_DIPLOMACY ) { err_when( talk_res.is_talk_msg_deleted(short_para1) ); // it shouldn't have been deleted as when it's deleted in TalkRes(), it will be removed from news_array immediately TalkMsg* talkMsgPtr = talk_res.get_talk_msg(short_para1); int nationRecno; if( talkMsgPtr->reply_type == REPLY_WAITING || talkMsgPtr->reply_type == REPLY_NOT_NEEDED ) { nationRecno = talkMsgPtr->from_nation_recno; } else nationRecno = talkMsgPtr->to_nation_recno; nation_array[nationRecno]->disp_nation_color(NEWS_X1, y+2); } else { if( is_loc_valid() ) image_icon.put_back( NEWS_X1, y+2, "NEWS_GO" ); if( id==NEWS_CHAT_MSG ) { char colorCode = game.color_remap_array[nation_color1].main_color; nation_array.disp_nation_color(NEWS_X1, y+2, colorCode ); } } //------- display the message content -------// news_font_ptr->put( NEWS_X1+NEWS_ICON_WIDTH, y, dateStr ); news_font_ptr->put_paragraph( NEWS_X1+NEWS_ICON_WIDTH+dateWidth, y, NEWS_X2, y+newsHeight, msgStr, NEWS_LINE_SPACE ); return 0; } //------- End of function News::put -----// //------ Begin of function NewsArray::remove -----// // // Remove a specific news from the news_array. // // newsId = id. of the news // shortPara1 = short_para1 of the news // void NewsArray::remove(int newsId, int shortPara1) { News* newsPtr; for( int i=size() ; i>0 ; i-- ) { newsPtr = news_array[i]; if( newsPtr->id == newsId && newsPtr->short_para1 == shortPara1 ) { news_array.linkout(i); //### begin alex 31/3 ###// //if( i 1 ) if( i<=last_clear_recno && last_clear_recno > 0 ) last_clear_recno--; //#### end alex 31/3 ####// break; } } } //------- End of function NewsArray::remove -----// //------- Begin of function NewsArray::operator[] -----// News* NewsArray::operator[](int recNo) { #ifdef DEBUG News* msgPtr; if( recNo ) msgPtr = (News*) get(recNo); else msgPtr = NULL; // NULL will then cause error err_if( !msgPtr || msgPtr->news_date==0 ) err_now( "NewsArray[] is deleted" ); return msgPtr; #else return (News*) get(recNo); #endif } //--------- End of function NewsArray::operator[] ----//