Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2004:
[Freeciv-Dev] (PR#11508) New toy: The antimatter bomb
Home

[Freeciv-Dev] (PR#11508) New toy: The antimatter bomb

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#11508) New toy: The antimatter bomb
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Mon, 13 Dec 2004 16:55:58 -0800
Reply-to: bugs@xxxxxxxxxxx

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

Tired of the same old freeciv games that just never seem to end? Getting
sleepy at the very thought of rounding up those twenty something mech inf
behind city wall, coastal, SAM and SDI inside every AI city?

Well, the ultimate solution to all your problems is finally here!

Just drop the bomb somewhere near the problem area, and go home.

The antimatter bomb will kill everything inside its blast radius, which is
as big as a city radius. It will randomly turn one out of four tiles into
ocean. It will give you nuclear winter in a heartbeat.

This patch should be pretty much bugfree, but it exposes bugs in other
code, I believe. The client may crash (rare) due to some code that Vasco
plans to remove soon, so didn't bother trying to fix it. I am not 100%
sure that specials are handled correctly (all specials should probably be
removed).

Oh, and we need some real stats for the Antimatter ICBM before we even
think of putting it into cvs; and perhaps a real name :)

  - Per

Index: common/unittype.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unittype.c,v
retrieving revision 1.47
diff -u -r1.47 unittype.c
--- common/unittype.c   8 Dec 2004 14:36:22 -0000       1.47
+++ common/unittype.c   14 Dec 2004 00:46:10 -0000
@@ -47,7 +47,7 @@
   "Airbase", "Cities", "IgTired", "Missile_Carrier", "No_Land_Attack",
   "AddToCity", "Fanatic", "GameLoss", "Unique", "Unbribable", 
   "Undisbandable", "SuperSpy", "NoHome", "NoVeteran", "Bombarder",
-  "CityBuster", "NoBuild"
+  "CityBuster", "NoBuild", "Antimatter"
 };
 static const char *role_names[] = {
   "FirstBuild", "Explorer", "Hut", "HutTech", "Partisan",
@@ -446,11 +446,11 @@
 {
   Impr_Type_id impr_req;
   Tech_Type_id tech_req;
-
   CHECK_UNIT_TYPE(id);
   if (unit_type_flag(id, F_NUCLEAR)
-      && !get_player_bonus(p, EFT_ENABLE_NUKE) > 0)
+      && !get_player_bonus(p, EFT_ENABLE_NUKE) > 0) {
     return FALSE;
+  }
   if (unit_type_flag(id, F_NOBUILD)) {
     return FALSE;
   }
@@ -462,8 +462,9 @@
       && !government_has_flag(get_gov_pplayer(p), G_FANATIC_TROOPS)) {
     return FALSE;
   }
-  if (get_invention(p,unit_types[id].tech_requirement)!=TECH_KNOWN)
+  if (get_invention(p,unit_types[id].tech_requirement) != TECH_KNOWN) {
     return FALSE;
+  }
   if (unit_type_flag(id, F_UNIQUE)) {
     /* FIXME: This could be slow if we have lots of units. We could
      * consider keeping an array of unittypes updated with this info 
Index: common/unittype.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unittype.h,v
retrieving revision 1.38
diff -u -r1.38 unittype.h
--- common/unittype.h   8 Dec 2004 14:36:22 -0000       1.38
+++ common/unittype.h   14 Dec 2004 00:46:10 -0000
@@ -117,6 +117,7 @@
   F_BOMBARDER,        /* Has the ability to bombard */
   F_CITYBUSTER,       /* Gets double firepower against cities */
   F_NOBUILD,          /* Unit cannot be built (barb leader etc) */
+  F_ANTIMATTER,       /* Antimatter attack effect */
   F_LAST
 };
 #define F_MAX 64
Index: data/default/buildings.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/buildings.ruleset,v
retrieving revision 1.61
diff -u -r1.61 buildings.ruleset
--- data/default/buildings.ruleset      4 Dec 2004 09:27:00 -0000       1.61
+++ data/default/buildings.ruleset      14 Dec 2004 00:46:11 -0000
@@ -1829,7 +1829,7 @@
 
 [building_manhattan_project]
 name           = _("Manhattan Project")
