1
0
Fork 0
mirror of https://codeberg.org/noisytoot/notnotdnethack.git synced 2025-08-06 12:45:25 +01:00

Improve how HD breath is handled

This commit is contained in:
NeroOneTrueKing 2020-08-04 12:29:22 -05:00
parent d6b4a51a54
commit 7412ed24f8
4 changed files with 96 additions and 171 deletions

View file

@ -726,26 +726,33 @@ struct obj {
#define Dragon_shield_to_pm(obj) &mons[PM_GRAY_DRAGON + (obj)->otyp \
- GRAY_DRAGON_SCALE_SHIELD]
#define Dragon_to_scales(pm) (GRAY_DRAGON_SCALES + (pm - mons))
#define Have_same_dragon_armor_and_shield (Is_dragon_shield(uarms) && ((Is_dragon_scales(uarm) && Dragon_scales_to_pm(uarm) == Dragon_shield_to_pm(uarms)) ||\
(Is_dragon_mail(uarm) && Dragon_mail_to_pm(uarm) == Dragon_shield_to_pm(uarms)) ||\
(uarm->oartifact == ART_DRAGON_PLATE && (\
Dragon_shield_to_pm(uarms) == &mons[PM_SILVER_DRAGON] ||\
Dragon_shield_to_pm(uarms) == &mons[PM_BLACK_DRAGON] ||\
Dragon_shield_to_pm(uarms) == &mons[PM_BLUE_DRAGON] ||\
Dragon_shield_to_pm(uarms) == &mons[PM_RED_DRAGON] ||\
Dragon_shield_to_pm(uarms) == &mons[PM_WHITE_DRAGON] ||\
Dragon_shield_to_pm(uarms) == &mons[PM_GRAY_DRAGON] ||\
Dragon_shield_to_pm(uarms) == &mons[PM_ORANGE_DRAGON]\
)) ||\
(uarm->oartifact == ART_CHROMATIC_DRAGON_SCALES && (\
Dragon_shield_to_pm(uarms) == &mons[PM_BLACK_DRAGON] ||\
Dragon_shield_to_pm(uarms) == &mons[PM_RED_DRAGON] ||\
Dragon_shield_to_pm(uarms) == &mons[PM_BLUE_DRAGON] ||\
Dragon_shield_to_pm(uarms) == &mons[PM_WHITE_DRAGON] ||\
Dragon_shield_to_pm(uarms) == &mons[PM_YELLOW_DRAGON] ||\
Dragon_shield_to_pm(uarms) == &mons[PM_GREEN_DRAGON]\
))\
))
#define Dragon_armor_to_pm(obj) (\
Is_dragon_shield((obj)) ? Dragon_shield_to_pm((obj)) : \
Is_dragon_mail((obj)) ? Dragon_mail_to_pm((obj)) : \
Is_dragon_scales((obj)) ? Dragon_scales_to_pm((obj)) : (struct permonst*)0)
#define Dragon_armor_matches_mtyp(obj, mtyp) (\
(Dragon_armor_to_pm((obj)) == &mons[(mtyp)]) || \
((obj)->oartifact == ART_DRAGON_PLATE && ( \
(mtyp) == PM_SILVER_DRAGON || \
(mtyp) == PM_BLACK_DRAGON || \
(mtyp) == PM_BLUE_DRAGON || \
(mtyp) == PM_RED_DRAGON || \
(mtyp) == PM_WHITE_DRAGON || \
(mtyp) == PM_GRAY_DRAGON || \
(mtyp) == PM_ORANGE_DRAGON \
)) || \
((obj)->oartifact == ART_CHROMATIC_DRAGON_SCALES && (\
(mtyp) == PM_BLACK_DRAGON || \
(mtyp) == PM_RED_DRAGON || \
(mtyp) == PM_BLUE_DRAGON || \
(mtyp) == PM_WHITE_DRAGON || \
(mtyp) == PM_YELLOW_DRAGON || \
(mtyp) == PM_GREEN_DRAGON \
))\
)
/* Elven gear */
#define is_elven_weapon(otmp) ((otmp)->otyp == ELVEN_ARROW\
|| (otmp)->otyp == ELVEN_SPEAR\

View file

