bool wiz_create_item_subaction(menu_type *m, const ui_event *e, int oid) { object_kind **choices = menu_priv(m); object_kind *kind = choices[oid]; object_type *i_ptr; object_type object_type_body; if (e->type != EVT_SELECT) return TRUE; /* Get local object */ i_ptr = &object_type_body; /* Create the item */ object_prep(i_ptr, kind, p_ptr->depth, RANDOMISE); /* Apply magic (no messages, no artifacts) */ apply_magic(i_ptr, p_ptr->depth, FALSE, FALSE, FALSE); /* Mark as cheat, and where created */ i_ptr->origin = ORIGIN_CHEAT; i_ptr->origin_depth = p_ptr->depth; if (kind->tval == TV_GOLD) make_gold(i_ptr, p_ptr->depth, kind->sval); /* Drop the object from heaven */ drop_near(cave, i_ptr, 0, p_ptr->py, p_ptr->px, TRUE); return FALSE; }
/* * Create lots of items. */ static void wiz_test_kind(int tval) { int py = p_ptr->py; int px = p_ptr->px; int sval; object_type object_type_body; object_type *i_ptr = &object_type_body; for (sval = 0; sval < 255; sval++) { object_kind *kind = lookup_kind(tval, sval); if (!kind) continue; /* Create the item */ object_prep(i_ptr, kind, p_ptr->depth, RANDOMISE); /* Apply magic (no messages, no artifacts) */ apply_magic(i_ptr, p_ptr->depth, FALSE, FALSE, FALSE); /* Mark as cheat, and where created */ i_ptr->origin = ORIGIN_CHEAT; i_ptr->origin_depth = p_ptr->depth; if (tval == TV_GOLD) make_gold(i_ptr, p_ptr->depth, sval); /* Drop the object from heaven */ drop_near(cave, i_ptr, 0, py, px, TRUE); } msg("Done."); }
/** * Allocate objects upon opening a chest * * Disperse treasures from the given chest, centered at (x,y). * * Small chests often contain "gold", while Large chests always contain * items. Wooden chests contain 2 items, Iron chests contain 4 items, * and Steel chests contain 6 items. The "value" of the items in a * chest is based on the level on which the chest is generated. * * Judgment of size and construction of chests is currently made from the name. */ static void chest_death(int y, int x, struct object *chest) { int number, value; bool tiny; struct object *treasure; /* Small chests often hold "gold" */ tiny = strstr(chest->kind->name, "Small") ? TRUE : FALSE; /* Determine how much to drop (see above) */ if (strstr(chest->kind->name, "wooden")) number = 2; else if (strstr(chest->kind->name, "iron")) number = 4; else if (strstr(chest->kind->name, "steel")) number = 6; else number = 2 * (randint1(3)); /* Zero pval means empty chest */ if (!chest->pval) number = 0; /* Determine the "value" of the items */ value = chest->origin_depth - 10 + 2 * chest->sval; if (value < 1) value = 1; /* Drop some objects (non-chests) */ for (; number > 0; --number) { /* Small chests often drop gold */ if (tiny && (randint0(100) < 75)) treasure = make_gold(value, "any"); /* Otherwise drop an item, as long as it isn't a chest */ else { treasure = make_object(cave, value, FALSE, FALSE, FALSE, NULL, 0); if (!treasure) continue; if (tval_is_chest(treasure)) { mem_free(treasure); continue; } } /* Record origin */ treasure->origin = ORIGIN_CHEST; treasure->origin_depth = chest->origin_depth; /* Drop it in the dungeon */ drop_near(cave, treasure, 0, y, x, TRUE); } /* Empty */ chest->pval = 0; /* Known */ object_notice_everything(chest); }
/** * Creates the onbject a mimic is imitating. */ void mon_create_mimicked_object(struct chunk *c, struct monster *mon, int index) { struct object *obj; struct object_kind *kind = mon->race->mimic_kinds->kind; struct monster_mimic *mimic_kind; int i = 1; bool dummy = true; /* Pick a random object kind to mimic */ for (mimic_kind = mon->race->mimic_kinds; mimic_kind; mimic_kind = mimic_kind->next, i++) { if (one_in_(i)) { kind = mimic_kind->kind; } } if (tval_is_money_k(kind)) { obj = make_gold(player->depth, kind->name); } else { obj = object_new(); object_prep(obj, kind, mon->race->level, RANDOMISE); apply_magic(obj, mon->race->level, true, false, false, false); obj->number = 1; obj->origin = ORIGIN_DROP_MIMIC; obj->origin_depth = player->depth; } obj->mimicking_m_idx = index; mon->mimicked_obj = obj; /* Put the object on the floor if it goes, otherwise no mimicry */ if (floor_carry(c, mon->fy, mon->fx, obj, &dummy)) { list_object(c, obj); } else { /* Clear the mimicry */ obj->mimicking_m_idx = 0; mon->mimicked_obj = NULL; /* Give the object to the monster if appropriate */ if (rf_has(mon->race->flags, RF_MIMIC_INV)) { monster_carry(c, mon, obj); } else { /* Otherwise delete the mimicked object */ object_delete(&obj); } } }
/** * Place a random amount of gold at (x, y). * \param c current chunk * \param y * \param x co-ordinates * \param level generation depth * \param origin item origin */ void place_gold(struct chunk *c, int y, int x, int level, byte origin) { struct object *money = NULL; assert(square_in_bounds(c, y, x)); if (!square_canputitem(c, y, x)) return; money = make_gold(level, "any"); money->origin = origin; money->origin_depth = level; if (!floor_carry(c, y, x, money, FALSE)) object_delete(&money); }
/** * Place a random amount of gold at (x, y). * \param c current chunk * \param y co-ordinates * \param x co-ordinates * \param level generation depth * \param origin item origin */ void place_gold(struct chunk *c, int y, int x, int level, byte origin) { struct object *money = NULL; bool dummy = true; if (!square_in_bounds(c, y, x)) return; if (!square_canputitem(c, y, x)) return; money = make_gold(level, "any"); money->origin = origin; money->origin_depth = level; if (!floor_carry(c, y, x, money, &dummy)) { object_delete(&money); } else { list_object(c, money); } }
/* * Places a treasure (Gold or Gems) at given location * * The location must be a legal, clean, floor grid. */ void place_gold(s32b y, s32b x) { object_type *q_ptr; /* Paranoia -- check bounds */ if (!in_bounds(y, x)) return; /* Require clean floor space */ if (!cave_clean_bold(y, x)) return; /* Get local object */ q_ptr = new_object(); /* Make some gold */ if (!make_gold(q_ptr)) return; if (!floor_carry(y, x, q_ptr)) delete_object(q_ptr); }
/* * Helper function for monster_death - * Drop the monster's normal objects */ static void mon_drop_loot(int m_idx) { monster_type *m_ptr = &mon_list[m_idx]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; int j; bool chest = (r_ptr->flags1 & (RF1_DROP_CHEST)) ? TRUE : FALSE; bool good = (r_ptr->flags1 & (RF1_DROP_GOOD)) ? TRUE : FALSE; bool great = (r_ptr->flags1 & (RF1_DROP_GREAT)) ? TRUE : FALSE; bool do_gold = (!(r_ptr->flags1 & (RF1_ONLY_ITEM))); bool do_item = (!(r_ptr->flags1 & (RF1_ONLY_GOLD))); bool visible = (m_ptr->ml || (r_ptr->flags1 & (RF1_UNIQUE))); int force_coin = get_coin_type(r_ptr); int dump_item = 0; int dump_gold = 0; int number_drops = 0; object_type *i_ptr; object_type object_type_body; /* Average dungeon and monster levels */ s16b set_object_level = object_level = (effective_depth(p_ptr->depth) + r_ptr->level) / 2; /* Determine how much we can drop */ if ((r_ptr->flags1 & (RF1_DROP_60)) && (rand_int(100) < 60)) number_drops++; if ((r_ptr->flags1 & (RF1_DROP_90)) && (rand_int(100) < 90)) number_drops++; if (r_ptr->flags1 & (RF1_DROP_1D2)) number_drops += damroll(1, 2); if (r_ptr->flags1 & (RF1_DROP_2D2)) number_drops += damroll(2, 2); if (r_ptr->flags1 & (RF1_DROP_3D2)) number_drops += damroll(3, 2); if (r_ptr->flags1 & (RF1_DROP_4D2)) number_drops += damroll(4, 2); /* Hack -- handle creeping coins */ coin_type = force_coin; /* Drop some objects */ for (j = 0; j < number_drops; j++) { bool interesting = FALSE; /* Re-set the object level */ object_level = set_object_level; /* Get local object */ i_ptr = &object_type_body; /* Wipe the object */ object_wipe(i_ptr); /* work on the "too much junk" problem, large drops sometimes are less items with a "boost". */ if ((randint(750) < (number_drops * number_drops)) && (!(r_ptr->flags1 & (RF1_UNIQUE)))) { interesting = TRUE; number_drops -= 5; object_level += 5; /*Boundry Control*/ if (number_drops < 0) number_drops = 0; if (object_level > MAX_DEPTH) object_level = MAX_DEPTH; } /* Make Gold */ if (do_gold && (!chest) && (!do_item || (rand_int(100) < 50))) { /* Make some gold */ if (!make_gold(i_ptr)) continue; /* Assume seen XXX XXX XXX */ dump_gold++; } /* Make Object */ else { if (chest) { if (!make_object(i_ptr, good, great, DROP_TYPE_CHEST, FALSE)) continue; } /* Make an object */ else if (!make_object(i_ptr, good, great, DROP_TYPE_UNTHEMED, interesting)) continue; /* Remember history */ if (visible) object_history(i_ptr, ORIGIN_DROP_KNOWN, m_ptr->r_idx); else object_history(i_ptr, ORIGIN_DROP_UNKNOWN, 0); /* Assume seen XXX XXX XXX */ dump_item++; } /* Drop it in the dungeon */ drop_near(i_ptr, -1, m_ptr->fy, m_ptr->fx); } /* Re-set the object level */ object_level = set_object_level; /*If marked for a bonus item, create it and drop it */ if (m_ptr->mflag & (MFLAG_BONUS_ITEM)) { bool this_good = good; bool this_great = great; bool this_chest = chest; bool interesting = FALSE; char o_name[80]; /* Get local object */ i_ptr = &object_type_body; /* Wipe the object */ object_wipe(i_ptr); if (one_in_(50)) this_chest = TRUE; if (one_in_(15)) this_great = TRUE; if (one_in_(5)) this_good = TRUE; if ((!this_good) && (!this_great) && (!this_chest)) { object_level += 5; if (object_level > MAX_DEPTH) object_level = MAX_DEPTH; interesting = TRUE; } if (this_chest) { while (!make_object(i_ptr, TRUE, TRUE, DROP_TYPE_CHEST, FALSE)) continue; } /* Make an object */ else while (!make_object(i_ptr, this_good, this_good, DROP_TYPE_UNTHEMED, interesting)) continue; /* Remember history */ if (visible) object_history(i_ptr, ORIGIN_DROP_KNOWN, m_ptr->r_idx); else object_history(i_ptr, ORIGIN_DROP_UNKNOWN, 0); object_desc(o_name, sizeof(o_name), i_ptr, ODESC_PREFIX | ODESC_FULL); /* Drop it in the dungeon */ drop_near(i_ptr, -1, m_ptr->fy, m_ptr->fx); } /* Reset the object level */ object_level = effective_depth(p_ptr->depth); /* Reset "coin" type */ coin_type = 0; /* Take note of any dropped treasure */ if (visible && (dump_item || dump_gold)) { /* Take notes on treasure */ lore_treasure(m_idx, dump_item, dump_gold); } }
/* * Allocate objects upon opening a chest * * Disperse treasures from the given chest, centered at (x,y). * * Small chests often contain "gold", while Large chests always contain * items. Wooden chests contain 2 items, Iron chests contain 4 items, * and Steel chests contain 6 items. The "value" of the items in a * chest is based on the level on which the chest is generated. */ static void chest_death(int y, int x, s16b o_idx) { int number, value; bool tiny; object_type *o_ptr; object_type *i_ptr; object_type object_type_body; /* Get the chest */ o_ptr = object_byid(o_idx); /* Small chests often hold "gold" */ tiny = (o_ptr->sval < SV_CHEST_MIN_LARGE); /* Determine how much to drop (see above) */ number = (o_ptr->sval % SV_CHEST_MIN_LARGE) * 2; /* Zero pval means empty chest */ if (!o_ptr->pval[DEFAULT_PVAL]) number = 0; /* Determine the "value" of the items */ value = o_ptr->origin_depth - 10 + 2 * o_ptr->sval; if (value < 1) value = 1; /* Drop some objects (non-chests) */ for (; number > 0; --number) { /* Get local object */ i_ptr = &object_type_body; /* Wipe the object */ object_wipe(i_ptr); /* Small chests often drop gold */ if (tiny && (randint0(100) < 75)) make_gold(i_ptr, value, SV_GOLD_ANY); /* Otherwise drop an item, as long as it isn't a chest */ else { if (!make_object(cave, i_ptr, value, FALSE, FALSE, NULL)) continue; if (i_ptr->tval == TV_CHEST) continue; } /* Record origin */ i_ptr->origin = ORIGIN_CHEST; i_ptr->origin_depth = o_ptr->origin_depth; /* Drop it in the dungeon */ drop_near(cave, i_ptr, 0, y, x, TRUE); } /* Empty */ o_ptr->pval[DEFAULT_PVAL] = 0; /* Known */ object_notice_everything(o_ptr); }
/** * Creates a specific monster's drop, including any drops specified * in the monster.txt file. * * Returns true if anything is created, false if nothing is. */ static bool mon_create_drop(struct chunk *c, struct monster *mon, byte origin) { struct monster_drop *drop; bool great, good, gold_ok, item_ok; bool extra_roll = false; bool any = false; int number = 0, level, j, monlevel; struct object *obj; assert(mon); great = (rf_has(mon->race->flags, RF_DROP_GREAT)); good = great || (rf_has(mon->race->flags, RF_DROP_GOOD)); gold_ok = (!rf_has(mon->race->flags, RF_ONLY_ITEM)); item_ok = (!rf_has(mon->race->flags, RF_ONLY_GOLD)); /* Determine how much we can drop */ number = mon_create_drop_count(mon->race, false); /* Give added bonus for unique monters */ monlevel = mon->race->level; if (rf_has(mon->race->flags, RF_UNIQUE)) { monlevel = MIN(monlevel + 15, monlevel * 2); extra_roll = true; } /* Take the best of (average of monster level and current depth) and (monster level) - to reward fighting OOD monsters */ level = MAX((monlevel + player->depth) / 2, monlevel); level = MIN(level, 100); /* Morgoth currently drops all artifacts with the QUEST_ART flag */ if (rf_has(mon->race->flags, RF_QUESTOR) && (mon->race->level == 100)) { /* Search all the artifacts */ for (j = 1; j < z_info->a_max; j++) { struct artifact *art = &a_info[j]; struct object_kind *kind = lookup_kind(art->tval, art->sval); if (!kf_has(kind->kind_flags, KF_QUEST_ART)) { continue; } /* Allocate by hand, prep, apply magic */ obj = mem_zalloc(sizeof(*obj)); object_prep(obj, kind, 100, RANDOMISE); obj->artifact = art; copy_artifact_data(obj, obj->artifact); obj->artifact->created = true; /* Set origin details */ obj->origin = origin; obj->origin_depth = player->depth; obj->origin_race = mon->race; obj->number = 1; /* Try to carry */ if (monster_carry(c, mon, obj)) { any = true; } else { obj->artifact->created = false; object_wipe(obj); mem_free(obj); } } } /* Specified drops */ for (drop = mon->race->drops; drop; drop = drop->next) { if ((unsigned int)randint0(100) >= drop->percent_chance) continue; /* Allocate by hand, prep, apply magic */ obj = mem_zalloc(sizeof(*obj)); object_prep(obj, drop->kind, level, RANDOMISE); apply_magic(obj, level, true, good, great, extra_roll); /* Set origin details */ obj->origin = origin; obj->origin_depth = player->depth; obj->origin_race = mon->race; obj->number = randint0(drop->max - drop->min) + drop->min; /* Try to carry */ if (monster_carry(c, mon, obj)) { any = true; } else { object_wipe(obj); mem_free(obj); } } /* Make some objects */ for (j = 0; j < number; j++) { if (gold_ok && (!item_ok || (randint0(100) < 50))) { obj = make_gold(level, "any"); } else { obj = make_object(c, level, good, great, extra_roll, NULL, 0); if (!obj) continue; } /* Set origin details */ obj->origin = origin; obj->origin_depth = player->depth; obj->origin_race = mon->race; /* Try to carry */ if (monster_carry(c, mon, obj)) { any = true; } else { obj->artifact->created = false; object_wipe(obj); mem_free(obj); } } return any; }
/** * Attempts to place a copy of the given monster at the given position in * the dungeon. * * All of the monster placement routines eventually call this function. This * is what actually puts the monster in the dungeon (i.e., it notifies the cave * and sets the monsters position). The dungeon loading code also calls this * function directly. * * `origin` is the item origin to use for any monster drops (e.g. ORIGIN_DROP, * ORIGIN_DROP_PIT, etc.) The dungeon loading code calls this with origin = 0, * which prevents the monster's drops from being generated again. * * Returns the m_idx of the newly copied monster, or 0 if the placement fails. */ s16b place_monster(int y, int x, monster_type *mon, byte origin) { s16b m_idx; monster_type *m_ptr; assert(cave_in_bounds(cave, y, x)); assert(!cave_monster_at(cave, y, x)); /* Get a new record */ m_idx = mon_pop(); if (!m_idx) return 0; /* Copy the monster */ m_ptr = cave_monster(cave, m_idx); COPY(m_ptr, mon, monster_type); /* Set the ID */ m_ptr->midx = m_idx; /* Set the location */ cave->m_idx[y][x] = m_ptr->midx; m_ptr->fy = y; m_ptr->fx = x; assert(cave_monster_at(cave, y, x) == m_ptr); update_mon(m_ptr, TRUE); /* Hack -- Count the number of "reproducers" */ if (rf_has(m_ptr->race->flags, RF_MULTIPLY)) num_repro++; /* Count racial occurrences */ m_ptr->race->cur_num++; /* Create the monster's drop, if any */ if (origin) (void)mon_create_drop(m_ptr, origin); /* Make mimics start mimicking */ if (origin && m_ptr->race->mimic_kinds) { object_type *i_ptr; object_type object_type_body; object_kind *kind = m_ptr->race->mimic_kinds->kind; struct monster_mimic *mimic_kind; int i = 1; /* Pick a random object kind to mimic */ for (mimic_kind = m_ptr->race->mimic_kinds; mimic_kind; mimic_kind = mimic_kind->next, i++) { if (one_in_(i)) kind = mimic_kind->kind; } i_ptr = &object_type_body; if (kind->tval == TV_GOLD) { make_gold(i_ptr, p_ptr->depth, kind->sval); } else { object_prep(i_ptr, kind, m_ptr->race->level, RANDOMISE); apply_magic(i_ptr, m_ptr->race->level, TRUE, FALSE, FALSE, FALSE); i_ptr->number = 1; } i_ptr->origin = origin; i_ptr->mimicking_m_idx = m_idx; m_ptr->mimicked_o_idx = floor_carry(cave, y, x, i_ptr); } /* Result */ return m_idx; }
/** * Creates a specific monster's drop, including any drops specified * in the monster.txt file. * * Returns TRUE if anything is created, FALSE if nothing is. */ static bool mon_create_drop(struct monster *m_ptr, byte origin) { struct monster_drop *drop; bool great, good, gold_ok, item_ok; bool extra_roll = FALSE; bool any = FALSE; int number = 0, level, j, monlevel; object_type *i_ptr; object_type object_type_body; assert(m_ptr); great = (rf_has(m_ptr->race->flags, RF_DROP_GREAT)); good = great || (rf_has(m_ptr->race->flags, RF_DROP_GOOD)); gold_ok = (!rf_has(m_ptr->race->flags, RF_ONLY_ITEM)); item_ok = (!rf_has(m_ptr->race->flags, RF_ONLY_GOLD)); /* Determine how much we can drop */ if (rf_has(m_ptr->race->flags, RF_DROP_20) && randint0(100) < 20) number++; if (rf_has(m_ptr->race->flags, RF_DROP_40) && randint0(100) < 40) number++; if (rf_has(m_ptr->race->flags, RF_DROP_60) && randint0(100) < 60) number++; if (rf_has(m_ptr->race->flags, RF_DROP_4)) number += rand_range(2, 6); if (rf_has(m_ptr->race->flags, RF_DROP_3)) number += rand_range(2, 4); if (rf_has(m_ptr->race->flags, RF_DROP_2)) number += rand_range(1, 3); if (rf_has(m_ptr->race->flags, RF_DROP_1)) number++; /* Give added bonus for unique monters */ monlevel = m_ptr->race->level; if (rf_has(m_ptr->race->flags, RF_UNIQUE)){ monlevel = MIN(monlevel + 15, monlevel * 2); extra_roll = TRUE; } /* Take the best of (average of monster level and current depth) and (monster level) - to reward fighting OOD monsters */ level = MAX((monlevel + p_ptr->depth) / 2, monlevel); level = MIN(level, 100); /* Specified drops */ for (drop = m_ptr->race->drops; drop; drop = drop->next) { if ((unsigned int)randint0(100) >= drop->percent_chance) continue; i_ptr = &object_type_body; if (drop->artifact) { object_prep(i_ptr, objkind_get(drop->artifact->tval, drop->artifact->sval), level, RANDOMISE); i_ptr->artifact = drop->artifact; copy_artifact_data(i_ptr, i_ptr->artifact); i_ptr->artifact->created = 1; } else { object_prep(i_ptr, drop->kind, level, RANDOMISE); apply_magic(i_ptr, level, TRUE, good, great, extra_roll); } i_ptr->origin = origin; i_ptr->origin_depth = p_ptr->depth; i_ptr->origin_xtra = m_ptr->race->ridx; i_ptr->number = randint0(drop->max - drop->min) + drop->min; if (monster_carry(m_ptr, i_ptr)) any = TRUE; } /* Make some objects */ for (j = 0; j < number; j++) { i_ptr = &object_type_body; object_wipe(i_ptr); if (gold_ok && (!item_ok || (randint0(100) < 50))) { make_gold(i_ptr, level, SV_GOLD_ANY); } else { if (!make_object(cave, i_ptr, level, good, great, extra_roll, NULL, 0)) continue; } i_ptr->origin = origin; i_ptr->origin_depth = p_ptr->depth; i_ptr->origin_xtra = m_ptr->race->ridx; if (monster_carry(m_ptr, i_ptr)) any = TRUE; } return any; }
/** * Attempts to place a copy of the given monster at the given position in * the dungeon. * * All of the monster placement routines eventually call this function. This * is what actually puts the monster in the dungeon (i.e., it notifies the cave * and sets the monsters position). The dungeon loading code also calls this * function directly. * * `origin` is the item origin to use for any monster drops (e.g. ORIGIN_DROP, * ORIGIN_DROP_PIT, etc.) The dungeon loading code calls this with origin = 0, * which prevents the monster's drops from being generated again. * * Returns the m_idx of the newly copied monster, or 0 if the placement fails. */ s16b place_monster(struct chunk *c, int y, int x, struct monster *mon, byte origin) { s16b m_idx; struct monster *new_mon; assert(square_in_bounds(c, y, x)); assert(!square_monster(c, y, x)); /* Get a new record */ m_idx = mon_pop(c); if (!m_idx) return 0; /* Copy the monster */ new_mon = cave_monster(c, m_idx); memcpy(new_mon, mon, sizeof(struct monster)); /* Set the ID */ new_mon->midx = m_idx; /* Set the location */ c->squares[y][x].mon = new_mon->midx; new_mon->fy = y; new_mon->fx = x; assert(square_monster(c, y, x) == new_mon); update_mon(new_mon, c, true); /* Hack -- Count the number of "reproducers" */ if (rf_has(new_mon->race->flags, RF_MULTIPLY)) num_repro++; /* Count racial occurrences */ new_mon->race->cur_num++; /* Create the monster's drop, if any */ if (origin) (void)mon_create_drop(c, new_mon, origin); /* Make mimics start mimicking */ if (origin && new_mon->race->mimic_kinds) { struct object *obj; struct object_kind *kind = new_mon->race->mimic_kinds->kind; struct monster_mimic *mimic_kind; int i = 1; /* Pick a random object kind to mimic */ for (mimic_kind = new_mon->race->mimic_kinds; mimic_kind; mimic_kind = mimic_kind->next, i++) { if (one_in_(i)) kind = mimic_kind->kind; } if (tval_is_money_k(kind)) { obj = make_gold(player->depth, kind->name); } else { obj = object_new(); object_prep(obj, kind, new_mon->race->level, RANDOMISE); apply_magic(obj, new_mon->race->level, true, false, false, false); obj->number = 1; obj->origin = ORIGIN_DROP_MIMIC; obj->origin_depth = player->depth; } obj->mimicking_m_idx = m_idx; new_mon->mimicked_obj = obj; /* Put the object on the floor if it goes, otherwise no mimicry */ if (floor_carry(c, y, x, obj, false)) { list_object(c, obj); } else { /* Clear the mimicry */ obj->mimicking_m_idx = 0; new_mon->mimicked_obj = NULL; /* Give the object to the monster if appropriate */ if (rf_has(new_mon->race->flags, RF_MIMIC_INV)) { monster_carry(c, new_mon, obj); } else { /* Otherwise delete the mimicked object */ object_delete(&obj); } } } /* Result */ return m_idx; }
/* * Handle the "death" of a monster. * * Disperse treasures centered at the monster location based on the * various flags contained in the monster flags fields. * * Check for "Quest" completion when a quest monster is killed. * * Note that only the player can induce "monster_death()" on Uniques or quest monsters. * * Note that monsters can now carry objects, and when a monster dies, * it drops all of its objects, which may disappear in crowded rooms. */ void monster_death(int m_idx, int who) { int i, j, y, x; int dump_item = 0; int dump_gold = 0; int number_drops = 0; int total = 0; bool questlevel = FALSE; bool completed = FALSE; bool fixedquest = FALSE; bool writenote = TRUE; bool need_stairs = FALSE; s16b set_object_level; s16b this_o_idx, next_o_idx = 0; monster_type *m_ptr = &mon_list[m_idx]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; bool visible = (m_ptr->ml || (r_ptr->flags1 & (RF1_UNIQUE))); bool chest = (r_ptr->flags1 & (RF1_DROP_CHEST)) ? TRUE : FALSE; bool good = (r_ptr->flags1 & (RF1_DROP_GOOD)) ? TRUE : FALSE; bool great = (r_ptr->flags1 & (RF1_DROP_GREAT)) ? TRUE : FALSE; bool do_gold = (!(r_ptr->flags1 & (RF1_ONLY_ITEM))); bool do_item = (!(r_ptr->flags1 & (RF1_ONLY_GOLD))); int force_coin = get_coin_type(r_ptr); object_type *i_ptr; object_type object_type_body; /* Get the location */ y = m_ptr->fy; x = m_ptr->fx; /* Drop objects being carried */ for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) { object_type *o_ptr; /* Get the object */ o_ptr = &o_list[this_o_idx]; /*Remove the mark to hide when monsters carry this object*/ o_ptr->ident &= ~(IDENT_HIDE_CARRY); /* Get the next object */ next_o_idx = o_ptr->next_o_idx; /* Paranoia */ o_ptr->held_m_idx = 0; /* Get local object */ i_ptr = &object_type_body; /* Copy the object */ object_copy(i_ptr, o_ptr); /* Delete the object */ delete_object_idx(this_o_idx); /* Drop it */ drop_near(i_ptr, -1, y, x); } /* Forget objects */ m_ptr->hold_o_idx = 0; /* Mega-Hack -- drop "winner" treasures */ if (r_ptr->flags1 & (RF1_DROP_CHOSEN)) { /* Get local object */ i_ptr = &object_type_body; /* Mega-Hack -- Prepare to make "Grond" */ object_prep(i_ptr, lookup_kind(TV_HAFTED, SV_GROND)); /* Mega-Hack -- Mark this item as "Grond" */ i_ptr->art_num = ART_GROND; /* Mega-Hack -- Actually create "Grond" */ apply_magic(i_ptr, -1, TRUE, TRUE, TRUE, FALSE); /* Remember history */ object_history(i_ptr, ORIGIN_MORGOTH, 0); /* Drop it in the dungeon */ drop_near(i_ptr, -1, y, x); /* Get local object */ i_ptr = &object_type_body; /* Mega-Hack -- Prepare to make "Morgoth's crown" */ object_prep(i_ptr, lookup_kind(TV_CROWN, SV_MORGOTH)); /* Mega-Hack -- Mark this item as "Morgoth" */ i_ptr->art_num = ART_MORGOTH; /* Mega-Hack -- Actually create "Morgoth" */ apply_magic(i_ptr, -1, TRUE, TRUE, TRUE, FALSE); /* Remember history */ object_history(i_ptr, ORIGIN_MORGOTH, 0); /* Drop it in the dungeon */ drop_near(i_ptr, -1, y, x); } /* Determine how much we can drop */ if ((r_ptr->flags1 & (RF1_DROP_60)) && (rand_int(100) < 60)) number_drops++; if ((r_ptr->flags1 & (RF1_DROP_90)) && (rand_int(100) < 90)) number_drops++; if (r_ptr->flags1 & (RF1_DROP_1D2)) number_drops += damroll(1, 2); if (r_ptr->flags1 & (RF1_DROP_2D2)) number_drops += damroll(2, 2); if (r_ptr->flags1 & (RF1_DROP_3D2)) number_drops += damroll(3, 2); if (r_ptr->flags1 & (RF1_DROP_4D2)) number_drops += damroll(4, 2); /* Hack -- handle creeping coins */ coin_type = force_coin; /* Average dungeon and monster levels */ set_object_level = object_level = (effective_depth(p_ptr->depth) + r_ptr->level) / 2; /* Drop some objects */ for (j = 0; j < number_drops; j++) { bool interesting = FALSE; /* Re-set the object level */ object_level = set_object_level; /* Get local object */ i_ptr = &object_type_body; /* Wipe the object */ object_wipe(i_ptr); /* work on the "too much junk" problem, large drops sometimes are less items with a "boost". */ if ((randint(750) < (number_drops * number_drops)) && (!(r_ptr->flags1 & (RF1_UNIQUE)))) { interesting = TRUE; number_drops -= 5; object_level += 5; /*Boundry Control*/ if (number_drops < 0) number_drops = 0; if (object_level > MAX_DEPTH) object_level = MAX_DEPTH; } /* Make Gold */ if (do_gold && (!chest) && (!do_item || (rand_int(100) < 70))) { /* Make some gold */ if (!make_gold(i_ptr)) continue; /* Assume seen XXX XXX XXX */ dump_gold++; } /* Make Object */ else { if (chest) { if (!make_object(i_ptr, good, great, DROP_TYPE_CHEST, FALSE)) continue; } /* Make an object */ else if (!make_object(i_ptr, good, great, DROP_TYPE_UNTHEMED, interesting)) continue; /* Remember history */ if (visible) object_history(i_ptr, ORIGIN_DROP_KNOWN, m_ptr->r_idx); else object_history(i_ptr, ORIGIN_DROP_UNKNOWN, 0); /* Assume seen XXX XXX XXX */ dump_item++; } /* Drop it in the dungeon */ drop_near(i_ptr, -1, y, x); } /* Re-set the object level */ object_level = set_object_level; /*If marked for a bonus item, create it and drop it */ if (m_ptr->mflag & (MFLAG_BONUS_ITEM)) { bool this_good = good; bool this_great = great; bool this_chest = chest; bool interesting = FALSE; char o_name[80]; /* Get local object */ i_ptr = &object_type_body; /* Wipe the object */ object_wipe(i_ptr); if (one_in_(50)) this_chest = TRUE; if (one_in_(15)) this_great = TRUE; if (one_in_(5)) this_good = TRUE; if ((!this_good) && (!this_great) && (!this_chest)) { object_level += 5; if (object_level > MAX_DEPTH) object_level = MAX_DEPTH; interesting = TRUE; } if (this_chest) { while (!make_object(i_ptr, TRUE, TRUE, DROP_TYPE_CHEST, FALSE)) continue; } /* Make an object */ else while (!make_object(i_ptr, this_good, this_good, DROP_TYPE_UNTHEMED, interesting)) continue; /* Remember history */ if (visible) object_history(i_ptr, ORIGIN_DROP_KNOWN, m_ptr->r_idx); else object_history(i_ptr, ORIGIN_DROP_UNKNOWN, 0); object_desc(o_name, sizeof(o_name), i_ptr, ODESC_PREFIX | ODESC_FULL); /* Drop it in the dungeon */ drop_near(i_ptr, -1, y, x); } /* Reset the object level */ object_level = effective_depth(p_ptr->depth); /* Reset "coin" type */ coin_type = 0; /* Take note of any dropped treasure */ if (visible && (dump_item || dump_gold)) { /* Take notes on treasure */ lore_treasure(m_idx, dump_item, dump_gold); } /* Update monster list window */ p_ptr->redraw |= (PR_MONLIST); /* Count incomplete quests */ for (i = 0; i < z_info->q_max; i++) { quest_type *q_ptr = &q_info[i]; /* * Hack - don't count if player didn't kill, or on a town level * This assumes only a player can kill quest monsters!!!!! * This line is also ugly coding. :) */ if (((who != SOURCE_PLAYER) && (who != SOURCE_TRAP)) || (!p_ptr->depth)) continue; /* Quest level? */ if ((q_ptr->active_level == p_ptr->depth) && (p_ptr->depth > 0)) { /* One on the level */ questlevel = TRUE; /* Require "Quest Monsters" */ if (q_ptr->mon_idx == m_ptr->r_idx) { char race_name[80]; /* Get the monster race name (singular)*/ monster_desc_race(race_name, sizeof(race_name), q_ptr->mon_idx); /* Mark kills */ q_ptr->cur_num++; /* Redraw quest indicator */ p_ptr->redraw |= (PR_QUEST_ST); /* Completed quest? */ if (q_ptr->cur_num == q_ptr->max_num) { /* Mark complete */ q_ptr->active_level = 0; /* Mark fixed quests */ if ((q_ptr->q_type == QUEST_FIXED) || (q_ptr->q_type == QUEST_FIXED_U)) fixedquest = TRUE; if (q_ptr->q_type == QUEST_GUARDIAN) need_stairs = TRUE; /* One complete */ completed = TRUE; /*make a note of the completed quest, but not for fixed or * fixed unique quests */ if ((adult_take_notes) && (!fixedquest)) { char note[120]; /* Multiple quest monsters */ if (q_ptr->max_num > 1) { plural_aux(race_name, sizeof(race_name)); } if (r_ptr->flags1 & (RF1_UNIQUE)) { /*write note*/ if monster_nonliving(r_ptr) sprintf(note, "Quest: Destroyed %s", race_name); else sprintf(note, "Quest: Killed %s", race_name); } else { /* Write note */ if monster_nonliving(r_ptr)