예제 #1
0
파일: ability.C 프로젝트: SinaC/OldMud
/* checks for skill improvement */
void check_improve( CHAR_DATA *ch, int sn, bool success, int multiplier ) {
  int chance;
  char buf[100];

  if (IS_NPC(ch))
    return;

  // Modified by SinaC 2001
  if (ch->level < class_abilitylevel( /*ch->cstat(classes)*/ch, sn )
      // Modified by SinaC 2003
      ||  class_abilityrating( ch, sn, ch->pcdata->ability_info[sn].casting_level ) == 0
      ||  ch->pcdata->ability_info[sn].learned == 0
      ||  ch->pcdata->ability_info[sn].learned == 100)
    return;  /* skill is not known */

  /* check to see if the character has a chance to learn */
  chance = 10 * int_app[ch->cstat(INT)].learn;
  chance /= ( multiplier
	      *	class_abilityrating( ch, sn, ch->pcdata->ability_info[sn].casting_level )
	      *	4 );
  chance += ch->level;

  if (number_range(1,1000) > chance)
    return;

  /* now that the character has a CHANCE to learn, see if they really have */

  bool done = FALSE; // Added by SinaC 2003
  if (success) {
    chance = URANGE(5,100 - ch->pcdata->ability_info[sn].learned, 95);
    if (number_percent() < chance) {
      sprintf(buf,"You have become better at %s!\n\r",
	      ability_table[sn].name);
      send_to_char(buf,ch);
      ch->pcdata->ability_info[sn].learned++;
      gain_exp(ch,2 * class_abilityrating( ch, sn, ch->pcdata->ability_info[sn].casting_level), TRUE);
      done = TRUE;
    }
  }
  else {
    chance = URANGE(5,ch->pcdata->ability_info[sn].learned/2,30);
    if (number_percent() < chance) {
      sprintf(buf,
	      "You learn from your mistakes, and your %s skill improves.\n\r",
	      ability_table[sn].name);
      send_to_char(buf,ch);
      ch->pcdata->ability_info[sn].learned += number_range(1,3);
      ch->pcdata->ability_info[sn].learned = UMIN(ch->pcdata->ability_info[sn].learned,100);
      gain_exp(ch,2 * class_abilityrating( ch, sn, ch->pcdata->ability_info[sn].casting_level), TRUE);
      done = TRUE;
    }
  }
  if ( done && ch->pcdata->ability_info[sn].learned == 100 ) // Added by SinaC 2003
    send_to_charf(ch,"You are now master in '%s'.\n\r", ability_table[sn].name );
}
예제 #2
0
void die(struct char_data *ch)
{
  gain_exp(ch, -(GET_EXP(ch) / 2));
  if (!IS_NPC(ch))
    REMOVE_BIT(PLR_FLAGS(ch), PLR_KILLER | PLR_THIEF);
  raw_kill(ch);
}
예제 #3
0
void do_recall (CHAR_DATA * ch, char *argument)
{
    char buf[MAX_STRING_LENGTH];
    ROOM_INDEX_DATA *location;

    if (IS_NPC (ch))
    {
        send_to_char ("Only players can recall.\n\r", ch);
        return;
    }

    act ("$n prays for transportation!", ch, 0, 0, TO_ROOM);

    if ((location = get_room_index (100)) == NULL)
    {
        send_to_char ("You are completely lost.\n\r", ch);
        return;
    }

    if (ch->in_room == location)
        return;

    if (IS_SET (ch->in_room->room_flags, ROOM_NO_RECALL))
    {
        send_to_char ("Mota has forsaken you.\n\r", ch);
        return;
    }

           if(ch->infight)
    {
        int lose, skill;

        skill = get_skill (ch, gsn_recall);

        if (number_percent () < 80 * skill / 100)
        {
            WAIT_STATE (ch, 4);
            sprintf (buf, "You failed!.\n\r");
            send_to_char (buf, ch);
            return;
        }

        lose = (ch->desc != NULL) ? 25 : 50;
        gain_exp (ch, 0 - lose);
        sprintf (buf, "You recall from combat!  You lose %d exps.\n\r", lose);
        send_to_char (buf, ch);
        stop_fighting (ch, TRUE);

    }

    ch->move /= 2;
    act ("$n disappears.", ch, NULL, NULL, TO_ROOM);
    char_from_room (ch);
    char_to_room (ch, location);
    act ("$n appears in the room.", ch, NULL, NULL, TO_ROOM);
    do_function (ch, &do_look, "auto");

    return;
}
예제 #4
0
/* checks for skill improvement */
void check_improve( CHAR_DATA *ch, int sn, bool success, int multiplier )
{
	int chance = 0;

	if (IS_NPC(ch))
		return;

	if (ch->level < skill_table[sn].skill_level[ch->iclass]
		||  skill_table[sn].rating[ch->iclass] == 0
		||  ch->pcdata->learned[sn] == 0
		||  ch->pcdata->learned[sn] == 100)
	return;  /* skill is not known */ 

	/* check to see if the character has a chance to learn */
	chance = 10 * int_app[get_curr_stat(ch,STAT_INT)].learn;
	chance /= (	multiplier * skill_table[sn].rating[ch->iclass] * 4);
	chance += ch->level;

	if (number_range(1,1000) > chance)
		return;

	/* now that the character has a CHANCE to learn, see if they really have */	

	if (success)
	{
		chance = URANGE(5,100 - ch->pcdata->learned[sn], 95);
		if (number_percent() < chance)
		{
			send_to_char(Format("You have become better at %s!\n\r", skill_table[sn].name),ch);
			ch->pcdata->learned[sn]++;
			gain_exp(ch,2 * skill_table[sn].rating[ch->iclass]);
		}
	}

	else
	{
		chance = URANGE(5,ch->pcdata->learned[sn]/2,30);
		if (number_percent() < chance)
		{
			send_to_char(Format("You learn from your mistakes, and your %s skill improves.\n\r", skill_table[sn].name),ch);
			ch->pcdata->learned[sn] += number_range(1,3);
			ch->pcdata->learned[sn] = UMIN(ch->pcdata->learned[sn],100);
			gain_exp(ch,2 * skill_table[sn].rating[ch->iclass]);
		}
	}
}
예제 #5
0
void group_gain(struct char_data *ch, struct char_data *victim)
{
	char buf[256];
	int no_members, share;
	struct char_data *k;
	struct follow_type *f;

	if (!(k=ch->master))
		k = ch;


	if (IS_AFFECTED(k, AFF_GROUP) &&
	   (k->in_room == ch->in_room))
		no_members = 1;
	else
		no_members = 0;

	for (f=k->followers; f; f=f->next)
		if (IS_AFFECTED(f->follower, AFF_GROUP) &&
		   (f->follower->in_room == ch->in_room))
			no_members++;

	if (no_members >= 1)
		share = MIN(450000/no_members, (GET_EXP(victim)/3)/no_members);
	else
		share = 0;

	if (IS_AFFECTED(k, AFF_GROUP) &&
	   (k->in_room == ch->in_room)) {
		act("You receive your share of experience.", FALSE, k, 0, 0, TO_CHAR);
		gain_exp(k, share);
		change_alignment(k, victim);
	}

	for (f=k->followers; f; f=f->next) {
		if (IS_AFFECTED(f->follower, AFF_GROUP) &&
		   (f->follower->in_room == ch->in_room)) {
			act("You receive your share of experience.", FALSE, f->follower,0,0,TO_CHAR);
			gain_exp(f->follower, share);
			change_alignment(f->follower, victim);
		}
	}
}
예제 #6
0
int dump(struct char_data *ch, int cmd, char *arg) 
{
   struct obj_data *k;
	char buf[100];
   struct char_data *tmp_char;
   int value=0;

	void do_drop(struct char_data *ch, char *argument, int cmd);
	char *fname(char *namelist);

	for(k = world[ch->in_room].contents; k ; k = world[ch->in_room].contents)
	{
		sprintf(buf, "The %s vanish in a puff of smoke.\n\r" ,fname(k->name));
		for(tmp_char = world[ch->in_room].people; tmp_char;
			tmp_char = tmp_char->next_in_room)
			if (CAN_SEE_OBJ(tmp_char, k))
				send_to_char(buf,tmp_char);
		extract_obj(k);
	}

	if(cmd!=60) return(FALSE);

	do_drop(ch, arg, cmd);

	value = 0;

	for(k = world[ch->in_room].contents; k ; k = world[ch->in_room].contents)
	{
		sprintf(buf, "The %s vanish in a puff of smoke.\n\r",fname(k->name));
		for(tmp_char = world[ch->in_room].people; tmp_char;
			tmp_char = tmp_char->next_in_room)
			if (CAN_SEE_OBJ(tmp_char, k))
				send_to_char(buf,tmp_char);
			value += MAX(1, MIN(50, k->obj_flags.cost/10));

		extract_obj(k);
	}

	if (value) 
	{
		act("You are awarded for outstanding performance.", FALSE, ch, 0, 0, TO_CHAR);
		act("$n has been awarded for being a good citizen.", TRUE, ch, 0,0, TO_ROOM);

		if (GET_LEVEL(ch) < 3)
			gain_exp(ch, value);
		else
			GET_GOLD(ch) += value;
	}
}
예제 #7
0
void perform_group_gain(struct char_data *ch, int base,
			     struct char_data *victim)
{
  int share;

  share = MIN(max_exp_gain, MAX(1, base));

  if (share > 1)
    send_to_char(ch, "You receive your share of experience -- %d points.\r\n", share);
  else
    send_to_char(ch, "You receive your share of experience -- one measly little point!\r\n");

  gain_exp(ch, share);
  change_alignment(ch, victim);
}
예제 #8
0
void do_mpgainxp(CHAR_DATA* ch, char* argument)
{
    char       arg1[ MAX_INPUT_LENGTH ];
    char       arg2[ MAX_INPUT_LENGTH ];
    CHAR_DATA *victim;

    if ( !IS_NPC( ch ) )
    {
       send_to_char(C_DEFAULT, "Huh?\n\r", ch );
       return;
    }

    if ( IS_AFFECTED( ch, AFF_CHARM ) )
    {
        return;
    }

    argument = one_argument( argument, arg1 );
    argument = one_argument( argument, arg2 );

    if ( arg1[0] == '\0' || arg2[0]=='\0' )
    {
       bug( "Mpgainxp - No argument:  vnum %d.",
	   ch->pIndexData->vnum );
       return;
    }

    if ( !( victim = get_char_room( ch, arg1 ) ) )
    {
      return;
    } else
    {
       CHAR_DATA* gch;
       for ( gch = victim->in_room->people; gch; gch = gch->next_in_room )
       {
          if ( is_same_group( gch, victim ) )
          {
	     gain_exp( gch, atoi(arg2));
          }
       }

    }
}
예제 #9
0
/*!
 * @brief 青魔法のラーニング判定と成功した場合のラーニング処理
 * @param monspell ラーニングを試みるモンスター攻撃のID
 * @return なし
 */
void learn_spell(int monspell)
{
	if (p_ptr->action != ACTION_LEARN) return;
	if (monspell < 0) return; /* Paranoia */
	if (p_ptr->magic_num2[monspell]) return;
	if (p_ptr->confused || p_ptr->blind || p_ptr->image || p_ptr->stun || p_ptr->paralyzed) return;
	if (randint1(p_ptr->lev + 70) > monster_powers[monspell].level + 40)
	{
		p_ptr->magic_num2[monspell] = 1;
		msg_format(_("%sを学習した!", "You have learned %s!"), monster_powers[monspell].name);
		gain_exp(monster_powers[monspell].level * monster_powers[monspell].smana);

		/* Sound */
		sound(SOUND_STUDY);

		new_mane = TRUE;
		p_ptr->redraw |= (PR_STATE);
	}
}
예제 #10
0
void solo_gain(struct char_data *ch, struct char_data *victim)
{
  int exp;

  exp = MIN(max_exp_gain, GET_EXP(victim) / 3);

  /* Calculate level-difference bonus */
  if (IS_NPC(ch))
    exp += MAX(0, (exp * MIN(4, (GET_LEVEL(victim) - GET_LEVEL(ch)))) / 8);
  else
    exp += MAX(0, (exp * MIN(8, (GET_LEVEL(victim) - GET_LEVEL(ch)))) / 8);

  exp = MAX(exp, 1);

  if (exp > 1)
    send_to_char(ch, "You receive %d experience points.\r\n", exp);
  else
    send_to_char(ch, "You receive one lousy experience point.\r\n");

  gain_exp(ch, exp);
  change_alignment(ch, victim);
}
예제 #11
0
void solo_gain(struct char_data *ch, struct char_data *victim)
{
  int exp;

  exp = MIN(CONFIG_MAX_EXP_GAIN, GET_EXP(victim) / 3);

  /* Calculate level-difference bonus */
  if (IS_NPC(ch))
    exp += MAX(0, (exp * MIN(4, (GET_LEVEL(victim) - GET_LEVEL(ch)))) / 8);
  else
    exp += MAX(0, (exp * MIN(8, (GET_LEVEL(victim) - GET_LEVEL(ch)))) / 8);

  exp = MAX(exp, 1);
  if (script_compute_kill_exp(&ch, &victim, 1, &exp) != SCRIPT_RET_OK)
      exp = MAX(exp, 1);

  if (exp > 1)
    send_to_char(ch, "You receive %d experience points.\r\n", exp);
  else
    send_to_char(ch, "You receive one lousy experience point.\r\n");

  gain_exp(ch, exp);
  change_alignment(ch, victim);
}
예제 #12
0
/*
 * Alert: As of bpl14, this function returns the following codes:
 *	< 0	Victim died.
 *	= 0	No damage.
 *	> 0	How much damage done.
 */
