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

I refreshed this patch because I needed it for testing. 

Turns out it is somewhat harder to turn terrain into ocean in the more
recent code, since we do not really have an 'ocean' tile anymore (there
could be several). So I just transformed terrain one step toward wetter,
where possible. Not nearly as impressive as the previous version :(

  - Per
Index: server/unittools.c
===================================================================
--- server/unittools.c	(revision 12962)
+++ server/unittools.c	(working copy)
@@ -2013,12 +2013,13 @@
 
 /**************************************************************************
   Nuke a square: 1) remove all units on the square, and 2) halve the 
-  size of the city on the square.
+  size of the city on the square, if nuke, or destroy it, if antimatter.
 
   If it isn't a city square or an ocean square then with 50% chance add 
   some fallout, then notify the client about the changes.
 **************************************************************************/
-static void do_nuke_tile(struct player *pplayer, struct tile *ptile)
+static void do_nuke_tile(struct player *pplayer, struct tile *ptile, 
+                         bool antimatter)
 {
   struct city *pcity = tile_get_city(ptile);
 
@@ -2038,20 +2039,36 @@
   } unit_list_iterate_safe_end;
 
   if (pcity) {
-    notify_player(city_owner(pcity),
-		     ptile, E_CITY_NUKED,
-		     _("%s was nuked by %s."),
-		     pcity->name,
-		     pplayer == city_owner(pcity) ? _("yourself") : pplayer->name);
+    if (antimatter) {
+      notify_player(city_owner(pcity), ptile, E_CITY_NUKED,
+                    _("%s was obliterated by %s."),
+                    pcity->name, pplayer == pcity->owner
+                    ? _("yourself") : pplayer->name);
+      if (city_owner(pcity) != pplayer) {
+        notify_player(pplayer, ptile, E_CITY_NUKED,
+                      _("You obliterated %s."), pcity->name);
+      }
+      remove_city(pcity);
+    } else {
+      notify_player(city_owner(pcity), ptile, E_CITY_NUKED,
+                    _("%s was nuked by %s."), pcity->name,
+                    pplayer == pcity->owner ? _("yourself") : pplayer->name);
 
-    if (city_owner(pcity) != pplayer) {
-      notify_player(pplayer,
-		       ptile, E_CITY_NUKED,
-		       _("You nuked %s."),
-		       pcity->name);
+      if (city_owner(pcity) != pplayer) {
+        notify_player(pplayer, ptile, E_CITY_NUKED, _("You nuked %s."),
+                      pcity->name);
+      }
+      city_reduce_size(pcity, pcity->size / 2);
     }
+  }
 
-    city_reduce_size(pcity, pcity->size / 2);
+  if (antimatter && !is_ocean(tile_get_terrain(ptile)) && myrand(4) == 1
+      && ptile->terrain->warmer_wetter_result) {
+    struct terrain *old = tile_get_terrain(ptile);
+
+    tile_change_terrain(ptile, ptile->terrain->warmer_wetter_result);
+    check_terrain_change(ptile, old);
+    update_tile_knowledge(ptile);
   }
 
   if (!is_ocean(tile_get_terrain(ptile)) && myrand(2) == 1) {
@@ -2073,7 +2090,8 @@
   Nuke all the squares in a 3x3 square around the center of the explosion
   pplayer is the player that caused the explosion.
 **************************************************************************/
-void do_nuclear_explosion(struct player *pplayer, struct tile *ptile)
+void do_nuclear_explosion(struct player *pplayer, struct tile *ptile,
+                          bool antimatter)
 {
   if (ptile->owner) {
     ai_incident_nuclear(pplayer, ptile->owner);
@@ -2084,11 +2102,16 @@
   }
 
   square_iterate(ptile, 1, ptile1) {
-    do_nuke_tile(pplayer, ptile1);
+    do_nuke_tile(pplayer, ptile1, antimatter);
   } square_iterate_end;
 
-  notify_conn(NULL, ptile, E_NUKE,
-		 _("%s detonated a nuke!"), pplayer->name);
+  if (antimatter) {
+    notify_conn(NULL, ptile, E_NUKE,
+                _("%s detonated an antimatter bomb!"), pplayer->name);
+  } else {
+    notify_conn(NULL, ptile, E_NUKE,
+                _("%s detonated a nuke!"), pplayer->name);
+  }
 }
 
 /**************************************************************************
Index: server/unittools.h
===================================================================
--- server/unittools.h	(revision 12962)
+++ server/unittools.h	(working copy)
@@ -80,7 +80,8 @@
 void unit_goes_out_of_sight(struct player *pplayer, struct unit *punit);
 
 /* doing a unit activity */
-void do_nuclear_explosion(struct player *pplayer, struct tile *ptile);
+void do_nuclear_explosion(struct player *pplayer, struct tile *ptile,
+                          bool antimatter);
 bool do_airline(struct unit *punit, struct city *city2);
 bool do_paradrop(struct unit *punit, struct tile *ptile);
 void load_unit_onto_transporter(struct unit *punit, struct unit *ptrans);
Index: server/unithand.c
===================================================================
--- server/unithand.c	(revision 12962)
+++ server/unithand.c	(working copy)
@@ -776,29 +776,33 @@
 	"or cease-fire at %i, %i", TILE_XY(def_tile));
   }
   if (pplayers_allied(unit_owner(punit), unit_owner(pdefender))
-      && !(unit_flag(punit, F_NUCLEAR) && punit == pdefender)) {
+      && !(unit_flag(punit, F_NUCLEAR) && punit == pdefender)
+      && !(unit_flag(punit, F_ANTIMATTER) && punit == pdefender)) {
     die("Trying to attack a unit with which you have alliance at %i, %i",
 	TILE_XY(def_tile));
   }
 
-  if (unit_flag(punit, F_NUCLEAR)) {
+  if (unit_class_flag(punit->type->class, UCF_MISSILE)) {
     if ((pcity = sdi_try_defend(unit_owner(punit), def_tile))) {
       notify_player(pplayer, punit->tile, E_UNIT_LOST_ATT,
-		       _("Your Nuclear missile was shot down by"
+		       _("Your missile was shot down by"
 			 " SDI defences, what a waste."));
       notify_player(city_owner(pcity), def_tile, E_UNIT_WIN,
-		       _("The nuclear attack on %s was avoided by"
+		       _("The attack on %s was avoided by"
 			 " your SDI defense."), pcity->name);
       wipe_unit(punit);
       return;
-    } 
+    }
 
-    dlsend_packet_nuke_tile_info(game.est_connections,
-				 def_tile->x, def_tile->y);
+    if (unit_flag(punit, F_NUCLEAR) || unit_flag(punit, F_ANTIMATTER)) {
+      bool antimatter = unit_flag(punit, F_ANTIMATTER);
+      dlsend_packet_nuke_tile_info(game.est_connections,
+                                   def_tile->x, def_tile->y);
 
-    wipe_unit(punit);
-    do_nuclear_explosion(pplayer, def_tile);
-    return;
+      wipe_unit(punit);
+      do_nuclear_explosion(pplayer, def_tile, antimatter);
+      return;
+    }
   }
   moves_used = unit_move_rate(punit) - punit->moves_left;
   def_moves_used = unit_move_rate(pdefender) - pdefender->moves_left;
@@ -1123,7 +1127,7 @@
     } else {
       assert(is_enemy_city_tile(pdesttile, pplayer) != NULL);
 
-      if (unit_flag(punit, F_NUCLEAR)) {
+      if (unit_flag(punit, F_NUCLEAR) || unit_flag(punit, F_ANTIMATTER)) {
         move_unit(punit, pcity->tile, 0);
         handle_unit_attack_request(punit, punit); /* Boom! */
         return TRUE;
Index: data/default/units.ruleset
===================================================================
--- data/default/units.ruleset	(revision 12962)
+++ data/default/units.ruleset	(working copy)
@@ -1622,6 +1622,35 @@
  chance of nuclear winter.  Eco-friendly nukes!\
 ")
 
+[unit_antimatter]
+name          = _("Antimatter ICBM")
+class         = "Missile"
+tech_req      = "None"
+obsolete_by   = "None"
+graphic       = "u.nuclear"
+graphic_alt   = "-"
+sound_move    = "m_nuclear"
+sound_move_alt = "m_generic"
+sound_fight   = "f_nuclear"
+sound_fight_alt = "f_generic"
+build_cost    = 16
+pop_cost      = 0
+attack        = 99
+defense       = 0
+hitpoints     = 10
+firepower     = 1
+move_rate     = 16
+vision_radius_sq = 2
+transport_cap = 0
+fuel          = 1
+uk_happy      = 1
+uk_shield     = 1
+uk_food       = 0
+uk_gold       = 0
+flags         = "FieldUnit", "OneAttack", "Antimatter", "AirUnit"
+roles         = ""
+helptext      = _("The ultimate bomb.")
+
 [unit_diplomat]
 name          = _("Diplomat")
 class         = "Land"
Index: common/unittype.c
===================================================================
--- common/unittype.c	(revision 12962)
+++ common/unittype.c	(working copy)
@@ -53,7 +53,7 @@
   "AddToCity", "Fanatic", "GameLoss", "Unique", "Unbribable", 
   "Undisbandable", "SuperSpy", "NoHome", "NoVeteran", "Bombarder",
   "CityBuster", "NoBuild", "BadWallAttacker", "BadCityDefender",
-  "Helicopter", "AirUnit", "Fighter", "BarbarianOnly"
+  "Helicopter", "AirUnit", "Fighter", "BarbarianOnly", "Antimatter"
 };
 static const char *role_names[] = {
   "FirstBuild", "Explorer", "Hut", "HutTech", "Partisan",
Index: common/unittype.h
===================================================================
--- common/unittype.h	(revision 12962)
+++ common/unittype.h	(working copy)
@@ -113,6 +113,7 @@
   F_AIRUNIT,          /* Bad at attacking F_AEGIS units */
   F_FIGHTER,          /* Good at attacking F_HELICOPTER units */
   F_BARBARIAN_ONLY,   /* Only barbarians can build this unit */
+  F_ANTIMATTER,       /* Very nasty explosion */
   F_LAST
 };
 #define F_MAX 64
Index: client/control.c
===================================================================
--- client/control.c	(revision 12962)
+++ client/control.c	(working copy)
@@ -1387,7 +1387,7 @@
     return;
   }
   unit_list_iterate(punits, punit) {
-    if (unit_flag(punit, F_NUCLEAR)) {
+    if (unit_flag(punit, F_NUCLEAR) || unit_flag(punit, F_ANTIMATTER)) {
       can = TRUE;
       break;
     }
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to