예제 #1
0
varargs int cast_fireball (string str, int obj) {   
    object target;
    int x;

    if (!str) str = "NONE";
    if (str=="NONE") target = TP->query_current_attacker();
    if (!target) target = present(str, environment(TP));
    if (!target) {
	write(SYNTAX);
	return 0;
    }     

    if (!check_valid_targ(TP, target)) return 0;
    if (!obj) {
	if (!cast_spell(TP, COST)) return 0;

	lvl = query_caster_level(TP, "wizard");
	obj = lvl;
	write("You begin casting Fireball...\n");
	say(TPN+" begins uttering arcane words...\n");

	tell_room(environment(TP), TPN+" hurls a huge ball of fire at "+
	  target->query("cap_name")+"!\n", ({ caster, target }) );
	write("You hurl a ball of fire at "+target->query("cap_name")+".\n");
	tell_object(target, TPN+" hurls a huge ball of fire at you!\n");
    } else {
예제 #2
0
varargs int cast_lightning (string str, int obj) {
    object target;

    if (!str) str = "NONE";
    if (str=="NONE") target = TP->query_current_attacker();
    if (!target) target = present(str, environment(TP));
    if (!target) {
	write(SYNTAX);
	return 0;
    }     

    if (!check_valid_targ(TP, target)) return 0;
    if (!obj) {
	if (!cast_spell(TP, COST)) return 0;
	obj = query_caster_level(TP, "wizard");
	lvl = obj;
	write("You begin casting Chain Lightning...\n"+
	  "Electricity begins crackling between your fingers.\n");
	say(TPN+" begins uttering arcane words...\n"+
	  "Electricity begins crackling between "+
	  possessive(TP->query("gender"))+" fingers!\n");

	tell_room(environment(TP), TPN+" hurls a lightning bolt at "+
	  target->query("cap_name")+"!\n", ({ caster, target }) );
	write("You hurl a lightning bolt at "+
	  target->query("cap_name")+".\n");
	tell_object(target, TPN+" hurls a lightning bolt at you!\n");
    } else {
예제 #3
0
varargs int cast_coldcone (string str, int obj) {   
    object target;
    int x;

    if (!str) str = "NONE";
    if (str=="NONE") target = TP->query_current_attacker();
    if (!target) target = present(str, environment(TP));
    if (!target) {
	write(SYNTAX);
	return 0;
    }     

    if (!check_valid_targ(TP, target)) return INVALID_TARGET;
    if (!obj) {
	if (!cast_spell(TP, COST)) return NO_STRENGTH;
	TP->set("power_delay", 1);

	lvl = query_caster_level(TP, "wizard");
	obj = lvl;
	write("You begin casting Cone of Cold...\n");
	say(TPN+" begins uttering arcane words...\n");

	tell_room(environment(TP), TPN+" blasts a cone of freezing cold at "+
	  target->query("cap_name")+"!\n", ({ caster, target }) );
	write("You blast a cone of freezing cold at "+
	  target->query("cap_name")+".\n");
	tell_object(target, TPN+" blasts you with a cone"+
	  " of freezing cold!!\n");
    } else {
예제 #4
0
bool _other_spells(const spell_t* spell, creature_t* caster, creature_t* target, bool& did_cast)
{
  switch (spell->id)
  {
  case SPELL_ANIMATE_TREE:
  {
    for (int i = 0; i < current_dungeon->width * current_dungeon->height; i++)
    {
      int x = i % current_dungeon->width;
      int y = i / current_dungeon->width;

      if (tile_t* tile = get_tile_at(current_dungeon, x, y))
      {
        if (tile->id == TILE_TREE && caster->sees(x, y))
        {
          cast_spell(spell, caster, x, y);
          did_cast = true;

          break;
        }
      }
    }

    return true;
  }
  default:
    break;
  }

  return false;
}
예제 #5
0
파일: castle.c 프로젝트: sean/dominionmud
/* Used by King Welmar */
void fry_victim(struct char_data * ch)
{

  struct char_data *tch;

  if (ch->points.mana < 10)
    return;

  /* Find someone suitable to fry ! */

  if (!(tch = get_victim(ch)))
    return;

  switch (number(0, 8)) {
  case 1:
  case 2:
  case 3:
    act("You raise your hand in a dramatical gesture.", 1, ch, 0, 0, TO_CHAR);
    act("$n raises $s hand in a dramatical gesture.", 1, ch, 0, 0, TO_ROOM);
    cast_spell(ch, tch, 0, SPELL_COLOR_SPRAY);
    break;
  case 4:
  case 5:
    act("You concentrate and mumble to yourself.", 1, ch, 0, 0, TO_CHAR);
    act("$n concentrates, and mumbles to $mself.", 1, ch, 0, 0, TO_ROOM);
    cast_spell(ch, tch, 0, SPELL_HARM);
    break;
  case 6:
  case 7:
    act("You look deeply into the eyes of $N.", 1, ch, 0, tch, TO_CHAR);
    act("$n looks deeply into the eyes of $N.", 1, ch, 0, tch, TO_NOTVICT);
    act("You see an ill-boding flame in the eye of $n.", 1, ch, 0, tch, TO_VICT);
    cast_spell(ch, tch, 0, SPELL_FIREBALL);
    break;
  default:
    if (!number(0, 1))
      cast_spell(ch, ch, 0, SPELL_HEAL);
    break;
  }

  ch->points.mana -= 10;

  return;
}
예제 #6
0
void creature_cast_spell(creature_t* creature, creature_t* target)
{
  bool did_cast = false;

  // TODO: Cast specific spells depending on circumstance.

  spell_id spellid = creature->spellbook.spell[random(0,
      creature->spellbook.number_of_spells - 1)];
  const spell_t* spell = &get_spell(spellid);
  if ((spell->flag & SF_MISSILE)|| (spell->flag & SF_RAY))
  {
    if (in_range_of_spell(spell, creature, target->pos.x, target->pos.y)
        && !_is_ally_in_ray(creature, target))
    {
      cast_spell(spell, creature, target->pos.x, target->pos.y);
      did_cast = true;
    }
  }
  else if (spell->range == RANGE_SELF)
  {
    cast_spell(spell, creature, creature->pos.x, creature->pos.y);
    did_cast = true;
  }
  else
  {
    if (!_other_spells(spell, creature, target, did_cast))
    {
      // Smite targeted
      if (in_range_of_spell(spell, creature, target->pos.x, target->pos.y))
      {
        cast_spell(spell, creature, target->pos.x, target->pos.y);
        did_cast = true;
      }
    }
  }

  if (!did_cast)
  {
    creature->step_toward(target->pos.x, target->pos.y, target);
  }
}
예제 #7
0
/*
 * Rough duplicate of PC's cast.
 * @param mob the mobile
 * @vict the target of the spell
 * @spell_num the spell
 * @return TRUE if the mob was able to cast a spell even though it failed
 */
bool mob_cast(struct char_data *mob, struct char_data *vict, int spell_num) {
  int manaCost = mag_manacost(mob, spell_num);
  if(spell_num > 0
      && manaCost <= GET_MANA(mob)
      && spell_info[spell_num].min_level[(int)GET_CLASS(mob)] <= GET_LEVEL(mob)
      && !AFF_FLAGGED(mob, AFF_SILENCE)
      && GET_WAIT_STATE(mob) < 1) {
    /* This is a very simple check for 'spell success'. In the future a more
     * sophisticated approach should be implemented.
     */
    if(rand_number(0, 30) <= GET_INT(mob)) {
      cast_spell(mob, vict, NULL, spell_num);
    }
    /* even if the mob fails, they will still be "stunned" for a round */
    WAIT_STATE(mob, PULSE_VIOLENCE);
    GET_MANA(mob) = MAX(0, MIN(GET_MAX_MANA(mob), GET_MANA(mob) - manaCost));
    return TRUE;
  }

  return FALSE;
}
예제 #8
0
varargs int cast_necrobolt (string str, int obj) {   
    object target;

    if (!str) str = "NONE";
    if (str=="NONE") target = TP->query_current_attacker();
    if (!target) target = present(str, environment(TP));
    if (!target) {
	write(SYNTAX);
	return 0;
    }     

    if (!check_valid_targ(TP, target)) return 0;
    if (!obj) {
	obj = query_caster_level(TP, "wizard");
	if (!cast_spell(TP, COST)) return 0;

	write("You begin casting Necromantic Bolt...\n"+
	  "Your hands fill with negative energy.\n");
	say(TPN+" begins uttering arcane words...\n"+
	  "a thick blackness engulfs "+
	  possessive(TP->query("gender"))+" hands!\n");

	tell_room(environment(TP), TPN+" hurls a black beam of light at "+
	  target->query("cap_name")+"!\n", ({ caster, target }) );
예제 #9
0
bool cast_holy_lance(void) { return cast_spell(holy_lance_spell); }
예제 #10
0
bool cast_hell_lance(void) { return cast_spell(hell_lance_spell); }
예제 #11
0
bool cast_heroism(void) { return cast_spell(heroism_spell); }
예제 #12
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;
}
예제 #13
0
void
psionic_best_attack(struct creature *ch, struct creature *vict)
{
    int aggression = calculate_mob_aggression(ch, vict);

    // Psions can't really do anything when there's a psishield in place
    if (AFF3_FLAGGED(vict, AFF3_PSISHIELD)
        && can_cast_spell(ch, SPELL_PSIONIC_SHATTER)) {
        cast_spell(ch, vict, NULL, NULL, SPELL_PSIONIC_SHATTER);
        return;
    }
    if (aggression > 75) {
        // extremely aggressive - just attack hard
        if (!affected_by_spell(vict, SPELL_PSYCHIC_SURGE)
            && can_cast_spell(ch, SPELL_PSYCHIC_SURGE)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_SURGE);
            return;
        } else if (can_cast_spell(ch, SKILL_PSIBLAST)) {
            perform_offensive_skill(ch, vict, SKILL_PSIBLAST);
            return;
        } else if (GET_POSITION(vict) > POS_SITTING
            && can_cast_spell(ch, SPELL_EGO_WHIP)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_EGO_WHIP);
            return;
        }
    }
    if (aggression > 50) {
        // somewhat aggressive - balance attacking with crippling
        if (!affected_by_spell(vict, SPELL_PSYCHIC_CRUSH)
            && can_cast_spell(ch, SPELL_PSYCHIC_CRUSH)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_CRUSH);
            return;
        } else if (!affected_by_spell(vict, SPELL_MOTOR_SPASM)
            && can_cast_spell(ch, SPELL_MOTOR_SPASM)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_MOTOR_SPASM);
            return;
        } else if (GET_POSITION(vict) > POS_SITTING
            && can_cast_spell(ch, SPELL_EGO_WHIP)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_EGO_WHIP);
            return;
        } else if (can_cast_spell(ch, SKILL_PSIBLAST)) {
            perform_offensive_skill(ch, vict, SKILL_PSIBLAST);
            return;
        }
    }
    if (aggression > 25) {
        // not very aggressive - play more defensively
        if (!IS_CONFUSED(vict)
            && can_cast_spell(ch, SPELL_CONFUSION)
            && (IS_MAGE(vict) || IS_PSIONIC(vict) || IS_CLERIC(vict) ||
                IS_KNIGHT(vict) || IS_PHYSIC(vict))) {
            cast_spell(ch, vict, NULL, NULL, SPELL_CONFUSION);
            return;
        } else if (!AFF2_FLAGGED(ch, AFF2_VERTIGO)
            && can_cast_spell(ch, SPELL_VERTIGO)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_VERTIGO);
            return;
        } else if (!affected_by_spell(vict, SPELL_PSYCHIC_FEEDBACK)
            && can_cast_spell(ch, SPELL_PSYCHIC_FEEDBACK)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_FEEDBACK);
            return;
        } else if (nullpsi_is_advisable(vict)
            && can_cast_spell(ch, SPELL_NULLPSI)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_NULLPSI);
            return;
        } else if (can_cast_spell(ch, SKILL_PSIBLAST)) {
            perform_offensive_skill(ch, vict, SKILL_PSIBLAST);
            return;
        }
    }
    if (aggression > 5) {
        // attempt to neutralize or get away
        if (GET_POSITION(vict) > POS_SLEEPING
            && can_cast_spell(ch, SPELL_MELATONIC_FLOOD)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_MELATONIC_FLOOD);
            return;
        } else if (can_cast_spell(ch, SPELL_ASTRAL_SPELL)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_ASTRAL_SPELL);
            return;
        } else if (can_cast_spell(ch, SPELL_AMNESIA)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_AMNESIA);
            return;
        } else if (can_cast_spell(ch, SPELL_FEAR)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_FEAR);
            return;
        }
    }
    // desperation - just attack full force, as hard as possible
    if (!affected_by_spell(vict, SPELL_PSYCHIC_SURGE)
        && can_cast_spell(ch, SPELL_PSYCHIC_SURGE)) {
        cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_SURGE);
        return;
    } else if (!affected_by_spell(vict, SPELL_PSYCHIC_CRUSH)
        && can_cast_spell(ch, SPELL_PSYCHIC_CRUSH)) {
        cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_CRUSH);
        return;
    } else if (!affected_by_spell(vict, SPELL_MOTOR_SPASM)
        && can_cast_spell(ch, SPELL_MOTOR_SPASM)) {
        cast_spell(ch, vict, NULL, NULL, SPELL_MOTOR_SPASM);
        return;
    } else if (can_cast_spell(ch, SKILL_PSIBLAST)) {
        perform_offensive_skill(ch, vict, SKILL_PSIBLAST);
        return;
    } else if (GET_POSITION(vict) > POS_SITTING
        && can_cast_spell(ch, SPELL_EGO_WHIP)) {
        cast_spell(ch, vict, NULL, NULL, SPELL_EGO_WHIP);
        return;
    } else if (GET_POSITION(vict) > POS_SLEEPING
        && can_cast_spell(ch, SPELL_MELATONIC_FLOOD)) {
        cast_spell(ch, vict, NULL, NULL, SPELL_MELATONIC_FLOOD);
        return;
    } else if (can_cast_spell(ch, SPELL_ASTRAL_SPELL)) {
        cast_spell(ch, vict, NULL, NULL, SPELL_ASTRAL_SPELL);
        return;
    } else if (can_cast_spell(ch, SPELL_AMNESIA)) {
        cast_spell(ch, vict, NULL, NULL, SPELL_AMNESIA);
        return;
    } else if (can_cast_spell(ch, SPELL_FEAR)) {
        cast_spell(ch, vict, NULL, NULL, SPELL_FEAR);
        return;
    } else {
        hit(ch, vict, TYPE_UNDEFINED);
    }
}
예제 #14
0
/* Has all kinds of effects in different circumstances.
   Eventually will be more interesting */
