示例#1
0
/* Monster Fear */
bool fear_process_m(int m_idx)
{
    monster_type *m_ptr = &m_list[m_idx];
    if (MON_MONFEAR(m_ptr) && !MON_CSLEEP(m_ptr))
    {
        if (fear_save_m(m_ptr))
        {
            bool recovered = FALSE;
            if (fear_save_m(m_ptr))
            {
                set_monster_monfear(m_idx, 0);
                recovered = TRUE;
            }
            else
            {
            monster_race *r_ptr = &r_info[m_ptr->ap_r_idx];

                recovered = set_monster_monfear(m_idx,
                    MON_MONFEAR(m_ptr) - randint1(r_ptr->level / 20 + 1));
            }

            if (recovered && is_seen(m_ptr))
            {
                char m_name[80];
                char m_poss[80];

                monster_desc(m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
                monster_desc(m_name, m_ptr, 0);

                msg_format("%^s recovers %s courage.", m_name, m_poss);
            }
        }
        else if (one_in_(3) && !fear_save_m(m_ptr))
        {
            if (is_seen(m_ptr))
            {
                char m_name[80];
                monster_desc(m_name, m_ptr, 0);
                msg_format("%^s is scared stiff!", m_name);
            }
            return FALSE;
        }
    }
    return TRUE;
}
示例#2
0
static void _cyber_move_player(void)
{
    /* Cyberdemons move erratically (cf get_rep_dir()) and make a lot of noise */
    if (one_in_(66))
    {
        int i;

        cmsg_print(TERM_RED, "The dungeon trembles!");
        if (disturb_minor)
            disturb(0, 0);

        for (i = 1; i < m_max; i++)
        {
            monster_type *m_ptr = &m_list[i];

            if (!m_ptr->r_idx) continue;
            if (m_ptr->cdis < MAX_SIGHT * 2 && MON_CSLEEP(m_ptr))
                (void)set_monster_csleep(i, 0);
        }
    }
}
示例#3
0
/* Idea borrowed from Vanilla 3.5, but recoded from scratch ... */
void do_cmd_list_monsters(void)
{
    int         i, ct_types, ct_total = 0;
    int_map_ptr info = int_map_alloc(free);
    
    /* Collect */
    for (i = 0; i < max_m_idx; i++)
    {
        const monster_type *m_ptr = &m_list[i];
        _mon_list_info_ptr  info_ptr;
        
        if (!m_ptr->ap_r_idx) continue;
        if (!m_ptr->ml) continue;

        info_ptr = int_map_find(info, m_ptr->ap_r_idx);
        if (!info_ptr)
        {
            info_ptr = malloc(sizeof(_mon_list_info_t));
            info_ptr->r_idx = m_ptr->ap_r_idx;
            info_ptr->ct_total = 0;
            info_ptr->ct_awake = 0;
            info_ptr->ct_los = 0;
            
            int_map_add(info, m_ptr->ap_r_idx, info_ptr);
        }

        assert(info_ptr);
        info_ptr->ct_total++;
        ct_total++;

        if (!MON_CSLEEP(m_ptr)) info_ptr->ct_awake++;
        if (projectable(py, px, m_ptr->fy, m_ptr->fx)) info_ptr->ct_los++;
    }
    
    ct_types = int_map_count(info);
    if (ct_types)
    {
        int_map_iter_ptr  iter;
        int              *order;
        int               cx, cy, row = 1, col;

        /* Sort */
        C_MAKE(order, ct_types, int);

        i = 0;
        for (iter = int_map_iter_alloc(info); 
                int_map_iter_is_valid(iter); 
                int_map_iter_next(iter))
        {
            _mon_list_info_ptr info_ptr = int_map_iter_current(iter);
            order[i++] = info_ptr->r_idx;
        }
        int_map_iter_free(iter);

        ang_sort_comp = _compare_r_level;
        ang_sort_swap = _swap_int;
        ang_sort(order, NULL, ct_types);

        /* Display */
        Term_get_size(&cx, &cy);
        col = cx - 52;
        screen_save();
        c_prt(TERM_WHITE, format("You see %d monster%s", ct_total, ct_total != 1 ? "s" : ""), 0, col);
        for (i = 0; i < ct_types; i++)
        {
            int                 r_idx = order[i];
            const monster_race *r_ptr = &r_info[r_idx];
            byte                attr = TERM_WHITE;
            _mon_list_info_ptr  info_ptr = int_map_find(info, r_idx);
            char                buf[100];

            assert(info_ptr);

            Term_erase(col - 1, row, 53);

            if (row >= cy - 2) 
            {
                c_prt(TERM_YELLOW, "...", row++, col+2);
                break;
            }

            if (r_ptr->flags1 & RF1_UNIQUE)
                attr = TERM_VIOLET;
            else if (r_ptr->level > base_level)
                attr = TERM_RED;                
            else if (!info_ptr->ct_awake)
                attr = TERM_L_UMBER;

            if (info_ptr->ct_total == 1)
                sprintf(buf, "%s", r_name + r_ptr->name);
            else if (!info_ptr->ct_awake)
                sprintf(buf, "%s (%d sleeping)", r_name + r_ptr->name, info_ptr->ct_total);
            else if (info_ptr->ct_awake == info_ptr->ct_total)
                sprintf(buf, "%s (%d awake)", r_name + r_ptr->name, info_ptr->ct_total);
            else
                sprintf(buf, "%s (%d awake, %d sleeping)", r_name + r_ptr->name, 
                    info_ptr->ct_awake, info_ptr->ct_total - info_ptr->ct_awake);

            Term_queue_bigchar(col, row, r_ptr->x_attr, r_ptr->x_char, 0, 0);
            c_put_str(attr, format(" %-50.50s", buf), row++, col+1);
        }
        Term_erase(col - 1, row, 53);
        c_prt(TERM_YELLOW, "Hit any key.", row, col+2);
        inkey();
        prt("", 0, 0);

        screen_load();

        C_KILL(order, ct_types, int);
    }
    else
        msg_print("You see no visible monsters.");

    int_map_free(info);
}
示例#4
0
文件: save.c 项目: dis-/hengband
/*!
 * @brief モンスター情報を書き込む / Write a "monster" record
 * @param m_ptr モンスター情報保存元ポインタ
 * @return なし
 */
static void wr_monster(monster_type *m_ptr)
{
	u32b flags = 0x00000000;
	byte tmp8u;

	if (!is_original_ap(m_ptr)) flags |= SAVE_MON_AP_R_IDX;
	if (m_ptr->sub_align) flags |= SAVE_MON_SUB_ALIGN;
	if (MON_CSLEEP(m_ptr)) flags |= SAVE_MON_CSLEEP;
	if (MON_FAST(m_ptr)) flags |= SAVE_MON_FAST;
	if (MON_SLOW(m_ptr)) flags |= SAVE_MON_SLOW;
	if (MON_STUNNED(m_ptr)) flags |= SAVE_MON_STUNNED;
	if (MON_CONFUSED(m_ptr)) flags |= SAVE_MON_CONFUSED;
	if (MON_MONFEAR(m_ptr)) flags |= SAVE_MON_MONFEAR;
	if (m_ptr->target_y) flags |= SAVE_MON_TARGET_Y;
	if (m_ptr->target_x) flags |= SAVE_MON_TARGET_X;
	if (MON_INVULNER(m_ptr)) flags |= SAVE_MON_INVULNER;
	if (m_ptr->smart) flags |= SAVE_MON_SMART;
	if (m_ptr->exp) flags |= SAVE_MON_EXP;
	if (m_ptr->mflag2) flags |= SAVE_MON_MFLAG2;
	if (m_ptr->nickname) flags |= SAVE_MON_NICKNAME;
	if (m_ptr->parent_m_idx) flags |= SAVE_MON_PARENT;

	/*** Monster save flags ***/
	wr_u32b(flags);

	/*** Write only un-obvious elements ***/
	wr_s16b(m_ptr->r_idx);
	wr_byte(m_ptr->fy);
	wr_byte(m_ptr->fx);
	wr_s16b(m_ptr->hp);
	wr_s16b(m_ptr->maxhp);
	wr_s16b(m_ptr->max_maxhp);
	wr_u32b(m_ptr->dealt_damage);
	

	/* Monster race index of its appearance */
	if (flags & SAVE_MON_AP_R_IDX) wr_s16b(m_ptr->ap_r_idx);

	if (flags & SAVE_MON_SUB_ALIGN) wr_byte(m_ptr->sub_align);
	if (flags & SAVE_MON_CSLEEP) wr_s16b(m_ptr->mtimed[MTIMED_CSLEEP]);

	wr_byte(m_ptr->mspeed);
	wr_s16b(m_ptr->energy_need);

	if (flags & SAVE_MON_FAST)
	{
		tmp8u = (byte)m_ptr->mtimed[MTIMED_FAST];
		wr_byte(tmp8u);
	}
	if (flags & SAVE_MON_SLOW)
	{
		tmp8u = (byte)m_ptr->mtimed[MTIMED_SLOW];
		wr_byte(tmp8u);
	}
	if (flags & SAVE_MON_STUNNED)
	{
		tmp8u = (byte)m_ptr->mtimed[MTIMED_STUNNED];
		wr_byte(tmp8u);
	}
	if (flags & SAVE_MON_CONFUSED)
	{
		tmp8u = (byte)m_ptr->mtimed[MTIMED_CONFUSED];
		wr_byte(tmp8u);
	}
	if (flags & SAVE_MON_MONFEAR)
	{
		tmp8u = (byte)m_ptr->mtimed[MTIMED_MONFEAR];
		wr_byte(tmp8u);
	}
	if (flags & SAVE_MON_TARGET_Y) wr_s16b(m_ptr->target_y);
	if (flags & SAVE_MON_TARGET_X) wr_s16b(m_ptr->target_x);
	if (flags & SAVE_MON_INVULNER)
	{
		tmp8u = (byte)m_ptr->mtimed[MTIMED_INVULNER];
		wr_byte(tmp8u);
	}
	if (flags & SAVE_MON_SMART) wr_u32b(m_ptr->smart);
	if (flags & SAVE_MON_EXP) wr_u32b(m_ptr->exp);
	if (flags & SAVE_MON_MFLAG2) wr_byte(m_ptr->mflag2);
	if (flags & SAVE_MON_NICKNAME) wr_string(quark_str(m_ptr->nickname));
	if (flags & SAVE_MON_PARENT) wr_s16b(m_ptr->parent_m_idx);
}
示例#5
0
/*!
 * @brief フロア移動時のペット保存処理 / Preserve_pets
 * @return なし
 */
static void preserve_pet(void)
{
	int num;
	MONSTER_IDX i;

	for (num = 0; num < MAX_PARTY_MON; num++)
	{
		party_mon[num].r_idx = 0;
	}

	if (p_ptr->riding)
	{
		monster_type *m_ptr = &m_list[p_ptr->riding];

		/* Pet of other pet don't follow. */
		if (m_ptr->parent_m_idx)
		{
			p_ptr->riding = 0;
			p_ptr->pet_extra_flags &= ~(PF_RYOUTE);
			p_ptr->riding_ryoute = p_ptr->old_riding_ryoute = FALSE;
		}
		else
		{
			/* Preserve the mount */
			(void)COPY(&party_mon[0], m_ptr, monster_type);

			/* Delete from this floor */
			delete_monster_idx(p_ptr->riding);
		}
	}

	/*
	 * If player is in wild mode, no pets are preserved
	 * except a monster whom player riding
	 */
	if (!p_ptr->wild_mode && !p_ptr->inside_arena && !p_ptr->inside_battle)
	{
		for (i = m_max - 1, num = 1; (i >= 1 && num < MAX_PARTY_MON); i--)
		{
			monster_type *m_ptr = &m_list[i];

			if (!m_ptr->r_idx) continue;
			if (!is_pet(m_ptr)) continue;
			if (i == p_ptr->riding) continue;

			if (reinit_wilderness)
			{
				/* Don't lose sight of pets when getting a Quest */
			}
			else
			{
				int dis = distance(p_ptr->y, p_ptr->x, m_ptr->fy, m_ptr->fx);

				/* Confused (etc.) monsters don't follow. */
				if (MON_CONFUSED(m_ptr) || MON_STUNNED(m_ptr) || MON_CSLEEP(m_ptr)) continue;

				/* Pet of other pet don't follow. */
				if (m_ptr->parent_m_idx) continue;

				/*
				 * Pets with nickname will follow even from 3 blocks away
				 * when you or the pet can see the other.
				 */
				if (m_ptr->nickname && 
				    ((player_has_los_bold(m_ptr->fy, m_ptr->fx) && projectable(p_ptr->y, p_ptr->x, m_ptr->fy, m_ptr->fx)) ||
				     (los(m_ptr->fy, m_ptr->fx, p_ptr->y, p_ptr->x) && projectable(m_ptr->fy, m_ptr->fx, p_ptr->y, p_ptr->x))))
				{
					if (dis > 3) continue;
				}
				else
				{
					if (dis > 1) continue;
				}
			}

			(void)COPY(&party_mon[num], &m_list[i], monster_type);

			num++;

			/* Delete from this floor */
			delete_monster_idx(i);
		}
	}

	if (record_named_pet)
	{
		for (i = m_max - 1; i >=1; i--)
		{
			monster_type *m_ptr = &m_list[i];
			char m_name[80];

			if (!m_ptr->r_idx) continue;
			if (!is_pet(m_ptr)) continue;
			if (!m_ptr->nickname) continue;
			if (p_ptr->riding == i) continue;

			monster_desc(m_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
			do_cmd_write_nikki(NIKKI_NAMED_PET, RECORD_NAMED_PET_MOVED, m_name);
		}
	}


	/* Pet of other pet may disappear. */
	for (i = m_max - 1; i >=1; i--)
	{
		monster_type *m_ptr = &m_list[i];

		/* Are there its parent? */
		if (m_ptr->parent_m_idx && !m_list[m_ptr->parent_m_idx].r_idx)
		{
			/* Its parent have gone, it also goes away. */

			if (is_seen(m_ptr))
			{
				char m_name[80];

				/* Acquire the monster name */
				monster_desc(m_name, m_ptr, 0);

#ifdef JP
				msg_format("%sは消え去った!", m_name);
#else
				msg_format("%^s disappears!", m_name);
#endif
			}

			/* Delete the monster */
			delete_monster_idx(i);
		}
	}
}
示例#6
0
bool leprechaun_steal(int m_idx)
{
    bool result = FALSE;
    monster_type *m_ptr = &m_list[m_idx];
    monster_race *r_ptr = &r_info[m_ptr->r_idx];

    if ( !mon_save_p(m_ptr->r_idx, A_DEX) 
      || (MON_CSLEEP(m_ptr) && !mon_save_p(m_ptr->r_idx, A_DEX)))
    {
        object_type loot = {0};

        if (m_ptr->hold_o_idx && one_in_(2))
        {
            object_copy(&loot, &o_list[m_ptr->hold_o_idx]);
            delete_object_idx(m_ptr->hold_o_idx);
            loot.held_m_idx = 0;
        }
        else if (m_ptr->drop_ct > m_ptr->stolen_ct)
        {
            if (get_monster_drop(m_idx, &loot))
            {
                m_ptr->stolen_ct++;
                if (r_ptr->flags1 & RF1_UNIQUE)
                    r_ptr->stolen_ct++;
            }
        }

        if (!loot.k_idx)
        {
            msg_print("There is nothing to steal!");
        }
        else 
        {
            char o_name[MAX_NLEN];

            result = TRUE;
            object_desc(o_name, &loot, 0);
            if (mon_save_p(m_ptr->r_idx, A_DEX))
            {
                msg_format("Oops! You drop %s.", o_name);
                drop_near(&loot, -1, py, px);
            }
            else if (loot.tval == TV_GOLD)
            {
                msg_format("You steal %d gold pieces worth of %s.", (int)loot.pval, o_name);
                sound(SOUND_SELL);
                p_ptr->au += loot.pval;
                stats_on_gold_find(loot.pval);
                p_ptr->redraw |= (PR_GOLD);
                if (prace_is_(RACE_MON_LEPRECHAUN))
                    p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA);
            }
            else if (!inven_carry_okay(&loot))
            {
                msg_format("You have no room for %s.", o_name);
                drop_near(&loot, -1, py, px);
            }
            else
            {
                int slot = inven_carry(&loot);

                msg_format("You steal %s (%c).", o_name, index_to_label(slot));
                autopick_alter_item(slot, TRUE);
            }
        }
    }
    return result;
}