From dc6827ce120e00c6f450b0223287de0d13877ad9 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 21 Jun 2016 17:32:02 -0700 Subject: [PATCH 1/2] more monkeys My old monkey patch was a bit more extensive than Pasi's, although it didn't originally include letting apes be tameable with bananas. No sense in throwing it away: 1) Make monkeys and apes be omnivores instead of carnivores. 2) Make bananas be preferred food for herbivore/omnivore subset of Y-class, so excludes carniverous ape, owlbear, and yeti. [Sasquatch remain omnivorous but aren't tameable with bananas.] 3) While updating befriend_with_food(), make horses be affected only by food they might eat, not by meat and corpses and tins. So they'll be somewhat harder to cope with for characters not strong enough to kill them. [Dogs and cats are unchanged.] Not included (not even implemented...): 0) Allow archeologists to choose monkey for starting pet. [The one in "Raiders of the Lost Ark" didn't actually belong to Indiana Jones but spent a lot of time accompanying him.] --- include/mondata.h | 16 ++++++++++++---- src/dog.c | 4 ++-- src/monst.c | 6 ++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/mondata.h b/include/mondata.h index 229617782..cdb299007 100644 --- a/include/mondata.h +++ b/include/mondata.h @@ -193,10 +193,18 @@ (vegan(ptr) \ || ((ptr)->mlet == S_PUDDING && (ptr) != &mons[PM_BLACK_PUDDING])) +/* monkeys are tameable via bananas but not pacifiable via food, + otherwise their theft attack could be nullified too easily; + dogs and cats can be tamed by anything they like to eat and are + pacified by any other food; + horses can be tamed by always-veggy food or lichen corpses but + not tamed or pacified by other corpses or tins of veggy critters */ #define befriend_with_obj(ptr, obj) \ - (((obj)->oclass == FOOD_CLASS && is_domestic(ptr)) \ - || ((obj)->otyp == BANANA && \ - ((ptr) == &mons[PM_MONKEY] \ - || (ptr) == &mons[PM_APE]))) + (((ptr) == &mons[PM_MONKEY] || (ptr) == &mons[PM_APE]) \ + ? (obj)->otyp == BANANA \ + : (is_domestic(ptr) && (obj)->oclass == FOOD_CLASS \ + && ((ptr)->mlet != S_UNICORN \ + || objects[(obj)->otyp].oc_material == VEGGY \ + || ((obj)->otyp == CORPSE && (obj)->corpsenm == PM_LICHEN)))) #endif /* MONDATA_H */ diff --git a/src/dog.c b/src/dog.c index f2993751d..0d55baad8 100644 --- a/src/dog.c +++ b/src/dog.c @@ -814,8 +814,8 @@ register struct obj *obj; case CARROT: return herbi ? DOGFOOD : starving ? ACCFOOD : MANFOOD; case BANANA: - return (mptr->mlet == S_YETI) - ? DOGFOOD + return (mptr->mlet == S_YETI && herbi) + ? DOGFOOD /* for monkey and ape (tameable), sasquatch */ : (herbi || starving) ? ACCFOOD : MANFOOD; diff --git a/src/monst.c b/src/monst.c index 7839b06cc..b99e44531 100644 --- a/src/monst.c +++ b/src/monst.c @@ -1915,16 +1915,18 @@ struct permonst _mons2[] = { /* * Apelike beasts */ + /* tameable via banana; does not grow up into ape... + not flagged as domestic, so no guilt penalty for eating non-pet one */ MON("monkey", S_YETI, LVL(2, 12, 6, 0, 0), (G_GENO | 1), A(ATTK(AT_CLAW, AD_SITM, 0, 0), ATTK(AT_BITE, AD_PHYS, 1, 3), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(100, 50, MS_GROWL, MZ_SMALL), 0, 0, - M1_ANIMAL | M1_HUMANOID | M1_CARNIVORE, 0, M3_INFRAVISIBLE, CLR_GRAY), + M1_ANIMAL | M1_HUMANOID | M1_OMNIVORE, 0, M3_INFRAVISIBLE, CLR_GRAY), MON("ape", S_YETI, LVL(4, 12, 6, 0, 0), (G_GENO | G_SGROUP | 2), A(ATTK(AT_CLAW, AD_PHYS, 1, 3), ATTK(AT_CLAW, AD_PHYS, 1, 3), ATTK(AT_BITE, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK), SIZ(1100, 500, MS_GROWL, MZ_LARGE), 0, 0, - M1_ANIMAL | M1_HUMANOID | M1_CARNIVORE, M2_STRONG, M3_INFRAVISIBLE, + M1_ANIMAL | M1_HUMANOID | M1_OMNIVORE, M2_STRONG, M3_INFRAVISIBLE, CLR_BROWN), MON("owlbear", S_YETI, LVL(5, 12, 5, 0, 0), (G_GENO | 3), A(ATTK(AT_CLAW, AD_PHYS, 1, 6), ATTK(AT_CLAW, AD_PHYS, 1, 6), From f32a9778b2bab1ca150a9db934cea7e643e9b4ef Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 22 Jun 2016 21:59:29 +0300 Subject: [PATCH 2/2] Unify mon throwing missile collision check --- src/mthrowu.c | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/mthrowu.c b/src/mthrowu.c index bff417325..a448ba8e6 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -414,6 +414,24 @@ boolean verbose; /* give message(s) even when you can't see what happened */ return 0; } +#define MT_FLIGHTCHECK(pre) \ + (/* missile hits edge of screen */ \ + !isok(bhitpos.x + dx, bhitpos.y + dy) \ + /* missile hits the wall */ \ + || IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ) \ + /* missile hit closed door */ \ + || closed_door(bhitpos.x + dx, bhitpos.y + dy) \ + /* missile might hit iron bars */ \ + /* the random chance for small objects hitting bars is */ \ + /* skipped when reaching them at point blank range */ \ + || (levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS \ + && hits_bars(&singleobj, \ + bhitpos.x, bhitpos.y, \ + bhitpos.x + dx, bhitpos.y + dy, \ + ((pre) ? 0 : !rn2(5)), 0)) \ + /* Thrown objects "sink" */ \ + || (!(pre) && IS_SINK(levl[bhitpos.x][bhitpos.y].typ))) + void m_throw(mon, x, y, dx, dy, range, obj) struct monst *mon; /* launching monster */ @@ -471,17 +489,7 @@ struct obj *obj; /* missile (or stack providing it) */ } } - /* pre-check for doors, walls and boundaries. - Also need to pre-check for bars regardless of direction; - the random chance for small objects hitting bars is - skipped when reaching them at point blank range */ - if (!isok(bhitpos.x + dx, bhitpos.y + dy) - || IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ) - || closed_door(bhitpos.x + dx, bhitpos.y + dy) - || (levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS - && hits_bars(&singleobj, - bhitpos.x, bhitpos.y, - bhitpos.x + dx, bhitpos.y + dy, 0, 0))) { + if (MT_FLIGHTCHECK(TRUE)) { (void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y); return; } @@ -611,20 +619,7 @@ struct obj *obj; /* missile (or stack providing it) */ } } if (!range /* reached end of path */ - /* missile hits edge of screen */ - || !isok(bhitpos.x + dx, bhitpos.y + dy) - /* missile hits the wall */ - || IS_ROCK(levl[bhitpos.x + dx][bhitpos.y + dy].typ) - /* missile hit closed door */ - || closed_door(bhitpos.x + dx, bhitpos.y + dy) - /* missile might hit iron bars */ - || (levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS - && hits_bars(&singleobj, - bhitpos.x, bhitpos.y, - bhitpos.x + dx, bhitpos.y + dy, - !rn2(5), 0)) - /* Thrown objects "sink" */ - || IS_SINK(levl[bhitpos.x][bhitpos.y].typ)) { + || MT_FLIGHTCHECK(FALSE)) { if (singleobj) { /* hits_bars might have destroyed it */ if (m_shot.n > 1 && (cansee(bhitpos.x, bhitpos.y) || (archer && canseemon(archer)))) @@ -648,6 +643,8 @@ struct obj *obj; /* missile (or stack providing it) */ } } +#undef MT_FLIGHTCHECK + /* Monster throws item at another monster */ int thrwmm(mtmp, mtarg)