1
0
Fork 0
mirror of https://codeberg.org/noisytoot/notnotdnethack.git synced 2025-07-27 07:52:25 +01:00

Merge branch 'devel-local-vaults' into devel-3.20.1

This commit is contained in:
ChrisANG 2021-05-05 21:41:02 -04:00
commit f749a4901a
15 changed files with 442 additions and 12 deletions

View file

@ -1556,6 +1556,7 @@ E void FDECL(mon_to_gold, (struct monst*));
E void FDECL(mnexto, (struct monst *));
E void FDECL(monline, (struct monst *));
E void FDECL(mofflin, (struct monst *));
E void FDECL(mofflin_close, (struct monst *));
E boolean FDECL(mnearto, (struct monst *,XCHAR_P,XCHAR_P,BOOLEAN_P));
E void FDECL(poisontell, (int));
E void FDECL(poisoned, (const char *,int,const char *,int));
@ -2697,6 +2698,7 @@ E boolean FDECL(teleok, (int,int,BOOLEAN_P));
E boolean FDECL(goodpos, (int,int,struct monst *,unsigned));
E boolean FDECL(eonline, (coord *,XCHAR_P,XCHAR_P,struct permonst *));
E boolean FDECL(eofflin, (coord *,XCHAR_P,XCHAR_P,struct permonst *));
E boolean FDECL(eofflin_close, (coord *,XCHAR_P,XCHAR_P,struct permonst *));
E boolean FDECL(enexto, (coord *,XCHAR_P,XCHAR_P,struct permonst *));
E boolean FDECL(enexto_core, (coord *,XCHAR_P,XCHAR_P,struct permonst *,unsigned));
E void FDECL(xpathto, (int,XCHAR_P,XCHAR_P,int (*)(genericptr_t,int,int),void *));
@ -2807,7 +2809,7 @@ E void FDECL(fill_pit, (int,int));
E int FDECL(float_down, (long, long));
E void FDECL(m_float_down, (struct monst *, boolean));
E int FDECL(fire_damage, (struct obj *,BOOLEAN_P,BOOLEAN_P,XCHAR_P,XCHAR_P));
E boolean FDECL(water_damage, (struct obj *,BOOLEAN_P,BOOLEAN_P,BOOLEAN_P, struct monst *));
E boolean FDECL(water_damage, (struct obj *, BOOLEAN_P, BOOLEAN_P, uchar, struct monst *));
E boolean NDECL(drown);
E int NDECL(dodeepswim);
E void FDECL(drain_en, (int));

View file

@ -63,6 +63,7 @@
#define MS_SECRETS 52 /* Tells secrets */
#define MS_SCREAM 53 /* Screams in madness */
#define MS_HARROW 54 /* Summon wraiths */
#define MS_APOC 55 /* Dire Revelations */
#define MR_FIRE 0x0001 /* 1 resists fire */

View file

