From 11625c077288bd5dcbfa765633a5398976458ad9 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Sat, 12 Nov 2016 01:24:03 +0000 Subject: [PATCH 01/11] Make free actions easier to predict, nonfree actions more predictable This fixes melee kiting more comprehensively (it now doesn't work against slower monsters either), and prevents you doing things like opening up a gap when running from an imp (you couldn't do that in 3.4.3). --- src/allmain.c | 13 ++++++------- src/mon.c | 30 +++++++++++++++++------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/allmain.c b/src/allmain.c index de1fb1557..1ca917a74 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -132,14 +132,13 @@ boolean resuming; moveamt = youmonst.data->mmove; if (Very_fast) { /* speed boots or potion */ - /* average movement is 1.67 times normal */ - moveamt += NORMAL_SPEED / 2; - if (rn2(3) == 0) - moveamt += NORMAL_SPEED / 2; - } else if (Fast) { - /* average movement is 1.33 times normal */ + /* gain a free action on 2/3 of turns */ if (rn2(3) != 0) - moveamt += NORMAL_SPEED / 2; + moveamt += NORMAL_SPEED; + } else if (Fast) { + /* gain a free action on 1/3 of turns */ + if (rn2(3) == 0) + moveamt += NORMAL_SPEED; } } diff --git a/src/mon.c b/src/mon.c index 35966e381..f387655e7 100644 --- a/src/mon.c +++ b/src/mon.c @@ -582,6 +582,7 @@ mcalcmove(mon) struct monst *mon; { int mmove = mon->data->mmove; + int mmove_adj; /* Note: MSLOW's `+ 1' prevents slowed speed 1 getting reduced to 0; * MFAST's `+ 2' prevents hasted speed 1 from becoming a no-op; @@ -592,21 +593,24 @@ struct monst *mon; else if (mon->mspeed == MFAST) mmove = (4 * mmove + 2) / 3; - if (mon == u.usteed) { - if (u.ugallop && context.mv) { - /* average movement is 1.50 times normal */ - mmove = ((rn2(2) ? 4 : 5) * mmove) / 3; - } - } else if (mmove) { - /* vary movement points allocated to slightly reduce predictability; - random increment (avg +2) exceeds random decrement (avg +1) by - a small amount; normal speed monsters will occasionally get an - extra move and slow ones won't be quite as slow */ - mmove += rn2(5) - rn2(3); /* + 0..4 - 0..2, average net +1 */ - if (mmove < 1) - mmove = 1; + if (mon == u.usteed && u.ugallop && context.mv) { + /* increase movement by a factor of 1.5; also increase variance of + movement speed (if it's naturally 24, we don't want it to always + become 36) */ + mmove = ((rn2(2) ? 4 : 5) * mmove) / 3; } + /* Randomly round the monster's speed to a multiple of NORMAL_SPEED. This + makes it impossible for the player to predict when they'll get a free + turn (thus preventing exploits like "melee kiting"), while retaining + guarantees about shopkeepers not being outsped by a normal-speed player, + normal-speed players being unable to open up a gap when fleeing a + normal-speed monster, etc.*/ + mmove_adj = mmove % NORMAL_SPEED; + mmove -= mmove_adj; + if (rn2(NORMAL_SPEED) < mmove_adj) + mmove += NORMAL_SPEED; + return mmove; } From ec2beee61fd9b3ebd53895f3d8b69922f7a306ba Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Sat, 12 Nov 2016 01:28:47 +0000 Subject: [PATCH 02/11] Changelog for movement speed changes --- doc/fixes36.1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 30731b652..90e77dc6a 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -355,6 +355,8 @@ wielding Trollsbane prevents trolls from reviving wielding Demonbane prevents demons summoning friends Elbereth must now be on a square by itself to function Elbereth now erodes based on attacks by the player, not monsters scared +movement speeds are made less predictable by using random rounding, rather + than via adding a random offset Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository From 06bd0d426b257e3cfb687bbb69570f61550bbbe8 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 14 Nov 2016 19:34:16 +0200 Subject: [PATCH 03/11] Make Dragonbane confer reflection when wielded --- doc/fixes36.1 | 1 + include/artilist.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 815b9f1ad..34cdffc71 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -353,6 +353,7 @@ sometimes generate the random mazes with wide corridors, thick walls, put throne room gold in the chest wielding Trollsbane prevents trolls from reviving wielding Demonbane prevents demons summoning friends +wielding Dragonbane confers reflection Elbereth must now be on a square by itself to function Elbereth now erodes based on attacks by the player, not monsters scared novels are made of paper, not gold diff --git a/include/artilist.h b/include/artilist.h index b3510386c..e06e99a7f 100644 --- a/include/artilist.h +++ b/include/artilist.h @@ -103,7 +103,8 @@ STATIC_OVL NEARDATA struct artifact artilist[] = { FIRE(5, 0), FIRE(0, 0), NO_CARY, 0, A_NONE, NON_PM, NON_PM, 3000L, NO_COLOR), - A("Dragonbane", BROADSWORD, (SPFX_RESTR | SPFX_DCLAS), 0, S_DRAGON, + A("Dragonbane", BROADSWORD, + (SPFX_RESTR | SPFX_DCLAS | SPFX_REFLECT), 0, S_DRAGON, PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 500L, NO_COLOR), From b0c68714ce1aaa35a0c6d10f916c1ea87f2ad973 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 14 Nov 2016 20:22:33 +0200 Subject: [PATCH 04/11] Make Ogresmasher grant 25 constitution --- doc/fixes36.1 | 1 + src/attrib.c | 6 ++++++ src/cmd.c | 2 ++ src/wield.c | 3 +++ 4 files changed, 12 insertions(+) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 34cdffc71..a20c06e8a 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -354,6 +354,7 @@ put throne room gold in the chest wielding Trollsbane prevents trolls from reviving wielding Demonbane prevents demons summoning friends wielding Dragonbane confers reflection +wielding Ogresmasher grants 25 constitution Elbereth must now be on a square by itself to function Elbereth now erodes based on attacks by the player, not monsters scared novels are made of paper, not gold diff --git a/src/attrib.c b/src/attrib.c index 5c80c5ed2..bdb1ff1f1 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -1002,6 +1002,9 @@ int x; && (youmonst.data->mlet == S_NYMPH || u.umonnum == PM_SUCCUBUS || u.umonnum == PM_INCUBUS)) return (schar) 18; + } else if (x == A_CON) { + if (uwep && uwep->oartifact == ART_OGRESMASHER) + return (schar) 25; } else if (x == A_INT || x == A_WIS) { /* yes, this may raise int/wis if player is sufficiently * stupid. there are lower levels of cognition than "dunce". @@ -1047,6 +1050,9 @@ int attrindx; /* lower limit for Str can also be 25 */ if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER) lolimit = hilimit; + } else if (attrindx == A_CON) { + if (uwep && uwep->oartifact == ART_OGRESMASHER) + lolimit = hilimit; } /* this exception is hypothetical; the only other worn item affecting Int or Wis is another helmet so can't be in use at the same time */ diff --git a/src/cmd.c b/src/cmd.c index 35ffe9c1f..317405b45 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1638,6 +1638,8 @@ int mode, final, attrindx; break; case A_CON: attrname = "constitution"; + if (uwep && uwep->oartifact == ART_OGRESMASHER && uwep->cursed) + hide_innate_value = TRUE; break; case A_INT: attrname = "intelligence"; diff --git a/src/wield.c b/src/wield.c index 929d45c82..4df6c3615 100644 --- a/src/wield.c +++ b/src/wield.c @@ -96,6 +96,9 @@ register struct obj *obj; if (!Blind) pline("%s shining.", Tobjnam(olduwep, "stop")); } + if (uwep == obj && ((uwep && uwep->oartifact == ART_OGRESMASHER) + || olduwep && olduwep->oartifact == ART_OGRESMASHER)) + context.botl = 1; /* Note: Explicitly wielding a pick-axe will not give a "bashing" * message. Wielding one via 'a'pplying it will. * 3.2.2: Wielding arbitrary objects will give bashing message too. From 5da34b7db667d5de74e9f2881a7213584654593b Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 2 Dec 2016 22:03:10 +0200 Subject: [PATCH 05/11] Fix segfault when looking at detected monster hiding under unknown armor This segfault happened when a detected monster such as a garter snake was hiding under an unknown/unseen armor of a type that has no description field (eg. a leather armor), and you farlooked at the monster. At the same time, simplifies the code a tiny bit. --- src/objnam.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/objnam.c b/src/objnam.c index d395ea747..7a800d23a 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -268,7 +268,7 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ register struct objclass *ocl = &objects[typ]; int nn = ocl->oc_name_known, omndx = obj->corpsenm; const char *actualn = OBJ_NAME(*ocl); - const char *dn = OBJ_DESCR(*ocl); + const char *dn = OBJ_DESCR(*ocl) ? OBJ_DESCR(*ocl) : actualn; const char *un = ocl->oc_uname; boolean pluralize = (obj->quan != 1L) && !(cxn_flags & CXN_SINGULAR); boolean known, dknown, bknown; @@ -327,15 +327,15 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ Strcpy(buf, (obj->spe < 3) ? "moist " : "wet "); if (!dknown) - Strcat(buf, dn ? dn : actualn); + Strcat(buf, dn); else if (nn) Strcat(buf, actualn); else if (un) { - Strcat(buf, dn ? dn : actualn); + Strcat(buf, dn); Strcat(buf, " called "); Strcat(buf, un); } else - Strcat(buf, dn ? dn : actualn); + Strcat(buf, dn); /* If we use an() here we'd have to remember never to use */ /* it whenever calling doname() or xname(). */ if (typ == FIGURINE && omndx != NON_PM) { From daff7653f866ba7f3c4775d1dc0ef0c356c198b3 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 4 Dec 2016 21:38:59 +0200 Subject: [PATCH 06/11] Add missing symbols to Blank symset and Guidebook --- dat/symbols | 4 ++++ doc/Guidebook.mn | 1 + doc/Guidebook.tex | 1 + 3 files changed, 6 insertions(+) diff --git a/dat/symbols b/dat/symbols index 619d436a7..c6afc4c5e 100644 --- a/dat/symbols +++ b/dat/symbols @@ -453,11 +453,13 @@ start: Blank S_hbeam: \032 S_hcdbridge: \032 S_hcdoor: \032 + S_hodbridge: \032 S_hodoor: \032 S_hole: \032 S_human: \032 S_humanoid: \032 S_hwall: \032 + S_ice: \032 S_imp: \032 S_invisible: \032 S_jabberwock: \032 @@ -543,7 +545,9 @@ start: Blank S_vbeam: \032 S_vcdbridge: \032 S_vcdoor: \032 + S_venom: \032 S_vibrating_square: \032 + S_vodbridge: \032 S_vodoor: \032 S_vortex: \032 S_vwall: \032 diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index cf4d13739..f5adc8b6e 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -3543,6 +3543,7 @@ h S_humanoid (humanoid) - S_hwall (horizontal wall) . S_ice (ice) i S_imp (imp or minor demon) +I S_invisible (invisible monster) J S_jabberwock (jabberwock) j S_jelly (jelly) k S_kobold (kobold) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 5bf4fc351..0f3c83504 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -4334,6 +4334,7 @@ Default & Symbol Name & Description\\ \verb@-@ & S\verb+_+hwall & (horizontal wall)\\ \verb@.@ & S\verb+_+ice & (ice)\\ \verb@i@ & S\verb+_+imp & (imp or minor demon)\\ +\verb@I@ & S\verb+_+invisible & (invisible monster)\\ \verb@J@ & S\verb+_+jabberwock & (jabberwock)\\ \verb@j@ & S\verb+_+jelly & (jelly)\\ \verb@k@ & S\verb+_+kobold & (kobold)\\ From b8d8556eff8eb133c56f27421a905a30d9a7e975 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 7 Dec 2016 17:53:03 +0200 Subject: [PATCH 07/11] Fix some issues found with fuzz testing Mostly to do with relocating monsters when the level is already full, and unsticking a monster if it gets relocated. --- include/extern.h | 1 + src/dog.c | 8 +++++--- src/mhitm.c | 1 + src/mon.c | 26 +++++++++++++++++++++----- src/wizard.c | 8 ++++++-- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/include/extern.h b/include/extern.h index 300af5e06..3ab3e6ce4 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1351,6 +1351,7 @@ E void FDECL(unstuck, (struct monst *)); E void FDECL(killed, (struct monst *)); E void FDECL(xkilled, (struct monst *, int)); E void FDECL(mon_to_stone, (struct monst *)); +E void FDECL(m_into_limbo, (struct monst *)); E void FDECL(mnexto, (struct monst *)); E void FDECL(maybe_mnexto, (struct monst *)); E boolean FDECL(mnearto, (struct monst *, XCHAR_P, XCHAR_P, BOOLEAN_P)); diff --git a/src/dog.c b/src/dog.c index fba998407..0b9d2ae9f 100644 --- a/src/dog.c +++ b/src/dog.c @@ -430,9 +430,10 @@ boolean with_you; mtmp->mx = 0; /*(already is 0)*/ mtmp->my = xyflags; - if (xlocale) - (void) mnearto(mtmp, xlocale, ylocale, FALSE); - else { + if (xlocale) { + if (!mnearto(mtmp, xlocale, ylocale, FALSE)) + goto fail_mon_placement; + } else { if (!rloc(mtmp, TRUE)) { /* * Failed to place migrating monster, @@ -440,6 +441,7 @@ boolean with_you; * Dump the monster's cargo and leave the monster dead. */ struct obj *obj; +fail_mon_placement: while ((obj = mtmp->minvent) != 0) { obj_extract_self(obj); obj_no_longer_held(obj); diff --git a/src/mhitm.c b/src/mhitm.c index 2b67b47b0..39407c3a8 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -744,6 +744,7 @@ register struct attack *mattk; if (cansee(dx, dy)) pline("%s is regurgitated!", Monnam(mdef)); + remove_monster(dx,dy); place_monster(magr, ax, ay); place_monster(mdef, dx, dy); newsym(ax, ay); diff --git a/src/mon.c b/src/mon.c index f387655e7..23ebcdb45 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2029,6 +2029,8 @@ struct monst *mdef; /* hero is thrown from his steed when it disappears */ if (mdef == u.usteed) dismount_steed(DISMOUNT_GENERIC); + /* stuck to you? release */ + unstuck(mdef); /* drop special items like the Amulet so that a dismissed Kop or nurse can't remove them from the game */ mdrop_special_objs(mdef); @@ -2449,6 +2451,16 @@ struct monst *mtmp; return TRUE; } +/* drop monster into "limbo" - that is, migrate to the current level */ +void +m_into_limbo(mtmp) +struct monst *mtmp; +{ + unstuck(mtmp); + mdrop_special_objs(mtmp); + migrate_to_level(mtmp, ledger_no(&u.uz), MIGR_APPROX_XY, NULL); +} + /* make monster mtmp next to you (if possible); might place monst on far side of a wall or boulder */ void @@ -2465,7 +2477,11 @@ struct monst *mtmp; return; } - if (!enexto(&mm, u.ux, u.uy, mtmp->data)) + if (!enexto(&mm, u.ux, u.uy, mtmp->data)) { + m_into_limbo(mtmp); + return; + } + if (!isok(mm.x, mm.y)) return; rloc_to(mtmp, mm.x, mm.y); if (!in_mklev && (mtmp->mstrategy & STRAT_APPEARMSG)) { @@ -2534,6 +2550,8 @@ boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */ */ if (!enexto(&mm, newx, newy, mtmp->data)) return FALSE; + if (!isok(mm.x,mm.y)) + return FALSE; newx = mm.x; newy = mm.y; } @@ -2545,12 +2563,10 @@ boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */ othermon->mx = othermon->my = 0; (void) mnearto(othermon, x, y, FALSE); if (othermon->mx == 0 && othermon->my == 0) { - /* reloc failed, dump monster into "limbo" - (aka migrate to current level) */ + /* reloc failed */ othermon->mx = oldx; othermon->my = oldy; - mdrop_special_objs(othermon); - migrate_to_level(othermon, ledger_no(&u.uz), MIGR_APPROX_XY, NULL); + m_into_limbo(othermon); } } diff --git a/src/wizard.c b/src/wizard.c index 6ab8e57bd..3f58433c8 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -380,7 +380,10 @@ register struct monst *mtmp; if (!rn2(3 + mtmp->mhp / 10)) (void) rloc(mtmp, TRUE); } else if (sx && (mtmp->mx != sx || mtmp->my != sy)) { - (void) mnearto(mtmp, sx, sy, TRUE); + if (!mnearto(mtmp, sx, sy, TRUE)) { + m_into_limbo(mtmp); + return 0; + } } /* if you're not around, cast healing spells */ if (distu(mtmp->mx, mtmp->my) > (BOLT_LIM * BOLT_LIM)) @@ -433,7 +436,8 @@ register struct monst *mtmp; return 0; } } else { /* a monster has it - 'port beside it. */ - (void) mnearto(mtmp, tx, ty, FALSE); + if (!mnearto(mtmp, tx, ty, FALSE)) + m_into_limbo(mtmp); return 0; } } From 97ffc0f53d2e3d0f4181fc74164f2e39a802e407 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 7 Dec 2016 20:23:07 +0200 Subject: [PATCH 08/11] Fix segfault when attacked while polyed into disenchanter The pointer keeping tabs of monster's current weapon was not cleared. How to trigger: Get hit by a monster wielding a weapon, teleport to another level, poly into disenchanter, get hit by any monster with AD_PHYS attack and not wielding any weapon. --- src/mhitu.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/mhitu.c b/src/mhitu.c index 1cdd7bce7..86a064f84 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -5,7 +5,7 @@ #include "hack.h" #include "artifact.h" -STATIC_VAR NEARDATA struct obj *otmp; +STATIC_VAR NEARDATA struct obj *mon_currwep = (struct obj *) 0; STATIC_DCL boolean FDECL(u_slip_free, (struct monst *, struct attack *)); STATIC_DCL int FDECL(passiveum, (struct permonst *, struct monst *, @@ -646,6 +646,7 @@ register struct monst *mtmp; for (i = 0; i < NATTK; i++) { sum[i] = 0; + mon_currwep = (struct obj *)0; mattk = getmattk(mtmp, &youmonst, i, sum, &alt_attk); if ((u.uswallow && mattk->aatyp != AT_ENGL) || (skipnonmagc && mattk->aatyp != AT_MAGC)) @@ -747,18 +748,18 @@ register struct monst *mtmp; break; } if (foundyou) { - otmp = MON_WEP(mtmp); - if (otmp) { - hittmp = hitval(otmp, &youmonst); + mon_currwep = MON_WEP(mtmp); + if (mon_currwep) { + hittmp = hitval(mon_currwep, &youmonst); tmp += hittmp; - mswings(mtmp, otmp); + mswings(mtmp, mon_currwep); } if (tmp > (j = dieroll = rnd(20 + i))) sum[i] = hitmu(mtmp, mattk); else missmu(mtmp, (tmp == j), mattk); /* KMH -- Don't accumulate to-hit bonuses */ - if (otmp) + if (mon_currwep) tmp -= hittmp; } else { wildmiss(mtmp, mattk); @@ -968,6 +969,7 @@ register struct attack *mattk; : "crushed"); } } else { /* hand to hand weapon */ + struct obj *otmp = mon_currwep; if (mattk->aatyp == AT_WEAP && otmp) { int tmp; @@ -2710,10 +2712,10 @@ register struct attack *mattk; return 1; } case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ - if (otmp) { + if (mon_currwep) { /* by_you==True: passive counterattack to hero's action is hero's fault */ - (void) drain_item(otmp, TRUE); + (void) drain_item(mon_currwep, TRUE); /* No message */ } return 1; From 66a0c98954f4d1f95728b94bfea1b636049266dd Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 8 Dec 2016 16:01:09 -0800 Subject: [PATCH 09/11] fix some recent lint --- include/extern.h | 4 ++-- src/wield.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/extern.h b/include/extern.h index 3ab3e6ce4..5a229a8da 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1356,8 +1356,8 @@ E void FDECL(mnexto, (struct monst *)); E void FDECL(maybe_mnexto, (struct monst *)); E boolean FDECL(mnearto, (struct monst *, XCHAR_P, XCHAR_P, BOOLEAN_P)); E void FDECL(m_respond, (struct monst *)); -E void FDECL(setmangry, (struct monst *, boolean)); -E void FDECL(wakeup, (struct monst *, boolean)); +E void FDECL(setmangry, (struct monst *, BOOLEAN_P)); +E void FDECL(wakeup, (struct monst *, BOOLEAN_P)); E void NDECL(wake_nearby); E void FDECL(wake_nearto, (int, int, int)); E void FDECL(seemimic, (struct monst *)); diff --git a/src/wield.c b/src/wield.c index 4df6c3615..585e971c9 100644 --- a/src/wield.c +++ b/src/wield.c @@ -96,8 +96,9 @@ register struct obj *obj; if (!Blind) pline("%s shining.", Tobjnam(olduwep, "stop")); } - if (uwep == obj && ((uwep && uwep->oartifact == ART_OGRESMASHER) - || olduwep && olduwep->oartifact == ART_OGRESMASHER)) + if (uwep == obj + && ((uwep && uwep->oartifact == ART_OGRESMASHER) + || (olduwep && olduwep->oartifact == ART_OGRESMASHER))) context.botl = 1; /* Note: Explicitly wielding a pick-axe will not give a "bashing" * message. Wielding one via 'a'pplying it will. From 9b725218bb071a2ba057fe3d53917cc196cd3ddc Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 8 Dec 2016 16:39:55 -0800 Subject: [PATCH 10/11] fix #H4706 - non-zero hit points for poison death For "the poison was deadly" against hero, hit points were set to -1 (which gets displayed as 0 when shown) but the status lines weren't being updated, so stale positive HP value was visible during final disclosure. --- doc/fixes36.1 | 2 ++ src/attrib.c | 1 + src/end.c | 12 ++++++++++++ 3 files changed, 15 insertions(+) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 9fd1a03a9..28aa198ac 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -360,6 +360,8 @@ Elbereth now erodes based on attacks by the player, not monsters scared novels are made of paper, not gold movement speeds are made less predictable by using random rounding, rather than via adding a random offset +some death by the-poison-was-deadly situations left stale non-zero HP shown + on the status line during final disclosure Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/src/attrib.c b/src/attrib.c index bdb1ff1f1..c87afb683 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -272,6 +272,7 @@ boolean thrown_weapon; /* thrown weapons are less deadly */ if (i == 0 && typ != A_CHA) { /* instant kill */ u.uhp = -1; + context.botl = TRUE; pline_The("poison was deadly..."); } else if (i > 5) { /* HP damage; more likely--but less severe--with missiles */ diff --git a/src/end.c b/src/end.c index d097292fb..08141258f 100644 --- a/src/end.c +++ b/src/end.c @@ -922,6 +922,18 @@ int how; return; } } + if (program_state.panicking +#ifdef HANGUPHANDLING + || program_state.done_hup +#endif + ) { + /* skip status update if panicking or disconnected */ + context.botl = context.botlx = FALSE; + } else { + /* otherwise force full status update */ + context.botlx = TRUE; + bot(); + } if (how == ASCENDED || (!killer.name[0] && how == GENOCIDED)) killer.format = NO_KILLER_PREFIX; From 2655910a0f03f26111bb41e947f5f8a6c8dcc2af Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 8 Dec 2016 17:22:59 -0800 Subject: [PATCH 11/11] fix #H4597 - sitting on level teleport trap During #sit: "You sit down. You step on a level teleporter." Switch to alternate phrasing for #sit. Webs and polymorph traps had similar issues. --- doc/fixes36.1 | 2 ++ include/extern.h | 10 +++++----- include/hack.h | 4 ++-- src/sit.c | 2 +- src/teleport.c | 16 ++++++++++++---- src/trap.c | 19 +++++++++++-------- 6 files changed, 33 insertions(+), 20 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 28aa198ac..7142c52ca 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -362,6 +362,8 @@ movement speeds are made less predictable by using random rounding, rather than via adding a random offset some death by the-poison-was-deadly situations left stale non-zero HP shown on the status line during final disclosure +when sitting at a trap spot: You sit down. You step on a level teleporter. + (likewise for polymorph trap, and similar issue for web) Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 5a229a8da..52b810a60 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2282,8 +2282,8 @@ E boolean FDECL(stucksteed, (BOOLEAN_P)); E boolean FDECL(goodpos, (int, int, struct monst *, unsigned)); 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 boolean FDECL(enexto_core, (coord *, XCHAR_P, XCHAR_P, + struct permonst *, unsigned)); E void FDECL(teleds, (int, int, BOOLEAN_P)); E boolean FDECL(safe_teleds, (BOOLEAN_P)); E boolean FDECL(teleport_pet, (struct monst *, BOOLEAN_P)); @@ -2293,13 +2293,13 @@ E int NDECL(dotele); E void NDECL(level_tele); E void FDECL(domagicportal, (struct trap *)); E void FDECL(tele_trap, (struct trap *)); -E void FDECL(level_tele_trap, (struct trap *)); +E void FDECL(level_tele_trap, (struct trap *, unsigned)); E void FDECL(rloc_to, (struct monst *, int, int)); E boolean FDECL(rloc, (struct monst *, BOOLEAN_P)); E boolean FDECL(tele_restrict, (struct monst *)); E void FDECL(mtele_trap, (struct monst *, struct trap *, int)); -E int FDECL(mlevel_tele_trap, - (struct monst *, struct trap *, BOOLEAN_P, int)); +E int FDECL(mlevel_tele_trap, (struct monst *, struct trap *, + BOOLEAN_P, int)); E boolean FDECL(rloco, (struct obj *)); E int NDECL(random_teleport_level); E boolean FDECL(u_teleport_mon, (struct monst *, BOOLEAN_P)); diff --git a/include/hack.h b/include/hack.h index cc878942c..bf2273b2b 100644 --- a/include/hack.h +++ b/include/hack.h @@ -296,9 +296,9 @@ enum hmon_atkmode_types { #define FORCETRAP 0x01 /* triggering not left to chance */ #define NOWEBMSG 0x02 /* suppress stumble into web message */ #define FORCEBUNGLE 0x04 /* adjustments appropriate for bungling */ -#define RECURSIVETRAP 0x08 /* trap changed into another type this same turn \ - */ +#define RECURSIVETRAP 0x08 /* trap changed into another type this same turn */ #define TOOKPLUNGE 0x10 /* used '>' to enter pit below you */ +#define VIASITTING 0x20 /* #sit while at trap location (affects message) */ /* Flags to control test_move in hack.c */ #define DO_MOVE 0 /* really doing the move */ diff --git a/src/sit.c b/src/sit.c index 047e22338..a6c6a0906 100644 --- a/src/sit.c +++ b/src/sit.c @@ -113,7 +113,7 @@ dosit() } } else { You("sit down."); - dotrap(trap, 0); + dotrap(trap, VIASITTING); } } else if (Underwater || Is_waterlevel(&u.uz)) { if (Is_waterlevel(&u.uz)) diff --git a/src/teleport.c b/src/teleport.c index 5c42151a6..8fb3f8c84 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -872,12 +872,20 @@ struct trap *trap; } void -level_tele_trap(trap) +level_tele_trap(trap, trflags) struct trap *trap; +unsigned trflags; { - You("%s onto a level teleport trap!", - Levitation ? (const char *) "float" - : locomotion(youmonst.data, "step")); + char verbbuf[BUFSZ]; + + if ((trflags & VIASITTING) != 0) + Strcpy(verbbuf, "trigger"); /* follows "You sit down." */ + else + Sprintf(verbbuf, "%s onto", + Levitation ? (const char *) "float" + : locomotion(youmonst.data, "step")); + You("%s a level teleport trap!", verbbuf); + if (Antimagic) { shieldeff(u.ux, u.uy); } diff --git a/src/trap.c b/src/trap.c index 23e26dec3..0df86b1d7 100644 --- a/src/trap.c +++ b/src/trap.c @@ -850,6 +850,7 @@ unsigned trflags; webmsgok = (trflags & NOWEBMSG) == 0, forcebungle = (trflags & FORCEBUNGLE) != 0, plunged = (trflags & TOOKPLUNGE) != 0, + viasitting = (trflags & VIASITTING) != 0, adj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE); int oldumort; int steed_article = ARTICLE_THE; @@ -1237,7 +1238,7 @@ unsigned trflags; case LEVEL_TELEP: seetrap(trap); - level_tele_trap(trap); + level_tele_trap(trap, trflags); break; case WEB: /* Our luckless player has stumbled into a web. */ @@ -1253,7 +1254,7 @@ unsigned trflags; if (webmsgok) { char verbbuf[BUFSZ]; - if (forcetrap) { + if (forcetrap || viasitting) { Strcpy(verbbuf, "are caught by"); } else if (u.usteed) { Sprintf(verbbuf, "lead %s into", @@ -1382,15 +1383,17 @@ unsigned trflags; char verbbuf[BUFSZ]; seetrap(trap); - if (u.usteed) - Sprintf(verbbuf, "lead %s", + if (viasitting) + Strcpy(verbbuf, "trigger"); /* follows "You sit down." */ + else if (u.usteed) + Sprintf(verbbuf, "lead %s onto", x_monnam(u.usteed, steed_article, (char *) 0, SUPPRESS_SADDLE, FALSE)); else - Sprintf(verbbuf, "%s", Levitation - ? (const char *) "float" - : locomotion(youmonst.data, "step")); - You("%s onto a polymorph trap!", verbbuf); + Sprintf(verbbuf, "%s onto", + Levitation ? (const char *) "float" + : locomotion(youmonst.data, "step")); + You("%s a polymorph trap!", verbbuf); if (Antimagic || Unchanging) { shieldeff(u.ux, u.uy); You_feel("momentarily different.");