From 13b8725ac2c871b0454e16d5d81dc5ab59ebb260 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 7 Dec 2024 19:38:01 -0800 Subject: [PATCH] combine taming of already tame monsters Merge the recent change in the effect of blessed scroll of taming on already tame monsters with the earlier change of any taming on already tame monsters. Non-blessed has a chance of boosting monst->mtame by 1 when it is less than 10, more likely the lower the current value is. For blessed, boost by 2 after that, so possibly by 3 if it is very low. Make spell of charm monster when skilled or expert in enchantment spells behave the same as blessed scroll of taming. [I'm not too sure about this; it may make the spell too powerful.] --- doc/fixes3-7-0.txt | 1 - src/dog.c | 26 +++++++++++++++++++++----- src/read.c | 22 ++++++++++------------ src/spell.c | 2 +- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 4154520b9..78feef0e9 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1484,7 +1484,6 @@ when hero who is poly'd into metallivore form eats a tin, bypass "smells like digging in ice was handled inconsistently, particularly if done at the span spot in front of closed drawbridge angry god may remove an intrinsic -blessed scroll of taming increases tameness of already tame creatures blessed scroll of destroy armor asks which armor to destroy diff --git a/src/dog.c b/src/dog.c index 21d18d89f..607f2cdf8 100644 --- a/src/dog.c +++ b/src/dog.c @@ -1092,8 +1092,18 @@ dogfood(struct monst *mon, struct obj *obj) * on the original mtmp. It now returns TRUE if the taming succeeded. */ boolean -tamedog(struct monst *mtmp, struct obj *obj, boolean givemsg) +tamedog( + struct monst *mtmp, + struct obj *obj, /* food or scroll/spell */ + boolean givemsg) { + boolean blessed_scroll = FALSE; + + if (obj && (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS)) { + blessed_scroll = obj->blessed ? TRUE : FALSE; + /* the rest of this routine assumes 'obj' represents food */ + obj = (struct obj *) NULL; + } /* reduce timed sleep or paralysis, leaving mtmp->mcanmove as-is (note: if mtmp is donning armor, this will reduce its busy time) */ if (mtmp->mfrozen) @@ -1159,11 +1169,17 @@ tamedog(struct monst *mtmp, struct obj *obj, boolean givemsg) return FALSE; } - /* 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) + /* maximum tameness is 20, only reachable via eating; if already tame but + less than 10, taming magic might make it become tamer; blessed scroll + or skilled spell raises low tameness by 2 or 3, uncursed by 0 or 1 */ + if (mtmp->mtame && mtmp->mtame < 10) { + if (mtmp->mtame < rnd(10)) mtmp->mtame++; + if (blessed_scroll) { + mtmp->mtame += 2; + if (mtmp->mtame > 10) + mtmp->mtame = 10; + } return FALSE; /* didn't just get tamed */ } /* pacify angry shopkeeper but don't tame him/her/it/them */ diff --git a/src/read.c b/src/read.c index 565ce90ea..b3c265d38 100644 --- a/src/read.c +++ b/src/read.c @@ -490,11 +490,13 @@ doread(void) pline("This %s has no label.", singular(scroll, xname)); return ECMD_OK; } else if (otyp == MAGIC_MARKER) { + static const int red_mons[] = { + PM_FIRE_ANT, PM_PYROLISK, PM_HELL_HOUND, PM_IMP, + PM_LARGE_MIMIC, PM_LEOCROTTA, PM_SCORPION, PM_XAN, + PM_GIANT_BAT, PM_WATER_MOCCASIN, PM_FLESH_GOLEM, + PM_BARBED_DEVIL, PM_MARILITH, PM_PIRANHA + }; char buf[BUFSZ]; - const int red_mons[] = { PM_FIRE_ANT, PM_PYROLISK, PM_HELL_HOUND, - PM_IMP, PM_LARGE_MIMIC, PM_LEOCROTTA, PM_SCORPION, PM_XAN, - PM_GIANT_BAT, PM_WATER_MOCCASIN, PM_FLESH_GOLEM, PM_BARBED_DEVIL, - PM_MARILITH, PM_PIRANHA }; struct permonst *pm = &mons[red_mons[scroll->o_id % SIZE(red_mons)]]; if (Blind) { @@ -1037,14 +1039,9 @@ maybe_tame(struct monst *mtmp, struct obj *sobj) /* 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, FALSE); - if (sobj->blessed && was_tame && mtmp->mtame) { - int new_tame = min(10, ACURR(A_CHA) / 2); + (void) tamedog(mtmp, sobj, FALSE); - if (mtmp->mtame < new_tame) - mtmp->mtame = new_tame; - } - if ((!was_peaceful && mtmp->mpeaceful) || (!was_tame && mtmp->mtame)) + if ((!was_peaceful && mtmp->mpeaceful) || was_tame != mtmp->mtame) return 1; } return 0; @@ -2103,7 +2100,8 @@ seffect_mail(struct obj **sobjp) /* scroll effects; return 1 if we use up the scroll and possibly make it become discovered, 0 if caller should take care of those side-effects */ int -seffects(struct obj *sobj) /* sobj - scroll or fake spellbook for spell */ +seffects( + struct obj *sobj) /* sobj - scroll or fake spellbook for spell */ { int otyp = sobj->otyp; diff --git a/src/spell.c b/src/spell.c index 3ef28cafa..3acdb3e1c 100644 --- a/src/spell.c +++ b/src/spell.c @@ -1509,12 +1509,12 @@ spelleffects(int spell_otyp, boolean atme, boolean force) case SPE_DETECT_FOOD: case SPE_CAUSE_FEAR: case SPE_IDENTIFY: + case SPE_CHARM_MONSTER: /* high skill yields effect equivalent to blessed scroll */ if (role_skill >= P_SKILLED) pseudo->blessed = 1; FALLTHROUGH; /*FALLTHRU*/ - case SPE_CHARM_MONSTER: case SPE_MAGIC_MAPPING: case SPE_CREATE_MONSTER: (void) seffects(pseudo);