int damage(struct char_data *ch, struct char_data *victim, int dam, int attacktype)
{
  if (GET_POS(victim) <= POS_DEAD) {
    /* This is "normal"-ish now with delayed extraction. -gg 3/15/2001 */
    if (PLR_FLAGGED(victim, PLR_NOTDEADYET) || MOB_FLAGGED(victim, MOB_NOTDEADYET))
      return (-1);

    log("SYSERR: Attempt to damage corpse '%s' in room #%d by '%s'.",
		GET_NAME(victim), GET_ROOM_VNUM(IN_ROOM(victim)), GET_NAME(ch));
    die(victim);
    return (-1);			/* -je, 7/7/92 */
  }

  /* peaceful rooms */
  if (ch != victim && ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) {
    send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n");
    return (0);
  }

  /* shopkeeper protection */
  if (!ok_damage_shopkeeper(ch, victim))
    return (0);

  /* You can't damage an immortal! */
  if (!IS_NPC(victim) && (GET_LEVEL(victim) >= LVL_IMMORT))
    dam = 0;

  if (victim != ch) {
    /* Start the attacker fighting the victim */
    if (GET_POS(ch) > POS_STUNNED && (FIGHTING(ch) == NULL))
      set_fighting(ch, victim);

    /* Start the victim fighting the attacker */
    if (GET_POS(victim) > POS_STUNNED && (FIGHTING(victim) == NULL)) {
      set_fighting(victim, ch);
      if (MOB_FLAGGED(victim, MOB_MEMORY) && !IS_NPC(ch))
	remember(victim, ch);
    }
  }

  /* If you attack a pet, it hates your guts */
  if (victim->master == ch)
    stop_follower(victim);

  /* If the attacker is invisible, he becomes visible */
  if (AFF_FLAGGED(ch, AFF_INVISIBLE | AFF_HIDE))
    appear(ch);

  /* Cut damage in half if victim has sanct, to a minimum 1 */
  if (AFF_FLAGGED(victim, AFF_SANCTUARY) && dam >= 2)
    dam /= 2;

  /* Check for PK if this is not a PK MUD */
  if (!pk_allowed) {
    check_killer(ch, victim);
    if (PLR_FLAGGED(ch, PLR_KILLER) && (ch != victim))
      dam = 0;
  }

  /* Set the maximum damage per round and subtract the hit points */
  dam = MAX(MIN(dam, 100), 0);
  GET_HIT(victim) -= dam;

  /* Gain exp for the hit */
  if (ch != victim)
    gain_exp(ch, GET_LEVEL(victim) * dam);

  update_pos(victim);

  /*
   * skill_message sends a message from the messages file in lib/misc.
   * dam_message just sends a generic "You hit $n extremely hard.".
   * skill_message is preferable to dam_message because it is more
   * descriptive.
   * 
   * If we are _not_ attacking with a weapon (i.e. a spell), always use
   * skill_message. If we are attacking with a weapon: If this is a miss or a
   * death blow, send a skill_message if one exists; if not, default to a
   * dam_message. Otherwise, always send a dam_message.
   */
  if (!IS_WEAPON(attacktype))
    skill_message(dam, ch, victim, attacktype);
  else {
    if (GET_POS(victim) == POS_DEAD || dam == 0) {
      if (!skill_message(dam, ch, victim, attacktype))
	dam_message(dam, ch, victim, attacktype);
    } else {
      dam_message(dam, ch, victim, attacktype);
    }
  }

  /* Use send_to_char -- act() doesn't send message if you are DEAD. */
  switch (GET_POS(victim)) {
  case POS_MORTALLYW:
    act("$n is mortally wounded, and will die soon, if not aided.", TRUE, victim, 0, 0, CommTarget::TO_ROOM);
    send_to_char(victim, "You are mortally wounded, and will die soon, if not aided.\r\n");
    break;
  case POS_INCAP:
    act("$n is incapacitated and will slowly die, if not aided.", TRUE, victim, 0, 0, CommTarget::TO_ROOM);
    send_to_char(victim, "You are incapacitated an will slowly die, if not aided.\r\n");
    break;
  case POS_STUNNED:
    act("$n is stunned, but will probably regain consciousness again.", TRUE, victim, 0, 0, CommTarget::TO_ROOM);
    send_to_char(victim, "You're stunned, but will probably regain consciousness again.\r\n");
    break;
  case POS_DEAD:
    act("$n is dead!  R.I.P.", FALSE, victim, 0, 0, CommTarget::TO_ROOM);
    send_to_char(victim, "You are dead!  Sorry...\r\n");
    break;

  default:			/* >= POSITION SLEEPING */
    if (dam > (GET_MAX_HIT(victim) / 4))
      send_to_char(victim, "That really did HURT!\r\n");

    if (GET_HIT(victim) < (GET_MAX_HIT(victim) / 4)) {
      send_to_char(victim, "%sYou wish that your wounds would stop BLEEDING so much!%s\r\n",
		CCRED(victim, C_SPR), CCNRM(victim, C_SPR));
      if (ch != victim && MOB_FLAGGED(victim, MOB_WIMPY))
	do_flee(victim, NULL, 0, 0);
    }
    if (!IS_NPC(victim) && GET_WIMP_LEV(victim) && (victim != ch) &&
	GET_HIT(victim) < GET_WIMP_LEV(victim) && GET_HIT(victim) > 0) {
      send_to_char(victim, "You wimp out, and attempt to flee!\r\n");
      do_flee(victim, NULL, 0, 0);
    }
    break;
  }

  /* Help out poor linkless people who are attacked */
  if (!IS_NPC(victim) && !(victim->desc) && GET_POS(victim) > POS_STUNNED) {
    do_flee(victim, NULL, 0, 0);
    if (!FIGHTING(victim)) {
      act("$n is rescued by divine forces.", FALSE, victim, 0, 0, CommTarget::TO_ROOM);
      GET_WAS_IN(victim) = IN_ROOM(victim);
      char_from_room(victim);
      char_to_room(victim, 0);
    }
  }

  /* stop someone from fighting if they're stunned or worse */
  if (GET_POS(victim) <= POS_STUNNED && FIGHTING(victim) != NULL)
    stop_fighting(victim);

  /* Uh oh.  Victim died. */
  if (GET_POS(victim) == POS_DEAD) {
    if (ch != victim && (IS_NPC(victim) || victim->desc)) {
      if (AFF_FLAGGED(ch, AFF_GROUP))
	group_gain(ch, victim);
      else
        solo_gain(ch, victim);
    }

    if (!IS_NPC(victim)) {
      mudlog(BRF, LVL_IMMORT, TRUE, "%s killed by %s at %s", GET_NAME(victim), GET_NAME(ch), world[IN_ROOM(victim)].name);
      if (MOB_FLAGGED(ch, MOB_MEMORY))
	forget(ch, victim);
    }
    die(victim);
    return (-1);
  }
  return (dam);
}
예제 #13
0
파일: cmd-obj.c 프로젝트: non/angband
/*
 * Use an object the right way.
 *
 * There may be a BIG problem with any "effect" that can cause "changes"
 * to the inventory.  For example, a "scroll of recharging" can cause
 * a wand/staff to "disappear", moving the inventory up.  Luckily, the
 * scrolls all appear BEFORE the staffs/wands, so this is not a problem.
 * But, for example, a "staff of recharging" could cause MAJOR problems.
 * In such a case, it will be best to either (1) "postpone" the effect
 * until the end of the function, or (2) "change" the effect, say, into
 * giving a staff "negative" charges, or "turning a staff into a stick".
 * It seems as though a "rod of recharging" might in fact cause problems.
 * The basic problem is that the act of recharging (and destroying) an
 * item causes the inducer of that action to "move", causing "o_ptr" to
 * no longer point at the correct item, with horrifying results.
 */
void do_cmd_use(cmd_code code, cmd_arg args[])
{
    int item = args[0].item;
    object_type *o_ptr = object_from_item_idx(item);
    int effect;
    bool ident = FALSE, used = FALSE;
    bool was_aware = object_flavor_is_aware(o_ptr);
    int dir = 5;
    int px = p_ptr->px, py = p_ptr->py;
    int snd, boost, level;
    use_type use;
    int items_allowed = 0;

    /* Determine how this item is used. */
    if (obj_is_rod(o_ptr))
    {
        if (!obj_can_zap(o_ptr))
        {
            msg_print("That rod is still charging.");
            return;
        }

        use = USE_TIMEOUT;
        snd = MSG_ZAP_ROD;
        items_allowed = USE_INVEN | USE_FLOOR;
    }
    else if (obj_is_wand(o_ptr))
    {
        if (!obj_has_charges(o_ptr))
        {
            msg_print("That wand has no charges.");
            return;
        }

        use = USE_CHARGE;
        snd = MSG_ZAP_ROD;
        items_allowed = USE_INVEN | USE_FLOOR;
    }
    else if (obj_is_staff(o_ptr))
    {
        if (!obj_has_charges(o_ptr))
        {
            msg_print("That staff has no charges.");
            return;
        }

        use = USE_CHARGE;
        snd = MSG_USE_STAFF;
        items_allowed = USE_INVEN | USE_FLOOR;
    }
    else if (obj_is_food(o_ptr))
    {
        use = USE_SINGLE;
        snd = MSG_EAT;
        items_allowed = USE_INVEN | USE_FLOOR;
    }
    else if (obj_is_potion(o_ptr))
    {
        use = USE_SINGLE;
        snd = MSG_QUAFF;
        items_allowed = USE_INVEN | USE_FLOOR;
    }
    else if (obj_is_scroll(o_ptr))
    {
        /* Check player can use scroll */
        if (!player_can_read())
            return;

        use = USE_SINGLE;
        snd = MSG_GENERIC;
        items_allowed = USE_INVEN | USE_FLOOR;
    }
    else if (obj_is_activatable(o_ptr))
    {
        if (!obj_can_activate(o_ptr))
        {
            msg_print("That item is still charging.");
            return;
        }

        use = USE_TIMEOUT;
        snd = MSG_ACT_ARTIFACT;
        items_allowed = USE_EQUIP;
    }
    else
    {
        msg_print("The item cannot be used at the moment");
    }

    /* Check if item is within player's reach. */
    if (items_allowed == 0 || !item_is_available(item, NULL, items_allowed))
    {
        msg_print("You cannot use that item from its current location.");
        return;
    }

    /* track the object used */
    track_object(item);

    /* Figure out effect to use */
    effect = object_effect(o_ptr);

    /* If the item requires a direction, get one (allow cancelling) */
    if (obj_needs_aim(o_ptr))
        dir = args[1].direction;

    /* Check for use if necessary, and execute the effect */
    if ((use != USE_CHARGE && use != USE_TIMEOUT) ||
            check_devices(o_ptr))
    {
        /* Special message for artifacts */
        if (artifact_p(o_ptr))
        {
            message(snd, 0, "You activate it.");
            if (a_info[o_ptr->name1].effect_msg)
                activation_message(o_ptr, a_info[o_ptr->name1].effect_msg);
            level = a_info[o_ptr->name1].level;
        }
        else
        {
            /* Make a noise! */
            sound(snd);
            level = k_info[o_ptr->k_idx].level;
        }

        /* A bit of a hack to make ID work better.
        	-- Check for "obvious" effects beforehand. */
        if (effect_obvious(effect)) object_flavor_aware(o_ptr);

        /* Boost damage effects if skill > difficulty */
        boost = p_ptr->state.skills[SKILL_DEVICE] - level;
        if (boost < 0) boost = 0;

        /* Do effect */
        used = effect_do(effect, &ident, was_aware, dir,
                         beam_chance(o_ptr->tval), boost);

        /* Quit if the item wasn't used and no knowledge was gained */
        if (!used && (was_aware || !ident)) return;
    }

    /* If the item is a null pointer or has been wiped, be done now */
    if (!o_ptr || o_ptr->k_idx <= 1) return;

    if (ident) object_notice_effect(o_ptr);

    /* Food feeds the player */
    if (o_ptr->tval == TV_FOOD || o_ptr->tval == TV_POTION)
        (void)set_food(p_ptr->food + o_ptr->pval);

    /* Use the turn */
    p_ptr->energy_use = 100;

    /* Mark as tried and redisplay */
    p_ptr->notice |= (PN_COMBINE | PN_REORDER);
    p_ptr->redraw |= (PR_INVEN | PR_EQUIP | PR_OBJECT);

    /*
     * If the player becomes aware of the item's function, then mark it as
     * aware and reward the player with some experience.  Otherwise, mark
     * it as "tried".
     */
    if (ident && !was_aware)
    {
        /* Object level */
        int lev = k_info[o_ptr->k_idx].level;

        object_flavor_aware(o_ptr);
        if (o_ptr->tval == TV_ROD) object_notice_everything(o_ptr);
        gain_exp((lev + (p_ptr->lev / 2)) / p_ptr->lev);
        p_ptr->notice |= PN_SQUELCH;
    }
    else if (used)
    {
        object_flavor_tried(o_ptr);
    }

    /* If there are no more of the item left, then we're done. */
    if (!o_ptr->number) return;

    /* Chargeables act differently to single-used items when not used up */
    if (used && use == USE_CHARGE)
    {
        /* Use a single charge */
        o_ptr->pval--;

        /* Describe charges */
        if (item >= 0)
            inven_item_charges(item);
        else
            floor_item_charges(0 - item);
    }
    else if (used && use == USE_TIMEOUT)
    {
        /* Artifacts use their own special field */
        if (o_ptr->name1)
        {
            const artifact_type *a_ptr = &a_info[o_ptr->name1];
            o_ptr->timeout = randcalc(a_ptr->time, 0, RANDOMISE);
        }
        else
        {
            const object_kind *k_ptr = &k_info[o_ptr->k_idx];
            o_ptr->timeout += randcalc(k_ptr->time, 0, RANDOMISE);
        }
    }
    else if (used && use == USE_SINGLE)
    {
        /* Destroy a potion in the pack */
        if (item >= 0)
        {
            inven_item_increase(item, -1);
            inven_item_describe(item);
            inven_item_optimize(item);
        }

        /* Destroy a potion on the floor */
        else
        {
            floor_item_increase(0 - item, -1);
            floor_item_describe(0 - item);
            floor_item_optimize(0 - item);
        }
    }

    /* Hack to make Glyph of Warding work properly */
    if (cave_feat[py][px] == FEAT_GLYPH)
    {
        /* Shift any objects to further away */
        for (o_ptr = get_first_object(py, px); o_ptr; o_ptr =
                    get_next_object(o_ptr))
        {
            drop_near(o_ptr, 0, py, px, FALSE);
        }

        /* Delete the "moved" objects from their original position */
        delete_object(py, px);
    }


}
예제 #14
0
/*
 * Attempt to disarm the chest at the given location
 *
 * Assume there is no monster blocking the destination
 *
 * Returns TRUE if repeated commands may continue
 */
