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:
parent
d6b4a51a54
commit
7412ed24f8
4 changed files with 96 additions and 171 deletions
|
@ -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\
|
||||
|
|
42
src/cmd.c
42
src/cmd.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
166
src/polyself.c
166
src/polyself.c
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue