Split trap victim generation into separate function

This commit is contained in:
Pasi Kallinen
2023-03-19 10:06:50 +02:00
parent 0e761c3e30
commit f3d457dbd4

View File

@@ -22,6 +22,7 @@ void clear_level_structures(void);
static void fill_ordinary_room(struct mkroom *);
static void makelevel(void);
static boolean bydoor(coordxy, coordxy);
static void mktrap_victim(struct trap *);
static struct mkroom *find_branch_room(coord *);
static struct mkroom *pos_to_room(coordxy, coordxy);
static boolean place_niche(struct mkroom *, coordxy *, coordxy *, coordxy *);
@@ -1390,6 +1391,122 @@ occupied(coordxy x, coordxy y)
|| invocation_pos(x, y));
}
/* generate a corpse and some items on top of a trap */
static void
mktrap_victim(struct trap *ttmp)
{
/* Object generated by the trap; initially NULL, stays NULL if
we fail to generate an object or if the trap doesn't
generate objects. */
struct obj *otmp = NULL;
int victim_mnum; /* race of the victim */
unsigned lvl = level_difficulty();
int kind = ttmp->ttyp;
coordxy x = ttmp->tx, y = ttmp->ty;
/* Not all trap types have special handling here; only the ones
that kill in a specific way that's obvious after the fact. */
switch (kind) {
case ARROW_TRAP:
otmp = mksobj(ARROW, TRUE, FALSE);
otmp->opoisoned = 0;
/* don't adjust the quantity; maybe the trap shot multiple
times, there was an untrapping attempt, etc... */
break;
case DART_TRAP:
otmp = mksobj(DART, TRUE, FALSE);
break;
case ROCKTRAP:
otmp = mksobj(ROCK, TRUE, FALSE);
break;
default:
/* no item dropped by the trap */
break;
}
if (otmp) {
place_object(otmp, x, y);
}
/* now otmp is reused for other items we're placing */
/* Place a random possession. This could be a weapon, tool,
food, or gem, i.e. the item classes that are typically
nonmagical and not worthless. */
do {
int poss_class = RANDOM_CLASS; /* init => lint suppression */
switch (rn2(4)) {
case 0:
poss_class = WEAPON_CLASS;
break;
case 1:
poss_class = TOOL_CLASS;
break;
case 2:
poss_class = FOOD_CLASS;
break;
case 3:
poss_class = GEM_CLASS;
break;
}
otmp = mkobj(poss_class, FALSE);
/* these items are always cursed, both for flavour (owned
by a dead adventurer, bones-pile-style) and for balance
(less useful to use, and encourage pets to avoid the trap) */
if (otmp) {
otmp->blessed = 0;
otmp->cursed = 1;
otmp->owt = weight(otmp);
place_object(otmp, x, y);
}
/* 20% chance of placing an additional item, recursively */
} while (!rn2(5));
/* Place a corpse. */
switch (rn2(15)) {
case 0:
/* elf corpses are the rarest as they're the most useful */
victim_mnum = PM_ELF;
/* elven adventurers get sleep resistance early; so don't
generate elf corpses on sleeping gas traps unless a)
we're on dlvl 2 (1 is impossible) and b) we pass a coin
flip */
if (kind == SLP_GAS_TRAP && !(lvl <= 2 && rn2(2)))
victim_mnum = PM_HUMAN;
break;
case 1: case 2:
victim_mnum = PM_DWARF;
break;
case 3: case 4: case 5:
victim_mnum = PM_ORC;
break;
case 6: case 7: case 8: case 9:
/* more common as they could have come from the Mines */
victim_mnum = PM_GNOME;
/* 10% chance of a candle too */
if (!rn2(10)) {
otmp = mksobj(rn2(4) ? TALLOW_CANDLE : WAX_CANDLE,
TRUE, FALSE);
otmp->quan = 1;
otmp->blessed = 0;
otmp->cursed = 1;
otmp->owt = weight(otmp);
place_object(otmp, x, y);
}
break;
default:
/* the most common race */
victim_mnum = PM_HUMAN;
break;
}
otmp = mkcorpstat(CORPSE, NULL, &mons[victim_mnum], x, y,
CORPSTAT_INIT);
if (otmp)
otmp->age -= (TAINT_AGE + 1); /* died too long ago to eat */
}
/* make a trap somewhere (in croom if mazeflag = 0 && !tm) */
/* if tm != null, make trap at that location */
void
@@ -1561,113 +1678,7 @@ mktrap(
&& !(kind == ROLLING_BOULDER_TRAP
&& t->launch.x == t->tx && t->launch.y == t->ty)
&& !is_pit(kind) && kind < HOLE) {
/* Object generated by the trap; initially NULL, stays NULL if
we fail to generate an object or if the trap doesn't
generate objects. */
struct obj *otmp = NULL;
int victim_mnum; /* race of the victim */
/* Not all trap types have special handling here; only the ones
that kill in a specific way that's obvious after the fact. */
switch (kind) {
case ARROW_TRAP:
otmp = mksobj(ARROW, TRUE, FALSE);
otmp->opoisoned = 0;
/* don't adjust the quantity; maybe the trap shot multiple
times, there was an untrapping attempt, etc... */
break;
case DART_TRAP:
otmp = mksobj(DART, TRUE, FALSE);
break;
case ROCKTRAP:
otmp = mksobj(ROCK, TRUE, FALSE);
break;
default:
/* no item dropped by the trap */
break;
}
if (otmp) {
place_object(otmp, m.x, m.y);
}
/* now otmp is reused for other items we're placing */
/* Place a random possession. This could be a weapon, tool,
food, or gem, i.e. the item classes that are typically
nonmagical and not worthless. */
do {
int poss_class = RANDOM_CLASS; /* init => lint suppression */
switch (rn2(4)) {
case 0:
poss_class = WEAPON_CLASS;
break;
case 1:
poss_class = TOOL_CLASS;
break;
case 2:
poss_class = FOOD_CLASS;
break;
case 3:
poss_class = GEM_CLASS;
break;
}
otmp = mkobj(poss_class, FALSE);
/* these items are always cursed, both for flavour (owned
by a dead adventurer, bones-pile-style) and for balance
(less useful to use, and encourage pets to avoid the trap) */
if (otmp) {
otmp->blessed = 0;
otmp->cursed = 1;
otmp->owt = weight(otmp);
place_object(otmp, m.x, m.y);
}
/* 20% chance of placing an additional item, recursively */
} while (!rn2(5));
/* Place a corpse. */
switch (rn2(15)) {
case 0:
/* elf corpses are the rarest as they're the most useful */
victim_mnum = PM_ELF;
/* elven adventurers get sleep resistance early; so don't
generate elf corpses on sleeping gas traps unless a)
we're on dlvl 2 (1 is impossible) and b) we pass a coin
flip */
if (kind == SLP_GAS_TRAP && !(lvl <= 2 && rn2(2)))
victim_mnum = PM_HUMAN;
break;
case 1: case 2:
victim_mnum = PM_DWARF;
break;
case 3: case 4: case 5:
victim_mnum = PM_ORC;
break;
case 6: case 7: case 8: case 9:
/* more common as they could have come from the Mines */
victim_mnum = PM_GNOME;
/* 10% chance of a candle too */
if (!rn2(10)) {
otmp = mksobj(rn2(4) ? TALLOW_CANDLE : WAX_CANDLE,
TRUE, FALSE);
otmp->quan = 1;
otmp->blessed = 0;
otmp->cursed = 1;
otmp->owt = weight(otmp);
place_object(otmp, m.x, m.y);
}
break;
default:
/* the most common race */
victim_mnum = PM_HUMAN;
break;
}
otmp = mkcorpstat(CORPSE, NULL, &mons[victim_mnum], m.x, m.y,
CORPSTAT_INIT);
if (otmp)
otmp->age -= (TAINT_AGE + 1); /* died too long ago to eat */
mktrap_victim(t);
}
}