static bool do_cmd_disarm_chest(int y, int x, s16b o_idx)
{
	int i, j;

	bool more = FALSE;

	object_type *o_ptr = &o_list[o_idx];


	/* Get the "disarm" factor */
	i = p_ptr->state.skills[SKILL_DISARM];

	/* Penalize some conditions */
	if (p_ptr->timed[TMD_BLIND] || no_light()) i = i / 10;
	if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) i = i / 10;

	/* Extract the difficulty */
	j = i - o_ptr->pval;

	/* Always have a small chance of success */
	if (j < 2) j = 2;

	/* Must find the trap first. */
	if (!object_is_known(o_ptr))
	{
		msg_print("I don't see any traps.");
	}

	/* Already disarmed/unlocked */
	else if (o_ptr->pval <= 0)
	{
		msg_print("The chest is not trapped.");
	}

	/* No traps to find. */
	else if (!chest_traps[o_ptr->pval])
	{
		msg_print("The chest is not trapped.");
	}

	/* Success (get a lot of experience) */
	else if (randint0(100) < j)
	{
		message(MSG_DISARM, 0, "You have disarmed the chest.");
		gain_exp(o_ptr->pval);
		o_ptr->pval = (0 - o_ptr->pval);
	}

	/* Failure -- Keep trying */
	else if ((i > 5) && (randint1(i) > 5))
	{
		/* We may keep trying */
		more = TRUE;
		flush();
		msg_print("You failed to disarm the chest.");
	}

	/* Failure -- Set off the trap */
	else
	{
		msg_print("You set off a trap!");
		chest_trap(y, x, o_idx);
	}

	/* Result */
	return (more);
}
예제 #15
0
/*
 * Perform the basic "open" command on doors
 *
 * Assume there is no monster blocking the destination
 *
 * Returns TRUE if repeated commands may continue
 */
static bool do_cmd_open_aux(int y, int x)
{
	int i, j;

	bool more = FALSE;


	/* Verify legality */
	if (!do_cmd_open_test(y, x)) return (FALSE);


	/* Jammed door */
	if (cave_feat[y][x] >= FEAT_DOOR_HEAD + 0x08)
	{
		/* Stuck */
		msg_print("The door appears to be stuck.");
	}

	/* Locked door */
	else if (cave_feat[y][x] >= FEAT_DOOR_HEAD + 0x01)
	{
		/* Disarm factor */
		i = p_ptr->state.skills[SKILL_DISARM];

		/* Penalize some conditions */
		if (p_ptr->timed[TMD_BLIND] || no_light()) i = i / 10;
		if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) i = i / 10;

		/* Extract the lock power */
		j = cave_feat[y][x] - FEAT_DOOR_HEAD;

		/* Extract the difficulty XXX XXX XXX */
		j = i - (j * 4);

		/* Always have a small chance of success */
		if (j < 2) j = 2;

		/* Success */
		if (randint0(100) < j)
		{
			/* Message */
			message(MSG_LOCKPICK, 0, "You have picked the lock.");

			/* Open the door */
			cave_set_feat(y, x, FEAT_OPEN);

			/* Update the visuals */
			p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS);

			/* Experience */
			gain_exp(1);
		}

		/* Failure */
		else
		{
			flush();

			/* Message */
			message(MSG_LOCKPICK_FAIL, 0, "You failed to pick the lock.");

			/* We may keep trying */
			more = TRUE;
		}
	}

	/* Closed door */
	else
	{
		/* Open the door */
		cave_set_feat(y, x, FEAT_OPEN);

		/* Update the visuals */
		p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS);

		/* Sound */
		sound(MSG_OPENDOOR);
	}

	/* Result */
	return (more);
}
예제 #16
0
void area25(int damage) {
  int  x,y;
  int  x1,y1;
  int  mon;
  int  i;
  x1 = player.x; y1 = player.y;
  if (x1<2) x1=2; else if (x1>98) x1 = 98;
  if (y1<2) y1=2; else if (y1>98) y1 = 98;
  for (x=x1-2; x<=x1+2; x++)
    for (y=y1-2; y<=y1+2; y++)
      if (player.map[x][y] < 0 || (player.map[x][y]>400 && player.map[x][y]<500)) {
        if (in_arena == 'Y') mon = player.map[x][y] - 400;
          else mon = player.map[x][y];
        i = 90;
        if (in_arena == 'Y' && player.monster[mon][a_mon].special == 1) i = 0;
        if (in_arena != 'Y' && player.monster[1][mon].special == 1) i = 0;
        if (u_random(100) < i) {
          clear_prompt();
          noise(1000,100);
          prompt("HIT !!!");
          if (in_arena != 'Y' && player.monster[1][mon].special > 9) {
            player.align -= 20;
            player.monster[1][mon].special -= 10;
            if (player.align < 0) player.align = 0;
            }
          if (in_arena == 'Y' && player.monster[mon][a_mon].special > 9) {
            player.align -= 20;
            player.monster[mon][a_mon].special -= 10;
            if (player.align < 0) player.align = 0;
            }
          if (in_sight(x,y) == '*') {
            show_sprite(x-player.map_x,y-player.map_y,80);
            delay(250);
            show_spot(x,y);
            }
          i = u_random(damage) + 1;
          if (in_arena == 'Y') player.monster[mon][a_mon].hp -= i;
            else player.monster[1][mon].hp -= i;
          if (in_arena == 'Y') i=player.monster[mon][a_mon].hp;
            else i=player.monster[1][mon].hp;
          if (i <= 0) {
            clear_prompt();
            if (in_arena != 'Y') {
              gain_exp(player.monster[1][mon].exp);
              player.map[x][y] = player.monster[1][mon].prev;
              }
            if (in_arena == 'Y') {
              gain_exp(player.monster[mon][a_mon].exp);
              player.map[x][y] = player.monster[mon][a_mon].prev;
              }
            show_spot(x,y);
            if (in_arena != 'Y' && player.monster[1][mon].special > 9) {
              player.align -= 20;
              if (player.align < 0) player.align = 0;
              }
            if (in_arena == 'Y' && player.monster[mon][a_mon].special > 9) {
              player.align -= 20;
              if (player.align < 0) player.align = 0;
              }
            show_side();
            }
    
          }
        else {
          clear_prompt();
          prompt("Fizzle. . .");
          }
        }
  }
예제 #17
0
파일: wizard2.c 프로젝트: naota/hengband
/*!
 * @brief デバッグコマンドを選択する処理のメインルーチン /
 * Ask for and parse a "debug command"
 * The "command_arg" may have been set.
 * @return なし
 */