void s_ritual(void)
{
    pob symbol;
    int i,roomno;
    int x,y;

    mprint("You begin your ritual....");
    mprint("You enter a deep trance. Time Passes...");
    setgamestatus(SKIP_PLAYER);
    time_clock(FALSE);
    setgamestatus(SKIP_PLAYER);
    time_clock(FALSE);
    setgamestatus(SKIP_PLAYER);
    time_clock(FALSE);
    setgamestatus(SKIP_PLAYER);
    time_clock(FALSE);
    setgamestatus(SKIP_PLAYER);
    time_clock(FALSE);
    if (RitualHour == hour())
        mprint("Your mental fatigue prevents from completing the ritual!");
    else if (random_range(100) > Player.iq+Player.pow+Player.level)
        mprint("Your concentration was broken -- the ritual fails!");
    else {
        mprint("You charge the ritual with magical energy and focus your will.");
        mprint("Time Passes...");
        setgamestatus(SKIP_PLAYER);
        time_clock(FALSE);
        setgamestatus(SKIP_PLAYER);
        time_clock(FALSE);
        setgamestatus(SKIP_PLAYER);
        time_clock(FALSE);
        setgamestatus(SKIP_PLAYER);
        time_clock(FALSE);
        setgamestatus(SKIP_PLAYER);
        time_clock(FALSE);
        RitualHour = hour();
        /* set of random conditions for different ritual effects */
        if (Current_Environment == E_CITY) {
            mprint("Flowing waves of mystical light congeal all around you.");
            mprint("'Like wow, man! Colors!'");
            mprint("Appreciative citizens throw you spare change.");
            Player.cash +=random_range(50);
        }
        else if ( (roomno=Level->site[Player.x][Player.y].roomnumber) >= ROOMBASE )
        {
            if (RitualRoom == roomno)
                mprint("For some reason the ritual doesn't work this time...");
            else {
                RitualRoom = roomno;
                switch (RitualRoom) {
                case RS_TREASURE: /* ransacked treasure chamber */
                    mprint("Your spell sets off frenetic growth all around you!");
                    for(i=0; i<8; i++) {
                        Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].locchar =
                            HEDGE;
                        Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].p_locf =
                            L_TRIFID;
                        lset(Player.x+Dirs[0][i], Player.y+Dirs[1][i], CHANGED);
                    }
                    break;
                case RS_HAREM: /* harem */
                case RS_BOUDOIR: /* boudoir */
                    mprint("A secret panel opens next to the bed....");
                    if (random_range(2))
                        summon(0,INCUBUS); /* succubus/incubus */
                    else summon(0,SATYR); /* satyr/nymph */
                    break;
                case RS_SHRINE: /*shrine to high magic */
                    mprint("A storm of mana coaelesces around you.");
                    mprint("You are buffeted by bursts of random magic.");
                    p_damage(random_range(Player.pow),UNSTOPPABLE,"high magic");
                    mprint("Continue ritual? Could be dangerous.... [yn] ");
                    if (ynq()=='y') s_wish();
                    else mprint("The mana fades away to nothingness.");
                    x = Player.x;
                    y = Player.y;
                    while (x >= 0 && Level->site[x - 1][y].roomnumber == RS_SHRINE)
                        x--;
                    while (y >= 0 && Level->site[x][y - 1].roomnumber == RS_SHRINE)
                        y--;
                    for (i = 0; Level->site[x][y].roomnumber == RS_SHRINE;) {
                        Level->site[x][y].roomnumber = RS_ZORCH;
                        lset(x, y, CHANGED);
                        x++;
                        i++;
                        if (Level->site[x][y].roomnumber != RS_SHRINE) {
                            x -= i;
                            i = 0;
                            y++;
                        }
                    }
                    break;
                case RS_MAGIC_LAB: /* magician's lab */
                    mprint("Your magical activity sets off a latent spell in the lab!");
                    cast_spell(random_range(NUMSPELLS));
                    break;
                case RS_PENTAGRAM: /* pentagram room */
                    mprint("A smoky form begins to coalesce....");
                    summon(-1,-1);
                    mprint("Fortunately, it seems confined to the pentagram.");
                    m_status_reset(Level->mlist->m,MOBILE);
                    break;
                case RS_OMEGA_DAIS: /* blue omega room */
                    mprint("The Lords of Destiny look upon you....");
                    if (Player.level > 10) {
                        mprint("A curtain of blue flames leaps up from the omega.");
                        morewait();
                        l_adept();
                    }
                    else {
                        if (Player.patron == DESTINY) {
                            mprint("Your patrons take pity on you.");
                            if ((Player.rank[PRIESTHOOD]<SPRIEST) &&
                                    (! find_item(&symbol,OB_SYMBOL_DESTINY,-1))) {
                                symbol = ((pob) checkmalloc(sizeof(objtype)));
                                *symbol = Objects[OB_SYMBOL_DESTINY];
                                symbol->known = 2;
                                symbol->charge = 17;
                                gain_item(symbol);
                                mprint("You feel uplifted.");
                            }
                            else gain_experience(min(1000,Player.xp));
                        }
                        else if (random_range(3)==1) {
                            mprint("You feel Fated.");
                            gain_experience(Player.level*Player.level*10);
                            Player.hp = max(Player.hp, Player.maxhp);
                        }
                        else if (random_range(2)) {
                            mprint("You feel Doomed.");
                            Player.hp = 1;
                            Player.mana = 0;
                            Player.xp = 0;
                        }
                        else mprint("The Lords of Destiny laugh at you!");
                    }
                    break;
                default:
                    mprint("Well, not much effect. Chalk it up to experience.");
                    gain_experience(Player.level*5);
                    break;
                }
            }
        }
        else {
            if (RitualRoom == Level->site[Player.x][Player.y].roomnumber)
                mprint("The ritual fails for some unexplainable reason.");
            else {
                mprint("The ritual seems to be generating some spell effect.");
                RitualRoom = Level->site[Player.x][Player.y].roomnumber;
                switch (RitualRoom) {
                case RS_WALLSPACE:
                    shadowform();
                    break;
                case RS_CORRIDOR:
                    haste(0);
                    break;
                case RS_PONDS:
                    breathe(0);
                    break;
                case RS_ADEPT:
                    hero(1);
                    break;
                default:
                    mprint("The ritual doesn't seem to produce any tangible results...");
                    gain_experience(Player.level*6);
                }
            }
        }
    }
}
예제 #15
0
bool cast_light_area(void) { return cast_spell(light_area_spell); }
예제 #16
0
bool
psionic_mob_fight(struct creature *ch, struct creature *precious_vict)
{
    struct creature *vict = NULL;

    if (!is_fighting(ch))
        return false;

    // pick an enemy
    if (!(vict = choose_opponent(ch, precious_vict)))
        return false;

    int aggression = calculate_mob_aggression(ch, vict);

    // Psions can't really do anything when there's a psishield in place
    if (AFF3_FLAGGED(vict, AFF3_PSISHIELD)
        && can_cast_spell(ch, SPELL_PSIONIC_SHATTER)) {
        cast_spell(ch, vict, NULL, NULL, SPELL_PSIONIC_SHATTER);
        return true;
    }
    // Prioritize healing with aggression
    if (GET_HIT(ch) < (GET_MAX_HIT(ch) * MIN(20, MAX(80, aggression)) / 100)
        && can_cast_spell(ch, SPELL_WOUND_CLOSURE)) {
        cast_spell(ch, ch, NULL, NULL, SPELL_WOUND_CLOSURE);
        return true;
    }

    if (aggression > 75) {
        // extremely aggressive - just attack hard
        if (can_cast_spell(ch, SKILL_PSIBLAST)) {
            perform_offensive_skill(ch, vict, SKILL_PSIBLAST);
            return true;
        } else if (GET_POSITION(vict) > POS_SITTING
            && can_cast_spell(ch, SPELL_EGO_WHIP)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_EGO_WHIP);
            return true;
        }
    }
    if (aggression > 50) {
        // somewhat aggressive - balance attacking with crippling
        if (GET_MANA(ch) < GET_MAX_MANA(ch) / 2
            && can_cast_spell(ch, SKILL_PSIDRAIN)
            && can_psidrain(ch, vict, NULL, false)) {
            perform_psidrain(ch, vict);
            return true;
        } else if (!affected_by_spell(vict, SPELL_PSYCHIC_CRUSH)
            && can_cast_spell(ch, SPELL_PSYCHIC_CRUSH)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_CRUSH);
            return true;
        } else if (!affected_by_spell(vict, SPELL_MOTOR_SPASM)
            && can_cast_spell(ch, SPELL_MOTOR_SPASM)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_MOTOR_SPASM);
            return true;
        } else if (!affected_by_spell(ch, SPELL_ADRENALINE)
            && can_cast_spell(ch, SPELL_ADRENALINE)) {
            cast_spell(ch, ch, NULL, NULL, SPELL_ADRENALINE);
            return true;
        } else if (GET_POSITION(vict) > POS_SITTING
            && can_cast_spell(ch, SPELL_EGO_WHIP)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_EGO_WHIP);
            return true;
        } else if (can_cast_spell(ch, SKILL_PSIBLAST)) {
            perform_offensive_skill(ch, vict, SKILL_PSIBLAST);
            return true;
        }
    }
    if (aggression > 25) {
        // not very aggressive - play more defensively
        if (IS_PSIONIC(vict)
            && !affected_by_spell(ch, SPELL_PSYCHIC_RESISTANCE)
            && can_cast_spell(ch, SPELL_PSYCHIC_RESISTANCE)) {
            cast_spell(ch, ch, NULL, NULL, SPELL_PSYCHIC_RESISTANCE);
            return true;
        } else if (!IS_CONFUSED(vict)
            && can_cast_spell(ch, SPELL_CONFUSION)
            && (IS_MAGE(vict) || IS_PSIONIC(vict) || IS_CLERIC(vict) ||
                IS_KNIGHT(vict) || IS_PHYSIC(vict))) {
            cast_spell(ch, vict, NULL, NULL, SPELL_CONFUSION);
            return true;
        } else if (GET_MOVE(ch) < GET_MAX_MOVE(ch) / 4
            && can_cast_spell(ch, SPELL_ENDURANCE)) {
            cast_spell(ch, ch, NULL, NULL, SPELL_ENDURANCE);
            return true;
        } else if (GET_MOVE(ch) < GET_MAX_MOVE(ch) / 4
            && can_cast_spell(ch, SPELL_DERMAL_HARDENING)) {
            cast_spell(ch, ch, NULL, NULL, SPELL_DERMAL_HARDENING);
            return true;
        } else if (!AFF2_FLAGGED(ch, AFF2_VERTIGO)
            && can_cast_spell(ch, SPELL_VERTIGO)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_VERTIGO);
            return true;
        } else if (!affected_by_spell(vict, SPELL_PSYCHIC_FEEDBACK)
            && can_cast_spell(ch, SPELL_PSYCHIC_FEEDBACK)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_FEEDBACK);
            return true;
        } else if (!affected_by_spell(vict, SPELL_WEAKNESS)
            && can_cast_spell(ch, SPELL_WEAKNESS)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_WEAKNESS);
            return true;
        } else if (!affected_by_spell(vict, SPELL_CLUMSINESS)
            && can_cast_spell(ch, SPELL_CLUMSINESS)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_CLUMSINESS);
            return true;
        } else if (can_cast_spell(ch, SKILL_PSIBLAST)) {
            perform_offensive_skill(ch, vict, SKILL_PSIBLAST);
            return true;
        }
    }
    if (aggression > 5) {
        // attempt to neutralize or get away
        if (GET_POSITION(vict) > POS_SLEEPING
            && can_cast_spell(ch, SPELL_MELATONIC_FLOOD)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_MELATONIC_FLOOD);
            return true;
        } else if (can_cast_spell(ch, SPELL_ASTRAL_SPELL)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_ASTRAL_SPELL);
            return true;
        } else if (can_cast_spell(ch, SPELL_AMNESIA)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_AMNESIA);
            return true;
        } else if (can_cast_spell(ch, SPELL_FEAR)) {
            cast_spell(ch, vict, NULL, NULL, SPELL_FEAR);
            return true;
        }
    }

    return false;
}
예제 #17
0
bool cast_alchemy(void) { return cast_spell(alchemy_spell); }
예제 #18
0
bool cast_breathe_fire_I(void) { return cast_spell(breathe_fire_I_spell); }
예제 #19
0
bool cast_berserk(void) { return cast_spell(berserk_spell); }
예제 #20
0
bool cast_banish_evil(void) { return cast_spell(banish_evil_spell); }
예제 #21
0
/**
 * Apply a potion.
 * @param op Object applying the potion.
 * @param tmp The potion.
 * @return 1 if the potion was successfully applied, 0 otherwise. */
