-/* NetHack 3.6 mkobj.c $NHDT-Date: 1570569798 2019/10/08 21:23:18 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.153 $ */
+/* NetHack 3.6 mkobj.c $NHDT-Date: 1570754586 2019/10/11 00:43:06 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.154 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
struct obj *otmp;
otmp = mksobj(otyp, init, artif);
- if (otmp) {
- add_to_migration(otmp);
- otmp->owornmask = (long) MIGR_TO_SPECIES;
- otmp->corpsenm = mflags2;
- }
+ add_to_migration(otmp);
+ otmp->owornmask = (long) MIGR_TO_SPECIES;
+ otmp->corpsenm = mflags2;
return otmp;
}
-/* mkobj(): select a type of item from a class, use mksobj() to create it */
+/* mkobj(): select a type of item from a class, use mksobj() to create it;
+ result is always non-Null */
struct obj *
mkobj(oclass, artif)
char oclass;
for (n = rn2(n + 1); n > 0; n--) {
if (box->otyp == ICE_BOX) {
- if (!(otmp = mksobj(CORPSE, TRUE, TRUE)))
- continue;
+ otmp = mksobj(CORPSE, TRUE, TRUE);
/* Note: setting age to 0 is correct. Age has a different
* from usual meaning for objects stored in ice boxes. -KAA
*/
SCROLL_CLASS, GEM_CLASS, SPBOOK_CLASS,
WEAPON_CLASS, TOOL_CLASS, 0 };
-/* mksobj(): create a specific type of object */
+/* mksobj(): create a specific type of object; result it always non-Null */
struct obj *
mksobj(otyp, init, artif)
int otyp;
case COIN_CLASS:
break; /* do nothing */
default:
- impossible("impossible mkobj %d, sym '%c'.", otmp->otyp,
- objects[otmp->otyp].oc_class);
- dealloc_obj(otmp); /* free() would suffice here */
- return (struct obj *) 0;
+ /* 3.6.3: this used to be impossible() followed by return 0
+ but most callers aren't prepared to deal with Null result
+ and cluttering them up to do so is pointless */
+ panic("mksobj tried to make type %d, class %d.",
+ (int) otmp->otyp, (int) objects[otmp->otyp].oc_class);
+ /*NOTREACHED*/
}
}
static int treefruits[] = { APPLE, ORANGE, PEAR, BANANA, EUCALYPTUS_LEAF };
+/* called when a tree is kicked; never returns Null */
struct obj *
rnd_treefruit_at(x, y)
int x, y;
return mksobj_at(treefruits[rn2(SIZE(treefruits))], x, y, TRUE, FALSE);
}
+/* create a stack of N gold pieces; never returns Null */
struct obj *
mkgold(amount, x, y)
long amount;
int x, y;
{
- register struct obj *gold = g_at(x, y);
+ struct obj *gold = g_at(x, y);
if (amount <= 0L) {
long mul = rnd(30 / max(12-depth(&u.uz), 2));
+
amount = (long) (1 + rnd(level_difficulty() + 2) * mul);
}
if (gold) {
return gold;
}
-/* return TRUE if the corpse has special timing */
-#define special_corpse(num) \
- (((num) == PM_LIZARD) || ((num) == PM_LICHEN) || (is_rider(&mons[num])) \
- || (mons[num].mlet == S_TROLL))
+/* return TRUE if the corpse has special timing;
+ lizards and lichen don't rot, trolls and Riders auto-revive */
+#define special_corpse(num) \
+ (((num) == PM_LIZARD || (num) == PM_LICHEN) \
+ || (mons[num].mlet == S_TROLL || is_rider(&mons[num])))
-/*
+/* mkcorpstat: make a corpse or statue; never returns Null.
+ *
* OEXTRA note: Passing mtmp causes mtraits to be saved
* even if ptr passed as well, but ptr is always used for
* the corpse type (corpsenm). That allows the corpse type
int x, y;
unsigned corpstatflags;
{
- register struct obj *otmp;
+ struct obj *otmp;
boolean init = ((corpstatflags & CORPSTAT_INIT) != 0);
if (objtype != CORPSE && objtype != STATUE)
impossible("making corpstat type %d", objtype);
if (x == 0 && y == 0) { /* special case - random placement */
otmp = mksobj(objtype, init, FALSE);
- if (otmp)
- (void) rloco(otmp);
- } else
+ (void) rloco(otmp);
+ } else {
otmp = mksobj_at(objtype, x, y, init, FALSE);
- if (otmp) {
- if (mtmp) {
- struct obj *otmp2;
-
- if (!ptr)
- ptr = mtmp->data;
- /* save_mtraits frees original data pointed to by otmp */
- otmp2 = save_mtraits(otmp, mtmp);
- if (otmp2)
- otmp = otmp2;
- }
- /* use the corpse or statue produced by mksobj() as-is
- unless `ptr' is non-null */
- if (ptr) {
- int old_corpsenm = otmp->corpsenm;
-
- otmp->corpsenm = monsndx(ptr);
- otmp->owt = weight(otmp);
- if (otmp->otyp == CORPSE && (special_corpse(old_corpsenm)
- || special_corpse(otmp->corpsenm))) {
- obj_stop_timers(otmp);
- start_corpse_timeout(otmp);
- }
+ }
+
+ /* when 'mtmp' is non-null make a corpse or statue of that monster,
+ otherwise keep the random type chosen by mksobj() */
+ if (mtmp) {
+ int old_corpsenm = otmp->corpsenm;
+
+ /* save_mtraits updates otmp->oextra->omonst in place */
+ (void) save_mtraits(otmp, mtmp);
+
+ /* when 'ptr' is non-null use the type specified by our caller,
+ otherwise use the monster's species for the corpse */
+ if (!ptr)
+ ptr = mtmp->data;
+
+ otmp->corpsenm = monsndx(ptr);
+ otmp->owt = weight(otmp);
+ if (otmp->otyp == CORPSE && (special_corpse(old_corpsenm)
+ || special_corpse(otmp->corpsenm))) {
+ obj_stop_timers(otmp);
+ start_corpse_timeout(otmp);
}
}
return otmp;
corpse_revive_type(obj)
struct obj *obj;
{
- int revivetype;
+ int revivetype = obj->corpsenm;
struct monst *mtmp;
- if (has_omonst(obj)
- && ((mtmp = get_mtraits(obj, FALSE)) != (struct monst *) 0)) {
+
+ if (has_omonst(obj) && ((mtmp = get_mtraits(obj, FALSE)) != 0)) {
/* mtmp is a temporary pointer to a monster's stored
attributes, not a real monster */
revivetype = mtmp->mnum;
- } else
- revivetype = obj->corpsenm;
+ }
return revivetype;
}
return mnew;
}
-/* make an object named after someone listed in the scoreboard file */
+/* make an object named after someone listed in the scoreboard file;
+ never returns Null */
struct obj *
mk_tt_object(objtype, x, y)
int objtype; /* CORPSE or STATUE */
-register int x, y;
+int x, y;
{
- register struct obj *otmp, *otmp2;
+ struct obj *otmp;
boolean initialize_it;
/* player statues never contain books */
initialize_it = (objtype != STATUE);
- if ((otmp = mksobj_at(objtype, x, y, initialize_it, FALSE)) != 0) {
- /* tt_oname will return null if the scoreboard is empty */
- if ((otmp2 = tt_oname(otmp)) != 0)
- otmp = otmp2;
- }
+ otmp = mksobj_at(objtype, x, y, initialize_it, FALSE);
+ /* tt_oname() will return null if the scoreboard is empty;
+ assigning an object name used to allocate a new obj but
+ doesn't any more so we can safely ignore the return value */
+ (void) tt_oname(otmp);
+
return otmp;
}
-/* make a new corpse or statue, uninitialized if a statue (i.e. no books) */
+/* make a new corpse or statue, uninitialized if a statue (i.e. no books);
+ never returns Null */
struct obj *
mk_named_object(objtype, ptr, x, y, nm)
int objtype; /* CORPSE or STATUE */
const char *nm;
{
struct obj *otmp;
- unsigned corpstatflags =
- (objtype != STATUE) ? CORPSTAT_INIT : CORPSTAT_NONE;
+ unsigned corpstatflags = (objtype != STATUE) ? CORPSTAT_INIT
+ : CORPSTAT_NONE;
otmp = mkcorpstat(objtype, (struct monst *) 0, ptr, x, y, corpstatflags);
if (nm)