@ -225,6 +225,7 @@ struct monst {
#define YELLOW_TEMPLATE 16 /* causes sleep and damages sanity (unimplemented) */
#define DREAM_LEECH 17 /* sucks mental atributes */
#define MAD_TEMPLATE 18 /* mad angel template */
#define FALLEN_TEMPLATE 19 /* fallen angel template */
#define MAXTEMPLATE MAD_TEMPLATE
//define HALF_DEMON FACTION_PADDING+1 /* half-demon ??? */

View file

@ -82,4 +82,8 @@ extern struct trap *ftrap;
#define FLESH_HOOK 26
#define TRAPNUM 27
//Flags for the water damage function.
#define WD_LETHE 0x1
#define WD_BLOOD 0x2
#endif /* TRAP_H */

View file

@ -1638,6 +1638,9 @@ int x, y;
case VN_A_O_DEATH:
mid = PM_ANCIENT_OF_DEATH;
break;
case VN_APOCALYPSE:
mid = PM_APOCALYPSE_ANGEL;
break;
case VN_HARROWER:
mid = PM_HARROWER_OF_ZARIEL;
break;
@ -1681,7 +1684,10 @@ int x, y;
if(mon){
if(levl[x][y].vaulttype == VN_MAD_ANGEL){
set_template(mon, MAD_TEMPLATE);
mon->m_lev += (mon->data->mlevel)/2;
}
mon->mhpmax = max(4, 8*mon->m_lev);
mon->mhp = mon->mhpmax;
if(mid == PM_TULANI_ELADRIN || mid == PM_GAE_ELADRIN){
if(dungeon_topology.eprecursor_typ == PRE_POLYP && rn2(2))
mon->ispolyp = TRUE;

View file

@ -4059,6 +4059,9 @@ int tary;
/* alienists summon aliens. wowzers. */
return cast_spell(magr, mdef, attk, SUMMON_ALIEN, tarx, tary);
}
else if (has_template(magr, FALLEN_TEMPLATE)) {
return cast_spell(magr, mdef, attk, SUMMON_DEVIL, tarx, tary);
}
else
{
struct monst *mtmp;

View file

@ -3224,7 +3224,7 @@ struct monst * mdef; /* another monster which is next to it */
return ALLOW_M|ALLOW_TM;
/* angels vs. demons (excluding Lamashtu) */
#define fallen(mx) (has_template(mx, MAD_TEMPLATE) || mx->mfaction == LAMASHTU_FACTION)
#define fallen(mx) (has_template(mx, MAD_TEMPLATE) || has_template(mx, FALLEN_TEMPLATE) || mx->mfaction == LAMASHTU_FACTION)
#define normalAngel(mx) (is_angel(mx->data) && !fallen(mx))
#define fallenAngel(mx) (is_angel(mx->data) && fallen(mx))
if (normalAngel(magr) && (is_demon(md) || fallenAngel(mdef)))
@ -5543,7 +5543,7 @@ monline(mtmp) /* Make monster mtmp next to you (if possible) */
}
void
mofflin(mtmp) /* Make monster mtmp next to you (if possible) */
mofflin(mtmp) /* Make monster mtmp near to you (if possible) */
struct monst *mtmp;
{
coord mm;
@ -5562,6 +5562,26 @@ mofflin(mtmp) /* Make monster mtmp next to you (if possible) */
return;
}
void
mofflin_close(mtmp) /* Make monster mtmp near to you (if possible) */
struct monst *mtmp;
{
coord mm;
#ifdef STEED
if (mtmp == u.usteed) {
/* Keep your steed in sync with you instead */
mtmp->mx = u.ux;
mtmp->my = u.uy;
return;
}
#endif
if(!eofflin_close(&mm, u.ux, u.uy, mtmp->data)) return;
rloc_to(mtmp, mm.x, mm.y);
return;
}
/* mnearto()
* Put monster near (or at) location if possible.
* Returns:
@ -5728,6 +5748,7 @@ register struct monst *mtmp;
|| mtmp->data->msound == MS_TRUMPET || mtmp->mtyp == PM_RHYMER
|| mtmp->data->msound == MS_SECRETS || mtmp->data->msound == MS_HOWL
|| mtmp->data->msound == MS_SCREAM || mtmp->data->msound == MS_HARROW
|| mtmp->data->msound == MS_APOC
)
) {
domonnoise(mtmp, FALSE);
@ -7894,7 +7915,7 @@ struct monst *mtmp;
xdamagey(mtmp, &youmonst, (struct attack *)0, damage);
}
if(distmin(u.ux,u.uy,mtmp->mx,mtmp->my) <= BOLT_LIM){
mofflin(mtmp);
mofflin_close(mtmp);
}
}
}

View file

@ -413,6 +413,17 @@ int template;
ptr->mflagst |= MT_ANIMAL;
ptr->mflagst &= ~(MT_PEACEFUL | MT_ITEMS | MT_HIDE | MT_CONCEAL);
ptr->mflagsg |= (MG_DISPLACEMENT);
ptr->maligntyp = min(ptr->maligntyp-6, -6);
break;
case FALLEN_TEMPLATE:
ptr->pac = max(9, ptr->pac);
ptr->spe_hdr = 9;
ptr->msound = MS_CUSS;
ptr->mflagst |= (MT_HOSTILE | MT_STALK);
ptr->mflagst &= ~(MT_PEACEFUL);
ptr->mflagsg &= ~(MG_HATESUNHOLY);
ptr->mflagsg |= (MG_HATESHOLY);
ptr->maligntyp = max(ptr->maligntyp+9, 9);
break;
}
#undef MT_ITEMS
@ -708,11 +719,6 @@ int template;
attk->damn++;
attk->damd += 2;
}
if (template == MAD_TEMPLATE && !is_null_attk(attk) && attk->adtyp != AD_DISN){
if(attk->adtyp == AD_PHYS)
attk->damn++;
attk->damd += 4;
}
if (template == YELLOW_TEMPLATE && (
end_insert_okay
))
@ -735,6 +741,22 @@ int template;
attk->damd = 6;
special = TRUE;
}
if (template == MAD_TEMPLATE && !is_null_attk(attk) && attk->adtyp != AD_DISN){
if(attk->adtyp == AD_PHYS)
attk->damn++;
attk->damd += 4;
}
if (template == FALLEN_TEMPLATE && (
end_insert_okay
))
{
maybe_insert();
attk->aatyp = AT_NONE;
attk->adtyp = AD_FIRE;
attk->damn = 0;
attk->damd = 9;
special = TRUE;
}
}
#undef insert_okay
#undef end_insert_okay
@ -755,6 +777,7 @@ int template;
else if (template == YELLOW_TEMPLATE) Sprintf(nameBuffer, "%s of Carcosa", base->mname);
else if (template == DREAM_LEECH) Sprintf(nameBuffer, "%s the Dream-Leech", base->mname);
else if (template == MAD_TEMPLATE) Sprintf(nameBuffer, "%s the mad", base->mname);
else if (template == FALLEN_TEMPLATE) Sprintf(nameBuffer, "%s the fallen", base->mname);
// else if (template == MISTWEAVER) Depends on sex, handled elsewhere
else Sprintf(nameBuffer, "%s", base->mname);
}
@ -771,6 +794,7 @@ int template;
else if (template == YELLOW_TEMPLATE) Sprintf(nameBuffer, "fulvous %s", base->mname);
else if (template == DREAM_LEECH) Sprintf(nameBuffer, "%s dream-leech", base->mname);
else if (template == MAD_TEMPLATE) Sprintf(nameBuffer, "mad %s", base->mname);
else if (template == FALLEN_TEMPLATE) Sprintf(nameBuffer, "fallen %s", base->mname);
// else if (template == MISTWEAVER) Depends on sex, handled elsewhere
else Sprintf(nameBuffer, "%s", base->mname);
}

View file

@ -1239,6 +1239,7 @@ register struct monst *mtmp;
|| (mdat->msound == MS_SCREAM && !rn2(7))
|| (mdat->msound == MS_HOWL && !rn2(7))
|| (mdat->msound == MS_HARROW && !mtmp->mspec_used)
|| (mdat->msound == MS_APOC && !mtmp->mspec_used)
) m_respond(mtmp);
if(!mtmp->mblinded) for (gazemon = fmon; gazemon; gazemon = nxtmon){

View file

@ -5943,6 +5943,16 @@ is a red right hand
MM_FLY /*MM*/, MT_STALK|MT_COLLECT|MT_HOSTILE|MT_TRAITOR /*MT*/, MF_MARTIAL_E /*MF*/,
MB_HUMANOID|MB_WINGS|MB_STRONG /*MB*/, MG_INFRAVISIBLE|MG_NASTY|MG_NOPOLY /*MG*/,
0 /*MA*/, MV_EXTRAMISSION|MV_SEE_INVIS /*MV*/, CLR_WHITE),
MON("apocalypse angel", S_DEMON,//19 /* Needs encyc entry */
LVL_FULL(15, 10, DETAIL_AC(6,0,13), FLAT_SPE_DR(6, 7,3,9,3,9), 99, 20), (G_HELL|G_NOCORPSE|G_NOGEN),
A(ATTK(AT_LNCK, AD_DRST, 1, 6), ATTK(AT_HITS, AD_APCS, 0, 0),
ATTK(AT_NONE, AD_FIRE, 0, 9),
NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_HUMAN, 400, MS_APOC, MZ_HUMAN),
MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_MAGIC, 0,
MM_FLY|MM_FLOAT /*MM*/, MT_STALK|MT_COLLECT|MT_HOSTILE|MT_TRAITOR|MT_WANTSBOOK|MT_WANTSAMUL /*MT*/, MF_MARTIAL_E /*MF*/,
MB_HUMANOID|MB_WINGS|MB_STRONG /*MB*/, MG_NOWISH|MG_NOPOLY|MG_INFRAVISIBLE|MG_NASTY|MG_SANLOSS /*MG*/,
0 /*MA*/, MV_EXTRAMISSION|MV_SEE_INVIS|MV_DETECTION|MV_OMNI /*MV*/, CLR_BRIGHT_MAGENTA),
MON("ancient of blessings", S_DEMON,//23 /* Needs encyc entry */
LVL_FULL(15, 17, DETAIL_AC(7,3,7), FLAT_SPE_DR(7, 17, 7, 7, 7, 7), 77, 14), (G_HELL|G_NOCORPSE|G_NOGEN), /*Needs encyc entry*/
A(ATTK(AT_DEVA, AD_ENCH, 1, 7), ATTK(AT_XWEP, AD_ENCH, 1, 7),

View file

@ -539,6 +539,7 @@ register struct monst *mtmp;
) {
case MS_MEW:
case MS_HISS:
case MS_APOC:
ret = "hiss";
break;
case MS_BARK:
@ -1704,6 +1705,58 @@ asGuardian:
}
} else goto humanoid_sound;
}break;
case MS_APOC:
if(chatting){
if(!mtmp->mpeaceful) pline_msg = "hisses!";
else {
pline_msg = "does not respond.";
return 0; /* no sound */
}
break;
}
else {
struct monst *tmpm, *nmon;
int atknum = rnd(4);
int i, mnum;
mtmp->mspec_used = 66;
if(canspotmon(mtmp)){
pline("%s snake head hisses a prophecy!", s_suffix(Monnam(mtmp)));
}
switch(atknum){
/*Slashing darkness*/
case 1:
mnum = PM_INVIDIAK;
pline("The darkness shifts and forms into blades!");
break;
/*Falling stars*/
case 2:
mnum = PM_MOTE_OF_LIGHT;
pline("Stars fall from the sky!");
break;
/*Scream*/
case 3:
mnum = PM_WALKING_DELIRIUM;
pline("The world trembles and crawls!");
break;
/*Earthquake*/
case 4:
mnum = PM_EARTH_ELEMENTAL;
pline("The entire world is shaking around you!");
break;
}
for(i = Insanity/3; i > 0; i--){
tmpm = makemon(&mons[mnum], 0, 0, MM_NOCOUNTBIRTH|MM_ESUM);
if(tmpm){
mark_mon_as_summoned(tmpm, mtmp, 66, 0);
if(mnum == PM_MOTE_OF_LIGHT)
set_template(tmpm, FALLEN_TEMPLATE);
tmpm->m_lev = 15;
tmpm->mhpmax = max(4, 8*tmpm->m_lev);
tmpm->mhp = tmpm->mhpmax;
}
}
}
break;
case MS_HOWL:{
struct monst *tmpm;
pline_msg = "howls.";

View file

@ -183,6 +183,48 @@ full:
return TRUE;
}
boolean
eofflin_close(cc, xx, yy, mdat)
coord *cc;
register xchar xx, yy;
struct permonst *mdat;
{
#define COORD_SIZE 8
coord good[COORD_SIZE], *good_ptr;
int x, y, i;
int xmin, xmax, ymin, ymax;
struct monst fakemon = {0}; /* dummy monster */
int knix[COORD_SIZE] = {2, 2, 1, -1, -2, -2, 1, -1};
int kniy[COORD_SIZE] = {1, -1, 2, 2, 1, -1, -2, -2};
if (!mdat) {
#ifdef DEBUG
pline("enexto() called with mdat==0");
#endif
/* default to player's original monster type */
mdat = &mons[u.umonster];
}
set_mon_data_core(&fakemon, mdat); /* set up for goodpos */
good_ptr = good;
for(i = 0; i < COORD_SIZE; i++){
x = u.ux + knix[i];
y = u.uy + kniy[i];
if(goodpos(x, y, &fakemon, 0)){
good_ptr->x = x;
good_ptr->y = y;
good_ptr++;
}
}
//No good spots
if(!(good_ptr - good))
return FALSE;
i = rn2((int)(good_ptr - good));
cc->x = good[i].x;
cc->y = good[i].y;
return TRUE;
}
boolean
eonline(cc, xx, yy, mdat)
coord *cc;

