1
0
Fork 0
mirror of https://codeberg.org/noisytoot/notnotdnethack.git synced 2025-05-02 13:25:10 +01:00

Merge branch 'devel-3.22.1' of https://github.com/Chris-plus-alphanumericgibberish/dNAO.git into devel-3.22.1

# Conflicts:
#	src/weapon.c
This commit is contained in:
chris 2024-03-23 18:32:03 -04:00
commit 846dfdde92
15 changed files with 372 additions and 196 deletions

View file

@ -3270,6 +3270,7 @@ E void FDECL(setmwielded, (struct monst *, struct obj *, long));
E void FDECL(setmnotwielded, (struct monst *, struct obj *));
E void FDECL(init_mon_wield_item, (struct monst *));
E int NDECL(abon);
E float FDECL(atr_dbon, (struct obj *, struct monst *, int));
E int FDECL(dbon, (struct obj *, struct monst *));
E void NDECL(reset_skills);
E boolean FDECL(fake_skill, (int));

View file

@ -5170,8 +5170,8 @@ boolean printmessages;
}
}
if(otmp->otyp == BESTIAL_CLAW){
int insight_mod;
int studystack;
int insight_mod = 0;
int studystack = 0;
if(youagr){
if(active_glyph(BEASTS_EMBRACE))
insight_mod = 30*pow(.97,u.uinsight);
@ -9489,7 +9489,7 @@ arti_invoke(obj)
x=u.dx;y=u.dy;
getLoc = FALSE;
}
verbalize("Even Stars Fall");
verbalize("Even Stars Fall.");
for (; starfall > 0; starfall--){
if(getLoc){
x = rn2(COLNO-2)+1;

106
src/do.c
View file

@ -2576,91 +2576,49 @@ long timeout;
int
donull()
{
static long lastreped = -13;//hacky way to tell if the player has recently tried repairing themselves
static long lastreped = -13; // counter to tell if you recently tried to repair yourself/meditate
u.unull = TRUE;
int regen = 0;
if(uclockwork){
if(!Upolyd && u.uhp<u.uhpmax){
int *hp = (Upolyd) ? (&u.mh) : (&u.uhp);
int *hpmax = (Upolyd) ? (&u.mhmax) : (&u.uhpmax);
if ((*hp) < (*hpmax)){
if (uclockwork) {
if(lastreped < monstermoves-13) You("attempt to make repairs.");
if(!rn2(15-u.ulevel/2)){
u.uhp += rnd(10);
if(!rn2(15 - u.ulevel/2)){
(*hp) += rnd(10);
flags.botl = 1;
}
if(uwep && uwep->oartifact == ART_SINGING_SWORD && uwep->osinging == OSING_HEALING){
u.uhp++;
}
if(u.uhp > u.uhpmax) u.uhp = u.uhpmax;
lastreped = monstermoves;
if(u.uhp == u.uhpmax){
regen = 1;
} else if (uandroid && u.uen > 0) {
(*hp) += u.ulevel/6+1;
if(rn2(6) < u.ulevel%6) (*hp) += 1;
u.uen--;
flags.botl = 1;
regen = 1;
}
if (uwep && uwep->oartifact == ART_SINGING_SWORD && uwep->osinging == OSING_HEALING){
(*hp) += 1;
regen = 2;
}
if ((*hp) >= (*hpmax) && regen > 0){
if(uclockwork && lastreped == monstermoves){
You("complete your repairs.");
lastreped = -13;
stop_occupation();
occupation = 0; /*redundant failsafe? why doesn't stop_occupation work?*/
}
} else if(Upolyd && u.mh<u.mhmax){
if(lastreped < monstermoves-100) You("attempt to make repairs.");
if(!rn2(15-u.ulevel/2)){
u.mh += rnd(10);
flags.botl = 1;
}
if(uwep && uwep->oartifact == ART_SINGING_SWORD && uwep->osinging == OSING_HEALING){
u.mh++;
}
if(u.mh > u.mhmax) u.mh = u.mhmax;
lastreped = monstermoves;
if(u.mh == u.mhmax){
You("complete your repairs.");
lastreped = -13;
stop_occupation();
occupation = 0; /*redundant failsafe? why doesn't stop_occupation work?*/
}
} else if(u.sealsActive&SEAL_EURYNOME && ++u.eurycounts>5) unbind(SEAL_EURYNOME,TRUE);
} else if(uandroid){
if(!Upolyd && u.uhp<u.uhpmax && u.uen > 0){
u.uhp += u.ulevel/6+1;
if(rn2(6) < u.ulevel%6)
u.uhp++;
flags.botl = 1;
u.uen--;
if(uwep && uwep->oartifact == ART_SINGING_SWORD && uwep->osinging == OSING_HEALING){
u.uhp++;
}
if(u.uhp > u.uhpmax) u.uhp = u.uhpmax;
if(u.uhp == u.uhpmax){
} else if (uandroid && regen == 1){
You("finish regenerating.");
stop_occupation();
occupation = 0; /*redundant failsafe? why doesn't stop_occupation work?*/
}
} else if(Upolyd && u.mh<u.mhmax && u.uen > 0){
u.mh += u.ulevel/3+1;
flags.botl = 1;
u.uen--;
if(uwep && uwep->oartifact == ART_SINGING_SWORD && uwep->osinging == OSING_HEALING){
u.uhp++;
}
if(u.mh > u.mhmax) u.mh = u.mhmax;
if(u.mh == u.mhmax){
You("finish regenerating.");
stop_occupation();
occupation = 0; /*redundant failsafe? why doesn't stop_occupation work?*/
}
} else if(u.sealsActive&SEAL_EURYNOME && ++u.eurycounts>5) unbind(SEAL_EURYNOME,TRUE);
} else {
if(Role_if(PM_MONK)){
if(lastreped < monstermoves-13) You("meditate.");
lastreped = monstermoves;
}
else if(u.sealsActive&SEAL_EURYNOME && ++u.eurycounts>5) unbind(SEAL_EURYNOME,TRUE);
if(Upolyd && u.uhp<u.uhpmax){
if(uwep && uwep->oartifact == ART_SINGING_SWORD && uwep->osinging == OSING_HEALING){
u.mh++;
}
} else if(!Upolyd && u.uhp<u.uhpmax){
if(uwep && uwep->oartifact == ART_SINGING_SWORD && uwep->osinging == OSING_HEALING){
u.uhp++;
} else if (regen == 2){
Your("sword hums contentedly.");
}
stop_occupation();
(*hp) = (*hpmax);
}
} else if (!Role_if(PM_MONK) && u.sealsActive&SEAL_EURYNOME && ++u.eurycounts>5) {
// monks meditate & fast, increasing pw regen and lowering hunger rate while they haven't moved
unbind(SEAL_EURYNOME,TRUE);
}
return MOVE_STANDARD; /* Do nothing, but let other things happen */
}

View file

@ -2348,7 +2348,7 @@ struct obj * otmp;
break;
case ART_SCORPION_CARAPACE:
if(check_carapace_mod(otmp, CPROP_PLATES))
def = 7;
def += 5;
else if(check_carapace_mod(otmp, CPROP_HARD_SCALE))
def += 1;//offsetting the chitin material
break;
@ -2449,7 +2449,7 @@ struct obj * otmp;
break;
case ART_SCORPION_CARAPACE:
if(check_carapace_mod(otmp, CPROP_PLATES))
def = 7;
def += 5;
else if(check_carapace_mod(otmp, CPROP_HARD_SCALE))
def += 1;//offsetting the chitin material
break;

View file

@ -2,6 +2,7 @@
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
#include <math.h>
#include "hack.h"
#include "artifact.h"
@ -2820,6 +2821,10 @@ winid *datawin;
int lspe_mult = dmgval_core(&wdice[1], TRUE, obj, otyp, &youmonst); // large dice
int enc_bonus = (obj) ? (obj->spe) : 0;
if (otyp == CRYSTAL_SWORD) enc_bonus += enc_bonus / 3;
if (otyp == SEISMIC_HAMMER) {
wdice[0].oc_damd += 3*enc_bonus;
wdice[1].oc_damd += 3*enc_bonus;
}
Sprintf(buf, "Damage: ");
@ -2999,24 +3004,26 @@ winid *datawin;
/* other weapon special effects */
if(obj){
int ldamd = objects[otyp].oc_wldam.oc_damd;
int sdamd = objects[otyp].oc_wsdam.oc_damd;
if(obj->otyp == TORCH){
Sprintf(buf2, "Deals 1d10%s bonus fire damage when lit.", (obj->spe ? sitoa(obj->spe) : ""));
Sprintf(buf2, "When lit, deals +1d10%s fire damage.", (obj->spe ? sitoa(obj->spe) : ""));
OBJPUTSTR(buf2);
}
if(obj->otyp == MAGIC_TORCH){
Sprintf(buf2, "Deals 1d8%s fire damage when lit.", (obj->spe ? sitoa(2*obj->spe) : ""));
Sprintf(buf2, "When lit, deals +1d8%s fire damage.", (obj->spe ? sitoa(2*obj->spe) : ""));
OBJPUTSTR(buf2);
}
if(obj->otyp == SHADOWLANDER_S_TORCH){
Sprintf(buf2, "Deals 1d10%s bonus cold damage when lit.", (obj->spe ? sitoa(obj->spe) : ""));
Sprintf(buf2, "When lit, deals +1d10%s cold damage.", (obj->spe ? sitoa(obj->spe) : ""));
OBJPUTSTR(buf2);
}
if(obj->otyp == SUNROD){
Sprintf(buf2, "Deals 1d10%s bonus lightning and acid damage when lit.", (obj->spe ? sitoa(obj->spe) : ""));
Sprintf(buf2, "When lit, deals +1d10%s lightning and acid damage and may blind struck targets.", (obj->spe ? sitoa(obj->spe) : ""));
OBJPUTSTR(buf2);
}
if(obj->otyp == KAMEREL_VAJRA){
Sprintf(buf2, "Deals 2d6 bonus lightning damage when lit, or 6d6 if wielded by an Ara Kamerel.");
Sprintf(buf2, "When lit, deals +2d6 lightning damage, or +6d6 if wielded by an Ara Kamerel, and may blind struck targets.");
OBJPUTSTR(buf2);
}
if(obj->otyp == VIPERWHIP && obj->ovar1_heads > 1){
@ -3024,7 +3031,7 @@ winid *datawin;
OBJPUTSTR(buf2);
}
if(obj->otyp == MIRRORBLADE){
Sprintf(buf2, "May use a weapon-wielding opponent's own weapon against them.");
Sprintf(buf2, "Uses a weapon-wielding opponent's own weapon against them, if their damage is higher.");
OBJPUTSTR(buf2);
}
if(obj->otyp == CRYSTAL_SWORD && obj->spe >= 3){
@ -3032,24 +3039,163 @@ winid *datawin;
OBJPUTSTR(buf2);
}
if(force_weapon(obj)){
Sprintf(buf2, "When charged, deals an extra 1.5 dice of bonus energy damage.");
if (obj->otyp == FORCE_WHIP)
Sprintf(buf2, "When charged, deals +1d%d%s energy damage versus small and +2d%d%s versus large.",
sdamd, sitoa((sdamd+1)/2+2), ldamd, sitoa((ldamd+1)/2+2));
else
Sprintf(buf2, "When charged, deals +1d%d%s energy damage versus small and +1d%d%s versus large.",
sdamd, sitoa((sdamd+1)/2), ldamd, sitoa((ldamd+1)/2));
OBJPUTSTR(buf2);
}
if(obj->otyp == DOUBLE_FORCE_BLADE){
Sprintf(buf2, "Deals double damage if wielded without an off-hand weapon, at the cost of an extra 1/4 move.");
Sprintf(buf2, "Doubles base damage if wielded without two-weaponing, at the cost of an extra 1/4 move.");
OBJPUTSTR(buf2);
}
if(obj->otyp == RAKUYO){
Sprintf(buf2, "Deals an extra 1d4%s vs small or 1d3%s vs large if wielded without an off-hand weapon, at the cost of an extra 1/4 move.",
(obj->spe ? sitoa(obj->spe) : ""), (obj->spe ? sitoa(obj->spe) : ""));
Sprintf(buf2, "Deals +1d%d%s base damage vs small and +1d%d%s vs large if wielded without two-weaponing, at the cost of an extra 1/4 move.",
(4 + 2*(obj->objsize - MZ_MEDIUM)), (obj->spe ? sitoa(obj->spe) : ""),
(3 + 2*(obj->objsize - MZ_MEDIUM)), (obj->spe ? sitoa(obj->spe) : ""));
OBJPUTSTR(buf2);
}
if(obj->otyp == DISKOS && u.uinsight >= 15){
int dice = (u.uinsight >= 45) ? 3 : ((u.uinsight >= 20) ? 2 : 1);
int lflat = (u.uinsight >= 50) ? ldamd : 0;
int sflat = (u.uinsight >= 50) ? sdamd : 0;
if(u.ualign.record < -3 && Insanity > 50){
lflat += ldamd*(50-u.usanity)/50;
sflat += sdamd*(50-u.usanity)/50;
}
else if(u.ualign.record > 3 && u.usanity > 90){
lflat += ldamd*(10-Insanity)/10;
sflat += sdamd*(10-Insanity)/10;
}
Sprintf(buf2, "Deals +%dd%d%s %senergy damage versus small and +%dd%d%s versus large.",
dice, sdamd, (sflat ? sitoa(sflat) : ""), (u.ualign.record < -3) ? "unholy " : ((u.ualign.record > 3) ? "holy " : ""),
dice, ldamd, (lflat ? sitoa(lflat) : ""));
OBJPUTSTR(buf2);
}
if(is_mercy_blade(obj) & !u.veil){
Sprintf(buf2, "Deals extra damage scaled by insight%s, currently %d%% extra damage.",
(u.uinsight >= 25) ? " and charisma" : "",
(min(u.uinsight, 50) + ((u.uinsight >= 25) ? min((u.uinsight-25)/2, ACURR(A_CHA)) : 0))*2);
OBJPUTSTR(buf2);
if (u.uinsight >= 25){
Sprintf(buf2, "Lowers struck targets' morale based on your charisma, currently -%d per hit, capped at -%d.",
ACURR(A_CHA)/5, (obj->spe + ACURR(A_CHA)));
OBJPUTSTR(buf2);
}
}
if(obj->otyp == CROW_QUILL || obj->otyp == SET_OF_CROW_TALONS){
Sprintf(buf2, "Makes struck targets vulnerable, adding %d stacks per hit.", (obj->otyp == CROW_QUILL) ? 4 : 3);
OBJPUTSTR(buf2);
}
if(obj->otyp == BESTIAL_CLAW && active_glyph(BEASTS_EMBRACE)){
Sprintf(buf2, "Makes struck targets vulnerable, adding stacks equal to 10%% of damage, capped at %d (scaling inversely with insight).",
(int)(30*pow(.97, u.uinsight)));
OBJPUTSTR(buf2);
}
if(obj->otyp == ISAMUSEI){
int factor = 20;
if(u.uinsight >= 70){
factor = 4;
}
else if(u.uinsight >= 57){
factor = 5;
}
else if(u.uinsight >= 45){
factor = 6;
}
else if(u.uinsight >= 33){
factor = 8;
}
else if(u.uinsight >= 22){
factor = 10;
}
Sprintf(buf2, "Attempts to lower the target's current health by %d%% of its current value.", 100/factor);
OBJPUTSTR(buf2);
}
if(obj->otyp == PINCER_STAFF && u.uinsight >= 10){
Sprintf(buf2, "Deals double base damage %s%son consecutive attacks against the same target.",
(obj->oartifact == ART_FALLINGSTAR_MANDIBLES) ? "plus 1d12 magic damage " : "",
(u.uinsight >= 50) ? "and attempts to steal worn armor " : "");
OBJPUTSTR(buf2);
}
if(obj->oartifact == ART_ESSCOOAHLIPBOOURRR){
Sprintf(buf2, "Deals double base damage on consecutive attacks against the same target.");
OBJPUTSTR(buf2);
}
if(obj->oartifact == ART_ROD_OF_SEVEN_PARTS){
Sprintf(buf2, "Gains +1 enchantment for every 7 kills, capped at %d.", min(u.ulevel/3, 7));
OBJPUTSTR(buf2);
}
if(obj->oartifact == ART_RUINOUS_DESCENT_OF_STARS){
if (u.uinsight >= 6){
Sprintf(buf2, "Deals +%dd6 fire damage, scaling with your insight.", min(6, u.uinsight/6));
OBJPUTSTR(buf2);
}
if (NightmareAware_Insanity >= 4){
Sprintf(buf2, "Deals +%dd%d acid damage, scaling with your missing sanity.",
ClearThoughts ? 1 : 2, min(12, NightmareAware_Insanity/4));
OBJPUTSTR(buf2);
}
if (u.uinsight >= 42){
Sprintf(buf2, "Randomly drops falling stars on a hit, causing up to %d physical & fiery explosions centered anywhere on the level.",
min(6, (u.uinsight - 36)/6));
OBJPUTSTR(buf2);
}
}
if(obj->oartifact == ART_ARYVELAHR_KERYM){
Sprintf(buf2, "Deals +2d10 damage to orcs, demons, drow, and the undead.");
OBJPUTSTR(buf2);
}
if(obj->oartifact == ART_SILVER_STARLIGHT){
Sprintf(buf2, "Deals an extra base die + 1d4 bonus precision damage.");
OBJPUTSTR(buf2);
}
if (obj->oartifact == ART_SHADOWLOCK){
Sprintf(buf2, "Deals +2d6%s cold damage, but also deals 4d6%s physical and 2d6%s cold damage to the wielder every hit.",
(obj->spe ? sitoa(obj->spe) : ""), (obj->spe ? sitoa(obj->spe) : ""), (obj->spe ? sitoa(obj->spe) : ""));
OBJPUTSTR(buf2);
}
if(obj->oartifact == ART_TROLLSBANE){
Sprintf(buf2, "Deals +2d20%s to covetous monsters.", (obj->spe ? sitoa(obj->spe*2) : ""));
OBJPUTSTR(buf2);
}
if(obj->oartifact == ART_MASAMUNE){
int experts = -2;
for(int skl = 1; skl < P_NUM_SKILLS; skl++){
if(P_SKILL(skl) >= P_EXPERT)
experts += 2;
}
Sprintf(buf2, "Deals +2 damage for every expert weapon skill past your first, currently %s.", sitoa(max(0, experts)));
OBJPUTSTR(buf2);
}
if(obj->oartifact == ART_KUSANAGI_NO_TSURUGI){
Sprintf(buf2, "Instantly kills struck elementals and vortices.");
OBJPUTSTR(buf2);
}
if(obj->oartifact == ART_GIANTSLAYER){
Sprintf(buf2, "Hamstrings giants & other boulder-throwers, reducing their speed by 6 movement points.");
OBJPUTSTR(buf2);
}
if(obj->oartifact == ART_TECPATL_OF_HUHETOTL){
Sprintf(buf2, "Drinks the blood of targets that have any, dealing +2d4 damage and potentially sacrificing slain foes.");
OBJPUTSTR(buf2);
}
if(obj->oartifact == ART_PLAGUE && monstermoves < artinstance[ART_PLAGUE].PlagueDuration){
Sprintf(buf2, "Terminally ill targets explode in a cloud of virulent toxins, damaging those around them.");
OBJPUTSTR(buf2);
}
if(obj->oartifact == ART_WEBWEAVER_S_CROOK){
Sprintf(buf2, "Traps struck targets in webs.");
OBJPUTSTR(buf2);
}
if(obj->oartifact == ART_ATMA_WEAPON && !Drain_resistance){
Sprintf(buf2, "Scales base damage by your current health percentage.");
Sprintf(buf2, "Scales base damage by your current health percentage, currently %d%%.",
Upolyd ? (u.mh * 100) / u.mhmax : (u.uhp * 100) / u.uhpmax);
OBJPUTSTR(buf2);
}
if(fast_weapon(obj)){
@ -3064,6 +3210,10 @@ winid *datawin;
Sprintf(buf2, "Deals 20%% extra damage to all targets when the wielder is at 30%% health or lower.");
OBJPUTSTR(buf2);
}
if(is_vibroweapon(obj)){
Sprintf(buf2, "Drains one charge per hit and deals less damage when uncharged.");
OBJPUTSTR(buf2);
}
}
/* poison */
if (obj) {
@ -3094,7 +3244,7 @@ winid *datawin;
OBJPUTSTR("Coated with silver.");
}
else if (poisons == OPOISON_HALLU) {
OBJPUTSTR("Coated with hallucinogen.");
OBJPUTSTR("Coated with hallucinogens.");
}
/* general mash-em-together poison */
else {
@ -3138,6 +3288,29 @@ winid *datawin;
(hitbon >= 0 ? "bonus" : "penalty"));
OBJPUTSTR(buf);
}
/* Damage bonus from attributes */
#define dbon_to_word(num) ((num == 0) ? "no " : ((num == 0.5) ? "half " : ((num == 1.5) ? "half again " : ((num == 2) ? "double " : "full "))))
#define atr_to_word(atr) ((atr == A_STR) ? "strength" : ((atr == A_DEX) ? "dexterity" : ((atr == A_CON) ? "constitution" \
: ((atr == A_INT) ? "intelligence" : ((atr == A_WIS) ? "wisdom" : "charisma")))))
if (obj){
float atrdbon = 0;
boolean has_before = FALSE;
Sprintf(buf, "Gains ");
for (int i = A_STR; i < A_MAX; i++){
atrdbon = atr_dbon(obj, &youmonst, i);
if ((atrdbon == 0 && i == A_STR) || atrdbon > 0){
Sprintf(buf2, "%sbonus %sfrom %s, ", dbon_to_word(atrdbon), (has_before) ? "" : "damage ", atr_to_word(i));
Strcat(buf, buf2);
has_before = TRUE;
}
}
Sprintf(buf2, "currently %d.", dbon(obj, &youmonst));
Strcat(buf, buf2);
OBJPUTSTR(buf);
}
#undef dbon_to_word
#undef atr_to_word
}
/* object properties (objects only) */
if(!check_oprop(obj, OPROP_NONE)){
@ -3350,6 +3523,24 @@ winid *datawin;
Sprintf(buf2, "%s.", buf);
OBJPUTSTR(buf2);
}
if (check_oprop(obj, OPROP_SFLMW))
{
Sprintf(buf2, "Offers slain targets to the Silver Flame.");
OBJPUTSTR(buf2);
}
if (check_oprop(obj, OPROP_GOATW))
{
Sprintf(buf2, "Feeds slain foes to the Black Mother.");
OBJPUTSTR(buf2);
}
if (check_oprop(obj, OPROP_SOTHW))
{
Sprintf(buf2, "Slakes the thirst of Yog-Sothoth.");
OBJPUTSTR(buf2);
}
}
/* other artifact weapon effects */
if (oartifact) {

View file

@ -4508,7 +4508,7 @@ int tary;
n++;
if (!n){
if (youagr || youdef || canseemon(mdef))
pline("Silver rays whiz past %s!",
pline("Silver rays whizz past %s!",
youdef ? "you" : mon_nam(mdef));
return MM_MISS;
}

View file

@ -5161,6 +5161,9 @@ boolean was_swallowed; /* digestion */
if(Role_if(PM_ANACHRONONAUT) && (mon->mpeaceful || (has_lifesigns(mon) && mon->mvar_lifesigns)) && In_quest(&u.uz) && Is_qstart(&u.uz)){
if(!cansee(mon->mx,mon->my)) map_invisible(mon->mx, mon->my);
}
/* bypass anything about templates, etc. just always make a corpse*/
if (is_rider(mdat)) return TRUE;
/* Liches and Vlad and his wives have a fancy death message, and leave no corpse */
if ((mdat->mlet == S_LICH) ||
(mdat->mlet == S_VAMPIRE && mdat->geno & G_UNIQ)) {
@ -6359,7 +6362,7 @@ xkilled(mtmp, dest)
goto cleanup;
}
if((dest & 2) || LEVEL_SPECIFIC_NOCORPSE(mdat))
if(!is_rider(mdat) && ((dest & 2) || LEVEL_SPECIFIC_NOCORPSE(mdat)))
goto cleanup;
#ifdef MAIL

View file

@ -5997,7 +5997,7 @@ struct permonst _mons2[] = {
SIZ(WT_HUMAN, 400, MS_GUARD, MZ_HUMAN), 0, 0,
MM_WALLWALK /*MM*/, MT_OMNIVORE|MT_PEACEFUL|MT_COLLECT /*MT*/, MF_MARTIAL_S /*MF*/,
MB_HUMANOID|MB_STRONG /*MB*/, MG_NOWISH|MG_NOPOLY|MG_MERC|MG_INFRAVISIBLE /*MG*/,
MA_HUMAN /*MA*/, MV_NORMAL /*MV*/, 0 /*MW*/, CLR_BLUE),
MA_HUMAN /*MA*/, MV_NORMAL|MV_SEE_INVIS /*MV*/, 0 /*MW*/, CLR_BLUE),
MON("prisoner", S_HUMAN,//14
LVL(12, 12, 0, 0), G_NOGEN, /* for special levels */
DEF(NAT_AC(0)),

View file

@ -4531,6 +4531,9 @@ int wishflags;
} else if (!strncmpi(bp, "wrathful ", l=9) && strncmpi(bp, "Wrathful Wind", 13) && strncmpi(bp, "Wrathful Spider", 15)) {
add_oprop_list(oprop_list, OPROP_WRTHW);
} else if (!strncmpi(bp, "luminous ", l=9) || !strncmpi(bp, "radiant ", l=8)) {
add_oprop_list(oprop_list, OPROP_ELFLW);
} else if (!strncmpi(bp, "flaying ", l=8)) {
add_oprop_list(oprop_list, OPROP_FLAYW);
} else if (!strncmpi(bp, "excoriating ", l=12)) {

View file

@ -592,7 +592,7 @@ register struct monst *mtmp;
else if(is_blind(mtmp)) Strcat(info, ", dazzled");
if (mtmp->mstun) Strcat(info, ", stunned");
if (mtmp->msleeping) Strcat(info, ", asleep");
if (mtmp->mstdy > 0) Sprintf(eos(info), ", weakened (%d)", mtmp->mstdy);
if (mtmp->mstdy > 0) Sprintf(eos(info), ", vulnerable (%d)", mtmp->mstdy);
if (mtmp->encouraged != 0) Sprintf(eos(info), ", morale (%d)", mtmp->encouraged);
else if (mtmp->mstdy < 0) Sprintf(eos(info), ", protected (%d)", mtmp->mstdy);
#if 0 /* unfortunately mfrozen covers temporary sleep and being busy
@ -676,7 +676,7 @@ ustatusline()
} /* note: "goop" == "glop"; variation is intentional */
}
if (Stunned) Strcat(info, ", stunned");
if (u.ustdy > 0) Sprintf(eos(info), ", weakened (%d)", u.ustdy);
if (u.ustdy > 0) Sprintf(eos(info), ", vulnerable (%d)", u.ustdy);
if (u.uencouraged != 0) Sprintf(eos(info), ", morale (%d)", u.uencouraged);
#ifdef STEED
if (!u.usteed)

View file

@ -746,12 +746,14 @@ struct obj *spellbook;
if (RoSbook == READ_SPELL){
char qbuf[QBUFSZ];
Sprintf(qbuf, "You know \"%s\" quite well already. Try to refresh your memory anyway?", OBJ_NAME(objects[booktype]));
/* identify the book in case you learnt the spell from an artifact book or aphanactonan archive */
makeknown(booktype);
for (int i = 0; i < MAXSPELL; i++)
if (spellid(i) == booktype && spellknow(i) > KEEN/10 && yn(qbuf) == 'n')
for (int i = 0; i < MAXSPELL; i++){
if (spellid(i) == booktype && spellknow(i) > KEEN/10 && yn(qbuf) == 'n'){
/* identify the book in case you learnt the spell from an artifact book or aphanactonan archive */
makeknown(booktype);
return MOVE_CANCELLED;
}
}
}
spellbook->in_use = TRUE;
@ -817,9 +819,10 @@ struct obj *spellbook;
You("begin to study the ward.");
else if (spellbook->otyp == SPE_BOOK_OF_THE_DEAD)
You("begin to recite the runes.");
else
else {
You("begin to memorize the runes.");
makeknown(spellbook->otyp);
}
}
book = spellbook;

