Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2002:
[Freeciv-Dev] Re: (PR#2293) Paratroopers jumping into an empty city
Home

[Freeciv-Dev] Re: (PR#2293) Paratroopers jumping into an empty city

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: ue80@xxxxxxxxxxxxxxxxxxx
Cc: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#2293) Paratroopers jumping into an empty city
From: "Davide Pagnin via RT" <rt@xxxxxxxxxxxxxx>
Date: Sun, 17 Nov 2002 10:21:55 -0800
Reply-to: rt@xxxxxxxxxxxxxx

> 1) We can let people declare war automatically if they paradrop in a
> not_known no_contact empty city (fixing the problem that the paratrooper
> enter a city to which we are not in *real* WAR).
> I have to say that this should be the correct answer if we agree that
> the pplayer_at_war() function do return TRUE if we are in NO_CONTACT...
> 
> 2) We can instead kill the paratrooper if he paradrop in a not_known
> no_contact empty city (as we do for neutral, peace or cease-fire).
> This is perhaps easy, but then we need to make_contact() happen before
> the paradrop.

This patch I supply, choose this solution.
If you paradrop in an empty unknown city and it turns out that the owner
is a no_contact player, then contact is made and your paratrooper is
killed.

For ease of readability and future uses, I have added
pplayers_no_contact() function to player.[ch].

> 
> 3) What should happen if we paradrop on a stack of unit that contain
> units of a nation we are in no_contact status, should we need to
> make_contact()?

There is no easy way to call make_contact() if it is needed, thus I will
wait comments on this before going further on this possible
improvement/fix.

> 
> Let me know your thoughts, this fix (partial or complete) need to find
> its way before 1.14.0.
> 
>       Ciao,Davide
> 
> 
> 
> 

diff -urN -Xfreeciv/diff_ignore freeciv/common/player.c 
freeciv-beta/common/player.c
--- freeciv/common/player.c     Tue Nov 12 15:09:47 2002
+++ freeciv-beta/common/player.c        Sun Nov 17 18:59:56 2002
@@ -546,6 +546,19 @@
 }
 
 /***************************************************************
+returns true iff players have no contacts .
+***************************************************************/
+bool pplayers_no_contact(const struct player *pplayer,
+                        const struct player *pplayer2)
+{
+  enum diplstate_type ds = pplayer_get_diplstate(pplayer, pplayer2)->type;
+  if (pplayer == pplayer2) return FALSE;
+  if (is_barbarian(pplayer) || is_barbarian(pplayer2))
+    return FALSE;
+  return ds == DS_NO_CONTACT;
+}
+
+/***************************************************************
 returns true iff players can attack each other.
 ***************************************************************/
 bool pplayers_at_war(const struct player *pplayer,
diff -urN -Xfreeciv/diff_ignore freeciv/common/player.h 
freeciv-beta/common/player.h
--- freeciv/common/player.h     Tue Nov 12 15:09:47 2002
+++ freeciv-beta/common/player.h        Sun Nov 17 18:57:37 2002
@@ -248,6 +248,8 @@
                                                     *pplayer,
                                                     const struct player
                                                     *pplayer2);
