/* * 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 : OTALKMSG.CPP //Description : Object TalkMsg #include #include #include #include #include #include #include #include #include #include //------ Define function pointers array ------// static char talk_msg_reply_needed_array[] = { 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, }; //------- Begin of function TalkMsg::TalkMsg --------// // TalkMsg::TalkMsg() { memset( this, 0, sizeof(TalkMsg) ); } //-------- End of function TalkMsg::TalkMsg ---------// //------- Begin of function TalkMsg::process_accepted_reply --------// // void TalkMsg::process_accepted_reply() { Nation* toNation = nation_array[to_nation_recno]; Nation* fromNation = nation_array[from_nation_recno]; NationRelation* fromRelation = fromNation->get_relation(to_nation_recno); NationRelation* toRelation = toNation->get_relation(from_nation_recno); int goodRelationDec=0; // whether the message is for requesting help. switch(talk_id) { case TALK_PROPOSE_TRADE_TREATY: toNation->set_trade_treaty(from_nation_recno, 1); break; case TALK_PROPOSE_FRIENDLY_TREATY: toNation->form_friendly_treaty(from_nation_recno); break; case TALK_PROPOSE_ALLIANCE_TREATY: toNation->form_alliance_treaty(from_nation_recno); break; case TALK_END_TRADE_TREATY: toNation->set_trade_treaty(from_nation_recno, 0); //---- set reject date on proposing treaty ----// fromRelation->last_talk_reject_date_array[TALK_PROPOSE_TRADE_TREATY-1] = info.game_date; toRelation->last_talk_reject_date_array[TALK_PROPOSE_TRADE_TREATY-1] = info.game_date; fromRelation->last_talk_reject_date_array[TALK_END_TRADE_TREATY-1] = info.game_date; toRelation->last_talk_reject_date_array[TALK_END_TRADE_TREATY-1] = info.game_date; //----- decrease reputation -----// if( toNation->reputation > 0 ) fromNation->change_reputation( -toNation->reputation * 5 / 100 ); break; case TALK_END_FRIENDLY_TREATY: case TALK_END_ALLIANCE_TREATY: fromNation->end_treaty(to_nation_recno, NATION_NEUTRAL); //---- set reject date on proposing treaty ----// // // If a friendly treaty is rejected, assuming an alliance treaty // is even more impossible. (thus set reject date on both friendly // and alliance treaties.) // // If a alliance treaty is rejected, only set reject date on // alliance treaty, it may still try proposing friendly treaty later. // //---------------------------------------------// fromRelation->last_talk_reject_date_array[TALK_PROPOSE_FRIENDLY_TREATY-1] = info.game_date; toRelation->last_talk_reject_date_array[TALK_PROPOSE_FRIENDLY_TREATY-1] = info.game_date; fromRelation->last_talk_reject_date_array[TALK_PROPOSE_ALLIANCE_TREATY-1] = info.game_date; toRelation->last_talk_reject_date_array[TALK_PROPOSE_ALLIANCE_TREATY-1] = info.game_date; break; case TALK_REQUEST_MILITARY_AID: goodRelationDec = 10; break; case TALK_REQUEST_TRADE_EMBARGO: { //--- send an end treaty message to the target kingdom ---// TalkMsg talkMsg; memset(&talkMsg, 0, sizeof(TalkMsg)); talkMsg.to_nation_recno = (char) talk_para1; talkMsg.from_nation_recno = to_nation_recno; talkMsg.talk_id = TALK_END_TRADE_TREATY; talk_res.send_talk_msg( &talkMsg, COMMAND_AUTO ); goodRelationDec = 4; } break; case TALK_REQUEST_CEASE_WAR: unit_array.stop_war_between(to_nation_recno, from_nation_recno); toNation->set_relation_status(from_nation_recno, NATION_TENSE); fromRelation->last_talk_reject_date_array[TALK_DECLARE_WAR-1] = info.game_date; toRelation->last_talk_reject_date_array[TALK_DECLARE_WAR-1] = info.game_date; break; case TALK_REQUEST_DECLARE_WAR: #ifdef AMPLUS if( fromNation->get_relation_status(talk_para1) == NATION_HOSTILE ) // the requesting nation must be at war with the enemy { #else { err_when( fromNation->get_relation_status(talk_para1) != NATION_HOSTILE ); // the requesting nation must be at war with the enemy #endif //-- if we are currently allied or friendly with the nation, we need to terminate the friendly/alliance treaty first --// TalkMsg talkMsg; if( toNation->get_relation_status(talk_para1) == NATION_ALLIANCE ) { memset(&talkMsg, 0, sizeof(TalkMsg)); talkMsg.to_nation_recno = (char) talk_para1; talkMsg.from_nation_recno = to_nation_recno; talkMsg.talk_id = TALK_END_ALLIANCE_TREATY; talk_res.send_talk_msg( &talkMsg, COMMAND_AUTO ); } else if( toNation->get_relation_status(talk_para1) == NATION_FRIENDLY ) { memset(&talkMsg, 0, sizeof(TalkMsg)); talkMsg.to_nation_recno = (char) talk_para1; talkMsg.from_nation_recno = to_nation_recno; talkMsg.talk_id = TALK_END_FRIENDLY_TREATY; talk_res.send_talk_msg( &talkMsg, COMMAND_AUTO ); } //--- send a declare war message to the target kingdom ---// memset(&talkMsg, 0, sizeof(TalkMsg)); talkMsg.to_nation_recno = (char) talk_para1; talkMsg.from_nation_recno = to_nation_recno; talkMsg.talk_id = TALK_DECLARE_WAR; talk_res.send_talk_msg( &talkMsg, COMMAND_AUTO ); //----------------------------------------------------// goodRelationDec = 10; } break; case TALK_REQUEST_BUY_FOOD: { int buyCost = talk_para1 * talk_para2 / 10; fromNation->add_food( (float) talk_para1 ); fromNation->add_expense( EXPENSE_IMPORTS, (float) buyCost, 0 ); toNation->consume_food( (float) talk_para1 ); toNation->add_income( INCOME_EXPORTS, (float) buyCost, 0 ); break; } case TALK_DECLARE_WAR: toRelation->started_war_on_us_count++; // how many times this nation has started a war with us, the more the times the worse this nation is. toNation->set_relation_status(from_nation_recno, NATION_HOSTILE); fromRelation->last_talk_reject_date_array[TALK_REQUEST_CEASE_WAR-1] = info.game_date; toRelation->last_talk_reject_date_array[TALK_REQUEST_CEASE_WAR-1] = info.game_date; //--- decrease reputation of the nation which declares war ---// if( toNation->reputation > 0 ) fromNation->change_reputation( -toNation->reputation * 20 / 100 ); break; case TALK_GIVE_TRIBUTE: case TALK_GIVE_AID: fromNation->give_tribute( to_nation_recno, talk_para1 ); break; case TALK_DEMAND_TRIBUTE: case TALK_DEMAND_AID: toNation->give_tribute( from_nation_recno, talk_para1 ); goodRelationDec = talk_para1/200; break; case TALK_GIVE_TECH: fromNation->give_tech( to_nation_recno, talk_para1, talk_para2 ); break; case TALK_DEMAND_TECH: talk_para2 = tech_res[talk_para1]->get_nation_tech_level(to_nation_recno); // get the latest tech version id. of the agreed nation. toNation->give_tech( from_nation_recno, talk_para1, talk_para2 ); goodRelationDec = talk_para2*3; break; case TALK_REQUEST_SURRENDER: { float offeredAmt = (float) talk_para1 * 10; // * 10 is to restore its original value. It has been divided by 10 to cope with the upper limit of toNation->add_income(INCOME_TRIBUTE, offeredAmt); fromNation->add_expense(EXPENSE_TRIBUTE, offeredAmt); toNation->surrender(from_nation_recno); break; } case TALK_SURRENDER: fromNation->surrender(to_nation_recno); break; default: err_here(); } //---- if the nation accepts a message that is requesting help, then decrease its good_relation_duration_rating, so it won't accept so easily next time ---// if( goodRelationDec ) toRelation->good_relation_duration_rating -= (float) goodRelationDec; //-- remove talk messges that are the same but sent from the opposite nation --// TalkMsg talkMsg; talkMsg.from_nation_recno = to_nation_recno; talkMsg.to_nation_recno = from_nation_recno; talkMsg.talk_id = talk_id; int loopCount=0; while(1) { err_when( loopCount++ > 100 ); int talkMsgRecno = talk_res.is_talk_msg_exist(&talkMsg, 0); // don't check talk_para1 & talk_para2 if( talkMsgRecno ) talk_res.del_talk_msg(talkMsgRecno); else break; } } //-------- End of function TalkMsg::process_accepted_reply ---------// //----- Begin of function TalkMsg::is_reply_needed ------// // // Whether a reply is needed for this message. // int TalkMsg::is_reply_needed() { return talk_msg_reply_needed_array[talk_id-1]; } //------- End of function TalkMsg::is_reply_needed ------// //----- Begin of function TalkMsg::is_valid_to_reply ------// // // Return whether this message is still valid. Only // if this message is valid, the receiver can answer // this message. // int TalkMsg::is_valid_to_reply() { //-----------------------------------------------------// // When a diplomatic message is sent, the receiver must // reply the message with a month. //-----------------------------------------------------// #define TALK_MSG_VALID_DAYS 30 if( info.game_date > date + TALK_MSG_VALID_DAYS ) return 0; //--- check if the nations are still there -----// if( nation_array.is_deleted(from_nation_recno) ) return 0; if( nation_array.is_deleted(to_nation_recno) ) return 0; //--------------------------------------// if( !talk_res.can_send_msg(to_nation_recno, from_nation_recno, talk_id) ) return 0; //--------------------------------------// Nation* toNation = nation_array[to_nation_recno]; Nation* fromNation = nation_array[from_nation_recno]; switch( talk_id ) { case TALK_REQUEST_TRADE_EMBARGO: if( nation_array.is_deleted(talk_para1) ) return 0; //-- if the requesting nation is itself trading with the target nation --// if( fromNation->get_relation(talk_para1)->trade_treaty ) return 0; //-- or if the requested nation already doesn't have a trade treaty with the nation --// if( !toNation->get_relation(talk_para1)->trade_treaty ) return 0; break; case TALK_REQUEST_DECLARE_WAR: if( nation_array.is_deleted(talk_para1) ) return 0; //-- if the requesting nation is no longer hostile with the nation --// if( fromNation->get_relation_status(talk_para1) != NATION_HOSTILE ) return 0; //-- or if the requested nation has become hostile with the nation --// if( toNation->get_relation_status(talk_para1) == NATION_HOSTILE ) return 0; break; case TALK_REQUEST_BUY_FOOD: return fromNation->cash >= talk_para1 * talk_para2 / 10; case TALK_GIVE_TRIBUTE: case TALK_GIVE_AID: return fromNation->cash >= talk_para1; case TALK_GIVE_TECH: /* // still display the message even if the nation already has the technology //---- if the nation has acquired the technology itself ----// if( tech_res[talk_para1]->get_nation_tech_level(to_nation_recno) >= talk_para2 ) return 0; */ break; case TALK_DEMAND_TECH: /* //---- if the requesting nation has acquired the technology itself ----// if( tech_res[talk_para1]->get_nation_tech_level(from_nation_recno) >= talk_para2 ) return 0; */ break; } return 1; } //------- End of function TalkMsg::is_valid_to_reply ------// //----- Begin of function TalkMsg::is_valid_to_disp ------// // // Return whether this message is still valid. Only // if this message is valid, the receiver can answer // this message. // int TalkMsg::is_valid_to_disp() { //--- check if the nations are still there -----// if( nation_array.is_deleted(from_nation_recno) ) return 0; if( nation_array.is_deleted(to_nation_recno) ) return 0; //--------------------------------------// Nation* toNation = nation_array[to_nation_recno]; Nation* fromNation = nation_array[from_nation_recno]; switch( talk_id ) { case TALK_REQUEST_TRADE_EMBARGO: if( nation_array.is_deleted(talk_para1) ) return 0; break; case TALK_REQUEST_DECLARE_WAR: if( nation_array.is_deleted(talk_para1) ) return 0; break; } return 1; } //------- End of function TalkMsg::is_valid_to_disp ------// //----- Begin of function TalkMsg::can_accept ------// // // Return whether the receiver can accept this message // if he wants to. // int TalkMsg::can_accept() { Nation* toNation = nation_array[to_nation_recno]; switch( talk_id ) { case TALK_REQUEST_BUY_FOOD: return toNation->food >= talk_para1; case TALK_DEMAND_TRIBUTE: case TALK_DEMAND_AID: return toNation->cash >= talk_para1; case TALK_DEMAND_TECH: // the requested nation has the technology return tech_res[talk_para1]->get_nation_tech_level(to_nation_recno) > 0; } return 1; } //------- End of function TalkMsg::can_accept ------// //----- Begin of function TalkMsg::from_nation_name ------// // char* TalkMsg::from_nation_name() { static String str; str = nation_array[from_nation_recno]->nation_name(); //------ add nation color bar -------// if( talk_res.msg_add_nation_color ) { char colorCodeStr[] = " 0"; colorCodeStr[1] = FIRST_NATION_COLOR_CODE_IN_TEXT + nation_array[from_nation_recno]->color_scheme_id; str += colorCodeStr; } return str; } //------- End of function TalkMsg::from_nation_name ------// //----- Begin of function TalkMsg::to_nation_name ------// // char* TalkMsg::to_nation_name() { static String str; str = nation_array[to_nation_recno]->nation_name(); //------ add nation color bar -------// if( talk_res.msg_add_nation_color ) { char colorCodeStr[] = " 0"; colorCodeStr[1] = FIRST_NATION_COLOR_CODE_IN_TEXT + nation_array[to_nation_recno]->color_scheme_id; str += colorCodeStr; } return str; } //------- End of function TalkMsg::to_nation_name ------// //----- Begin of function TalkMsg::from_king_name ------// // char* TalkMsg::from_king_name() { static String str; str = translate.process("King "); str += nation_array[from_nation_recno]->king_name(); //------ add nation color bar -------// if( talk_res.msg_add_nation_color ) { char colorCodeStr[] = " 0"; colorCodeStr[1] = FIRST_NATION_COLOR_CODE_IN_TEXT + nation_array[from_nation_recno]->color_scheme_id; str += colorCodeStr; } return str; } //------- End of function TalkMsg::from_king_name ------// //----- Begin of function TalkMsg::to_king_name ------// // char* TalkMsg::to_king_name() { static String str; str = translate.process("King "); str += nation_array[to_nation_recno]->king_name(); //------ add nation color bar -------// if( talk_res.msg_add_nation_color ) { char colorCodeStr[] = " 0"; colorCodeStr[1] = FIRST_NATION_COLOR_CODE_IN_TEXT + nation_array[to_nation_recno]->color_scheme_id; str += colorCodeStr; } return str; } //------- End of function TalkMsg::to_king_name ------// //----- Begin of function TalkMsg::nation_color_code_str ------// // char* TalkMsg::nation_color_code_str(int nationRecno) { static char colorCodeStr[] = " 0"; colorCodeStr[1] = FIRST_NATION_COLOR_CODE_IN_TEXT + nation_array[nationRecno]->color_scheme_id; return colorCodeStr; } //------- End of function TalkMsg::nation_color_code_str ------//