void do_cmd_debug(void)
{
	int     x, y, i;
	char    cmd;


	/* Get a "debug command" */
	get_com("Debug Command: ", &cmd, FALSE);

	/* Analyze the command */
	switch (cmd)
	{
	/* Nothing */
	case ESCAPE:
	case ' ':
	case '\n':
	case '\r':
		break;

#ifdef ALLOW_SPOILERS

	/* Hack -- Generate Spoilers */
	case '"':
		do_cmd_spoilers();
		break;

#endif /* ALLOW_SPOILERS */

	/* Hack -- Help */
	case '?':
		do_cmd_help();
		break;

	/* Cure all maladies */
	case 'a':
		do_cmd_wiz_cure_all();
		break;

	/* Know alignment */
	case 'A':
		msg_format("Your alignment is %d.", p_ptr->align);
		break;

	/* Teleport to target */
	case 'b':
		do_cmd_wiz_bamf();
		break;

	case 'B':
		battle_monsters();
		break;

	/* Create any object */
	case 'c':
		wiz_create_item();
		break;

	/* Create a named artifact */
	case 'C':
		wiz_create_named_art();
		break;

	/* Detect everything */
	case 'd':
		detect_all(DETECT_RAD_ALL * 3);
		break;

	/* Dimension_door */
	case 'D':
		wiz_dimension_door();
		break;

	/* Edit character */
	case 'e':
		do_cmd_wiz_change();
		break;

	/* Blue Mage Only */
	case 'E':
		if (p_ptr->pclass == CLASS_BLUE_MAGE)
		{
			do_cmd_wiz_blue_mage();
		}
		break;

	/* View item info */
	case 'f':
		identify_fully(FALSE);
		break;

	/* Create desired feature */
	case 'F':
		do_cmd_wiz_create_feature();
		break;

	/* Good Objects */
	case 'g':
		if (command_arg <= 0) command_arg = 1;
		acquirement(p_ptr->y, p_ptr->x, command_arg, FALSE, FALSE, TRUE);
		break;

	/* Hitpoint rerating */
	case 'h':
		do_cmd_rerate(TRUE);
		break;

#ifdef MONSTER_HORDES
	case 'H':
		do_cmd_summon_horde();
		break;
#endif /* MONSTER_HORDES */

	/* Identify */
	case 'i':
		(void)ident_spell(FALSE);
		break;

	/* Go up or down in the dungeon */
	case 'j':
		do_cmd_wiz_jump();
		break;

	/* Self-Knowledge */
	case 'k':
		self_knowledge();
		break;

	/* Learn about objects */
	case 'l':
		do_cmd_wiz_learn();
		break;

	/* Magic Mapping */
	case 'm':
		map_area(DETECT_RAD_ALL * 3);
		break;

	/* Mutation */
	case 'M':
		(void)gain_random_mutation(command_arg);
		break;

	/* Reset Class */
	case 'R':
		(void)do_cmd_wiz_reset_class();
		break;

	/* Specific reward */
	case 'r':
		(void)gain_level_reward(command_arg);
		break;

	/* Summon _friendly_ named monster */
	case 'N':
		do_cmd_wiz_named_friendly(command_arg);
		break;

	/* Summon Named Monster */
	case 'n':
		do_cmd_wiz_named(command_arg);
		break;

	/* Dump option bits usage */
	case 'O':
		do_cmd_dump_options();
		break;

	/* Object playing routines */
	case 'o':
		do_cmd_wiz_play();
		break;

	/* Phase Door */
	case 'p':
		teleport_player(10, 0L);
		break;

	/* Complete a Quest -KMW- */
	case 'q':
		if(p_ptr->inside_quest)
		{
			if (quest[p_ptr->inside_quest].status == QUEST_STATUS_TAKEN)
			{
				complete_quest(p_ptr->inside_quest);
				break;
			}
		}
		else
		{
			msg_print("No current quest");
			msg_print(NULL);
		}
		break;

	/* Make every dungeon square "known" to test streamers -KMW- */
	case 'u':
		for (y = 0; y < cur_hgt; y++)
		{
			for (x = 0; x < cur_wid; x++)
			{
				cave[y][x].info |= (CAVE_GLOW | CAVE_MARK);
			}
		}
		wiz_lite(FALSE);
		break;

	/* Summon Random Monster(s) */
	case 's':
		if (command_arg <= 0) command_arg = 1;
		do_cmd_wiz_summon(command_arg);
		break;

	/* Special(Random Artifact) Objects */
	case 'S':
		if (command_arg <= 0) command_arg = 1;
		acquirement(p_ptr->y, p_ptr->x, command_arg, TRUE, TRUE, TRUE);
		break;

	/* Teleport */
	case 't':
		teleport_player(100, 0L);
		break;

	/* Very Good Objects */
	case 'v':
		if (command_arg <= 0) command_arg = 1;
		acquirement(p_ptr->y, p_ptr->x, command_arg, TRUE, FALSE, TRUE);
		break;

	/* Wizard Light the Level */
	case 'w':
		wiz_lite((bool)(p_ptr->pclass == CLASS_NINJA));
		break;

	/* Increase Experience */
	case 'x':
		gain_exp(command_arg ? command_arg : (p_ptr->exp + 1));
		break;

	/* Zap Monsters (Genocide) */
	case 'z':
		do_cmd_wiz_zap();
		break;

	/* Zap Monsters (Omnicide) */
	case 'Z':
		do_cmd_wiz_zap_all();
		break;

	/* Hack -- whatever I desire */
	case '_':
		do_cmd_wiz_hack_ben();
		break;

	/* Not a Wizard Command */
	default:
		msg_print("That is not a valid debug command.");
		break;
	}
}
예제 #18
0
/* Cast the specified spell */
bool spell_cast(int spell, int dir)
{
    int chance;
    int plev = p_ptr->lev;
    bool failed = FALSE;
    int py = p_ptr->py;
    int px = p_ptr->px;

    /* Get the spell */
    const magic_type *mt_ptr = &mp_ptr->info[spell];

    /* Spell failure chance */
    chance = spell_chance(spell);

    /* Specialty Ability */
    if (player_has(PF_HEIGHTEN_MAGIC))
	plev += 1 + ((p_ptr->heighten_power + 5) / 10);
    if (player_has(PF_CHANNELING))
	plev += get_channeling_boost();

    /* Failed spell */
    if (randint0(100) < chance) {
	failed = TRUE;

	if (OPT(flush_failure))
	    flush();
	msg(magic_desc[mp_ptr->spell_realm][SPELL_FAIL]);
    }

    /* Process spell */
    else {
	/* Cast the spell */
	if (!cast_spell(mp_ptr->spell_book, mt_ptr->index, dir, plev))
	    return FALSE;

	/* A spell was cast */
	sound(MSG_SPELL);


	/* A spell was cast or a prayer prayed */
	if (!(p_ptr->spell_flags[spell] & PY_SPELL_WORKED)){
	    int e = mt_ptr->sexp;

	    /* The spell worked */
	    p_ptr->spell_flags[spell] |= PY_SPELL_WORKED;

	    /* Gain experience */
	    gain_exp(e * mt_ptr->slevel);
	    
	    /* Redraw object recall */
	    p_ptr->redraw |= (PR_OBJECT);
	}
    }

    /* Hack - simplify rune of mana calculations by fully draining the rune
     * first */
    if (cave_trap_specific(py, px, RUNE_MANA) && 
	(mana_reserve <= mt_ptr->smana)	&& (mt_ptr->index != 60)) 
    {
	p_ptr->csp += mana_reserve;
	mana_reserve = 0;
    }

    /* Rune of mana can take less mana than specified */
    if (mt_ptr->index == 60) {
	/* Standard mana amount */
	int mana = 40;

	/* Already full? */
	if (mana_reserve >= MAX_MANA_RESERVE) {
	    /* Use no mana */
	    mana = 0;
	}

	/* Don't put in more than we have */
	else if (p_ptr->csp < mana)
	    mana = p_ptr->csp;

	/* Don't put in more than it will hold */
	if (mana_reserve + mana > MAX_MANA_RESERVE)
	    mana = MAX_MANA_RESERVE - mana_reserve;

	/* Deduct */
	p_ptr->csp -= mana;
    }

    /* Use mana from a rune if possible */
    else if (cave_trap_specific(py, px, RUNE_MANA)
	     && (mana_reserve > mt_ptr->smana)) {
	mana_reserve -= mt_ptr->smana;
    }

    /* Sufficient mana */
    else if (mt_ptr->smana <= p_ptr->csp) {
	/* Use some mana */
	p_ptr->csp -= mt_ptr->smana;

	/* Specialty ability Harmony */
	if ((failed == FALSE) & (player_has(PF_HARMONY))) {
	    int frac, boost;

	    /* Percentage of max hp to be regained */
	    frac = 3 + (mt_ptr->smana / 3);

	    /* Cap at 10 % */
	    if (frac > 10)
		frac = 10;

	    /* Calculate fractional bonus */
	    boost = (frac * p_ptr->mhp) / 100;

	    /* Apply bonus */
	    (void) hp_player(boost);
	}
    }

    /* Over-exert the player */
    else {
	int oops = mt_ptr->smana - p_ptr->csp;

	/* No mana left */
	p_ptr->csp = 0;
	p_ptr->csp_frac = 0;

	/* Message */
	if (mp_ptr->spell_realm == REALM_NECROMANTIC)
	    msg("You collapse after the ritual!");
	else
	    msg("You faint from the effort!");

	/* Hack -- Bypass free action */
	(void) inc_timed(TMD_PARALYZED, randint1(5 * oops + 1), TRUE);

	/* Damage CON (possibly permanently) */
	if (randint0(100) < 50) {
	    bool perm = (randint0(100) < 25);

	    /* Message */
	    msg("You have damaged your health!");

	    /* Reduce constitution */
	    (void) dec_stat(A_CON, 15 + randint1(10), perm);
	}
    }


    /* Redraw mana */
    p_ptr->redraw |= (PR_MANA);

    return TRUE;
}
예제 #19
0
/*
 * Destroy an item
 */
