diff --git a/src/mklev.c b/src/mklev.c index 99a9f90d0..02eda196d 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -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); } }