bool CAI_Stalker::bfAssignWatch(CScriptEntityAction *tpEntityAction)
{
	if (!inherited::bfAssignWatch(tpEntityAction))
		return		(false);
	
	CScriptWatchAction	&l_tWatchAction = tpEntityAction->m_tWatchAction;

//	float			&yaw = movement().m_head.target.yaw, &pitch = movement().m_head.target.pitch;

	switch (l_tWatchAction.m_tGoalType) {
		case CScriptWatchAction::eGoalTypeObject : {
			if (!xr_strlen(l_tWatchAction.m_bone_to_watch))
				l_tWatchAction.m_tpObjectToWatch->Center(l_tWatchAction.m_tWatchVector);
			else {
				CBoneInstance	&l_tBoneInstance = smart_cast<IKinematics*>(l_tWatchAction.m_tpObjectToWatch->Visual())->LL_GetBoneInstance(smart_cast<IKinematics*>(l_tWatchAction.m_tpObjectToWatch->Visual())->LL_BoneID(l_tWatchAction.m_bone_to_watch));
				Fmatrix			l_tMatrix;

				l_tMatrix			= l_tBoneInstance.mTransform;
				l_tMatrix.mulA_43	(l_tWatchAction.m_tpObjectToWatch->XFORM());

				l_tWatchAction.m_tWatchVector	= l_tMatrix.c;
			}
			sight().setup(l_tWatchAction.m_tWatchType,&l_tWatchAction.m_tWatchVector);
			break;
		}
		case CScriptWatchAction::eGoalTypeDirection : {
			sight().setup(l_tWatchAction.m_tWatchType,&l_tWatchAction.m_tWatchVector);
			break;
		}
		case CScriptWatchAction::eGoalTypeWatchType : {
			break;
		}
		case CScriptWatchAction::eGoalTypeCurrent : {
			l_tWatchAction.m_tWatchType	= SightManager::eSightTypeCurrentDirection;
			l_tWatchAction.m_bCompleted = true;
			return						(false);
		}
		default : NODEFAULT;
	}

	if ((CScriptWatchAction::eGoalTypeWatchType != l_tWatchAction.m_tGoalType) && (angle_difference(movement().m_head.target.yaw,movement().m_head.current.yaw) < EPS_L) && (angle_difference(movement().m_head.target.pitch,movement().m_head.current.pitch) < EPS_L))
		l_tWatchAction.m_bCompleted = true;
	else
		l_tWatchAction.m_bCompleted = false;
	
	return		(!l_tWatchAction.m_bCompleted);
}
Exemple #2
0
/**
 * Clears shroud (and fog) around the provided location for @a view_team
 * based on @a sight_range, @a costs, and @a slowed.
 * This will also record sighted events, which should be either fired or
 * explicitly dropped. (The sighter is the unit with underlying id @a viewer_id.)
 *
 * This should only be called if delayed shroud updates is off.
 * It is wasteful to call this if view_team uses neither fog nor shroud.
 *
 * @param real_loc         The actual location of the viewing unit.
 *                         (This is used to avoid having a unit sight itself.)
 * @param known_units      These locations are not checked for uncovered units.
 * @param enemy_count      Incremented for each enemy uncovered (excluding known_units).
 * @param friend_count     Incremented for each friend uncovered (excluding known_units).
 * @param spectator        Will be told of uncovered units (excluding known_units).
 * @param instant          If false, then drawing delays (used to make movement look better) are allowed.
 *
 * @return whether or not information was uncovered (i.e. returns true if any
 *         locations in visual range were fogged/shrouded under shared vision/maps).
 */
bool shroud_clearer::clear_unit(const map_location &view_loc, team &view_team,
                                std::size_t viewer_id, int sight_range, bool slowed,
                                const movetype::terrain_costs & costs,
                                const map_location & real_loc,
                                const std::set<map_location>* known_units,
                                std::size_t * enemy_count, std::size_t * friend_count,
                                move_unit_spectator * spectator, bool instant)
{
	// Give animations a chance to progress; see bug #20324.
	if ( !instant  && display::get_singleton() )
		display::get_singleton()->draw(true);

	bool cleared_something = false;
	// Dummy variables to make some logic simpler.
	std::size_t enemies=0, friends=0;
	if ( enemy_count == nullptr )
		enemy_count = &enemies;
	if ( friend_count == nullptr )
		friend_count = &friends;

	// Make sure the jamming map is up-to-date.
	if ( view_team_ != &view_team ) {
		calculate_jamming(&view_team);
		// Give animations a chance to progress; see bug #20324.
		if ( !instant  && display::get_singleton() )
			display::get_singleton()->draw(true);
	}

	// Determine the hexes to clear.
	pathfind::vision_path sight(costs, slowed, sight_range, view_loc, jamming_);
	// Give animations a chance to progress; see bug #20324.
	if ( !instant  && display::get_singleton() )
		display::get_singleton()->draw(true);

	// Clear the fog.
	for (const pathfind::paths::step &dest : sight.destinations) {
		bool known = known_units  &&  known_units->count(dest.curr) != 0;
		if ( clear_loc(view_team, dest.curr, view_loc, real_loc, viewer_id, !known,
		               *enemy_count, *friend_count, spectator) )
			cleared_something = true;
	}
	//TODO guard with game_config option
	for (const map_location &dest : sight.edges) {
		bool known = known_units  &&  known_units->count(dest) != 0;
		if ( clear_loc(view_team, dest, view_loc, real_loc, viewer_id, !known,
		               *enemy_count, *friend_count, spectator) )
			cleared_something = true;
	}

	return cleared_something;
}
bool CAI_Stalker::bfAssignMovement(CScriptEntityAction *tpEntityAction)
{
	if (!inherited::bfAssignMovement(tpEntityAction))
		return						(false);
	
	CScriptMovementAction			&l_tMovementAction	= tpEntityAction->m_tMovementAction;
	CScriptWatchAction				&l_tWatchAction		= tpEntityAction->m_tWatchAction;
	CScriptAnimationAction			&l_tAnimationAction	= tpEntityAction->m_tAnimationAction;
	CScriptObjectAction				&l_tObjectAction	= tpEntityAction->m_tObjectAction;

	CObjectHandler::set_goal		(l_tObjectAction.m_tGoalType);
	
	movement().set_path_type		(movement().path_type());
	movement().set_detail_path_type	(l_tMovementAction.m_tPathType);
	movement().set_body_state		(l_tMovementAction.m_tBodyState);
	movement().set_movement_type	(l_tMovementAction.m_tMovementType);
	movement().set_mental_state		(l_tAnimationAction.m_tMentalState);
	sight().setup					(l_tWatchAction.m_tWatchType,&l_tWatchAction.m_tWatchVector);
	movement().update				(Device.dwTimeDelta);
	sight().update					();

	return							(true);
}
Exemple #4
0
/**
 * Determines if @a loc is within @a viewer's visual range.
 * This is a moderately expensive function (vision is recalculated
 * with each call), so avoid using it heavily.
 * If @a jamming is left as nullptr, the jamming map is also calculated
 * with each invocation.
 */
