2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2010, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * See files README, COPYING and CREDITS in the root of the source
23 * tree for related information and legal notices. It is expected
24 * that future projects/authors will amend these files as needed.
28 * detonate.c: Detonate a nuclear device in a sector.
30 * Known contributors to this file:
31 * Steve McClure, 1998-2000
32 * Markus Armbruster, 2004-2009
49 #include "prototypes.h"
54 static void kaboom(int x, int y, int rad);
57 detonate(struct nukstr *np, coord x, coord y, int airburst)
59 int nuketype = np->nuk_type;
75 pr("Releasing RV's for %s detonation...\n",
76 airburst ? "airburst" : "groundburst");
79 ncp = &nchr[nuketype];
80 kaboom(x, y, ncp->n_blast);
84 if (sect.sct_type == SCT_WATER)
85 rad = 0; /* Nukes falling on water affect only 1 sector */
87 putnuke(np->nuk_uid, np);
89 snxtsct_dist(&ns, x, y, rad);
90 while (nxtsct(&ns, §)) {
93 if ((damage = nukedamage(ncp, ns.curdist, airburst)) <= 0)
95 if (type == SCT_SANCT) {
96 pr("bounced off %s\n", xyas(ns.x, ns.y, player->cnum));
97 mpr(own, "%s nuclear device bounced off %s\n",
98 cname(player->cnum), xyas(ns.x, ns.y, own));
99 nreport(player->cnum, N_NUKE, own, 1);
102 sect_damage(§, damage);
104 fallout = sect.sct_fallout;
105 if (ncp->n_flags & N_NEUT)
106 fallout += damage * 30;
108 fallout += damage * 3;
109 sect.sct_fallout = MIN(fallout, FALLOUT_MAX);
114 if (type == SCT_WATER || type == SCT_BSPAN ||
115 type == SCT_BTOWER) {
116 if (type != SCT_WATER) {
117 pr("left nothing but water in %s\n",
118 xyas(ns.x, ns.y, player->cnum));
119 if (own != player->cnum)
121 "%s nuclear device left nothing but water in %s\n",
122 cname(player->cnum), xyas(ns.x, ns.y, own));
123 sect.sct_newtype = SCT_WATER;
124 sect.sct_type = SCT_WATER;
127 sect.sct_newtype = SCT_WASTE;
128 sect.sct_type = SCT_WASTE;
129 pr("turned %s into a radioactive wasteland\n",
130 xyas(ns.x, ns.y, player->cnum));
131 if (own != player->cnum)
133 "%s nuclear device turned %s into a radioactive wasteland\n",
134 cname(player->cnum), xyas(ns.x, ns.y, own));
136 changed |= map_set(player->cnum, sect.sct_x, sect.sct_y,
137 dchr[sect.sct_type].d_mnem, 0);
139 pr("did %d%% damage in %s\n",
140 damage, xyas(ns.x, ns.y, player->cnum));
141 if (own != player->cnum)
142 mpr(own, "%s nuclear device did %d%% damage in %s\n",
143 cname(player->cnum), damage, xyas(ns.x, ns.y, own));
145 (void)putsect(§);
146 if (type != SCT_WATER)
147 nreport(player->cnum, N_NUKE, own, 1);
151 writebmap(player->cnum);
153 snxtitem_dist(&ni, EF_PLANE, x, y, rad);
154 while (nxtitem(&ni, &plane)) {
155 if ((own = plane.pln_own) == 0)
157 if (plane.pln_flags & PLN_LAUNCHED)
159 damage = nukedamage(ncp, ni.curdist, airburst) - plane.pln_harden;
162 if (plane.pln_ship >= 0) {
163 /* Are we on a sub? */
164 getship(plane.pln_ship, &ship);
166 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
169 /* Should we damage this sub? */
170 getsect(ship.shp_x, ship.shp_y, §1);
172 if (sect1.sct_type == SCT_BSPAN ||
173 sect1.sct_type == SCT_BTOWER ||
174 sect1.sct_type == SCT_WATER) {
175 /* Ok, we're not in a harbor or trapped
176 inland. Now, did we get pasted
178 if (ship.shp_x != x || ship.shp_y != y) {
179 /* Nope, so don't mess with it */
185 planedamage(&plane, damage);
186 if (own == player->cnum) {
187 pr("%s at %s reports %d%% damage\n",
189 xyas(plane.pln_x, plane.pln_y, own), damage);
191 mpr(own, "%s nuclear device did %d%% damage to %s at %s\n",
192 cname(player->cnum), damage,
193 prplane(&plane), xyas(plane.pln_x, plane.pln_y, own));
195 putplane(ni.cur, &plane);
198 snxtitem_dist(&ni, EF_LAND, x, y, rad);
199 while (nxtitem(&ni, &land)) {
200 if ((own = land.lnd_own) == 0)
202 if ((damage = nukedamage(ncp, ni.curdist, airburst)) <= 0)
205 if (land.lnd_ship >= 0) {
206 /* Are we on a sub? */
207 getship(land.lnd_ship, &ship);
209 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
212 /* Should we damage this sub? */
213 getsect(ship.shp_x, ship.shp_y, §1);
215 if (sect1.sct_type == SCT_BSPAN ||
216 sect1.sct_type == SCT_BTOWER ||
217 sect1.sct_type == SCT_WATER) {
218 /* Ok, we're not in a harbor or trapped
219 inland. Now, did we get pasted
221 if (ship.shp_x != x || ship.shp_y != y) {
222 /* Nope, so don't mess with it */
228 land_damage(&land, damage);
229 if (own == player->cnum) {
230 pr("%s at %s reports %d%% damage\n",
231 prland(&land), xyas(land.lnd_x, land.lnd_y, own), damage);
233 mpr(own, "%s nuclear device did %d%% damage to %s at %s\n",
234 cname(player->cnum), damage,
235 prland(&land), xyas(land.lnd_x, land.lnd_y, own));
237 putland(land.lnd_uid, &land);
240 snxtitem_dist(&ni, EF_SHIP, x, y, rad);
241 while (nxtitem(&ni, &ship)) {
242 if ((own = ship.shp_own) == 0)
244 if ((damage = nukedamage(ncp, ni.curdist, airburst)) <= 0)
246 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
249 /* Should we damage this sub? */
250 getsect(ship.shp_x, ship.shp_y, §1);
252 if (sect1.sct_type == SCT_BSPAN ||
253 sect1.sct_type == SCT_BTOWER ||
254 sect1.sct_type == SCT_WATER) {
255 /* Ok, we're not in a harbor or trapped
256 inland. Now, did we get pasted
258 if (ship.shp_x != x || ship.shp_y != y) {
259 /* Nope, so don't mess with it */
264 ship_damage(&ship, damage);
265 if (own == player->cnum) {
266 pr("%s at %s reports %d%% damage\n",
267 prship(&ship), xyas(ship.shp_x, ship.shp_y, own), damage);
269 mpr(own, "%s nuclear device did %d%% damage to %s at %s\n",
270 cname(player->cnum), damage, prship(&ship),
271 xyas(ship.shp_x, ship.shp_y, own));
273 putship(ship.shp_uid, &ship);
276 snxtitem_dist(&ni, EF_NUKE, x, y, rad);
277 while (nxtitem(&ni, &nuke)) {
278 if ((own = nuke.nuk_own) == 0)
280 if ((damage = nukedamage(ncp, ni.curdist, airburst)) <= 0)
282 if (roll(100) >= damage)
285 if (own == player->cnum) {
286 pr("%s at %s destroyed\n",
287 prnuke(&nuke), xyas(nuke.nuk_x, nuke.nuk_y, own));
289 mpr(own, "%s nuclear device destroyed %s at %s\n",
290 cname(player->cnum), prnuke(&nuke),
291 xyas(nuke.nuk_x, nuke.nuk_y, own));
293 putnuke(ni.cur, &nuke);
296 return nukedamage(ncp, 0, airburst);
304 kaboom(int x, int y, int rad)
306 pr("\n\nK A B O O ");
309 pr("M ! in %s\n\n", xyas(x, y, player->cnum));