View file

@ -514,8 +514,8 @@ register struct monst *grd;
verbalize("You've been warned, knave!");
mnexto(grd);
levl[m][n].typ = egrd->fakecorr[0].ftyp;
newsym(m,n);
grd->mpeaceful = 0;
newsym(m,n);
return(-1);
}
/* not fair to get mad when (s)he's fainted or paralyzed */

View file

@ -2728,28 +2728,103 @@ abon() /* attack bonus for strength & dexterity */
#endif /* OVL0 */
#ifdef OVL1
/*
* Specific modifier for that attribute for that otyp,
* written like this so it's usable for invent.c
*/
float
atr_dbon(otmp, mtmp, atr)
struct obj *otmp;
struct monst *mtmp;
int atr;
{
float mod = 0;
switch (atr){
case A_STR:
mod = bimanual_mod(otmp, mtmp);
if (is_rakuyo(otmp))
return 0;
if (is_rapier(otmp) || is_mercy_blade(otmp) || otmp->otyp == SET_OF_CROW_TALONS ||
(otmp->otyp == LIGHTSABER && !otmp->oartifact && otmp->ovar1_lightsaberHandle == 0))
mod = 0.5;
if (otmp->oartifact == ART_LIFEHUNT_SCYTHE || otmp->oartifact == ART_VELKA_S_RAPIER ||
otmp->oartifact == ART_FRIEDE_S_SCYTHE || otmp->oartifact == ART_CRUCIFIX_OF_THE_MAD_KING)
mod = 0.5;
if (check_oprop(otmp, OPROP_OCLTW) || (u.uinsight > 0 && check_oprop(otmp, OPROP_GSSDW)))
mod = 0.5;
return mod;
case A_DEX:
if (is_rakuyo(otmp))
return 2; // otherwise gets caught by rapiers
if (otmp->oartifact == ART_LIFEHUNT_SCYTHE || otmp->oartifact == ART_YORSHKA_S_SPEAR ||
otmp->oartifact == ART_FRIEDE_S_SCYTHE)
mod += 2;
if (is_rapier(otmp) || is_mercy_blade(otmp) || otmp->otyp == SET_OF_CROW_TALONS ||
(otmp->otyp == LIGHTSABER && !otmp->oartifact && otmp->ovar1_lightsaberHandle == 0))
mod += 1;
return mod;
case A_CON:
return mod;
case A_INT:
if (u.uinsight > 0 && check_oprop(otmp, OPROP_GSSDW))
mod += 1;
if (otmp->oartifact == ART_VELKA_S_RAPIER || otmp->oartifact == ART_FRIEDE_S_SCYTHE)
mod += 1;
if (mercy_blade_prop(otmp))
mod += 0.5;
if (check_oprop(otmp, OPROP_ELFLW))
mod += 0.5;
return mod;
case A_WIS:
if (otmp->oartifact == ART_YORSHKA_S_SPEAR)
mod += 1;
if (check_oprop(otmp, OPROP_OCLTW))
mod += 1;
if (otmp->oartifact == ART_CRUCIFIX_OF_THE_MAD_KING)
mod += 0.5;
if (check_oprop(otmp, OPROP_ELFLW))
mod += 0.5;
return mod;
case A_CHA:
if (check_oprop(otmp, OPROP_ELFLW))
mod += 0.5;
return mod;
default:
return mod;
}
}
int
dbon(otmp, mtmp)
struct obj *otmp;
struct monst *mtmp;
{
boolean youagr = mtmp == &youmonst;
if (youagr) mtmp = (struct monst *) 0;
struct obj *armg = (youagr ? uarmg : which_armor(mtmp, W_ARMG));
int bare_bonus = weapon_dam_bonus((struct obj *) 0, P_BARE_HANDED_COMBAT);
int damage_bon = 0;
int str, dex, con, itl, wis, cha;
int strbon, dexbon, conbon, intbon, wisbon, chabon;
boolean half_str;
str = acurr(A_STR, mtmp);
dex = acurr(A_DEX, mtmp);
con = acurr(A_CON, mtmp);
itl = acurr(A_INT, mtmp);
wis = acurr(A_WIS, mtmp);
cha = acurr(A_CHA, mtmp);
int str, stat;
int strbon, statbon;
str = acurr(A_STR, (youagr) ? ((struct monst *) 0) : mtmp);
/* please remove fractional strength already */
if (str < 6) strbon = str - 6;
@ -2766,90 +2841,28 @@ struct monst *mtmp;
if(youagr && u.umadness&MAD_RAGE && !BlockableClearThoughts)
strbon += (Insanity)/10;
if(youagr ? Race_if(PM_HALF_DRAGON) && flags.HDbreath == AD_FIRE && u.ulevel >= 15 :
is_half_dragon(mtmp->data) && mtmp->mvar_hdBreath == AD_FIRE && mtmp->data->mlevel >= 15)
if(youagr ?
(Race_if(PM_HALF_DRAGON) && flags.HDbreath == AD_FIRE && u.ulevel >= 15) :
(is_half_dragon(mtmp->data) && mtmp->mvar_hdBreath == AD_FIRE && mtmp->data->mlevel >= 15)
)
strbon += 2;
strbon *= bimanual_mod(otmp, (youagr) ? &youmonst : mtmp);
dexbon = (dex == 25) ? 8 : ((dex-10)/2);
conbon = (con == 25) ? 8 : ((con-10)/2);
intbon = (itl == 25) ? 8 : ((itl-10)/2);
wisbon = (wis == 25) ? 8 : ((wis-10)/2);
chabon = (cha == 25) ? 8 : ((cha-10)/2);
if (!otmp){
if (youagr && u.umaniac && bare_bonus > 0)
damage_bon += min_ints(bare_bonus, chabon);
if (otmp){
damage_bon = (int)(strbon * atr_dbon(otmp, mtmp, A_STR));
for (int i = A_DEX; i < A_MAX; i++){
stat = acurr(i, (youagr) ? ((struct monst *) 0) : mtmp);
statbon = (stat == 25) ? 8 : ((stat-10)/2);
damage_bon += (int)(statbon * atr_dbon(otmp, mtmp, i));
}
if (youagr && otmp->oartifact == ART_IBITE_ARM){
if(bare_bonus > 0) damage_bon += ACURR(A_CHA)/5 + bare_bonus*2;
}
} else {
/* all of these ifs should almost always fire, it's for readability */
/* if two bonus sources can stack, they're in separate ifs so they can both fire*/
if (dexbon){
if (is_rakuyo(otmp)){
strbon = 0;
damage_bon += dexbon * 2;
} else if (is_rapier(otmp) || is_mercy_blade(otmp) || otmp->otyp == SET_OF_CROW_TALONS ||
(otmp->otyp == LIGHTSABER && !otmp->oartifact && otmp->ovar1_lightsaberHandle == 0)){
half_str = TRUE;
damage_bon += dexbon;
}
if (otmp->oartifact == ART_LIFEHUNT_SCYTHE || otmp->oartifact == ART_YORSHKA_S_SPEAR || otmp->oartifact == ART_FRIEDE_S_SCYTHE){
if (otmp->oartifact != ART_YORSHKA_S_SPEAR) half_str = TRUE;
damage_bon += dexbon * 2;
}
}
damage_bon = strbon;
if (conbon){
// no conbon items yet
}
if (intbon){
if (u.uinsight > 0 && check_oprop(otmp, OPROP_GSSDW)){
half_str = TRUE;
damage_bon += intbon;
}
if (otmp->oartifact == ART_VELKA_S_RAPIER || otmp->oartifact == ART_FRIEDE_S_SCYTHE){
half_str = TRUE;
damage_bon += intbon;
}
if (mercy_blade_prop(otmp)){
half_str = TRUE;
damage_bon += intbon/2;
}
if (check_oprop(otmp, OPROP_ELFLW)){
damage_bon += intbon/2;
}
}
if (wisbon){
if (otmp->oartifact == ART_YORSHKA_S_SPEAR){
damage_bon += wisbon;
}
if (check_oprop(otmp, OPROP_OCLTW)){
half_str = TRUE;
damage_bon += wisbon;
}
if (otmp->oartifact == ART_CRUCIFIX_OF_THE_MAD_KING){
half_str = TRUE;
damage_bon += wisbon/2;
}
if (check_oprop(otmp, OPROP_ELFLW)){
damage_bon += wisbon/2;
}
}
if (chabon){
if (check_oprop(otmp, OPROP_ELFLW)){
damage_bon += chabon/2;
}
if (otmp->oartifact == ART_IBITE_ARM){
if(bare_bonus > 0) damage_bon += cha/5 + bare_bonus*2;
}
}
if (youagr && u.umaniac && bare_bonus > 0)
damage_bon += min_ints(bare_bonus, (ACURR(A_CHA) == 25) ? 8 : ((ACURR(A_CHA)-10)/2));
}
if (half_str) strbon /= 2;
damage_bon += strbon;
if (damage_bon && armg && check_oprop(armg, OPROP_RWTH) && (
(youagr && u.ualign.record >= 20 && u.ualign.type != A_CHAOTIC && u.ualign.type != A_NEUTRAL) ||

View file

@ -13505,11 +13505,11 @@ int vis; /* True if action is at all visible to the player */
sneak_dice++;
if (weapon && weapon->owornmask && weapon->oartifact == ART_SPINESEEKER)
sneak_dice++;
if (weapon && weapon->oartifact == ART_LOLTH_S_FANG)
if (weapon && weapon->owornmask && weapon->oartifact == ART_LOLTH_S_FANG)
sneak_dice++;
if (weapon && weapon->owornmask && weapon->otyp == BESTIAL_CLAW && active_glyph(BEASTS_EMBRACE))
sneak_dice++;
if (weapon && weapon->owornmask && weapon->oartifact == ART_PEN_OF_THE_VOID && weapon->ovar1_seals&SEAL_ANDROMALIUS)
if (weapon && weapon->oartifact == ART_PEN_OF_THE_VOID && weapon->ovar1_seals&SEAL_ANDROMALIUS)
sneak_dice++;
/* check sneak attack conditions -- defender's conditions must allow sneak attacking */
@ -13582,7 +13582,7 @@ int vis; /* True if action is at all visible to the player */
/* some things increase the number of sneak dice even further */
if (weapon && weapon->owornmask && weapon->oartifact == ART_SPINESEEKER && (sneak_attack&SNEAK_BEHIND))
sneak_dice++;
if (weapon && weapon->oartifact == ART_LOLTH_S_FANG && (sneak_attack&SNEAK_TRAPPED) && t_at(x(mdef), y(mdef)) && t_at(x(mdef), y(mdef))->ttyp == WEB)
if (weapon && weapon->owornmask && weapon->oartifact == ART_LOLTH_S_FANG && (sneak_attack&SNEAK_TRAPPED) && t_at(x(mdef), y(mdef)) && t_at(x(mdef), y(mdef))->ttyp == WEB)
sneak_dice++;
if (weapon && weapon->oartifact == ART_PEN_OF_THE_VOID && weapon->ovar1_seals&SEAL_ANDROMALIUS && (mvitals[PM_ACERERAK].died > 0))
sneak_dice++;

View file

@ -290,6 +290,10 @@ curses_display_nhwindow(winid wid, BOOLEAN_P block)
/* actually display the window */
wnoutrefresh(curses_get_nhwin(wid));
if (curses_window_has_border(wid)) {
WINDOW *win = curses_get_nhwin(wid);
box(win, 0, 0);
}
/* flush pending writes from other windows too */
doupdate();
if ((wid == MAP_WIN) && block) {