int apply_potion(object *op, object *tmp)
{
	int i;

	/* some sanity checks */
	if (!op || !tmp || (op->type == PLAYER && (!CONTR(op) || !CONTR(op)->exp_ptr[EXP_MAGICAL] || !CONTR(op)->exp_ptr[EXP_WISDOM])))
	{
		LOG(llevBug,"apply_potion() called with invalid objects! obj: %s (%s - %s) tmp:%s\n", query_name(op, NULL), CONTR(op) ? query_name(CONTR(op)->exp_ptr[EXP_MAGICAL], NULL) : "<no contr>", CONTR(op) ? query_name(CONTR(op)->exp_ptr[EXP_WISDOM], NULL) : "<no contr>", query_name(tmp, NULL));
		return 0;
	}

	if (op->type == PLAYER)
	{
		/* set chosen_skill to "magic device" - thats used when we "use" a potion */
		if (!change_skill(op, SK_USE_MAGIC_ITEM))
		{
			/* no skill, no potion use (dust & balm too!) */
			return 0;
		}

		if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED))
		{
			identify(tmp);
		}

		/* special potions. Only players get this */
		if (tmp->last_eat == -1)
		{
			/* create a force and copy the effects in */
			object *force = get_archetype("force");

			if (!force)
			{
				LOG(llevBug, "apply_potion: Can't create force object?\n");
				return 0;
			}

			force->type = POTION_EFFECT;
			/* or it will auto destroy with first tick */
			SET_FLAG(force, FLAG_IS_USED_UP);
			/* how long this force will stay */
			force->stats.food += tmp->stats.food;

			if (force->stats.food <= 0)
			{
				force->stats.food = 1;
			}

			/* negative effects because cursed or damned */
			if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))
			{
				/* now we have a bit work because we change (multiply,...) the
				 * base values of the potion - that can invoke out of bounce
				 * values we must catch here. */

				/* effects stays 3 times longer */
				force->stats.food *= 3;

				for (i = 0; i < NROFATTACKS; i++)
				{
					int tmp_a;
					int tmp_p;

					tmp_a = tmp->attack[i] > 0 ? -tmp->attack[i] : tmp->attack[i];
					tmp_p = tmp->protection[i] > 0 ? -tmp->protection[i] : tmp->protection[i];

					/* double bad effect when damned */
					if (QUERY_FLAG(tmp, FLAG_DAMNED))
					{
						tmp_a *= 2;
						tmp_p *= 2;
					}

					/* we don't want out of bound values ... */
					if ((int) force->protection[i] + tmp_p > 100)
					{
						force->protection[i] = 100;
					}
					else if ((int) force->protection[i] + tmp_p < -100)
					{
						force->protection[i] = -100;
					}
					else
					{
						force->protection[i] += (sint8) tmp_p;
					}

					if ((int) force->attack[i] + tmp_a > 100)
					{
						force->attack[i] = 100;
					}
					else if ((int) force->attack[i] + tmp_a < 0)
					{
						force->attack[i] = 0;
					}
					else
					{
						force->attack[i] += tmp_a;
					}
				}

				insert_spell_effect("meffect_purple", op->map, op->x, op->y);
				play_sound_map(op->map, CMD_SOUND_EFFECT, "poison.ogg", op->x, op->y, 0, 0);
			}
			/* all positive (when not on default negative) */
			else
			{
				/* we don't must do the hard way like cursed/damned (no multiplication or
				 * sign change). */
				memcpy(force->protection, tmp->protection, sizeof(tmp->protection));
				memcpy(force->attack, tmp->attack, sizeof(tmp->attack));
				insert_spell_effect("meffect_green", op->map, op->x, op->y);
				play_sound_map(op->map, CMD_SOUND_EFFECT, "magic_default.ogg", op->x, op->y, 0, 0);
			}

			/* now copy stats values */
			force->stats.Str = QUERY_FLAG(tmp, FLAG_CURSED) ? (tmp->stats.Str > 0 ? -tmp->stats.Str : tmp->stats.Str) : (QUERY_FLAG(tmp, FLAG_DAMNED) ? (tmp->stats.Str > 0 ? (-tmp->stats.Str) * 2 : tmp->stats.Str * 2) : tmp->stats.Str);
			force->stats.Con = QUERY_FLAG(tmp, FLAG_CURSED) ? (tmp->stats.Con > 0 ? -tmp->stats.Con : tmp->stats.Con) : (QUERY_FLAG(tmp, FLAG_DAMNED) ? (tmp->stats.Con > 0 ? (-tmp->stats.Con) * 2 : tmp->stats.Con * 2) : tmp->stats.Con);
			force->stats.Dex = QUERY_FLAG(tmp, FLAG_CURSED) ? (tmp->stats.Dex > 0 ? -tmp->stats.Dex : tmp->stats.Dex) : (QUERY_FLAG(tmp, FLAG_DAMNED) ? (tmp->stats.Dex > 0 ? (-tmp->stats.Dex) * 2 : tmp->stats.Dex * 2) : tmp->stats.Dex);
			force->stats.Int = QUERY_FLAG(tmp, FLAG_CURSED) ? (tmp->stats.Int > 0 ? -tmp->stats.Int : tmp->stats.Int) : (QUERY_FLAG(tmp, FLAG_DAMNED) ? (tmp->stats.Int > 0 ? (-tmp->stats.Int) * 2 : tmp->stats.Int * 2) : tmp->stats.Int);
			force->stats.Wis = QUERY_FLAG(tmp, FLAG_CURSED) ? (tmp->stats.Wis > 0 ? -tmp->stats.Wis : tmp->stats.Wis) : (QUERY_FLAG(tmp, FLAG_DAMNED) ? (tmp->stats.Wis > 0 ? (-tmp->stats.Wis) * 2 : tmp->stats.Wis * 2) : tmp->stats.Wis);
			force->stats.Pow = QUERY_FLAG(tmp, FLAG_CURSED) ? (tmp->stats.Pow > 0 ? -tmp->stats.Pow : tmp->stats.Pow) : (QUERY_FLAG(tmp, FLAG_DAMNED) ? (tmp->stats.Pow > 0 ? (-tmp->stats.Pow) * 2 : tmp->stats.Pow * 2) : tmp->stats.Pow);
			force->stats.Cha = QUERY_FLAG(tmp, FLAG_CURSED) ? (tmp->stats.Cha > 0 ? -tmp->stats.Cha : tmp->stats.Cha) : (QUERY_FLAG(tmp, FLAG_DAMNED) ? (tmp->stats.Cha > 0 ? (-tmp->stats.Cha) * 2 : tmp->stats.Cha * 2) : tmp->stats.Cha);

			/* kick the force in, and apply it to player */
			force->speed_left = -1;
			force = insert_ob_in_ob(force, op);
			CLEAR_FLAG(tmp, FLAG_APPLIED);
			SET_FLAG(force, FLAG_APPLIED);

			/* implicit fix_player() here */
			if (!change_abil(op, force))
			{
				new_draw_info(NDI_UNIQUE, op, "Nothing happened.");
			}

			decrease_ob(tmp);
			return 1;
		}

		/* Potion of minor restoration */
		if (tmp->last_eat == 1)
		{
			object *depl;
			archetype *at;

			if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))
			{
				if (QUERY_FLAG(tmp, FLAG_DAMNED))
				{
					drain_stat(op);
					drain_stat(op);
					drain_stat(op);
					drain_stat(op);
				}
				else
				{
					drain_stat(op);
					drain_stat(op);
				}

				fix_player(op);
				decrease_ob(tmp);
				insert_spell_effect("meffect_purple", op->map, op->x, op->y);
				play_sound_map(op->map, CMD_SOUND_EFFECT, "poison.ogg", op->x, op->y, 0, 0);
				return 1;
			}

			if ((at = find_archetype("depletion")) == NULL)
			{
				LOG(llevBug, "BUG: Could not find archetype depletion.");
				return 0;
			}

			depl = present_arch_in_ob(at, op);

			if (depl != NULL)
			{
				for (i = 0; i < NUM_STATS; i++)
				{
					if (get_attr_value(&depl->stats, i))
					{
						new_draw_info(NDI_UNIQUE, op, restore_msg[i]);
					}
				}

				/* in inventory of ... */
				remove_ob(depl);
				fix_player(op);
			}
			else
			{
				new_draw_info(NDI_UNIQUE, op, "You feel a great loss...");
			}

			decrease_ob(tmp);
			insert_spell_effect("meffect_green", op->map, op->x, op->y);
			play_sound_map(op->map, CMD_SOUND_EFFECT, "magic_default.ogg", op->x, op->y, 0, 0);
			return 1;
		}
		/* improvement potion */
		else if (tmp->last_eat == 2)
		{
			int success_flag = 0, hp_flag = 0, sp_flag = 0, grace_flag = 0;

			if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))
			{
				/* jump in by random - goto power */
				if (RANDOM() % 2)
				{
					goto hp_jump;
				}
				else if (RANDOM() % 2)
				{
					goto sp_jump;
				}
				else
				{
					goto grace_jump;
				}

				while (!hp_flag || !sp_flag || !grace_flag)
				{
hp_jump:
					/* mark we have checked hp chain */
					hp_flag = 1;

					for (i = 2; i <= op->level; i++)
					{
						/* move one value to max */
						if (CONTR(op)->levhp[i] != 1)
						{
							CONTR(op)->levhp[i] = 1;
							success_flag = 2;
							goto improve_done;
						}
					}
sp_jump:
					/* mark we have checked sp chain */
					sp_flag = 1;

					for (i = 2; i <= CONTR(op)->exp_ptr[EXP_MAGICAL]->level; i++)
					{
						/* move one value to max */
						if (CONTR(op)->levsp[i] != 1)
						{
							CONTR(op)->levsp[i] = 1;
							success_flag = 2;
							goto improve_done;
						}
					}
grace_jump:
					/* mark we have checked grace chain */
					grace_flag = 1;

					for (i = 2; i <= CONTR(op)->exp_ptr[EXP_WISDOM]->level; i++)
					{
						/* move one value to max */
						if (CONTR(op)->levgrace[i] != 1)
						{
							CONTR(op)->levgrace[i] = 1;
							success_flag = 2;
							goto improve_done;
						}
					}
				}

				success_flag = 3;
			}
			else
			{
				/* jump in by random - goto power */
				if (RANDOM() % 2)
				{
					goto hp_jump2;
				}
				else if (RANDOM() % 2)
				{
					goto sp_jump2;
				}
				else
				{
					goto grace_jump2;
				}

				while (!hp_flag || !sp_flag || !grace_flag)
				{
hp_jump2:
					/* mark we have checked hp chain */
					hp_flag = 1;

					for (i = 1; i <= op->level; i++)
					{
						/* move one value to max */
						if (CONTR(op)->levhp[i] != (char) op->arch->clone.stats.maxhp)
						{
							CONTR(op)->levhp[i] = (char) op->arch->clone.stats.maxhp;
							success_flag = 1;
							goto improve_done;
						}
					}
sp_jump2:
					/* mark we have checked sp chain */
					sp_flag = 1;

					for (i = 1; i <= CONTR(op)->exp_ptr[EXP_MAGICAL]->level; i++)
					{
						/* move one value to max */
						if (CONTR(op)->levsp[i] != (char) op->arch->clone.stats.maxsp)
						{
							CONTR(op)->levsp[i] = (char) op->arch->clone.stats.maxsp;
							success_flag = 1;
							goto improve_done;
						}
					}
grace_jump2:
					/* mark we have checked grace chain */
					grace_flag = 1;

					for (i = 1; i <= CONTR(op)->exp_ptr[EXP_WISDOM]->level; i++)
					{
						/* move one value to max */
						if (CONTR(op)->levgrace[i] != (char) op->arch->clone.stats.maxgrace)
						{
							CONTR(op)->levgrace[i] = (char) op->arch->clone.stats.maxgrace;
							success_flag = 1;
							goto improve_done;
						}

					}
				}
			}

improve_done:
			CLEAR_FLAG(tmp, FLAG_APPLIED);

			if (!success_flag)
			{
				new_draw_info(NDI_UNIQUE, op, "The potion had no effect - you are already perfect.");
				play_sound_map(op->map, CMD_SOUND_EFFECT, "magic_default.ogg", op->x, op->y, 0, 0);
			}
			else if (success_flag == 1)
			{
				fix_player(op);
				insert_spell_effect("meffect_yellow", op->map, op->x, op->y);
				play_sound_map(op->map, CMD_SOUND_EFFECT, "magic_default.ogg", op->x, op->y, 0, 0);
				new_draw_info(NDI_UNIQUE, op, "You feel a little more perfect!");
			}
			else if (success_flag == 2)
			{
				fix_player(op);
				insert_spell_effect("meffect_purple", op->map, op->x, op->y);
				play_sound_map(op->map, CMD_SOUND_EFFECT, "poison.ogg", op->x, op->y, 0, 0);
				new_draw_info(NDI_UNIQUE, op, "The foul potion burns like fire in you!");
			}
			/* bad potion but all values of this player are 1! poor poor guy.... */
			else
			{
				insert_spell_effect("meffect_purple", op->map, op->x, op->y);
				play_sound_map(op->map, CMD_SOUND_EFFECT, "poison.ogg", op->x, op->y, 0, 0);
				new_draw_info(NDI_UNIQUE, op, "The potion was foul but had no effect on your tortured body.");
			}

			decrease_ob(tmp);
			return 1;
		}
	}

	if (tmp->stats.sp == SP_NO_SPELL)
	{
		new_draw_info(NDI_UNIQUE, op, "Nothing happens as you apply it.");
		decrease_ob(tmp);
		return 0;
	}

	/* A potion that casts a spell.  Healing, restore spellpoint (power
	 * potion) and heroism all fit into this category. */
	if (tmp->stats.sp != SP_NO_SPELL)
	{
		/* apply potion fires in player's facing direction, unless the spell is SELF one, ie, healing or cure ilness. */
		cast_spell(op, tmp, spells[tmp->stats.sp].flags & SPELL_DESC_SELF ? 0 : op->facing, tmp->stats.sp, 1, spellPotion, NULL);
		decrease_ob(tmp);

		/* if you're dead, no point in doing this... */
		if (!QUERY_FLAG(op, FLAG_REMOVED))
		{
			fix_player(op);
		}

		return 1;
	}

	/* CLEAR_FLAG is so that if the character has other potions
	 * that were grouped with the one consumed, his
	 * stat will not be raised by them.  fix_player just clears
	 * up all the stats. */
	CLEAR_FLAG(tmp, FLAG_APPLIED);
	fix_player(op);
	decrease_ob(tmp);
	return 1;
}
예제 #22
0
bool cast_hypnotic_gaze(void) { return cast_spell(hypnotic_gaze_spell); }
예제 #23
0
bool cast_laser_eye(void) { return cast_spell(laser_eye_spell); }
예제 #24
0
void
psionic_activity(struct creature *ch)
{
    if (room_is_dark(ch->in_room)
        && !has_dark_sight(ch)
        && can_cast_spell(ch, SPELL_RETINA))
        cast_spell(ch, ch, NULL, NULL, SPELL_RETINA);
    else if (GET_HIT(ch) < GET_MAX_HIT(ch) * 0.80) {
        if (can_cast_spell(ch, SPELL_CELL_REGEN))
            cast_spell(ch, ch, NULL, NULL, SPELL_CELL_REGEN);
        else if (can_cast_spell(ch, SPELL_WOUND_CLOSURE))
            cast_spell(ch, ch, NULL, NULL, SPELL_WOUND_CLOSURE);
    } else if (!AFF_FLAGGED(ch, AFF_NOPAIN)
        && !AFF_FLAGGED(ch, AFF_SANCTUARY)
        && can_cast_spell(ch, SPELL_NOPAIN))
        cast_spell(ch, ch, NULL, NULL, SPELL_NOPAIN);
    else if (!room_has_air(ch->in_room) &&
        !can_travel_sector(ch, ch->in_room->sector_type, 0) &&
        can_cast_spell(ch, SPELL_BREATHING_STASIS) &&
        !AFF3_FLAGGED(ch, AFF3_NOBREATHE))
        cast_spell(ch, ch, NULL, NULL, SPELL_BREATHING_STASIS);
    else if (!AFF2_FLAGGED(ch, AFF2_TELEKINESIS)
        && can_cast_spell(ch, SPELL_TELEKINESIS))
        cast_spell(ch, ch, NULL, NULL, SPELL_TELEKINESIS);
    else if (!affected_by_spell(ch, SPELL_DERMAL_HARDENING)
        && can_cast_spell(ch, SPELL_DERMAL_HARDENING))
        cast_spell(ch, ch, NULL, NULL, SPELL_DERMAL_HARDENING);
    else if (!AFF3_FLAGGED(ch, AFF3_PSISHIELD)
        && can_cast_spell(ch, SPELL_PSISHIELD))
        cast_spell(ch, ch, NULL, NULL, SPELL_PSISHIELD);
    else if (can_cast_spell(ch, SPELL_PSYCHIC_RESISTANCE) &&
        !affected_by_spell(ch, SPELL_PSYCHIC_RESISTANCE))
        cast_spell(ch, ch, NULL, NULL, SPELL_PSYCHIC_RESISTANCE);
    else if (can_cast_spell(ch, SPELL_POWER)
        && !affected_by_spell(ch, SPELL_POWER))
        cast_spell(ch, ch, NULL, NULL, SPELL_POWER);
    else if (!AFF_FLAGGED(ch, AFF_CONFIDENCE)
        && can_cast_spell(ch, SPELL_CONFIDENCE))
        cast_spell(ch, ch, NULL, NULL, SPELL_CONFIDENCE);
}
예제 #25
0
bool cast_identify(void) { return cast_spell(identify_spell); }
예제 #26
0
void magic_eater_gain(void) 
{ 
    if (cast_spell(_absorb_magic_spell))
        energy_use = 100;
}
예제 #27
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;
}
예제 #28
0
void do_cmd_spell(void)
{
    spell_info spells[MAX_SPELLS];
    caster_info *caster = get_caster_info();
    int ct = 0; 
    int choice = 0;
    int max_cost = 0;

    if (!caster) 
    {
        msg_print("You cannot cast spells.");
        return;
    }
    
    if (p_ptr->confused)
    {
        msg_print("You are too confused!");
        return;
    }

    if (p_ptr->special_defense & KATA_MASK)
    {
        set_action(ACTION_NONE);
    }
    
    ct = _get_spell_table(spells, MAX_SPELLS);
    if (ct == 0)
    {
        /* User probably canceled the prompt for a spellbook */
        return;
    }

    if (caster->options & CASTER_USE_HP)
        max_cost = p_ptr->chp;
    else
        max_cost = p_ptr->csp;
    choice = choose_spell(spells, ct, caster->magic_desc, max_cost);

    if (choice >= 0 && choice < ct)
    {
        spell_info *spell = &spells[choice];

        if (spell->level > p_ptr->lev)
        {
            msg_print("You can't use that spell yet!");
            return;
        }

        /* Verify Cost ... Note, I'm removing options for over exertion 
           Also note we now pay casting costs up front for mana casters. 
           If the user cancels, then we return the cost below.
        */
        if (caster->options & CASTER_USE_HP)
        {
            if (spell->cost > p_ptr->chp)
            {
                msg_print("You do not have enough hp to use this power.");
                return;
            }
        }
        else
        {
            if (spell->cost > p_ptr->csp)
            {
                msg_print("You do not have enough mana to use this power.");
                return;
            }
            p_ptr->csp -= spell->cost;
        }

        /* Check for Failure */
        if (randint0(100) < spell->fail)
        {
            sound(SOUND_FAIL); /* Doh! */
            spell_stats_on_fail(spell);
            fail_spell(spell->fn);
            if (flush_failure) flush();
            msg_print("You failed to concentrate hard enough!");
            if (!(caster->options & CASTER_USE_HP) && demigod_is_(DEMIGOD_ATHENA) )
                p_ptr->csp += spell->cost/2;
            if (caster->on_fail != NULL)
                (caster->on_fail)(spell);
        }
        else
        {
            if (!cast_spell(spell->fn))
            {
                /* Give back the spell cost, since the user canceled the spell */
                if (!(caster->options & CASTER_USE_HP)) p_ptr->csp += spell->cost;
                return;
            }
            spell_stats_on_cast(spell);
            sound(SOUND_ZAP); /* Wahoo! */
        }

        energy_use = get_spell_energy(spell->fn);

        if ((caster->options & CASTER_USE_HP) && spell->cost > 0)
            take_hit(DAMAGE_USELIFE, spell->cost, "concentrating too hard", -1);

        if (caster->on_cast != NULL)
            (caster->on_cast)(spell);

        p_ptr->redraw |= (PR_MANA);
        p_ptr->redraw |= (PR_HP);
        p_ptr->window |= (PW_SPELL);
    }
}
예제 #29
0
void do_cmd_power(void)
{
    spell_info spells[MAX_SPELLS];
    int ct = 0; 
    int choice = 0;
    race_t *race_ptr = get_race();
    class_t *class_ptr = get_class();
    
    if (p_ptr->confused)
    {
        msg_print("You are too confused!");
        return;
    }

    /* Hack ... Rethink this a bit, but the alternative of hacking into
       the 'm' command is a million times worse! 
       Doppelgangers need to be able to cancel their current mimicry.
       Also, add Mimic power back first so it always stays in the 'a' slot. */
    if (race_ptr->mimic && p_ptr->prace == RACE_DOPPELGANGER)
    {
        ct += (get_true_race()->get_powers)(spells + ct, MAX_SPELLS - ct);
    }
    
    if (race_ptr->get_powers != NULL)
    {
        ct += (race_ptr->get_powers)(spells + ct, MAX_SPELLS - ct);
    }

    if (class_ptr != NULL && class_ptr->get_powers != NULL)
    {
        ct += (class_ptr->get_powers)(spells + ct, MAX_SPELLS - ct);
    }

    ct += mut_get_powers(spells + ct, MAX_SPELLS - ct);

    if (ct == 0)
    {
        msg_print("You have no powers.");
        return;
    }

    _add_extra_costs_powers(spells, ct);

    choice = choose_spell(spells, ct, "power", p_ptr->csp + p_ptr->chp);

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

    if (choice >= 0 && choice < ct)
    {
        spell_info *spell = &spells[choice];
        
        if (spell->level > p_ptr->lev)
        {
            msg_print("You can't use that power yet!");
            return;
        }

        if (spell->cost > p_ptr->chp + p_ptr->csp)
        {
            msg_print("Using this power will kill you!  Why not rest a bit first?");
            return;
        }

        /* Check for Failure */
        if (randint0(100) < spell->fail)
        {
            spell_stats_on_fail(spell);
            sound(SOUND_FAIL); /* Doh! */
            fail_spell(spell->fn);
            if (flush_failure) flush();
            msg_print("You failed to concentrate hard enough!");
        }
        else
        {
            if (!cast_spell(spell->fn))
                return;
            spell_stats_on_cast(spell);
            sound(SOUND_ZAP); /* Wahoo! */
        }

        energy_use = get_spell_energy(spell->fn);

        /* Casting costs spill over into hit points */
        if (p_ptr->csp < spell->cost)
        {
            int cost = spell->cost - p_ptr->csp;
            p_ptr->csp = 0;
            take_hit(DAMAGE_USELIFE, cost, "concentrating too hard", -1);
        }
        else 
            p_ptr->csp -= spell->cost;

        p_ptr->redraw |= (PR_MANA);
        p_ptr->redraw |= (PR_HP);
        p_ptr->window |= (PW_SPELL);
    }
}
예제 #30
0
파일: monk.c 프로젝트: lollek/imoria
void discipline()
{
    /*{  Use a monk's mental discipline. . . .                  -RAD-   }*/
    integer      i2;
    integer      choice,chance;
    integer      y_dumy,x_dumy;
    boolean      redraw;
    boolean      flag;

    redraw = false;
    reset_flag = true;
    if (py.flags.confused > 0) {
	msg_print("You are too confused to concentrate....");
    } else if (py.flags.image > 0) {
	msg_print("Colors and images run through your head, distracting you.");
    } else {
	flag = false;
	for (i2=0 ; (i2 < 40) && !flag ; i2++) {
	    if (magic_spell[py.misc.pclass][i2].learned) {
		flag = true;
	    }
	}
	
	if (flag) {
	    inven_temp->data = monk_book;
	    if (cast_spell("Use which discipline?",inven_temp,
			   &choice,&chance,&redraw)) {
		//with magic_spell[py.misc.pclass][choice]. do;
		reset_flag = false;
		if (randint(100) < chance) {
		    msg_print("You lost your concentration!");
		} else {
		    
		    y_dumy = char_row;
		    x_dumy = char_col;
		    d__monk_effects(choice);
		    if (!reset_flag) {
			//with py.misc do;
			PM.exp += magic_spell[py.misc.pclass][choice].sexp;
			prt_experience();
			magic_spell[py.misc.pclass][choice].sexp = 0;
		    }
		}
		//with py.misc do;
		if (!reset_flag) {
		    if (magic_spell[py.misc.pclass][choice].smana > PM.cmana) {
			msg_print("You are distracted by the effort!");
			py.flags.paralysis =
			    randint(5*trunc(magic_spell[py.misc.pclass][choice].smana-PM.cmana));
			PM.cmana = 0;
		    } else {
			PM.cmana -= magic_spell[py.misc.pclass][choice].smana;
		    }
		    prt_mana();
		}
		
	    } else {
		erase_line(1,1);
	    }
	} else {
	    msg_print("You don't know any disciplines!");
	}
    }
}