Complete.Org: Mailing Lists: Archives: freeciv-dev: June 2005:
[Freeciv-Dev] (PR#13361) AI Reactions
Home

[Freeciv-Dev] (PR#13361) AI Reactions

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#13361) AI Reactions
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Tue, 28 Jun 2005 03:26:42 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13361 >

This patch adds AI reactions to certain player actions:
 * Diplomat incidents
 * Declarations of war
 * Nuclear explosions

These will worsen AI attitudes towards the player. Also changes Senate so
that it will only prevent declarations of war, not every treaty reduction.

For declarations of war, we will remember the highest level of treaties
between players ever, and punish AI attitudes towards war between former
allies and friends, which is an indication of backstabbing and betrayal.

Needs testing.

  - Per

Index: ai/advdiplomacy.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/advdiplomacy.c,v
retrieving revision 1.80
diff -u -r1.80 advdiplomacy.c
--- ai/advdiplomacy.c   21 Jun 2005 16:20:59 -0000      1.80
+++ ai/advdiplomacy.c   28 Jun 2005 10:21:43 -0000
@@ -1376,3 +1376,76 @@
     }
   } players_iterate_end;
 }
+
+/* AI attitude call-backs */
+
+/********************************************************************** 
+  Nuclear strike. Victim is whoever's territory was hit, and may be
+  NULL.
+***********************************************************************/
+void ai_incident_nuclear(struct player *violator, struct player *victim)
+{
+  if (violator == victim) {
+    players_iterate(pplayer) {
+      if (pplayer != violator) {
+        pplayer->ai.love[violator->player_no] -= MAX_AI_LOVE / 20;
+      }
+    } players_iterate_end;
+    return;
+  } else {
+    players_iterate(pplayer) {
+      if (pplayer != violator) {
+        pplayer->ai.love[violator->player_no] -= MAX_AI_LOVE / 10;
+        if (victim == pplayer) {
+          pplayer->ai.love[violator->player_no] -= MAX_AI_LOVE / 10;
+        }
+      }
+    } players_iterate_end;
+  }
+}
+
+/********************************************************************** 
+  Diplomat caused an incident.
+***********************************************************************/
+void ai_incident_diplomat(struct player *violator, struct player *victim)
+{
+  players_iterate(pplayer) {
+    if (pplayer != violator) {
+      /* Dislike backstabbing bastards */
+      pplayer->ai.love[violator->player_no] -= MAX_AI_LOVE / 100;
+      if (victim == pplayer) {
+        pplayer->ai.love[violator->player_no] -= MAX_AI_LOVE / 7;
+      }
+    }
+  } players_iterate_end;
+}
+
+/********************************************************************** 
+  War declared against a player.  We apply a penalty because this
+  means he is seen as untrustworthy, especially if past relations
+  with the victim have been cordial (betrayal).
+
+  Reasons for war and other mitigating circumstances are checked
+  in calling code.
+***********************************************************************/
+void ai_incident_war(struct player *violator, struct player *victim)
+{
+  players_iterate(pplayer) {
+    if (pplayer != violator) {
+      /* Dislike backstabbing bastards */
+      pplayer->ai.love[violator->player_no] -= MAX_AI_LOVE / 30;
+      if (violator->diplstates[victim->player_no].max_state == DS_PEACE) {
+        /* Extra penalty if they once had a peace treaty */
+        pplayer->ai.love[violator->player_no] -= MAX_AI_LOVE / 30;
+      } else if (violator->diplstates[victim->player_no].max_state 
+                 == DS_ALLIANCE) {
+        /* Extra penalty if they once had an alliance */
+        pplayer->ai.love[violator->player_no] -= MAX_AI_LOVE / 10;
+      }
+      if (victim == pplayer) {
+        pplayer->ai.love[violator->player_no] -= 
+          MIN(pplayer->ai.love[violator->player_no] - MAX_AI_LOVE / 3, -1);
+      }
+    }
+  } players_iterate_end;
+}
Index: ai/advdiplomacy.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/advdiplomacy.h,v
retrieving revision 1.3
diff -u -r1.3 advdiplomacy.h
--- ai/advdiplomacy.h   15 Dec 2004 03:59:21 -0000      1.3
+++ ai/advdiplomacy.h   28 Jun 2005 10:21:43 -0000
@@ -29,4 +29,8 @@
 void ai_treaty_accepted(struct player *pplayer, struct player *aplayer, 
                         struct Treaty *ptreaty);
 
+void ai_incident_war(struct player *violator, struct player *victim);
+void ai_incident_diplomat(struct player *violator, struct player *victim);
+void ai_incident_nuclear(struct player *violator, struct player *victim);
+
 #endif
Index: common/player.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
retrieving revision 1.157
diff -u -r1.157 player.h
--- common/player.h     21 Jun 2005 16:21:01 -0000      1.157
+++ common/player.h     28 Jun 2005 10:21:43 -0000
@@ -181,6 +181,7 @@
 struct player_diplstate {
   enum diplstate_type type;    /* this player's disposition towards other */
   /* the following are for "pacts" */
+  enum diplstate_type max_state; /* maximum treaty level ever had */
   int turns_left;              /* until pact (e.g., cease-fire) ends */
   int has_reason_to_cancel;    /* 0: no, 1: this turn, 2: this or next turn */
   int contact_turns_left;      /* until contact ends */
Index: server/diplhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/diplhand.c,v
retrieving revision 1.95
diff -u -r1.95 diplhand.c
--- server/diplhand.c   23 Jun 2005 21:58:23 -0000      1.95
+++ server/diplhand.c   28 Jun 2005 10:21:43 -0000
@@ -431,6 +431,10 @@
       case CLAUSE_PEACE:
        pgiver->diplstates[pdest->player_no].type=DS_PEACE;
        pdest->diplstates[pgiver->player_no].type=DS_PEACE;
+       pgiver->diplstates[pdest->player_no].max_state = 
+          MAX(DS_PEACE, pgiver->diplstates[pdest->player_no].max_state);
+       pdest->diplstates[pgiver->player_no].max_state = 
+          MAX(DS_PEACE, pdest->diplstates[pgiver->player_no].max_state);
        notify_player_ex(pgiver, NULL, E_TREATY_PEACE,
                         _("You agree on a peace treaty with %s."),
                         pdest->name);
@@ -444,6 +448,10 @@
       case CLAUSE_ALLIANCE:
        pgiver->diplstates[pdest->player_no].type=DS_ALLIANCE;
        pdest->diplstates[pgiver->player_no].type=DS_ALLIANCE;
+       pgiver->diplstates[pdest->player_no].max_state = 
+          MAX(DS_PEACE, pgiver->diplstates[pdest->player_no].max_state);
+       pdest->diplstates[pgiver->player_no].max_state = 
+          MAX(DS_PEACE, pdest->diplstates[pgiver->player_no].max_state);
        notify_player_ex(pgiver, NULL, E_TREATY_ALLIANCE,
                         _("You agree on an alliance with %s."),
                         pdest->name);
Index: server/diplomats.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/diplomats.c,v
retrieving revision 1.81
diff -u -r1.81 diplomats.c
--- server/diplomats.c  27 Jun 2005 14:30:19 -0000      1.81
+++ server/diplomats.c  28 Jun 2005 10:21:43 -0000
@@ -35,6 +35,8 @@
 #include "unithand.h"
 #include "unittools.h"
 
+#include "advdiplomacy.h"
+
 #include "diplomats.h"
 
 
@@ -1354,6 +1356,7 @@
       die("Bug in maybe_cause_incident()");
     }
     victim_player->diplstates[offender->player_no].has_reason_to_cancel = 2;
+    ai_incident_diplomat(offender, victim_player);
     send_player_info(offender, NULL);
     send_player_info(victim_player, NULL);
   }
Index: server/plrhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v
retrieving revision 1.393
diff -u -r1.393 plrhand.c
--- server/plrhand.c    24 Jun 2005 10:12:47 -0000      1.393
+++ server/plrhand.c    28 Jun 2005 10:21:44 -0000
@@ -51,6 +51,7 @@
 #include "spacerace.h"
 #include "unittools.h"
 
+#include "advdiplomacy.h"
 #include "advmilitary.h"
 #include "aidata.h"
 #include "aihand.h"
@@ -571,13 +572,14 @@
                          "constant provocations of the %s."),
                        get_nation_name_plural(pplayer2->nation));
     }
-  } else {
+  } else if (new_type == DS_WAR) {
     if (has_senate && pplayer->revolution_finishes < 0) {
         notify_player_ex(pplayer, NULL, E_ANARCHY,
                          _("The senate decides to dissolve "
                          "rather than support your actions any longer."));
        handle_player_change_government(pplayer, pplayer->government);
     }
+    ai_incident_war(pplayer, pplayer2);
   }
 
   send_player_info(pplayer, NULL);
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.257
diff -u -r1.257 savegame.c
--- server/savegame.c   23 Jun 2005 21:58:24 -0000      1.257
+++ server/savegame.c   28 Jun 2005 10:21:44 -0000
@@ -2016,6 +2016,9 @@
     plr->diplstates[i].type = 
       secfile_lookup_int_default(file, DS_WAR,
                                 "player%d.diplstate%d.type", plrno, i);
+    plr->diplstates[i].max_state = 
+      secfile_lookup_int_default(file, DS_NEUTRAL,
+                                "player%d.diplstate%d.max_state", plrno, i);
     plr->diplstates[i].turns_left = 
       secfile_lookup_int_default(file, -2,
                                 "player%d.diplstate%d.turns_left", plrno, i);
@@ -2725,6 +2728,8 @@
   for (i = 0; i < MAX_NUM_PLAYERS+MAX_NUM_BARBARIANS; i++) {
     secfile_insert_int(file, plr->diplstates[i].type,
                       "player%d.diplstate%d.type", plrno, i);
+    secfile_insert_int(file, plr->diplstates[i].max_state,
+                      "player%d.diplstate%d.max_state", plrno, i);
     secfile_insert_int(file, plr->diplstates[i].turns_left,
                       "player%d.diplstate%d.turns_left", plrno, i);
     secfile_insert_int(file, plr->diplstates[i].has_reason_to_cancel,
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.363
diff -u -r1.363 unittools.c
--- server/unittools.c  27 Jun 2005 14:30:19 -0000      1.363
+++ server/unittools.c  28 Jun 2005 10:21:45 -0000
@@ -54,6 +54,7 @@
 #include "techtools.h"
 #include "gamehand.h"
 
+#include "advdiplomacy.h"
 #include "aiexplorer.h"
 #include "aitools.h"
 #include "aiunit.h"
@@ -2133,6 +2134,14 @@
 **************************************************************************/
 void do_nuclear_explosion(struct player *pplayer, struct tile *ptile)
 {
+  if (ptile->owner) {
+    ai_incident_nuclear(pplayer, ptile->owner);
+  } else if (ptile->city) {
+    ai_incident_nuclear(pplayer, city_owner(ptile->city));
+  } else {
+    ai_incident_nuclear(pplayer, NULL);
+  }
+
   square_iterate(ptile, 1, ptile1) {
     do_nuke_tile(pplayer, ptile1);
   } square_iterate_end;

[Prev in Thread] Current Thread [Next in Thread]