@ -536,32 +536,26 @@ boolean you_abilities;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_BOLD, buf, MENU_UNSELECTED);
if (mon_abilities && uarm && uarms &&
Is_dragon_armor(uarm) && Is_dragon_shield(uarms) &&
Have_same_dragon_armor_and_shield &&
(Dragon_armor_matches_mtyp(uarm, Dragon_armor_to_pm(uarms)->mtyp)
|| Dragon_armor_matches_mtyp(uarms, Dragon_armor_to_pm(uarm)->mtyp)) &&
uarm->age < monstermoves && uarms->age < monstermoves
){
if (!((Race_if(PM_HALF_DRAGON) &&
(((flags.HDbreath == AD_COLD) && (
(uarm && (uarm->otyp == WHITE_DRAGON_SCALES || uarm->otyp == WHITE_DRAGON_SCALE_MAIL)) ||
(uarms && uarms->otyp == WHITE_DRAGON_SCALE_SHIELD))) ||
((flags.HDbreath == AD_FIRE) && (
(uarm && (uarm->otyp == RED_DRAGON_SCALES || uarm->otyp == RED_DRAGON_SCALE_MAIL)) ||
(uarms && uarms->otyp == RED_DRAGON_SCALE_SHIELD))) ||
((flags.HDbreath == AD_SLEE) && (
(uarm && (uarm->otyp == ORANGE_DRAGON_SCALES || uarm->otyp == ORANGE_DRAGON_SCALE_MAIL)) ||
(uarms && uarms->otyp == ORANGE_DRAGON_SCALE_SHIELD))) ||
((flags.HDbreath == AD_ELEC) && (
(uarm && (uarm->otyp == BLUE_DRAGON_SCALES || uarm->otyp == BLUE_DRAGON_SCALE_MAIL)) ||
(uarms && uarms->otyp == BLUE_DRAGON_SCALE_SHIELD))) ||
((flags.HDbreath == AD_DRST) && (
(uarm && (uarm->otyp == GREEN_DRAGON_SCALES || uarm->otyp == GREEN_DRAGON_SCALE_MAIL)) ||
(uarms && uarms->otyp == GREEN_DRAGON_SCALE_SHIELD))) ||
((flags.HDbreath == AD_ACID) && (
(uarm && (uarm->otyp == YELLOW_DRAGON_SCALES || uarm->otyp == YELLOW_DRAGON_SCALE_MAIL)) ||
(uarms && uarms->otyp == YELLOW_DRAGON_SCALE_SHIELD))) ||
((flags.HDbreath == AD_MAGM) && (
(uarm && (uarm->otyp == GRAY_DRAGON_SCALES || uarm->otyp == GRAY_DRAGON_SCALE_MAIL)) ||
(uarms && uarms->otyp == GRAY_DRAGON_SCALE_SHIELD))))))
){
boolean armormatch = FALSE;
/* halfdragons combine armor breath with their own; don't list if it matches */
if (Race_if(PM_HALF_DRAGON)) {
int mtyp;
switch (flags.HDbreath) {
case AD_FIRE: mtyp = PM_RED_DRAGON; break;
case AD_COLD: mtyp = PM_WHITE_DRAGON; break;
case AD_ELEC: mtyp = PM_BLUE_DRAGON; break;
case AD_DRST: mtyp = PM_GREEN_DRAGON; break;
case AD_SLEE: mtyp = PM_ORANGE_DRAGON; break;
case AD_ACID: mtyp = PM_YELLOW_DRAGON; break;
}
/* note: when shield and armor match despite color differences, it is the shield's color that is used */
armormatch = Dragon_shield_to_pm(uarms) == &mons[mtyp];
}
if (!armormatch) {
add_ability('a', "Use your armor's breath weapon", MATTK_DSCALE);
}
}

View file

@ -867,136 +867,52 @@ int
dobreathe(mdat)
struct permonst *mdat;
{
struct zapdata zapdata;
struct attack *mattk;
if (Strangled) {
You_cant("breathe. Sorry.");
return(0);
}
if (u.uen < 15) {
You("don't have enough energy to breathe!");
return(0);
}
losepw(15);
flags.botl = 1;
struct attack mattk;
int powermult = 100;
if (!getdir((char *)0)) return(0);
mattk = attacktype_fordmg(mdat, AT_BREA, AD_ANY);
if(!mattk && Race_if(PM_HALF_DRAGON)) mattk = attacktype_fordmg(&mons[PM_HALF_DRAGON], AT_BREA, AD_ANY);
if (!mattk)
impossible("bad breath attack?"); /* mouthwash needed... */
else{
int type = mattk->adtyp;
double multiplier = 1.0;
if(type == AD_HDRG){
type = flags.HDbreath;
if(type == AD_SLEE) multiplier = 4.0;
{
struct attack * aptr;
aptr = attacktype_fordmg(mdat, AT_BREA, AD_ANY);
if (!aptr && Race_if(PM_HALF_DRAGON)) aptr = attacktype_fordmg(&mons[PM_HALF_DRAGON], AT_BREA, AD_ANY);
if (!aptr) {
impossible("bad breath attack?");
return 0;
}
basiczap(&zapdata, type, ZAP_BREATH, 0); /* begin setup of zapdata */
if(Race_if(PM_HALF_DRAGON)){
// give Half-dragons a +0.5 bonus per armor piece that matches their default breath
if (flags.HDbreath == AD_FIRE){
if (uarm){
if (Is_dragon_scales(uarm) && Dragon_scales_to_pm(uarm) == &mons[PM_RED_DRAGON])
multiplier += 0.5;
if (Is_dragon_mail(uarm) && Dragon_mail_to_pm(uarm) == &mons[PM_RED_DRAGON])
multiplier += 0.5;
}
if (uarms){
if (Is_dragon_shield(uarms) && Dragon_shield_to_pm(uarms) == &mons[PM_RED_DRAGON])
multiplier += 0.5;
}
} else if (flags.HDbreath == AD_COLD){
if (uarm){
if (Is_dragon_scales(uarm) && Dragon_scales_to_pm(uarm) == &mons[PM_WHITE_DRAGON])
multiplier += 0.5;
if (Is_dragon_mail(uarm) && Dragon_mail_to_pm(uarm) == &mons[PM_WHITE_DRAGON])
multiplier += 0.5;
}
if (uarms){
if (Is_dragon_shield(uarms) && Dragon_shield_to_pm(uarms) == &mons[PM_WHITE_DRAGON])
multiplier += 0.5;
}
} else if (flags.HDbreath == AD_ELEC){
if (uarm){
if (Is_dragon_scales(uarm) && Dragon_scales_to_pm(uarm) == &mons[PM_BLUE_DRAGON])
multiplier += 0.5;
if (Is_dragon_mail(uarm) && Dragon_mail_to_pm(uarm) == &mons[PM_BLUE_DRAGON])
multiplier += 0.5;
}
if (uarms){
if (Is_dragon_shield(uarms) && Dragon_shield_to_pm(uarms) == &mons[PM_BLUE_DRAGON])
multiplier += 0.5;
}
} else if (flags.HDbreath == AD_DRST){
if (uarm){
if (Is_dragon_scales(uarm) && Dragon_scales_to_pm(uarm) == &mons[PM_GREEN_DRAGON])
multiplier += 0.5;
if (Is_dragon_mail(uarm) && Dragon_mail_to_pm(uarm) == &mons[PM_GREEN_DRAGON])
multiplier += 0.5;
}
if (uarms){
if (Is_dragon_shield(uarms) && Dragon_shield_to_pm(uarms) == &mons[PM_GREEN_DRAGON])
multiplier += 0.5;
}
} else if (flags.HDbreath == AD_SLEE){
if (uarm){
if (Is_dragon_scales(uarm) && Dragon_scales_to_pm(uarm) == &mons[PM_ORANGE_DRAGON])
multiplier += 2.0;
if (Is_dragon_mail(uarm) && Dragon_mail_to_pm(uarm) == &mons[PM_ORANGE_DRAGON])
multiplier += 2.0;
}
if (uarms){
if (Is_dragon_shield(uarms) && Dragon_shield_to_pm(uarms) == &mons[PM_ORANGE_DRAGON])
multiplier += 2.0;
}
} else if (flags.HDbreath == AD_ACID){
if (uarm){
if (Is_dragon_scales(uarm) && Dragon_scales_to_pm(uarm) == &mons[PM_YELLOW_DRAGON])
multiplier += 0.5;
if (Is_dragon_mail(uarm) && Dragon_mail_to_pm(uarm) == &mons[PM_YELLOW_DRAGON])
multiplier += 0.5;
}
if (uarms){
if (Is_dragon_shield(uarms) && Dragon_shield_to_pm(uarms) == &mons[PM_YELLOW_DRAGON])
multiplier += 0.5;
}
}
// Chromatic/Platinum dragon gear is never going to naturally apply
// Because it's black/silver, so give it appropriate buffs here
if (((uarm && uarm->oartifact == ART_CHROMATIC_DRAGON_SCALES) ||
(uarms && uarms->oartifact == ART_CHROMATIC_DRAGON_SCALES)) &&
(flags.HDbreath == AD_FIRE || flags.HDbreath == AD_COLD ||
flags.HDbreath == AD_ELEC || flags.HDbreath == AD_DRST ||
flags.HDbreath == AD_ACID))
multiplier += 0.5;
if (uarm && uarm->oartifact == ART_DRAGON_PLATE &&
(flags.HDbreath == AD_FIRE || flags.HDbreath == AD_COLD ||
flags.HDbreath == AD_ELEC || flags.HDbreath == AD_SLEE))
multiplier += (flags.HDbreath == AD_SLEE)?2.0:0.5;
}
if(carrying_art(ART_DRAGON_S_HEART_STONE))
multiplier *= 2;
/* dragon-breath is hard to reflect */
if (is_true_dragon(mdat) || (Race_if(PM_HALF_DRAGON) && u.ulevel >= 14))
zapdata.unreflectable = ZAP_REFL_ADVANCED;
/* find damage */
zapdata.damn = mattk->damn + (u.ulevel / 2);
zapdata.damd = (mattk->damd ? mattk->damd : 6) * multiplier;
/* do the zap */
zap(&youmonst, u.ux, u.uy, u.dx, u.dy, rn1(7, 7), &zapdata);
mattk = *aptr;
}
return(1);
if (Race_if(PM_HALF_DRAGON) && (mattk.adtyp == AD_HDRG || flags.HDbreath == mattk.adtyp)) {
/* HalfDragons get a +0.5x bonus per armor piece that matches their default breath */
int mtyp;
switch (flags.HDbreath)
{
case AD_FIRE: mtyp = PM_RED_DRAGON; break;
case AD_COLD: mtyp = PM_WHITE_DRAGON; break;
case AD_ELEC: mtyp = PM_BLUE_DRAGON; break;
case AD_DRST: mtyp = PM_GREEN_DRAGON; break;
case AD_SLEE: mtyp = PM_ORANGE_DRAGON; break;
case AD_ACID: mtyp = PM_YELLOW_DRAGON; break;
default:
impossible("bad HDbreath %d", flags.HDbreath);
return 0;
}
if (uarm && Dragon_armor_matches_mtyp(uarm, mtyp))
powermult += 50;
if (uarms && Dragon_armor_matches_mtyp(uarms, mtyp))
powermult += 50;
}
if(carrying_art(ART_DRAGON_S_HEART_STONE))
powermult *= 2;
/* use powermult to increase the damage dealt */
mattk.damd = (mattk.damd ? mattk.damd : 6) * powermult / 100;
/* use xbreathey to do the attack */
return xbreathey(&youmonst, &mattk, 0, 0);
}
int

View file

@ -2597,8 +2597,6 @@ boolean stoponhit;
*
* magr is breathing at (tarx, tary)
*
* The player's version is fairly separate, and is in polyself.c
* TODO: make #monster use this function; add additional functionality to make that possible
*/
boolean
xbreathey(magr, attk, tarx, tary)
@ -2665,6 +2663,16 @@ int tary;
}
}
/* player uses Pw to breathe instead of having a cooldown */
if (youagr) {
if (u.uen < 15) {
You("don't have enough energy to breathe!");
return(0);
}
losepw(15);
flags.botl = 1;
}
/* message */
if (youagr) {
You("breathe %s!", breathwep(typ));