#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "emlen.h"
bool is_elemental_aligned(CHAR_DATA * ch, SPELL_DATA * spell) {
//char buffer[500];
//sprintf(buffer,"Mana Type is %d\n\r",spell->mana_type);
//send_to_char (buffer,ch);
if(IS_SET(ch->pcdata->elemental_alignment,ELEMENTAL_ALIGN_WATER) && spell->mana_type == 8)
return true;
else if(IS_SET(ch->pcdata->elemental_alignment,ELEMENTAL_ALIGN_FIRE) && spell->mana_type == 4)
return true;
else if(IS_SET(ch->pcdata->elemental_alignment,ELEMENTAL_ALIGN_EARTH) && spell->mana_type == 1)
return true;
else if(IS_SET(ch->pcdata->elemental_alignment,ELEMENTAL_ALIGN_AIR) && spell->mana_type == 2)
return true;
else if(IS_SET(ch->pcdata->elemental_alignment,ELEMENTAL_ALIGN_GOOD) && spell->mana_type == 16)
return true;
else if(IS_SET(ch->pcdata->elemental_alignment,ELEMENTAL_ALIGN_EVIL) && spell->mana_type == 16)
return true;
return false;
}
void
show_hitdam (int gsn, char *noun, int dam, CHAR_DATA * ch, CHAR_DATA * victim)
{
#ifdef NEW_WORLD
int ty;
char rvp[1024];
char rss[1024];
char *tt;
ty = 0;
if (victim->hit < 0)
return;
sprintf (rss, "$B$6Your %s *a $N.$R$7", noun);
for (tt = rss; *tt != '\0'; tt++)
{
if (*tt == '*')
{
tt++;
if (*tt == 'a')
{
strcat (rvp, (star_a (dam, victim->max_hit)));
ty = strlen (rvp);
}
}
else
{
rvp[ty] = *tt;
rvp[ty + 1] = '\0';
ty++;
}
}
act (rvp, ch, NULL, victim, TO_CHAR);
#else
dam_message (ch, victim, dam, gsn, 0);
#endif
return;
}
void
spell_summon (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *vict;
if (!target_name || target_name[0] == '\0')
return;
if ((vict = get_char_world (ch, target_name)) == NULL)
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
if (FIGHTING (vict) || LEVEL (vict) > LEVEL (ch) + 20 || !vict->in_room->area->open ||
vict->in_room->vnum < 1000 || vict == ch ||
ch->in_room->vnum < 1000)
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
if (vict->pcdata->no_quit_pk > 0 || ch->pcdata->no_quit_pk > 0)
{
send_to_char("The spell failed.\n\r", ch);
return;
}
if (vict->pcdata->no_quit > 0)
{
send_to_char("Your victim has recently cast a spell of great power and you cannot get a lock on them.\n\r", ch);
return;
}
if (IS_MOB (vict) && !pow.can_summon_mobs)
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
if ((vict->in_room && IS_SET (vict->in_room->room_flags, ROOM_NOSUMMON)) ||
(ch->in_room && IS_SET (ch->in_room->room_flags, ROOM_NOSUMMON)))
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
if (IS_PLAYER (vict) && IS_PLAYER (ch) && (DIFF_ALIGN(ch, vict)))
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
act ("$n disappears in a flash of bright light!", vict, NULL, vict, TO_ROOM);
char_from_room (vict);
char_to_room (vict, ch->in_room);
act ("$n appears in a blinding flash of light!", vict, NULL, vict, TO_ROOM);
send_to_char ("You have been summoned!!\n\r", vict);
do_look (vict, "auto");
return;
}
void
spell_teleport (int sn, int level, CHAR_DATA * ch, void *vo)
{
ROOM_DATA *rd;
CHAR_DATA *victim = (CHAR_DATA *) vo;
int i;
if (!victim)
victim = ch;
if (FIGHTING (ch))
{
send_to_char ("The spell failed!\n\r", ch);
return;
}
/*
if (IN_BATTLE(ch))
{
send_to_char ("Not in the battleground!\n\r", ch);
return;
}
if (IN_BATTLE(victim))
{
send_to_char ("Not in the battleground!\n\r", ch);
return;
}
if (IS_IMMORTAL(victim) && IS_PLAYER(victim))
{
send_to_char ("The spell failed!\n\r", ch);
return;
}
*/
if (IS_MOB (victim))
{
send_to_char ("The spell failed!\n\r", ch);
return;
}
for (i = 0;i < 10000;i++)
{
while ((rd = get_room_index (number_range (1001, 99999))) == NULL || !rd->area->open ||
rd->sector_type == SECT_WATER_NOSWIM || rd->sector_type == SECT_WATER_SWIM ||
IS_SET (rd->room_flags, ROOM_NOSUMMON));
if (IS_SET (rd->room_flags, ROOM_CANTELEPORT))
break;
}
if (IS_SET(rd->room_flags, ROOM_CANTELEPORT))
{
act ("$n disappears!", victim, NULL, victim, TO_ROOM);
char_from_room (victim);
char_to_room (victim, rd);
}
else
send_to_char ("The barriers of space are too thick, you remain where you are!\n\r", ch);
return;
}
void
spell_word_of_recall (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (IS_MOB (ch))
return;
if (!victim)
victim = ch;
if (IS_MOB (victim))
return;
if (ch->in_room && IS_SET (ch->in_room->room_flags, ROOM_NO_RECALL))
{
send_to_char ("The spell failed!\n\r", ch);
return;
}
if (FIGHTING (ch))
{
send_to_char ("The spell failed!\n\r", ch);
return;
}
if (DIFF_ALIGN(ch, victim))
return;
if (IS_AFFECTED (victim, AFF_CURSE)) {
if (victim==ch) {
send_to_char("A powerful curse is preventing you from recalling!\n\r", ch);
} else {
send_to_char("A powerful curse prevents your spell from succeeding!\n\r",ch);
}
return;
}
act ("$n disappears!", victim, NULL, victim, TO_ROOM);
char_from_room (victim);
char_to_room (victim, get_room_index (ch->pcdata->alignment+100));
victim->pcdata->no_quit_pk = 0; /* JRAJRA */
victim->pcdata->no_quit = 0;
return;
}
void
scatter_mob (CHAR_DATA * mob)
{
int just_moved_dir = -1;
int moved_rooms = 0;
int move_tries = 0;
int move_dir;
if (!mob->in_room)
return;
while (move_tries < 20 && moved_rooms < 3)
{
move_dir = number_range (0, 5);
while (move_dir == rev_dir[just_moved_dir])
move_dir = number_range (0, 5);
if (move_char (mob, move_dir))
{
move_tries++;
moved_rooms++;
just_moved_dir = move_dir;
continue;
}
else
move_tries++;
}
return;
}
void
do_spray (CHAR_DATA * ch, char *argy)
{
char buf[500];
char arg1[SML_LENGTH];
SINGLE_OBJECT *spray;
CHAR_DATA *victim;
DEFINE_COMMAND ("spray", do_spray, POSITION_FIGHTING, 0, LOG_NORMAL, "Allows you to spray a bottle of repellant at a mob.")
argy = one_argy (argy, arg1);
if (!str_prefix ("with", argy))
argy = one_argy (argy, buf);
if (argy == "" || argy[0] == '\0')
{
if ((spray = get_item_held (ch, ITEM_REPELLANT)) == NULL)
{
send_to_char ("Spray who with what?\n\r", ch);
return;
}
}
else if ((spray = get_obj_carry (ch, argy)) == NULL)
{
if ((spray = get_obj_wear (ch, argy)) == NULL)
{
send_to_char ("You don't seem to be carrying that.\n\r", ch);
return;
}
}
if (spray->pIndexData->item_type != ITEM_REPELLANT)
{
send_to_char ("You can't spray that!\n\r", ch);
return;
}
if ((victim = get_char_room (ch, arg1)) == NULL)
{
send_to_char ("I don't see a creature or person like that to spray it on.\n\r", ch);
return;
}
/* Spraying it.. remove a 'squirt' */
((I_SPRAY *) spray->more)->sprays--;
if (IS_PLAYER (victim))
{
act ("You spray $N, but $E doesn't seem to be affected.", ch, NULL, victim, TO_CHAR);
act ("$n sprays some liquid in your face, but nothing happens.", ch, NULL, victim, TO_VICT);
act ("$n sprays some liquid in $N's face, but nothing seems to happen.", ch, NULL, victim, TO_NOTVICT);
}
if (IS_MOB (victim))
{
int i;
bool yes_no = FALSE;
for (i = 0; i < 9; i++)
if (((I_SPRAY *) spray->more)->repels[i] == victim->pIndexData->vnum)
{
yes_no = TRUE;
break;
}
if (!yes_no)
{
act ("You spray $N, but $E doesn't seem to be affected.", ch, NULL, victim, TO_CHAR);
act ("$n sprays some liquid at you, but nothing happens.", ch, NULL, victim, TO_VICT);
act ("$n sprays some liquid at $N, but nothing seems to happen.", ch, NULL, victim, TO_NOTVICT);
}
else
{
act ("You spray $N.", ch, NULL, victim, TO_CHAR);
act ("$n sprays some liquid at you.", ch, NULL, victim, TO_VICT);
act ("$n sprays some liquid at $N.", ch, NULL, victim, TO_NOTVICT);
if (FIGHTING (victim))
{
if (HUNTING (victim) && !str_cmp (HUNTING (victim), NAME (ch)))
{
free_string (HUNTING (victim));
victim->fgt->hunting = NULL;
}
stop_fighting (FIGHTING (victim), TRUE);
stop_fighting (victim, TRUE);
}
scatter_mob (victim);
}
}
if (((I_SPRAY *) spray->more)->sprays < 1)
{
send_to_char ("The spray is empty, and magically disappears!\n\r", ch);
free_it (spray);
}
return;
}
/* Fix this!!! */
void
spell_dispel_magic (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (!IS_PLAYER(ch))
return;
while (victim->affected)
{
affect_remove (victim, victim->affected);
break;
}
victim->affected_by = victim->pcdata->nat_abilities;
victim->more_affected_by = victim->pcdata->nat_abilities2;
FIXIT(victim);
/* JRAJRA - Old dispel magic code..
if (victim->affected_by == 0
|| level + 30 < LEVEL (victim)
|| (saves_spell (level, victim) && saves_spell (level, victim)))
{
send_to_char ("You failed.\n\r", ch);
return;
}
for (;;)
{
affected_by = 1 << number_bits (5);
if (IS_SET (victim->affected_by, affected_by))
break;
}
REMOVE_BIT (victim->affected_by, affected_by);
send_to_char ("You successfully removed a spell from the victim!\n\r", ch);
act ("$n just removed a spell effect from you!", ch, NULL, victim, TO_VICT);
return;
*/
}
void
spell_create_object (SPELL_DATA * spell, int level, CHAR_DATA * ch, void *vo)
{
SINGLE_OBJECT *obj;
if ((obj = create_object (get_obj_index (spell->creates_obj), 0)) == NULL)
{
send_to_char ("A god has set up this spell wrong.. please contact a god.\n\r", ch);
return;
}
if (IS_SET (spell->spell_bits, SPELL_OBJ_TO_ROOM))
obj_to (obj, ch->in_room);
else
{
obj_to (obj, ch);
obj->wear_loc = -1;
}
return;
}
bool
remove_sa (SPELL_DATA * spell, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (!is_affectedt (victim, spell->bitvector) || number_range(1,9) >
get_curr_wis(ch) || number_range(1,9) > get_curr_wis(victim))
{
send_to_char ("You failed to remove any affects.\n\r", ch);
return FALSE;
}
affect_strip_bits (victim, spell->bitvector);
return TRUE;
}
void
write_stuff (SPELL_DATA * spell, CHAR_DATA * ch, CHAR_DATA * victim)
{
if (spell->act_to_ch_1)
act (spell->act_to_ch_1, ch, NULL, victim, TO_CHAR);
if (spell->act_to_ch_2)
act (spell->act_to_ch_2, ch, NULL, victim, TO_CHAR);
if (victim && spell->act_to_vict_1)
act (spell->act_to_vict_1, ch, NULL, victim, TO_VICT);
if (victim && spell->act_to_vict_2)
act (spell->act_to_vict_2, ch, NULL, victim, TO_VICT);
if (victim && ch == victim && spell->act_to_vict_1)
act (spell->act_to_vict_1, ch, NULL, victim, TO_CHAR);
if (victim && ch == victim && spell->act_to_vict_2)
act (spell->act_to_vict_2, ch, NULL, victim, TO_CHAR);
if (spell->act_to_notvict_1)
act (spell->act_to_notvict_1, ch, NULL, victim, TO_NOTVICT);
if (spell->act_to_notvict_2)
act (spell->act_to_notvict_2, ch, NULL, victim, TO_NOTVICT);
return;
}
void
general_spell (SPELL_DATA * spell, int level, CHAR_DATA * ch, void *vo)
{
if (IS_PLAYER(ch) && spell->spell_type == TAR_CHAR_OFFENSIVE &&
IS_AUGMENTED(ch, AUG_MIND_POWER) && IS_AUGMENTED(ch, AUG_HAND_SPD) &&
IS_AUGMENTED(ch, AUG_LEG_SPD) && IS_AUGMENTED (ch, AUG_FOOT_SPD) &&
IS_AUGMENTED(ch, AUG_FOCUS) && IS_AUGMENTED (ch, AUG_CHANNEL) &&
IS_AUGMENTED(ch, AUG_MENTAL_ARMOR) && IS_AUGMENTED (ch, AUG_MANA_BOOST) &&
IS_AUGMENTED(ch, AUG_MIND_FOCUS) && get_curr_wis(ch) > 27 &&
get_curr_int(ch) > 27 && number_range(1,100) == 3)
{
send_to_char("\x1b[1;31mYou have achieved a double cast!!!\n\r", ch);
general_spell2 (spell, level, ch, vo, FALSE, ch->in_room);
}
general_spell2 (spell, level, ch, vo, FALSE, ch->in_room);
return;
}
void
general_spell2 (SPELL_DATA * spell, int level, CHAR_DATA * ch, void *vo,
bool area, ROOM_DATA *targetroom)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
CHAR_DATA *next = NULL;
bool once = FALSE;
int dur = 0;
bool sskip = FALSE;
bool cast_at_n = FALSE;
bool casterBonus = false;
bool victimBonus = false;
bool alignshardBonus = false;
// Set elemental Bonus here, and use booleans below
if(spell != NULL && ch != NULL && victim != NULL) {
if(is_elemental_aligned(ch,spell)) casterBonus = true;
if(is_elemental_aligned(victim,spell)) victimBonus = true;
if(IS_SET(victim->pcdata->elemental_alignment,ELEMENTAL_ALIGN_GOOD) && ch->pcdata->alignment != 2)
alignshardBonus = true;
if(IS_SET(victim->pcdata->elemental_alignment,ELEMENTAL_ALIGN_EVIL) && ch->pcdata->alignment != 1)
alignshardBonus = true;
}
if (IS_SET (spell->spell_bits, SPELL_NOT_SELF) && ch == victim && !IS_SET (spell->spell_bits, SPELL_ALL_IN_ROOM))
{
send_to_char ("You find that you cannot cast this spell upon yourself...\n\r", ch);
return;
}
if (spell->spell_type != TAR_CHAR_OFFENSIVE && IS_SET(spell->spell_bits, SPELL_HURT_OPP_ALIGN) && !DIFF_ALIGN(ch, victim))
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
if (spell->creates_obj != 0)
{
spell_create_object (spell, level, ch, vo);
}
if (!IS_SET (spell->spell_bits, SPELL_ONLY_MULTI_MOBS) || IS_MOB (victim))
{
if (ch && victim && IS_PLAYER (ch) && IS_PLAYER(victim) &&
IS_SET (spell->spell_bits, SPELL_ALL_IN_ROOM) &&
spell->spell_type == TAR_CHAR_OFFENSIVE &&
(!DIFF_ALIGN(ch, victim)))
{
sskip = TRUE;
}
if (!sskip && IS_SET (spell->spell_bits, SPELL_ALL_IN_ROOM))
{
cast_at_n = TRUE;
if (victim != NULL && victim->in_room == ch->in_room)
victim = ch->in_room->more->people;
next = victim->next_in_room;
}
}
for (once = TRUE; ((once || next != NULL) && (!victim || (victim && victim->data_type!=50))); victim = next)
{
/* ARC:
Protect Neutral align from aggressive area spells
and prevent them from harming other players with same
*/
if (victim && IS_PLAYER (victim) && ch && IS_PLAYER(ch) && spell->spell_type == TAR_CHAR_OFFENSIVE
&& (ALIGN (victim) == 0 || ALIGN (ch) == 0) && !IN_BATTLE(ch) && ch->fgt->challenge != 10)
{
next = victim->next_in_room;
continue;
}
if (victim && IS_PLAYER (victim) && cast_at_n && IS_SET (spell->spell_bits, SPELL_ONLY_MULTI_MOBS))
{
next = victim->next_in_room;
continue;
}
else
{
if (!sskip && IS_SET (spell->spell_bits, SPELL_ALL_IN_ROOM))
next = victim->next_in_room;
else
next = NULL;
}
once = FALSE;
if (!sskip && ch)
{
if (IS_SET (spell->spell_bits, SPELL_ONLY_GROUP) &&
(DIFF_ALIGN(ch, victim) ||
(IS_PLAYER (ch) != IS_PLAYER (victim))))
continue;
if (IS_SET (spell->spell_bits, SPELL_ONLY_NOT_GROUP) &&
!DIFF_ALIGN(ch, victim) &&
IS_MOB(ch) == IS_MOB(victim))
continue;
}
/*
if (IS_IMMORTAL(victim) && IS_PLAYER(victim))
{
send_to_char ("Not on an immortal!\n\r", ch);
return;
}
*/
if (!victim)
victim = ch;
/* This is where we check all the "specials" */
if (spell->spell_bits >= SPELL_SUMMON)
{
if (IS_SET (spell->spell_bits, SPELL_LIFE_TAP))
spell_life_tap (spell->gsn, level, ch, vo);
if (IS_SET (spell->spell_bits, SPELL_RAISE_UNDEAD))
//spell_raise_undead (spell->gsn, level, ch, vo);
spell_raise_undead (spell, level, ch, vo);
if (IS_SET (spell->spell_bits, SPELL_SCRY))
spell_scry (spell->gsn, level, ch, vo);
if (IS_SET (spell->spell_bits, SPELL_LOCATE_PERSON))
spell_locate_person (spell->gsn, level, ch, vo);
if (IS_SET (spell->spell_bits, SPELL_REMOVES_BIT))
if (!remove_sa (spell, level, ch, victim))
{};
if (IS_SET (spell->spell_bits, SPELL_DISPEL_MAGIC))
spell_dispel_magic (spell->gsn, level, ch, vo);
if (IS_SET (spell->spell_bits, SPELL_IDENTIFY))
spell_identify (spell->gsn, level, ch, vo);
if (IS_SET (spell->spell_bits, SPELL_LOCATE_OBJECT))
spell_locate_object (spell->gsn, level, ch, vo);
if (IS_SET (spell->spell_bits, SPELL_TELEPORT))
spell_teleport(spell->gsn, level, ch, vo);
if (IS_SET (spell->spell_bits, SPELL_SUMMON))
spell_summon(spell->gsn, level, ch, vo);
if (IS_SET (spell->spell_bits, SPELL_RECALL))
spell_word_of_recall(spell->gsn, level, ch, vo);
if (IS_SET (spell->spell_bits, SPELL_MASS_DISTORTION))
{
victim->hit/=2;
}
if (IS_SET (spell->spell_bits, SPELL_ADD_MOVE))
{
int addmove = translate (spell->damage, level, ch);
int lvl = spell->spell_level;
int bonus = ((100 * get_curr_wis(ch))/((10 +lvl*2/7)));
affect_strip(ch, gsn_chameleon);
if (bonus > 120) bonus = 120;
if (bonus < 90) bonus /= 3;
if (bonus > 89)
{
if (is_member(ch, GUILD_HEALER)) bonus += lvl;
if (is_member(ch, GUILD_MYSTIC)) bonus += lvl/2;
if (IS_AUGMENTED(ch, AUG_MIND_FOCUS)) bonus += lvl/3+3;
bonus += (ch->pcdata->remort_times) * 8;
}
// Use elemental align modifiers here
if(casterBonus) bonus += .15 * bonus;
if(victimBonus) bonus += .15 * bonus; // its plus since this not an off spell
addmove = (((bonus)*addmove)/100);
if (IS_PLAYER(ch))
addmove = ((race_info[ch->pcdata->race].heal_percent + align_info[ch->pcdata->alignment].heal_percent)*addmove)/100;
if (IS_SET(victim->in_room->room_flags, ROOM_LOWMAGIC))
addmove/=2;
if (IS_SET(victim->in_room->room_flags, ROOM_HIGHMAGIC))
addmove= (3*addmove)/2;
victim->move += addmove;
if (victim->move > victim->max_move)
victim->move = victim->max_move;
if (victim->move < 1)
victim->move = 1;
}
if (IS_SET (spell->spell_bits, SPELL_HEALS_DAM))
{
int addhit = translate (spell->damage, level, ch);
int lvl = spell->spell_level;
int bonus = ((100 * get_curr_wis(ch))/((10 + lvl*2/7)));
affect_strip(ch, gsn_chameleon);
if (bonus > 120) bonus = 120;
if (bonus < 90) bonus /= 3;
if (bonus > 89)
{
if (is_member(ch, GUILD_HEALER)) bonus += lvl;
if (is_member(ch, GUILD_MYSTIC)) bonus += lvl/2;
if (IS_AUGMENTED(ch, AUG_MIND_FOCUS)) bonus += lvl/3+3;
bonus += (ch->pcdata->remort_times) * 8;
}
// Use elemental align modifiers here
if(casterBonus) bonus += .15 * bonus;
if(victimBonus) bonus += .15 * bonus; // its plus since this not an off spell
addhit = (((bonus)*addhit)/100);
if (IS_PLAYER(ch))
addhit = ((race_info[ch->pcdata->race].heal_percent + align_info[ch->pcdata->alignment].heal_percent)*addhit)/100;
victim->hit += addhit;
if (IS_SET(victim->in_room->room_flags, ROOM_LOWMAGIC))
addhit/=2;
if (IS_SET(victim->in_room->room_flags, ROOM_HIGHMAGIC))
addhit= (3*addhit)/2;
if (victim->hit > victim->max_hit)
victim->hit = victim->max_hit;
if (victim->hit < 1)
victim ->hit = 1;
}
}
/* ------------------------------------------------------------- */
/* Set Mana Shield Strength structure edited */
/* ------------------------------------------------------------- */
if(spell->bitvector2 == AFF_MANASHIELD)
{
int shieldStr = ch->pcdata->level;
if (is_member(ch, GUILD_WIZARD)) shieldStr += 40;
if (is_member(ch, GUILD_CONJURER)) shieldStr += 15;
if (is_member(ch, GUILD_HEALER)) shieldStr += 15;
if (is_member(ch, GUILD_MYSTIC)) shieldStr += 15;
if (is_member(ch, GUILD_NECROMANCER)) shieldStr += 40;
if (IS_AUGMENTED(ch, AUG_MIND_FOCUS)) shieldStr += 5;
if (IS_AUGMENTED(ch, AUG_FOCUS)) shieldStr += 5;
if (IS_AUGMENTED(ch, AUG_MIND_POWER)) shieldStr += 5;
shieldStr += (ch->pcdata->remort_times) * 2;
// Use elemental align modifiers here
if(casterBonus) shieldStr += .15 * shieldStr;
/* Cap it! */
if(shieldStr > 100)
shieldStr = 150;
ch->pcdata->mana_shield_strength = shieldStr;
}
write_stuff (spell, ch, victim);
if (str_cmp (spell->duration, "N/A") && translate (spell->duration, level, ch) > 0)
{
bool failed = FALSE;
dur = translate (spell->duration, level, ch);
if (spell->spell_type == TAR_CHAR_OFFENSIVE)
{
if (victim && ch != victim)
if (victim->in_room != ch->in_room && (number_range(1,5) != 3 || IS_MOB(victim)))
{
act ("$N resisted the effects of your spell!", ch, NULL, victim, TO_CHAR);
act ("You resisted the effects of $n's spell!", ch, NULL, victim, TO_VICT);
failed = TRUE;
}
else if (saves_spell(level, victim) &&
(IS_MOB(ch) || str_cmp(race_info[ch->pcdata->race].name, "flayer") || number_range(1,5) == 2))
{
act ("$N resisted the effects of your spell!", ch, NULL, victim, TO_CHAR);
act ("You resisted the effects of $n's spell!", ch, NULL, victim, TO_VICT);
if (FIGHTING (victim) == NULL && ch->in_room == victim->in_room)
set_fighting (victim, ch);
failed = TRUE;
}
if (IS_AUGMENTED(victim, AUG_MENTAL_ARMOR) || IS_AFFECTED_EXTRA(victim, AFF_MINDSHIELD))
dur = UMAX(dur/2, 1);
}
if (is_member(ch, GUILD_CONJURER)) dur += dur/3;
if (is_member(ch, GUILD_NECROMANCER)) dur += dur/3;
if (is_member(ch, GUILD_MYSTIC)) dur +=dur/3;
if (is_member(ch, GUILD_RANGER)) dur += dur/3;
if ((ch->in_room->vnum > 999 || spell->spell_type == TAR_CHAR_OFFENSIVE) && !failed )
{
int jj;
bool bigaffect = FALSE;
for (jj = 0; jj < 5; jj++)
{
if (translate (spell->modifier[jj], level, ch) != 0 &&
spell->location[jj] > 0)
bigaffect = TRUE;
}
for (jj = 0; jj < 5; jj++)
{
if (bigaffect && (translate(spell->modifier[jj], level,ch) == 0 || spell->location[jj] <= 0))
continue;
if (!bigaffect && jj > 0) break;
{
AFFECT_DATA paf;
int durr = dur;
int modif = translate (spell->modifier[jj], level, ch);
bzero (&paf, sizeof (paf));
if (is_member(ch, GUILD_CONJURER))
{
modif = (4*modif)/3;
}
paf.type = spell->gsn;
paf.duration = UMAX(0, (durr-1));
paf.location = spell->location[jj];
paf.modifier = modif;
paf.bitvector = spell->bitvector;
paf.bitvector2 = spell->bitvector2;
renew_affect ((IS_AFFECTED_EXTRA (victim,
AFF_SPELL_REFLECT) && spell->spell_type == TAR_CHAR_OFFENSIVE) ? ch : victim, &paf);
if (paf.bitvector == AFF_SLEEP)
{
do_sleep (victim, "");
NEW_POSITION(victim, POSITION_SLEEPING);
}
}
}
}
}
if (spell->spell_type == TAR_CHAR_OFFENSIVE && spell->damage != NULL)
{
int dam_left = 100;
int lvl = spell->spell_level;
int dam = translate (spell->damage, level, ch);
int mint = 17 + lvl/6;
int bonus = ((100 * get_curr_int(ch))/(mint));
check_same_side_pk(ch, victim);
/* cOMMENTED OUT BECAUSE IT BASHES PEOPLE, KINDA BUGGY
if (IS_AUGMENTED(ch, AUG_MIND_POWER)
&& is_member(ch,GUILD_WIZARD)
&& is_member(ch, GUILD_CONJURER)
&& number_range(1, UMIN(spell->spell_level, 60)) > 50
&& number_range(1,UMIN(LEVEL(ch),60)) > 50)
{
check_fgt(victim);
if (victim->fgt->ears < 9)
victim->fgt->ears = 10+number_range(1,2);
else
victim->fgt->ears += number_range(1,2);
victim->position = POSITION_BASHED;
}
*/
if (bonus > 120) bonus = 120;
if (bonus < 90) bonus /= 4;
if (bonus > 89)
{
if (IS_AUGMENTED(ch, AUG_MIND_POWER)) bonus *= (4/3);
}
bonus += (ch->pcdata->remort_times) * 6;
// THIS REMORT BONUS USED TO BE 8, LOWERED IT TO CALM MAGES DOWN
if (bonus > 150) bonus = 150;
if(!str_cmp(ch->pcdata->name,"Liberation") && !str_cmp(spell->spell_name,"Cantrip"))
bonus = 5000;
dam = ((bonus) * dam)/100;
if (IS_PLAYER(ch))
{
dam = ((race_info[ch->pcdata->race].attack_spell_percent + align_info[ch->pcdata->alignment].attack_spell_percent)*dam)/100;
/* THIS SERVES NO PURPOSE
if (IS_PLAYER(victim) && DIFF_ALIGN(ch, victim))
dam = dam*12/10;
*/
}
if(spell->spell_bits2 > 0 && victim && victim->in_room)
{
if (IS_SET (spell->spell_bits2,SPELL_FIRE))
{
if(IS_AFFECTED_EXTRA(victim,AFF_PROT_FIRE))
dam = dam *4/5;
else
spell_fire_breath (level, ch, (void *) victim);
if (victim->in_room->sector_type == SECT_DESERT || victim->in_room->sector_type == SECT_WASTELAND || victim->in_room->sector_type == SECT_LAVA)
dam = dam*5/4;
}
if (IS_SET (spell->spell_bits2,SPELL_ACID))
{
if(IS_AFFECTED_EXTRA(victim,AFF_PROT_ACID))
dam = dam*4/5;
else
spell_acid_breath (level, ch, (void *) victim);
if (victim->in_room->sector_type == SECT_WATER_SWIM || victim->in_room->sector_type == SECT_WATER_NOSWIM || victim->in_room->sector_type == SECT_UNDERWATER)
dam = dam*5/4;
}
if (IS_SET (spell->spell_bits2,SPELL_ICE))
{
if(IS_AFFECTED_EXTRA(victim,AFF_PROT_ICE))
dam = dam * 4/5;
else
spell_ice_breath (level, ch, (void *) victim);
if (victim->in_room->sector_type == SECT_ICE || victim->in_room->sector_type == SECT_ARCTIC || victim->in_room->sector_type == SECT_SNOW)
dam = dam*5/4;
}
if (IS_SET (spell->spell_bits2,SPELL_WIND))
{
if(IS_AFFECTED_EXTRA(victim,AFF_PROT_WIND))
dam = dam*4/5;
else
spell_wind_breath (level, ch, (void *) victim);
if (victim->in_room->sector_type == SECT_AIR || victim->in_room->sector_type == SECT_CLOUDS)
dam = dam*5/4;
}
if (IS_SET (spell->spell_bits2,SPELL_SHARD))
{
if(IS_AFFECTED_EXTRA(victim,AFF_PROT_SHARD))
dam = dam*4/5;
else
spell_shard_breath (level, ch, (void *) victim);
if (victim->in_room->sector_type == SECT_MOUNTAIN || victim->in_room->sector_type == SECT_HILLS || victim->in_room->sector_type == SECT_ROCKY || victim->in_room->sector_type == SECT_CANYON)
dam = dam*5/4;
}
if (IS_SET (spell->spell_bits2,SPELL_SHOCK))
{
if(IS_AFFECTED_EXTRA(victim,AFF_PROT_SHOCK))
dam = dam*4/5;
else
spell_shock_breath (level, ch, (void *) victim);
if (weather_info.sky == SKY_LIGHTNING && victim->in_room->sector_type != SECT_INSIDE && victim->in_room->sector_type < SECT_CAVE && !IS_SET(victim->in_room->room_flags, ROOM_INDOORS) && !IS_SET(victim->in_room->room_flags, ROOM_UNDERGROUND))
{
dam*=2;
}
}
}
if (!ch || !victim)
return;
if (IS_SET(victim->in_room->room_flags, ROOM_LOWMAGIC) && IS_PLAYER(ch))
dam/=2;
if (IS_SET(victim->in_room->room_flags, ROOM_HIGHMAGIC))
dam= (3*dam)/2;
if (victim->in_room->sector_type == SECT_ASTRAL)
dam*=2;
if (IS_SET (spell->spell_bits, SPELL_HURT_UNDEAD) && (IS_PLAYER (victim) || (IS_MOB (victim) && victim->pIndexData->mobtype != MOB_GHOST && victim->pIndexData->mobtype != MOB_UNDEAD)))
{
send_to_char ("This spell can only do harm to undead creatures.\n\r", ch);
return;
}
/* if (IS_SET(spell->spell_bits, SPELL_HURT_OPP_ALIGN), !DIFF_ALIGN(ch, victim))
dam = 0;*/
if (IS_AFFECTED_EXTRA(victim, AFF_SPELL_REFLECT))
{
affect_strip(victim, gsn_spell_reflect);
victim = ch;
}
if (IS_SET (spell->spell_bits, SPELL_HALVED_SAVE) && saves_spell (level, victim))
dam_left -= number_range(30,60);
if (IS_AFFECTED_EXTRA (victim, AFF_MINDSHIELD))
dam_left -= number_range(0,30);
if (IS_AUGMENTED(victim, AUG_MENTAL_ARMOR))
dam_left -= number_range(0,20);
if (dam_left < 30) dam_left = 30;
dam = ((dam_left * dam)/100);
if (victim->in_room != ch->in_room)
{
dam = dam*3/6;
if (IS_MOB(victim) && IS_SET(victim->act, ACT_SENTINEL))
dam = 0;
WAIT_STATE(ch, PULSE_VIOLENCE);
}
// Use elemental align modifiers here
if(casterBonus) {
//if(!IS_MOB(ch)) send_to_char ("U got the bonus.\n\r",ch);
dam += (.15 * dam);
}
if(victimBonus) {
//if(!IS_MOB(victim)) send_to_char ("U got the bonus.\n\r",victim);
dam -= (.15 * dam);
}
if(alignshardBonus) {
dam -= (.15 * dam);
}
damage (ch, victim, dam, spell->gsn);
show_hitdam (spell->gsn, spell->noun_damage, dam, ch, victim);
if (IS_SET (spell->spell_bits2, SPELL_VAMPIRIC))
{
ch->hit += dam/2;
if (ch->hit > ch->max_hit)
ch->hit = ch->max_hit;
act("You drain the life from $N, and it infuses your body.", ch, NULL, victim, TO_CHAR);
act("$n drain the life from you.",ch, NULL, victim, TO_VICT);
act("$n drains the life from $N.", ch, NULL, victim, TO_NOTVICT);
}
}
}
if (spell && spell->linked_to != NULL)
{
SPELL_DATA *sp;
if ((sp = skill_lookup (spell->linked_to, -1)) != NULL)
{
general_spell (sp, level, ch, vo);
}
}
if (IS_PLAYER (ch))
{
skill_gain (ch, spell->gsn, TRUE);
if (spell->spell_lag > 0 && IS_PLAYER(ch) && ch->pcdata->no_quit < spell->spell_lag)
ch->pcdata->no_quit = spell->spell_lag;
if (ch->pcdata->no_quit_pk < spell->spell_lag)
ch->pcdata->no_quit_pk = spell->spell_lag;
}
return;
}
void
spell_message (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *rec;
char buf[STD_LENGTH];
char targname[SML_LENGTH];
if (ch->pcdata->no_quit > 0)/* JRAJRA spell lag */
{
send_to_char("You cannot cast message yet!\n\r", ch);
return;
}
else
{
if (!target_name || target_name[0] == '\0')
{
send_to_char ("A voice booms from the heavens:\n\r", ch);
send_to_char ("\x1B[1;37mSyntax\x1B[0m: cast 'message' <\x1B[1;37mtarget\x1B[0m> <\x1B[1;37mmsg\x1B[0m>\n\r", ch);
return;
}
target_name = one_argy (target_name, targname);
if ((rec = get_char_world (ch, targname)) == NULL)
{
send_to_char ("You send a voice, but you get the feeling it could not deliver.\n\r", ch);
return;
}
sprintf (buf, "\x1B[1;32mA voice from afar tells you '\x1B[0m%s\x1B[1;32m'\x1B[0m\n\r",
target_name);
send_to_char (buf, rec);
sprintf (buf, "You send a mystical voice to talk to %s.", NAME (rec));
send_to_char (buf, ch);
return;
}
}
//ARC: The Life Tap Spell.
void
spell_life_tap (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *vampire = ch;
CHAR_DATA *victim = (CHAR_DATA *) vo;
int life = 0;
life = vampire->pcdata->level + 30 + number_range(1, vampire->pcdata->level);
victim->hit -= life;
vampire->hit += life;
if (vampire->max_hit < vampire->hit)
vampire->hit = vampire->max_hit;
return;
}
// The Raise Undead Spell.
void spell_raise_undead (SPELL_DATA * spell, int level, CHAR_DATA * ch, void *vo) {
CHAR_DATA *undead_creature;
MOB_PROTOTYPE *the_corpse;
MOB_PROTOTYPE *the_mobile;
AFFECT_DATA af;
char buf[500];
int sn = spell->gsn;
// Grab the target corpse object
SINGLE_OBJECT *target_corpse = (SINGLE_OBJECT *) vo;
// Return if target corpse is a PC
if ((target_corpse->pIndexData->item_type != ITEM_CORPSE_NPC)) {
send_to_char ("You just can't seem to raise that from the dead!\n\r", ch);
return;
}
// Get the mobile number from the spell data
the_mobile = get_mob_index (spell->creates_obj);
if (the_mobile == NULL || the_mobile->vnum == 1) { // Nothing there!
// Get the corpse mobs vnum number and create it
the_mobile = get_mob_index (((I_CONTAINER *)(target_corpse->more))->key_vnum);
}
if (the_mobile == NULL || the_mobile->vnum == 1) {
send_to_char ("You just can't seem to raise that from the dead!\n\r", ch);
return;
}
undead_creature = create_mobile (the_mobile);
char_to_room (undead_creature, ch->in_room);
act ("$n has raised $N from the dead\x1b[0;37m!", ch, NULL, undead_creature, TO_ROOM);
act ("You raise $N from the dead\x1b[0;37m!", ch, NULL, undead_creature, TO_CHAR);
free_it (target_corpse);
if (!(ch->number_of_mob_followers)) ch->number_of_mob_followers = 0;
else if (ch->number_of_mob_followers > 1) {
send_to_char ("But it falls *THUD* to the floor and decomposes...too many followers perhaps?\n\r",ch);
act ("But it falls *THUD* to the floor and decomposes...", ch, NULL, NULL, TO_ROOM);
free_it (undead_creature);
return;
}
bzero (&af, sizeof (af));
if (level < (LEVEL (undead_creature)-60) || IS_AFFECTED (undead_creature, AFF_NOCHARM)) {
act ("$N has been raised but snarls at you in complete hatred and attacks!", ch, NULL, undead_creature, TO_CHAR);
act ("$N snarls at $n in complete hatred and attacks!", ch, NULL, undead_creature, TO_ROOM);
check_fgt(undead_creature);
undead_creature->is_undead = TRUE;
undead_creature->fgt->fighting = ch;
NEW_POSITION(undead_creature, POSITION_FIGHTING);
multi_hit (undead_creature, ch, TYPE_UNDEFINED);
return;
}
// Fix undead stats so it can group, assist, etc
undead_creature->pcdata->alignment = ch->pcdata->alignment;
undead_creature->pIndexData->alignment = ch->pcdata->alignment;
// sprintf(buf,"Setting undead creature alignement to %d\n\r",undead_creature->pcdata->alignment);
// send_to_char (buf,ch);
undead_creature->pcdata->act2 = PLR_AUTOGOLD | PLR_AUTOSPLIT | PLR_ASSIST;
add_follower (undead_creature, ch);
do_group(ch, undead_creature->pcdata->name);
(ch->number_of_mob_followers)++;
af.type = sn;
af.duration = -1;
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_CHARM;
affect_to_char (undead_creature, &af);
undead_creature->is_undead = TRUE;
act ("$N gazes at you as if $S life revolved around you.", ch, NULL, undead_creature, TO_CHAR);
return;
}
void
spell_scry (int sn, int level, CHAR_DATA * ch, void *vo)
{
char buf[STD_LENGTH];
if (target_name == '\0')
{
return;
}
if (ch->pcdata->online_spot->located == TRUE && ch->pcdata->online_spot->pk_since_locate < 3)
{
send_to_char("You must pkill before using this spell again.\n\r", ch);
return;
}
if (!scry (ch, level, target_name))
{
sprintf (buf, "You were unable to scry %s.\n\r", target_name);
send_to_char (buf, ch);
}
else
{
ch->pcdata->online_spot->located = TRUE;
ch->pcdata->online_spot->pk_since_locate = 0;
}
return;
}
void
spell_locate_person (int sn, int level, CHAR_DATA * ch, void *vo)
{
char buf[STD_LENGTH];
if (target_name == '\0')
{
return;
}
if (!locate_person (ch, level, target_name))
{
sprintf (buf, "You were unable to locate %s.\n\r", target_name);
send_to_char (buf, ch);
}
else
{
ch->pcdata->online_spot->located = TRUE;
ch->pcdata->online_spot->pk_since_locate = 0;
}
return;
}
void
spell_identify (int sn, int level, CHAR_DATA * ch, void *vo)
{
SINGLE_OBJECT *obj = (SINGLE_OBJECT *) vo;
SPELL_DATA *spp;
char buf3[500];
char buf2[STD_LENGTH];
char buf[STD_LENGTH];
AFFECT_DATA *paf;
send_to_char (
"\x1B[0m-----------------------------------------------------------------------------\n\r",
ch);
sprintf (buf, "'%s\x1B[0m' is some sort of \x1B[1;34m%s\x1B[0m.\n\r",
STRR (obj, short_descr),
item_type_name (obj->pIndexData->item_type));
send_to_char (buf, ch);
sprintf (buf, "It weighs \x1B[1;37m%d\x1B[0;37m Stones and \x1b[1;37m%d\x1b[0;37m Pebbles , and is apparently worth \x1B[1;37m%d\x1B[0;33m copper\x1B[0m.\n\r",
(obj->pIndexData->weight/WGT_MULT),(obj->pIndexData->weight % WGT_MULT), obj->cost);
send_to_char (buf, ch);
sprintf (buf, "It is affected by [\x1B[1;34m%s\x1B[0;34m]\x1B[0m.\n\r",
extra_bit_name (obj->extra_flags));
send_to_char (buf, ch);
sprintf (buf,
"- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\r");
switch (obj->pIndexData->item_type)
{
case ITEM_SCROLL:
case ITEM_POTION:
{
I_POTION *pot = (I_POTION *) obj->more;
send_to_char (buf, ch);
sprintf (buf, "Level \x1B[1;34m%d\x1B[0m spells of:",
pot->spell_level);
send_to_char (buf, ch);
if (pot->spells[0] >= 0 && pot->spells[0] < SKILL_COUNT)
{
send_to_char (" '\x1B[1;37m", ch);
if ((spp = skill_lookup (NULL, pot->spells[0])) != NULL)
send_to_char (spp->spell_name, ch);
send_to_char ("\x1B[0m'", ch);
}
if (pot->spells[1] >= 0 && pot->spells[1] < SKILL_COUNT)
{
send_to_char (" '\x1B[1;37m", ch);
if ((spp = skill_lookup (NULL, pot->spells[1])) != NULL)
send_to_char (spp->spell_name, ch);
send_to_char ("\x1B[0m'", ch);
}
if (pot->spells[2] >= 0 && pot->spells[2] < SKILL_COUNT)
{
send_to_char (" '\x1B[1;37m", ch);
if ((spp = skill_lookup (NULL, pot->spells[2])) != NULL)
send_to_char (spp->spell_name, ch);
send_to_char ("\x1B[0m'", ch);
}
send_to_char (".\n\r", ch);
}
break;
case ITEM_WAND:
case ITEM_STAFF:
{
I_WAND *wnd = (I_WAND *) obj->more;
send_to_char (buf, ch);
sprintf (buf, "Has \x1B[34m%d\x1B[0m of \x1B[1;34m%d\x1B[0m charges of level \x1B[1;37m%d\x1B[0m",
wnd->current_charges, wnd->max_charges, wnd->spell_level);
send_to_char (buf, ch);
if (wnd->spells[0] >= 0 && wnd->spells[0] < SKILL_COUNT)
{
send_to_char (" '\x1B[1;37m", ch);
if ((spp = skill_lookup (NULL, wnd->spells[0])) != NULL)
send_to_char (spp->spell_name, ch);
send_to_char ("\x1B[0m'", ch);
}
send_to_char (".\n\r", ch);
break;
}
case ITEM_GEM:
{
I_GEM *gem = (I_GEM *) obj->more;
sprintf (buf2, "Mana Type(s): ");
if (IS_SET (gem->gem_type, MANA_FIRE))
strcat (buf2, "\x1B[1;31mFIRE ");
if (IS_SET (gem->gem_type, MANA_WATER))
strcat (buf2, "\x1B[1;34mWATER ");
if (IS_SET (gem->gem_type, MANA_EARTH))
strcat (buf2, "\x1B[0;33mEARTH ");
if (IS_SET (gem->gem_type, MANA_AIR))
strcat (buf2, "\x1B[1;36mAIR ");
if (IS_SET (gem->gem_type, MANA_SPIRIT))
strcat (buf2, "\x1B[1;34mSPIRIT ");
strcat (buf2, "\x1B[37;0m");
sprintf (buf3, "\n\rMaximum mana: \x1B[1;37m%d\x1B[0m.", gem->max_mana);
strcat (buf2, buf3);
send_to_char (buf2, ch);
send_to_char ("\n\rGems may not give you their max mana if you have low intelligence or wisdom.\n\r", ch);
sprintf (buf2, "Max spell level for this gem: %d\n\r", gem->max_level);
send_to_char (buf2, ch);
break;
}
case ITEM_WEAPON:
{
I_WEAPON *weap = (I_WEAPON *) obj->more;
send_to_char (buf, ch);
sprintf (buf, "This weapon is capable of \x1B[1;34m%d\x1B[0md\x1B[1;34m%d\x1B[0m damage.\n\r",
weap->firstdice, weap->seconddice);
send_to_char (buf, ch);
if (weap->ammo_type > 0 && IS_OBJ_STAT(obj, ITEM_RANGED))
{
sprintf(buf, "This ranged weapon takes ammunition of type %d.\n\r", weap->ammo_type);
send_to_char(buf, ch);
}
break;
}
case ITEM_AMMO:
{
I_AMMO *ammo = (I_AMMO *) obj->more;
send_to_char (buf, ch);
sprintf (buf, "This ammunition is capable of \x1B[1;34m%d\x1B[0md\x1B[1;34m%d\x1B[0m damage.\n\r",
ammo->firstdice, ammo->seconddice);
send_to_char(buf, ch);
sprintf(buf, "This ammo is of type %d.\n\r", ammo->ammo_type);
send_to_char(buf, ch);
break;
}
case ITEM_ARMOR:
{
I_ARMOR *arm = (I_ARMOR *) obj->more;
send_to_char (buf, ch);
sprintf (buf, "Leg AC: %d Body AC: %d Head AC: %d Arm AC: %d.\n\r", arm->protects_legs,
arm->protects_body, arm->protects_head, arm->protects_arms);
send_to_char (buf, ch);
break;
}
}
for (paf = obj->pIndexData->affected; paf != NULL; paf = paf->next)
{
if (paf->location != APPLY_NONE && paf->modifier != 0)
{
if (paf->modifier > 0)
sprintf (buf, "It is +\x1B[1;36m%d\x1B[0m to \x1B[36m%s\x1B[0m.\n\r",
paf->modifier, affect_loc_name (paf->location));
else
sprintf (buf, "It is -\x1B[1;36m%d\x1B[0m to \x1B[36m%s\x1B[0m.\n\r",
paf->modifier * -1, affect_loc_name (paf->location));
send_to_char (buf, ch);
}
}
for (paf = obj->affected; paf != NULL; paf = paf->next)
{
if (paf->location != APPLY_NONE && paf->modifier != 0)
{
if (paf->modifier > 0)
sprintf (buf, "It is +\x1B[1;36m%d\x1B[0m to \x1B[36m%s\x1B[0m.\n\r",
paf->modifier, affect_loc_name (paf->location));
else
sprintf (buf, "It is -\x1B[1;36m%d\x1B[0m to \x1B[36m%s\x1B[0m.\n\r",
paf->modifier * -1, affect_loc_name (paf->location));
send_to_char (buf, ch);
}
}
send_to_char (
"-----------------------------------------------------------------------------\n\r", ch);
return;
}
void
spell_locate_object (int sn, int level, CHAR_DATA * ch, void *vo)
{
char buf[SML_LENGTH];
SINGLE_OBJECT *obj;
SINGLE_OBJECT *in_obj;
bool found;
int number = 0;
found = FALSE;
if (level > 100 || LEVEL (ch) > 100)
return;
for (obj = object_list; obj != NULL && number <= LEVEL (ch);
obj = obj->next)
{
if (!can_see_obj (ch, obj) || !is_name (target_name, obj->pIndexData->name))
continue;
found = TRUE;
number++;
for (in_obj = obj; in_obj->in_obj != NULL; in_obj = in_obj->in_obj)
;
if (in_obj->carried_by != NULL)
{
sprintf (buf, "%s carried by %s.\n\r",
STRR (obj, short_descr), PERS (in_obj->carried_by, ch));
}
else
{
sprintf (buf, "%s in %s.\n\r",
STRR (obj, short_descr), in_obj->in_room == NULL
? "somewhere" : in_obj->in_room->name);
}
buf[0] = UPPER (buf[0]);
send_to_char (buf, ch);
}
if (!found)
send_to_char ("Nothing like that in hell, heaven or earth.\n\r", ch);
return;
}
void
spell_acid_breath (int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
SINGLE_OBJECT *obj_lose;
SINGLE_OBJECT *obj_next;
I_ARMOR *arm;
I_WEAPON *wep;
if (ch->in_room->vnum < 1000 || number_percent () > level)
return;
for (obj_lose = victim->carrying; obj_lose != NULL; obj_lose = obj_next)
{
obj_next = obj_lose->next_content;
if (number_range (1, 4) != 3)
continue;
switch (obj_lose->pIndexData->item_type)
{
case ITEM_ARMOR:
{
arm = (I_ARMOR *)obj_lose->more;
if (arm->condition_now > 0)
{
act ("$p is covered with acid!", victim, obj_lose, NULL, TO_CHAR);
arm->condition_now-= 4;
if (arm->condition_now <= 0)
{
obj_from(obj_lose);
free_it(obj_lose);
break;
}
if(number_range(1,50) == 2)
{
act ("$p is splashed with acid and loses some of its resilience!", victim, obj_lose, NULL, TO_CHAR);
arm->max_condition-= 3;
if (arm->max_condition < 1)
arm->max_condition = 1;
if (arm->protects_legs > 1)
arm->protects_legs -= number_bits(1);
if (arm->protects_body > 1)
arm->protects_body -= number_bits(1);
if (arm->protects_head > 1)
arm->protects_head -= number_bits(1);
if (arm->protects_arms > 1)
arm->protects_arms -= number_bits(1);
}
}
}
break;
case ITEM_WEAPON:
wep = (I_WEAPON *)obj_lose->more;
if (wep->damage_p > 0)
{
act("$p is splashed with acid!", ch, obj_lose, NULL, TO_CHAR);
wep->damage_p-=5;
if (wep->damage_p <= 0)
{
obj_from(obj_lose);
free_it(obj_lose);
break;
}
if(number_range(1,50) == 3)
{
if (wep->firstdice > 1)
wep->firstdice -= number_bits(1);
if (wep->seconddice > 1)
wep->seconddice -= number_bits(1);
act("The acid damages $p permanently!", victim, obj_lose, NULL, TO_CHAR);
if (wep->strength > 5)
wep->strength -= 3;
}
}
break;
case ITEM_CONTAINER:
act ("$p fumes and dissolves!",victim, obj_lose, NULL, TO_CHAR);
obj_from (obj_lose);
free_it (obj_lose);
break;
}
}
return;
}
void
spell_fire_breath (int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
SINGLE_OBJECT *obj_lose;
SINGLE_OBJECT *obj_next;
if (ch->in_room->vnum < 1000 || IS_AFFECTED_EXTRA (victim, AFF_PROT_FIRE) || number_percent () < level)
return;
for (obj_lose = victim->carrying; obj_lose != NULL; obj_lose = obj_next)
{
char *msg;
obj_next = obj_lose->next_content;
if (number_range (1,4) != 3)
continue;
switch (obj_lose->pIndexData->item_type)
{
default:
continue;
case ITEM_CONTAINER:
{
I_CONTAINER * cnt = (I_CONTAINER *) obj_lose->more;
if (!IS_SET(cnt->flags, CONT_INDESTRUCTABLE))
msg = "$p ignites and burns!";
else
continue;
}
break;
case ITEM_POTION:
msg = "$p bubbles and boils!";
break;
case ITEM_SCROLL:
msg = "$p crackles and burns!";
break;
case ITEM_STAFF:
msg = "$p smokes and chars!";
break;
case ITEM_WAND:
msg = "$p sparks and sputters!";
break;
case ITEM_AMMO:
msg = "$p blackens and burns!";
break;
case ITEM_FOOD:
msg = "$p blackens and crisps!";
break;
case ITEM_PILL:
msg = "$p melts and drips!";
break;
}
act (msg, victim, obj_lose, NULL, TO_CHAR);
obj_from (obj_lose);
free_it (obj_lose);
}
return;
}
void
spell_ice_breath (int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
SINGLE_OBJECT *obj_lose;
SINGLE_OBJECT *obj_next;
I_ARMOR *arm;
I_WEAPON *wep;
if (ch->in_room->vnum < 1000 || IS_AFFECTED_EXTRA (victim, AFF_PROT_ICE) || number_percent () < level)
return;
for (obj_lose = victim->carrying; obj_lose != NULL;
obj_lose = obj_next)
{
obj_next = obj_lose->next_content;
if (number_range (1, 5) != 3)
continue;
switch (obj_lose->pIndexData->item_type)
{
default:
continue;
case ITEM_POTION:
{
act ("$p turns to ice and explodes!", victim, obj_lose, NULL, TO_CHAR);
obj_from (obj_lose);
free_it (obj_lose);
}
break;
case ITEM_DRINK_CON:
{
act ("$p turns to ice and explodes!", victim, obj_lose, NULL, TO_CHAR);
obj_from (obj_lose);
free_it (obj_lose);
}
break;
case ITEM_ARMOR:
arm = (I_ARMOR *)obj_lose->more;
if (arm->condition_now > 0)
{
act ("$p freezes and cracks!", victim, obj_lose, NULL, TO_CHAR);
arm->condition_now-= 4;
if (arm->condition_now <= 0)
{
obj_from(obj_lose);
free_it(obj_lose);
break;
}
if(number_range(1,50) == 2)
{
act ("$p is frozen and permanently damaged!", victim, obj_lose, NULL, TO_CHAR);
arm->max_condition-= 3;
if (arm->max_condition < 2)
arm->max_condition = 2;
if (arm->protects_legs > 2)
arm->protects_legs -= number_bits(1);
if (arm->protects_body > 2)
arm->protects_body -= number_bits(1);
if (arm->protects_head > 2)
arm->protects_head -= number_bits(1);
if (arm->protects_arms > 2)
arm->protects_arms -= number_bits(1);
}
}
break;
case ITEM_WEAPON:
wep = (I_WEAPON *)obj_lose->more;
if (wep->damage_p > 0)
{
act("$p is frozen!", ch, obj_lose, NULL, TO_CHAR);
wep->damage_p-=5;
if (wep->damage_p <= 0)
{
obj_from(obj_lose);
free_it(obj_lose);
break;
}
if(number_range(1,50) == 3)
{
if (wep->firstdice > 1)
wep->firstdice -= number_bits(1);
if (wep->seconddice > 1)
wep->seconddice -= number_bits(1);
act("The ice damages $p permanently!", victim, obj_lose, NULL, TO_CHAR);
if (wep->strength > 5)
{
wep->strength -= 3;
}
}
}
break;
}
}
return;
}
void
spell_shard_breath (int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
SINGLE_OBJECT *obj_lose;
SINGLE_OBJECT *obj_next;
I_ARMOR *arm;
I_WEAPON *wep;
if (ch->in_room->vnum < 1000 || IS_AFFECTED_EXTRA (victim, AFF_PROT_SHARD) || number_percent () < level)
return;
for (obj_lose = victim->carrying; obj_lose != NULL;
obj_lose = obj_next)
{
obj_next = obj_lose->next_content;
if(number_range(1,4) != 3) continue;
switch (obj_lose->pIndexData->item_type)
{
default:
continue;
case ITEM_POTION:
{
act ("$p is hit with a shard and explodes!", victim,obj_lose, NULL, TO_CHAR);
obj_from (obj_lose);
free_it (obj_lose);
}
break;
case ITEM_DRINK_CON:
{
act ("$p gets zinged and rips open!", victim, obj_lose,NULL, TO_CHAR);
obj_from (obj_lose);
free_it (obj_lose);
}
break;
case ITEM_ARMOR:
arm = (I_ARMOR *)obj_lose->more;
if (arm->condition_now > 0)
{
act ("$p gets pelted with shards!", victim, obj_lose, NULL, TO_CHAR);
arm->condition_now-= 4;
if (arm->condition_now <= 0)
{
obj_from(obj_lose);
free_it(obj_lose);
break;
}
if(number_range(1,50) == 2)
{
act ("$p absorbs a solid blow from a flying sliver!", victim, obj_lose, NULL, TO_CHAR);
arm->max_condition-= 3;
if (arm->max_condition < 2)
arm->max_condition = 2;
if (arm->protects_legs > 1)
arm->protects_legs -= number_bits(1);
if (arm->protects_body > 1)
arm->protects_body -= number_bits(1);
if (arm->protects_head > 1)
arm->protects_head -= number_bits(1);
if (arm->protects_arms > 1)
arm->protects_arms -= number_bits(1);
}
}
break;
case ITEM_WEAPON:
wep = (I_WEAPON *)obj_lose->more;
if (wep->damage_p > 0)
{
act("$p gets zinged!", ch, obj_lose, NULL, TO_CHAR);
wep->damage_p-=5;
if (wep->damage_p <= 0)
{
obj_from(obj_lose);
free_it(obj_lose);
break;
}
if(number_range(1,50) == 3)
{
if (wep->firstdice > 1)
wep->firstdice -= number_bits(1);
if (wep->seconddice > 1)
wep->seconddice -= number_bits(1);
act("The shards damage $p permanently!", victim, obj_lose, NULL, TO_CHAR);
if (wep->strength > 5)
{
wep->strength -= 3;
}
}
}
break;
}
}
return;
}
void
spell_shock_breath (int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
SINGLE_OBJECT *obj;
SINGLE_OBJECT *obj_next;
if (ch->in_room->vnum < 1000 || IS_AFFECTED_EXTRA (victim, AFF_PROT_SHOCK) || number_percent () < level)
return;
for (obj = victim->carrying; obj != NULL; obj = obj_next)
{
obj_next = obj->next_content;
if (number_range (1, 4) != 3) continue;
switch (obj ->pIndexData->item_type)
{
default:
continue;
case ITEM_SCROLL:
case ITEM_PILL:
case ITEM_POTION:
{
act ("$p glows with power, then fades!", victim, obj, NULL, TO_CHAR);
if ((((I_POTION *) obj->more)->spell_level > 10) && (number_range(1,50) != 3))
((I_POTION *) obj->more)->spell_level -= number_range(5,10);
else
((I_POTION *) obj->more)->spell_level += number_range(5,10);
}
break;
case ITEM_STAFF:
case ITEM_WAND:
{
act ("$p sparks with energy, then falls silent!", victim, obj, NULL, TO_CHAR);
if ((((I_WAND *) obj->more)->current_charges > 0) && (number_range(1,50) != 3))
((I_WAND *) obj->more)->current_charges--;
else
((I_WAND *) obj->more)->current_charges++;
if ((((I_WAND *) obj->more)->spell_level > 10) && (number_range(1,50) != 3))
((I_WAND *) obj->more)->spell_level -= number_range(5,10);
else
((I_WAND *) obj->more)->spell_level += number_range(5,10);
}
break;
case ITEM_GEM:
{
if(number_range(1,3) == 3)
{
if (number_range(1,20) == 3)
{
((I_GEM *) obj->more)->gem_type =number_range(1,31);
act ("$p seems to change color before your eyes...", victim, obj, NULL, TO_CHAR);
}
if ((((I_GEM *) obj->more)->max_mana > 15) &&(number_range(1,10) == 3))
if(number_range(1,20) != 4)
{
act ("$p flares brightly and then fades...", victim, obj, NULL, TO_CHAR);
((I_GEM *) obj->more)->max_mana -= number_range(1,15);
}
else
{
act ("$p flares brightly and glows with power", victim, obj, NULL, TO_CHAR);
((I_GEM *) obj->more)->max_mana += number_range(1,15);
}
if ((((I_GEM *) obj->more)->max_level > 10) &&(number_range(1,10) == 3))
if(number_range(1,20) != 4)
{
act ("$p glows brightly and then fades...", victim, obj, NULL, TO_CHAR);
((I_GEM *) obj->more)->max_level -= number_range(1,10);
}
else
{
act ("$p glows brightly and hums with power", victim, obj, NULL, TO_CHAR);
((I_GEM *) obj->more)->max_level += number_range(1,10);
}
}
}
break;
}
}
return;
}
void
spell_wind_breath (int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (((ch->in_room->vnum >= (BATTLEGROUND_START_VNUM + bg_multiplier)) &&
(ch->in_room->vnum <= (BATTLEGROUND_END_VNUM + bg_multiplier))) ||
IS_AFFECTED_EXTRA (victim, AFF_PROT_WIND))
return;
if (number_percent () < level && !saves_spell (level, victim))
{
if ((number_range (1,50) == 5) && IS_AFFECTED(victim,
AFF_INVISIBLE))
{
affect_strip_bits (victim, AFF_INVISIBLE);
send_to_char("Everyone can SEE you now!\n\r", victim);
}
if ((number_range (1,50) == 5) && IS_AFFECTED(victim, AFF_FLYING))
{
affect_strip_bits (victim, AFF_FLYING);
send_to_char("You fall back down to the ground!\n\r", victim);
}
if (number_range (1,50) == 5 && IS_AFFECTED(victim, AFF_HIDE))
{
affect_strip_bits (victim, AFF_HIDE);
send_to_char("The burst of air uncovers your hiding place!\n\r", victim);
}
if ((number_range (1,50) == 5) && IS_AFFECTED(victim, AFF_SNEAK))
{
affect_strip_bits (victim, AFF_SNEAK);
send_to_char("The wind makes you stumble and crash!\n\r", victim);
}
if ((number_range (1,50) == 5) && IS_AFFECTED(victim, AFF_INFRARED))
{
affect_strip_bits (victim, AFF_INFRARED);
send_to_char("The dust swirls in your eyes, ruining your night vision!\n\r", victim);
}
if ((number_range (1,50) == 5) && IS_AFFECTED(victim,
AFF_DETECT_INVIS))
{
affect_strip_bits (victim, AFF_DETECT_INVIS);
send_to_char("The massive storm obscures your sensitive vision!\n\r", victim);
}
if ((number_range (1,50) == 5) && IS_AFFECTED(victim,
AFF_DETECT_HIDDEN))
{
affect_strip_bits (victim, AFF_DETECT_HIDDEN);
send_to_char("The wind makes it impossible to detect movements in the woods!\n\r", victim);
}
}
/* JRAJRAJRA */
return;
}
TRAP_DATA *
new_trap (CHAR_DATA * ch, ROOM_DATA * room)
{
TRAP_DATA *trp;
trp = (TRAP_DATA *) mem_alloc ((sizeof (*trp)));
trp->material = 1;
trp->level = LEVEL(ch);
trp->affects = 0;
room->more->trap = trp;
return trp;
}
/*
void
do_trapset (CHAR_DATA *ch, char *argy)
{
TRAP_DATA *trp;
SINGLE_OBJECT *obj;
int material, affects, level, door;
char arg1[SML_LENGTH];
DEFINE_COMMAND ("trapset", do_trapset, POSITION_STANDING, 0, LOG_NORMAL, "Creates a trap in the room!")
WAIT_STATE (ch, 35);
if (!ch || !ch->in_room) return;
check_room_more(ch->in_room);
if ((obj = get_item_held(ch, ITEM_TRAP)) == NULL)
{
send_to_char("You must be holding a trap in order to set a trap!\n\r", ch);
return;
}
if (ch->position != POSITION_STANDING)
{
send_to_char("You must be standing to set a trap!\n\r", ch);
return;
}
argy = one_argy(argy, arg1);
if ((door = get_direction_number(arg1)) < DIR_MAX)
{
EXIT_DATA *pexit;
if ((pexit = ch->in_room->exit[door]) == NULL || !pexit->to_room ||
!pexit->d_info)
{
send_to_char("What are you doing? There is no exit there.\n\r",ch);
return;
}
if(IS_SET(pexit->d_info->exit_info, EX_HASTRAP))
{
send_to_char("It's already trapped!\n\r", ch);
return;
}
if(number_range(1,120) > ch->pcdata->learned[gsn_trapset])
{
send_to_char("You failed to set the trap.\n\r", ch);
obj_from(obj);
free_it(obj);
return;
}
SET_BIT(pexit->d_info->exit_info, EX_HASTRAP);
obj_from(obj);
free_it(obj);
send_to_char("Ok, the door is now trapped.\n\r", ch);
return;
}
if (ch->in_room->more->trap)
{
ch->in_room->more->trap->material++;
ch->in_room->more->trap->material += 10;
set_off_trap(ch, ch->in_room, TRUE);
return;
}
material = ((I_TRAP *) obj->more)->material;
if (material <= 0) material = 1;
obj_from(obj);
free_it (obj);
level = LEVEL(ch);
trp = new_trap (ch, ch->in_room);
trp->level = LEVEL(ch);
trp->material = material;
trp->affects = affects;
if (((!is_member(ch, GUILD_RANGER) || !is_member(ch, GUILD_THIEFG)
|| !is_member(ch, GUILD_TINKER)) && number_range (1,120) >= ch->pcdata->learned[gsn_trapset]))
{
trp->material +=1;
trp->level +=10;
set_off_trap (ch,ch->in_room, TRUE);
}
else
send_to_char("Ok trap set.\n\r", ch);
return;
}
void
do_detrap (CHAR_DATA *ch, char* argy)
{
char arg1[SML_LENGTH];
int door;
EXIT_DATA *pexit;
SINGLE_OBJECT *obj;
DEFINE_COMMAND("detrap", do_detrap, POSITION_STANDING, 0, LOG_NORMAL, "Removes a trap from the room.")
if (IS_MOB(ch))
return;
WAIT_STATE(ch, 5*PULSE_VIOLENCE);
argy = one_argy(argy, arg1);
if(arg1[0] == '\0' || arg1 == "")
{
send_to_char("Detrap what?\n\r", ch);
return;
}
if ((door = get_direction_number (arg1)) != DIR_MAX)
{
if ((pexit = ch->in_room->exit[door]) == NULL)
{
send_to_char("There is no exit in that direction to detrap!\n\r", ch);
return;
}
if (!pexit->d_info || !IS_SET(pexit->d_info->exit_info, EX_HASTRAP))
{
send_to_char("That exit is not trapped!\n\r", ch);
return;
}
else
{
if (number_percent () < ch->pcdata->learned[gsn_detrap])
{
send_to_char("Ok, trap removed successfully.\n\r", ch);
REMOVE_BIT(pexit->d_info->exit_info, EX_HASTRAP);
skill_gain(ch, gsn_detrap, TRUE);
return;
}
else
{
send_to_char("That exit is not trapped!\n\r", ch);
return;
}
}
}
if(!str_cmp(arg1, "room"))
{
check_room_more(ch->in_room);
if(ch->in_room->more->trap == NULL)
{
send_to_char("There is no trap here to remove!\n\r", ch);
return;
}
if(number_percent() < ch->pcdata->learned[gsn_detrap])
{
TRAP_DATA *trp;
trp = ch->in_room->more->trap;
send_to_char("Ok, trap removed successfully.\n\r", ch);
free_m(trp);
ch->in_room->more->trap = NULL;
skill_gain(ch, gsn_detrap, TRUE);
return;
}
else
{
send_to_char("There is no trap here to remove!\n\r", ch);
return;
}
}
if ((obj = get_obj_here (ch, arg1, SEARCH_INV_FIRST)) != NULL)
{
if (obj->pIndexData->item_type != ITEM_CONTAINER)
{
send_to_char ("That's not a container.\n\r", ch);
return;
}
else
{
I_CONTAINER *con = (I_CONTAINER *) obj->more;
if(!IS_SET(con->flags, CONT_HASTRAP))
{
send_to_char("This container is not trapped.\n\r", ch);
return;
}
else
{
if (number_percent() < ch->pcdata->learned[gsn_detrap])
{
REMOVE_BIT(con->flags, CONT_HASTRAP);
send_to_char("Ok, trap removed successfully.\n\r", ch);
return;
}
else
{
send_to_char("This container is not trapped.\n\r", ch);
return;
}
}
}
}
else
{
send_to_char("Exactly what do you think is trapped in this room?\n\r", ch);
return;
}
return;
}
void
set_off_trap(CHAR_DATA *victim, ROOM_DATA *room, bool mistake)
{
TRAP_DATA *trp;
check_room_more(room);
if (!victim->in_room || victim->in_room != room) return;
trp = room->more->trap;
if (!room->more->trap)
{
fprintf(stderr, "Tried to set off trap and no trap in room!\n");
return;
}
level = victim->in_room->more->trap->level;
material = victim->in_room->more->trap->material;
dam = level * material/10;
{
CHAR_DATA *trapmob;
trapmob = create_mobile(get_mob_index(2));
char_to_room(trapmob, victim->in_room);
for (fch = room->more->people; fch != NULL; fch = fch_next)
{
fch_next = fch->next_in_room;
if (fch == trapmob)
continue;
act("The trap that $n set off hits $N\n\r", victim, NULL, fch, TO_NOTVICT);
act("The fallout from the trap that $n triggered hits YOU!\n\r", victim, NULL, fch, TO_VICT);
damage(trapmob, fch, dam, gsn_trapset);
}
extract_char(trapmob, TRUE);
}
{
CHAR_DATA *trapmob;
CHAR_DATA *fch;
SPELL_DATA *spl;
int dam;
trapmob = create_mobile(get_mob_index(2));
char_to_room(trapmob, victim->in_room);
check_room_more(victim->in_room);
for(fch = victim->in_room->more->people; fch != NULL; fch = fch->next_in_room)
{
dam = number_range(5,10) * number_range(5,10);
if (fch == trapmob) continue;
act("The force of the trap hits $N!", trapmob, NULL, fch, TO_NOTVICT);
act("The trap hits You!", trapmob, NULL, fch, TO_VICT);
if ((spl = skill_lookup(NULL, (number_range(61,114)))) != NULL && number_range(1,3) == 2)
{
general_spell(spl, 150, trapmob, fch);
}
else
damage(trapmob, fch, dam, gsn_trapset);
stop_fighting(trapmob, TRUE);
}
extract_char(trapmob, TRUE);
}
room->more->trap = NULL;
free_m(trp);
return;
} */