]> granicus.if.org Git - nethack/commitdiff
github issue #819 - magic harp vs shopkeeper
authorPatR <rankin@nethack.org>
Sat, 16 Jul 2022 12:08:26 +0000 (05:08 -0700)
committerPatR <rankin@nethack.org>
Sat, 16 Jul 2022 12:08:26 +0000 (05:08 -0700)
Issue reported by youkan700:  for shopkeepers, taming via magic harp
behaved differently than taming via scroll or spell.

Make magic harp's taming be the same as [non-cursed] scroll of taming
and spell of charm monster:  angry shopkeepers will be pacified (even
though they can't be tamed).

Also, add something I've been sitting on for ages:  when taming magic
hits an already tame monster, give that monster a chance to become
tamer.  Not significant for monsters that eat (unless being starved
for some reason) but matters for ones who don't eat.  For tameness N
(which has a maximum of 20), if N is less than 10, have any taming
yield a 10-N out of 10 chance to increase the tameness by 1.  So the
closer a pet is to becoming feral, the more likely for it to improve
tameness a little.

Closes #819

doc/fixes3-7-0.txt
src/dog.c
src/music.c
src/read.c

index 0e420632e490a070ced92a6d970bd7aee87b4ff7..e4fcb8828a19ce0e8cb6ae03f5f9555345a75489 100644 (file)
@@ -965,6 +965,8 @@ out of array bounds access attempt occurred when deciding whether to bounce
        if wand or spell zap reached edge of map
 if blind hero was challanged by a vault guard, it wasn't possible to see how
        to start following that guard out of the vault
+make taming via magic harp be consistent with scroll of taming and charm
+       spell:  an angry shopkeeper becomes pacified (but never tamed)
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
@@ -1731,6 +1733,7 @@ if built with DEBUG enabled and running in wizard mode, starting play with
        water on Plane of Water, and fumaroles on Plane of Fire be transparent
 add wizard mode #wizkill command to remove monster(s) from play
 some quest nemeses release a cloud of poisonous gas when they die
+taming magic acting on an already tame creature might make it become tamer
 
 
 Platform- and/or Interface-Specific New Features
index be1bb2d74494ebb19c452d9c17f1b5b16c7794dc..64b06b8c00cae592ad554ec01b10ff00f0b5cc0f 100644 (file)
--- a/src/dog.c
+++ b/src/dog.c
@@ -1012,8 +1012,23 @@ tamedog(struct monst *mtmp, struct obj *obj)
             return FALSE;
     }
 
-    if (mtmp->mtame || !mtmp->mcanmove
-        /* monsters with conflicting structures cannot be tamed */
+    /* if already tame, taming magic might make it become tamer */
+    if (mtmp->mtame) {
+        /* maximum tameness is 20, only reachable via eating */
+        if (rnd(10) > mtmp->mtame)
+            mtmp->mtame++;
+        return FALSE; /* didn't just get tamed */
+    }
+    /* pacify angry shopkeeper but don't tame him/her/it/them */
+    if (mtmp->isshk) {
+        make_happy_shk(mtmp, FALSE);
+        return FALSE;
+    }
+
+    if (!mtmp->mcanmove
+        /* monsters with conflicting structures cannot be tamed
+           [note: the various mextra structures don't actually conflict
+           with each other anymore] */
         || mtmp->isshk || mtmp->isgd || mtmp->ispriest || mtmp->isminion
         || is_covetous(mtmp->data) || is_human(mtmp->data)
         || (is_demon(mtmp->data) && !is_demon(g.youmonst.data))
index 4dd444d327797e31c8d32e8d2ce016eae779558d..e59470318ae6ac9e4b5084ef4a32ce807ca91dc2 100644 (file)
@@ -189,27 +189,24 @@ awaken_soldiers(struct monst* bugler  /* monster that played instrument */)
     }
 }
 
-/* Charm monsters in range.  Note that they may resist the spell.
- * If swallowed, range is reduced to 0.
- */
+/* Charm monsters in range.  Note that they may resist the spell. */
 static void
 charm_monsters(int distance)
 {
     struct monst *mtmp, *mtmp2;
 
-    if (u.uswallow) {
-        if (!resist(u.ustuck, TOOL_CLASS, 0, NOTELL))
-            (void) tamedog(u.ustuck, (struct obj *) 0);
-    } else {
-        for (mtmp = fmon; mtmp; mtmp = mtmp2) {
-            mtmp2 = mtmp->nmon;
-            if (DEADMONSTER(mtmp))
-                continue;
+    if (u.uswallow)
+        distance = 0; /* only u.ustuck will be affected (u.usteed is Null
+                       * since hero gets forcibly dismounted when engulfed) */
 
-            if (distu(mtmp->mx, mtmp->my) <= distance) {
-                if (!resist(mtmp, TOOL_CLASS, 0, NOTELL))
-                    (void) tamedog(mtmp, (struct obj *) 0);
-            }
+    for (mtmp = fmon; mtmp; mtmp = mtmp2) {
+        mtmp2 = mtmp->nmon;
+        if (DEADMONSTER(mtmp))
+            continue;
+
+        if (distu(mtmp->mx, mtmp->my) <= distance) {
+            if (!resist(mtmp, TOOL_CLASS, 0, NOTELL))
+                (void) tamedog(mtmp, (struct obj *) 0);
         }
     }
 }
index f0bb880cc33138f265eaa93da8cf5ed70d8e2f8f..3299ce2bd1b596c8009bfcf7021c6ec800199887 100644 (file)
@@ -1008,7 +1008,7 @@ forget(int howmuch)
 
 /* monster is hit by scroll of taming's effect */
 static int
-maybe_tame(struct monst* mtmp, struct obj* sobj)
+maybe_tame(struct monst *mtmp, struct obj *sobj)
 {
     int was_tame = mtmp->mtame;
     unsigned was_peaceful = mtmp->mpeaceful;
@@ -1018,9 +1018,9 @@ maybe_tame(struct monst* mtmp, struct obj* sobj)
         if (was_peaceful && !mtmp->mpeaceful)
             return -1;
     } else {
-        if (mtmp->isshk)
-            make_happy_shk(mtmp, FALSE);
-        else if (!resist(mtmp, sobj->oclass, 0, NOTELL))
+        /* for a shopkeeper, tamedog() will call make_happy_shk() but
+           not tame the target, so call it even if taming gets resisted */
+        if (!resist(mtmp, sobj->oclass, 0, NOTELL) || mtmp->isshk)
             (void) tamedog(mtmp, (struct obj *) 0);
         if ((!was_peaceful && mtmp->mpeaceful) || (!was_tame && mtmp->mtame))
             return 1;