void do_cmd_destroy(void)
{
    int          item, amt = 1;
    int          old_number;
    bool         force = FALSE;
    object_type *o_ptr;
    object_type  forge;
    object_type *q_ptr = &forge;
    bool         is_equipped = FALSE;
    char         o_name[MAX_NLEN];
    char         out_val[MAX_NLEN+40];

    cptr q, s;
    int mode = USE_INVEN | USE_FLOOR;

    if (p_ptr->pclass == CLASS_RUNE_KNIGHT)
        mode |= USE_EQUIP;

    if (p_ptr->special_defense & KATA_MUSOU)
    {
        set_action(ACTION_NONE);
    }

    /* Hack -- force destruction */
    if (command_arg > 0) force = TRUE;


    /* Get an item */
    q = "Destroy which item? ";
    s = "You have nothing to destroy.";

    if (!get_item(&item, q, s, mode)) return;

    /* Get the item (in the pack) */
    if (item >= 0)
    {
        o_ptr = &inventory[item];
        is_equipped = equip_is_valid_slot(item);
    }

    /* Get the item (on the floor) */
    else
    {
        o_ptr = &o_list[0 - item];
    }

    /* Hack for Rune Knight: They can destroy worn equipment, but only
       if it has the Sacrifice rune.  get_item() is not smart enough
       to handle this restriction ... */
    if (is_equipped && o_ptr->rune != RUNE_SACRIFICE)
    {
        msg_print("You must first remove that item before destroying it.");
        return;
    }

    /* Verify unless quantity given beforehand */
    if (!force && (confirm_destroy || (object_value(o_ptr) > 0)))
    {
        object_desc(o_name, o_ptr, OD_OMIT_PREFIX);

        /* Make a verification */
        sprintf(out_val, 
            "Really destroy %s? [y/n/Auto]",
            o_name);

        msg_print(NULL);

        /* HACK : Add the line to message buffer */
        message_add(out_val);
        p_ptr->window |= (PW_MESSAGE);
        window_stuff();

        /* Get an acceptable answer */
        while (TRUE)
        {
            char i;

            /* Prompt */
            prt(out_val, 0, 0);

            i = inkey();

            /* Erase the prompt */
            prt("", 0, 0);


            if (i == 'y' || i == 'Y')
            {
                break;
            }
            if (i == ESCAPE || i == 'n' || i == 'N')
            {
                /* Cancel */
                return;
            }
            if (i == 'A')
            {
                /* Add an auto-destroy preference line */
                if (autopick_autoregister(o_ptr))
                {
                    /* Auto-destroy it */
                    autopick_alter_item(item, TRUE);
                }

                /* The object is already destroyed. */
                return;
            }
        } /* while (TRUE) */
    }

    /* See how many items */
    if (o_ptr->number > 1)
    {
        /* Get a quantity */
        amt = get_quantity(NULL, o_ptr->number);

        /* Allow user abort */
        if (amt <= 0) return;
    }


    /* Describe the object */
    old_number = o_ptr->number;
    o_ptr->number = amt;
    object_desc(o_name, o_ptr, 0);
    o_ptr->number = old_number;

    /* Take a turn */
    energy_use = 100;

    /* Artifacts cannot be destroyed */
    if (!can_player_destroy_object(o_ptr))
    {
        energy_use = 0;

        /* Message */
        msg_format("You cannot destroy %s.", o_name);

        /* Done */
        return;
    }

    object_copy(q_ptr, o_ptr);

    stats_on_p_destroy(o_ptr, amt);

    if (prace_is_(RACE_MON_JELLY))
        jelly_eat_object(o_ptr);
    else if (prace_is_(RACE_MON_SWORD) && object_is_melee_weapon(o_ptr))
        sword_absorb_object(o_ptr);
    else if (prace_is_(RACE_MON_RING) && object_is_jewelry(o_ptr))
        ring_absorb_object(o_ptr);
    else
        msg_format("You destroy %s.", o_name);

    if (o_ptr->rune == RUNE_SACRIFICE)
    {
        int add_hp = is_equipped ? p_ptr->mhp : p_ptr->mhp/3;
        int add_sp = is_equipped ? p_ptr->msp : p_ptr->msp/3;

        msg_print("You feel a surge of wondrous power enter your body.");
        
        p_ptr->chp = MIN(p_ptr->mhp, p_ptr->chp + add_hp);
        p_ptr->chp_frac = 0;
        p_ptr->csp = MIN(p_ptr->msp, p_ptr->csp + add_sp);
        p_ptr->csp_frac = 0;

        p_ptr->redraw |= (PR_MANA);
        p_ptr->window |= (PW_PLAYER);
        p_ptr->window |= (PW_SPELL);
        p_ptr->redraw |= (PR_HP);

        if (is_equipped)
        {
            blast_object(o_ptr);
            o_ptr->curse_flags = TRC_HEAVY_CURSE;
        }
    }
    else if (is_equipped)
        blast_object(o_ptr);

    sound(SOUND_DESTITEM);

    /* Reduce the charges of rods/wands */
    reduce_charges(o_ptr, amt);

    /* Eliminate the item (from the pack) */
    if (item >= 0)
    {
        if (!is_equipped)
        {
            inven_item_increase(item, -amt);
            inven_item_describe(item);
            inven_item_optimize(item);
        }
    }

    /* Eliminate the item (from the floor) */
    else
    {
        floor_item_increase(0 - item, -amt);
        floor_item_describe(0 - item);
        floor_item_optimize(0 - item);
    }

    if ( p_ptr->pclass == CLASS_NECROMANCER
      && (q_ptr->tval == TV_LIFE_BOOK || q_ptr->tval == TV_CRUSADE_BOOK) )
    {
        int sp = 0;
        int osp = p_ptr->csp;
        switch (q_ptr->sval)
        {
        case 0: sp = 10; break;
        case 1: sp = 25; break;
        case 2: sp = 100; break;
        case 3: sp = 666; break;
        }

        p_ptr->csp += sp;
        if (p_ptr->csp >= p_ptr->msp)
        {
            p_ptr->csp = p_ptr->msp;
            p_ptr->csp_frac = 0;
        }

        if (p_ptr->csp > osp)
            msg_print("You feel your head clear.");

        p_ptr->redraw |= (PR_MANA);
    }

    if (high_level_book(q_ptr))
    {
        bool gain_expr = FALSE;

        if (p_ptr->prace == RACE_ANDROID)
        {
        }
        else if ((p_ptr->pclass == CLASS_WARRIOR) || (p_ptr->pclass == CLASS_BERSERKER))
        {
            gain_expr = TRUE;
        }
        else if (p_ptr->pclass == CLASS_PALADIN)
        {
            if (is_good_realm(p_ptr->realm1))
            {
                if (!is_good_realm(tval2realm(q_ptr->tval))) gain_expr = TRUE;
            }
            else
            {
                if (is_good_realm(tval2realm(q_ptr->tval))) gain_expr = TRUE;
            }
        }

        if (gain_expr && (p_ptr->exp < PY_MAX_EXP))
        {
            s32b tester_exp = p_ptr->max_exp / 20;
            if (tester_exp > 10000) tester_exp = 10000;
            if (q_ptr->sval < 3) tester_exp /= 4;
            if (tester_exp<1) tester_exp = 1;

            msg_print("You feel more experienced.");
            gain_exp(tester_exp * amt);
        }
    }

    if (high_level_book(q_ptr) && q_ptr->tval == TV_LIFE_BOOK)
    {
        virtue_add(VIRTUE_UNLIFE, 1);
        virtue_add(VIRTUE_VITALITY, -1);
    }
    else if ( high_level_book(q_ptr) 
           && (q_ptr->tval == TV_DEATH_BOOK || q_ptr->tval == TV_NECROMANCY_BOOK) )
    {
        virtue_add(VIRTUE_UNLIFE, -1);
        virtue_add(VIRTUE_VITALITY, 1);
    }    

    if (q_ptr->to_a || q_ptr->to_h || q_ptr->to_d)
        virtue_add(VIRTUE_ENCHANTMENT, -1);
    
    if (object_value_real(q_ptr) > 30000)
        virtue_add(VIRTUE_SACRIFICE, 2);
    
    else if (object_value_real(q_ptr) > 10000)
        virtue_add(VIRTUE_SACRIFICE, 1);

    if (q_ptr->to_a != 0 || q_ptr->to_d != 0 || q_ptr->to_h != 0)
        virtue_add(VIRTUE_HARMONY, 1);

    if (equip_is_valid_slot(item)) 
        calc_android_exp();
}
예제 #20
0
파일: spell.c 프로젝트: apwhite/angband
/* Cas the specified spell */
bool spell_cast(int spell, int dir)
{
	int chance;

	/* Get the spell */
	const magic_type *s_ptr = &mp_ptr->info[spell];	

	/* Spell failure chance */
	chance = spell_chance(spell);

	/* Failed spell */
	if (randint0(100) < chance)
	{
		flush();
		msg("You failed to concentrate hard enough!");
	}

	/* Process spell */
	else
	{
		/* Cast the spell */
		if (!cast_spell(cp_ptr->spell_book, spell, dir)) return FALSE;

		/* A spell was cast */
		sound(MSG_SPELL);

		if (!(p_ptr->spell_flags[spell] & PY_SPELL_WORKED))
		{
			int e = s_ptr->sexp;

			/* The spell worked */
			p_ptr->spell_flags[spell] |= PY_SPELL_WORKED;

			/* Gain experience */
			gain_exp(e * s_ptr->slevel);

			/* Redraw object recall */
			p_ptr->redraw |= (PR_OBJECT);
		}
	}

	/* Sufficient mana */
	if (s_ptr->smana <= p_ptr->csp)
	{
		/* Use some mana */
		p_ptr->csp -= s_ptr->smana;
	}

	/* Over-exert the player */
	else
	{
		int oops = s_ptr->smana - p_ptr->csp;

		/* No mana left */
		p_ptr->csp = 0;
		p_ptr->csp_frac = 0;

		/* Message */
		msg("You faint from the effort!");

		/* Hack -- Bypass free action */
		(void)inc_timed(TMD_PARALYZED, randint1(5 * oops + 1), TRUE);

		/* Damage CON (possibly permanently) */
		if (randint0(100) < 50)
		{
			bool perm = (randint0(100) < 25);

			/* Message */
			msg("You have damaged your health!");

			/* Reduce constitution */
			player_stat_dec(p_ptr, A_CON, perm);
		}
	}

	/* Redraw mana */
	p_ptr->redraw |= (PR_MANA);

	return TRUE;
}
예제 #21
0
파일: magic.c 프로젝트: nawglan/ShadowWind
int mag_points_char(struct spell_info_type *sinfo, struct char_data *caster, struct char_data *vict, int level)
{
  int modifier = dice(sinfo->num_dice, sinfo->size_dice);

  if (sinfo->unaffect)
    modifier = -modifier;

  modifier = modBySpecialization(caster, sinfo, modifier);
  gain_exp(caster, modifier * 2);
  switch (sinfo->point_loc) {
    case APPLY_AGE:
      vict->player.time.birth += (SECS_PER_MUD_YEAR * modifier);
      break;
    case APPLY_STR:
      GET_VSTR(vict) += modifier;
      GET_STR(vict) = MIN(100, GET_VSTR(vict));
      break;
    case APPLY_DEX:
      GET_VDEX(vict) += modifier;
      GET_DEX(vict) = MIN(100, GET_VDEX(vict));
      break;
    case APPLY_INT:
      GET_VINT(vict) += modifier;
      GET_INT(vict) = MIN(100, GET_VINT(vict));
      break;
    case APPLY_WIS:
      GET_VWIS(vict) += modifier;
      GET_WIS(vict) = MIN(100, GET_VWIS(vict));
      break;
    case APPLY_CON:
      GET_VCON(vict) += modifier;
      GET_CON(vict) = MIN(100, GET_VCON(vict));
      break;
    case APPLY_AGI:
      GET_VAGI(vict) += modifier;
      GET_AGI(vict) = MIN(100, GET_VAGI(vict));
      break;
    case APPLY_MANA:
      GET_MANA(vict) += modifier;
      if (GET_MANA(vict) > GET_MAX_MANA(vict))
        GET_MANA(vict) = GET_MAX_MANA(vict);
      break;
    case APPLY_HIT:
      GET_HIT(vict) += modifier;
      if (GET_HIT(vict) > GET_MAX_HIT(vict))
        GET_HIT(vict) = GET_MAX_HIT(vict);
      break;
    case APPLY_MOVE:
      GET_MOVE(vict) += modifier;
      if (GET_MOVE(vict) > GET_MAX_MOVE(vict))
        GET_MOVE(vict) = GET_MAX_MOVE(vict);
      break;
    case APPLY_HITROLL:
      GET_HITROLL(vict) += modifier;
      break;
    case APPLY_DAMROLL:
      GET_DAMROLL(vict) += modifier;
      break;
    case APPLY_SAVING_PARA:
      GET_SAVE(vict,SAVING_PARA) += modifier;
      break;
    case APPLY_SAVING_ROD:
      GET_SAVE(vict,SAVING_ROD) += modifier;
      break;
    case APPLY_SAVING_PETRI:
      GET_SAVE(vict,SAVING_PETRI) += modifier;
      break;
    case APPLY_SAVING_BREATH:
      GET_SAVE(vict,SAVING_BREATH) += modifier;
      break;
    case APPLY_SAVING_SPELL:
      GET_SAVE(vict,SAVING_SPELL) += modifier;
      break;
    case APPLY_MAX_HIT:
      GET_MAX_HIT(vict) += modifier;
      break;
    case APPLY_MAX_MANA:
      GET_MAX_MANA(vict) += modifier;
      break;
    case APPLY_MAX_MOVE:
      GET_MAX_MOVE(vict) += modifier;
      break;
    case APPLY_RES_DARK:
      GET_RESIST(vict, DAM_DARK) += modifier;
      break;
    case APPLY_RES_FIRE:
      GET_RESIST(vict, DAM_FIRE) += modifier;
      break;
    case APPLY_RES_COLD:
      GET_RESIST(vict, DAM_COLD) += modifier;
      break;
    case APPLY_RES_ACID:
      GET_RESIST(vict, DAM_ACID) += modifier;
      break;
    case APPLY_RES_POISON:
      GET_RESIST(vict, DAM_POISON) += modifier;
      break;
    case APPLY_RES_DISEASE:
      GET_RESIST(vict, DAM_DISEASE) += modifier;
      break;
    case APPLY_RES_CHARM:
      GET_RESIST(vict, DAM_CHARM) += modifier;
      break;
    case APPLY_RES_SLEEP:
      GET_RESIST(vict, DAM_SLEEP) += modifier;
      break;
    case APPLY_RES_SLASH:
      GET_RESIST(vict, DAM_SLASH) += modifier;
      break;
    case APPLY_RES_PIERCE:
      GET_RESIST(vict, DAM_PIERCE) += modifier;
      break;
    case APPLY_RES_BLUDGEON:
      GET_RESIST(vict, DAM_BLUDGEON) += modifier;
      break;
    case APPLY_RES_NWEAP:
      GET_RESIST(vict, DAM_NWEAP) += modifier;
      break;
    case APPLY_RES_MWEAP:
      GET_RESIST(vict, DAM_MWEAP) += modifier;
      break;
    case APPLY_RES_MAGIC:
      GET_RESIST(vict, DAM_MAGIC) += modifier;
      break;
    case APPLY_RES_ELECTRICITY:
      GET_RESIST(vict, DAM_ELECTRICITY) += modifier;
      break;
  }
  return 1;
}
예제 #22
0
파일: magic.c 프로젝트: nawglan/ShadowWind
int mag_affect_char(struct spell_info_type *sinfo, int affect_flag, struct char_data *caster, struct char_data *vict, int level)
{
  struct affected_type af;
  int i;
  int spell = 0;
  int unaffect = 0;
  int circle = (level + 4) / 5;

  /* innate */
  if (level == -1) {
    SET_BIT(AFF_FLAGS(vict), affect_flag);
    return 1;
  }

  if (sinfo->unaffect) {
    spell = spells[find_spell_num(sinfo->unaffect)].spellindex;
    unaffect = 1;
  }

  if (!unaffect) {
    af.type = sinfo->spellindex;
    af.bitvector = sinfo->spell_plr_bit;
    af.bitvector2 = sinfo->spell_plr_bit2;
    af.bitvector3 = sinfo->spell_plr_bit3;

    if (sinfo->spell_duration)
      af.duration = sinfo->spell_duration * 12;
    else
      af.duration = (SECS_PER_MUD_HOUR * level) / 15; /* level/3 mud hours duration */

    af.duration = modBySpecialization(caster, sinfo, af.duration);
    gain_exp(caster, af.duration * 2);
    if (strcmp(sinfo->command, "stoneskin") == 0)
      af.duration = level * 5;
    for (i = 0; i < NUM_MODIFY; i++) {
      af.modifier[i] = 0;
      af.location[i] = 0;
    }

    for (i = 0; i < NUM_MODIFY; i++) {
      if (sinfo->plr_aff[i].location) {
        if (strcmp(sinfo->command, "vitality") == 0 || strcmp(sinfo->command, "vigorize") == 0)
          af.modifier[i] = (sinfo->plr_aff[i].modifier * level);
        else if (strcmp(sinfo->command, "barkskin") == 0) {
          af.modifier[i] = (sinfo->plr_aff[i].modifier - (3.5 * circle));
        } else
          af.modifier[i] = sinfo->plr_aff[i].modifier;
        af.location[i] = sinfo->plr_aff[i].location;
      }
    }
    if (IS_NPC(vict) && IS_AFFECTED(vict, sinfo->spell_plr_bit) && IS_AFFECTED2(vict, sinfo->spell_plr_bit2) && IS_AFFECTED3(vict, sinfo->spell_plr_bit3) && !affected_by_spell(vict, sinfo->spellindex))
      return 0;

    if (affected_by_spell(vict, sinfo->spellindex) && !(sinfo->accum_duration || sinfo->accum_affect))
      return 0;

    affect_join(vict, &af, sinfo->accum_duration, sinfo->avg_duration, sinfo->accum_affect, sinfo->avg_affect);
  } else {
    if (affected_by_spell(vict, sinfo->spellindex) && !(sinfo->accum_duration || sinfo->accum_affect))
      return 0;
    affect_from_char(vict, spell);
  }
  return 1;
}
예제 #23
0
/*
 * Ask for and parse a "debug command"
 *
 * The "p_ptr->command_arg" may have been set.
 */
