/** * Check if this (now dead) monster is a quest monster, and act appropriately */ bool quest_check(const struct monster *m) { int i, total = 0; /* Don't bother with non-questors */ if (!rf_has(m->race->flags, RF_QUESTOR)) return FALSE; /* Mark quests as complete */ for (i = 0; i < z_info->quest_max; i++) { /* Note completed quests */ if (player->quests[i].level == m->race->level) { player->quests[i].level = 0; player->quests[i].cur_num++; } /* Count incomplete quests */ if (player->quests[i].level) total++; } /* Build magical stairs */ build_quest_stairs(m->fy, m->fx); /* Nothing left, game over... */ if (total == 0) { player->total_winner = TRUE; player->upkeep->redraw |= (PR_TITLE); msg("*** CONGRATULATIONS ***"); msg("You have won the game!"); msg("You may retire (commit suicide) when you are ready."); } return TRUE; }
/** * Handles the "death" of a monster. * * Disperses treasures carried by the monster centered at the monster location. * Note that objects dropped may disappear in crowded rooms. * * Checks for "Quest" completion when a quest monster is killed. * * Note that only the player can induce "monster_death()" on Uniques. * Thus (for now) all Quest monsters should be Uniques. * * If `stats` is true, then we skip updating the monster memory. This is * used by stats-generation code, for efficiency. */ void monster_death(struct monster *m_ptr, bool stats) { int i; int dump_item = 0; int dump_gold = 0; int total = 0; s16b this_o_idx, next_o_idx = 0; object_type *i_ptr; object_type object_type_body; bool visible = (m_ptr->ml || rf_has(m_ptr->race->flags, RF_UNIQUE)); int y = m_ptr->fy; int x = m_ptr->fx; /* Delete any mimicked objects */ if (m_ptr->mimicked_o_idx > 0) delete_object_idx(m_ptr->mimicked_o_idx); /* 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 = object_byid(this_o_idx); /* Line up the next object */ next_o_idx = o_ptr->next_o_idx; /* Paranoia */ o_ptr->held_m_idx = 0; /* Get local object, copy it and delete the original */ i_ptr = &object_type_body; object_copy(i_ptr, o_ptr); delete_object_idx(this_o_idx); /* Count it and drop it - refactor once origin is a bitflag */ if (!stats) { if ((i_ptr->tval == TV_GOLD) && (i_ptr->origin != ORIGIN_STOLEN)) dump_gold++; else if ((i_ptr->tval != TV_GOLD) && ((i_ptr->origin == ORIGIN_DROP) || (i_ptr->origin == ORIGIN_DROP_PIT) || (i_ptr->origin == ORIGIN_DROP_VAULT) || (i_ptr->origin == ORIGIN_DROP_SUMMON) || (i_ptr->origin == ORIGIN_DROP_SPECIAL) || (i_ptr->origin == ORIGIN_DROP_BREED) || (i_ptr->origin == ORIGIN_DROP_POLY) || (i_ptr->origin == ORIGIN_DROP_WIZARD))) dump_item++; } /* Change origin if monster is invisible, unless we're in stats mode */ if (!visible && !stats) i_ptr->origin = ORIGIN_DROP_UNKNOWN; drop_near(cave, i_ptr, 0, y, x, TRUE); } /* Forget objects */ m_ptr->hold_o_idx = 0; /* Take note of any dropped treasure */ if (visible && (dump_item || dump_gold)) lore_treasure(m_ptr, dump_item, dump_gold); /* Update monster list window */ p_ptr->redraw |= PR_MONLIST; /* Nothing else to do for non-"Quest Monsters" */ if (!rf_has(m_ptr->race->flags, RF_QUESTOR)) return; /* Mark quests as complete */ for (i = 0; i < MAX_Q_IDX; i++) { /* Note completed quests */ if (q_list[i].level == m_ptr->race->level) q_list[i].level = 0; /* Count incomplete quests */ if (q_list[i].level) total++; } /* Build magical stairs */ build_quest_stairs(y, x); /* Nothing left, game over... */ if (total == 0) { p_ptr->total_winner = TRUE; p_ptr->redraw |= (PR_TITLE); msg("*** CONGRATULATIONS ***"); msg("You have won the game!"); msg("You may retire (commit suicide) when you are ready."); } }