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

On 28/01/07, Daniel Markstedt wrote:
>
> On 1/28/07, Per Inge Mathisen wrote:
> > >
> > >> > ~Event upon the death of a unique unit.
> > >> > ~Event upon the conquest of a specific city.

 This alpha level patch implements two city events:
 "city_lost"           - city has been transferred from player to player
 "city_destroyed" - city has been destroyed

 Only trunk version attached.

> Important for making Freeciv a serious platform for Civ2-style
> scenario creation.

 We lack quite a lot of important events. Adding these is bug-prone,
so it should take place in S2_1 only if event is really critical for
many (most) scenarios.
 I guess these ones are. But it would be nice to know ASAP, if some
others are needed before 2.1.0.


 - ML

diff -Nurd -X.diff_ignore freeciv/common/events.h freeciv/common/events.h
--- freeciv/common/events.h	2007-08-05 16:40:58.000000000 +0300
+++ freeciv/common/events.h	2007-09-03 23:49:37.000000000 +0300
@@ -17,7 +17,10 @@
 
 /* Add new event types to the end. Client saves message settings by
  * type number and installing new event type in between would cause
- * erronous loading of existing .civclientrc */
+ * erronous loading of existing .civclientrc
+ * When adding events to stable branch, there is risk that TRUNK
+ * already has allocated next slot for something else (and has
+ * new event in upper slot) */
 enum event_type {
   E_CITY_CANTBUILD,
   E_CITY_LOST,
@@ -124,7 +127,7 @@
   /* 
    * Note: If you add a new event, make sure you make a similar change
    * to the events array in common/events.c using GEN_EV and to
-   * data/stdsounds.spec.
+   * data/stdsounds.soundspec.
    */
   E_LAST
 };
diff -Nurd -X.diff_ignore freeciv/server/citytools.c freeciv/server/citytools.c
--- freeciv/server/citytools.c	2007-09-02 15:38:29.000000000 +0300
+++ freeciv/server/citytools.c	2007-09-04 00:11:05.000000000 +0300
@@ -1267,6 +1267,12 @@
    * the city will be destroyed.
    */
   if (pcity->size <= 1) {
+
+    script_signal_emit("city_destroyed", 3,
+                       API_TYPE_CITY, pcity,
+                       API_TYPE_PLAYER, cplayer,
+                       API_TYPE_PLAYER, pplayer);
+
     notify_player(pplayer, pcity->tile, E_UNIT_WIN_ATT,
 		     _("You destroy %s completely."), pcity->name);
     notify_player(cplayer, pcity->tile, E_CITY_LOST, 
@@ -1347,12 +1353,18 @@
     }
   } players_iterate_end;
 
-  city_reduce_size(pcity, 1);
+  assert(pcity->size > 1); /* reduce size should not destroy this city */
+  city_reduce_size(pcity, 1, pplayer);
   send_player_info(pplayer, pplayer); /* Update techs */
 
   if (do_civil_war) {
     civil_war(cplayer);
   }
+
+  script_signal_emit("city_lost", 3,
+                     API_TYPE_CITY, pcity,
+                     API_TYPE_PLAYER, cplayer,
+                     API_TYPE_PLAYER, pplayer);
 }
 
 /**************************************************************************
diff -Nurd -X.diff_ignore freeciv/server/cityturn.c freeciv/server/cityturn.c
--- freeciv/server/cityturn.c	2007-08-31 11:51:59.000000000 +0300
+++ freeciv/server/cityturn.c	2007-09-04 00:12:25.000000000 +0300
@@ -396,7 +396,8 @@
   Reduce the city size.  Return TRUE if the city survives the population
   loss.
 **************************************************************************/
-bool city_reduce_size(struct city *pcity, int pop_loss)
+bool city_reduce_size(struct city *pcity, int pop_loss,
+                      struct player *destroyer)
 {
   int i;
 
@@ -405,6 +406,12 @@
   }
 
   if (pcity->size <= pop_loss) {
+
+    script_signal_emit("city_destroyed", 3,
+                       API_TYPE_CITY, pcity,
+                       API_TYPE_PLAYER, pcity->owner,
+                       API_TYPE_PLAYER, destroyer);
+
     remove_city(pcity);
     return FALSE;
   }
@@ -572,7 +579,10 @@
     }
     return TRUE;
   } else if (size < pcity->size) {
-    return city_reduce_size(pcity, pcity->size - size);
+    /* We assume that city_change_size() is never called because
+     * of enemy actions. If that changes, enemy must be passed
+     * to city_reduce_size() */
+    return city_reduce_size(pcity, pcity->size - size, NULL);
   } else {
     return TRUE;
   }
@@ -622,7 +632,7 @@
     }
     pcity->food_stock = (city_granary_size(pcity->size - 1)
 			 * granary_savings(pcity)) / 100;
-    city_reduce_size(pcity, 1);
+    city_reduce_size(pcity, 1, NULL);
   }
 }
 
@@ -1105,7 +1115,7 @@
 			 "upkeep %s!"),
 			 pcity->name,
 			 unit_name_translation(punit));
