Skip to content

Commit

Permalink
Fix: Major overhaul of zap/explosion types.
Browse files Browse the repository at this point in the history
This combines EvilHack commits db2e58b253 and f141d95a31. I'm very excited the EvilHack team started this project because it has been much needed for any fork that wants to add new zap types.

I added a few more macros to clarify things and tried to tidy up the zap code wherever possible.
  • Loading branch information
elunna committed Sep 23, 2023
1 parent 22bac0c commit 5cb059f
Show file tree
Hide file tree
Showing 19 changed files with 167 additions and 145 deletions.
36 changes: 36 additions & 0 deletions include/hack.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,42 @@ enum bhit_call_types {
INVIS_BEAM = 5
};

/* Zap Type definitions, formerly in zap.c */
#define ZT_MAGIC_MISSILE (AD_MAGM - 1)
#define ZT_FIRE (AD_FIRE - 1)
#define ZT_COLD (AD_COLD - 1)
#define ZT_SLEEP (AD_SLEE - 1)
#define ZT_DEATH (AD_DISN - 1) /* or disintegration */
#define ZT_LIGHTNING (AD_ELEC - 1)
#define ZT_POISON_GAS (AD_DRST - 1)
#define ZT_ACID (AD_ACID - 1)
#define ZT_SONIC (AD_LOUD - 1)
#define ZT_WATER (AD_WATR - 1)

#define MAX_ZT (ZT_WATER + 1)

#define BASE_ZT(x) ((x) % MAX_ZT)

/* convert 1..11 to 0..10 */
#define AD_to_ZT(k) ((int) k - 1)
/* do the same and then add MAX_ZT for spells */
#define AD_to_SPELL(k) BASE_ZT(AD_to_ZT((k)))

/* Converts a zap type (ie: ZT_FIRE) to it's wand, spell, or breath equivalent.
* Example: ZT_WAND(ZT_FIRE) or ZT_SPELL(ZT_FIRE)
* NOT for AD_TYPES, ex: ZT_WAND(AD_FIRE)
*/
#define ZT_WAND(x) (x)
#define ZT_SPELL(x) (MAX_ZT + (x))
#define ZT_BREATH(x) (MAX_ZT + MAX_ZT + (x))
#define ZT_MONSPELL(x) (-((MAX_ZT*2) + x))
#define ZT_MONWAND(x) (-((MAX_ZT*3) + x))

#define FIRST_WAND (WAN_MAGIC_MISSILE)
#define LAST_WAND (WAN_DELUGE)
#define FIRST_SPELLBOOK (SPE_MAGIC_MISSILE)
#define LAST_SPELLBOOK (SPE_SONICBOOM)