static bool can_see(const unit & viewer, const map_location & loc,
                    const std::map<map_location, int> * jamming = nullptr)
{
	// Make sure we have a "jamming" map.
	std::map<map_location, int> local_jamming;
	if ( jamming == nullptr ) {
		create_jamming_map(local_jamming, resources::gameboard->get_team(viewer.side()));
		jamming = &local_jamming;
	}

	// Determine which hexes this unit can see.
	pathfind::vision_path sight(viewer, viewer.get_location(), *jamming);

	return sight.destinations.contains(loc)  ||  sight.edges.count(loc) != 0;
}
Exemple #5
0
void CAI_Stalker::Exec_Look			(float dt)
{
	sight().Exec_Look				(dt);
}
Exemple #6
0
/*
 * quaff:
 *	Let the hero drink a potion
 */
int quaff()
{
	struct object *obj;
	struct linked_list *item, *titem;
	struct thing *th;
	int wh;
	char buf[LINLEN];
	bool bless, curse;

	/*
	 * Make certain that it is somethings that we want to drink
	 */
	if ((item = get_item("quaff", POTION)) == NULL)
		return 0;
	obj = OBJPTR(item);
	if (obj->o_type != POTION) {
		msg("That's undrinkable!");
		after = FALSE;
		return 0;
	}
	wh = obj->o_which;
	bless = o_on(obj, ISBLESS);
	curse = o_on(obj, ISCURSED);
	del_pack(item);		/* get rid of it */

	/*
	 * Calculate the effect it has on the poor guy.
	 */
	switch(wh) {
	case P_CONFUSE:
		if (!bless) {
			if (pl_on(ISINVINC))
				msg("You remain level-headed.");
			else {
				chg_abil(WIS,-1,TRUE);		/* confuse his mind */
				if (pl_off(ISHUH)) {
					msg("Wait, what's going on here. Huh? What? Who?");
					if (pl_on(ISHUH))
						lengthen(unconfuse,rnd(8)+HUHDURATION);
					else
						fuse(unconfuse,TRUE,rnd(8)+HUHDURATION);
					player.t_flags |= ISHUH;
				}
			}
			p_know[P_CONFUSE] = TRUE;
		}
	when P_POISON:
		if (!bless) {
			if (pl_off(ISINVINC) && !iswearing(R_SUSTSTR) &&
			  !iswearing(R_SUSAB)) {
				chg_abil(CON,-1,TRUE);		
				chg_abil(STR,-(rnd(3)+1),TRUE);
				msg("You feel very sick now.");
			}
			else
				msg("You feel momentarily sick.");
			p_know[P_POISON] = TRUE;
		}
	when P_HEALING:
		if (!curse) {
			heal_self(4, TRUE);
			msg("You begin to feel better.");
			if (!iswearing(R_SLOW))
				notslow(FALSE);
			sight(FALSE);
			p_know[P_HEALING] = TRUE;
		}
	when P_STRENGTH:
		if (!curse) {
			msg("You feel stronger, now.  What bulging muscles!");
			chg_abil(STR,1,TRUE);
			p_know[P_STRENGTH] = TRUE;
		}
	when P_MFIND:
		/*
		 * Potion of monster detection - find all monsters
		 */
		if (mlist != NULL && !curse) {
			dispmons();
			mpos = 0;
			msg("You begin to sense the presence of monsters--More--");
			p_know[P_MFIND] = TRUE;
			wait_for(cw,' ');
			msg("");		/* clear line */
		}
		else
			msg("You have a strange feeling for a moment, then it passes.");
	when P_TFIND:
		/*
		 * Potion of magic detection.  Show the potions and scrolls
		 */
		if (lvl_obj != NULL && !curse) {
			struct linked_list *mobj;
			struct object *tp;
			bool show;

			show = FALSE;
			wclear(hw);
			for (mobj = lvl_obj; mobj != NULL; mobj = next(mobj)) {
				tp = OBJPTR(mobj);
				if (is_magic(tp)) {
					show = TRUE;
					mvwaddch(hw, tp->o_pos.y, tp->o_pos.x, MAGIC);
				}
			}
			for(titem = mlist; titem != NULL; titem = next(titem)) {
				struct linked_list *pitem;

				th = THINGPTR(titem);
				for(pitem=th->t_pack;pitem!=NULL;pitem=next(pitem)) {
					if (is_magic(ldata(pitem))) {
						show = TRUE;
						mvwaddch(hw,th->t_pos.y, th->t_pos.x, MAGIC);
					}
				}
			}
			if (show) {
				msg("You begin to sense the presence of magic.");
				overlay(hw,cw);
				p_know[P_TFIND] = TRUE;
				break;
			}
		}
		msg("You have a strange feeling for a moment, then it passes.");
	when P_PARALYZE:
		if (!bless) {
			if (pl_on(ISINVINC))
				msg("You feel numb for a moment.");
			else {
				msg("You can't move.");
				player.t_nocmd = HOLDTIME;
			}
			p_know[P_PARALYZE] = TRUE;
		}
	when P_SEEINVIS:
		if (!curse) {
			int invlen = roll(40,20);

			msg("This potion tastes like %s juice.", fruit);
			if (pl_off(CANSEE)) {
				player.t_flags |= CANSEE;
				fuse(unsee, TRUE, invlen);
				light(&hero);
			}
			else
				lengthen(unsee, invlen);
			sight(FALSE);
		}
	when P_RAISE:
		if (!curse) {
			msg("You suddenly feel much more skillful.");
			p_know[P_RAISE] = TRUE;
			chg_abil(DEX,1,TRUE);
			chg_abil(WIS,1,TRUE);
			chg_abil(CON,1,TRUE);
			raise_level();
		}
	when P_XHEAL:
		if (!curse) {
			heal_self(8, TRUE);
			if (rnd(100) < 50)
				chg_abil(CON,1,TRUE);
			msg("You begin to feel much better.");
			p_know[P_XHEAL] = TRUE;
			if (!iswearing(R_SLOW))
				notslow(FALSE);
			unconfuse();
			extinguish(unconfuse);
			sight(FALSE);
		}
	when P_HASTE:
		if (!curse) {
			add_haste(TRUE);
			msg("You feel yourself moving much faster.");
			p_know[P_HASTE] = TRUE;
		}
	when P_INVINC:
		if (!curse) {
			int time = rnd(400) + 350;

			msg("You feel invincible.");
			if (player.t_flags & ISINVINC)
				lengthen(notinvinc,time);
			else
				fuse(notinvinc,TRUE,time);
			player.t_flags |= ISINVINC;
			p_know[P_INVINC] = TRUE;
		}
	when P_SMART:
		if (!curse) {
			msg("You feel more perceptive.");
			p_know[P_SMART] = TRUE;
			chg_abil(WIS,1,TRUE);
		}
	when P_RESTORE:
		if (!curse) {
			msg("Hey, this tastes great. You feel warm all over.");
			him->s_re = max_stats.s_re;
			him->s_ef = max_stats.s_re;
			ringabil();				/* add in rings */
			updpack();				/* update weight */
			p_know[P_RESTORE] = TRUE;
			extinguish(rchg_str);	/* kill restore in from ulodyte */
		}
	when P_BLIND:
		if (!bless) {
			if (pl_on(ISINVINC))
				msg("The light dims for a moment.");
			else {
				chg_abil(WIS,-1,TRUE);
				msg("A cloak of darkness falls around you.");
				if (pl_off(ISBLIND)) {
					player.t_flags |= ISBLIND;
					fuse(sight, TRUE, rnd(400) + 450);
					light(&hero);
				}
			}
			p_know[P_BLIND] = TRUE;
		}
	when P_ETH:
		if (!curse) {
			int ethlen = roll(40,20);

			msg("You feel more vaporous.");
			if (pl_on(ISETHER))
				lengthen(noteth,ethlen);
			else
				fuse(noteth,TRUE,ethlen);
			player.t_flags |= ISETHER;
			p_know[P_ETH] = TRUE;
		}
	when P_NOP:
		msg("This potion tastes extremely dull.");
	when P_DEX:
		if (!curse) {
			chg_abil(DEX,1,TRUE);		/* increase dexterity */
			p_know[P_DEX] = TRUE;
			msg("You feel much more agile.");
		}
	when P_REGEN:
		if (!curse) {
			int reglen = rnd(450) + 450;

			if (pl_on(ISREGEN))
				lengthen(notregen, reglen);
			else
				fuse(notregen, TRUE, reglen);
			player.t_flags |= ISREGEN;
			msg("You feel yourself improved.");
			p_know[P_REGEN] = TRUE;
		}
	when P_DECREP:
	case P_SUPHERO: {
		int howmuch = rnd(3) + 1;

		if (wh == P_DECREP) {
			if (!bless) {
				if (iswearing(R_SUSAB) || pl_on(ISINVINC)) {
					msg("You feel momentarily woozy.");
					howmuch = 0;
				}
				else {
					msg("You feel crippled.");
					howmuch = -howmuch;
					if (!iswearing(R_SUSTSTR))
						chg_abil(STR,howmuch,TRUE);
				}
			}
			else
				howmuch = 0;
		}
		else {			/* potion of superhero */
			if (curse)
				howmuch = 0;
			msg("You feel invigorated.");
			chg_abil(STR,howmuch,TRUE);
		}
		chg_abil(CON,howmuch,TRUE);
		chg_abil(DEX,howmuch,TRUE);
		chg_abil(WIS,howmuch,TRUE);		/* change abilities */
		p_know[wh] = TRUE;
	}
	otherwise:
		msg("What an odd tasting potion!");
		return 0;
	}
	nochange = FALSE;
	if (p_know[wh] && p_guess[wh]) {
		free(p_guess[wh]);
		p_guess[wh] = NULL;
	}
	else if(!p_know[wh] && p_guess[wh] == NULL) {
		strcpy(buf, p_colors[wh]);
		msg(callit);
		if (get_str(buf, cw) == NORM) {
			p_guess[wh] = new(strlen(buf) + 1);
			strcpy(p_guess[wh], buf);
		}
void
ring_on(void)
{
    struct object   *obj;
    struct linked_list  *item;
    int ring;
    char buf[2 * LINELEN];

    if ((item = get_item("put on", RING)) == NULL)
        return;

    obj = OBJPTR(item);

    if (obj->o_type != RING)
    {
        msg("You can't put that on!");
        return;
    }

    /* find out which hand to put it on */

    if (is_current(obj))
    {
        msg("Already wearing that!");
        return;
    }

    if (cur_ring[LEFT_1] == NULL)
        ring = LEFT_1;
    else if (cur_ring[LEFT_2] == NULL)
        ring = LEFT_2;
    else if (cur_ring[LEFT_3] == NULL)
        ring = LEFT_3;
    else if (cur_ring[LEFT_4] == NULL)
        ring = LEFT_4;
    else if (cur_ring[LEFT_5] == NULL)
        ring = LEFT_5;
    else if (cur_ring[RIGHT_1] == NULL)
        ring = RIGHT_1;
    else if (cur_ring[RIGHT_2] == NULL)
        ring = RIGHT_2;
    else if (cur_ring[RIGHT_3] == NULL)
        ring = RIGHT_3;
    else if (cur_ring[RIGHT_4] == NULL)
        ring = RIGHT_4;
    else if (cur_ring[RIGHT_5] == NULL)
        ring = RIGHT_5;
    else
    {
        msg("You already have on ten rings.");
        return;
    }

    cur_ring[ring] = obj;

    /* Calculate the effect it has on the poor guy. */

    switch (obj->o_which)
    {
        case R_ADDSTR:
            pstats.s_str += obj->o_ac;
            break;
        case R_ADDHIT:
            pstats.s_dext += obj->o_ac;
            break;
        case R_ADDINTEL:
            pstats.s_intel += obj->o_ac;
            break;
        case R_ADDWISDOM:
            pstats.s_wisdom += obj->o_ac;
            break;
        case R_FREEDOM:
            turn_off(player, ISHELD);
            hold_count = 0;
            break;
        case R_TRUESEE:
            if (off(player, PERMBLIND))
            {
                turn_on(player, CANTRUESEE);
                msg("You become more aware of your surroundings.");
                sight(NULL);
                light(&hero);
                mvwaddch(cw, hero.y, hero.x, PLAYER);
            }
            break;

        case R_SEEINVIS:
            if (off(player, PERMBLIND))
            {
                turn_on(player, CANTRUESEE);
                msg("Your eyes begin to tingle.");
                sight(NULL);
                light(&hero);
                mvwaddch(cw, hero.y, hero.x, PLAYER);
            }
            break;

        case R_AGGR:
            aggravate();
            break;

        case R_CARRYING:
            updpack();
            break;

        case R_LEVITATION:
            msg("You begin to float in the air!");
            break;

        case R_LIGHT:
            if (roomin(hero) != NULL)
            {
                light(&hero);
                mvwaddch(cw, hero.y, hero.x, PLAYER);
            }
    }

    status(FALSE);

    if (know_items[TYP_RING][obj->o_which] &&
        guess_items[TYP_RING][obj->o_which])
    {
        mem_free(guess_items[TYP_RING][obj->o_which]);
        guess_items[TYP_RING][obj->o_which] = NULL;
    }
    else if (!know_items[TYP_RING][obj->o_which] &&
         askme &&
         (obj->o_flags & ISKNOW) == 0 &&
         guess_items[TYP_RING][obj->o_which] == NULL)
    {
        mpos = 0;
        msg("What do you want to call it? ");

        if (get_string(buf, cw) == NORM)
        {
            guess_items[TYP_RING][obj->o_which] =
                new_alloc(strlen(buf) + 1);
            strcpy(guess_items[TYP_RING][obj->o_which], buf);
        }
        msg("");
    }
}
Exemple #8
0
void
quaff()
{
    THING *obj, *tp, *mp;
    bool discardit = FALSE;
    bool show, trip;

    obj = get_item("quaff", POTION);
    /*
     * Make certain that it is somethings that we want to drink
     */
    if (obj == NULL)
	return;
    if (obj->o_type != POTION)
    {
	if (!terse)
	    msg("yuk! Why would you want to drink that?");
	else
	    msg("that's undrinkable");
	return;
    }
    if (obj == cur_weapon)
	cur_weapon = NULL;

    /*
     * Calculate the effect it has on the poor guy.
     */
    trip = on(player, ISHALU);
    discardit = (bool)(obj->o_count == 1);
    leave_pack(obj, FALSE, FALSE);
    switch (obj->o_which)
    {
	case P_CONFUSE:
	    do_pot(P_CONFUSE, !trip);
	when P_POISON:
	    pot_info[P_POISON].oi_know = TRUE;
	    if (ISWEARING(R_SUSTSTR))
		msg("you feel momentarily sick");
	    else
	    {
		chg_str(-(rnd(3) + 1));
		msg("you feel very sick now");
		come_down();
	    }
	when P_HEALING:
	    pot_info[P_HEALING].oi_know = TRUE;
	    if ((pstats.s_hpt += roll(pstats.s_lvl, 4)) > max_hp)
		pstats.s_hpt = ++max_hp;
	    sight();
	    msg("you begin to feel better");
	when P_STRENGTH:
	    pot_info[P_STRENGTH].oi_know = TRUE;
	    chg_str(1);
	    msg("you feel stronger, now.  What bulging muscles!");
	when P_MFIND:
	    player.t_flags |= SEEMONST;
	    fuse((void(*)())turn_see, TRUE, HUHDURATION, AFTER);
	    if (!turn_see(FALSE))
		msg("you have a %s feeling for a moment, then it passes",
		    choose_str("normal", "strange"));
	when P_TFIND:
	    /*
	     * Potion of magic detection.  Show the potions and scrolls
	     */
	    show = FALSE;
	    if (lvl_obj != NULL)
	    {
		wclear(hw);
		for (tp = lvl_obj; tp != NULL; tp = next(tp))
		{
		    if (is_magic(tp))
		    {
			show = TRUE;
			wmove(hw, tp->o_pos.y, tp->o_pos.x);
			waddch(hw, MAGIC);
			pot_info[P_TFIND].oi_know = TRUE;
		    }
		}
		for (mp = mlist; mp != NULL; mp = next(mp))
		{
		    for (tp = mp->t_pack; tp != NULL; tp = next(tp))
		    {
			if (is_magic(tp))
			{
			    show = TRUE;
			    wmove(hw, mp->t_pos.y, mp->t_pos.x);
			    waddch(hw, MAGIC);
			}
		    }
		}
	    }
	    if (show)
	    {
		pot_info[P_TFIND].oi_know = TRUE;
		show_win("You sense the presence of magic on this level.--More--");
	    }
	    else
		msg("you have a %s feeling for a moment, then it passes",
		    choose_str("normal", "strange"));
	when P_LSD:
	    if (!trip)
	    {
		if (on(player, SEEMONST))
		    turn_see(FALSE);
		start_daemon(visuals, 0, BEFORE);
		seenstairs = seen_stairs();
	    }
	    do_pot(P_LSD, TRUE);
	when P_SEEINVIS:
	    sprintf(prbuf, "this potion tastes like %s juice", fruit);
	    show = on(player, CANSEE);
	    do_pot(P_SEEINVIS, FALSE);
	    if (!show)
		invis_on();
	    sight();
	when P_RAISE:
	    pot_info[P_RAISE].oi_know = TRUE;
	    msg("you suddenly feel much more skillful");
	    raise_level();
	when P_XHEAL:
	    pot_info[P_XHEAL].oi_know = TRUE;
	    if ((pstats.s_hpt += roll(pstats.s_lvl, 8)) > max_hp)
	    {
		if (pstats.s_hpt > max_hp + pstats.s_lvl + 1)
		    ++max_hp;
		pstats.s_hpt = ++max_hp;
	    }
	    sight();
	    come_down();
	    msg("you begin to feel much better");
	when P_HASTE:
	    pot_info[P_HASTE].oi_know = TRUE;
	    after = FALSE;
	    if (add_haste(TRUE))
		msg("you feel yourself moving much faster");
	when P_RESTORE:
	    if (ISRING(LEFT, R_ADDSTR))
		add_str(&pstats.s_str, -cur_ring[LEFT]->o_arm);
	    if (ISRING(RIGHT, R_ADDSTR))
		add_str(&pstats.s_str, -cur_ring[RIGHT]->o_arm);
	    if (pstats.s_str < max_stats.s_str)
		pstats.s_str = max_stats.s_str;
	    if (ISRING(LEFT, R_ADDSTR))
		add_str(&pstats.s_str, cur_ring[LEFT]->o_arm);
	    if (ISRING(RIGHT, R_ADDSTR))
		add_str(&pstats.s_str, cur_ring[RIGHT]->o_arm);
	    msg("hey, this tastes great.  It make you feel warm all over");
	when P_BLIND:
	    do_pot(P_BLIND, TRUE);
	when P_LEVIT:
	    do_pot(P_LEVIT, TRUE);
#ifdef MASTER
	otherwise:
	    msg("what an odd tasting potion!");
	    return;
#endif
    }
    status();
    /*
     * Throw the item away
     */

    call_it(&pot_info[obj->o_which]);

    if (discardit)
	discard(obj);
    return;
}
Exemple #9
0
/***************************************************  Main  ***********************************************/
int main(int argc, char** argv)
{

	
	if(argc<=1){
		//cout << "Input image was not loaded, please verify: " << argv[1] << endl;
		showInstructions();
		return -1;
	}
	
	int c = atoi(argv[1]);
	cv::Mat templ, ori, result;
	string img1_file, img2_file , inpoints1, inpoints2,outpoints1,outpoints2,input3dtriangles, result_image;
	
	switch ( c ) {
	case 0: 
		break;
	case 1: {
		if(argc<5){
			cout << "Application usage is not correct, please refer to usage" << endl;
			showInstructions();
			return -1;
		}
 		
 		
 		img1_file = argv[2];
 		img2_file = argv[3];
 		outpoints1 = argv[4];
 		outpoints2 = argv[5];
 		//Read image files
 		ori = imread(img1_file,1);
 		templ = imread(img2_file,1);
 		testTriangleWrite(ori,templ,1,0.5,outpoints1,outpoints2);
 		
 		cout << "Load Points successfully written in files: " << outpoints1 << " and " << outpoints2 << endl;
 		return 1;
 		
 		}
	case 2:
	{
	
		if(argc<8){
			cout << "Application usage is not correct, please refer to usage" << endl;
			showInstructions();
			return -1;
		}
		img1_file = argv[2];
 		img2_file = argv[3];
 		input3dtriangles = argv[4];
 		inpoints1 = argv[5];
 		inpoints2 = argv[6];
 		int img_number = atoi(argv[7]);
 		result_image = argv[8];
 		
 		//Read image files
 		ori = imread(img1_file,1);
 		templ = imread(img2_file,1);
 		
 		//Test reading and interpolating image
 		result = testTriangleRead(ori, templ, 1, 0.5, input3dtriangles, inpoints1,inpoints2, img_number, result_image );
		
		//Save image
		//imwrite(result_image,result);
		cout<< "Load image interpolated and saved in file: " << result_image << endl;
		return 1;
	}
	
	case 3:
	{
		if(argc<4){
			cout << "Application usage is not correct, please refer to usage" << endl;
			showInstructions();
			return -1;
		}
		img1_file = argv[2];
		input3dtriangles = argv[3];
		result_image = argv[4];
		
		//Read image files
 		ori = imread(img1_file,1);
 		
 		result = testMultipleTrianglePerspective(ori,input3dtriangles);
 		
 		imwrite(result_image,result);
 		cout << "Load 3 successfully reconstructed image from input triangles" << endl;
 		return 1;
	}
	
	case 4: 
	{
	
		if(argc<5){
			cout << "Application usage is not correct, please refer to usage" << endl;
			showInstructions();
			return -1;
		}
		img1_file = argv[2];
 		img2_file = argv[3];
 		int nb_inter = atoi(argv[4]);
 		string folder = argv[5];
 		
 		//Read image files
 		ori = imread(img1_file,1);
 		templ = imread(img2_file,1);
 		
 		multipleInterpolateTest(ori,templ,nb_inter,folder);
 		return 1;
	
	}
	
	case 5: 
	{
	
		if(argc<3){
			cout << "Application usage is not correct, please refer to usage" << endl;
			showInstructions();
			return -1;
		}
		img1_file = argv[2];
 		string folder = argv[3];
 		
 		//Read image files
 		ori = imread(img1_file,1);
 		
 		if(!ori.data){
 			cout << "Please choose correct image. Error loading image file" << endl;
 			return -1;
 		}
 		getCubeFacesTest(ori,folder);
 		return 1;
	
	}
 	 
	default:
	  showInstructions();
 	  return -1;
	}
	

	//setupImageAndClouds(name,)
	/********************************* Define parameters ***************************************/
	//Define the constants that we will be using. 
	// - radius is the desired radius of the sphere
	// - phi0 and phi1 represent min and max values of angle phi [0,2PI]
	// - theta0 and theta1 represent min and max values of angle theta [0,PI]
	// alpha the rotation angel between successive images


	//Math variables, point coordinates and angles
	double theta,phi,x,y,z;

	//b,g,r color values of input image
	float b,g,r;

	//empty color vector
	cv::Vec3f color(0.0,0.0,0.0);
	cv::Vec3b colorOri;


	//Pcl point cloud for sphere
	PointCloud<PointXYZRGB>::Ptr cloud (new PointCloud<PointXYZRGB>);
	PointCloud<PointXYZRGB>::Ptr sight (new PointCloud<PointXYZRGB>);
	PointCloud<PointXYZRGB>::Ptr sightFlat (new PointCloud<PointXYZRGB>);
	PointXYZRGB iPoint;
	PointXYZRGB vPoint;
	PointXYZRGB u;
	PointXYZRGB v;

	//Sphere Centers are all defined in the XY plane because we do not rotate outside that plane
	double xc,zc;
	double yc = 0;



	//Setup 3D visualizer
	//visualization::PCLVisualizer viewer("3D viewer");
	//	visualization::CloudViewer cViewer ("Simple Cloud Viewer");
	//	//viewer.setBackgroundColor (0, 0, 0);



	//String names for line
	ostringstream line;

	// Vectors for mats and pointClouds
	vector<cv::Mat> allImages(nb_images);
	vector<PointCloud<PointXYZRGB>::Ptr> allPtClouds(nb_images);
	vector<PointCloud<PointXYZRGB>::Ptr> CTBPtClouds(3);
	vector<PointCloud<PointXYZRGB>::Ptr> allVtClouds(nb_images);

	// cv::Mat for original and spherical image
	//cv::Mat ori,top,bottom;

	//Number of lines to draw
	int nbLines = 1000000;
	int lnCount = 0;
	/*********************************************** end Define parameters *************************************************/


	//Loading images
	//cv::Mat ori1, ori2, ori3;



	//Load first image to get size and data
	//int im_num = 0;
	//loadImagei(name,im_num+1,ori);

	//Verify image has content
	//if(!ori.data){
	//	cout << "Input image was not loaded, please verify: " << argv[1] << im_num + 1 <<".jpg" << endl;
	//	return -1;
	//}


	//allImages[im_num] = ori;
	//sphereCenter(alpha, im_num, dist_c, xc, zc);
	//cout << "xc: "<< xc << endl;
	//cloud = EquiToSphere(ori, radius,xc,yc,zc);


	//allPtClouds[im_num] = cloud;
	//im_num++;
	//recover cv::Mat props
	//cv::Size s = ori.size();
	//int rows = s.height;
	//int cols = s.width;
	//cvResizeWindow("Original",rows,cols);
	//cvNamedWindow("Keypoints 2D",0);
	//imshow("Original",ori);
	//cvNamedWindow("Original",0);
	//cvNamedWindow("SightMat",0);

	//For testing
	//cv::Mat sph = cv::Mat::zeros(rows, cols, CV_8UC3);
	//end for testing

	//loadImagei(name,3,ori2);
	//loadImagei(name,4,ori3);


	/**************************************************** End of Initiate ************************************************/	

	//For testing in order not to load all images every time
	//int tempCount =atoi(argv[2]);
	//cout << "Images to be loaded: " << tempCount<< endl;

	//for(int k=im_num; k<tempCount; k++){
		//cout << "k: " << k << endl;
		//loadImagei(name,k+1,ori);
		//allImages[k] = ori;
		//cout << "width: " << allImages[k].cols << endl;
		//cout << "Height: " << allImages[k].rows << endl;
		//Verify image has content
		//if(!ori.data){
		//	cout << "Input image was not loaded, please verify: " << argv[1] << k+1 <<".jpg" << endl;
		//	return -1;
		//}

		//Get the center of the Kth sphere in World Coordinates
		//sphereCenter(alpha, k, dist_c, xc, zc);

		//Create Sphere from Equirectangular image and store in Point Cloud
		//yc=0;
		//cloud = EquiToSphere(ori, radius,xc,yc,zc);
		//allPtClouds[k] = cloud;	

		//Save the PCD files
		//ostringstream file;
		//file << "./theta_pcds/" ;
		//cloud->width = cols;
		//cloud->height = rows;
		//cloud->points.resize(cols*rows);
		//cloud->is_dense = true;
		//file << name <<k << ".pcd"; 
		//String s = file.str();
		//io::savePCDFileASCII(s,*cloud);	

	//}//End of K loop of image

	//If Top and Bottom given
	//	string tb = argv[3];
	//	if(tb==""){
	//		//Load top and bottom Images
	//		loadImageTop(name,top,"top");
	//		xc = 0;		
	//		yc = dist_c;
	//		zc = 0;
	//		cloud = EquiToSphere(top, radius,xc,yc,zc);
	//		
	//		loadImageTop(name,bottom,"bottom");
	//		xc = 0;		
	//		yc = -dist_c;
	//		zc = 0;
	//		cloud = EquiToSphere(top, radius,xc,yc,zc);
	//		
	//	}

	//t1 = clock() - t;
	//cout << "Time to execute firs part before Kmean: " << (float)t1/CLOCKS_PER_SEC <<endl;

	/******************************* Test Zone ******************************************************/
	//=====================Testing space variables==================================//
	//cloud = allPtClouds[0];
	//ori = allImages[0];

	int nbPoints = 10;
	vector<PointXYZRGB> points;
	int m = 0;
	PointXYZRGB ikm;	
	PointXYZRGB o;
	//set o to origin
	o.x = 0;
	o.y = 0;
	o.z = 0;


	//Set u to anywhere in the sphere and v any direction
	u.x = 0;
	u.y = 0;
	u.z = 0;;
	v.x = 0;
	v.y = 1;
	v.z = 0;



	double step = 2*radius/nbPoints;
	iPoint.x = 0;
	iPoint.z = 0;
	iPoint.b = 255;
	v.r = 255;
	ikm.g = 255;
	vector<PointXYZRGB> linep(50);


	



	//Test of get plane function and project to Sphere with this plane
	//getPlaneAndProjectToSphere(PointXYZRGB u, PointXYZRGB v, PointCloud<PointXYZRGB>::Ptr sight)



	//Test of projection with Angle from 1 point
	//	projectionWithAngleFromOnePointTest(1,radius);



/////////////////////////////// end Test of viewing angle origin //////////////////////////////////
	//viewingAngleOriginTest( u,  v, radius,  rows, cols,cloud, sightFlat);
	//int trows = round(2048*70/360);
	//int tcols = round(1024*57/180);
	//sph = imageFromPcPlane(sightFlat,allImages[0],trows, tcols);
	//cv::imshow("SightMat" , sph);
//	cv::waitKey(0);
	//Viewing angles
///////////////////////////////////////  Test point on ray ////////////////////////////////////////
	//	iPoint.x = 0;
	//	iPoint.y = 0;
	//	iPoint.z = 0;
	//	
	//	o.r = o.g = o.b = 255;
	//	sight->points.push_back(u);
	//	//cout << "Ipoint on Ray: " << isOnRay(o,u,v) << endl;
	//	//cout << "Ipoint on Ray: " << isCloseToRayCube(o,u,v,0) << endl;
	//	
	//	//for all the pt clouds converted
	//	
	//	for(int m=0;m<tempCount;m++){
	//		//Get the sphere center of projection
	//		sphereCenter(alpha, m, dist_c, xc, zc);
	//		o.x = xc;
	//		o.z = zc;
	//		cloud = allPtClouds[m];
	//		for(int n=0;n<cloud->size();n++){
	//			iPoint = cloud->points[n];
	//		

	//			if(isCloseToRayCube(u,o,iPoint,.9)){
	//				sightFlat->points.push_back(iPoint);
	//				//cout << "ray passing through u: " << iPoint << endl;
	//			}
	//		}
	//	
		//cout << "Number of points: " << sightFlat->size() << endl;
	//	}
	//	
	//	//for Top and Bottom
//////////////////////////////////////  end Test point on ray ////////////////////////////////////


	//Test of 2D keypoints and Matches
	//KeyPointAndMatchesTest(allImages[0], allImages[1]);
	
	//Test of image interpolation
	ori = cv::imread("Bottom/Bottom3.jpg",1);

	
	templ = cv::imread("Bottom/Bottom4.jpg",1);

//	interpolate2DTest(allImages[0], allImages[1], 8, 4);
	
	//Test of sphereInterpolate
	//sightFlat = sphereInterpolate(allImages[0], allImages[1], 8, 4);
	
//	//Test of optical flow 
	//optFlowMapTest(ori, templ);
	
	//Line detection testing
	//getLinesTest(ori);
	
//	edge detection test
//	cv::Mat result1 = detectEdges(ori);
//	cv::Mat result2 = detectEdges(templ);
//	cv::namedWindow("edges1", 0);
//	cv::namedWindow("edges2", 0);
//	cv::imshow("edges1", result1);
//	cv::imshow("edges2", result2);
	
	
	//cv::Mat inter = cv::Mat::ones(ori.rows/2, ori.cols/2, ori.type());
	//cv::resize(ori,inter,inter.size(),0,0,INTER_CUBIC);
	//cv::pyrDown(ori,inter,Size(ori.cols/2,ori.rows/2));
	//ori = inter;
	
	//cv::pyrDown(templ,inter,Size(ori.cols/2,ori.rows/2));
	//cv::Mat inter2 = cv::Mat::ones(ori.rows/2, ori.cols/2, ori.type());
	//cv::resize(templ,inter2,inter.size(),0,0,INTER_CUBIC);
	//templ = inter2;

	
	//Test of Delaunay Triangles
	//delaunayTriangleTest(ori, "T1");
	//delaunayTriangleTestBound(ori, "T1");
	//delaunayTriangleTest(allImages[1], "T2");
	
	//Test with Maching
	//delaunayMatchedTrianglesTest(ori, templ,sightFlat);
	//delaunayMatchedTrianglesBoundTest(ori, templ,sightFlat);
	
	//Test delaunay interpolation
	double nb_inter = 50;
	int i=0;
	//vector<cv::Mat> interpolated = delaunayInterpolateMultiple(ori,templ,1,nb_inter);
	
	
	//Multi image vector for test
	vector<cv::Mat> images;
	
	//Test of multiple interpolated images 
	//multipleInterpolateTest(ori,templ,2);	
	

	//Test of reading files from folder and making video
	//Read and write files from tmp
	//for(i=0;i<nb_inter;i++){
	//	ostringstream nameWindow;
	//	nameWindow << "temp/Interpolated Image_"<< i << ".jpg" ;
		//nameWindow << "Bottom/Bottom"<< i+1 << ".jpg" ;
	//	Mat image = cv::imread(nameWindow.str(),1);
	//	if(!image.data){
	//		cout << "Please verify image names" << endl;
	//		break;
	//	}
	//	else{
	//		images.push_back(image);
	//	}
	//}
	//string videoName = "temp/Interpolated Video" ;
	//imageListToVideo(images,videoName);
//	sightFlat = EquiToSphere(result, 1,0,0,0);
	
	
	
	
	//EquiTrans Test 
	//EquitransTest(ori,90.,0.);

	
	//3D Keypoints Test
//	PointCloud<PointWithScale>::Ptr sightFlat1;
//	threeDKeypointsTest(cloud,sightFlat1);
//	PointWithScale pws;
//	PointXYZRGB pxy;
	//cout << "OutCloud size: " << sightFlat1->size() << endl;
//	for(int m=0;m<sightFlat1->size();m++){
//		pws = sightFlat1->points[m];
//		pxy.x = pws.x;
//		pxy.y =  pws.y;
//		pxy.z = pws.z;
//		sightFlat->points.push_back(pxy);
//	}

 	//twoDToThreeDkeypoints(ori);
 	//testCloudObj(allPtClouds[0]);
 	
 	//test3DTriangulation(allPtClouds[0]);
 	
 	//Test writting 3D points
 	//delaunayInterpolateCubeMakeTriangles(ori,templ,1,0.5,"Txt_files/Points3D_test3_1.txt","Txt_files/Points3D_test4_1.txt");
 	//testTriangleWrite(ori,templ,1,0.5,"Txt_files/Zenkoji5_6.txt","Txt_files/Zenkoji6.txt");
 	//Testing reading
 	//testTriangleRead(ori, templ, 1, 0.5, "Txt_files/trianglesZenkoji4_5.txt", "Txt_files/Zenkoji4_5.txt","Txt_files/Zenkoji5.txt", 48);
 	
 	
 	
 	//ori = cv::imread("../Tests/TestResultsNikko/Originals/Nikko (33).JPG",1);
	//templ = cv::imread("../Tests/TestResultsNikko/Originals/Nikko (34).JPG",1);
 	//testTriangleRead(ori, templ, 1, 0.5, "Txt_files/trianglesZenkoji4_5.txt", "Txt_files/Zenkoji4_5.txt","Txt_files/Zenkoji5.txt", 48, "TestResultsZenk/InterPersp4_5_");
 	
 	
 	//testTrianglePerspective(templ);
 	//cloud = EquiToSphere(ori,1,0,0,0);
 	//testTriangleContent3D(ori, cloud,sightFlat);
 	
 	//testSingleTrianglePerspective(ori,templ,1,0.5);
 	//testMultipleTrianglePerspective(ori,"Txt_files/trianglesPoints3D_test3_1.txt");
///////////////////////End of 3D keypoints test ////////////////////////////

	
	//Test of 3D affine
	//ThreeDAffineTransformTest();
	
	
	
	//testKeypointConversion(ori,templ);
	
	//Make video from images
	//string folder = "";
	//imageListToVideo("TestResultsZenk/Equi4_5", "InterpolatedOmni", 48,"TestResultsZenk/Equi4_5/InterpolatedVideo");
	
	
	//Test 2 images video
	//vector<cv::Mat> images;
	//for(int i=0;i<24;i++){
	//	images.push_back(ori);
	//}
	//for(int i=24;i<48;i++){
	//	images.push_back(templ);
	//}
	//imageListToVideo(images,"TestResultsZenk/Originals5_6/NonInterpolatedVideo");
	
	//testImageDiff(ori,templ);
	//randomTest(ori,templ);

	ori = imread("../Tests/TestRotation/Right/Right (14).JPG",1);
	//templ = imread("../Tests/TestRotation/Right/Right (30).JPG",1);
	
	//rotateImageTest("../Tests/TestRotation/Inside", "Test", 48, 270, "../Tests/TestRotation/RotatedChurchRight/Right");
	templ = rotateImagey(ori,20);
	//testImageDiff(ori,templ,"diffImage");
	imwrite("../Tests/TestRotation/Right/Right (14)_rotated-1.JPG", templ);
	
	/******************************************* End of Test Zone ***************************************************************/


	//cvResizeWindow("Keypoints 2D",rows,cols);



	//	cViewer.showCloud (allPtClouds[0]);
	//	cViewer.showCloud (sightFlat);
	//cViewer.showCloud(sightFlat);
	//viewer.addPointCloud(sightFlat, "Sphere");

	//	viewer.addPointCloud(cloud, "Sphere");
	//viewer.addPointCloud(sight, "Sphere1");

	//viewer.addPointCloud(allPtClouds[0], "Sphere");
	//	viewer.addPointCloud(allPtClouds[1], "Sphere1");
		//viewer.addPointCloud(allPtClouds[2], "Sphere2");
	//	viewer.addPointCloud(allPtClouds[3], "Sphere3");
	//imshow("Original",allImages[0]);

	//viewer.addCoordinateSystem (radius*2);
	//viewer.setPointCloudRenderingProperties (visualization::PCL_VISUALIZER_POINT_SIZE, 1, "Sphere");
	//viewer.registerKeyboardCallback (keyboardEventOccurred, (void*)&viewer);
	//while (!viewer.wasStopped ()){
		// This seems to cause trouble when having cloud viewer and viewr running
		//cv::imshow("Keypoints 2D" , sightMat);
	//	viewer.spinOnce (100);

		//cv::waitKey(0);
//		boost::this_thread::sleep (boost::posix_time::microseconds (10000));
	//}

	//close viewer



	
	cv::waitKey(0);



	return 0;
}
void
ring_on(void)
{
    register struct object *obj;
    register struct linked_list *item;
    register int ring;
    char buf[LINELEN];

    item = get_item("put on", RING);
    /*
     * Make certain that it is somethings that we want to wear
     */
    if (item == NULL)
	return;
    obj = (struct object *) ldata(item);
    if (obj->o_type != RING) {
	msg("You can't put that on!");
	return;
    }

    /*
     * find out which hand to put it on
     */
    if (is_current(obj))
	return;

    if      (cur_ring[LEFT_1] == NULL) ring = LEFT_1;
    else if (cur_ring[LEFT_2] == NULL) ring = LEFT_2;
    else if (cur_ring[LEFT_3] == NULL) ring = LEFT_3;
    else if (cur_ring[LEFT_4] == NULL) ring = LEFT_4;
    else if (cur_ring[RIGHT_1] == NULL) ring = RIGHT_1;
    else if (cur_ring[RIGHT_2] == NULL) ring = RIGHT_2;
    else if (cur_ring[RIGHT_3] == NULL) ring = RIGHT_3;
    else if (cur_ring[RIGHT_4] == NULL) ring = RIGHT_4;
    else
    {
	if (terse) 
	    msg("Wearing enough rings.");
	else
	    msg("You already have on eight rings.");
	return;
    }
    cur_ring[ring] = obj;

    /*
     * Calculate the effect it has on the poor guy.
     */
    switch (obj->o_which)
    {
	when R_ADDSTR:
	    pstats.s_str += obj->o_ac;
	when R_ADDHIT:
	    pstats.s_dext += obj->o_ac;
	when R_ADDINTEL:
	    pstats.s_intel += obj->o_ac;
	when R_ADDWISDOM:
	    pstats.s_wisdom += obj->o_ac;
	when R_SEEINVIS:
	    if (off(player, PERMBLIND)) {
		turn_on(player, CANSEE);
		msg("Your eyes begin to tingle.");
		sight();
		light(&hero);
		mvwaddch(cw, hero.y, hero.x, PLAYER);
	    }
	when R_AGGR:
	    aggravate();
	when R_CARRYING:
	    updpack(FALSE);
	when R_LEVITATION:
	    msg("You begin to float in the air!");
	when R_LIGHT: {
		if(roomin(&hero) != NULL) {
			light(&hero);
			mvwaddch(cw, hero.y, hero.x, PLAYER);
		}
	    }
    }
    status(FALSE);
    if (r_know[obj->o_which] && r_guess[obj->o_which])
    {
	free(r_guess[obj->o_which]);
	r_guess[obj->o_which] = NULL;
    }
    else if (!r_know[obj->o_which] && 
	     askme && 
	     (obj->o_flags & ISKNOW) == 0 &&
	     r_guess[obj->o_which] == NULL) {
	mpos = 0;
	msg(terse ? "Call it: " : "What do you want to call it? ");
	if (get_str(buf, msgw) == NORM)
	{
	    r_guess[obj->o_which] = new(strlen(buf) + 1);
	    strcpy(r_guess[obj->o_which], buf);
	}
/*
 * quaff:
 *	Quaff a potion from the pack
 */
quaff()
{
    register THING *obj, *th;
    register bool discardit = FALSE;

    obj = get_item("quaff", POTION);
    /*
     * Make certain that it is somethings that we want to drink
     */
    if (obj == NULL)
	return;
    if (obj->o_type != POTION)
    {
	if (!terse)
	    msg("yuk! Why would you want to drink that?");
	else
	    msg("that's undrinkable");
	return;
    }
    if (obj == cur_weapon)
	cur_weapon = NULL;

    /*
     * Calculate the effect it has on the poor guy.
     */
    switch (obj->o_which)
    {
	case P_CONFUSE:
	    p_know[P_CONFUSE] = TRUE;
	    if (!on(player, ISHUH))
	    {
		if (on(player, ISHUH))
		    lengthen(unconfuse, rnd(8)+HUHDURATION);
		else
		    fuse(unconfuse, 0, rnd(8)+HUHDURATION, AFTER);
		player.t_flags |= ISHUH;
		msg("wait, what's going on here. Huh? What? Who?");
	    }
	when P_POISON:
	    p_know[P_POISON] = TRUE;
	    if (!ISWEARING(R_SUSTSTR))
	    {
		chg_str(-(rnd(3)+1));
		msg("you feel very sick now");
	    }
	    else
		msg("you feel momentarily sick");
	when P_HEALING:
	    p_know[P_HEALING] = TRUE;
	    if ((pstats.s_hpt += roll(pstats.s_lvl, 4)) > max_hp)
		pstats.s_hpt = ++max_hp;
	    sight();
	    msg("you begin to feel better");
	when P_STRENGTH:
	    p_know[P_STRENGTH] = TRUE;
	    chg_str(1);
	    msg("you feel stronger, now.  What bulging muscles!");
	when P_MFIND:
	    player.t_flags |= SEEMONST;
	    fuse(turn_see, TRUE, HUHDURATION, AFTER);
	    if (mlist == NULL)
		msg("you have a strange feeling for a moment");
	    else
		p_know[P_MFIND] |= turn_see(FALSE);
	when P_TFIND:
	    /*
	     * Potion of magic detection.  Show the potions and scrolls
	     */
	    if (lvl_obj != NULL)
	    {
		register THING *tp;
		register bool show;

		show = FALSE;
		wclear(hw);
		for (tp = lvl_obj; tp != NULL; tp = next(tp))
		{
		    if (is_magic(tp))
		    {
			show = TRUE;
			mvwaddch(hw, tp->o_pos.y, tp->o_pos.x, MAGIC);
			p_know[P_TFIND] = TRUE;
		    }
		}
		for (th = mlist; th != NULL; th = next(th))
		{
		    for (tp = th->t_pack; tp != NULL; tp = next(tp))
		    {
			if (is_magic(tp))
			{
			    show = TRUE;
			    mvwaddch(hw, th->t_pos.y, th->t_pos.x, MAGIC);
			    p_know[P_TFIND] = TRUE;
			}
		    }
		}
		if (show)
		{
		    show_win(hw, 
			"You sense the presence of magic on this level.--More--");
		    break;
		}
	    }
	    msg("you have a strange feeling for a moment, then it passes");
	when P_PARALYZE:
	    p_know[P_PARALYZE] = TRUE;
	    no_command = HOLDTIME;
	    player.t_flags &= ~ISRUN;
	    msg("you can't move");
	when P_SEEINVIS:
	    if (!on(player, CANSEE))
	    {
		fuse(unsee, 0, SEEDURATION, AFTER);
		look(FALSE);
		invis_on();
	    }
	    sight();
	    msg("this potion tastes like %s juice", fruit);
	when P_RAISE:
	    p_know[P_RAISE] = TRUE;
	    msg("you suddenly feel much more skillful");
	    raise_level();
	when P_XHEAL:
	    p_know[P_XHEAL] = TRUE;
	    if ((pstats.s_hpt += roll(pstats.s_lvl, 8)) > max_hp)
	    {
		if (pstats.s_hpt > max_hp + pstats.s_lvl + 1)
		    ++max_hp;
		pstats.s_hpt = ++max_hp;
	    }
	    sight();
	    msg("you begin to feel much better");
	when P_HASTE:
	    p_know[P_HASTE] = TRUE;
	    if (add_haste(TRUE))
		msg("you feel yourself moving much faster");
	when P_RESTORE:
	    if (ISRING(LEFT, R_ADDSTR))
		add_str(&pstats.s_str, -cur_ring[LEFT]->o_ac);
	    if (ISRING(RIGHT, R_ADDSTR))
		add_str(&pstats.s_str, -cur_ring[RIGHT]->o_ac);
	    if (pstats.s_str < max_stats.s_str)
		pstats.s_str = max_stats.s_str;
	    if (ISRING(LEFT, R_ADDSTR))
		add_str(&pstats.s_str, cur_ring[LEFT]->o_ac);
	    if (ISRING(RIGHT, R_ADDSTR))
		add_str(&pstats.s_str, cur_ring[RIGHT]->o_ac);
	    msg("hey, this tastes great.  It make you feel warm all over");
	when P_BLIND:
	    p_know[P_BLIND] = TRUE;
	    if (!on(player, ISBLIND))
	    {
		player.t_flags |= ISBLIND;
		fuse(sight, 0, SEEDURATION, AFTER);
		look(FALSE);
	    }
	    msg("a cloak of darkness falls around you");
	when P_NOP:
	    msg("this potion tastes extremely dull");
	otherwise:
	    msg("what an odd tasting potion!");
	    return;
    }
    status();
    /*
     * Throw the item away
     */
    inpack--;
    if (obj->o_count > 1)
	obj->o_count--;
    else
    {
	detach(pack, obj);
        discardit = TRUE;
    }

    call_it(p_know[obj->o_which], &p_guess[obj->o_which]);

    if (discardit)
	discard(obj);
}