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:
commit
f749a4901a
15 changed files with 442 additions and 12 deletions
|
@ -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));
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 ??? */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
27
src/mon.c
27
src/mon.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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){
|
||||
|
|
10
src/monst.c
10
src/monst.c
|
@ -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),
|
||||
|
|
53
src/sounds.c
53
src/sounds.c
|
@ -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.";
|
||||
|
|
|
@ -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;
|
||||
|
|
20
src/trap.c
20
src/trap.c
|
@ -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;
|
||||
|
|
10
src/wizard.c
10
src/wizard.c
|
@ -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
|
||||
|
|
238
src/xhity.c
238
src/xhity.c
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue