github issue #819 - magic harp vs shopkeeper

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
This commit is contained in:
PatR
2022-07-16 05:08:26 -07:00
parent 29afd90bad
commit 231bd75b7f
4 changed files with 36 additions and 21 deletions

View File

@@ -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))

View 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);
}
}
}

View 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;