-tech_req       = "Nuclear Fission"
+tech_req       = "None"
 bldg_req       = "None"
 graphic        = "b.manhattan_project"
 graphic_alt    = "-"
@@ -1840,7 +1840,7 @@
 ;equiv_repl    =
 obsolete_by    = "None"
 is_wonder      = 1
-build_cost     = 600
+build_cost     = 20
 upkeep         = 0
 sabotage       = 0
 effect         =
Index: data/default/units.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/units.ruleset,v
retrieving revision 1.65
diff -u -r1.65 units.ruleset
--- data/default/units.ruleset  8 Dec 2004 14:36:22 -0000       1.65
+++ data/default/units.ruleset  14 Dec 2004 00:46:11 -0000
@@ -1500,7 +1500,7 @@
 [unit_nuclear]
 name          = _("Nuclear")
 move_type     = "Air"
-tech_req      = "Rocketry"
+tech_req      = "Writing"
 obsolete_by   = "None"
 graphic       = "u.nuclear"
 graphic_alt   = "-"
@@ -1544,6 +1544,38 @@
  chance of nuclear winter.  Eco-friendly nukes!\
 ")
 
+[unit_antimatter]
+name          = _("Antimatter ICBM")
+move_type     = "Air"
+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    = 20
+pop_cost      = 0
+attack        = 99
+defense       = 0
+hitpoints     = 10
+firepower     = 1
+move_rate     = 48
+vision_range  = 1
+transport_cap = 0
+fuel          = 1
+uk_happy      = 1
+uk_shield     = 1
+uk_food       = 0
+uk_gold       = 0
+flags         = "FieldUnit", "OneAttack", "Missile", "Nuclear", "Antimatter"
+roles         = ""
+helptext      = _("\
+You can build Antimatter units whenever you want!  They pretty much\
+ kill everything, so use them first!\
+")
+
 [unit_diplomat]
 name          = _("Diplomat")
 move_type     = "Land"
Index: data/trident/units.png
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/trident/units.png,v
retrieving revision 1.3
diff -u -r1.3 units.png
Binary files /tmp/cvsFHza5K and units.png differ
Index: server/diplhand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/diplhand.h,v
retrieving revision 1.11
diff -u -r1.11 diplhand.h
--- server/diplhand.h   3 Sep 2004 04:22:37 -0000       1.11
+++ server/diplhand.h   14 Dec 2004 00:46:12 -0000
@@ -13,7 +13,8 @@
 #ifndef FC__DIPLHAND_H
 #define FC__DIPLHAND_H
 
-#define REPUTATION_LOSS_NUKE (GAME_MAX_REPUTATION * 0.03)
+#define REPUTATION_LOSS_NUKE (GAME_MAX_REPUTATION * 0.06)
+#define REPUTATION_LOSS_ANTIMATTER (GAME_MAX_REPUTATION * 0.3)
 
 #include "fc_types.h"
 