+bool pplayers_no_contact(const struct player *pplayer,
+                        const struct player *pplayer2);
 bool pplayers_at_war(const struct player *pplayer,
                    const struct player *pplayer2);
 bool pplayers_allied(const struct player *pplayer,
diff -urN -Xfreeciv/diff_ignore freeciv/server/unittools.c 
freeciv-beta/server/unittools.c
--- freeciv/server/unittools.c  Tue Nov 12 15:09:54 2002
+++ freeciv-beta/server/unittools.c     Sun Nov 17 19:06:43 2002
@@ -2253,24 +2253,35 @@
 **************************************************************************/
 bool do_paradrop(struct unit *punit, int dest_x, int dest_y)
 {
+  struct tile *ptile = map_get_tile(dest_x, dest_y);
+  struct player *pplayer = unit_owner(punit);
+
   if (!unit_flag(punit, F_PARATROOPERS)) {
-    notify_player_ex(unit_owner(punit), punit->x, punit->y, E_NOEVENT,
-                    _("Game: This unit type can not be paradropped."));
+    notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT,
+                     _("Game: This unit type can not be paradropped."));
     return FALSE;
   }
 
   if (!can_unit_paradrop(punit))
     return FALSE;
 
-  if (!map_get_known(dest_x, dest_y, unit_owner(punit))) {
-    notify_player_ex(unit_owner(punit), dest_x, dest_y, E_NOEVENT,
-                    _("Game: The destination location is not known."));
+  if (!map_get_known(dest_x, dest_y, pplayer)) {
+    notify_player_ex(pplayer, dest_x, dest_y, E_NOEVENT,
+                     _("Game: The destination location is not known."));
     return FALSE;
   }
 
-  if (map_get_player_tile(dest_x, dest_y, unit_owner(punit))->terrain == 
T_OCEAN) {
-    notify_player_ex(unit_owner(punit), dest_x, dest_y, E_NOEVENT,
-                    _("Game: Cannot paradrop into ocean."));
+  if (map_get_player_tile(dest_x, dest_y, pplayer)->terrain == T_OCEAN) {
+    notify_player_ex(pplayer, dest_x, dest_y, E_NOEVENT,
+                     _("Game: Cannot paradrop into ocean."));
+    return FALSE;    
+  }
+
+  if (map_get_known_and_seen(dest_x, dest_y, pplayer) && ((ptile->city
+      && pplayers_non_attack(pplayer, city_owner(ptile->city))) 
+      || is_non_attack_unit_tile(ptile, pplayer))) {
+    notify_player_ex(pplayer, dest_x, dest_y, E_NOEVENT,
+                     _("Game: Cannot attack unless you declare war first."));
     return FALSE;    
   }
 
@@ -2278,34 +2289,46 @@
     int range = unit_type(punit)->paratroopers_range;
     int distance = real_map_distance(punit->x, punit->y, dest_x, dest_y);
     if (distance > range) {
-      notify_player_ex(unit_owner(punit), dest_x, dest_y, E_NOEVENT,
-                      _("Game: The distance to the target (%i) "
-                        "is greater than the unit's range (%i)."),
-                      distance, range);
+      notify_player_ex(pplayer, dest_x, dest_y, E_NOEVENT,
+                       _("Game: The distance to the target (%i) "
+                         "is greater than the unit's range (%i)."),
+                       distance, range);
       return FALSE;
     }
   }
 
   if (map_get_terrain(dest_x, dest_y) == T_OCEAN) {
     int srange = unit_type(punit)->vision_range;
-    show_area(unit_owner(punit), dest_x, dest_y, srange);
+    show_area(pplayer, dest_x, dest_y, srange);
 
-    notify_player_ex(unit_owner(punit), dest_x, dest_y, E_UNIT_LOST,
-                    _("Game: Your %s paradropped into the ocean "
-                      "and was lost."),
-                    unit_type(punit)->name);
+    notify_player_ex(pplayer, dest_x, dest_y, E_UNIT_LOST,
+                     _("Game: Your %s paradropped into the ocean "
+                       "and was lost."),
+                     unit_type(punit)->name);
+    server_remove_unit(punit);
+    return TRUE;
+  }
+
+  if ((ptile->city && pplayers_non_attack(pplayer, city_owner(ptile->city)))
+      || is_non_allied_unit_tile(ptile, pplayer)) {
+    int srange = unit_type(punit)->vision_range;
+    show_area(pplayer, dest_x, dest_y, srange);
+    notify_player_ex(pplayer, dest_x, dest_y, E_UNIT_LOST_ATT,
+                     _("Game: Your %s was killed by enemy units at the "
+                       "paradrop destination."),
+                     unit_type(punit)->name);
     server_remove_unit(punit);
     return TRUE;
   }
 
-  if (is_non_allied_unit_tile
-      (map_get_tile(dest_x, dest_y), unit_owner(punit))) {
+  if (ptile->city && pplayers_no_contact(pplayer, city_owner(ptile->city))) {
     int srange = unit_type(punit)->vision_range;
-    show_area(unit_owner(punit), dest_x, dest_y, srange);
-    notify_player_ex(unit_owner(punit), dest_x, dest_y, E_UNIT_LOST_ATT,
-                    _("Game: Your %s was killed by enemy units at the "
-                      "paradrop destination."),
-                    unit_type(punit)->name);
+    show_area(pplayer, dest_x, dest_y, srange);
+    make_contact(pplayer, city_owner(ptile->city), dest_x, dest_y);
+    notify_player_ex(pplayer, dest_x, dest_y, E_UNIT_LOST_ATT,
+                     _("Game: Your %s was killed by enemy units at the "
+                       "paradrop destination."),
+                     unit_type(punit)->name);
     server_remove_unit(punit);
     return TRUE;
   }

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