ONEWS.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. /*
  2. * Seven Kingdoms: Ancient Adversaries
  3. *
  4. * Copyright 1997,1998 Enlight Software Ltd.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. //Filename : ONEWS.CPP
  21. //Description : Object News
  22. #include <OVGA.h>
  23. #include <OINFO.h>
  24. #include <OHELP.h>
  25. #include <OGAME.h>
  26. #include <OCONFIG.h>
  27. #include <OSYS.h>
  28. #include <OMOUSE.h>
  29. #include <OFONT.h>
  30. #include <ODATE.h>
  31. #include <OIMGRES.h>
  32. #include <ONATION.h>
  33. #include <OTALKRES.h>
  34. #include <ONEWS.h>
  35. //------- define screen coordinations -------//
  36. enum { NEWS_HEIGHT = 20,
  37. NEWS_X1 = ZOOM_X1+8,
  38. NEWS_X2 = ZOOM_X2-16,
  39. NEWS_Y2 = ZOOM_Y2-5,
  40. };
  41. //--------- define static vars --------------//
  42. static Font* news_font_ptr = &font_news;
  43. //------ Begin of function NewsArray::NewsArray -----//
  44. NewsArray::NewsArray() : DynArray(sizeof(News), 100)
  45. {
  46. }
  47. //-------- End of function NewsArray::NewsArray -----//
  48. //------ Begin of function NewsArray::init -----//
  49. //
  50. void NewsArray::init()
  51. {
  52. reset();
  53. set_font(&font_san); // use black font
  54. }
  55. //------- End of function NewsArray::init -----//
  56. //------ Begin of function NewsArray::deinit -----//
  57. //
  58. void NewsArray::deinit()
  59. {
  60. reset();
  61. }
  62. //------- End of function NewsArray::deinit -----//
  63. //------ Begin of function NewsArray::reset -----//
  64. //
  65. // Reset all news display options and clear all news in the log
  66. //
  67. void NewsArray::reset()
  68. {
  69. zap(); // clear all news in the log
  70. last_clear_recno = 0;
  71. news_add_flag = 1;
  72. default_setting();
  73. }
  74. //------- End of function NewsArray::reset -----//
  75. //------ Begin of function NewsArray::default_setting -----//
  76. //
  77. // Reset all news display options
  78. //
  79. void NewsArray::default_setting()
  80. {
  81. news_type_option[NEWS_NORMAL]=1;
  82. news_who_option = NEWS_DISP_PLAYER; // default display news of groups controlled by the player
  83. }
  84. //------- End of function NewsArray::default_setting -----//
  85. //------ Begin of function NewsArray::set_font -----//
  86. //
  87. void NewsArray::set_font(Font* fontPtr)
  88. {
  89. news_font_ptr = fontPtr;
  90. }
  91. //------- End of function NewsArray::set_font -----//
  92. //------ Begin of function NewsArray::disp -----//
  93. //
  94. void NewsArray::disp()
  95. {
  96. //-- only display news in normal view and diplomatic/chat option screen ---//
  97. int rc=0;
  98. switch( sys.view_mode )
  99. {
  100. case MODE_NORMAL:
  101. rc = 1;
  102. break;
  103. case MODE_NATION:
  104. rc = info.nation_report_mode==NATION_REPORT_TALK ||
  105. info.nation_report_mode==NATION_REPORT_CHAT;
  106. break;
  107. }
  108. if( rc )
  109. {
  110. put(0); // 0-not a detect action
  111. }
  112. }
  113. //------- End of function NewsArray::disp -----//
  114. //------ Begin of function NewsArray::detect -----//
  115. //
  116. int NewsArray::detect()
  117. {
  118. //-- only display news in normal view and diplomatic option screen ---//
  119. if( sys.view_mode == MODE_NORMAL ||
  120. (sys.view_mode == MODE_NATION &&
  121. (info.nation_report_mode==NATION_REPORT_TALK ||
  122. info.nation_report_mode==NATION_REPORT_CHAT) ) )
  123. {
  124. return put(1); // 1-is a detect action
  125. }
  126. return 0;
  127. }
  128. //------- End of function NewsArray::detect -----//
  129. //------ Begin of function NewsArray::put -----//
  130. //
  131. // Display or detect news messages.
  132. //
  133. // <int> detectAction - 1 if this is a detect action.
  134. //
  135. int NewsArray::put(int detectAction)
  136. {
  137. int i, y;
  138. News* newsPtr;
  139. vga.use_back();
  140. //--- count the no. of recent news which should be displayed ---//
  141. int dispCount=0;
  142. for( i=size() ; i>=max(1,last_clear_recno+1) ; i-- )
  143. {
  144. newsPtr = (News*) get(i);
  145. //----- if display major news only ------//
  146. if( config.disp_news_flag == OPTION_DISPLAY_MAJOR_NEWS ||
  147. game.game_mode == GAME_TUTORIAL ) // only display major news in the tutorial
  148. {
  149. if( !newsPtr->is_major() )
  150. continue;
  151. }
  152. //---------------------------------------//
  153. if( info.game_date < newsPtr->news_date + DISP_NEWS_DAYS )
  154. {
  155. if( ++dispCount >= DISP_NEWS_COUNT )
  156. break;
  157. }
  158. else
  159. break;
  160. }
  161. //----- display news messages from the bottom up ------//
  162. y = NEWS_Y2 - NEWS_HEIGHT;
  163. int newsRecno, newsHeight;
  164. for( i=dispCount ; i>0 ; i-- )
  165. {
  166. newsRecno = size()-i+1;
  167. newsPtr = (News*) get(newsRecno);
  168. //----- if display major news only ------//
  169. if( config.disp_news_flag == OPTION_DISPLAY_MAJOR_NEWS ||
  170. game.game_mode == GAME_TUTORIAL ) // only display major news in the tutorial
  171. {
  172. if( !newsPtr->is_major() )
  173. continue;
  174. }
  175. //---- if it's a diplomatic message, check if it's still valid ----//
  176. if( newsPtr->id == NEWS_DIPLOMACY )
  177. {
  178. 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
  179. TalkMsg* talkMsgPtr = talk_res.get_talk_msg(newsPtr->short_para1);
  180. //--- if it is no longer valid, delete it ---//
  181. if( talkMsgPtr->reply_type==REPLY_WAITING && !talkMsgPtr->is_valid_to_reply() )
  182. {
  183. news_array.linkout(newsRecno);
  184. continue;
  185. }
  186. }
  187. //----- display the new message now -----//
  188. if( newsPtr->put( y, detectAction, newsHeight ) ) // return 1 if reply diplomatic message
  189. return 1;
  190. y -= newsHeight;
  191. }
  192. //------- display buttons -------//
  193. if( !detectAction )
  194. {
  195. image_icon.put_back(NEWS_X2+3, NEWS_Y2-12, "NEWS_LOG"); // news log report
  196. if( dispCount > 0 ) // clear news button
  197. image_icon.put_back(NEWS_X2+3, NEWS_Y2-26, "NEWS_CLR");
  198. }
  199. //------- detect buttons -------//
  200. else
  201. {
  202. //--- detect news log report ---//
  203. help.set_help( NEWS_X2+3, NEWS_Y2-12, NEWS_X2+12, NEWS_Y2-3, "NEWSLOG" );
  204. if( mouse.single_click( NEWS_X2+3, NEWS_Y2-12, NEWS_X2+12, NEWS_Y2-3 ) )
  205. sys.set_view_mode(MODE_NEWS_LOG);
  206. if( dispCount > 0 ) // clear news button
  207. {
  208. help.set_help( NEWS_X2+3, NEWS_Y2-26, NEWS_X2+12, NEWS_Y2-17, "CLRNEWS" );
  209. if( mouse.single_click( NEWS_X2+3, NEWS_Y2-26, NEWS_X2+12, NEWS_Y2-17 ) )
  210. clear_news_disp();
  211. }
  212. }
  213. //-------------------------------//
  214. vga.use_front();
  215. return 0;
  216. }
  217. //------- End of function NewsArray::put -----//
  218. //------ Begin of function NewsArray::clear_news_disp -----//
  219. //
  220. // Clear all news on the screen.
  221. //
  222. void NewsArray::clear_news_disp()
  223. {
  224. last_clear_recno = size();
  225. }
  226. //------- End of function NewsArray::clear_news_disp -----//
  227. //------ Begin of function News::put -----//
  228. //
  229. // <int> y - the y display location of the news message
  230. // <int> detectAction - whether it's a detect action
  231. // <int&> newsHeight - for returning the height of the news message displayed
  232. //
  233. // return: <int> 1 - if detect pressing on the news
  234. // 0 - not detected or it's a display action
  235. //
  236. int News::put(int y, int detectAction, int& newsHeight)
  237. {
  238. //------- get the height of the message -------//
  239. #define NEWS_LINE_SPACE 2
  240. #define NEWS_SECOND_LINE_HEIGHT 16
  241. #define NEWS_ICON_WIDTH 17
  242. String msgStr(msg());
  243. char* dateStr = date.date_str(news_date,1);
  244. int dateWidth = news_font_ptr->text_width(dateStr) + 5; // 5 is the space between the date and the text
  245. newsHeight = NEWS_HEIGHT;
  246. if( NEWS_ICON_WIDTH + dateWidth + news_font_ptr->text_width(msgStr) > NEWS_X2-NEWS_X1+1 )
  247. {
  248. y -= NEWS_SECOND_LINE_HEIGHT; // two line messages.
  249. newsHeight += NEWS_SECOND_LINE_HEIGHT;
  250. }
  251. //---- brighten the area for display in non-standard terrain set ---//
  252. vga.active_buf->adjust_brightness(ZOOM_X1, y-3, NEWS_X2+1, y+newsHeight-4, 6);
  253. //------ if it's a detect action --------//
  254. if( detectAction )
  255. {
  256. help.set_help( NEWS_X1, y, NEWS_X1+10, y+10, "REPLYDIP" );
  257. if( mouse.single_click( NEWS_X1, y, NEWS_X1+10, y+10 ) )
  258. {
  259. if( id == NEWS_DIPLOMACY )
  260. {
  261. 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
  262. TalkMsg* talkMsgPtr = talk_res.get_talk_msg(short_para1);
  263. if( talkMsgPtr->reply_type == REPLY_WAITING ) // currently waiting a reply from the player
  264. {
  265. vga.use_front();
  266. talk_res.player_reply(short_para1);
  267. return 1;
  268. }
  269. }
  270. else if( id == NEWS_CHAT_MSG )
  271. {
  272. int fromNationRecno = info.remote_chat_array[short_para1-1].from_nation_recno;
  273. if( !nation_array.is_deleted(fromNationRecno) )
  274. {
  275. vga.use_front();
  276. info.player_reply_chat(fromNationRecno);
  277. return 1;
  278. }
  279. }
  280. else if( is_loc_valid() )
  281. {
  282. vga.use_front();
  283. world.go_loc( loc_x, loc_y, 1 ); // 1-select object on the location if there is any
  284. return 1;
  285. }
  286. }
  287. return 0;
  288. }
  289. //---- display the color of the sender nation ----//
  290. if( id==NEWS_DIPLOMACY )
  291. {
  292. 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
  293. TalkMsg* talkMsgPtr = talk_res.get_talk_msg(short_para1);
  294. int nationRecno;
  295. if( talkMsgPtr->reply_type == REPLY_WAITING ||
  296. talkMsgPtr->reply_type == REPLY_NOT_NEEDED )
  297. {
  298. nationRecno = talkMsgPtr->from_nation_recno;
  299. }
  300. else
  301. nationRecno = talkMsgPtr->to_nation_recno;
  302. nation_array[nationRecno]->disp_nation_color(NEWS_X1, y+2);
  303. }
  304. else
  305. {
  306. if( is_loc_valid() )
  307. image_icon.put_back( NEWS_X1, y+2, "NEWS_GO" );
  308. if( id==NEWS_CHAT_MSG )
  309. {
  310. char colorCode = game.color_remap_array[nation_color1].main_color;
  311. nation_array.disp_nation_color(NEWS_X1, y+2, colorCode );
  312. }
  313. }
  314. //------- display the message content -------//
  315. news_font_ptr->put( NEWS_X1+NEWS_ICON_WIDTH, y, dateStr );
  316. news_font_ptr->put_paragraph( NEWS_X1+NEWS_ICON_WIDTH+dateWidth, y, NEWS_X2,
  317. y+newsHeight, msgStr, NEWS_LINE_SPACE );
  318. return 0;
  319. }
  320. //------- End of function News::put -----//
  321. //------ Begin of function NewsArray::remove -----//
  322. //
  323. // Remove a specific news from the news_array.
  324. //
  325. // <int> newsId = id. of the news
  326. // <int> shortPara1 = short_para1 of the news
  327. //
  328. void NewsArray::remove(int newsId, int shortPara1)
  329. {
  330. News* newsPtr;
  331. for( int i=size() ; i>0 ; i-- )
  332. {
  333. newsPtr = news_array[i];
  334. if( newsPtr->id == newsId &&
  335. newsPtr->short_para1 == shortPara1 )
  336. {
  337. news_array.linkout(i);
  338. //### begin alex 31/3 ###//
  339. //if( i<last_clear_recno && last_clear_recno > 1 )
  340. if( i<=last_clear_recno && last_clear_recno > 0 )
  341. last_clear_recno--;
  342. //#### end alex 31/3 ####//
  343. break;
  344. }
  345. }
  346. }
  347. //------- End of function NewsArray::remove -----//
  348. //------- Begin of function NewsArray::operator[] -----//
  349. News* NewsArray::operator[](int recNo)
  350. {
  351. #ifdef DEBUG
  352. News* msgPtr;
  353. if( recNo )
  354. msgPtr = (News*) get(recNo);
  355. else
  356. msgPtr = NULL; // NULL will then cause error
  357. err_if( !msgPtr || msgPtr->news_date==0 )
  358. err_now( "NewsArray[] is deleted" );
  359. return msgPtr;
  360. #else
  361. return (News*) get(recNo);
  362. #endif
  363. }
  364. //--------- End of function NewsArray::operator[] ----//