/* attack mode for hmon() */
enum hmon_atkmode_types {
HMON_MELEE = 0, /* hand-to-hand */
Expand Down
10 changes: 5 additions & 5 deletions src/artifact.c
Original file line number Diff line number Diff line change
Expand Up @@ -1710,10 +1710,10 @@ int dieroll; /* needed for Magicbane and vorpal blades */
if (!rn2(3)) {
pline("The world shakes!");
if (youattack && can_we_zap(u.dx, u.dy, 13)) {
dobuzz((int) (20 + (AD_ELEC - 1)), 3, u.ux, u.uy,
dobuzz((int) ZT_SPELL(ZT_LIGHTNING), 3, u.ux, u.uy,
u.dx, u.dy, TRUE);
} else {
dobuzz((int) (-20 - (AD_ELEC - 1)), 3, magr->mx,
dobuzz((int) -ZT_SPELL(ZT_LIGHTNING), 3, magr->mx,
magr->my, mdx, mdy, TRUE);
}
}
Expand Down Expand Up @@ -1766,10 +1766,10 @@ int dieroll; /* needed for Magicbane and vorpal blades */
* 2d6 - same as a wand. */
if (rn2(4)) {
if (youattack && (u.uhp == u.uhpmax) && can_we_zap(u.dx, u.dy, 13)) {
dobuzz((int) (20 + (AD_MAGM - 1)), 2, u.ux, u.uy, u.dx,
dobuzz((int) ZT_SPELL(ZT_MAGIC_MISSILE), 2, u.ux, u.uy, u.dx,
u.dy, TRUE);
} else if (magr && magr->mhp == magr->mhpmax) {
dobuzz((int) (-20 - (AD_MAGM - 1)), 2, magr->mx, magr->my,
dobuzz((int) -ZT_SPELL(ZT_MAGIC_MISSILE), 2, magr->mx, magr->my,
mdx, mdy, TRUE);
}
}
Expand Down Expand Up @@ -3246,7 +3246,7 @@ struct obj *obj;
struct obj* pseudo = mksobj(WAN_LIGHTNING, FALSE, FALSE);
pseudo->blessed = pseudo->cursed = 0;
/* type is a "spell of lightning bolt" which doesn't actually
* exist: 10 + AD_ELEC - 1 */
* exist: 10 + ZT_LIGHTNING */
if(!getdir(NULL) || (!u.dx && !u.dy && !u.dz)) {
int damage = zapyourself(pseudo, TRUE);
if (damage > 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -2039,7 +2039,7 @@ zapdir_to_glyph(dx, dy, beam_type)
register int dx, dy;
int beam_type;
{
if (beam_type >= NUM_ZAP) {
if (beam_type > NUM_ZAP) {
impossible("zapdir_to_glyph: illegal beam type");
beam_type = 0;
}
Expand Down
4 changes: 1 addition & 3 deletions src/dothrow.c
Original file line number Diff line number Diff line change
Expand Up @@ -2253,14 +2253,12 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */
exercise(A_DEX, TRUE);

/* Detonate bolts shot by Hellfire */
#define ZT_FIRE (10 + (AD_FIRE - 1))
if (hellfiring && ammo_and_launcher(obj, uwep)) {

if (cansee(bhitpos.x, bhitpos.y))
pline("%s explodes in a ball of fire!", Doname2(obj));
else
You_hear("an explosion");
explode(bhitpos.x, bhitpos.y, ZT_FIRE, d(2, 6),
explode(bhitpos.x, bhitpos.y, ZT_SPELL(ZT_FIRE), d(2, 6),
WEAPON_CLASS, EXPL_FIERY);
}

Expand Down
20 changes: 9 additions & 11 deletions src/explode.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ int expltype;
other types produce a generic magical explosion */
if (objects[type].oc_dir == RAY
&& type != WAN_DIGGING && type != WAN_DELUGE && type != WAN_SLEEP) {
type -= WAN_MAGIC_MISSILE;
if (type < 0 || type > 9) {
type -= FIRST_WAND;
if (type < 0 || type > MAX_ZT) {
impossible("explode: wand has bad zap type (%d).", type);
type = 0;
}
Expand Down Expand Up @@ -148,7 +148,7 @@ int expltype;
/* If str is e.g. "flaming sphere's explosion" from above, we want to
* still assign adtyp appropriately, but not replace str. */
const char *adstr = NULL;
switch (abs(type) % 10) {
switch (BASE_ZT(abs(type))) {
case 0:
adstr = (olet == SPIRIT_CLASS) ? "soul blast" : "magical blast";
adtyp = AD_MAGM;
Expand Down Expand Up @@ -934,9 +934,7 @@ boolean diluted_oil;
{
int dmg = d(diluted_oil ? 3 : 4, 4);

/* ZT_SPELL(ZT_FIRE) = ZT_SPELL(AD_FIRE-1) = 10+(2-1) = 11 */
#define ZT_SPELL_O_FIRE 11 /* value kludge, see zap.c */
explode(x, y, ZT_SPELL_O_FIRE, dmg, BURNING_OIL, EXPL_FIERY);
explode(x, y, ZT_SPELL(ZT_FIRE), dmg, BURNING_OIL, EXPL_FIERY);
}

/* lit potion of oil is exploding; extinguish it as a light source before
Expand Down Expand Up @@ -1011,12 +1009,12 @@ struct attack *mattk;

if (mattk->adtyp == AD_PHYS) {
type = PHYS_EXPL_TYPE;
} else if (mattk->adtyp >= AD_MAGM && mattk->adtyp <= AD_PSYC) {
/* The -1, +20, *-1 math is to set it up as a 'monster breath' type for
* the explosions (it isn't, but this is the closest analogue). */
type = -((mattk->adtyp - 1) + 20);
} else if (mattk->adtyp >= AD_MAGM && mattk->adtyp <= AD_WATR) {
/* Set it up as a 'monster breath' type for the explosions (it isn't,
* but this is the closest analogue). */
type = -(ZT_BREATH(mattk->adtyp - 1));
} else {
impossible("unknown type for mon_explode %d", mattk->adtyp);
impossible("unknown type for mon_explodes %d", mattk->adtyp);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/fountain.c
Original file line number Diff line number Diff line change
Expand Up @@ -1219,7 +1219,7 @@ int x, y;
levl[x][y].doormask = 0;
newsym(x, y);
level.flags.nforges--;
explode(u.ux, u.uy, AD_FIRE - 1, resist_reduce(rnd(30), FIRE_RES),
explode(u.ux, u.uy, ZT_FIRE, resist_reduce(rnd(30), FIRE_RES),
FORGE_EXPLODE, EXPL_FIERY);
maybe_unhide_at(x, y);
}
Expand Down
28 changes: 13 additions & 15 deletions src/mcastu.c
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ int spellnum;
if (m_canseeu(mtmp)
&& distu(mtmp->mx, mtmp->my) <= (ml < mcastrange(ml))) {
pline("%s douses you in a torrent of acid!", Monnam(mtmp));
explode(u.ux, u.uy, AD_ACID - 1, d((ml / 2) + 4, 8),
explode(u.ux, u.uy, ZT_ACID, d((ml / 2) + 4, 8),
MON_CASTBALL, EXPL_ACID);
if (how_resistant(ACID_RES) == 100) {
shieldeff(u.ux, u.uy);
Expand Down Expand Up @@ -869,8 +869,8 @@ int spellnum;
if (m_canseeu(mtmp) && distu(mtmp->mx, mtmp->my) <= mcastrange(ml)) {
pline("%s blasts you with %s!", Monnam(mtmp),
(spellnum == MGC_FIRE_BOLT) ? "fire" : "ice");
explode(u.ux, u.uy, (spellnum == MGC_FIRE_BOLT) ? AD_FIRE - 1
: AD_COLD - 1,
explode(u.ux, u.uy, (spellnum == MGC_FIRE_BOLT) ? ZT_FIRE
: ZT_COLD,
resist_reduce(d((ml / 5) + 1, 8),
(spellnum == MGC_FIRE_BOLT) ? FIRE_RES : COLD_RES),
MON_CASTBALL, (spellnum == MGC_FIRE_BOLT) ? EXPL_FIERY
Expand Down Expand Up @@ -1537,8 +1537,6 @@ int spellnum;
return FALSE;
}

/* convert 1..10 to 0..9; add 10 for second group (spell casting) */
#define ad_to_typ(k) (10 + (int) k - 1)

/* monster uses spell against player (ranged) */
int
Expand All @@ -1555,13 +1553,13 @@ register struct attack *mattk;
cursetxt(mtmp, FALSE);
return 0;
}
if (lined_up(mtmp) && rn2(3)) {
if (lined_up(mtmp) && !rn2(3)) {
nomul(0);
if (mattk->adtyp && (mattk->adtyp < 11)) { /* no cf unsigned > 0 */
if (mattk->adtyp && (mattk->adtyp <= MAX_ZT)) { /* no cf unsigned > 0 */
if (canseemon(mtmp))
pline("%s zaps you with a %s!", Monnam(mtmp),
flash_types[ad_to_typ(mattk->adtyp) - 10]);
buzz(-ad_to_typ(mattk->adtyp), (int) mattk->damn, mtmp->mx,
flash_types[AD_to_ZT(mattk->adtyp)]);
buzz(ZT_MONSPELL(AD_to_ZT(mattk->adtyp)), (int) mattk->damn, mtmp->mx,
mtmp->my, sgn(tbx), sgn(tby));
} else
impossible("Monster spell %d cast", mattk->adtyp - 1);
Expand All @@ -1587,11 +1585,11 @@ register struct attack *mattk;
}
if (mlined_up(mtmp, mdef, FALSE) && rn2(3)) {
nomul(0);
if (mattk->adtyp && (mattk->adtyp < 11)) { /* no cf unsigned > 0 */
if (mattk->adtyp && (mattk->adtyp <= MAX_ZT)) { /* no cf unsigned > 0 */
if (canseemon(mtmp))
pline("%s zaps %s with a %s!", Monnam(mtmp),
mon_nam(mdef), flash_types[ad_to_typ(mattk->adtyp) - 10]);
dobuzz(-ad_to_typ(mattk->adtyp), (int) mattk->damn, mtmp->mx,
mon_nam(mdef), flash_types[AD_to_ZT(mattk->adtyp)]);
dobuzz(-AD_to_SPELL(mattk->adtyp), (int) mattk->damn, mtmp->mx,
mtmp->my, sgn(tbx), sgn(tby), FALSE);
} else
impossible("Monster spell %d cast", mattk->adtyp - 1);
Expand Down Expand Up @@ -2114,7 +2112,7 @@ int spellnum;
}
if (yours || canseemon(mtmp))
You("douse %s in a torrent of acid!", mon_nam(mtmp));
explode(mtmp->mx, mtmp->my, AD_ACID - 1, d((u.ulevel / 2) + 4, 8),
explode(mtmp->mx, mtmp->my, ZT_ACID, d((u.ulevel / 2) + 4, 8),
WAND_CLASS, EXPL_ACID);
if (resists_acid(mtmp) || defended(mtmp, AD_ACID)) {
shieldeff(mtmp->mx, mtmp->my);
Expand Down Expand Up @@ -2305,8 +2303,8 @@ int spellnum;
if (yours || canseemon(mtmp)) {
You("blast %s with %s!", mon_nam(mtmp),
(spellnum == MGC_FIRE_BOLT) ? "fire" : "ice");
explode(mtmp->mx, mtmp->my, (spellnum == MGC_FIRE_BOLT) ? AD_FIRE - 1
: AD_COLD - 1,
explode(mtmp->mx, mtmp->my,
(spellnum == MGC_FIRE_BOLT) ? ZT_FIRE : ZT_COLD,
d((u.ulevel / 5) + 1, 8), WAND_CLASS, 1);
if (spellnum == MGC_FIRE_BOLT
&& (resists_fire(mtmp) || defended(mtmp, AD_FIRE))) {
Expand Down
9 changes: 4 additions & 5 deletions src/mthrowu.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,14 @@ int x, y;
}

/* D: Detonate crossbow bolts from Hellfire if they hit */
#define ZT_FIRE (10 + (AD_FIRE - 1))
if (ohit && mwep && mwep->oartifact == ART_HELLFIRE
&& is_ammo(obj) && ammo_and_launcher(obj, mwep)) {
if (cansee(bhitpos.x, bhitpos.y))
pline("%s explodes in a ball of fire!", Doname2(obj));
else
You_hear("an explosion");

explode(bhitpos.x, bhitpos.y, -ZT_FIRE, d(2, 6), WEAPON_CLASS,
explode(bhitpos.x, bhitpos.y, -ZT_SPELL(ZT_FIRE), d(2, 6), WEAPON_CLASS,
EXPL_FIERY);

/* D: Exploding bolts will be destroyed */
Expand Down Expand Up @@ -1186,7 +1185,7 @@ struct attack *mattk;
if ((typ >= AD_MAGM) && (typ <= AD_WATR)) {
if (canseemon(mtmp))
pline("%s breathes %s!", Monnam(mtmp), breathwep[typ - 1]);
dobuzz((int) (-20 - (typ - 1)), (int) mattk->damn,
dobuzz((int) -ZT_BREATH(typ - 1), (int) mattk->damn,
mtmp->mx, mtmp->my, sgn(tbx), sgn(tby), FALSE);
nomul(0);
/* breath runs out sometimes. Also, give monster some
Expand Down Expand Up @@ -1423,7 +1422,7 @@ breamu(mtmp, mattk)
struct monst *mtmp;
struct attack *mattk;
{
/* if new breath types are added, change AD_ACID to max type */
/* if new breath types are added, change max type */
int typ = (mattk->adtyp == AD_RBRE) ? rnd(AD_WATR) : mattk->adtyp;

if (lined_up(mtmp)) {
Expand All @@ -1441,7 +1440,7 @@ struct attack *mattk;
if (canseemon(mtmp))
pline("%s breathes %s!", Monnam(mtmp),
breathwep[typ - 1]);
buzz((int) (-20 - (typ - 1)), (int) mattk->damn, mtmp->mx,
buzz((int) -ZT_BREATH(typ - 1), (int) mattk->damn, mtmp->mx,
mtmp->my, sgn(tbx), sgn(tby));
nomul(0);
/* breath runs out sometimes. Also, give monster some
Expand Down
21 changes: 10 additions & 11 deletions src/muse.c
Original file line number Diff line number Diff line change
Expand Up @@ -2606,7 +2606,7 @@ struct monst *mtmp;
if (oseen)
makeknown(otmp->otyp);
m_using = TRUE;
buzz((int) (-30 - (otmp->otyp - WAN_MAGIC_MISSILE)),
buzz(ZT_MONWAND(otmp->otyp - WAN_MAGIC_MISSILE),
(otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6, mtmp->mx, mtmp->my,
sgn(tbx), sgn(tby));
m_using = FALSE;
Expand All @@ -2616,9 +2616,8 @@ struct monst *mtmp;
case MUSE_HORN_OF_BLASTING:
mplayhorn(mtmp, otmp, FALSE);
m_using = TRUE;
buzz(-30 - ((otmp->otyp == FROST_HORN) ? AD_COLD - 1 :
(otmp->otyp == HORN_OF_BLASTING) ? AD_LOUD - 1 : AD_FIRE - 1),
mtmp->m_lev, mtmp->mx, mtmp->my, sgn(tbx),
buzz(ZT_MONWAND((otmp->otyp == FROST_HORN) ? ZT_COLD : ZT_FIRE),
rn1(6, 6), mtmp->mx, mtmp->my, sgn(tbx),
sgn(tby));
m_using = FALSE;
return (DEADMONSTER(mtmp)) ? 1 : 2;
Expand Down Expand Up @@ -4405,8 +4404,9 @@ boolean by_you; /* true: if mon kills itself, hero gets credit/blame */
pline("%s breathes fire on %sself.", Monnam(mon), mhim(mon));
if (!rn2(3))
mon->mspec_used = rn1(10, 5);
/* -21 => monster's fire breath; 1 => # of damage dice */
dmg = zhitm(mon, by_you ? 21 : -21, 1, &odummyp);
/* 1 => # of damage dice */
dmg = zhitm(mon, by_you ? ZT_BREATH(ZT_FIRE) : -ZT_BREATH(ZT_FIRE),
1, &odummyp);
} else if (otyp == SCR_FIRE) {
mreadmsg(mon, obj);
if (mon->mconf) {
Expand All @@ -4421,9 +4421,7 @@ boolean by_you; /* true: if mon kills itself, hero gets credit/blame */
} else {
dmg = (2 * (rn1(3, 3) + 2 * bcsign(obj)) + 1) / 3;
m_useup(mon, obj); /* before explode() */
/* -11 => monster's fireball */
explode(mon->mx, mon->my, -11, dmg, SCROLL_CLASS,
/* by_you: override -11 for mon but not others */
explode(mon->mx, mon->my, -ZT_SPELL(ZT_FIRE), dmg, SCROLL_CLASS,
by_you ? -EXPL_FIERY : EXPL_FIERY);
dmg = 0; /* damage has been applied by explode() */
}
Expand All @@ -4432,8 +4430,9 @@ boolean by_you; /* true: if mon kills itself, hero gets credit/blame */
mplayhorn(mon, obj, TRUE);
else
mzapwand(mon, obj, TRUE);
/* -1 => monster's wand of fire; 2 => # of damage dice */
dmg = zhitm(mon, by_you ? 1 : -1, 2, &odummyp);
/* 2 => # of damage dice */
dmg = zhitm(mon, by_you ? ZT_WAND(ZT_FIRE) : -ZT_WAND(ZT_FIRE),
2, &odummyp);
}

if (dmg) {
Expand Down
4 changes: 2 additions & 2 deletions src/music.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,8 +675,8 @@ struct obj *instr;
"PWAAAAOOMP!"};
if (!Deaf) pline("%s", blasting_msg[rn2(3)]);
}
buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 :
(instr->otyp == HORN_OF_BLASTING) ? AD_LOUD - 1 : AD_FIRE - 1,
buzz((instr->otyp == FROST_HORN) ? ZT_COLD :
(instr->otyp == HORN_OF_BLASTING) ? ZT_SONIC : ZT_FIRE,
u.ulevel, u.ux, u.uy, u.dx, u.dy);
}
/* makeknown(instr->otyp); */
Expand Down
13 changes: 5 additions & 8 deletions src/polyself.c
Original file line number Diff line number Diff line change
Expand Up @@ -1426,8 +1426,7 @@ rehumanize()
int
dobreathe()
{
struct attack *mattk;

struct attack *mattk;
if (Strangled) {
You_cant("breathe. Sorry.");
return 0;
Expand All @@ -1450,13 +1449,11 @@ dobreathe()
else if (youmonst.data == &mons[PM_CRYSTAL_GOLEM]) {
/* Extra handling for AD_RBRE - player might poly into a crystal
* golem. */
uchar adtyp;
adtyp = mattk->adtyp == AD_RBRE ? rnd(AD_ACID) : mattk->adtyp;
buzz((int) (20 + adtyp - 1), (int) mattk->damn, u.ux, u.uy, u.dx,
uchar adtyp = mattk->adtyp == AD_RBRE ? rnd(AD_WATR) : mattk->adtyp;
buzz((int) ZT_BREATH(AD_to_ZT(adtyp)), (int) mattk->damn, u.ux, u.uy, u.dx,
u.dy);
}
else
buzz((int) (20 + mattk->adtyp - 1), (int) mattk->damn, u.ux, u.uy,
} else
buzz((int) ZT_BREATH(AD_to_ZT(mattk->adtyp)), (int) mattk->damn, u.ux, u.uy,
u.dx, u.dy);
return 1;
}
Expand Down
2 changes: 1 addition & 1 deletion src/potion.c
Original file line number Diff line number Diff line change
Expand Up @@ -3514,7 +3514,7 @@ dodip()
/* Turn off engine before fueling, turn off fuel too :-) */
if (obj->lamplit || potion->lamplit) {
useup(potion);
explode(u.ux, u.uy, 11, d(6, 6), 0, EXPL_FIERY);
explode(u.ux, u.uy, ZT_SPELL(ZT_FIRE), d(6, 6), 0, EXPL_FIERY);
exercise(A_WIS, FALSE);
return 1;
}
Expand Down
2 changes: 1 addition & 1 deletion src/priest.c
Original file line number Diff line number Diff line change
Expand Up @@ -895,7 +895,7 @@ struct monst *priest;
break;
}

buzz(-10 - (AD_ELEC - 1), 6, x, y, sgn(tbx),
buzz(-(ZT_SPELL(ZT_LIGHTNING)), 6, x, y, sgn(tbx),
sgn(tby)); /* bolt of lightning */
exercise(A_WIS, FALSE);
}
Expand Down
Loading

0 comments on commit 5cb059f

Please sign in to comment.