the water used on the Plane of Water stops thrown or kicked items
looting will do #force if you could do it and the container is locked
and you didn't have a tool to unlock it
+use silly names for rays (such as breath weapons) when hallucinating
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
/* ### mthrowu.c ### */
+extern const char *rnd_hallublast(void);
extern boolean m_has_launcher_and_ammo(struct monst *);
extern int thitu(int, int, struct obj **, const char *);
extern int ohitmon(struct monst *, struct obj *, int, boolean);
extern int destroy_mitem(struct monst *, int, int);
extern int resist(struct monst *, char, int, int);
extern void makewish(void);
+extern const char *flash_str(int, boolean);
#endif /* !MAKEDEFS_C && !MDLIB_C */
static boolean
spell_would_be_useless(struct monst *, unsigned int, int);
-extern const char *const flash_types[]; /* from zap.c */
-
/* feedback when frustrated monster couldn't cast a spell */
static void
cursetxt(struct monst *mtmp, boolean undirected)
if (mattk->adtyp && (mattk->adtyp < 11)) { /* no cf unsigned >0 */
if (canseemon(mtmp))
pline("%s zaps you with a %s!", Monnam(mtmp),
- flash_types[ad_to_typ(mattk->adtyp)]);
+ flash_str(ad_to_typ(mattk->adtyp), FALSE));
buzz(-ad_to_typ(mattk->adtyp), (int) mattk->damn, mtmp->mx,
mtmp->my, sgn(g.tbx), sgn(g.tby));
} else
static int monmulti(struct monst *, struct obj *, struct obj *);
static void monshoot(struct monst *, struct obj *, struct obj *);
+static const char* breathwep_name(int);
static int drop_throw(struct obj *, boolean, int, int);
static int m_lined_up(struct monst *, struct monst *);
"strange breath #9"
};
+/* hallucinatory ray types */
+const char *const hallublasts[] = {
+ "asteroids", "beads", "bubbles", "butterflies", "champagne", "chaos",
+ "coins", "cotton candy", "crumbs", "dark matter", "darkness", "dust specks",
+ "emoticons", "emotions", "entropy", "flowers", "foam", "fog", "gamma rays",
+ "gelatin", "gemstones", "ghosts", "glass shards", "glitter", "good vibes",
+ "gravel", "gravity", "gravy", "grawlixes", "holy light", "hornets",
+ "hot air", "hyphens", "hypnosis", "infrared", "insects", "laser beams",
+ "leaves", "lightening", "logic gates", "magma", "marbles", "mathematics",
+ "megabytes", "metal shavings", "metapatterns", "meteors", "mist", "mud",
+ "music", "nanites", "needles", "noise", "nostalgia", "oil", "paint",
+ "photons", "pixels", "plasma", "polarity", "powder", "powerups",
+ "prismatic light", "pure logic", "purple", "radio waves", "rainbows",
+ "rock music", "rocket fuel", "rope", "sadness", "salt", "sand", "scrolls",
+ "sludge", "smileys", "snowflakes", "sparkles", "specularity", "spores",
+ "stars", "steam", "tetrahedrons", "text", "the past", "tornadoes",
+ "toxic waste", "ultraviolet light", "viruses", "water", "waveforms", "wind",
+ "X-rays", "zorkmids"
+};
+
+/* Return a random hallucinatory blast. */
+const char *
+rnd_hallublast(void)
+{
+ return hallublasts[rn2(SIZE(hallublasts))];
+}
+
boolean
m_has_launcher_and_ammo(struct monst* mtmp)
{
return MM_MISS;
}
+/* Return the name of a breath weapon. If the player is hallucinating, return
+ * a silly name instead.
+ * typ is AD_MAGM, AD_FIRE, etc */
+static const char *
+breathwep_name(int typ)
+{
+ if (Hallucination)
+ return rnd_hallublast();
+
+ return breathwep[typ - 1];
+}
+
/* monster breathes at monster (ranged) */
int
breamm(struct monst* mtmp, struct attack* mattk, struct monst* mtarg)
if ((typ >= AD_MAGM) && (typ <= AD_ACID)) {
boolean utarget = (mtarg == &g.youmonst);
if (canseemon(mtmp))
- pline("%s breathes %s!", Monnam(mtmp), breathwep[typ - 1]);
+ pline("%s breathes %s!",
+ Monnam(mtmp), breathwep_name(typ));
dobuzz((int) (-20 - (typ - 1)), (int) mattk->damn,
mtmp->mx, mtmp->my, sgn(g.tbx), sgn(g.tby), utarget);
nomul(0);
losehp(damage, buf, KILLED_BY); /* fire or frost damage */
}
} else {
- buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1,
- rn1(6, 6), u.ux, u.uy, u.dx, u.dy);
+ int type = (instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1;
+
+ if (!Blind)
+ 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);
}
makeknown(instr->otyp);
break;
ubreatheu(struct attack *mattk)
{
int dtyp = 20 + mattk->adtyp - 1; /* breath by hero */
- const char *fltxt = flash_types[dtyp]; /* blast of <something> */
- zhitu(dtyp, mattk->damn, fltxt, u.ux, u.uy);
+ zhitu(dtyp, mattk->damn, flash_str(dtyp, TRUE), u.ux, u.uy);
}
/* light damages hero in gremlin form */
struct monst *mon;
coord save_bhitpos;
boolean shopdamage = FALSE;
- const char *fltxt;
struct obj *otmp;
int spell_type;
+ int fltyp = (type <= -30) ? abstype : abs(type);
+ int habstype = Hallucination ? rn2(6) : abstype;
/* if its a Hero Spell then get its SPE_TYPE */
spell_type = is_hero_spell(type) ? SPE_MAGIC_MISSILE + abstype : 0;
- fltxt = flash_types[(type <= -30) ? abstype : abs(type)];
if (u.uswallow) {
register int tmp;
if (!u.ustuck) {
u.uswallow = 0;
} else {
- pline("%s rips into %s%s", The(fltxt), mon_nam(u.ustuck),
- exclam(tmp));
+ pline("%s rips into %s%s", The(flash_str(fltyp, FALSE)),
+ mon_nam(u.ustuck), exclam(tmp));
/* Using disintegration from the inside only makes a hole... */
if (tmp == MAGIC_COOKIE)
u.ustuck->mhp = 0;
range = 1;
save_bhitpos = g.bhitpos;
- tmp_at(DISP_BEAM, zapdir_to_glyph(dx, dy, abstype));
+ tmp_at(DISP_BEAM, zapdir_to_glyph(dx, dy, habstype));
while (range-- > 0) {
lsx = sx;
sx += dx;
if (zap_hit(find_mac(mon), spell_type)) {
if (mon_reflects(mon, (char *) 0)) {
if (cansee(mon->mx, mon->my)) {
- hit(fltxt, mon, exclam(0));
+ hit(flash_str(fltyp, FALSE), mon, exclam(0));
shieldeff(mon->mx, mon->my);
(void) mon_reflects(mon,
"But it reflects from %s %s!");
if (is_rider(mon->data)
&& abs(type) == ZT_BREATH(ZT_DEATH)) {
if (canseemon(mon)) {
- hit(fltxt, mon, ".");
+ hit(flash_str(fltyp, FALSE), mon, ".");
pline("%s disintegrates.", Monnam(mon));
pline("%s body reintegrates before your %s!",
s_suffix(Monnam(mon)),
}
if (mon->data == &mons[PM_DEATH] && abstype == ZT_DEATH) {
if (canseemon(mon)) {
- hit(fltxt, mon, ".");
+ hit(flash_str(fltyp, FALSE), mon, ".");
pline("%s absorbs the deadly %s!", Monnam(mon),
type == ZT_BREATH(ZT_DEATH) ? "blast"
: "ray");
}
if (tmp == MAGIC_COOKIE) { /* disintegration */
- disintegrate_mon(mon, type, fltxt);
+ disintegrate_mon(mon, type, flash_str(fltyp, FALSE));
} else if (DEADMONSTER(mon)) {
if (type < 0) {
/* mon has just been killed by another monster */
- monkilled(mon, fltxt, AD_RBRE);
+ monkilled(mon, flash_str(fltyp, FALSE), AD_RBRE);
} else {
int xkflags = XKILL_GIVEMSG; /* killed(mon); */
if (!otmp) {
/* normal non-fatal hit */
if (say || canseemon(mon))
- hit(fltxt, mon, exclam(tmp));
+ hit(flash_str(fltyp, FALSE), mon, exclam(tmp));
} else {
/* some armor was destroyed; no damage done */
if (canseemon(mon))
range -= 2;
} else {
if (say || canseemon(mon))
- miss(fltxt, mon);
+ miss(flash_str(fltyp, FALSE), mon);
}
} else if (sx == u.ux && sy == u.uy && range >= 0) {
nomul(0);
goto buzzmonst;
} else if (zap_hit((int) u.uac, 0)) {
range -= 2;
- pline("%s hits you!", The(fltxt));
+ pline("%s hits you!", The(flash_str(fltyp, FALSE)));
if (Reflecting) {
if (!Blind) {
(void) ureflects("But %s reflects from your %s!",
dy = -dy;
shieldeff(sx, sy);
} else {
- zhitu(type, nd, fltxt, sx, sy);
+ /* flash_str here only used for killer; suppress
+ * hallucination */
+ zhitu(type, nd, flash_str(fltyp, TRUE), sx, sy);
}
} else if (!Blind) {
- pline("%s whizzes by you!", The(fltxt));
+ pline("%s whizzes by you!", The(flash_str(fltyp, FALSE)));
} else if (abstype == ZT_LIGHTNING) {
Your("%s tingles.", body_part(ARM));
}
if ((--range > 0 && isok(lsx, lsy) && cansee(lsx, lsy))
|| fireball) {
if (Is_airlevel(&u.uz)) { /* nothing to bounce off of */
- pline_The("%s vanishes into the aether!", fltxt);
+ pline_The("%s vanishes into the aether!",
+ flash_str(fltyp, FALSE));
if (fireball)
type = ZT_WAND(ZT_FIRE); /* skip pending fireball */
break;
sy = lsy;
break; /* fireballs explode before the obstacle */
} else
- pline_The("%s bounces!", fltxt);
+ pline_The("%s bounces!", flash_str(fltyp, FALSE));
}
if (!dx || !dy || !rn2(bchance)) {
dx = -dx;
dx = -dx;
break;
}
- tmp_at(DISP_CHANGE, zapdir_to_glyph(dx, dy, abstype));
+ tmp_at(DISP_CHANGE, zapdir_to_glyph(dx, dy, habstype));
}
}
}
}
}
+/* Fills buf with the appropriate string for this ray.
+ * In the hallucination case, insert "blast of <silly thing>".
+ * Assumes that the caller will specify typ in the appropriate range for
+ * wand/spell/breath weapon. */
+const char*
+flash_str(int typ,
+ boolean nohallu) /* suppress hallucination (for death reasons) */
+{
+ static char fltxt[BUFSZ];
+ if (Hallucination && !nohallu) {
+ /* always return "blast of foo" for simplicity.
+ * This could be extended with hallucinatory rays, but probably not worth
+ * it at this time. */
+ Sprintf(fltxt, "blast of %s", rnd_hallublast());
+ }
+ else {
+ Strcpy(fltxt, flash_types[typ]);
+ }
+ return fltxt;
+}
+
/*zap.c*/