Merge branch 'NetHack-3.6'
This commit is contained in:
+6
-1
@@ -1,4 +1,4 @@
|
|||||||
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.62 $ $NHDT-Date: 1561081353 2019/06/21 01:42:33 $
|
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.64 $ $NHDT-Date: 1561233801 2019/06/22 20:03:21 $
|
||||||
|
|
||||||
This fixes36.3 file is here to capture information about updates in the 3.6.x
|
This fixes36.3 file is here to capture information about updates in the 3.6.x
|
||||||
lineage following the release of 3.6.2 in May 2019. Please note, however,
|
lineage following the release of 3.6.2 in May 2019. Please note, however,
|
||||||
@@ -79,6 +79,11 @@ for wizard mode 'monpolycontrol', allow usually disallowed type 'chameleon',
|
|||||||
add Space, Return, and Escape to '? k' (help for menu control keys)
|
add Space, Return, and Escape to '? k' (help for menu control keys)
|
||||||
hero can no longer negotiate a bribe with a demon lord when deaf
|
hero can no longer negotiate a bribe with a demon lord when deaf
|
||||||
wishing for "foo amulet" now yields an "amulet of foo" rather than random one
|
wishing for "foo amulet" now yields an "amulet of foo" rather than random one
|
||||||
|
code in parse_conf_file() to trim trailing blanks/cr was skipping over them
|
||||||
|
partly eaten food with one bite left had message anomalies when eaten; the
|
||||||
|
usual "you resume your meal" case lacked the "you're finished" message
|
||||||
|
when done; eating something else in between to clobber meal context
|
||||||
|
resulted in no messages at all when restarting and finishing last bite
|
||||||
|
|
||||||
|
|
||||||
Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository
|
Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 eat.c $NHDT-Date: 1559670604 2019/06/04 17:50:04 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.202 $ */
|
/* NetHack 3.6 eat.c $NHDT-Date: 1561233801 2019/06/22 20:03:21 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.203 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -25,7 +25,7 @@ STATIC_DCL void FDECL(cpostfx, (int));
|
|||||||
STATIC_DCL void FDECL(consume_tin, (const char *));
|
STATIC_DCL void FDECL(consume_tin, (const char *));
|
||||||
STATIC_DCL void FDECL(start_tin, (struct obj *));
|
STATIC_DCL void FDECL(start_tin, (struct obj *));
|
||||||
STATIC_DCL int FDECL(eatcorpse, (struct obj *));
|
STATIC_DCL int FDECL(eatcorpse, (struct obj *));
|
||||||
STATIC_DCL void FDECL(start_eating, (struct obj *));
|
STATIC_DCL void FDECL(start_eating, (struct obj *, BOOLEAN_P));
|
||||||
STATIC_DCL void FDECL(fprefx, (struct obj *));
|
STATIC_DCL void FDECL(fprefx, (struct obj *));
|
||||||
STATIC_DCL void FDECL(fpostfx, (struct obj *));
|
STATIC_DCL void FDECL(fpostfx, (struct obj *));
|
||||||
STATIC_DCL int NDECL(bite);
|
STATIC_DCL int NDECL(bite);
|
||||||
@@ -1413,15 +1413,12 @@ const char *mesg;
|
|||||||
gainstr(tin, 0, FALSE);
|
gainstr(tin, 0, FALSE);
|
||||||
|
|
||||||
tin = costly_tin(COST_OPEN);
|
tin = costly_tin(COST_OPEN);
|
||||||
|
lesshungry(tin->blessed ? 600 /* blessed */
|
||||||
lesshungry(tin->blessed
|
: !tin->cursed ? (400 + rnd(200)) /* uncursed */
|
||||||
? 600 /* blessed */
|
: (200 + rnd(400))); /* cursed */
|
||||||
: !tin->cursed
|
|
||||||
? (400 + rnd(200)) /* uncursed */
|
|
||||||
: (200 + rnd(400))); /* cursed */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
use_up_tin:
|
use_up_tin:
|
||||||
if (carried(tin))
|
if (carried(tin))
|
||||||
useup(tin);
|
useup(tin);
|
||||||
else
|
else
|
||||||
@@ -1499,7 +1496,7 @@ struct obj *otmp;
|
|||||||
}
|
}
|
||||||
pline("Using %s you try to open the tin.", yobjnam(uwep, (char *) 0));
|
pline("Using %s you try to open the tin.", yobjnam(uwep, (char *) 0));
|
||||||
} else {
|
} else {
|
||||||
no_opener:
|
no_opener:
|
||||||
pline("It is not so easy to open this tin.");
|
pline("It is not so easy to open this tin.");
|
||||||
if (Glib) {
|
if (Glib) {
|
||||||
pline_The("tin slips from your %s.",
|
pline_The("tin slips from your %s.",
|
||||||
@@ -1723,8 +1720,9 @@ struct obj *otmp;
|
|||||||
|
|
||||||
/* called as you start to eat */
|
/* called as you start to eat */
|
||||||
STATIC_OVL void
|
STATIC_OVL void
|
||||||
start_eating(otmp)
|
start_eating(otmp, already_partly_eaten)
|
||||||
struct obj *otmp;
|
struct obj *otmp;
|
||||||
|
boolean already_partly_eaten;
|
||||||
{
|
{
|
||||||
const char *old_nomovemsg, *save_nomovemsg;
|
const char *old_nomovemsg, *save_nomovemsg;
|
||||||
static char msgbuf[BUFSZ];
|
static char msgbuf[BUFSZ];
|
||||||
@@ -1769,7 +1767,8 @@ struct obj *otmp;
|
|||||||
|
|
||||||
if (++g.context.victual.usedtime >= g.context.victual.reqtime) {
|
if (++g.context.victual.usedtime >= g.context.victual.reqtime) {
|
||||||
/* print "finish eating" message if they just resumed -dlc */
|
/* print "finish eating" message if they just resumed -dlc */
|
||||||
done_eating(g.context.victual.reqtime > 1 ? TRUE : FALSE);
|
done_eating((g.context.victual.reqtime > 1
|
||||||
|
|| already_partly_eaten) ? TRUE : FALSE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1778,28 +1777,35 @@ struct obj *otmp;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* called on "first bite" of (non-corpse) food.
|
* Called on "first bite" of (non-corpse) food, after touchfood() has
|
||||||
* used for non-rotten non-tin non-corpse food
|
* marked it 'partly eaten'. Used for non-rotten non-tin non-corpse food.
|
||||||
|
* Messages should use present tense since multi-turn food won't be
|
||||||
|
* finishing at the time they're issued.
|
||||||
*/
|
*/
|
||||||
STATIC_OVL void
|
STATIC_OVL void
|
||||||
fprefx(otmp)
|
fprefx(otmp)
|
||||||
struct obj *otmp;
|
struct obj *otmp;
|
||||||
{
|
{
|
||||||
switch (otmp->otyp) {
|
switch (otmp->otyp) {
|
||||||
case FOOD_RATION:
|
case FOOD_RATION: /* nutrition 800 */
|
||||||
|
/* 200+800 remains below 1000+1, the satiation threshold */
|
||||||
if (u.uhunger <= 200)
|
if (u.uhunger <= 200)
|
||||||
pline(Hallucination ? "Oh wow, like, superior, man!"
|
pline("%s!", Hallucination ? "Oh wow, like, superior, man"
|
||||||
: "That food really hit the spot!");
|
: "This food really hits the spot");
|
||||||
else if (u.uhunger <= 700)
|
|
||||||
pline("That satiated your %s!", body_part(STOMACH));
|
/* 700-1+800 remains below 1500, the choking threshold which
|
||||||
|
triggers "you're having a hard time getting it down" feedback */
|
||||||
|
else if (u.uhunger < 700)
|
||||||
|
pline("This satiates your %s!", body_part(STOMACH));
|
||||||
|
/* [satiation message may be inaccurate if eating gets interrupted] */
|
||||||
break;
|
break;
|
||||||
case TRIPE_RATION:
|
case TRIPE_RATION:
|
||||||
if (carnivorous(g.youmonst.data) && !humanoid(g.youmonst.data))
|
if (carnivorous(g.youmonst.data) && !humanoid(g.youmonst.data)) {
|
||||||
pline("That tripe ration was surprisingly good!");
|
pline("This tripe ration is surprisingly good!");
|
||||||
else if (maybe_polyd(is_orc(g.youmonst.data), Race_if(PM_ORC)))
|
} else if (maybe_polyd(is_orc(g.youmonst.data), Race_if(PM_ORC))) {
|
||||||
pline(Hallucination ? "Tastes great! Less filling!"
|
pline(Hallucination ? "Tastes great! Less filling!"
|
||||||
: "Mmm, tripe... not bad!");
|
: "Mmm, tripe... not bad!");
|
||||||
else {
|
} else {
|
||||||
pline("Yak - dog food!");
|
pline("Yak - dog food!");
|
||||||
more_experienced(1, 0);
|
more_experienced(1, 0);
|
||||||
newexplevel();
|
newexplevel();
|
||||||
@@ -1832,7 +1838,7 @@ struct obj *otmp;
|
|||||||
default:
|
default:
|
||||||
if (otmp->otyp == SLIME_MOLD && !otmp->cursed
|
if (otmp->otyp == SLIME_MOLD && !otmp->cursed
|
||||||
&& otmp->spe == g.context.current_fruit) {
|
&& otmp->spe == g.context.current_fruit) {
|
||||||
pline("My, that was a %s %s!",
|
pline("My, this is a %s %s!",
|
||||||
Hallucination ? "primo" : "yummy",
|
Hallucination ? "primo" : "yummy",
|
||||||
singular(otmp, xname));
|
singular(otmp, xname));
|
||||||
} else if (otmp->otyp == APPLE && otmp->cursed && !Sleep_resistance) {
|
} else if (otmp->otyp == APPLE && otmp->cursed && !Sleep_resistance) {
|
||||||
@@ -1851,9 +1857,7 @@ struct obj *otmp;
|
|||||||
if (!Hallucination) {
|
if (!Hallucination) {
|
||||||
pline("Core dumped.");
|
pline("Core dumped.");
|
||||||
} else {
|
} else {
|
||||||
/* This is based on an old Usenet joke, a fake a.out manual
|
/* based on an old Usenet joke, a fake a.out manual page */
|
||||||
* page
|
|
||||||
*/
|
|
||||||
int x = rnd(100);
|
int x = rnd(100);
|
||||||
|
|
||||||
pline("%s -- core dumped.",
|
pline("%s -- core dumped.",
|
||||||
@@ -1871,7 +1875,7 @@ struct obj *otmp;
|
|||||||
will be abused more times before illness completes */
|
will be abused more times before illness completes */
|
||||||
make_vomiting((Vomiting & TIMEOUT) + (long) d(10, 4), TRUE);
|
make_vomiting((Vomiting & TIMEOUT) + (long) d(10, 4), TRUE);
|
||||||
} else {
|
} else {
|
||||||
give_feedback:
|
give_feedback:
|
||||||
pline("This %s is %s", singular(otmp, xname),
|
pline("This %s is %s", singular(otmp, xname),
|
||||||
otmp->cursed
|
otmp->cursed
|
||||||
? (Hallucination ? "grody!" : "terrible!")
|
? (Hallucination ? "grody!" : "terrible!")
|
||||||
@@ -2438,7 +2442,8 @@ doeat()
|
|||||||
{
|
{
|
||||||
struct obj *otmp;
|
struct obj *otmp;
|
||||||
int basenutrit; /* nutrition of full item */
|
int basenutrit; /* nutrition of full item */
|
||||||
boolean dont_start = FALSE, nodelicious = FALSE;
|
boolean dont_start = FALSE, nodelicious = FALSE,
|
||||||
|
already_partly_eaten;
|
||||||
|
|
||||||
if (Strangled) {
|
if (Strangled) {
|
||||||
pline("If you can't breathe air, how can you consume solids?");
|
pline("If you can't breathe air, how can you consume solids?");
|
||||||
@@ -2600,8 +2605,10 @@ doeat()
|
|||||||
g.context.victual.piece = touchfood(otmp);
|
g.context.victual.piece = touchfood(otmp);
|
||||||
if (g.context.victual.piece)
|
if (g.context.victual.piece)
|
||||||
g.context.victual.o_id = g.context.victual.piece->o_id;
|
g.context.victual.o_id = g.context.victual.piece->o_id;
|
||||||
You("resume your meal.");
|
You("resume %syour meal.",
|
||||||
start_eating(g.context.victual.piece);
|
(g.context.victual.usedtime + 1 >= g.context.victual.reqtime)
|
||||||
|
? "the last bite of " : "");
|
||||||
|
start_eating(g.context.victual.piece, FALSE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2616,7 +2623,7 @@ doeat()
|
|||||||
/* KMH, conduct */
|
/* KMH, conduct */
|
||||||
u.uconduct.food++;
|
u.uconduct.food++;
|
||||||
|
|
||||||
g.context.victual.o_id = 0;
|
already_partly_eaten = otmp->oeaten ? TRUE : FALSE;
|
||||||
g.context.victual.piece = otmp = touchfood(otmp);
|
g.context.victual.piece = otmp = touchfood(otmp);
|
||||||
if (g.context.victual.piece)
|
if (g.context.victual.piece)
|
||||||
g.context.victual.o_id = g.context.victual.piece->o_id;
|
g.context.victual.o_id = g.context.victual.piece->o_id;
|
||||||
@@ -2669,8 +2676,13 @@ doeat()
|
|||||||
dont_start = TRUE;
|
dont_start = TRUE;
|
||||||
}
|
}
|
||||||
consume_oeaten(otmp, 1); /* oeaten >>= 1 */
|
consume_oeaten(otmp, 1); /* oeaten >>= 1 */
|
||||||
} else
|
} else if (!already_partly_eaten) {
|
||||||
fprefx(otmp);
|
fprefx(otmp);
|
||||||
|
} else {
|
||||||
|
You("%s %s.",
|
||||||
|
(g.context.victual.reqtime == 1) ? "eat" : "begin eating",
|
||||||
|
doname(otmp));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* re-calc the nutrition */
|
/* re-calc the nutrition */
|
||||||
@@ -2702,7 +2714,7 @@ doeat()
|
|||||||
g.context.victual.canchoke = (u.uhs == SATIATED);
|
g.context.victual.canchoke = (u.uhs == SATIATED);
|
||||||
|
|
||||||
if (!dont_start)
|
if (!dont_start)
|
||||||
start_eating(otmp);
|
start_eating(otmp, already_partly_eaten);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3159,7 +3171,7 @@ int corpsecheck; /* 0, no check, 1, corpses, 2, tinnable corpses */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skipfloor:
|
skipfloor:
|
||||||
/* We cannot use ALL_CLASSES since that causes getobj() to skip its
|
/* We cannot use ALL_CLASSES since that causes getobj() to skip its
|
||||||
* "ugly checks" and we need to check for inedible items.
|
* "ugly checks" and we need to check for inedible items.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+2
-2
@@ -2994,9 +2994,9 @@ boolean FDECL((*proc), (char *));
|
|||||||
*ep = '\0';
|
*ep = '\0';
|
||||||
|
|
||||||
/* trim off spaces at end of line */
|
/* trim off spaces at end of line */
|
||||||
while (--ep >= inbuf
|
while (ep >= inbuf
|
||||||
&& (*ep == ' ' || *ep == '\t' || *ep == '\r'))
|
&& (*ep == ' ' || *ep == '\t' || *ep == '\r'))
|
||||||
*ep = '\0';
|
*ep-- = '\0';
|
||||||
|
|
||||||
if (!config_error_nextline(inbuf)) {
|
if (!config_error_nextline(inbuf)) {
|
||||||
rv = FALSE;
|
rv = FALSE;
|
||||||
|
|||||||
+64
-59
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 makemon.c $NHDT-Date: 1559733390 2019/06/05 11:16:30 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.137 $ */
|
/* NetHack 3.6 makemon.c $NHDT-Date: 1561236435 2019/06/22 20:47:15 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.138 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -819,18 +819,20 @@ xchar x, y; /* clone's preferred location or 0 (near mon) */
|
|||||||
if (x == 0) {
|
if (x == 0) {
|
||||||
mm.x = mon->mx;
|
mm.x = mon->mx;
|
||||||
mm.y = mon->my;
|
mm.y = mon->my;
|
||||||
if (!enexto(&mm, mm.x, mm.y, mon->data) || MON_AT(mm.x, mm.y))
|
|
||||||
return (struct monst *) 0;
|
|
||||||
} else if (!isok(x, y)) {
|
|
||||||
return (struct monst *) 0; /* paranoia */
|
|
||||||
} else {
|
} else {
|
||||||
mm.x = x;
|
mm.x = x;
|
||||||
mm.y = y;
|
mm.y = y;
|
||||||
if (MON_AT(mm.x, mm.y)) {
|
|
||||||
if (!enexto(&mm, mm.x, mm.y, mon->data) || MON_AT(mm.x, mm.y))
|
|
||||||
return (struct monst *) 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!isok(mm.x, mm.y)) { /* paranoia */
|
||||||
|
impossible("clone_mon trying to create a monster at <%d,%d>?",
|
||||||
|
mm.x, mm.y);
|
||||||
|
return (struct monst *) 0;
|
||||||
|
}
|
||||||
|
if (MON_AT(mm.x, mm.y)) { /* (always True for the x==0 case) */
|
||||||
|
if (!enexto(&mm, mm.x, mm.y, mon->data) || MON_AT(mm.x, mm.y))
|
||||||
|
return (struct monst *) 0;
|
||||||
|
}
|
||||||
|
|
||||||
m2 = newmonst();
|
m2 = newmonst();
|
||||||
*m2 = *mon; /* copy condition of old monster */
|
*m2 = *mon; /* copy condition of old monster */
|
||||||
m2->mextra = (struct mextra *) 0;
|
m2->mextra = (struct mextra *) 0;
|
||||||
@@ -846,7 +848,7 @@ xchar x, y; /* clone's preferred location or 0 (near mon) */
|
|||||||
m2->mtrapped = 0;
|
m2->mtrapped = 0;
|
||||||
m2->mcloned = 1;
|
m2->mcloned = 1;
|
||||||
m2->minvent = (struct obj *) 0; /* objects don't clone */
|
m2->minvent = (struct obj *) 0; /* objects don't clone */
|
||||||
m2->mleashed = FALSE;
|
m2->mleashed = 0;
|
||||||
/* Max HP the same, but current HP halved for both. The caller
|
/* Max HP the same, but current HP halved for both. The caller
|
||||||
* might want to override this by halving the max HP also.
|
* might want to override this by halving the max HP also.
|
||||||
* When current HP is odd, the original keeps the extra point.
|
* When current HP is odd, the original keeps the extra point.
|
||||||
@@ -856,21 +858,20 @@ xchar x, y; /* clone's preferred location or 0 (near mon) */
|
|||||||
m2->mhp = mon->mhp / 2;
|
m2->mhp = mon->mhp / 2;
|
||||||
mon->mhp -= m2->mhp;
|
mon->mhp -= m2->mhp;
|
||||||
|
|
||||||
/* since shopkeepers and guards will only be cloned if they've been
|
/* clone doesn't have mextra so mustn't retain special monster flags */
|
||||||
* polymorphed away from their original forms, the clone doesn't have
|
m2->isshk = 0;
|
||||||
* room for the extra information. we also don't want two shopkeepers
|
m2->isgd = 0;
|
||||||
* around for the same shop.
|
m2->ispriest = 0;
|
||||||
*/
|
/* ms->isminion handled below */
|
||||||
if (mon->isshk)
|
|
||||||
m2->isshk = FALSE;
|
/* clone shouldn't be reluctant to move on spots 'parent' just moved on */
|
||||||
if (mon->isgd)
|
(void) memset((genericptr_t) m2->mtrack, 0, sizeof m2->mtrack);
|
||||||
m2->isgd = FALSE;
|
|
||||||
if (mon->ispriest)
|
|
||||||
m2->ispriest = FALSE;
|
|
||||||
place_monster(m2, m2->mx, m2->my);
|
place_monster(m2, m2->mx, m2->my);
|
||||||
if (emits_light(m2->data))
|
if (emits_light(m2->data))
|
||||||
new_light_source(m2->mx, m2->my, emits_light(m2->data), LS_MONSTER,
|
new_light_source(m2->mx, m2->my, emits_light(m2->data), LS_MONSTER,
|
||||||
monst_to_any(m2));
|
monst_to_any(m2));
|
||||||
|
/* if 'parent' is named, give the clone the same name */
|
||||||
if (has_mname(mon)) {
|
if (has_mname(mon)) {
|
||||||
m2 = christen_monst(m2, MNAME(mon));
|
m2 = christen_monst(m2, MNAME(mon));
|
||||||
} else if (mon->isshk) {
|
} else if (mon->isshk) {
|
||||||
@@ -878,31 +879,35 @@ xchar x, y; /* clone's preferred location or 0 (near mon) */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* not all clones caused by player are tame or peaceful */
|
/* not all clones caused by player are tame or peaceful */
|
||||||
if (!g.context.mon_moving) {
|
if (!g.context.mon_moving && mon->mpeaceful) {
|
||||||
if (mon->mtame)
|
if (mon->mtame)
|
||||||
m2->mtame = rn2(max(2 + u.uluck, 2)) ? mon->mtame : 0;
|
m2->mtame = rn2(max(2 + u.uluck, 2)) ? mon->mtame : 0;
|
||||||
else if (mon->mpeaceful)
|
else if (mon->mpeaceful)
|
||||||
m2->mpeaceful = rn2(max(2 + u.uluck, 2)) ? 1 : 0;
|
m2->mpeaceful = rn2(max(2 + u.uluck, 2)) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
/* if guardian angel could be cloned (maybe after polymorph?),
|
||||||
|
m2 could be both isminion and mtame; isminion takes precedence */
|
||||||
|
if (m2->isminion) {
|
||||||
|
int atyp;
|
||||||
|
|
||||||
newsym(m2->mx, m2->my); /* display the new monster */
|
newemin(m2);
|
||||||
if (m2->mtame) {
|
*EMIN(m2) = *EMIN(mon);
|
||||||
if (mon->isminion) {
|
/* renegade when same alignment as hero but not peaceful or
|
||||||
newemin(m2);
|
when peaceful while being different alignment from hero */
|
||||||
if (EMIN(mon))
|
atyp = EMIN(m2)->min_align;
|
||||||
*(EMIN(m2)) = *(EMIN(mon));
|
EMIN(m2)->renegade = (atyp != u.ualign.type) ^ !m2->mpeaceful;
|
||||||
} else {
|
} else if (m2->mtame) {
|
||||||
/* because m2 is a copy of mon it is tame but not init'ed.
|
/* Because m2 is a copy of mon it is tame but not init'ed.
|
||||||
* however, tamedog will not re-tame a tame dog, so m2
|
However, tamedog() will not re-tame a tame dog, so m2
|
||||||
* must be made non-tame to get initialized properly.
|
must be made non-tame to get initialized properly. */
|
||||||
*/
|
m2->mtame = 0;
|
||||||
m2->mtame = 0;
|
if (tamedog(m2, (struct obj *) 0))
|
||||||
if (tamedog(m2, (struct obj *) 0)) {
|
*EDOG(m2) = *EDOG(mon);
|
||||||
*(EDOG(m2)) = *(EDOG(mon));
|
/* [TODO? some (most? all?) edog fields probably should be
|
||||||
}
|
reinitialized rather that retain the 'parent's values] */
|
||||||
}
|
|
||||||
}
|
}
|
||||||
set_malign(m2);
|
set_malign(m2);
|
||||||
|
newsym(m2->mx, m2->my); /* display the new monster */
|
||||||
|
|
||||||
return m2;
|
return m2;
|
||||||
}
|
}
|
||||||
@@ -1107,6 +1112,8 @@ register int x, y;
|
|||||||
int mmflags;
|
int mmflags;
|
||||||
{
|
{
|
||||||
register struct monst *mtmp;
|
register struct monst *mtmp;
|
||||||
|
struct monst fakemon;
|
||||||
|
coord cc;
|
||||||
int mndx, mcham, ct, mitem;
|
int mndx, mcham, ct, mitem;
|
||||||
boolean anymon = (!ptr);
|
boolean anymon = (!ptr);
|
||||||
boolean byyou = (x == u.ux && y == u.uy);
|
boolean byyou = (x == u.ux && y == u.uy);
|
||||||
@@ -1114,40 +1121,37 @@ int mmflags;
|
|||||||
boolean countbirth = ((mmflags & MM_NOCOUNTBIRTH) == 0);
|
boolean countbirth = ((mmflags & MM_NOCOUNTBIRTH) == 0);
|
||||||
unsigned gpflags = (mmflags & MM_IGNOREWATER) ? MM_IGNOREWATER : 0;
|
unsigned gpflags = (mmflags & MM_IGNOREWATER) ? MM_IGNOREWATER : 0;
|
||||||
|
|
||||||
|
fakemon = cg.zeromonst;
|
||||||
|
cc.x = cc.y = 0;
|
||||||
|
|
||||||
/* if caller wants random location, do it here */
|
/* if caller wants random location, do it here */
|
||||||
if (x == 0 && y == 0) {
|
if (x == 0 && y == 0) {
|
||||||
coord cc;
|
|
||||||
struct monst fakemon;
|
|
||||||
|
|
||||||
cc.x = cc.y = 0; /* lint suppression */
|
|
||||||
fakemon = cg.zeromonst;
|
|
||||||
fakemon.data = ptr; /* set up for goodpos */
|
fakemon.data = ptr; /* set up for goodpos */
|
||||||
if (!makemon_rnd_goodpos(ptr ? &fakemon : (struct monst *)0,
|
if (!makemon_rnd_goodpos(ptr ? &fakemon : (struct monst *) 0,
|
||||||
gpflags, &cc))
|
gpflags, &cc))
|
||||||
return (struct monst *) 0;
|
return (struct monst *) 0;
|
||||||
x = cc.x;
|
x = cc.x;
|
||||||
y = cc.y;
|
y = cc.y;
|
||||||
} else if (byyou && !g.in_mklev) {
|
} else if (byyou && !g.in_mklev) {
|
||||||
coord bypos;
|
if (!enexto_core(&cc, u.ux, u.uy, ptr, gpflags))
|
||||||
|
|
||||||
if (enexto_core(&bypos, u.ux, u.uy, ptr, gpflags)) {
|
|
||||||
x = bypos.x;
|
|
||||||
y = bypos.y;
|
|
||||||
} else
|
|
||||||
return (struct monst *) 0;
|
return (struct monst *) 0;
|
||||||
|
x = cc.x;
|
||||||
|
y = cc.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
if (!isok(x, y)) {
|
||||||
|
impossible("makemon trying to create a monster at <%d,%d>?", x, y);
|
||||||
|
return (struct monst *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Does monster already exist at the position? */
|
/* Does monster already exist at the position? */
|
||||||
if (MON_AT(x, y)) {
|
if (MON_AT(x, y)) {
|
||||||
if ((mmflags & MM_ADJACENTOK) != 0) {
|
if (!(mmflags & MM_ADJACENTOK)
|
||||||
coord bypos;
|
|| !enexto_core(&cc, x, y, ptr, gpflags))
|
||||||
if (enexto_core(&bypos, x, y, ptr, gpflags)) {
|
|
||||||
x = bypos.x;
|
|
||||||
y = bypos.y;
|
|
||||||
} else
|
|
||||||
return (struct monst *) 0;
|
|
||||||
} else
|
|
||||||
return (struct monst *) 0;
|
return (struct monst *) 0;
|
||||||
|
x = cc.x;
|
||||||
|
y = cc.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
@@ -1167,7 +1171,6 @@ int mmflags;
|
|||||||
* for instance.)
|
* for instance.)
|
||||||
*/
|
*/
|
||||||
int tryct = 0; /* maybe there are no good choices */
|
int tryct = 0; /* maybe there are no good choices */
|
||||||
struct monst fakemon;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (!(ptr = rndmonst())) {
|
if (!(ptr = rndmonst())) {
|
||||||
@@ -1354,6 +1357,7 @@ int mmflags;
|
|||||||
? !(mmflags & (MM_EPRI | MM_EMIN))
|
? !(mmflags & (MM_EPRI | MM_EMIN))
|
||||||
: (mndx == PM_ANGEL && !(mmflags & MM_EMIN) && !rn2(3))) {
|
: (mndx == PM_ANGEL && !(mmflags & MM_EMIN) && !rn2(3))) {
|
||||||
struct emin *eminp;
|
struct emin *eminp;
|
||||||
|
|
||||||
newemin(mtmp);
|
newemin(mtmp);
|
||||||
eminp = EMIN(mtmp);
|
eminp = EMIN(mtmp);
|
||||||
|
|
||||||
@@ -1385,6 +1389,7 @@ int mmflags;
|
|||||||
if (!rn2(100) && is_domestic(ptr)
|
if (!rn2(100) && is_domestic(ptr)
|
||||||
&& can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)) {
|
&& can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)) {
|
||||||
struct obj *otmp = mksobj(SADDLE, TRUE, FALSE);
|
struct obj *otmp = mksobj(SADDLE, TRUE, FALSE);
|
||||||
|
|
||||||
put_saddle_on_mon(otmp, mtmp);
|
put_saddle_on_mon(otmp, mtmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user