void do_cmd_debug(void)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	char cmd;


	/* Get a "debug command" */
	if (!get_com("Debug Command: ", &cmd)) return;

	/* Analyze the command */
	switch (cmd)
	{
		/* Ignore */
		case ESCAPE:
		case ' ':
		case '\n':
		case '\r':
		{
			break;
		}

#ifdef ALLOW_SPOILERS

		/* Hack -- Generate Spoilers */
		case '"':
		{
			do_cmd_spoilers();
			break;
		}

#endif


		/* Hack -- Help */
		case '?':
		{
			do_cmd_help();
			break;
		}

		/* Cure all maladies */
		case 'a':
		{
			do_cmd_wiz_cure_all();
			break;
		}

		/* Teleport to target */
		case 'b':
		{
			do_cmd_wiz_bamf();
			break;
		}

		/* Create any object */
		case 'c':
		{
			wiz_create_item();
			break;
		}

		/* Create an artifact */
		case 'C':
		{
			wiz_create_artifact(p_ptr->command_arg);
			break;
		}

		/* Detect everything */
		case 'd':
		{
			detect_all();
			break;
		}

		/* Edit character */
		case 'e':
		{
			do_cmd_wiz_change();
			break;
		}

		/* View item info */
		case 'f':
		{
			(void)identify_fully();
			break;
		}

		/* Good Objects */
		case 'g':
		{
			if (p_ptr->command_arg <= 0) p_ptr->command_arg = 1;
			acquirement(py, px, p_ptr->command_arg, FALSE);
			break;
		}

		/* Hitpoint rerating */
		case 'h':
		{
			do_cmd_rerate();
			break;
		}

		/* Identify */
		case 'i':
		{
			(void)ident_spell();
			break;
		}

		/* Go up or down in the dungeon */
		case 'j':
		{
			do_cmd_wiz_jump();
			break;
		}

		/* Self-Knowledge */
		case 'k':
		{
			self_knowledge();
			break;
		}

		/* Learn about objects */
		case 'l':
		{
			do_cmd_wiz_learn();
			break;
		}

		/* Magic Mapping */
		case 'm':
		{
			map_area();
			break;
		}

		/* Summon Named Monster */
		case 'n':
		{
			do_cmd_wiz_named(p_ptr->command_arg, TRUE);
			break;
		}

		/* Object playing routines */
		case 'o':
		{
			do_cmd_wiz_play();
			break;
		}

		/* Phase Door */
		case 'p':
		{
			teleport_player(10);
			break;
		}

		/* Query the dungeon */
		case 'q':
		{
			do_cmd_wiz_query();
			break;
		}

		/* Summon Random Monster(s) */
		case 's':
		{
			if (p_ptr->command_arg <= 0) p_ptr->command_arg = 1;
			do_cmd_wiz_summon(p_ptr->command_arg);
			break;
		}

		/* Teleport */
		case 't':
		{
			teleport_player(100);
			break;
		}

		/* Un-hide all monsters */
		case 'u':
		{
			if (p_ptr->command_arg <= 0) p_ptr->command_arg = 255;
			do_cmd_wiz_unhide(p_ptr->command_arg);
			break;
		}

		/* Very Good Objects */
		case 'v':
		{
			if (p_ptr->command_arg <= 0) p_ptr->command_arg = 1;
			acquirement(py, px, p_ptr->command_arg, TRUE);
			break;
		}

		/* Wizard Light the Level */
		case 'w':
		{
			wiz_lite();
			break;
		}

		/* Increase Experience */
		case 'x':
		{
			if (p_ptr->command_arg)
			{
				gain_exp(p_ptr->command_arg);
			}
			else
			{
				gain_exp(p_ptr->exp + 1);
			}
			break;
		}

		/* Zap Monsters (Genocide) */
		case 'z':
		{
			if (p_ptr->command_arg <= 0) p_ptr->command_arg = MAX_SIGHT;
			do_cmd_wiz_zap(p_ptr->command_arg);
			break;
		}

		/* Oops */
		default:
		{
			msg_print("That is not a valid debug command.");
			break;
		}
	}
}
예제 #24
0
/* Used to update where people are in the quest */
void update_chquest( CHAR_DATA *ch, QUEST_DATA * quest, int nchapter )
{
    CHQUEST_DATA           *chquest;
    CHAP_DATA              *chapter;
    int                     mins,
                            seconds;
    bool                    skipped = FALSE;

    if ( !quest || !ch || !ch->pcdata )
        return;

    for ( chquest = ch->pcdata->first_quest; chquest; chquest = chquest->next ) {
        if ( chquest->questnum == quest->number )
            break;
    }

    /*
     * If no quest need to start it for them 
     */
    if ( !chquest ) {
        if ( nchapter != 1 ) {
            send_to_char( "&GYou have to do the quest in order. Check your &WJOURNAL&D.\r\n", ch );
            return;
        }
        chapter = get_chap_from_quest( 1, quest );
        if ( !chapter ) {
            send_to_char
                ( "For now this is all you can do on this quest. Try back another time.\r\n", ch );
            return;
        }
        CREATE( chquest, CHQUEST_DATA, 1 );
        chquest->questnum = quest->number;
        chquest->questlimit = quest->timelimit;
        chquest->progress = 1;
        chquest->times = 1;
        chquest->kamount = 0;
        chquest->chaplimit = chapter->timelimit;
        link_chquest( ch, chquest );
        send_to_char( "\r\n&G¡has iniciado un nuevo quest!&D\r\n", ch );

        if ( xIS_SET( ch->act, PLR_BATTLE ) )
            send_to_char( "!!SOUND(sound/quest.wav)\r\n", ch );

        send_to_char( "&GTeclea &WDIARIO &Gpara ver más información sobre el quest.&D\r\n", ch );
        if ( chquest->chaplimit > 0 )
            ch_printf( ch, "&RTienes %s para finalizar este capítulo.&D\r\n",
                       show_timeleft( chquest->chaplimit ) );
        if ( chquest->questlimit > 0 )
            ch_printf( ch, "&RTienes %s para finalizar el quest.&D\r\n",
                       show_timeleft( chquest->questlimit ) );
        return;
    }

    if ( !quest->skipchapters ) {
        if ( nchapter != ( chquest->progress + 1 ) ) {
            send_to_char( "&GTienes que hacer el quest en orden. Mira tu &WDIARIO&D.\r\n", ch );
            return;
        }

        /*
         * Ok so we have the chquest so lets increase it 
         */
        ++chquest->progress;
    }
    else {
        chquest->progress = nchapter;                  /* If we skip need to set it to
                                                        * the new chapter */
        skipped = TRUE;
    }

    /*
     * Ok redoing it? 
     */
    if ( chquest->progress == 1 ) {
        int                     times = chquest->times;

        chapter = get_chap_from_quest( 1, quest );
        if ( !chapter ) {
            send_to_char
                ( "Por ahora no puedes hacer más. Inténtalo más tarde.\r\n", ch );
            return;
        }

        chquest->questlimit = quest->timelimit;
        chquest->chaplimit = chapter->timelimit;
        chquest->kamount = 0;
        send_to_char( "\r\n&G¡Has iniciado un nuevo quest!&D\r\n", ch );
        send_to_char( "&GTeclea &WDIARIO &para más información sobre el quest.&D\r\n", ch );
        if ( chquest->chaplimit > 0 )
            ch_printf( ch, "&RTienes %s para finalizar el capítulo.&D\r\n",
                       show_timeleft( chquest->chaplimit ) );
        if ( chquest->questlimit > 0 )
            ch_printf( ch, "&RTienes %s para finalizar el capítulo.&D\r\n",
                       show_timeleft( chquest->questlimit ) );
        ch_printf( ch, "&Bhas intentado este quest %d %s&D\r\n", times,
                   times >= 5 ? "veces!" : times == 1 ? "veces." : "vez." );
        chquest->times++;
        return;
    }

    /*
     * Was this the end of the quest? 
     */
    if ( chquest->progress == ( quest->chapters + 1 ) ) {
        send_to_char( "&G¡has finalizado tu quest!&D\r\n", ch );
        if ( quest->glory == 1 ) {
            ch->quest_curr += ( quest->level + get_curr_con( ch ) );
            ch->quest_accum += ( quest->level + get_curr_con( ch ) );
            ch_printf( ch, "&YGanas %d puntos de gloria.&D\r\n",
                       quest->level + get_curr_con( ch ) );
            gain_exp( ch, 0 + ch->level * 100 + quest->level * 2000 );
        }
        else {
            gain_exp( ch, 0 + ch->level * 100 + quest->level * 2000 );
        }
        if ( ch->pcdata->clan ) {
            CLAN_DATA              *clan;

            clan = ch->pcdata->clan;
            ch->pcdata->clanpoints += 1;
            clan->totalpoints += 1;
            ch_printf( ch,
                       "&G%s ha ganado 1 punto por tu quest, ¡ahora tiene %d puntos de clan!\r\n",
                       clan->name, clan->totalpoints );
            save_clan( clan );
        }

        if ( chquest->questlimit )
            ch_printf( ch, "&RTenías %s cuando completaste tu quest.&D\r\n",
                       show_timeleft( chquest->questlimit ) );
        chquest->chaplimit = 0;
        chquest->questlimit = 0;
        chquest->kamount = 0;
        return;
    }

    chapter = get_chap_from_quest( chquest->progress, quest );
    if ( !chapter ) {
        send_to_char( "Por ahora no puedes hacer más en este quest. Inténtalo más tarde.\r\n",
                      ch );
        return;
    }

    chquest->chaplimit = chapter->timelimit;
    chquest->kamount = 0;

    /*
     * If they aren't skipping show this message 
     */
//   if( !quest->skipchapters && skipped )
    send_to_char( "&Continúas el quest, teclea &WDIARIO &para ver qué sigue.&D\r\n", ch );

    if ( chquest->chaplimit > 0 )
        ch_printf( ch, "&RTienes %s para finalizar el capítulo.&D\r\n",
                   show_timeleft( chquest->chaplimit ) );
    if ( chquest->questlimit > 0 )
        ch_printf( ch, "&RTienes %s para finalizar el quest.&D\r\n",
                   show_timeleft( chquest->questlimit ) );
}
예제 #25
0
static bool quaff_potion(object_type *o_ptr, bool *ident)
{
	/* Analyze the potion */
	switch (o_ptr->sval)
	{
		case SV_POTION_WATER:
		case SV_POTION_APPLE_JUICE:
		case SV_POTION_SLIME_MOLD:
		{
			msg_print("You feel less thirsty.");
			*ident = TRUE;
			break;
		}

		case SV_POTION_SLOWNESS:
		{
			if (set_slow(p_ptr->slow + randint(25) + 15)) *ident = TRUE;
			break;
		}

		case SV_POTION_SALT_WATER:
		{
			msg_print("The potion makes you vomit!");
			(void)set_food(PY_FOOD_STARVE - 1);
			(void)set_poisoned(0);
			(void)set_paralyzed(p_ptr->paralyzed + 4);
			*ident = TRUE;
			break;
		}

		case SV_POTION_POISON:
		{
			if (!(p_ptr->resist_pois || p_ptr->oppose_pois))
			{
				if (set_poisoned(p_ptr->poisoned + rand_int(15) + 10))
				{
					*ident = TRUE;
				}
			}
			break;
		}

		case SV_POTION_BLINDNESS:
		{
			if (!p_ptr->resist_blind)
			{
				if (set_blind(p_ptr->blind + rand_int(100) + 100))
				{
					*ident = TRUE;
				}
			}
			break;
		}

		case SV_POTION_CONFUSION:
		{
			if (!p_ptr->resist_confu)
			{
				if (set_confused(p_ptr->confused + rand_int(20) + 15))
				{
					*ident = TRUE;
				}
			}
			break;
		}

		case SV_POTION_SLEEP:
		{
			if (!p_ptr->free_act)
			{
				if (set_paralyzed(p_ptr->paralyzed + rand_int(4) + 4))
				{
					*ident = TRUE;
				}
			}
			break;
		}

		case SV_POTION_LOSE_MEMORIES:
		{
			if (!p_ptr->hold_life && (p_ptr->exp > 0))
			{
				msg_print("You feel your memories fade.");
				lose_exp(p_ptr->exp / 4);
				*ident = TRUE;
			}
			break;
		}

		case SV_POTION_RUINATION:
		{
			msg_print("Your nerves and muscles feel weak and lifeless!");
			take_hit(damroll(10, 10), "a potion of Ruination");
			(void)dec_stat(A_DEX, 25, TRUE);
			(void)dec_stat(A_WIS, 25, TRUE);
			(void)dec_stat(A_CON, 25, TRUE);
			(void)dec_stat(A_STR, 25, TRUE);
			(void)dec_stat(A_CHR, 25, TRUE);
			(void)dec_stat(A_INT, 25, TRUE);
			*ident = TRUE;
			break;
		}

		case SV_POTION_DEC_STR:
		{
			if (do_dec_stat(A_STR)) *ident = TRUE;
			break;
		}

		case SV_POTION_DEC_INT:
		{
			if (do_dec_stat(A_INT)) *ident = TRUE;
			break;
		}

		case SV_POTION_DEC_WIS:
		{
			if (do_dec_stat(A_WIS)) *ident = TRUE;
			break;
		}

		case SV_POTION_DEC_DEX:
		{
			if (do_dec_stat(A_DEX)) *ident = TRUE;
			break;
		}

		case SV_POTION_DEC_CON:
		{
			if (do_dec_stat(A_CON)) *ident = TRUE;
			break;
		}

		case SV_POTION_DEC_CHR:
		{
			if (do_dec_stat(A_CHR)) *ident = TRUE;
			break;
		}

		case SV_POTION_DETONATIONS:
		{
			msg_print("Massive explosions rupture your body!");
			take_hit(damroll(50, 20), "a potion of Detonation");
			(void)set_stun(p_ptr->stun + 75);
			(void)set_cut(p_ptr->cut + 5000);
			*ident = TRUE;
			break;
		}

		case SV_POTION_DEATH:
		{
			msg_print("A feeling of Death flows through your body.");
			take_hit(5000, "a potion of Death");
			*ident = TRUE;
			break;
		}

		case SV_POTION_INFRAVISION:
		{
			if (set_tim_infra(p_ptr->tim_infra + 100 + randint(100)))
			{
				*ident = TRUE;
			}
			break;
		}

		case SV_POTION_DETECT_INVIS:
		{
			if (set_tim_invis(p_ptr->tim_invis + 12 + randint(12)))
			{
				*ident = TRUE;
			}
			break;
		}

		case SV_POTION_SLOW_POISON:
		{
			if (set_poisoned(p_ptr->poisoned / 2)) *ident = TRUE;
			break;
		}

		case SV_POTION_CURE_POISON:
		{
			if (set_poisoned(0)) *ident = TRUE;
			break;
		}

		case SV_POTION_BOLDNESS:
		{
			if (set_afraid(0)) *ident = TRUE;
			break;
		}

		case SV_POTION_SPEED:
		{
			if (!p_ptr->fast)
			{
				if (set_fast(randint(25) + 15)) *ident = TRUE;
			}
			else
			{
				(void)set_fast(p_ptr->fast + 5);
			}
			break;
		}

		case SV_POTION_RESIST_HEAT:
		{
			if (set_oppose_fire(p_ptr->oppose_fire + randint(10) + 10))
			{
				*ident = TRUE;
			}
			break;
		}

		case SV_POTION_RESIST_COLD:
		{
			if (set_oppose_cold(p_ptr->oppose_cold + randint(10) + 10))
			{
				*ident = TRUE;
			}
			break;
		}

		case SV_POTION_HEROISM:
		{
			if (hp_player(10)) *ident = TRUE;
			if (set_afraid(0)) *ident = TRUE;
			if (set_hero(p_ptr->hero + randint(25) + 25)) *ident = TRUE;
			break;
		}

		case SV_POTION_BERSERK_STRENGTH:
		{
			if (hp_player(30)) *ident = TRUE;
			if (set_afraid(0)) *ident = TRUE;
			if (set_shero(p_ptr->shero + randint(25) + 25)) *ident = TRUE;
			break;
		}

		case SV_POTION_CURE_LIGHT:
		{
			if (hp_player(damroll(2, 8))) *ident = TRUE;
			if (set_blind(0)) *ident = TRUE;
			if (set_cut(p_ptr->cut - 10)) *ident = TRUE;
			break;
		}

		case SV_POTION_CURE_SERIOUS:
		{
			if (hp_player(damroll(4, 8))) *ident = TRUE;
			if (set_blind(0)) *ident = TRUE;
			if (set_confused(0)) *ident = TRUE;
			if (set_cut((p_ptr->cut / 2) - 50)) *ident = TRUE;
			break;
		}

		case SV_POTION_CURE_CRITICAL:
		{
			if (hp_player(damroll(6, 8))) *ident = TRUE;
			if (set_blind(0)) *ident = TRUE;
			if (set_confused(0)) *ident = TRUE;
			if (set_poisoned(0)) *ident = TRUE;
			if (set_stun(0)) *ident = TRUE;
			if (set_cut(0)) *ident = TRUE;
			break;
		}

		case SV_POTION_HEALING:
		{
			if (hp_player(300)) *ident = TRUE;
			if (set_blind(0)) *ident = TRUE;
			if (set_confused(0)) *ident = TRUE;
			if (set_poisoned(0)) *ident = TRUE;
			if (set_stun(0)) *ident = TRUE;
			if (set_cut(0)) *ident = TRUE;
			break;
		}

		case SV_POTION_STAR_HEALING:
		{
			if (hp_player(1200)) *ident = TRUE;
			if (set_blind(0)) *ident = TRUE;
			if (set_confused(0)) *ident = TRUE;
			if (set_poisoned(0)) *ident = TRUE;
			if (set_stun(0)) *ident = TRUE;
			if (set_cut(0)) *ident = TRUE;
			break;
		}

		case SV_POTION_LIFE:
		{
			msg_print("You feel life flow through your body!");
			restore_level();
			(void)set_poisoned(0);
			(void)set_blind(0);
			(void)set_confused(0);
			(void)set_image(0);
			(void)set_stun(0);
			(void)set_cut(0);
			(void)do_res_stat(A_STR);
			(void)do_res_stat(A_CON);
			(void)do_res_stat(A_DEX);
			(void)do_res_stat(A_WIS);
			(void)do_res_stat(A_INT);
			(void)do_res_stat(A_CHR);

			/* Recalculate max. hitpoints */
			update_stuff();

			hp_player(5000);

			*ident = TRUE;
			break;
		}

		case SV_POTION_RESTORE_MANA:
		{
			if (p_ptr->csp < p_ptr->msp)
			{
				p_ptr->csp = p_ptr->msp;
				p_ptr->csp_frac = 0;
				msg_print("Your feel your head clear.");
				p_ptr->redraw |= (PR_MANA);
				p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1);
				*ident = TRUE;
			}
			break;
		}

		case SV_POTION_RESTORE_EXP:
		{
			if (restore_level()) *ident = TRUE;
			break;
		}

		case SV_POTION_RES_STR:
		{
			if (do_res_stat(A_STR)) *ident = TRUE;
			break;
		}

		case SV_POTION_RES_INT:
		{
			if (do_res_stat(A_INT)) *ident = TRUE;
			break;
		}

		case SV_POTION_RES_WIS:
		{
			if (do_res_stat(A_WIS)) *ident = TRUE;
			break;
		}

		case SV_POTION_RES_DEX:
		{
			if (do_res_stat(A_DEX)) *ident = TRUE;
			break;
		}

		case SV_POTION_RES_CON:
		{
			if (do_res_stat(A_CON)) *ident = TRUE;
			break;
		}

		case SV_POTION_RES_CHR:
		{
			if (do_res_stat(A_CHR)) *ident = TRUE;
			break;
		}

		case SV_POTION_INC_STR:
		{
			if (do_inc_stat(A_STR)) *ident = TRUE;
			break;
		}

		case SV_POTION_INC_INT:
		{
			if (do_inc_stat(A_INT)) *ident = TRUE;
			break;
		}

		case SV_POTION_INC_WIS:
		{
			if (do_inc_stat(A_WIS)) *ident = TRUE;
			break;
		}

		case SV_POTION_INC_DEX:
		{
			if (do_inc_stat(A_DEX)) *ident = TRUE;
			break;
		}

		case SV_POTION_INC_CON:
		{
			if (do_inc_stat(A_CON)) *ident = TRUE;
			break;
		}

		case SV_POTION_INC_CHR:
		{
			if (do_inc_stat(A_CHR)) *ident = TRUE;
			break;
		}

		case SV_POTION_AUGMENTATION:
		{
			if (do_inc_stat(A_STR)) *ident = TRUE;
			if (do_inc_stat(A_INT)) *ident = TRUE;
			if (do_inc_stat(A_WIS)) *ident = TRUE;
			if (do_inc_stat(A_DEX)) *ident = TRUE;
			if (do_inc_stat(A_CON)) *ident = TRUE;
			if (do_inc_stat(A_CHR)) *ident = TRUE;
			break;
		}

		case SV_POTION_ENLIGHTENMENT:
		{
			msg_print("An image of your surroundings forms in your mind...");
			wiz_lite();
			*ident = TRUE;
			break;
		}

		case SV_POTION_STAR_ENLIGHTENMENT:
		{
			msg_print("You begin to feel more enlightened...");
			message_flush();
			wiz_lite();
			(void)do_inc_stat(A_INT);
			(void)do_inc_stat(A_WIS);
			(void)detect_traps();
			(void)detect_doors();
			(void)detect_stairs();
			(void)detect_treasure();
			(void)detect_objects_gold();
			(void)detect_objects_normal();
			identify_pack();
			self_knowledge();
			*ident = TRUE;
			break;
		}

		case SV_POTION_SELF_KNOWLEDGE:
		{
			msg_print("You begin to know yourself a little better...");
			message_flush();
			self_knowledge();
			*ident = TRUE;
			break;
		}

		case SV_POTION_EXPERIENCE:
		{
			if (p_ptr->exp < PY_MAX_EXP)
			{
				s32b ee = (p_ptr->exp / 2) + 10;
				if (ee > 100000L) ee = 100000L;
				msg_print("You feel more experienced.");
				gain_exp(ee);
				*ident = TRUE;
			}
			break;
		}
	}

	return (TRUE);
}
예제 #26
0
/*
 * Perform the basic "disarm" command
 *
 * Assume there is no monster blocking the destination
 *
 * Returns TRUE if repeated commands may continue
 */
