1
0
Fork 0
mirror of https://codeberg.org/noisytoot/notnotdnethack.git synced 2025-08-10 22:51:38 +01:00

Merge pull request #75 from NeroOneTrueKing/devel-monster-weapon-specials

Change: Non-physical-damage weapon attacks
This commit is contained in:
Chris-plus-alphanumericgibberish 2018-02-23 12:20:57 -05:00 committed by GitHub
commit dbf3727133
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 159 additions and 17 deletions

View file

@ -1001,6 +1001,8 @@ hitmm(magr, mdef, mattk)
Sprintf(buf,"%s squeezes", magr_name);
break;
}
case AT_NONE:
break;
default:
defaultmmhit:
if (is_weeping(magr->data)) {
@ -1193,6 +1195,8 @@ mdamagem(magr, mdef, mattk)
int armpro, num, tmp = d((int)mattk->damn, (int)mattk->damd);
boolean cancelled;
boolean phasearmor = FALSE;
boolean weaponhit = (mattk->aatyp == AT_WEAP || mattk->aatyp == AT_XWEP || mattk->aatyp == AT_DEVA);
struct attack alt_attk;
if(magr->mflee && pa == &mons[PM_BANDERSNATCH]) tmp = d((int)mattk->damn, 2*(int)mattk->damd);
@ -1236,7 +1240,7 @@ mdamagem(magr, mdef, mattk)
armpro = magic_negation(mdef);
cancelled = magr->mcan || !((rn2(3) >= armpro) || !rn2(50));
switch(mattk->adtyp) {
switch (weaponhit ? AD_PHYS : mattk->adtyp) {
case AD_DGST:
/* eating a Rider or its corpse is fatal */
if (is_rider(mdef->data)) {
@ -1332,7 +1336,7 @@ physical:{
oarm = which_armor(magr, W_ARMG);
if (mattk->aatyp == AT_KICK && thick_skinned(pd)) {
tmp = 0;
} else if(mattk->aatyp == AT_WEAP || mattk->aatyp == AT_DEVA || mattk->aatyp == AT_XWEP) {
} else if(weaponhit) {
if(otmp) {
if (otmp->otyp == CORPSE &&
touch_petrifies(&mons[otmp->corpsenm]))
@ -1419,6 +1423,39 @@ physical:{
if (otmp && tmp)
mrustm(magr, mdef, otmp);
}
// tack on bonus elemental damage, if applicable
if (mattk->adtyp != AD_PHYS){
alt_attk.aatyp = AT_NONE;
alt_attk.adtyp = mattk->adtyp;
switch (alt_attk.adtyp)
{
case AD_FIRE:
case AD_COLD:
case AD_ELEC:
case AD_ACID:
alt_attk.damn = 4;
alt_attk.damd = 6;
break;
case AD_EFIR:
case AD_ECLD:
case AD_EELC:
case AD_EACD:
alt_attk.damn = 3;
alt_attk.damd = 7;
break;
case AD_STUN:
alt_attk.damn = 1;
alt_attk.damd = 4;
break;
default:
alt_attk.damn = 0;
alt_attk.damd = 0;
break;
}
mdamagem(magr, mdef, &alt_attk);
if (DEADMONSTER(mdef))
return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
}
} else if (magr->data == &mons[PM_PURPLE_WORM] &&
mdef->data == &mons[PM_SHRIEKER]) {
/* hack to enhance mm_aggression(); we don't want purple

View file

@ -102,6 +102,8 @@ register struct attack *mattk;
case AT_BOOM:
pline("%s explodes!", Monnam(mtmp));
break;
case AT_NONE:
break;
default:
pline("%s hits!", Monnam(mtmp));
}
@ -148,7 +150,7 @@ mpoisons_subj(mtmp, mattk)
struct monst *mtmp;
struct attack *mattk;
{
if (mattk->aatyp == AT_WEAP || mattk->aatyp == AT_XWEP) {
if (mattk->aatyp == AT_WEAP || mattk->aatyp == AT_XWEP || mattk->aatyp == AT_DEVA) {
struct obj *mwep = (mtmp == &youmonst) ? uwep : MON_WEP(mtmp);
/* "Foo's attack was poisoned." is pretty lame, but at least
it's better than "sting" when not a stinging attack... */
@ -172,7 +174,9 @@ struct attack *mattk;
return (mattk->aatyp == AT_TUCH || mattk->aatyp == AT_5SQR) ? "contact" :
(mattk->aatyp == AT_GAZE) ? "gaze" :
(mattk->aatyp == AT_ENGL) ? "vapor" :
(mattk->aatyp == AT_BITE || mattk->aatyp == AT_LNCK) ? "bite" : "sting";
(mattk->aatyp == AT_BITE || mattk->aatyp == AT_LNCK) ? "bite" :
(mattk->aatyp == AT_NONE) ? "attack" :
"sting";
}
}
@ -1544,9 +1548,11 @@ hitmu(mtmp, mattk)
struct obj *optr;
int dmg, armpro, permdmg;
boolean phasearmor = FALSE;
boolean weaponhit = (mattk->aatyp == AT_WEAP || mattk->aatyp == AT_XWEP || mattk->aatyp == AT_DEVA);
char buf[BUFSZ];
struct permonst *olduasmon = youracedata;
int res;
struct attack alt_attk;
if (!canspotmon(mtmp))
map_invisible(mtmp->mx, mtmp->my);
@ -1593,7 +1599,7 @@ hitmu(mtmp, mattk)
//uncancelled = !mtmp->mcan && ((rn2(3) >= armpro) || !rn2(50));
permdmg = 0;
/* Now, adjust damages via resistances or specific attacks */
switch(mattk->adtyp) {
switch(weaponhit ? AD_PHYS : mattk->adtyp) {
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
case AD_HODS:
@ -1711,7 +1717,7 @@ hitmu(mtmp, mattk)
}
if(oarm && dmg && oarm->otyp == GAUNTLETS_OF_POWER) dmg += 16;
} else { /* hand to hand weapon */
if((mattk->aatyp == AT_WEAP || mattk->aatyp == AT_XWEP) && otmp) {
if((weaponhit) && otmp) {
if (otmp->otyp == CORPSE &&
touch_petrifies(&mons[otmp->corpsenm])) {
dmg = 1;
@ -1830,6 +1836,37 @@ hitmu(mtmp, mattk)
if(oarm && dmg && oarm->otyp == GAUNTLETS_OF_POWER) dmg += 8;
hitmsg(mtmp, mattk);
}
// tack on bonus elemental damage, if applicable
if (mattk->adtyp != AD_PHYS){
alt_attk.aatyp = AT_NONE;
alt_attk.adtyp = mattk->adtyp;
switch (alt_attk.adtyp)
{
case AD_FIRE:
case AD_COLD:
case AD_ELEC:
case AD_ACID:
alt_attk.damn = 4;
alt_attk.damd = 6;
break;
case AD_EFIR:
case AD_ECLD:
case AD_EELC:
case AD_EACD:
alt_attk.damn = 3;
alt_attk.damd = 7;
break;
case AD_STUN:
alt_attk.damn = 1;
alt_attk.damd = 4;
break;
default:
alt_attk.damn = 0;
alt_attk.damd = 0;
break;
}
hitmu(mtmp, &alt_attk);
}
}
}break;
///////////////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -1990,7 +1990,7 @@ then fill new spaces with our spawn!
MA_MINION /*MA*/, MV_EXTRAMISSION|MV_SEE_INVIS /*MV*/, HI_LORD),
MON("Domiel", S_LAW_ANGEL,//
LVL(72, 17,-7, 77, 20), (G_PLANES|G_NOCORPSE|G_NOGEN|G_UNIQ),
A(ATTK(AT_WEAP, AD_PHYS, 3, 7), ATTK(AT_WEAP, AD_EFIR, 3, 7),
A(ATTK(AT_WEAP, AD_EFIR, 3, 7), ATTK(AT_WEAP, AD_EFIR, 3, 7),
ATTK(AT_MAGC, AD_CLRC, 0, 7),
NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_HUMAN, 400, 0, MS_CUSS, MZ_HUMAN),
@ -2050,8 +2050,8 @@ then fill new spaces with our spawn!
MON("Movanic Deva", S_NEU_ANGEL,//11 /*Needs tile*/
LVL(8, 12, 0, 30, 0), (G_PLANES|G_SGROUP|G_NOCORPSE|1),
A(ATTK(AT_WEAP, AD_PHYS, 2, 6), ATTK(AT_WEAP, AD_FIRE, 4, 6),
ATTK(AT_MAGC, AD_CLRC, 0, 6), NO_ATTK, NO_ATTK, NO_ATTK),
A(ATTK(AT_WEAP, AD_FIRE, 4, 6), ATTK(AT_MAGC, AD_CLRC, 0, 6),
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_HUMAN, 400, 0, MS_CUSS, MZ_HUMAN),
MR_COLD|MR_ELEC|MR_ACID|MR_STONE|MR_SLEEP|MR_POISON, 0,
MM_FLY /*MM*/, MT_STALK|MT_COLLECT /*MT*/,
@ -5222,7 +5222,7 @@ is a red right hand
MA_UNLIVING|MA_DEMON|MA_PRIMORDIAL|MA_INSECTOID /*MA*/, MV_EXTRAMISSION|MV_SEE_INVIS|MV_LIFESENSE|MV_OMNI /*MV*/, CLR_BRIGHT_MAGENTA),
MON("balrog", S_DEMON,//22
LVL(16, 5, -12, 75, -14), (G_HELL|G_NOCORPSE|2),
A(ATTK(AT_WEAP, AD_PHYS, 2, 8), ATTK(AT_WEAP, AD_FIRE, 4, 6),
A(ATTK(AT_WEAP, AD_FIRE, 2, 4), ATTK(AT_XWEP, AD_FIRE, 2, 4),
ATTK(AT_BOOM,AD_FIRE, 11, 11),
NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_LARGE, 400, 0, MS_SILENT, MZ_LARGE), MR_FIRE|MR_POISON, 0,
@ -5417,8 +5417,8 @@ is a red right hand
MA_DEMON|MA_ARACHNID|MA_ELF|MA_DROW|MA_PRIMORDIAL /*MA*/, MV_DARKSIGHT|MV_INFRAVISION|MV_SEE_INVIS /*MV*/, HI_LORD),
MON("Graz'zt", S_DEMON,//38
LVL(66, 18, -26, 66, -15), (G_HELL|G_NOCORPSE|G_NOGEN|G_UNIQ),
A(ATTK(AT_CLAW, AD_SSEX, 1, 6), ATTK(AT_WEAP, AD_PHYS, 2, 8),
ATTK(AT_WEAP, AD_ACID, 4, 8), ATTK(AT_MAGC, AD_SPEL, 6, 6),
A(ATTK(AT_CLAW, AD_SSEX, 1, 6), ATTK(AT_WEAP, AD_ACID, 4, 8),
ATTK(AT_MAGC, AD_SPEL, 6, 6), NO_ATTK,
NO_ATTK, NO_ATTK),
SIZ(WT_MEDIUM, 500, 0, MS_ORC, MZ_HUMAN), MR_FIRE|MR_POISON, 0,
MM_FLY /*MM*/, MT_STALK|MT_HOSTILE|MT_COLLECT|MT_WAITFORU|MT_WANTSAMUL|MT_TRAITOR /*MT*/,
@ -6655,7 +6655,7 @@ is a red right hand
MA_HUMAN|MA_ELF /*MA*/, MV_LOWLIGHT2 /*MV*/, CLR_BRIGHT_GREEN),
MON("Durin's Bane", S_DEMON,// /*Needs encyc entry*//*Needs tile*/
LVL(24, 7, -13, 80, -14), (G_NOCORPSE|G_NOGEN|G_UNIQ),
A(ATTK(AT_WEAP, AD_PHYS, 8, 4), ATTK(AT_WEAP, AD_FIRE, 4, 6),
A(ATTK(AT_WEAP, AD_FIRE, 8, 2), ATTK(AT_XWEP, AD_FIRE, 8, 2),
ATTK(AT_BOOM,AD_FIRE, 11, 11), NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_LARGE, 400, 0, MS_NEMESIS, MZ_LARGE), MR_FIRE|MR_POISON, 0,
MM_FLY /*MM*/, MT_STALK|MT_HOSTILE|MT_CLOSE|MT_WAITFORU|MT_COLLECT /*MT*/,
@ -6806,7 +6806,7 @@ is a red right hand
MA_REPTILIAN /*MA*/, MV_NORMAL|MV_INFRAVISION|MV_SCENT /*MV*/, HI_LORD),
MON("Master Assassin", S_HUMAN,//20
LVL(15, 12, 0, 30, 18), (G_NOGEN|G_UNIQ),
A(ATTK(AT_WEAP, AD_DRST, 2, 6), ATTK(AT_WEAP, AD_PHYS, 2, 8),
A(ATTK(AT_WEAP, AD_DRST, 2, 6), ATTK(AT_XWEP, AD_DRST, 2, 6),
ATTK(AT_CLAW, AD_SQUE, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_HUMAN, 400, 0, MS_NEMESIS, MZ_HUMAN), MR_STONE, 0,
0 /*MM*/, MT_OMNIVORE|MT_WANTSARTI|MT_WAITFORU|MT_HOSTILE|MT_STALK|MT_COLLECT|MT_MAGIC /*MT*/,

View file

@ -25,6 +25,9 @@ STATIC_DCL char * get_mb_description_of_monster_type(struct monst *, char *);
STATIC_DCL char * get_mv_description_of_monster_type(struct monst *, char *);
STATIC_DCL char * get_mg_description_of_monster_type(struct monst *, char *);
STATIC_DCL char * get_speed_description_of_monster_type(struct monst *, char *);
STATIC_DCL char * get_description_of_attack_type(uchar);
STATIC_DCL char * get_description_of_damage_type(uchar);
STATIC_DCL char * get_description_of_damage_prefix(uchar, uchar);
STATIC_DCL int generate_list_of_resistances(struct monst *, char *, int);
#ifdef PORT_HELP
extern void NDECL(port_help);
@ -1813,6 +1816,36 @@ get_description_of_damage_type(uchar id)
}
}
char *
get_description_of_damage_prefix(uchar aatyp, uchar adtyp)
{
switch (aatyp)
{
case AT_WEAP:
case AT_XWEP:
case AT_DEVA:
switch (adtyp)
{
case AD_PHYS:
return "";
case AD_FIRE:
case AD_COLD:
case AD_ELEC:
case AD_ACID:
return "physical + 4d6 ";
case AD_EFIR:
case AD_ECLD:
case AD_EELC:
case AD_EACD:
return "physical + 3d7 ";
default:
return "physical + ";
}
break;
}
return "";
}
char *
get_description_of_attack(struct attack *mattk, char * main_temp_buf)
{
@ -1837,7 +1870,7 @@ get_description_of_attack(struct attack *mattk, char * main_temp_buf)
strcat(main_temp_buf, " ");
}
#endif
sprintf(temp_buf, "%s - %s", get_description_of_attack_type(mattk->aatyp), get_description_of_damage_type(mattk->adtyp));
sprintf(temp_buf, "%s - %s%s", get_description_of_attack_type(mattk->aatyp), get_description_of_damage_prefix(mattk->aatyp, mattk->adtyp), get_description_of_damage_type(mattk->adtyp));
strcat(main_temp_buf, temp_buf);
#ifdef USE_TILES
strcat(main_temp_buf, "; ");

View file

@ -2713,6 +2713,8 @@ register struct attack *mattk;
register int tmp = d((int)mattk->damn, (int)mattk->damd);
int armpro;
boolean negated, phasearmor = FALSE;
boolean weaponhit = (mattk->aatyp == AT_WEAP || mattk->aatyp == AT_XWEP || mattk->aatyp == AT_DEVA);
struct attack alt_attk;
armpro = magic_negation(mdef);
/* since hero can't be cancelled, only defender's armor applies */
@ -2726,7 +2728,7 @@ register struct attack *mattk;
demonpet();
return(0);
}
switch(mattk->adtyp) {
switch (weaponhit ? AD_PHYS : mattk->adtyp) {
case AD_STUN:
if(!Blind)
pline("%s %s for a moment.", Monnam(mdef),
@ -2743,8 +2745,41 @@ register struct attack *mattk;
case AD_HEAL: /* likewise */
case AD_PHYS:
physical:
if(mattk->aatyp == AT_WEAP || mattk->aatyp == AT_XWEP) {
if(weaponhit) {
if(uwep) tmp = 0;
// tack on bonus elemental damage, if applicable
if (mattk->adtyp != AD_PHYS){
alt_attk.aatyp = AT_NONE;
alt_attk.adtyp = mattk->adtyp;
switch (alt_attk.adtyp)
{
case AD_FIRE:
case AD_COLD:
case AD_ELEC:
case AD_ACID:
alt_attk.damn = 4;
alt_attk.damd = 6;
break;
case AD_EFIR:
case AD_ECLD:
case AD_EELC:
case AD_EACD:
alt_attk.damn = 3;
alt_attk.damd = 7;
break;
case AD_STUN:
alt_attk.damn = 1;
alt_attk.damd = 4;
break;
default:
alt_attk.damn = 0;
alt_attk.damd = 0;
break;
}
damageum(mdef, &alt_attk);
if (DEADMONSTER(mdef))
return 2;
}
} else if(mattk->aatyp == AT_KICK) {
if(thick_skinned(mdef->data)) tmp = 0;
if(insubstantial(mdef->data)) {