-	if (!city_reduce_size(pcity, 1)) {
+	if (!city_reduce_size(pcity, 1, NULL)) {
 	  return FALSE;
 	}
 
@@ -1313,7 +1323,7 @@
        rearrange the worker to take into account the extra resources
        (food) needed. */
     if (pop_cost > 0) {
-      city_reduce_size(pcity, pop_cost);
+      city_reduce_size(pcity, pop_cost, NULL);
     }
 
     /* to eliminate micromanagement, we only subtract the unit's
diff -Nurd -X.diff_ignore freeciv/server/cityturn.h freeciv/server/cityturn.h
--- freeciv/server/cityturn.h	2007-08-04 18:36:24.000000000 +0300
+++ freeciv/server/cityturn.h	2007-09-03 23:50:16.000000000 +0300
@@ -28,7 +28,8 @@
 void apply_cmresult_to_city(struct city *pcity, struct cm_result *cmr);
 
 bool city_change_size(struct city *pcity, int new_size);
-bool city_reduce_size(struct city *pcity, int pop_loss);
+bool city_reduce_size(struct city *pcity, int pop_loss,
+                      struct player *destroyer);
 void send_global_city_turn_notifications(struct conn_list *dest);
 void send_city_turn_notifications(struct conn_list *dest, struct city *pcity);
 void update_city_activities(struct player *pplayer);
diff -Nurd -X.diff_ignore freeciv/server/diplomats.c freeciv/server/diplomats.c
--- freeciv/server/diplomats.c	2007-08-13 20:51:02.000000000 +0300
+++ freeciv/server/diplomats.c	2007-09-03 23:48:43.000000000 +0300
@@ -106,7 +106,7 @@
   freelog (LOG_DEBUG, "poison: succeeded");
 
   /* Poison people! */
-  city_reduce_size(pcity, 1);
+  city_reduce_size(pcity, 1, pplayer);
 
   /* Notify everybody involved. */
   notify_player(pplayer, pcity->tile, E_MY_DIPLOMAT_POISON,
@@ -735,7 +735,7 @@
 
   /* City loses some population. */
   if (pcity->size > 1) {
-    city_reduce_size(pcity, 1);
+    city_reduce_size(pcity, 1, pplayer);
   }
 
   /* This costs! */
diff -Nurd -X.diff_ignore freeciv/server/scripting/api.pkg freeciv/server/scripting/api.pkg
--- freeciv/server/scripting/api.pkg	2007-08-13 20:51:02.000000000 +0300
+++ freeciv/server/scripting/api.pkg	2007-09-03 23:48:43.000000000 +0300
@@ -472,8 +472,8 @@
     E_CHAT_ERROR @ CHAT_ERROR,
     /* 
      * Note: If you add a new event, make sure you make a similar change
-     * to the events array in client/options.c using GEN_EV and to
-     * data/stdsounds.spec.
+     * to the events array in common/events.c using GEN_EV and to
+     * data/stdsounds.soundspec.
      */
     E_LAST @ LAST
   };
diff -Nurd -X.diff_ignore freeciv/server/scripting/script_signal.c freeciv/server/scripting/script_signal.c
--- freeciv/server/scripting/script_signal.c	2007-09-02 17:21:02.000000000 +0300
+++ freeciv/server/scripting/script_signal.c	2007-09-04 00:41:37.000000000 +0300
@@ -151,6 +151,12 @@
 		       3, API_TYPE_TECH_TYPE, API_TYPE_PLAYER,
 		       API_TYPE_STRING);
 
+  /* First player is city owner, second is enemy. */
+  script_signal_create("city_destroyed",
+                       3, API_TYPE_CITY, API_TYPE_PLAYER, API_TYPE_PLAYER);
+  script_signal_create("city_lost",
+                       3, API_TYPE_CITY, API_TYPE_PLAYER, API_TYPE_PLAYER);
+
   script_signal_create("hut_enter", 1, API_TYPE_UNIT);
 }
 
diff -Nurd -X.diff_ignore freeciv/server/unithand.c freeciv/server/unithand.c
--- freeciv/server/unithand.c	2007-08-14 02:36:43.000000000 +0300
+++ freeciv/server/unithand.c	2007-09-03 23:48:43.000000000 +0300
@@ -750,7 +750,7 @@
       && pcity->size > 1
       && get_city_bonus(pcity, EFT_UNIT_NO_LOSE_POP) == 0
       && kills_citizen_after_attack(punit)) {
-    city_reduce_size(pcity,1);
+    city_reduce_size(pcity, 1, pplayer);
     city_refresh(pcity);
     send_city_info(NULL, pcity);
   }
@@ -852,7 +852,7 @@
       && pcity->size > 1
       && get_city_bonus(pcity, EFT_UNIT_NO_LOSE_POP) == 0
       && kills_citizen_after_attack(punit)) {
-    city_reduce_size(pcity,1);
+    city_reduce_size(pcity, 1, pplayer);
     city_refresh(pcity);
     send_city_info(NULL, pcity);
   }
diff -Nurd -X.diff_ignore freeciv/server/unittools.c freeciv/server/unittools.c
--- freeciv/server/unittools.c	2007-09-02 15:38:29.000000000 +0300
+++ freeciv/server/unittools.c	2007-09-03 23:48:43.000000000 +0300
@@ -2068,7 +2068,7 @@
 		       pcity->name);
     }
 
-    city_reduce_size(pcity, pcity->size / 2);
+    city_reduce_size(pcity, pcity->size / 2, pplayer);
   }
 
   if (!is_ocean(tile_get_terrain(ptile)) && myrand(2) == 1) {
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to