diff client/climisc.c client/climisc.c --- client/climisc.c Fri Jul 28 04:16:31 2000 +++ client/climisc.c Sat Aug 26 00:51:00 2000 @@ -366,6 +366,8 @@ void client_diplomacy_clause_string(char *buf, int bufsiz, struct Clause *pclause) { + struct city *pcity; + switch(pclause->type) { case CLAUSE_ADVANCE: my_snprintf(buf, bufsiz, _("The %s give %s"), @@ -373,9 +375,20 @@ advances[pclause->value].name); break; case CLAUSE_CITY: - my_snprintf(buf, bufsiz, _("The %s give %s"), - get_nation_name_plural(pclause->from->nation), - find_city_by_id(pclause->value)->name); + pcity = find_city_by_id(pclause->value); + if (pcity) { + my_snprintf(buf, bufsiz, _("The %s give %s"), + get_nation_name_plural(pclause->from->nation), + pcity->name); + } else { + /* FIXME: We end in here when + 1. Player A have seen city owned by player B. + 2. Player C conquers city, but player A don't know this because of + fog of war -> Player A have old city id. + 3. Players A and B meet. + 4. Player A adds clause asking city. */ + my_snprintf(buf, bufsiz,_("Known bug: Impossible clause, just erase.")); + } break; case CLAUSE_GOLD: my_snprintf(buf, bufsiz, _("The %s give %d gold"), diff common/diptreaty.c common/diptreaty.c --- common/diptreaty.c Tue May 30 01:10:22 2000 +++ common/diptreaty.c Fri Aug 25 23:35:02 2000 @@ -14,6 +14,7 @@ #include #include "genlist.h" +#include "log.h" #include "mem.h" #include "player.h" @@ -80,15 +81,6 @@ /* same clause already there */ return 0; } - if(type==CLAUSE_GOLD - && pclause->type==CLAUSE_GOLD - && pclause->from==pfrom) { - /* gold clause there, different value */ - ptreaty->accept0=0; - ptreaty->accept1=0; - pclause->value=val; - return 1; - } if(is_pact_clause(type) && is_pact_clause(pclause->type)) { /* pact clause already there */ @@ -96,6 +88,25 @@ ptreaty->accept1=0; pclause->type=type; return 1; + } + switch(type) { + case CLAUSE_ADVANCE: + if (pclause->value < A_FIRST || pclause->value >= A_LAST) { + freelog(LOG_ERROR, "Out of range tech value %i in clause.", + pclause->value); + return 0; + } + break; + case CLAUSE_GOLD: + if (pclause->type==CLAUSE_GOLD && pclause->from==pfrom) { + /* gold clause there, different value */ + ptreaty->accept0=0; + ptreaty->accept1=0; + pclause->value=val; + return 1; + } + break; + default: } } diff server/diplhand.c server/diplhand.c --- server/diplhand.c Fri Aug 25 09:53:49 2000 +++ server/diplhand.c Sat Aug 26 00:55:50 2000 @@ -73,7 +73,8 @@ struct packet_diplomacy_info *packet) { struct Treaty *ptreaty; - struct player *plr0, *plr1, *pgiver, *pdest; + struct player *plr0, *plr1, *pgiver, *pdest, *other; + int *giver_accept; plr0=&game.players[packet->plrno0]; plr1=&game.players[packet->plrno1]; @@ -81,9 +82,66 @@ if((ptreaty=find_treaty(plr0, plr1)) && pgiver==pplayer) { if(ptreaty->plr0==pgiver) - ptreaty->accept0=!ptreaty->accept0; + giver_accept = &ptreaty->accept0; else - ptreaty->accept1=!ptreaty->accept1; + giver_accept = &ptreaty->accept1; + + other=(plr0==pplayer) ? plr1 : plr0; + if (! *giver_accept) { /* Tries to accept. */ + + /* Check that player who accepts can keep what (s)he promises. */ + + struct genlist_iterator myiter; + + genlist_iterator_init(&myiter, &ptreaty->clauses, 0); + + for(;ITERATOR_PTR(myiter); ITERATOR_NEXT(myiter)) { + struct Clause *pclause=(struct Clause *)ITERATOR_PTR(myiter); + struct city *pcity; + + if(pclause->from == pplayer) { + switch(pclause->type) { + case CLAUSE_ADVANCE: + if (get_invention(pplayer, pclause->value) != TECH_KNOWN) { + freelog(LOG_ERROR, + "The %s don't know tech %s, but try to give it to the %s.", + get_nation_name_plural(pplayer->nation), + advances[pclause->value].name, + get_nation_name_plural(other->nation)); + notify_player(pplayer, + _("Game: You don't have tech %s, you can't accept treaty."), + advances[pclause->value].name); + return; + } + break; + case CLAUSE_CITY: + pcity = find_city_by_id(pclause->value); + if (!pcity || pcity->owner != pplayer->player_no) { + notify_player(pplayer, + _("You are not owner of %s, you can't accept treaty."), + pcity->name); + return; + } + if (pcity && pcity->improvements[B_PALACE]) { + notify_player(pplayer, + _("Game: Your capital is requested, you can't accept treaty.")); + return; + } + break; + case CLAUSE_GOLD: + if (pplayer->economic.gold < pclause->value) { + notify_player(pplayer, + _("Game: You don't have enought gold, you can't accept treaty.")); + return; + } + break; + default: + } + } + } + } + + *giver_accept = ! *giver_accept; lsend_packet_diplomacy_info(&plr0->connections, PACKET_DIPLOMACY_ACCEPT_TREATY, @@ -112,23 +170,45 @@ get_nation_name_plural(plr0->nation), get_nation_name_plural(plr1->nation)); + /* Check that one who accepted treaty earlier still have everything + (s)he promised to give. */ - /* verify gold! the player's gold amount could have changed during - * the meeting */ genlist_iterator_init(&myiter, &ptreaty->clauses, 0); for(;ITERATOR_PTR(myiter); ITERATOR_NEXT(myiter)) { struct Clause *pclause=(struct Clause *)ITERATOR_PTR(myiter); - pgiver=pclause->from; - - if(pclause->type==CLAUSE_GOLD && pgiver->economic.goldvalue) { - - notify_player(plr0, _("Game: The %s don't have the promised amount " - "of gold! Treaty canceled!"), - get_nation_name_plural(pgiver->nation)); - notify_player(plr1, _("Game: The %s don't have the promised amount " - "of gold! Treaty canceled!"), - get_nation_name_plural(pgiver->nation)); - goto cleanup; + struct city *pcity; + if (pclause->from == other) { + switch(pclause->type) { + case CLAUSE_CITY: + pcity = find_city_by_id(pclause->value); + if (!pcity || pcity->owner != other->player_no) { + notify_player(plr0, + _("Game: The %s no longer control %s! " + "Treaty canceled!"), + get_nation_name_plural(other->nation), + pcity->name); + notify_player(plr1, + _("Game: The %s no longer control %s! " + "Treaty canceled!"), + get_nation_name_plural(other->nation), + pcity->name); + goto cleanup; + } + case CLAUSE_GOLD: + if (other->economic.goldvalue) { + notify_player(plr0, + _("Game: The %s don't have the promised amount " + "of gold! Treaty canceled!"), + get_nation_name_plural(other->nation)); + notify_player(plr1, + _("Game: The %s don't have the promised amount " + "of gold! Treaty canceled!"), + get_nation_name_plural(other->nation)); + goto cleanup; + } + break; + default: + } } }