View file

@ -3242,12 +3242,15 @@ xchar x, y;
/* returns TRUE if obj is destroyed */
boolean
water_damage(obj, force, here, lethe, owner)
water_damage(obj, force, here, modifiers, owner)
struct obj *obj;
boolean force, here, lethe;
boolean force, here;
uchar modifiers;
struct monst *owner;
{
/* Dips in the Lethe are a very poor idea - Lethe patch*/
boolean lethe = modifiers|WD_LETHE;
boolean blood = modifiers|WD_BLOOD;
int luckpenalty = lethe ? 7 : 0;
struct obj *otmp;
struct obj *obj_original = obj;
@ -3309,6 +3312,12 @@ struct monst *owner;
uncurse(obj);
unbless(obj);
}
if(blood){
if(obj->blessed)
unbless(obj);
else if(!obj->cursed)
curse(obj);
}
switch (obj->oclass) {
case SCROLL_CLASS:
@ -3353,6 +3362,13 @@ struct monst *owner;
obj->odiluted = 0;
set_object_color(obj);
}
} else if (blood) {
if (obj->otyp == POT_BLOOD){
obj->otyp = POT_BLOOD;
otmp->corpsenm = PM_HUMAN;
obj->odiluted = 0;
set_object_color(obj);
}
} else if (obj->odiluted || obj->otyp == POT_AMNESIA) {
obj->otyp = POT_WATER;
obj->blessed = obj->cursed = 0;

View file

@ -407,6 +407,11 @@ tactics(mtmp)
){
monline(mtmp);
if(!mon_can_see_you(mtmp) || !couldsee(mtmp->mx, mtmp->my)) mnexto(mtmp);
} else if(attacktype_fordmg(mtmp->data, AT_LRCH, AD_ANY) ||
attacktype_fordmg(mtmp->data, AT_LNCK, AD_ANY)
){
mofflin_close(mtmp);
if(!mon_can_see_you(mtmp) || !couldsee(mtmp->mx, mtmp->my)) mnexto(mtmp);
} else if((attacktype_fordmg(mtmp->data, AT_MMGC, AD_ANY) ||
attacktype_fordmg(mtmp->data, AT_MAGC, AD_ANY) )
&& !mtmp->mcan && !mtmp->mspec_used
@ -462,6 +467,11 @@ tactics(mtmp)
){
monline(mtmp);
if(!mon_can_see_you(mtmp)) mnexto(mtmp);
} else if(attacktype_fordmg(mtmp->data, AT_LRCH, AD_ANY) ||
attacktype_fordmg(mtmp->data, AT_LNCK, AD_ANY)
){
mofflin_close(mtmp);
if(!mon_can_see_you(mtmp) || !couldsee(mtmp->mx, mtmp->my)) mnexto(mtmp);
} else if((attacktype_fordmg(mtmp->data, AT_MMGC, AD_ANY) ||
attacktype_fordmg(mtmp->data, AT_MAGC, AD_ANY) )
&& !mtmp->mcan && !mtmp->mspec_used

View file

@ -4,6 +4,8 @@
#include "xhity.h"
extern int monstr[];
STATIC_DCL void FDECL(wildmiss, (struct monst *, struct attack *, struct obj *, boolean));
STATIC_DCL boolean FDECL(u_surprise, (struct monst *, boolean));
STATIC_DCL struct attack * FDECL(getnextspiritattack, (boolean));
@ -248,7 +250,6 @@ struct monst * mdef;
if (!DEADMONSTER(mdef) && u.sealsActive&SEAL_AHAZU){
if ((*hp(mdef) < .1*(*hpmax(mdef))) && !(is_rider(pd) || pd->msound == MS_NEMESIS)){
#define MAXVALUE 24
extern const int monstr[];
int value = min(monstr[monsndx(pd)] + 1, MAXVALUE);
pline("%s sinks into your deep black shadow!", Monnam(mdef));
cprefx(monsndx(pd), TRUE, TRUE);
@ -5456,6 +5457,241 @@ boolean ranged;
alt_attk.adtyp = AD_DRST;
return xmeleehurty(magr, mdef, &alt_attk, originalattk, weapon_p, FALSE, dmg, dieroll, vis, ranged);
case AD_APCS:{
boolean hits;
/* print a hit message */
if(!youdef){
if(is_deaf(mdef) || !intelligent_mon(mdef)){
return MM_MISS;
}
}
if(!notmcan){
if(vis && dohitmsg){
if(youagr)
pline("You whisper banal platitudes in %s %s.", s_suffix(mon_nam(mdef)), mbodypart(mdef, EAR));
else if(youdef)
pline("%s whispers banal platitudes in your %s.", Monnam(magr), body_part(EAR));
else
pline("%s whispers banal platitudes in %s %s.", Monnam(magr), s_suffix(mon_nam(mdef)), mbodypart(mdef, EAR));
}
return MM_MISS;
}
if(vis && dohitmsg){
if(youagr)
pline("You whisper terrible truths in %s %s.", s_suffix(mon_nam(mdef)), mbodypart(mdef, EAR));
else if(youdef)
pline("%s whispers terrible truths in your %s.", Monnam(magr), body_part(EAR));
else
pline("%s whispers terrible truths in %s %s.", Monnam(magr), s_suffix(mon_nam(mdef)), mbodypart(mdef, EAR));
}
/*Check insight*/
if(youdef){
hits = rn2(u.uinsight) >= 10;
}
else {
//Just do a level check for monsters
hits = rn2(mdef->m_lev) >= 10;
}
if(!hits){
if(youdef){
pline("But you fail to understand!");
u.uinsight++;
make_confused(HConfusion + 10L, TRUE);
}
else {
if(vis)
pline("%s staggers!", Monnam(mdef));
mdef->mstun = 1;
mdef->mconf = 1;
}
}
else {
if(youdef){
dmg = Insanity/5;
if(Insanity%5 && rn2(Insanity%5))
dmg++;
}
else {
if(youagr)
dmg = rnd(u.ulevel);
else
dmg = rnd(monstr[magr->mtyp]);
if(resist(mdef, 0, 0, NOTELL))
dmg = max(1, dmg/2);
}
switch(rn2(9)){
/*Sow doubt*/
case 0:
/* player is more detailed */
if (!youdef) {
if(canseemon(mdef))
pline("%s looks doubtful.", Monnam(mdef));
mdef->mdoubt = TRUE;
}
else {
pline("Doubt clouds your heart.");
make_doubtful(itimeout_incr(HDoubt, dmg*50), TRUE);
}
return MM_HIT;
/*Blaspheme*/
case 1:
/* player is more detailed */
if (!youdef){
if(canseemon(mdef))
pline("%s looks doubtful.", Monnam(mdef));
if(rn2(10)){
struct attack fakespell = { AT_MAGC, AD_CLRC, 10, 7 };
cast_spell(magr, mdef, &fakespell, LIGHTNING, mdef->mx, mdef->my);
return MM_HIT;
}
else {
alt_attk.aatyp = AT_HITS;
alt_attk.adtyp = AD_DISN;
alt_attk.damn = 7;
alt_attk.damd = 1;
return xmeleehurty(magr, mdef, &alt_attk, &alt_attk, (struct obj **) 0, FALSE, 7, 20, vis, TRUE);
}
}
else {
int angrygod = A_CHAOTIC + rn2(3); //Note: -1 to +1
pline("Blasphemous thoughts fill your mind!");
u.ualign.record -= rnd(20);
u.ualign.sins++;
u.hod += rnd(20);
u.ugangr[Align2gangr(angrygod)]++;
angrygods(angrygod);
}
return MM_HIT;
/*Lower Sanity*/
case 2:
/* player is more detailed */
if (!youdef) {
if(canseemon(mdef))
pline("%s looks confused!", Monnam(mdef));
mdef->mstun = 1;
mdef->mconf = 1;
}
else {
pline("The truth shakes the foundations of your mind!");
change_usanity(u_sanity_loss_minor(magr), TRUE);
}
return MM_HIT;
/*Tear at self*/
case 3:
if(!youdef){
if(canseemon(mdef))
pline("%s tears at %sself.", Monnam(mdef), mhis(mdef));
xdamagey(magr, mdef, attk, d(dmg,10));
}
else {
if (u.sealsActive&SEAL_HUGINN_MUNINN){
unbind(SEAL_HUGINN_MUNINN, TRUE);
}
else {
pline("The truth tears down the foundations of your mind!");
while (!(ABASE(A_WIS) <= ATTRMIN(A_WIS)) && dmg > 0) {
dmg--;
(void)adjattrib(A_WIS, -1, TRUE);
forget(10); /* lose 10% of memory per point lost*/
exercise(A_WIS, FALSE);
}
if (dmg > 0) {
You("tear at yourself in horror!"); //assume always able to damage self
xdamagey(magr, mdef, attk, d(dmg,10));
}
}
}
return MM_HIT;
/*Prophesize doom*/
case 4:{
int maxDoom = youagr ? u.ulevel : monstr[magr->mtyp];
pline("%s shares a prophecy of doom!", Monnam(magr));
if(!youdef){
if(canseemon(mdef))
pline("%s looks despondent.", Monnam(mdef));
mdef->encouraged -= dmg;
if(mdef->mstdy > -maxDoom){
mdef->mstdy = max(mdef->mstdy-dmg, -maxDoom);
}
}
else {
You_feel("despondent.");
u.uencouraged -= dmg;
if(u.ustdy > -maxDoom){
u.ustdy = max(u.ustdy-dmg, -maxDoom);
}
}
return MM_HIT;
}
/*Rider attack*/
case 5:
switch(rn2(4)){
case 0:
alt_attk.adtyp = AD_DETH;
alt_attk.damn = 8;
alt_attk.damd = 8;
return xmeleehurty(magr, mdef, &alt_attk, originalattk, (struct obj **) 0, TRUE, 0, 20, vis, TRUE);
case 1:
alt_attk.adtyp = AD_FAMN;
alt_attk.damn = 8;
alt_attk.damd = 8;
return xmeleehurty(magr, mdef, &alt_attk, originalattk, (struct obj **) 0, TRUE, 0, 20, vis, TRUE);
case 2:
alt_attk.adtyp = AD_PEST;
alt_attk.damn = 8;
alt_attk.damd = 8;
return xmeleehurty(magr, mdef, &alt_attk, originalattk, (struct obj **) 0, TRUE, 0, 20, vis, TRUE);
case 3:
alt_attk.adtyp = AD_CNFT;
alt_attk.damn = 8;
alt_attk.damd = 8;
return xmeleehurty(magr, mdef, &alt_attk, originalattk, (struct obj **) 0, TRUE, 0, 20, vis, TRUE);
}
//Not reached
return MM_MISS;
/*Lower protection*/
case 6:
if(youdef){
u.uacinc -= dmg;
u.ublessed = max(0, u.ublessed-dmg);
}
else {
pline("%s shares a prophecy of your death!", Monnam(magr));
if(canseemon(mdef))
pline("%s looks fearful.", Monnam(mdef));
//Monsters are less detailed, just discourage them.
mdef->encouraged = max(-dmg, mdef->encouraged-dmg);
}
return MM_HIT;
/*Lower luck*/
case 7:
if(youdef){
pline("%s shares a prophecy of great misfortune!", Monnam(magr));
change_luck(-dmg);
}
else {
if(canseemon(mdef))
pline("%s looks fearful.", Monnam(mdef));
//Monsters are less detailed, just discourage them.
mdef->encouraged = max(-dmg, mdef->encouraged-dmg);
}
return MM_HIT;
/*Water to blood*/
case 8:
pline("Space bleeds around %s.", youdef ? "you" : mon_nam(mdef));
(void) water_damage(youdef ? invent : mdef->minvent, FALSE, FALSE, WD_BLOOD, mdef);
return MM_HIT;
}
}
if(alt_attk.damn || alt_attk.damd){
/* make physical attack without hitmsg */
alt_attk.adtyp = AD_PHYS;
return xmeleehurty(magr, mdef, &alt_attk, originalattk, weapon_p, FALSE, dmg, dieroll, vis, ranged);
}
else return MM_HIT;
}
case AD_LRVA:
/* print a basic hit message */
if (vis && dohitmsg) {