static bool do_cmd_disarm_aux(int y, int x)
{
	int i, j, power;

	cptr name;

	bool more = FALSE;


	/* Verify legality */
	if (!do_cmd_disarm_test(y, x)) return (FALSE);


	/* Get the trap name */
	name = f_info[cave_feat[y][x]].name;

	/* Get the "disarm" factor */
	i = p_ptr->state.skills[SKILL_DISARM];

	/* Penalize some conditions */
	if (p_ptr->timed[TMD_BLIND] || no_light()) i = i / 10;
	if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) i = i / 10;

	/* XXX XXX XXX Variable power? */

	/* Extract trap "power" */
	power = 5;

	/* Extract the difficulty */
	j = i - power;

	/* Always have a small chance of success */
	if (j < 2) j = 2;

	/* Success */
	if (randint0(100) < j)
	{
		/* Message */
		message_format(MSG_DISARM, 0, "You have disarmed the %s.", name);

		/* Reward */
		gain_exp(power);

		/* Forget the trap */
		cave_info[y][x] &= ~(CAVE_MARK);

		/* Remove the trap */
		cave_set_feat(y, x, FEAT_FLOOR);
	}

	/* Failure -- Keep trying */
	else if ((i > 5) && (randint1(i) > 5))
	{
		flush();

		/* Message */
		msg_format("You failed to disarm the %s.", name);

		/* We may keep trying */
		more = TRUE;
	}

	/* Failure -- Set off the trap */
	else
	{
		/* Message */
		msg_format("You set off the %s!", name);

		/* Hit the trap */
		hit_trap(y, x);
	}

	/* Result */
	return (more);
}
예제 #27
0
파일: shops.c 프로젝트: smthbh/SWFotE-Mud
void do_sell( CHAR_DATA *ch, char *argument )
{
    char buf[MAX_STRING_LENGTH];
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *keeper;
    OBJ_DATA *obj;
    int cost;

    one_argument( argument, arg );

    if ( arg[0] == '\0' )
    {
	send_to_char( "Sell what?\n\r", ch );
	return;
    }

    if ( ( keeper = find_keeper( ch ) ) == NULL )
	return;

    if ( ( obj = get_obj_carry( ch, arg ) ) == NULL )
    {
	act( AT_TELL, "$n tells you 'You don't have that item.'", keeper, NULL, ch, TO_VICT );
	ch->reply = keeper;
	return;
    }
    /* Bug report and solution thanks to [email protected] */
    if ( !can_see_obj( keeper, obj) ) 
    {
        send_to_char("What are you trying to sell me? I don't buy thin air!\n\r", ch );
        return;
    }


    if ( !can_drop_obj( ch, obj ) )
    {
	send_to_char( "You can't let go of it!\n\r", ch );
	return;
    }

    if ( obj->timer > 0 )
    {
	act( AT_TELL, "$n tells you, '$p is depreciating in value too quickly...'", keeper, obj, ch, TO_VICT );
	return;
    }

    if ( ( cost = get_cost( ch, keeper, obj, FALSE ) ) <= 0 )
    {
	act( AT_ACTION, "$n looks uninterested in $p.", keeper, obj, ch, TO_VICT );
	return;
    }

    if ( cost > keeper->gold )
    {
	act( AT_TELL, "$n makes a credit transaction.", keeper, obj, ch, TO_VICT );
        lower_economy( ch->in_room->area, cost-keeper->gold );
    }
    
    separate_obj( obj );
    act( AT_ACTION, "$n sells $p.", ch, obj, NULL, TO_ROOM );
    sprintf( buf, "You sell $p for %d credit%s.",
	cost, cost == 1 ? "" : "s" );
    act( AT_ACTION, buf, ch, obj, NULL, TO_CHAR );
    ch->gold     += cost;
    keeper->gold -= cost;
    if ( keeper->gold < 0 )
	keeper->gold = 0;

    if ( obj->item_type == ITEM_TRASH )
	extract_obj( obj );
    else  if ( IS_SET( obj->extra_flags , ITEM_CONTRABAND) )
   {
       long ch_exp;
       
       ch_exp = UMIN( obj->cost*10 , ( exp_level( ch->skill_level[SMUGGLING_ABILITY]+1) - exp_level( ch->skill_level[SMUGGLING_ABILITY])  ) / 10  );
       ch_printf( ch, "You receive %ld smuggling experience for unloading your contraband.\n\r " , ch_exp );
       gain_exp( ch, ch_exp , SMUGGLING_ABILITY );
       if ( obj->item_type == ITEM_SPICE || obj->item_type == ITEM_RAWSPICE )
	 extract_obj( obj );
       else
       {
         REMOVE_BIT( obj->extra_flags , ITEM_CONTRABAND );
         obj_from_char( obj );
         obj_to_char( obj, keeper );
       }
   }
    else if ( obj->item_type == ITEM_SPICE || obj->item_type == ITEM_RAWSPICE )
	extract_obj( obj );
    else
    {
	obj_from_char( obj );
	obj_to_char( obj, keeper );
    }

    return;
}
예제 #28
0
/*
 * Attempt to open the given chest at the given location
 *
 * Assume there is no monster blocking the destination
 *
 * Returns TRUE if repeated commands may continue
 */
