Exemplo n.º 1
0
/*
 * 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)
Exemplo n.º 2
0
/*
 * 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;
	int total = 0;
	bool questlevel = FALSE;
	bool completed = FALSE;
	bool fixedquest = FALSE;
	bool writenote = TRUE;

	monster_type *m_ptr = &mon_list[m_idx];

	monster_race *r_ptr = &r_info[m_ptr->r_idx];

	/* Drop any objects the monster is carrying */
	if (m_ptr->hold_o_idx)
	{
		mon_drop_held_objects(m_ptr);
	}

	/* Mega-Hack -- drop "winner" treasures */
	if (r_ptr->flags1 & (RF1_DROP_CHOSEN))
	{
		mon_drop_chosen_objects(m_ptr);
	}

	/* Drop the monster's standard loot */
	mon_drop_loot(m_idx);

	/* 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!!!!!
		 */
		if (((who != SOURCE_PLAYER) && (who != SOURCE_TRAP)) || (!p_ptr->depth)) continue;

		/* Quest level? */
		if ((q_ptr->base_level == p_ptr->depth) && !is_quest_complete(i))
		{
			/* We are on a quest level */
			questlevel = TRUE;

			/* Mark fixed quests */
			if (quest_fixed(q_ptr)) fixedquest = TRUE;

			process_quest_monster_death(i, m_idx, &writenote);

			/* We just completed the quest */
			if (q_ptr->q_flags & (QFLAG_COMPLETED))
			{
				completed = TRUE;
			}
		}

		/* Count remaining permanent quests */
		if (quest_fixed(q_ptr))
		{
			if (!is_quest_complete(i)) total++;
		}
	}

	/* If the player kills a Unique, and the notes option is on, write a note.
	 * If the unique is a guild questor, the note was already written */
   	if ((r_ptr->flags1 & (RF1_UNIQUE)) && (adult_take_notes) && (writenote))
	{

		char note2[120];
 		char real_name[120];

		/*write note for player ghosts*/
		if (r_ptr->flags2 & (RF2_PLAYER_GHOST))
		{
			/*paranoia*/
			/* Check there is a name/ghost first */
			if (player_ghost_name[0] == '\0')
			{
				/*Make sure the name has been created*/
				prepare_ghost_name();
			}

			my_strcpy(note2, format("Destroyed %^s", player_ghost_name), sizeof (note2));
		}

		/*All other uniques*/
		else
		{
			/* Get the monster's real name for the notes file */
			monster_desc_race(real_name, sizeof(real_name), m_ptr->r_idx);

			/* Write note */
       		if monster_nonliving(r_ptr) my_strcpy(note2, format("Destroyed %s", real_name), sizeof (note2));
			else my_strcpy(note2, format("Killed %s", real_name), sizeof (note2));
		}
Exemplo n.º 3
0
//Helper function to get the complete monster name.
QString MakeMonsterDialog::get_mon_display_name(int r_idx)
{
    return (monster_desc_race(r_idx));
}