Index: server/unithand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v
retrieving revision 1.317
diff -u -r1.317 unithand.c
--- server/unithand.c   8 Dec 2004 04:28:27 -0000       1.317
+++ server/unithand.c   14 Dec 2004 00:46:12 -0000
@@ -743,9 +743,11 @@
   }
 
   if (unit_flag(punit, F_NUCLEAR)) {
+    bool antimatter = unit_flag(punit, F_ANTIMATTER);
+
     if ((pcity = sdi_defense_close(unit_owner(punit), def_tile))) {
       notify_player_ex(pplayer, punit->tile, E_UNIT_LOST_ATT,
-                      _("Game: Your Nuclear missile was shot down by"
+                      _("Game: Your nuclear missile was shot down by"
                         " SDI defences, what a waste."));
       notify_player_ex(city_owner(pcity), def_tile, E_UNIT_WIN,
                       _("Game: The nuclear attack on %s was avoided by"
@@ -758,7 +760,7 @@
                                 def_tile->y);
 
     wipe_unit(punit);
-    do_nuclear_explosion(pplayer, def_tile);
+    do_nuclear_explosion(pplayer, def_tile, antimatter);
     return;
   }
   moves_used = unit_move_rate(punit) - punit->moves_left;
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.313
diff -u -r1.313 unittools.c
--- server/unittools.c  9 Dec 2004 16:38:35 -0000       1.313
+++ server/unittools.c  14 Dec 2004 00:46:12 -0000
@@ -1990,7 +1990,8 @@
   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 = map_get_city(ptile);
 
@@ -2009,7 +2010,7 @@
     wipe_unit_spec_safe(punit, FALSE);
   } unit_list_iterate_end;
 
-  if (pcity) {
+  if (pcity && !antimatter) {
     notify_player_ex(city_owner(pcity),
                     ptile, E_CITY_NUKED,
                     _("Game: %s was nuked by %s."),
@@ -2024,6 +2025,16 @@
     }
 
     city_reduce_size(pcity, pcity->size / 2);
+  } else if (pcity && antimatter) {
+    notify_player_ex(city_owner(pcity), ptile, E_CITY_NUKED,
+                    _("Game: %s was obliterated by %s."),
+                    pcity->name, pplayer == city_owner(pcity) 
+                      ? _("yourself") : pplayer->name);
+    if (city_owner(pcity) != pplayer) {
+      notify_player_ex(pplayer, ptile, E_CITY_NUKED,
+                      _("Game: You obliterated %s."), pcity->name);
+    }
+    remove_city(pcity);
   }
 
   if (!is_ocean(map_get_terrain(ptile)) && myrand(2) == 1) {
@@ -2045,19 +2056,52 @@
   Nuke all the squares in a 3x3 square around the center of the explosion
   pplayer is the player that caused the explosion. You lose reputation
   each time.
+
+  Antimatter explosions leave an ocean in the middle and turns some 
+  terrain into swamps.
 **************************************************************************/
-void do_nuclear_explosion(struct player *pplayer, struct tile *ptile)
+void do_nuclear_explosion(struct player *pplayer, struct tile *ptile,
+                          bool antimatter)
 {
-  square_iterate(ptile, 1, ptile1) {
-    do_nuke_tile(pplayer, ptile1);
-  } square_iterate_end;
+  if (antimatter) {
+    Terrain_type_id old = map_get_terrain(ptile);
+    Terrain_type_id new = -1;
+
+    terrain_type_iterate(id) {
+      if (is_ocean(id)) {
+        new = id;
+      }
+    } terrain_type_iterate_end;
+
+    /* We use this iterator here to avoid a clean square */
+    map_city_radius_iterate(ptile, ptile1) {
+      do_nuke_tile(pplayer, ptile1, TRUE);
+      if (new != 1) {
+        old = map_get_terrain(ptile1);
+        if (myrand(4) == 0) {
+          change_terrain(ptile1, new);
+          (void) check_terrain_ocean_land_change(ptile1, old);
+        }
+      }
+    } map_city_radius_iterate_end;
+  } else {
+    square_iterate(ptile, 1, ptile1) {
+      do_nuke_tile(pplayer, ptile1, FALSE);
+    } square_iterate_end;
+  }
 
   /* Give reputation penalty to nuke users */
-  pplayer->reputation = MAX(pplayer->reputation - REPUTATION_LOSS_NUKE, 0);
+  if (antimatter) {
+    pplayer->reputation = MAX(pplayer->reputation 
+                              - REPUTATION_LOSS_ANTIMATTER, 0);
+    notify_conn_ex(&game.game_connections, ptile, E_NUKE,
+                  _("Game: %s detonated an antimatter bomb!"), pplayer->name);
+  } else {
+    pplayer->reputation = MAX(pplayer->reputation - REPUTATION_LOSS_NUKE, 0);
+    notify_conn_ex(&game.game_connections, ptile, E_NUKE,
+                  _("Game: %s detonated a nuke!"), pplayer->name);
+  }
   send_player_info(pplayer, NULL);
-
-  notify_conn_ex(&game.game_connections, ptile, E_NUKE,
-                _("Game: %s detonated a nuke!"), pplayer->name);
 }
 
 /**************************************************************************
Index: server/unittools.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.h,v
retrieving revision 1.71
diff -u -r1.71 unittools.h
--- server/unittools.h  29 Sep 2004 02:24:24 -0000      1.71
+++ server/unittools.h  14 Dec 2004 00:46:12 -0000
@@ -74,7 +74,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 try_move_unit(struct unit *punit, struct tile *ptile); 
 bool do_airline(struct unit *punit, struct city *city2);
 bool do_paradrop(struct unit *punit, struct tile *ptile);

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