static bool do_cmd_open_chest(int y, int x, s16b o_idx)
{
	int i, j;

	bool flag = TRUE;

	bool more = FALSE;

	object_type *o_ptr = &o_list[o_idx];


	/* Attempt to unlock it */
	if (o_ptr->pval > 0)
	{
		/* Assume locked, and thus not open */
		flag = FALSE;

		/* Get the "disarm" factor */
		i = p_ptr->state.skills[SKILL_DISARM];

		/* Penalize some conditions */
		if (p_ptr->timed[TMD_BLIND] || no_light()) i = i / 10;
		if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) i = i / 10;

		/* Extract the difficulty */
		j = i - o_ptr->pval;

		/* Always have a small chance of success */
		if (j < 2) j = 2;

		/* Success -- May still have traps */
		if (randint0(100) < j)
		{
			message(MSG_LOCKPICK, 0, "You have picked the lock.");
			gain_exp(1);
			flag = TRUE;
		}

		/* Failure -- Keep trying */
		else
		{
			/* We may continue repeating */
			more = TRUE;
			flush();
			message(MSG_LOCKPICK_FAIL, 0, "You failed to pick the lock.");
		}
	}

	/* Allowed to open */
	if (flag)
	{
		/* Apply chest traps, if any */
		chest_trap(y, x, o_idx);

		/* Let the Chest drop items */
		chest_death(y, x, o_idx);

		/* Squelch chest if autosquelch calls for it */
		p_ptr->notice |= PN_SQUELCH;

		/* Redraw chest, to be on the safe side (it may have been squelched) */
		light_spot(y, x);
	}

	/* Result */
	return (more);
}
예제 #29
0
/*
 * Ask for and parse a "debug command"
 * The "command_arg" may have been set.
 */
void do_cmd_debug(void)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int     x, y;
	char    cmd;


	/* Get a "debug command" */
	(void)get_com("Debug Command: ", &cmd);

	/* Analyze the command */
	switch (cmd)
	{
		/* Nothing */
		case ESCAPE:
		case ' ':
		case '\n':
		case '\r':
		break;


#ifdef ALLOW_SPOILERS

		/* Hack -- Generate Spoilers */
		case '"':
			do_cmd_spoilers();
		break;

#endif /* ALLOW_SPOILERS */

#ifdef MATLAB
		case '=':
			output_monster_matlab();
		break;
#endif /* MATLAB */

		/* Hack -- Help */
		case '?':
			screen_save();
			(void)show_file("wizard.txt", NULL, 0 , 0);
			screen_load();
		break;


		/* Cure all maladies */
		case 'a':
			do_cmd_wiz_cure_all();
		break;

		/* Know alignment */
		case 'A':
			msg_format("Your alignment is %d.", p_ptr->align);
		break;

		/* Teleport to target */
		case 'b':
			do_cmd_wiz_bamf();
		break;

		/* Create any object */
		case 'c':
			wiz_create_item();
		break;

		/* Create a named artifact */
		case 'C':
/*			wiz_create_named_art(p_ptr->command_arg);*/
		break;

		/* Detect everything */
		case 'd':
			(void)detect_all();
		break;

		/* Edit character */
		case 'e':
			do_cmd_wiz_change();
		break;

		/* View item info */
		case 'f':
			(void)identify_fully();
		break;

		/* Create feature */
		case 'F':
			if (p_ptr->command_arg > 0) do_cmd_wiz_feature(p_ptr->command_arg);
		break;

		/* Good Objects */
		case 'g':
			if (p_ptr->command_arg <= 0) p_ptr->command_arg = 1;
			acquirement(py, px, p_ptr->command_arg, FALSE, TRUE);
		break;

		/* Hitpoint rerating */
		case 'h':
			do_cmd_rerate();
		break;

#ifdef MONSTER_HORDES
		case 'H':
			do_cmd_summon_horde();
		break;
#endif /* MONSTER_HORDES */

		/* Identify */
		case 'i':
			(void)ident_spell();
		break;

		/* Fields Integrity */
		case 'I':
			(void)test_field_data_integrity();
		break;

		/* Go up or down in the dungeon */
		case 'j':
			do_cmd_wiz_jump();
		break;

		/* Test compression code */
		case 'J':
			/* test_compress_module(); */
		break;

		/* Self-Knowledge */
		case 'k':
			self_knowledge();
		break;

		/* Learn about objects */
		case 'l':
			do_cmd_wiz_learn();
		break;

		/* Lose Mutation */
		case 'L':
			(void)lose_mutation(p_ptr->command_arg);
		break;

		/* Magic Mapping */
		case 'm':
			map_area();
		break;

		/* Gain Mutation */
		case 'M':
			(void)gain_mutation(p_ptr->command_arg);
		break;

		/* Specific reward */
		case 'r':
			(void)gain_level_reward(p_ptr->command_arg);
		break;

		/* Summon _friendly_ named monster */
		case 'N':
			do_cmd_wiz_named_friendly(p_ptr->command_arg, TRUE);
		break;

		/* Summon Named Monster */
		case 'n':
			do_cmd_wiz_named(p_ptr->command_arg, TRUE);
		break;

		/* Object playing routines */
		case 'o':
			do_cmd_wiz_play();
		break;

		/* Phase Door */
		case 'p':
			teleport_player(10);
		break;

#if 0
		/* Complete a Quest -KMW- */
		case 'q':
		{
			for (i = 0; i < max_quests; i++)
			{
				if (p_ptr->quest[i].status == QUEST_STATUS_TAKEN)
				{
					p_ptr->quest[i].status++;
					msg_print("Completed Quest");
					msg_print(NULL);
					break;
				}
			}
			if (i == max_quests)
			{
				msg_print("No current quest");
				msg_print(NULL);
			}
			break;
		}
#endif

		/* Make every dungeon square "known" to test streamers -KMW- */
		case 'u':
		{
			for (y = min_hgt; y < max_hgt; y++)
			{
				for (x = min_wid; x < max_wid; x++)
				{
					area(y, x)->info |= (CAVE_GLOW | CAVE_MARK);
				}
			}

			wiz_lite();
			break;
		}

		/* Summon Random Monster(s) */
		case 's':
			if (p_ptr->command_arg <= 0) p_ptr->command_arg = 1;
			do_cmd_wiz_summon(p_ptr->command_arg);
		break;

		/* Teleport */
		case 't':
			teleport_player(100);
		break;

		/* Very Good Objects */
		case 'v':
			if (p_ptr->command_arg <= 0) p_ptr->command_arg = 1;
			acquirement(py, px, p_ptr->command_arg, TRUE, TRUE);
		break;

		/* Wizard Light the Level */
		case 'w':
			if (p_ptr->depth)
			{
				wiz_lite();
			}
			else
			{
				learn_map();
			}
		break;

		case 'W':
			test_decision_tree();
		break;

		/* Increase Experience */
		case 'x':
			if (p_ptr->command_arg)
			{
				gain_exp(p_ptr->command_arg);
			}
			else
			{
				gain_exp(p_ptr->exp + 1);
			}
		break;

		/* Zap Monsters (Genocide) */
		case 'z':
			do_cmd_wiz_zap();
		break;

		case 'Z':
			do_cmd_wiz_zap_all();
		break;

		/* Hack -- whatever I desire */
		case '_':
			do_cmd_wiz_hack_ben();
		break;

#ifdef USE_SCRIPT
		/* Hack -- activate a script */
		case '@':
			do_cmd_wiz_script();
		break;
#endif /* USE_SCRIPT */

		/* Not a Wizard Command */
		default:
			msg_print("That is not a valid debug command.");
		break;
	}
}
예제 #30
0
void generic_complete_quest(struct char_data *ch)
{
  qst_rnum rnum;
  qst_vnum vnum = GET_QUEST(ch);
  struct obj_data *new_obj;
  int happy_qp, happy_gold, happy_exp;

  if (--GET_QUEST_COUNTER(ch) <= 0) {
    rnum = real_quest(vnum);
    if (IS_HAPPYHOUR && IS_HAPPYQP) {
      happy_qp = (int)(QST_POINTS(rnum) * (((float)(100+HAPPY_QP))/(float)100));
      happy_qp = MAX(happy_qp, 0);
      GET_QUESTPOINTS(ch) += happy_qp;
      send_to_char(ch,
          "%s\r\nYou have been awarded %d quest points for your service.\r\n",
          QST_DONE(rnum), happy_qp);
	} else {
      GET_QUESTPOINTS(ch) += QST_POINTS(rnum);
      send_to_char(ch,
          "%s\r\nYou have been awarded %d quest points for your service.\r\n",
          QST_DONE(rnum), QST_POINTS(rnum));
    }
    if (QST_GOLD(rnum)) {
      if ((IS_HAPPYHOUR) && (IS_HAPPYGOLD)) {
        happy_gold = (int)(QST_GOLD(rnum) * (((float)(100+HAPPY_GOLD))/(float)100));
        happy_gold = MAX(happy_gold, 0);
        increase_gold(ch, happy_gold);
        send_to_char(ch,
              "You have been awarded %d gold coins for your service.\r\n",
              happy_gold);
	  } else {
        increase_gold(ch, QST_GOLD(rnum));
        send_to_char(ch,
              "You have been awarded %d gold coins for your service.\r\n",
              QST_GOLD(rnum));
      }
    }
    if (QST_EXP(rnum)) {
      gain_exp(ch, QST_EXP(rnum));
      if ((IS_HAPPYHOUR) && (IS_HAPPYEXP)) {
        happy_exp = (int)(QST_EXP(rnum) * (((float)(100+HAPPY_EXP))/(float)100));
        happy_exp = MAX(happy_exp, 0);
        send_to_char(ch,
              "You have been awarded %d experience for your service.\r\n",
              happy_exp);
      } else {
        send_to_char(ch,
              "You have been awarded %d experience points for your service.\r\n",
              QST_EXP(rnum));
      }
    }
    if (QST_OBJ(rnum) && QST_OBJ(rnum) != NOTHING) {
      if (real_object(QST_OBJ(rnum)) != NOTHING) {
        if ((new_obj = read_object((QST_OBJ(rnum)),VIRTUAL)) != NULL) {
            obj_to_char(new_obj, ch);
            send_to_char(ch, "You have been presented with %s%s for your service.\r\n",
                GET_OBJ_SHORT(new_obj), CCNRM(ch, C_NRM));
        }
      }
    }
    if (!IS_SET(QST_FLAGS(rnum), AQ_REPEATABLE))
      add_completed_quest(ch, vnum);
    clear_quest(ch);
    if ((real_quest(QST_NEXT(rnum)) != NOTHING) &&
        (QST_NEXT(rnum) != vnum) &&
        !is_complete(ch, QST_NEXT(rnum))) {
      rnum = real_quest(QST_NEXT(rnum));
      set_quest(ch, rnum);
      send_to_char(ch,
          "The next stage of your quest awaits:\r\n%s",
          QST_INFO(rnum));
    }
  }
  save_char(ch);
}