Buzz macros and related stuff

Add macros to convert AD_foo, WAN_foo, and SPE_foo to relative values
for passing to BZ_U_foo and BZ_M_foo macros.

Change some return values in monster spellcasting function from
magic numbers to MM_MISS or MM_HIT.

Make buzzmu consider hero resistances - previously the
monster with innate zapping ray (Angels and Asmodeus) would
just keep doing that attack, but they will now just curse if
it saw the hero resist the attack.
This commit is contained in:
Pasi Kallinen
2022-07-19 15:14:55 +03:00
parent 0bca93be87
commit d713c1826b
11 changed files with 58 additions and 38 deletions
+1
View File
@@ -3381,6 +3381,7 @@ extern struct monst *bhit(coordxy, coordxy, int, enum bhit_call_types,
extern struct monst *boomhit(struct obj *, coordxy, coordxy); extern struct monst *boomhit(struct obj *, coordxy, coordxy);
extern int zhitm(struct monst *, int, int, struct obj **); extern int zhitm(struct monst *, int, int, struct obj **);
extern int burn_floor_objects(coordxy, coordxy, boolean, boolean); extern int burn_floor_objects(coordxy, coordxy, boolean, boolean);
extern void ubuzz(int, int);
extern void buzz(int, int, coordxy, coordxy, int, int); extern void buzz(int, int, coordxy, coordxy, int, int);
extern void dobuzz(int, int, coordxy, coordxy, int, int, boolean); extern void dobuzz(int, int, coordxy, coordxy, int, int, boolean);
extern void melt_ice(coordxy, coordxy, const char *); extern void melt_ice(coordxy, coordxy, const char *);
+19
View File
@@ -642,6 +642,25 @@ enum getobj_callback_returns {
* it. */ * it. */
#define PHYS_EXPL_TYPE -1 #define PHYS_EXPL_TYPE -1
/* macros for dobuzz() type */
#define BZ_VALID_ADTYP(adtyp) ((adtyp) >= AD_MAGM && (adtyp) <= AD_SPC2)
#define BZ_OFS_AD(adtyp) (abs((adtyp) - AD_MAGM) % 10)
#define BZ_OFS_WAN(otyp) (abs((otyp) - WAN_MAGIC_MISSILE) % 10)
#define BZ_OFS_SPE(otyp) (abs((otyp) - SPE_MAGIC_MISSILE) % 10)
/* hero shooting a wand */
#define BZ_U_WAND(bztyp) (0 + (bztyp))
/* hero casting a spell */
#define BZ_U_SPELL(bztyp) (10 + (bztyp))
/* hero breathing as a monster */
#define BZ_U_BREATH(bztyp) (20 + (bztyp))
/* monster casting a spell */
#define BZ_M_SPELL(bztyp) (-10 - (bztyp))
/* monster breathing */
#define BZ_M_BREATH(bztyp) (-20 - (bztyp))
/* monster shooting a wand */
#define BZ_M_WAND(bztyp) (-30 - (bztyp))
/* /*
* option setting restrictions * option setting restrictions
*/ */
+2
View File
@@ -1203,6 +1203,7 @@ SCROLL("blank paper", "unlabeled", 0, 28, 60, SCR_BLANK_PAPER),
#define PAPER LEATHER /* override enum for use in SPELL() expansion */ #define PAPER LEATHER /* override enum for use in SPELL() expansion */
SPELL("dig", "parchment", SPELL("dig", "parchment",
P_MATTER_SPELL, 20, 6, 5, 1, RAY, HI_LEATHER, SPE_DIG), P_MATTER_SPELL, 20, 6, 5, 1, RAY, HI_LEATHER, SPE_DIG),
/* magic missile ... finger of death must be in this order; see buzz() */
SPELL("magic missile", "vellum", SPELL("magic missile", "vellum",
P_ATTACK_SPELL, 45, 2, 2, 1, RAY, HI_LEATHER, SPE_MAGIC_MISSILE), P_ATTACK_SPELL, 45, 2, 2, 1, RAY, HI_LEATHER, SPE_MAGIC_MISSILE),
#undef PAPER /* revert to normal material */ #undef PAPER /* revert to normal material */
@@ -1382,6 +1383,7 @@ WAND("probing", "uranium", 30, 150, 1, IMMEDIATE, METAL, HI_METAL,
WAN_PROBING), WAN_PROBING),
WAND("digging", "iron", 55, 150, 1, RAY, IRON, HI_METAL, WAND("digging", "iron", 55, 150, 1, RAY, IRON, HI_METAL,
WAN_DIGGING), WAN_DIGGING),
/* magic missile ... lightning must be in this order; see buzz() */
WAND("magic missile", "steel", 50, 150, 1, RAY, IRON, HI_METAL, WAND("magic missile", "steel", 50, 150, 1, RAY, IRON, HI_METAL,
WAN_MAGIC_MISSILE), WAN_MAGIC_MISSILE),
WAND("fire", "hexagonal", 40, 175, 1, RAY, IRON, HI_METAL, WAND("fire", "hexagonal", 40, 175, 1, RAY, IRON, HI_METAL,
+18 -23
View File
@@ -210,20 +210,20 @@ castmu(register struct monst *mtmp,
if (foundyou) if (foundyou)
impossible( impossible(
"spellcasting monster found you and doesn't know it?"); "spellcasting monster found you and doesn't know it?");
return 0; return MM_MISS;
} }
break; break;
} }
} while (--cnt > 0 } while (--cnt > 0
&& spell_would_be_useless(mtmp, mattk->adtyp, spellnum)); && spell_would_be_useless(mtmp, mattk->adtyp, spellnum));
if (cnt == 0) if (cnt == 0)
return 0; return MM_MISS;
} }
/* monster unable to cast spells? */ /* monster unable to cast spells? */
if (mtmp->mcan || mtmp->mspec_used || !ml) { if (mtmp->mcan || mtmp->mspec_used || !ml) {
cursetxt(mtmp, is_undirected_spell(mattk->adtyp, spellnum)); cursetxt(mtmp, is_undirected_spell(mattk->adtyp, spellnum));
return 0; return MM_MISS;
} }
if (mattk->adtyp == AD_SPEL || mattk->adtyp == AD_CLRC) { if (mattk->adtyp == AD_SPEL || mattk->adtyp == AD_CLRC) {
@@ -241,14 +241,14 @@ castmu(register struct monst *mtmp,
canseemon(mtmp) ? Monnam(mtmp) : "Something", canseemon(mtmp) ? Monnam(mtmp) : "Something",
is_waterwall(mtmp->mux,mtmp->muy) ? "empty water" is_waterwall(mtmp->mux,mtmp->muy) ? "empty water"
: "thin air"); : "thin air");
return 0; return MM_MISS;
} }
nomul(0); nomul(0);
if (rn2(ml * 10) < (mtmp->mconf ? 100 : 20)) { /* fumbled attack */ if (rn2(ml * 10) < (mtmp->mconf ? 100 : 20)) { /* fumbled attack */
if (canseemon(mtmp) && !Deaf) if (canseemon(mtmp) && !Deaf)
pline_The("air crackles around %s.", mon_nam(mtmp)); pline_The("air crackles around %s.", mon_nam(mtmp));
return 0; return MM_MISS;
} }
if (canspotmon(mtmp) || !is_undirected_spell(mattk->adtyp, spellnum)) { if (canspotmon(mtmp) || !is_undirected_spell(mattk->adtyp, spellnum)) {
pline("%s casts a spell%s!", pline("%s casts a spell%s!",
@@ -274,7 +274,7 @@ castmu(register struct monst *mtmp,
impossible( impossible(
"%s casting non-hand-to-hand version of hand-to-hand spell %d?", "%s casting non-hand-to-hand version of hand-to-hand spell %d?",
Monnam(mtmp), mattk->adtyp); Monnam(mtmp), mattk->adtyp);
return 0; return MM_MISS;
} }
} else if (mattk->damd) } else if (mattk->damd)
dmg = d((int) ((ml / 2) + mattk->damn), (int) mattk->damd); dmg = d((int) ((ml / 2) + mattk->damn), (int) mattk->damd);
@@ -283,7 +283,7 @@ castmu(register struct monst *mtmp,
if (Half_spell_damage) if (Half_spell_damage)
dmg = (dmg + 1) / 2; dmg = (dmg + 1) / 2;
ret = 1; ret = MM_HIT;
switch (mattk->adtyp) { switch (mattk->adtyp) {
case AD_FIRE: case AD_FIRE:
pline("You're enveloped in flames."); pline("You're enveloped in flames.");
@@ -850,34 +850,29 @@ spell_would_be_useless(struct monst *mtmp, unsigned int adtyp, int spellnum)
return FALSE; 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 (ranged) */ /* monster uses spell (ranged) */
int int
buzzmu(register struct monst *mtmp, register struct attack *mattk) buzzmu(register struct monst *mtmp, register struct attack *mattk)
{ {
/* don't print constant stream of curse messages for 'normal' /* don't print constant stream of curse messages for 'normal'
spellcasting monsters at range */ spellcasting monsters at range */
if (mattk->adtyp > AD_SPC2) if (!BZ_VALID_ADTYP(mattk->adtyp))
return 0; return MM_MISS;
if (mtmp->mcan) { if (mtmp->mcan || m_seenres(mtmp, cvt_adtyp_to_mseenres(mattk->adtyp))) {
cursetxt(mtmp, FALSE); cursetxt(mtmp, FALSE);
return 0; return MM_MISS;
} }
if (lined_up(mtmp) && rn2(3)) { if (lined_up(mtmp) && rn2(3)) {
nomul(0); nomul(0);
if (mattk->adtyp && (mattk->adtyp < 11)) { /* no cf unsigned >0 */ if (canseemon(mtmp))
if (canseemon(mtmp)) pline("%s zaps you with a %s!", Monnam(mtmp),
pline("%s zaps you with a %s!", Monnam(mtmp), flash_str(BZ_OFS_AD(mattk->adtyp), FALSE));
flash_str(ad_to_typ(mattk->adtyp), FALSE)); buzz(BZ_M_SPELL(BZ_OFS_AD(mattk->adtyp)), (int) mattk->damn, mtmp->mx,
buzz(-ad_to_typ(mattk->adtyp), (int) mattk->damn, mtmp->mx, mtmp->my, sgn(g.tbx), sgn(g.tby));
mtmp->my, sgn(g.tbx), sgn(g.tby)); return MM_HIT;
} else
impossible("Monster spell %d cast", mattk->adtyp - 1);
} }
return 1; return MM_MISS;
} }
/*mcastu.c*/ /*mcastu.c*/
+1 -1
View File
@@ -720,7 +720,7 @@ dochug(register struct monst* mtmp)
for (a = &mdat->mattk[0]; a < &mdat->mattk[NATTK]; a++) { for (a = &mdat->mattk[0]; a < &mdat->mattk[NATTK]; a++) {
if (a->aatyp == AT_MAGC if (a->aatyp == AT_MAGC
&& (a->adtyp == AD_SPEL || a->adtyp == AD_CLRC)) { && (a->adtyp == AD_SPEL || a->adtyp == AD_CLRC)) {
if (castmu(mtmp, a, FALSE, FALSE)) { if ((castmu(mtmp, a, FALSE, FALSE) & MM_HIT)) {
tmp = MMOVE_DONE; /* bypass m_move() */ tmp = MMOVE_DONE; /* bypass m_move() */
break; break;
} }
+3 -3
View File
@@ -886,7 +886,7 @@ breathwep_name(int typ)
if (Hallucination) if (Hallucination)
return rnd_hallublast(); return rnd_hallublast();
return breathwep[typ - 1]; return breathwep[BZ_OFS_AD(typ)];
} }
/* monster breathes at monster (ranged) */ /* monster breathes at monster (ranged) */
@@ -915,12 +915,12 @@ breamm(struct monst* mtmp, struct attack* mattk, struct monst* mtarg)
return MM_HIT; return MM_HIT;
if (!mtmp->mspec_used && rn2(3)) { if (!mtmp->mspec_used && rn2(3)) {
if ((typ >= AD_MAGM) && (typ <= AD_ACID)) { if (BZ_VALID_ADTYP(typ)) {
boolean utarget = (mtarg == &g.youmonst); boolean utarget = (mtarg == &g.youmonst);
if (canseemon(mtmp)) if (canseemon(mtmp))
pline("%s breathes %s!", pline("%s breathes %s!",
Monnam(mtmp), breathwep_name(typ)); Monnam(mtmp), breathwep_name(typ));
dobuzz((int) (-20 - (typ - 1)), (int) mattk->damn, dobuzz(BZ_M_BREATH(BZ_OFS_AD(typ)), (int) mattk->damn,
mtmp->mx, mtmp->my, sgn(g.tbx), sgn(g.tby), utarget); mtmp->mx, mtmp->my, sgn(g.tbx), sgn(g.tby), utarget);
nomul(0); nomul(0);
/* breath runs out sometimes. Also, give monster some /* breath runs out sometimes. Also, give monster some
+2 -2
View File
@@ -1565,7 +1565,7 @@ use_offensive(struct monst* mtmp)
if (oseen) if (oseen)
makeknown(otmp->otyp); makeknown(otmp->otyp);
g.m_using = TRUE; g.m_using = TRUE;
buzz((int) (-30 - (otmp->otyp - WAN_MAGIC_MISSILE)), buzz(BZ_M_WAND(BZ_OFS_WAN(otmp->otyp)),
(otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6, mtmp->mx, mtmp->my, (otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6, mtmp->mx, mtmp->my,
sgn(mtmp->mux - mtmp->mx), sgn(mtmp->muy - mtmp->my)); sgn(mtmp->mux - mtmp->mx), sgn(mtmp->muy - mtmp->my));
g.m_using = FALSE; g.m_using = FALSE;
@@ -1574,7 +1574,7 @@ use_offensive(struct monst* mtmp)
case MUSE_FROST_HORN: case MUSE_FROST_HORN:
mplayhorn(mtmp, otmp, FALSE); mplayhorn(mtmp, otmp, FALSE);
g.m_using = TRUE; g.m_using = TRUE;
buzz(-30 - ((otmp->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1), buzz(BZ_M_WAND(BZ_OFS_AD((otmp->otyp == FROST_HORN) ? AD_COLD : AD_FIRE)),
rn1(6, 6), mtmp->mx, mtmp->my, sgn(mtmp->mux - mtmp->mx), rn1(6, 6), mtmp->mx, mtmp->my, sgn(mtmp->mux - mtmp->mx),
sgn(mtmp->muy - mtmp->my)); sgn(mtmp->muy - mtmp->my));
g.m_using = FALSE; g.m_using = FALSE;
+2 -2
View File
@@ -599,11 +599,11 @@ do_improvisation(struct obj* instr)
losehp(damage, buf, KILLED_BY); /* fire or frost damage */ losehp(damage, buf, KILLED_BY); /* fire or frost damage */
} }
} else { } else {
int type = (instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1; int type = BZ_OFS_AD((instr->otyp == FROST_HORN) ? AD_COLD : AD_FIRE);
if (!Blind) if (!Blind)
pline("A %s blasts out of the horn!", flash_str(type, FALSE)); pline("A %s blasts out of the horn!", flash_str(type, FALSE));
buzz(type, rn1(6, 6), u.ux, u.uy, u.dx, u.dy); ubuzz(BZ_U_WAND(type), rn1(6, 6));
} }
makeknown(instr->otyp); makeknown(instr->otyp);
break; break;
+1 -2
View File
@@ -1252,8 +1252,7 @@ dobreathe(void)
else if (!u.dx && !u.dy && !u.dz) else if (!u.dx && !u.dy && !u.dz)
ubreatheu(mattk); ubreatheu(mattk);
else else
buzz((int) (20 + mattk->adtyp - 1), (int) mattk->damn, u.ux, u.uy, ubuzz(BZ_U_BREATH(BZ_OFS_AD(mattk->adtyp)), (int) mattk->damn);
u.dx, u.dy);
return ECMD_TIME; return ECMD_TIME;
} }
+1 -1
View File
@@ -809,7 +809,7 @@ ghod_hitsu(struct monst *priest)
break; break;
} }
buzz(-10 - (AD_ELEC - 1), 6, x, y, sgn(g.tbx), buzz(BZ_M_SPELL(BZ_OFS_AD(AD_ELEC)), 6, x, y, sgn(g.tbx),
sgn(g.tby)); /* bolt of lightning */ sgn(g.tby)); /* bolt of lightning */
exercise(A_WIS, FALSE); exercise(A_WIS, FALSE);
} }
+8 -4
View File
@@ -3235,11 +3235,9 @@ weffects(struct obj *obj)
if (otyp == WAN_DIGGING || otyp == SPE_DIG) if (otyp == WAN_DIGGING || otyp == SPE_DIG)
zap_dig(); zap_dig();
else if (otyp >= SPE_MAGIC_MISSILE && otyp <= SPE_FINGER_OF_DEATH) else if (otyp >= SPE_MAGIC_MISSILE && otyp <= SPE_FINGER_OF_DEATH)
buzz(otyp - SPE_MAGIC_MISSILE + 10, u.ulevel / 2 + 1, u.ux, u.uy, ubuzz(BZ_U_SPELL(BZ_OFS_SPE(otyp)), u.ulevel / 2 + 1);
u.dx, u.dy);
else if (otyp >= WAN_MAGIC_MISSILE && otyp <= WAN_LIGHTNING) else if (otyp >= WAN_MAGIC_MISSILE && otyp <= WAN_LIGHTNING)
buzz(otyp - WAN_MAGIC_MISSILE, ubuzz(BZ_U_WAND(BZ_OFS_WAN(otyp)), (otyp == WAN_MAGIC_MISSILE) ? 2 : 6);
(otyp == WAN_MAGIC_MISSILE) ? 2 : 6, u.ux, u.uy, u.dx, u.dy);
else else
impossible("weffects: unexpected spell or wand"); impossible("weffects: unexpected spell or wand");
disclose = TRUE; disclose = TRUE;
@@ -4254,6 +4252,12 @@ disintegrate_mon(struct monst *mon,
xkilled(mon, XKILL_NOMSG | XKILL_NOCORPSE); xkilled(mon, XKILL_NOMSG | XKILL_NOCORPSE);
} }
void
ubuzz(int type, int nd)
{
dobuzz(type, nd, u.ux, u.uy, u.dx, u.dy, TRUE);
}
void void
buzz(int type, int nd, coordxy sx, coordxy sy, int dx, int dy) buzz(int type, int nd, coordxy sx, coordxy sy, int dx, int dy)
{ {