/*
* 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 ------//