/***************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* In order to use any part of this Envy Diku Mud, you must comply with *
* the original Diku license in 'license.doc', the Merc license in *
* 'license.txt', as well as the Envy license in 'license.nvy'. *
* In particular, you may not remove either of these copyright notices. *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
* *
* ROM 2.4 is copyright 1993-1998 Russ Taylor *
* ROM has been brought to you by the ROM consortium *
* Russ Taylor (rtaylor@hypercube.org) *
* Gabrielle Taylor (gtaylor@hypercube.org) *
* Brian Moore (zump@rom.org) *
* By using this code, you have agreed to follow the terms of the *
* ROM license, in the file Rom24/doc/rom.license *
* *
* Code Adapted and Improved by Abandoned Realms Mud *
* and Aabahran: The Forsaken Lands Mud by Virigoth *
* *
* Continued Production of this code is available at www.flcodebase.com *
***************************************************************************/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "magic.h"
#include "cabal.h"
#include "recycle.h"
#include "interp.h"
char *target_name;
/* manalock effect for dispel/cancellation */
/* TRUE on removal of mana lock */
bool effect_manalock(int sn, int level, CHAR_DATA* ch, CHAR_DATA* victim)
{
int upkeep = UMAX(5, (get_skill(victim, gsn_dispel_magic) - get_skill(ch, sn)) * 2);
int chance = 50 + (get_skill(ch, gsn_mana_lock) - 60) * 2;
/*
ch is the character attempting to dispel
victim is holder of manalock
*/
//roll if we block iwth mana lock.
if (number_percent() < chance)
{
//check upkeep.
if (victim->mana < upkeep)
{
send_to_char("Unable to sustain your manalock you lose control.\n\r", victim);
affect_strip(victim, gsn_mana_lock);//VERY important to strip it first :)
spell_dispel_magic(sn, victim->level + 8, victim, victim, TARGET_CHAR);
act("The area around $n shimmers and blurs.", victim, NULL, NULL, TO_ROOM);
return TRUE;
}
else
victim->mana -= upkeep;
//do messages
if (ch == victim)
act("Your manalock seems to interfere.", ch, NULL, victim, TO_CHAR);
else
{
act("You feed energy to your manalock and negate $n's spell.", ch, NULL, victim, TO_VICT);
act("$N's manalock seems to negate your spell.", ch, NULL, victim, TO_CHAR);
}
check_improve(ch, gsn_mana_lock, TRUE, 1);
return FALSE;
}
check_improve(ch, gsn_mana_lock, FALSE, 1);
if (check_dispel(level,victim,gsn_mana_lock)){
return FALSE;
}
return FALSE;
}
void spell_cancellation( int sn, int level, CHAR_DATA *ch, void *vo,int target ){
CHAR_DATA *victim;
AFFECT_DATA* paf, *paf_next;
char arg1[MIL];
int csn = 0; //0 means cancell all
bool found = FALSE;
target_name = one_argument( target_name, arg1);
/* get the victim first */
/* CASE: null spell arguments */
if (IS_NULLSTR(arg1))
victim = ch;
/* CASE: one argument (must select if it is a person or a spell)*/
else if (IS_NULLSTR(target_name)){
/* decide between spell or victim target */
if ( (victim = get_char_room( ch, NULL, arg1)) == NULL){
victim = ch;
/* check for spell */
if ( (csn = skill_lookup(arg1)) < 1){
send_to_char("No such spell or skill.\n\r",ch);
return;
}
}
else
csn = 0; //cancel all spells
}
/* CASE: first and second argument */
else{
if ( (victim = get_char_room( ch, NULL, arg1)) == NULL){
send_to_char("They aren't here.\n\r", ch);
return;
}
if ( (csn = skill_lookup(target_name)) < 1){
send_to_char("No such spell or skill.\n\r",ch);
return;
}
}
/* victim check */
if (ch != victim && (victim->master == NULL || victim->master != ch)){
send_to_char("They are not following you.\n\r", ch);
return;
}
/* csn checks */
if (csn){
char *spell_name = IS_GEN(csn) ? effect_table[GN_POS(csn)].name : skill_table[csn].name;
if (!IS_GNBIT(csn, GN_CANCEL)){
sendf(ch, "%s cannot be cancelled.\n\r", spell_name);
return;
}
if (!is_affected(victim, csn)){
if (victim == ch){
sendf(ch, "You are not affected by %s.\n\r", spell_name);
return;
}
else{
sendf(ch, "They are not affected by %s.\n\r", spell_name);
return;
}
}
}//end csn checks
/* now we cancel the spell/spells */
/* check if there is anything to dispel */
if (csn < 1){
for (paf = victim->affected; paf; paf = paf_next){
paf_next = paf->next;
/* check if we can dispel */
if (IS_GNBIT(paf->type, GN_CANCEL))
break;
}
if (paf == NULL){
send_to_char("There are no more spells to cancel.\n\r", ch);
return;
}
}
/* look for mana lock */
if (is_affected(victim, gsn_mana_lock)){
if (effect_manalock(sn, level, ch, victim))
found = TRUE;
else
return;
}
/* begin checking spells */
for (paf = victim->affected; paf; paf = paf_next){
paf_next = paf->next;
/* always skip to the last duplicate affect */
if (paf_next && paf_next->type == paf->type)
continue;
if (csn && paf->type != csn)
continue;
/* check if we can dispel */
if (!IS_GNBIT(paf->type, GN_CANCEL))
continue;
/* can dispel, check */
if (check_dispel(level, victim, paf->type)){
found = TRUE;
}
}
if (found){
send_to_char("Ok.\n\r",ch);
/* CONTINENCY */
check_contingency(victim, NULL, CONT_DISPEL);
}
else
send_to_char("Spell failed.\n\r",ch);
}
void spell_dispel_magic( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA* paf, *paf_next;
bool found = FALSE;
/* quick check to make sure there is anything left to dispel */
/* begin checking spells */
for (paf = victim->affected; paf; paf = paf_next){
paf_next = paf->next;
if (IS_GNBIT(paf->type, GN_DISPEL))
break;
}
if (paf == NULL){
send_to_char("There is nothing left to dispel.\n\r", ch);
return;
}
/* check saves */
if (ch == victim
|| (psiamp_failed(ch, victim, level, DAM_MENTAL, skill_table[sn].spell_type, skill_table[sn].flags)
&& saves_spell(level, victim,DAM_MENTAL, skill_table[sn].spell_type))
)
{
send_to_char( "You feel a brief tingling sensation.\n\r",victim);
send_to_char( "You failed.\n\r", ch);
return;
}
/* look for mana lock */
if (is_affected(victim, gsn_mana_lock)){
if (effect_manalock(sn, level, ch, victim))
found = TRUE;
else
return;
}
/* begin checking spells */
for (paf = victim->affected; paf; paf = paf_next){
paf_next = paf->next;
/* always skip to the last duplicate affect */
if (paf_next && paf_next->type == paf->type)
continue;
/* check if we can dispel */
if (!IS_GNBIT(paf->type, GN_DISPEL))
continue;
/* can dispel, check */
if (check_dispel(level, victim, paf->type)){
found = TRUE;
}
}
if (found){
send_to_char("Ok.\n\r",ch);
/* CONTINENCY */
check_contingency(victim, NULL, CONT_DISPEL);
}
else
send_to_char("Spell failed.\n\r",ch);
}
/*effect_freeze_weapon*/
/*only in magic2.c*/
bool effect_freeze_weapon(CHAR_DATA* ch, CHAR_DATA* victim, int gsn)
{
//The effect causes a weapon of an opponent to crumble due to
//intense temp. change.
//We will need these for item.s
OBJ_DATA* wield;
OBJ_DATA* dual;
//And an int for chance.
int chance = 45;
const int luck_mod = 2;
//Few saftey checks.
if (ch == NULL || victim == NULL)
return FALSE;
//Currently this only works for icestorm.
if (gsn != skill_lookup("ice storm"))
return FALSE;
//Ad finaly we go on.
//first run the check if we succeed.
chance += (16 - get_curr_stat(victim, STAT_LUCK))*luck_mod;
//and now we roll.
if (number_percent() < chance)
{
//Ok now do the evil work.
if ( (wield = get_eq_char(victim,WEAR_WIELD)) != NULL)
{
//we check for ice as weapon material
//(everything else is destroyed, as even the magic fueling
//magical weapons is extinguished inthe terrible cold :)
if ( (wield->item_type == ITEM_WEAPON
|| wield->item_type == ITEM_WAND
|| wield->item_type == ITEM_STAFF
|| wield->item_type == ITEM_POTION
|| wield->item_type == ITEM_THROW
|| wield->item_type == ITEM_ARMOR)
&& strcmp(wield->material, "ice"))
{
if (!IS_OBJ_STAT(wield,ITEM_BURN_PROOF)
&& !IS_OBJ_STAT(wield,ITEM_HAS_OWNER)){
act("$p shatters into a hundred icy shards in $n's hands.", victim, wield, NULL, TO_ROOM);
act("Due to intense temperature stress $p shatters in your hands.", ch, wield, victim, TO_VICT);
//we destroy it!
extract_obj(wield);
}
}//END IF PROPER ITEM
}//END IF wield!=null.
}//end if <chance
//and now we roll AGAIn for the second item.
if (number_percent() > chance)
return FALSE;
//Ok now do more of the evil work.
if (( dual = get_eq_char(victim,WEAR_SHIELD)) == NULL)
{
if (( dual = get_eq_char(victim,WEAR_SECONDARY)) == NULL)
dual = get_eq_char(victim,WEAR_HOLD);
}
if (dual != NULL)
{
//we check for ice as weapon material
//(everything else is destroyed, as even the magic fueling
//magical weapons is extinguished inthe terrible cold :)
if ( (dual->item_type == ITEM_WEAPON
|| dual->item_type == ITEM_WAND
|| dual->item_type == ITEM_STAFF
|| dual->item_type == ITEM_POTION
|| dual->item_type == ITEM_THROW
|| dual->item_type == ITEM_ARMOR)
&& strcmp(dual->material, "ice"))
{
if (!IS_OBJ_STAT(dual,ITEM_BURN_PROOF)
&& !IS_OBJ_STAT(dual,ITEM_HAS_OWNER)){
act("$p shatters into a hundred icy shards in $N's hands.", victim, dual, victim, TO_ROOM);
act("Due to intense temperature stress $p shatters in your hands.", ch,dual, victim, TO_VICT);
//we destroy it!
extract_obj(dual);
}
}//END IF PROPER ITEM
}//END IF wield!=null.
return TRUE;
}//END EFFECT_FREEZE_WQEAPON
void spell_ice_storm( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *vch, *vch_next;
static const sh_int dam_each[] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 30, 35, 40, 45, 50, 55,
60, 65, 70, 75, 80, 82, 84, 86, 88, 90,
92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
115, 120, 125, 130, 135, 137, 139, 142, 145, 150
};
int dam;
level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
level = UMAX(0, level);
dam = number_range( 3 * dam_each[level] / 2, 5 * dam_each[level] / 2 );
act("You summon the elemental force of ice to your aid.", ch,NULL,NULL,TO_CHAR );
act("$n calls upon the forces of nature and creates a vortex of subzero temperature.",ch,NULL,NULL,TO_ROOM);
for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
{
vch_next = vch->next_in_room;
if ( vch != ch && !is_area_safe(ch,vch))
{
m_yell(ch,vch,FALSE);
if ( saves_spell( level, vch, DAM_COLD,skill_table[sn].spell_type) )
dam = 4 * dam / 5;
else
effect_freeze_weapon(ch, vch, sn);
damage( ch, vch, dam, sn, DAM_COLD ,TRUE);
}
}
}
/*FireStorm*/
/*linked only to magic2.c*/
void spell_firestorm( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
//The caster creates a standing storm of fire in the room.
//Intial damage is done as per table.
//update of firestorm(combat and regular) done by effect_firestorm_update(..)
//blinding effect done by effect_firebreath
//in fight.c, and act_move.c
CHAR_DATA *vch, *vch_next;
AFFECT_DATA af;
static const sh_int dam_each[] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 40, 45, 50, 55, 60, 65,
70, 75, 80, 85, 90, 92, 94, 96, 98, 100,
102, 104, 106, 108, 110,112, 114, 116, 118, 120,
122, 124, 126, 128, 130,135, 140, 145, 150, 150
};
int dam;
level= UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
level= UMAX(0, level);
dam= number_range( 2 * dam_each[level]/3, dam_each[level] * 2 );
if(is_affected(ch, gen_firestorm))
{
act("You cause the firestorm to violently expand.", ch,NULL,NULL,TO_CHAR );
act("The firestorm explodes in hellish fury!",ch,NULL,NULL,TO_ROOM);
//we cut the damage down.
dam = 3 * dam / 5;
}
else
{
act("You create a vortex of fire, sulfur, and brimstone overhead.", ch,NULL,NULL,TO_CHAR );
act("$n calls upon the forces of Hell and raises a Firestorm!",ch,NULL,NULL,TO_ROOM);
}
//We attach the firestorm effect to the caster. Now effect_update_firestorm will check this
//when appropriate and do damage/clear it etc.
//The modifier is the room vnum, TO_NONE prevent this from being shown on casters aff.
if (!is_affected(ch, gen_firestorm))
{
af.where = TO_AFFECTS;
af.type = gen_firestorm;
af.level = level;
af.duration = number_range(0, 1);
af.location = APPLY_NONE;
af.modifier = ch->in_room->vnum;
af.bitvector = 0;
affect_to_char(ch,&af);
}
//We run through all the people in the room.
for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
{
vch_next = vch->next_in_room;
if ( saves_spell( level, vch, DAM_FIRE,skill_table[sn].spell_type) )
dam /= 2;
//And we do damage unless safe.
if ( vch != ch && !is_area_safe(ch,vch))
{
m_yell(ch,vch,FALSE);
//Now we do the chance to blind effect.
//the effect blinds unless victim svs at (lvl/4 +dam/15) lvl.
fire_effect(vch, ch->level, 2 * dam, TARGET_CHAR);
damage( ch, vch, dam, sn, DAM_FIRE ,TRUE);
}//end if safe
}//end for vch
}//end spell_firestorm
/*New druid spell. Testing. Don't touch. -Shadow */
void spell_arms_of_gaia( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (((IS_GOOD(ch) && IS_EVIL(victim)) || (IS_EVIL(ch) &&
IS_GOOD(victim))) && !IS_IMMORTAL(ch))
{
sendf(ch, "It would go against your beliefs to aid %s.\n\r",
PERS(victim,ch));
return;
}
if (ch->in_room->sector_type != SECT_FOREST)
{
send_to_char("You cannot seem to surround yourself outside of a forest.\n\r",ch);
return;
}
if (is_affected(victim, sn))
{
send_to_char("You are already within Gaia's arms.\n\r", ch);
return;
}
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = 5 + level;
af.location = APPLY_AC;
af.modifier = -50;
af.bitvector = 0;
affect_to_char( victim, &af );
act_new( "You surround yourself in the Arms of Gaia.", victim, NULL, NULL, TO_CHAR, POS_DEAD );
act( "$n bows $s head and proffers a blessing to the Earth Mother.", victim, NULL, NULL, TO_ROOM );
}
void spell_protective_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( ch, sn ) )
{
send_to_char("You are already shielded.\n\r",ch);
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level/6);
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_PROTECT_SHIELD;
affect_to_char( victim, &af );
act( "You surround yourself in a protective shell of magic.", ch, NULL, NULL, TO_CHAR );
act( "$n is surrounded by a protective shell of magic.", ch, NULL, NULL, TO_ROOM );
}
void spell_missile_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target){
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( ch, sn ) ){
send_to_char("You are already shielded.\n\r",ch);
return;
}
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = 24;
af.location = 0;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( victim, &af );
act( "You are now protected from ranged weapons.", ch, NULL, NULL, TO_CHAR );
act( "$n is surrounded by a missile shield.", ch, NULL, NULL, TO_ROOM );
}
void spell_jet_steam( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
OBJ_DATA *fountain;
bool found = FALSE;
//test for weather
if (ch->in_room->sector_type == SECT_WATER_SWIM
|| ch->in_room->sector_type == SECT_WATER_NOSWIM
|| ( mud_data.weather_info.sky >= SKY_RAINING && temp_adjust( ch->in_room->temp ) > 35))
found = TRUE;
//if still nto found, test for fountain.
if (!found)
for ( fountain = ch->in_room->contents; fountain != NULL; fountain = fountain->next_content )
if ( fountain->item_type == ITEM_FOUNTAIN )
{
found = TRUE;
break;
}
//now if we havent found anythign by this time then we fail.
if ( !found )
{
send_to_char("You need a source of water to cast that spell.\n\r",ch);
return;
}
dam = 50 + dice( 6, 3 ) * level/10;
if ( saves_spell( level, victim, DAM_DROWNING,skill_table[sn].spell_type ) )
dam /= 2;
act("You make the water sizzle with heat.", ch,NULL,NULL,TO_CHAR );
act("$n channels energy into the water.",ch,NULL,NULL,TO_ROOM);
damage( ch, victim, dam, sn,DAM_DROWNING,TRUE);
}
void spell_mystic_tendrils( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
int m_gain = number_range(level/2, level) + int_app[get_curr_stat(ch,STAT_INT)].practice * 2,
chance = number_percent(), dam = number_range(level/2, 2 * level / 3);
chance += (dam - level) /10;
chance += 2*(get_curr_stat(ch,STAT_LUCK) - 16);
if ( ch->hit < dam)
{
send_to_char( "You tear into your physical body.\n\r", ch );
damage(ch,ch,dam,sn, DAM_NONE,TRUE);
}
else
{
send_to_char( "You tear into your physical body.\n\r", ch );
damage( ch, ch, dam, sn,DAM_NONE,TRUE);
if (chance < 20)
{
send_to_char("Something disturbs you and you lose the spell.\n\r",ch);
m_gain = 0;
}
else if (chance < 60)
{
send_to_char("You regain some mental strength.\n\r",ch);
m_gain /= 2;
}
else if (chance < 90)
{
send_to_char("You regain more mental strength.\n\r",ch);
}
else
{
send_to_char("Yes! You feel a sudden surge of mental strength.\n\r",ch);
m_gain *= 2;
}
ch->mana = UMIN(ch->max_mana, ch->mana + m_gain);
}
}
void spell_ice_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED2(victim, AFF_FIRE_SHIELD) || IS_AFFECTED2(victim, AFF_ICE_SHIELD) || IS_AFFECTED2(victim,AFF_MANA_SHIELD))
{
send_to_char("You are already surrounded by a shield.\n\r",ch);
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level/7);
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_ICE_SHIELD;
affect_to_char( victim, &af );
act( "An icy blue shell of cold revolves around you.", ch, NULL, NULL, TO_CHAR );
act( "$n is surrounded by an icy blue shell.", ch, NULL, NULL, TO_ROOM );
}
void spell_fire_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED2(victim, AFF_FIRE_SHIELD) || IS_AFFECTED2(victim, AFF_ICE_SHIELD) || IS_AFFECTED2(victim,AFF_MANA_SHIELD))
{
send_to_char("You are already surrounded by a shield.\n\r",ch);
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level/7);
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_FIRE_SHIELD;
affect_to_char( victim, &af );
act( "A flaming sphere revolves around you.", ch, NULL, NULL, TO_CHAR );
act( "$n is surrounded by a sphere of flames.", ch, NULL, NULL, TO_ROOM );
}
void spell_mana_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED2(victim, AFF_FIRE_SHIELD) || IS_AFFECTED2(victim, AFF_ICE_SHIELD) || IS_AFFECTED2(victim,AFF_MANA_SHIELD))
{
send_to_char("You are already surrounded by a shield.\n\r",ch);
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level/7);
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_MANA_SHIELD;
affect_to_char( victim, &af );
act( "A shimmering sphere of magic encases you.", ch, NULL, NULL, TO_CHAR );
act( "$n is encased by a shimmering sphere of magic.", ch, NULL, NULL, TO_ROOM );
}
void spell_hellstream( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA* paf;
OBJ_DATA *obj_melt;
bool issave = FALSE;
const int base_chance = 3;
const int glow_mod = 4;
const int hum_mod = 4;
const int enchant_mod = 18;
const int svs_mod = 12;
const int melt_check = 40; //chance to start melting when svs fail.
int dam = (7 * level / 2) + (level / 5) * (dice( 3, 6 ) + 2);
if ( saves_spell(level + 2, victim, DAM_ENERGY,skill_table[sn].spell_type ) )
{
issave = TRUE;
dam /= 2;
}
act("You bow your head as you call forth the full power of the arcane.", victim,NULL,ch,TO_VICT );
act("The ground erupts as you are caught in a searing beam of arcane light.",victim,NULL,ch,TO_CHAR);
act("The ground erupts as $n is caught in a searing beam of arcane light.",victim,NULL,NULL,TO_ROOM);
//Check if we should start meltint
if (number_percent() < melt_check && !issave
&& check_immune(victim, DAM_ENERGY, FALSE) != IS_IMMUNE)
{
int chance = 0;
//Begin cycling through all items and melting.
for ( obj_melt = victim->carrying; obj_melt != NULL; obj_melt = obj_melt->next_content)
{
bool has_saves = FALSE;
chance = base_chance;
//we add up modifiers
if (IS_OBJ_STAT(obj_melt, ITEM_GLOW))
chance += glow_mod;
if (IS_OBJ_STAT(obj_melt, ITEM_HUM))
chance += hum_mod;
//Now we check for saves vs spell or aff.
if (obj_melt->enchanted)
chance+= enchant_mod;
else //Item is NOT enchanted
{
//Begin searching throgh paf's for svs
for ( paf = obj_melt->pIndexData->affected; paf != NULL; paf = paf->next )
if( (paf->location == APPLY_SAVING_AFFL) || (paf->location == APPLY_SAVING_SPELL) )
has_saves = TRUE;
}//end non-enchant check.
//check regular affects unless we already found one
if (!has_saves)
for ( paf = obj_melt->affected; paf != NULL; paf = paf->next )
if( (paf->location == APPLY_SAVING_AFFL) || (paf->location == APPLY_SAVING_SPELL) )
has_saves = TRUE;
//Finaly now if there are saves we apply the mod.
if (has_saves)
chance+= svs_mod;
//We check if we blow it.
if ( ( number_percent() < chance)
&& !IS_OBJ_STAT(obj_melt,ITEM_BURN_PROOF)
&& !IS_OBJ_STAT(obj_melt,ITEM_HAS_OWNER))
{
if (has_saves)
act("$p shudders under the stress and explodes.",ch,obj_melt,NULL, TO_ALL);
else
{
act("$p crumbles in $n's hellstream.",ch,obj_melt,NULL,TO_ROOM);
act("$p crumbles in your hellstream.",ch,obj_melt,NULL,TO_CHAR);
}//end else (has saves)
//check if we spill items.
if (obj_melt->item_type == ITEM_CONTAINER)
{
OBJ_DATA *t_obj, *n_obj;
act("The items in $p scatter to the ground.",victim,obj_melt,NULL,TO_CHAR);
for (t_obj = obj_melt->contains; t_obj != NULL; t_obj = n_obj)
{
n_obj = t_obj->next_content;
obj_from_obj(t_obj);
if ((number_bits(2) == 0 || victim->in_room == NULL)
&& !IS_OBJ_STAT(t_obj,ITEM_BURN_PROOF))
extract_obj(t_obj);
else
obj_to_room(t_obj,victim->in_room);
}//end for t_obj
}//end if CONTAINER
extract_obj(obj_melt);
}//end if blow
}//end for obj_melt
}//end if notsave
damage( ch, victim, dam, sn,DAM_ENERGY,TRUE);
}//edn spell_hellstream
void spell_flesh_golem( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
AFFECT_DATA af;
CHAR_DATA *mob;
int dur = (is_affected(ch, gsn_soul_tap) ? 6 : 12);
/* cap to ignore spell level boost */
level = UMIN(ch->level, level);
if (get_summoned(ch, MOB_VNUM_FLESH_GOLEM) > 0)
{
send_to_char("Your flesh golem is already in existence.\n\r",ch);
return;
}
if ( is_affected( ch, sn ) )
{
send_to_char("You do not feel up to creating another flesh golem.\n\r",ch);
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = dur;
af.location = 0;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
act ("You create a flesh golem!", ch, NULL, NULL, TO_CHAR);
act ("$n creates a flesh golem!", ch, NULL, NULL, TO_ROOM);
mob = create_mobile( get_mob_index( MOB_VNUM_FLESH_GOLEM ) );
char_to_room(mob,ch->in_room);
mob->level = level;
mob->max_hit = ch->level*17;
mob->hit = mob->max_hit;
mob->alignment = ch->alignment;
SET_BIT(mob->affected_by, AFF_CHARM);
mob->comm = COMM_NOTELL|COMM_NOYELL|COMM_NOCHANNELS;
mob->summoner = ch;
mob->hitroll = ch->level/5;
mob->damroll = ch->level/5 + 5;
mob->damage[DICE_NUMBER] = URANGE(2,(ch->level/10),4);
mob->damage[DICE_TYPE] = (ch->level/10) +4;
add_follower(mob,ch);
mob->leader=ch;
}
void spell_stone_golem( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
AFFECT_DATA af;
CHAR_DATA *mob;
int dur = (is_affected(ch, gsn_soul_tap) ? 6 : 12);
/* cap to ignore spell level boost */
level = UMIN(ch->level, level);
if (!can_follow(ch, ch))
return;
if (get_summoned(ch, MOB_VNUM_STONE_GOLEM) > 0)
{
send_to_char("Your stone golem is already in existence.\n\r",ch);
return;
}
if ( is_affected( ch, sn ) )
{
send_to_char("You do not feel up to creating another stone golem.\n\r",ch);
return;
}
level = UMIN(ch->level, level);
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = dur;
af.location = 0;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
act ("You create a stone golem!", ch, NULL, NULL, TO_CHAR);
act ("$n creates a stone golem!", ch, NULL, NULL, TO_ROOM);
mob = create_mobile( get_mob_index( MOB_VNUM_STONE_GOLEM ) );
char_to_room(mob,ch->in_room);
mob->level = level;
mob->max_hit = level*17;
mob->hit = mob->max_hit;
mob->alignment = ch->alignment;
SET_BIT(mob->affected_by, AFF_CHARM);
mob->comm = COMM_NOTELL|COMM_NOYELL|COMM_NOCHANNELS;
mob->summoner = ch;
mob->hitroll = level/5 + 5;
mob->damroll = (level/5)*2 + 7;
mob->damage[DICE_NUMBER] = URANGE(3,(level/10),5);
mob->damage[DICE_TYPE] = (level/10)*2 + 1;
add_follower(mob,ch);
mob->leader=ch;
}
void spell_soul_capture(int sn,int level,CHAR_DATA *ch, void *vo,int target)
{
OBJ_DATA *obj = (OBJ_DATA *) vo, *newobj;
CHAR_DATA *victim;
char buf[MSL];
bool found = FALSE;
if (obj->item_type == ITEM_CORPSE_NPC
|| obj->owner == 0
|| obj->condition < 2
|| obj->pIndexData->vnum == OBJ_VNUM_FAKE_CORPSE)
{
send_to_char("You cannot seem to find a soul.\n\r",ch);
return;
}
if (obj->item_type != ITEM_CORPSE_PC)
{
send_to_char("There's no soul in that!\n\r",ch);
return;
}
if (obj->level < 15 && !IS_IMMORTAL(ch))
{
send_to_char("Not on that corpse.\n\r",ch);
return;
}
if (!can_loot(ch, obj)){
act("$g's power shields $p from your greedy fingers.", ch, obj, NULL, TO_CHAR);
return;
}
for (victim = player_list; victim != NULL; victim = victim->next_player)
if (victim->id == obj->owner)
{
found = TRUE;
break;
}
if (!found)
{
send_to_char("The soul has faded away.\n\r",ch);
return;
}
newobj = create_object(get_obj_index(OBJ_VNUM_SOUL),0);
free_string( newobj->short_descr );
sprintf( buf, "the soul of %s", victim->name);
newobj->short_descr = str_dup( buf );
free_string( newobj->description );
sprintf( buf, "The soul of %s has been captured.", victim->name);
newobj->description = str_dup( buf );
obj_to_char( newobj, ch );
sprintf( buf, "You capture the soul of %s.", victim->name);
act (buf, ch, NULL, NULL, TO_CHAR);
sprintf( buf, "$n captures the soul of %s.", victim->name);
act (buf, ch, NULL, NULL, TO_ROOM);
free_string(obj->description);
obj->description = str_dup("A desiccated corpse lies here.");
obj->condition = 1;
}
void spell_vampiric_touch( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam = dice( 20, 2 );
int gain = 0;
if ( saves_spell( level, victim, DAM_ENERGY,skill_table[sn].spell_type ) )
dam /= 2;
if (ch != victim){
gain = 20 + dice ( 7, 5 );
/* scale gain by level */
gain = UMAX(1, victim->level) * gain / ch->level;
}
else
gain = 0;
if ( damage( ch, victim, dam, sn,DAM_ENERGY,TRUE)){
ch->hit = UMIN( ch->max_hit, ch->hit + gain);
}
}
void spell_hold_undead( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (ch == victim)
{
send_to_char( "You can't hold yourself.\n\r",ch);
return;
}
if (!IS_UNDEAD(victim))
{
sendf( ch, "%s is unaffected by your spell.\n\r", PERS(victim,ch) );
multi_hit( victim, ch, TYPE_UNDEFINED );
return;
}
if ( IS_AFFECTED2(victim, AFF_HOLD) )
{
sendf(ch, "%s is already as calm as can be.\n\r", PERS(victim,ch));
return;
}
if ( saves_spell( level, victim, DAM_CHARM,skill_table[sn].spell_type ) )
{
sendf(ch, "You failed to hold %s.\n\r", PERS(victim,ch));
multi_hit( victim, ch, TYPE_UNDEFINED );
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( 1 );
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_HOLD;
affect_to_char( victim, &af );
af.where = TO_AFFECTS;
af.bitvector = AFF_SLOW;
affect_to_char( victim, &af );
act_new( "Your body stops responding as $n bars you from your agressive nature.", ch,NULL,victim,TO_VICT,POS_DEAD );
act("$n exerts $s presence over $N.",ch,NULL,victim,TO_NOTVICT);
act("$N freezes and calms down as you exert your presence.",ch,NULL,victim,TO_CHAR);
}
CHAR_DATA* create_zombie(CHAR_DATA* ch, CHAR_DATA* victim, OBJ_DATA* obj)
{
CHAR_DATA* mob;
int i;
char buf[MSL];
AFFECT_DATA af;
mob = create_mobile( get_mob_index( MOB_VNUM_ZOMBIE ) );
mob->level = UMIN(52, victim->level);
mob->alignment = ch->alignment;
mob->sex = victim->sex;
mob->class = victim->class;
mob->size = victim->size;
//check for origins npc/pc
if (obj->item_type == ITEM_CORPSE_NPC)
{
if (victim->max_hit != 0)
mob->max_hit = UMIN(2000,victim->max_hit /3);
else
mob->max_hit = 1;
mob->hit = mob->max_hit;
if (victim->hitroll != 0)
mob->hitroll = UMIN(40, victim->hitroll / 2);
else
mob->hitroll = 0;
if (victim->damroll != 0)
mob->damroll = URANGE(1, victim->damroll / 2, 45);
else
mob->damroll = 0;
for (i = 0; i < 4; i++)
{
if (victim->armor[i] != 0)
mob->armor[i] = victim->armor[i];
else
mob->armor[i] = 0;
}
//set stats
for (i = 0; i < MAX_STATS; i++)
{
mob->perm_stat[i] = victim->perm_stat[i]/2;
mob->mod_stat[i] = victim->mod_stat[i]/2;
}
//set dam and acts.
mob->dam_type = victim->dam_type;
mob->act = victim->act;
mob->off_flags = victim->off_flags;
//remove unneccessary flags
REMOVE_BIT(mob->off_flags,ASSIST_ALL);
REMOVE_BIT(mob->off_flags,ASSIST_ALIGN);
REMOVE_BIT(mob->off_flags,ASSIST_RACE);
REMOVE_BIT(mob->off_flags,ASSIST_PLAYERS);
REMOVE_BIT(mob->off_flags,ASSIST_GUARD);
REMOVE_BIT(mob->off_flags,ASSIST_VNUM);
REMOVE_BIT(mob->off_flags,CABAL_GUARD);
REMOVE_BIT(mob->off_flags,GUILD_GUARD);
REMOVE_BIT(mob->off_flags,OFF_AREA_ATTACK);
REMOVE_BIT(mob->act,ACT_SCAVENGER);
REMOVE_BIT(mob->act,ACT_IS_HEALER);
REMOVE_BIT(mob->act,ACT_TRAIN);
REMOVE_BIT(mob->act,ACT_PRACTICE);
REMOVE_BIT(mob->act,ACT_TOO_BIG);
SET_BIT(mob->act,ACT_UNDEAD);
//setup combat stats
for (i = 0; i < 3; i++)
{
if (victim->damage[i] != 0)
mob->damage[i] = UMAX(1, victim->damage[i]/2);
else
mob->damage[i] = 0;
}
}//END IF NPC
else
{
mob->max_hit = 20 * victim->level;
mob->hit = mob->max_hit;
//DAM/HIT
mob->hitroll = victim->level/10;
mob->damroll = 2*victim->level/5;
//ARMOR
for (i = 0; i < 3; i++)
mob->armor[i] = interpolate(victim->level,100,-100);;
mob->armor[3] = interpolate(victim->level,100,0);;
//STATS
for (i = 0; i < MAX_STATS; i++)
{
mob->perm_stat[i] = victim->perm_stat[i];
mob->mod_stat[i] = victim->mod_stat[i];
}
if (obj->level != 0)
mob->damage[0] = obj->level/7;
else
mob->damage[0] = 0;
mob->damage[1] = 5;
mob->damage[2] = 1;
}//END PC
//SETUP COMON THINGS
obj->short_descr[0] = LOWER(obj->short_descr[0]);
sprintf( buf, "A zombie of %s", obj->short_descr);
str_replace( buf, "the corpse of ", "" );
free_string( mob->short_descr );
mob->short_descr = str_dup( buf );
sprintf( buf, "A zombie of %s stands here serving %s master.\n\r", obj->short_descr, (ch->sex == 2) ? "her" : "his");
str_replace( buf, "the corpse of ", "" );
free_string( mob->long_descr );
mob->long_descr = str_dup( buf );
//Load Zombie into room
char_to_room(mob,ch->in_room);
SET_BIT(mob->affected_by, AFF_CHARM);
mob->comm = COMM_NOTELL|COMM_NOYELL|COMM_NOCHANNELS;
//Setup the stats.
mob->summoner = ch;
add_follower(mob,ch);
mob->leader=ch;
//check inv.
empty_obj(obj);
//add an effect to store original mobs vnum.
//bitvector stores the offense flags seton the zombie, acts' are done manualy when loading
af.type = skill_lookup("animate corpse");
af.level = 60;
af.duration = -1;
/* store current offense flags in bitvector */
af.where = TO_NONE;
af.bitvector = mob->off_flags;
/* store original vnum in modifier (if PC corpse, then just zombie vnum) */
af.location = APPLY_NONE;
af.modifier = IS_NPC(victim) ? victim->pIndexData->vnum : mob->pIndexData->vnum;
affect_to_char(mob, &af);
return mob;
}//end Create zombie
void spell_animate_corpse(int sn,int level,CHAR_DATA *ch, void *vo,int target)
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
AFFECT_DATA af;
CHAR_DATA *victim;
bool found = FALSE;
bool fAdv = is_affected(ch, gsn_soul_tap);
int dur = 12;
int chance = 0;
if (get_summoned(ch, MOB_VNUM_ZOMBIE) >= UMAX(1,(ch->level/10)-2) && !IS_IMMORTAL(ch))
{
send_to_char("You can't control another zombie.\n\r",ch);
return;
}
if (!can_follow(ch, ch))
return;
if ( is_affected( ch, sn ) )
{
send_to_char("You are too drained to animate anything.\n\r",ch);
return;
}
if (obj->item_type != ITEM_CORPSE_PC && obj->item_type != ITEM_CORPSE_NPC)
{
send_to_char("That's not a corpse.\n\r",ch);
return;
}
if (obj->owner == 0 || obj->pIndexData->vnum == OBJ_VNUM_FAKE_CORPSE)
{
send_to_char("There is not enough power left in that corpse.\n\r",ch);
return;
}
if (obj->item_type == ITEM_CORPSE_PC)
{
if (obj->level < 15 && !IS_IMMORTAL(ch))
{
send_to_char("Not on that corpse.\n\r",ch);
return;
}
if (!can_loot(ch, obj)){
act("$g's power shields $p from your greedy fingers.", ch, obj, NULL, TO_CHAR);
return;
}
for (victim = player_list; victim != NULL; victim = victim->next_player)
if (victim->id == obj->owner)
{
found = TRUE;
break;
}
if (!found)
{
send_to_char("There is not enough power left in that corpse.\n\r",ch);
return;
}
}
else if (obj->item_type == ITEM_CORPSE_NPC && obj->owner == 3)
{
send_to_char("There is not enough power left in that corpse.\n\r",ch);
return;
}
else
victim = create_mobile( get_mob_index( obj->owner ) );
if (fAdv)
chance = 125;
else
chance = get_skill(ch,sn);
if (chance < 1)
chance = 75;
if (obj->level - ch->level > 10
|| obj->level > 52
|| number_percent() > chance + 5*(ch->level - obj->level) - 25 + (get_curr_stat(ch,STAT_LUCK)-16))
{
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = dur/2;
af.location = 0;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
act("You destroyed the corpse.",ch,NULL,NULL,TO_CHAR);
act("$n destroyed the corpse.",ch,NULL,NULL,TO_ROOM);
//empty obj
empty_obj(obj);
obj_from_room ( obj );
extract_obj ( obj );
}
else
{
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = dur;
af.location = 0;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
act ("You raise the dead into the form of a zombie!", ch, NULL, NULL, TO_CHAR);
act ("$n raises the dead!", ch, NULL, NULL, TO_ROOM);
create_zombie(ch, victim, obj);
if (IS_NPC(victim))
extract_char(victim,TRUE);
obj_from_room ( obj );
extract_obj ( obj );
}
}
void spell_shatter( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
//This is the new shatter spell.
/*
EFFECTS:
0 = Arms (-lvl/7 str, -lvl/5 hit/dam )
1 = Legs (-lvl/7 dex, enfeeble)
2 = Pelvis(-lvl/2% Mvs, +lvl/3% Damage, lvl%/2 Dysentry)
3 = Skull ( - (lvl to 3 *lvl/2)% mana, + lvl/3% damage, lvl/2% misdirection)
4 = Spleen (Drained, -lvl%2Mv, +1/8 Hp Dam)
*/
static const sh_int dam_each[] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15, 15, 15, 15, 15, 18, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 40, 50, 60,
62, 64, 66, 68, 70, 72, 74, 76, 78, 70,
81, 82, 83, 84, 85, 95, 105, 115, 130, 145
};
//POINTERS
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
//BUFFERS
char part[MSL], buf[MSL];
//DATA
int dam;
int number = number_range(0,4);
//CONST
//arm
const int arm_str = number_fuzzy(8);
const int arm_hit = number_fuzzy(8);
const int arm_dam = number_fuzzy(8);
const int arm_dur = number_fuzzy(8);
//legs
const int leg_dex = number_fuzzy(8);
const int leg_mov = 1;
const int leg_enf = 2;
const int leg_dur = number_fuzzy(8);
//pelvis
const int pel_mov = 2;
const int pel_dam = 3;
const int pel_dys = 2;
const int pel_dur = 2;
//skull
const int sku_dam = 3;
const int sku_mis = 2;
const int sku_dur = 5;
//spleen
const int spl_mov = 2;
const int spl_dam = 8;
const int spl_dur = 5;
//FLAGS
bool fAutoFail = FALSE;
//Get current damage
level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
level = UMAX(0, level);
dam = number_range(3 * dam_each[level] / 4, dam_each[level]);
//check if we fail.
if (is_affected( victim, sn ))
fAutoFail = TRUE;
else if ( saves_spell( level, victim, DAM_NEGATIVE,skill_table[sn].spell_type ) )
fAutoFail = TRUE;
//Display teh fail message.
if (fAutoFail)
send_to_char("You failed to shatter their bones.\n\r", ch);
else
{
switch(number)
{
/* ARMS */
case (0) :
sprintf(part, "arms");
af.type = sn;
af.level = level;
af.duration = level/arm_dur;
af.bitvector = 0;
af.where = TO_AFFECTS2;
af.location = APPLY_HITROLL;
af.modifier = -level/arm_hit;
affect_to_char( victim, &af );
af.where = TO_AFFECTS2;
af.location = APPLY_DAMROLL;
af.modifier = -level/arm_dam;
affect_to_char( victim, &af );
af.where = TO_AFFECTS2;
af.location = APPLY_STR;
af.modifier = -level/arm_str;
affect_to_char( victim, &af );
break;
/* LEGS */
case (1) :
sprintf(part, "legs");
victim->move -= (level / leg_mov) * victim->move / 100;
af.type = sn;
af.level = level;
af.duration = level/leg_dur;
af.bitvector = 0;
af.where = TO_AFFECTS2;
af.location = APPLY_DEX;
af.modifier = -level/leg_dex;
affect_to_char( victim, &af );
//check for chance to enfeeble.
if (number_percent() < level / leg_enf)
spell_enfeeblement(skill_lookup("enfeeblement"), level, ch, victim, TARGET_CHAR);
break;
/* PELVIS */
case (2) :
sprintf(part, "pelvis");
dam += (level / pel_dam) * dam / 100;
victim->move -= (level / pel_mov) * victim->move / 100;
af.type = sn;
af.level = level;
af.duration = level/pel_dur;
af.bitvector = 0;
af.where = TO_AFFECTS;
af.location = APPLY_NONE;
affect_to_char( victim, &af );
//chance for dysentry
if (number_percent() < level / pel_dys)
spell_dysentery(skill_lookup("dysentery"), level, ch, victim, TARGET_CHAR);
break;
/* SKULL */
case (3) :
sprintf(part, "skull");
dam += (level / sku_dam) * dam / 100;
victim->mana -= (number_range(level, 3 * level / 2)) * victim->mana / 100;
af.type = sn;
af.level = level;
af.duration = level/sku_dur;
af.bitvector = 0;
af.where = TO_AFFECTS2;
af.location = APPLY_NONE;
af.modifier = level;
affect_to_char( victim, &af );
//check for misdiretion
if (number_percent() < level / sku_mis)
{
af.type = gsn_misdirection;
af.level = level;
af.duration = level/sku_dur;
af.bitvector = 0;
af.where = TO_NONE;
af.location = APPLY_NONE;
af.modifier = level;
affect_to_char( victim, &af );
}
break;
/* SPLEEN */
case (4) :
sprintf(part, "spleen");
dam += victim->hit / spl_dam;
victim->move -= UMAX(0, (level / spl_mov) * victim->move / 100);
af.type = sn;
af.level = level;
af.duration = level/spl_dur;
af.location = APPLY_NONE;
af.where = TO_AFFECTS;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( victim, &af );
if (!is_affected(victim, gsn_drained))
{
af.type = gsn_drained;
af.where = TO_NONE;
af.location = APPLY_NONE;
af.modifier = 0;
affect_to_char( victim, &af );
}
break;
}
//floor the mvoe and mana properly.
if (victim->mana < 0)victim->mana = 0;
if (victim->move < 0)victim->move = 0;
sprintf(buf, "You shatter $N's %s!", part);
act(buf,ch,NULL,victim,TO_CHAR);
sprintf(buf, "You feel a sharp pain in your %s!", part);
act(buf,ch,NULL,victim,TO_VICT);
sprintf(buf, "$n shatters $N's %s!", part);
act(buf,ch,NULL,victim,TO_NOTVICT);
damage( ch, victim, number_fuzzy(dam), sn,DAM_NEGATIVE,TRUE);
}//end if
}//end do shatter.
void spell_chorus_of_anguish( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *vch, *vch_next;
int dam;
act("The cries of the damned fill the air.",ch,NULL,NULL,TO_ALL);
dam = level * 1.5 + dice(3,15);
for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
{
vch_next = vch->next_in_room;
if (saves_spell(level,vch,DAM_NEGATIVE,skill_table[sn].spell_type))
dam /= 2;
if (vch != ch && !is_area_safe(ch,vch))
{
send_to_char("You can't stand the cries of the damned.\n\r",vch);
m_yell(ch,vch,FALSE);
damage(ch,vch,dam,sn,DAM_NEGATIVE,TRUE);
}
}
}
void spell_strength_damned( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
int dur = (is_affected(ch, gsn_soul_tap) ? 30 : 60);
if (!IS_NPC(victim))
{
send_to_char("Not on players.\n\r",ch);
return;
}
if (!IS_AFFECTED(victim,AFF_CHARM) || ch != victim->master || victim->pIndexData->vnum != MOB_VNUM_ZOMBIE)
{
sendf(ch, "You don't have control over %s.\n\r", PERS(victim,ch));
return;
}
if ( is_affected( ch, sn ) )
{
send_to_char("You can't seem to find a source of unholy strength.\n\r",ch);
return;
}
if ( is_affected( victim, sn ) )
{
sendf(ch, "You can't strengthen %s any further.\n\r", PERS(victim,ch));
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = dur + 2 * (50 - level);
af.location = 0;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
af.duration = -1;
affect_to_char( victim, &af );
act("$N's wounds close as $E grows larger with unholy strength.",ch,NULL,victim,TO_ALL);
victim->max_hit = 3 * victim->max_hit / 2;
victim->hit = victim->max_hit;
victim->damage[0] = UMAX(1, 3*victim->damage[0]/2);
victim->damage[1] = UMAX(1, 3*victim->damage[1]/2);
victim->perm_stat[STAT_STR] = UMIN(25, 5 * victim->perm_stat[STAT_STR]/2);
victim->mod_stat[STAT_STR] = UMIN(25, 3 * victim->mod_stat[STAT_STR]/2);
victim->perm_stat[STAT_DEX] = UMIN(25, 3 * victim->perm_stat[STAT_DEX]/2);
victim->mod_stat[STAT_DEX] = UMIN(25, 3 * victim->mod_stat[STAT_DEX]/2);
}
void spell_death_grasp( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af, *paf;
int dam = number_fuzzy(level);
for ( paf = victim->affected; paf != NULL; paf = paf->next )
if (paf->type == gsn_death_grasp)
if (paf->modifier >= 5)
{
send_to_char("You can't drain any more vitality.\n\r",ch);
return;
}
level += (ch->tattoo == deity_lookup("cycle") ? level/10 : 0);
level += (20 - get_curr_stat(victim, STAT_CON));
/* the below is done, so each 2% of skill over 75 results in -1 save to spell*/
level += (get_skill(ch, sn) - 75) / 5;
if ( !saves_spell( level, victim, DAM_NEGATIVE,skill_table[sn].spell_type ) )
{
af.where = TO_AFFECTS2;
af.type = gsn_death_grasp;
af.level = level;
af.duration = level/10;
af.location = 0;
af.modifier = 1;
af.bitvector = 0;
affect_join( victim, &af );
act("Rotting hands erupt from the ground and drain your vitality.",ch,NULL,victim,TO_VICT);
act("Rotting hands erupt from the ground and claw at $N.",victim,NULL,victim,TO_ROOM);
}
damage( ch, victim, dam, sn,DAM_NEGATIVE,TRUE);
}
void spell_powerword_kill( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA *paf;
//DATA
int times = 0;
int chance = 0;
int skill = get_skill(ch, skill_lookup("powerword kill"));
int dam = number_fuzzy(100) + dice(10,15);
//CONST
const int luck_mod = 2;
const int grasp_mod = 7;
const int lvl_mod = 2;
const int skill_mod = 1;
const int skill_med = 75;
//begin calulating chances.
//Get the number of times target was grasped.
for ( paf = victim->affected; paf != NULL; paf = paf->next )
if (paf->type == gsn_death_grasp)
times += paf->modifier;
//calculate the chance:
chance += (get_curr_stat(victim,STAT_LUCK) - get_curr_stat(ch,STAT_LUCK)) / luck_mod;
chance += grasp_mod * times;
chance += (UMAX(0, victim->level - ch->level)) / lvl_mod * UMAX(1, times);
if (IS_NPC(victim))
chance += 15;
else
chance += skill_mod * (skill - skill_med) / 100;
if (chance > 60) chance = 60;
//give chance con bonus (not affected by ceiling)
chance = 20 * chance / get_curr_stat(victim, STAT_CON);
if (victim->level > 50 || (!IS_NPC(victim) && times < 2))
chance = 0;
if (IS_IMMORTAL(ch))
chance = 100;
//special checks.
if (IS_UNDEAD(victim))
chance = 0;
// sendf(ch, "chance: %d\n\r", chance);
if ( (number_percent() < chance
&& !IS_IMMORTAL(victim))
&& (!IS_NPC(victim) || !IS_SET(victim->act,ACT_TOO_BIG))){
act("You point your finger at $N and $E crumples to the ground.",ch,NULL,victim,TO_CHAR);
act("$n points a finger at you and utters Word of Death.",ch,NULL,victim,TO_VICT);
act("$N crumples to the ground, face frozen and contorted in fear.",ch,NULL,victim,TO_NOTVICT);
act( "$n is DEAD!!", victim, NULL, NULL, TO_ROOM );
act_new( "You have been KILLED!!", victim, NULL, NULL, TO_CHAR, POS_DEAD );
raw_kill(ch, victim);
do_autos(ch);
victim->hit = 1;
victim->mana = 1;
return;
}
else
{
act("Spell failed.",ch,NULL,victim,TO_CHAR);
act_new("Your heart stops beating for a split second.",ch,NULL,victim,TO_CHARVICT,POS_DEAD);
if (paf){
paf->modifier -= 2;
if (paf->modifier < 1)
affect_strip(victim, gsn_death_grasp);
}
}
damage( ch, victim, dam, sn, DAM_NEGATIVE ,TRUE);
}
void spell_knock( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
int door = (int) vo, np = number_percent();
ROOM_INDEX_DATA *to_room;
CHAR_DATA *gch;
EXIT_DATA *pexit = ch->in_room->exit[door], *pexit_rev;
if ( door < 0 )
return;
for ( gch = ch->in_room->people; gch; gch = gch->next_in_room )
if ( IS_NPC(gch) && IS_AWAKE(gch) && ch->level + 5 < gch->level )
{
act( "$N is standing too close to the lock.",ch, NULL, gch, TO_CHAR );
return;
}
if ( !IS_SET(pexit->exit_info, EX_CLOSED) && !IS_IMMORTAL(ch))
{ send_to_char( "It's not closed.\n\r", ch ); return; }
if ( pexit->key < 0 && !IS_IMMORTAL(ch))
{ send_to_char( "It can't be picked.\n\r", ch ); return; }
if ( !IS_SET(pexit->exit_info, EX_LOCKED) )
{ send_to_char( "It's already unlocked.\n\r", ch ); return; }
if ( IS_SET(pexit->exit_info, EX_PICKPROOF) && !IS_IMMORTAL(ch))
{ send_to_char( "You failed to open the door.\n\r", ch ); return; }
if ( !IS_SET(pexit->exit_info, EX_EASY) )
np = 2*np/3;
if ( !IS_SET(pexit->exit_info, EX_HARD) )
np = 3*np/2;
if ( !IS_SET(pexit->exit_info, EX_INFURIATING) )
np *= 2;
if ( !IS_NPC(ch) && UMAX(1,np - 2*(get_curr_stat(ch,STAT_LUCK) - 16)) > get_skill(ch,sn))
{
send_to_char( "You failed to open the door.\n\r", ch);
return;
}
REMOVE_BIT(pexit->exit_info, EX_LOCKED);
act( "An arcane hand raps gently upon the $d as the lock glows.", ch, NULL, pexit->keyword, TO_ALL );
if ( ( to_room = pexit->to_room ) != NULL && ( pexit_rev = to_room->exit[rev_dir[door]] ) != NULL
&& pexit_rev->to_room == ch->in_room )
REMOVE_BIT( pexit_rev->exit_info, EX_LOCKED );
}
void spell_blur( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( ch, sn ) )
{
send_to_char("You are already blurred.\n\r",ch);
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 2);
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_BLUR;
affect_to_char( victim, &af );
act( "Your physical contours become distorted.", ch, NULL, NULL, TO_CHAR );
act( "$n's contours become blurred.", ch, NULL, NULL, TO_ROOM );
}
void spell_phantasmal_griffon( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (victim == ch)
{
send_to_char("You can't fool yourself.\n\r",ch);
return;
}
if ( is_affected( ch, sn ) )
{
send_to_char("You can't create that illusion right now.\n\r",ch);
return;
}
af.where = TO_AFFECTS2;
af.type = gsn_phantasmal_griffon;
af.level = 100;
af.duration = -1;
af.location = 0;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
act("You call your phantasmal griffon to your aid!",ch,NULL,victim,TO_CHAR);
act("A griffon screams from above!",ch,NULL,victim,TO_ALL);
damage( ch, victim, 0, sn,DAM_NONE,FALSE);
}
void spell_illusionary_spectre( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (victim == ch)
{
send_to_char("You can't fool yourself.\n\r",ch);
return;
}
if ( is_affected( ch, sn ) )
{
send_to_char("You can't create that illusion right now.\n\r",ch);
return;
}
af.where = TO_AFFECTS2;
af.type = gsn_illusionary_spectre;
af.level = 100;
af.duration = -1;
af.location = 0;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
act("You send an illusionary spectre into the battle!",ch,NULL,victim,TO_CHAR);
act("A spectre materializes from the Nexus!",ch,NULL,victim,TO_ALL);
damage( ch, victim, 0, sn,DAM_NONE,FALSE);
}
void spell_phantom_dragon( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (victim == ch)
{
send_to_char("You can't fool yourself.\n\r",ch);
return;
}
if ( is_affected( ch, sn ) )
{
send_to_char("You can't create that illusion right now.\n\r",ch);
return;
}
af.where = TO_AFFECTS2;
af.type = gsn_phantom_dragon;
af.level = 100;
af.duration = -1;
af.location = 0;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
act("You send an esoteric phantasm into battle!",ch,NULL,victim,TO_CHAR);
act("An esoteric phantasm takes form and assails your senses!",ch,NULL,victim,TO_ALL);
damage( ch, victim, 0, sn,DAM_NONE,FALSE);
}
void spell_shrink( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (saves_spell( level, victim, DAM_MALED,skill_table[sn].spell_type ))
{
send_to_char("You failed.\n\r", ch);
return;
}
if ( is_affected( victim, sn ) || victim->size <= SIZE_TINY)
{
if (victim == ch)
act("You are already as small as possible.",ch,NULL,victim,TO_CHAR);
else
act("$N can't be shrunken any further.", ch,NULL,victim,TO_CHAR);
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = level / 6;
af.location = APPLY_SIZE;
af.modifier = -1;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_CON;
af.modifier = -2;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = -2;
affect_to_char( victim, &af );
af.location = APPLY_DAMROLL;
af.modifier = -3;
affect_to_char( victim, &af );
act_new( "The world and everything around you gets bigger.", victim,NULL,NULL,TO_CHAR,POS_DEAD );
act("$n shrinks in size.",victim,NULL,NULL,TO_ROOM);
}
void spell_enlarge( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) || victim->size >= SIZE_HUGE)
{
if (victim == ch)
act("You are already enlarged.",ch,NULL,victim,TO_CHAR);
else
act("You can't make $N any larger.", ch,NULL,victim,TO_CHAR);
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = level / 6;
af.location = APPLY_SIZE;
af.modifier = 1;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_CON;
af.modifier = 2;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = 2;
affect_to_char( victim, &af );
af.location = APPLY_DAMROLL;
af.modifier = 3;
affect_to_char( victim, &af );
act_new( "The world and everything around you seem to shrink.", victim,NULL,NULL,TO_CHAR,POS_DEAD );
act("$n dwarfs everything around $m as $e grows.",victim,NULL,NULL,TO_ROOM);
}
void spell_veil( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
{
if (victim == ch)
act("You are as veiled as it gets.",ch,NULL,victim,TO_CHAR);
else
act("$N is already surrounded by the dark walls.", ch,NULL,victim,TO_CHAR);
return;
}
if ( saves_spell( level, victim, DAM_MALED,skill_table[sn].spell_type ))
{
sendf(ch, "You failed to veil %s in darkness.\n\r", PERS(victim,ch));
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = (level / 6) + 1;
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_TERRAIN;
affect_to_char( victim, &af );
act("Thick shadows veil $n from outside world.", victim, NULL, NULL, TO_ROOM);
act("Thick walls of darkness veil you from the outside world.",ch, NULL, victim, TO_VICT);
}
void spell_prismatic_spray( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const sh_int dam_each[] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 30, 41,
42, 43, 44, 44, 45, 45, 46, 46, 47, 48,
49, 50, 51, 51, 52, 52, 53, 53, 54, 55,
56, 57, 58, 58, 59, 59, 60, 60, 61, 62,
63, 64, 65, 65, 66, 66, 67, 67, 68, 69
};
int dam;
level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
level = UMAX(0, level);
dam = number_range( dam_each[level], dam_each[level] * 2 );
act("A prism of colors shoot out from your hands.", ch,NULL,NULL,TO_CHAR );
act("A prism of colors shoot out from $n's hands.",ch,NULL,NULL,TO_ROOM);
switch(number_range(0,9))
{
case 0 :
act_new("You are struck by a beam of violet light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n is struck by a beam of violet light.",victim,NULL,NULL,TO_ROOM);
if ( saves_spell( level, victim, DAM_LIGHT,SPELL_AFFLICTIVE ) )
dam /= 2;
break;
case 1 :
act_new("You are struck by a beam of orange light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n is struck by a beam of orange light.",victim,NULL,NULL,TO_ROOM);
if ( saves_spell( level, victim, DAM_MALED,SPELL_MALEDICTIVE ) )
dam /= 2;
else
spell_slow(skill_lookup("slow"), level, ch, (void *) victim,TARGET_CHAR);
break;
case 2 :
act_new("You are struck by a beam of yellow light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n is struck by a beam of yellow light.",victim,NULL,NULL,TO_ROOM);
if ( saves_spell( level, victim, DAM_MALED,SPELL_MALEDICTIVE ) )
dam /= 2;
else
spell_blindness(gsn_blindness, level, ch, (void *) victim,TARGET_CHAR);
break;
case 3 :
act_new("You are struck by a beam of green light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n is struck by a beam of green light.",victim,NULL,NULL,TO_ROOM);
if ( saves_spell( level, victim, DAM_POISON,SPELL_MALEDICTIVE ) )
dam /= 2;
else
spell_poison(gsn_poison, level, ch, (void *) victim,TARGET_CHAR);
break;
case 4 :
act_new("You are struck by a beam of blue light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n is struck by a beam of blue light.",victim,NULL,NULL,TO_ROOM);
if ( saves_spell( level, victim, DAM_MALED,SPELL_MALEDICTIVE ) )
dam /= 2;
else
spell_weaken(skill_lookup("weaken"), level, ch, (void *) victim,TARGET_CHAR);
break;
case 5 :
act_new("You are struck by a beam of violet light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n is struck by a beam of violet light.",victim,NULL,NULL,TO_ROOM);
if ( saves_spell( level, victim, DAM_LIGHT,SPELL_AFFLICTIVE ) )
dam /= 2;
break;
case 6 :
act_new("You are struck by a beam of white light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n is struck by a beam of white light.",victim,NULL,NULL,TO_ROOM);
dam = 3 * dam /2;
if ( saves_spell( level, victim, DAM_LIGHT,SPELL_AFFLICTIVE ) )
dam /= 2;
break;
default :
act_new("You are struck by a beam of red light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n is struck by a beam of red light.",victim,NULL,NULL,TO_ROOM);
dam /= 2;
if ( saves_spell( level, victim, DAM_LIGHT,SPELL_AFFLICTIVE ) )
dam /= 2;
break;
}
damage( ch, victim, dam, sn, DAM_LIGHT, TRUE);
}
void spell_misdirection( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
act("With a flash of arcane energy a mighty thunderclap explodes beside $N.", ch, NULL, victim, TO_NOTVICT);
act("With a flash of arcane energy a mighty thunderclap explodes beside you.", ch, NULL, victim, TO_VICT);
damage(ch, victim, level, gsn_misdirection, DAM_SOUND, TRUE);
//deafen if vuln to sound. (damage or spell)
if (check_immune(victim,DAM_SOUND, TRUE) == IS_VULNERABLE
|| check_immune(victim,DAM_SOUND,FALSE) == IS_VULNERABLE)
spell_silence(gsn_silence, level + 5, ch, victim, TARGET_CHAR );
if ( is_affected( victim, sn ) )
{
if (victim == ch)
act("You are already dazed.",ch,NULL,victim,TO_CHAR);
else
act("$N already is dazed and confused.", ch,NULL,victim,TO_CHAR);
return;
}
if ( saves_spell( level, victim, DAM_SOUND,skill_table[sn].spell_type ))
{
act("$n covers $s ears just in time!", victim, NULL, NULL, TO_ROOM);
act("You cover your ears just in time!", victim, NULL, NULL, TO_CHAR);
return;
}
act("$s ears trickling with blood, $n looks around dazed and confused.", victim, NULL, NULL, TO_ROOM);
act("The mighty force of explosion dazes your senses and confuses your mind.", victim, NULL, NULL, TO_CHAR);
af.where = TO_AFFECTS2;
af.type = sn;
af.level = number_range(0,5);
af.duration = level / 10 - 1;
af.location = APPLY_DEX;
af.modifier = -1;
af.bitvector = AFF_MISDIRECTION;
affect_to_char( victim, &af );
af.level = number_range(0,5);
af.location = APPLY_INT;
af.modifier = -1;
af.bitvector = AFF_MISDIRECTION;
affect_to_char( victim, &af );
}
void spell_deluge_water( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam = level + dice( 10, 5 );
if ( saves_spell( level, victim, DAM_DROWNING,skill_table[sn].spell_type ) )
dam /= 2;
act("You create a cube of water.", ch,NULL,NULL,TO_CHAR );
act("$n creates a cube of water.",ch,NULL,NULL,TO_ROOM);
damage( ch, victim, dam, sn,DAM_DROWNING,TRUE);
}
void spell_shadowform( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( ch, sn ) )
{
send_to_char("You are already in shadowform.\n\r",ch);
return;
}
if (get_charmed_by(ch))
{
send_to_char( "You can't hide yourself when you have followers.\n\r", ch);
return;
}
if ( IS_AFFECTED(ch, AFF_FAERIE_FOG) || IS_AFFECTED(ch, AFF_FAERIE_FIRE))
{
send_to_char( "You can't change your form while glowing.\n\r", ch);
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = get_skill(ch, sn) < 1 ? number_fuzzy(7) : 12;
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_SHADOWFORM;
affect_to_char( victim, &af );
af.bitvector = AFF_PASS_DOOR;
act( "Your body loses its substance as you take on an ethereal form.", ch, NULL, NULL, TO_CHAR );
act( "$n's body loses its substance, and $e dematerializes.", ch, NULL, NULL, TO_ROOM );
}
void spell_feeblemind( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
{
if (victim == ch)
act("You are already feebleminded.",ch,NULL,victim,TO_CHAR);
else
act("$N already under the effects of feeblemind.",ch,NULL,victim,TO_CHAR);
return;
}
if ( saves_spell( level, victim, DAM_MENTAL,skill_table[sn].spell_type ) )
{
sendf(ch, "You failed to feeblemind %s.\n\r", PERS(victim,ch));
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = level/5;
af.location = APPLY_INT;
af.modifier = -(level-5)/3;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_WIS;
af.modifier = -level/5;
affect_to_char( victim, &af );
act_new("You feel your mind slipping away.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n gets a blank look on $s face.",victim,NULL,NULL,TO_ROOM);
}
void spell_flame_arrow(int sn,int level,CHAR_DATA *ch,void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const sh_int dam_each[] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54 ,55, 56, 60, 63, 69, 70, 71,
72, 74, 76, 78, 80, 81, 82, 83, 84, 85,
85, 85, 85, 85, 85, 90, 92, 94, 98, 100
};
int dam;
level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
level = UMAX(0, level);
dam = number_range( dam_each[level], 3 * dam_each[level] / 2 );
act("You create a flaming arrow and send it streaking towards $N.",ch,NULL,victim,TO_CHAR);
act("$n creates a flaming arrow and points it towards you.",ch,NULL,victim,TO_VICT);
act("$n creates a flaming arrow.",ch,NULL,victim,TO_NOTVICT);
if (IS_AFFECTED2(ch, AFF_FIRE_SHIELD)
&& check_immune(victim, DAM_FIRE, TRUE) != IS_VULNERABLE)
dam += (10 + 2 * dam / 10);
if ( saves_spell( level, victim,DAM_FIRE,skill_table[sn].spell_type) )
dam /= 2;
damage( ch, victim, dam, sn, DAM_FIRE ,TRUE);
}
void spell_iceball( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *vch, *vch_next;
static const sh_int dam_each[] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 30, 35, 40, 45, 50, 55,
60, 65, 70, 75, 80, 82, 84, 86, 88, 90,
90, 90, 90, 90, 90, 92, 94, 96, 98, 100,
101, 102, 103, 104, 105, 106, 107, 108, 109, 110
};
int dam;
level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
level = UMAX(0, level);
dam = number_range(3 * dam_each[level] / 4, 2 * dam_each[level]);
for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
{
vch_next = vch->next_in_room;
if ( saves_spell( level, vch, DAM_COLD,skill_table[sn].spell_type) )
dam = 80 * dam / 100;
if ( vch != ch && !is_area_safe(ch,vch))
{
m_yell(ch,vch,FALSE);
damage( ch, vch, dam, sn, DAM_COLD ,TRUE);
}
}
}
void spell_icicle(int sn,int level,CHAR_DATA *ch,void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const sh_int dam_each[] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44 ,45, 46, 50, 52, 53, 54, 55,
66, 67, 68, 68, 69, 70, 72, 74, 78, 80,
85, 86, 87, 88, 89, 90, 92, 94, 98, 100
};
int dam;
level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
level = UMAX(0, level);
dam = number_range( dam_each[level], 3 * dam_each[level] / 2 );
act("You conjure a magical bolt of ice and launch it at $N.",ch,NULL,victim,TO_CHAR);
act("$n conjures a magical bolt of ice and launches it at you.",ch,NULL,victim,TO_VICT);
act("$n conjures a magical bolt.",ch,NULL,victim,TO_NOTVICT);
if (IS_AFFECTED2(ch, AFF_ICE_SHIELD)
&& check_immune(victim, DAM_COLD, TRUE) != IS_VULNERABLE)
dam += (10 + 2 * dam / 10);
if ( saves_spell( level, victim,DAM_COLD,skill_table[sn].spell_type) )
dam /= 2;
damage( ch, victim, dam, sn, DAM_COLD ,TRUE);
}
/* void spell_ranger_staff( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
OBJ_DATA *staff = create_object( get_obj_index( OBJ_VNUM_RANGER_STAFF ), 0);
AFFECT_DATA *paf;
staff->value[1] = number_range(level -6, level)/3 + 2;
staff->value[2] = 2;
staff->level = level;
staff->timer = 24;
if (IS_EVIL(ch))
{
SET_BIT(staff->extra_flags,ITEM_ANTI_GOOD);
SET_BIT(staff->extra_flags,ITEM_ANTI_NEUTRAL);
}
else if (IS_GOOD(ch))
{
SET_BIT(staff->extra_flags,ITEM_ANTI_EVIL);
SET_BIT(staff->extra_flags,ITEM_ANTI_NEUTRAL);
}
else
{
SET_BIT(staff->extra_flags,ITEM_ANTI_GOOD);
SET_BIT(staff->extra_flags,ITEM_ANTI_EVIL);
}
paf = new_affect();
paf->type = sn;
paf->level = level;
paf->duration = -1;
paf->location = APPLY_HITROLL;
paf->modifier = level/5;
paf->bitvector = 0;
paf->next = staff->affected;
staff->affected = paf;
paf = new_affect();
paf->type = sn;
paf->level = level;
paf->duration = -1;
paf->location = APPLY_DAMROLL;
paf->modifier = level/5;
paf->bitvector = 0;
paf->next = staff->affected;
staff->affected = paf;
obj_to_char(staff, ch);
act( "You create $p.", ch, staff, NULL, TO_CHAR );
act( "$n creates $p.", ch, staff, NULL, TO_ROOM );
}*/
void spell_wrath(int sn, int level, CHAR_DATA *ch, void *vo,int target){
CHAR_DATA *victim = (CHAR_DATA *) vo;
const int holy_w = skill_lookup("holy word");
int dam = 0;
bool fHoly = is_affected(ch, holy_w);
int chance = fHoly ? 66 : 33;
if (victim->hit > ch->level * 8)
dam = number_range(14 * level / 5, 28 * level / 5);
else{
/* holy word allows for single powerful hit */
if (fHoly){
act_new(skill_table[holy_w].msg_off,ch,NULL,NULL,TO_CHAR,POS_DEAD);
affect_strip(ch, holy_w);
dam = number_range(14 * level / 5, 28 * level / 5);
}
else{
dam = UMIN(victim->hit, dice (ch->level, 5));
}
}
if (IS_GOOD(victim) ){
act("$N follows the path of goodness and is not affected by your wrath.\n\r", ch, NULL, victim, TO_CHAR);
act("$n attempts to wrath you, but you are unaffected.",ch,NULL,victim,TO_VICT);
act("$N is unaffected by $n's wrath.",ch,NULL,victim,TO_NOTVICT);
return;
}
if (IS_NEUTRAL(victim) )
dam /= 3;
if ( saves_spell( level, victim,DAM_HOLY,skill_table[sn].spell_type) ){
dam /= 2;
}
if ( is_affected(ch,gsn_heroism) )
dam = 4 * dam / 3;
if (IS_EVIL(victim)
&& !is_affected(victim,gsn_curse)
&& number_percent() < chance){
spell_curse(gsn_curse, level, ch, (void *) victim,TARGET_CHAR);
}
damage( ch, victim, dam, sn, DAM_HOLY ,TRUE);
}
void spell_ikuzachi( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam = level + dice(11,10);
if ( saves_spell( level, victim, DAM_ENERGY,skill_table[sn].spell_type ) )
dam /= 2;
act("You focus your mind to invoke the ancient arts.", ch,NULL,victim,TO_CHAR);
act("$n closes $s eyes for a moment then glares in your direction.",ch,NULL,victim,TO_VICT);
act("$n closes $s eyes for a moment in deep concentration.",ch,NULL,victim,TO_NOTVICT);
damage( ch, victim, dam, sn,DAM_ENERGY,TRUE);
}
void spell_silence( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
{
if (victim == ch)
act("Your world is already dead silent.",ch,NULL,victim,TO_CHAR);
else
act("$N has already been silenced.", ch,NULL,victim,TO_CHAR);
return;
}
if ( saves_spell( level, victim, IS_NPC(victim) ? DAM_MENTAL : DAM_CHARM,skill_table[sn].spell_type ))
{
sendf(ch, "You failed to silence %s.\n\r", PERS(victim,ch));
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = level / 8;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_SILENCE;
affect_to_char( victim, &af );
if (victim == ch)
send_to_char("Your world suddenly becomes dead silent.\n\r",ch);
else
{
act("$N has been silenced.",ch,NULL,victim,TO_CHAR);
act_new("Your world suddenly becomes dead silent.",ch,NULL,victim,TO_CHARVICT,POS_DEAD);
}
}
void spell_damnation( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,sn))
{
act("$N is already damned.",ch,NULL,victim,TO_CHAR);
return;
}
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = 3*level;
af.location = APPLY_HITROLL;
af.modifier = -1 * (level / 8);
af.bitvector = 0;
affect_to_char( victim, &af );
act_new( "The Gods have forsaken you.", ch,NULL,victim,TO_CHARVICT,POS_DEAD );
if ( ch != victim )
act("$N looks very uncomfortable.",ch,NULL,victim,TO_CHAR);
}
void spell_flashfire( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA* vch;
CHAR_DATA* vch_next;
AFFECT_DATA af;
act("You create a bright flash of light.",ch,NULL,NULL,TO_CHAR);
act("$n sends a brilliant sphere of light spiraling down!",ch,NULL,NULL,TO_ROOM);
for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
{
vch_next = vch->next_in_room;
if ( vch != ch && !is_area_safe(ch,vch) )
{
/* skip mirror image too */
if (IS_NPC(vch) && vch->master && vch->master == ch)
continue;
m_yell(ch,vch,FALSE);
if (!vch->fighting)
multi_hit( vch, ch, TYPE_UNDEFINED);
}
else
continue;
if ( IS_AFFECTED(vch, AFF_BLIND))
continue;
if ( saves_spell(level, vch, DAM_OTHER,skill_table[sn].spell_type) )
{
act_new("You squint your eyes, unaffected by the glare.",ch,NULL,vch,TO_CHARVICT,POS_DEAD);
act("$N avoids the glare.",ch,NULL,vch,TO_CHAR);
continue;
}
else
{
act_new("You have been blinded by the flash of light!",ch,NULL,vch,TO_CHARVICT,POS_DEAD);
act("$n is blinded by the flashfire!",vch,NULL,vch,TO_ROOM);
}
af.where = TO_AFFECTS;
af.type = gsn_blindness;
af.level = level;
af.location = APPLY_HITROLL;
af.duration = level / 8 + UMAX(0, (get_skill(ch, sn) - 75) / 5);
af.bitvector = AFF_BLIND;
if (!IS_NPC(vch) && number_percent() < get_skill(vch,gsn_blind_fighting)){
if (is_affected(vch, gsn_battletrance))
af.modifier = 0;
else
af.modifier = -3;
}
else
af.modifier = -6;
affect_to_char(vch,&af);
af.location = APPLY_AC;
if (!IS_NPC(vch) && number_percent() < get_skill(vch,gsn_blind_fighting)){
if (is_affected(vch, gsn_battletrance))
af.modifier = 0;
else
af.modifier = 5;
}
else
af.modifier = 15;
affect_to_char(vch,&af);
}
}
void spell_thunder_storm( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *vch, *vch_next;
static const sh_int dam_each[] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 30, 35, 40, 45, 50, 55,
60, 65, 70, 75, 80, 82, 84, 86, 88, 90,
92, 94, 96, 98, 100, 105, 110, 115, 120, 125,
127, 129, 131, 133, 135, 140, 145, 150, 150, 150
};
int dam;
int armor = 0;
level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
level = UMAX(0, level);
dam = number_range( 2 * dam_each[level]/3, dam_each[level] * 2 );
if ( !IS_OUTSIDE(ch) )
{
send_to_char( "Inside? Are you joking?!.\n\r", ch );
return;
}
if ( ( mud_data.weather_info.sky < SKY_RAINING
|| temp_adjust( ch->in_room->temp ) <= 35)
&& !IS_IMMORTAL(ch))
{
send_to_char( "The sky seems a bit too clear.\n\r", ch );
return;
}
act("You summon the force of thunder storm to your aid.",ch,NULL,NULL,TO_CHAR );
act("$n calls upon the forces of nature and calls forth a thunder storm.",ch,NULL,NULL,TO_ROOM);
for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
{
vch_next = vch->next_in_room;
if ( saves_spell( level, vch, DAM_LIGHTNING,skill_table[sn].spell_type) )
dam /= 2;
//We give bonus to the spell for the ac person has. (ac is n've so we subtr.)
//bonus is 1/2 value over 150, and regular over 200.
armor = -(vch->armor[0] + vch->armor[1] +vch->armor[2])/3;
if (armor > 200)
act("Sparks arc around $n's armor!", vch, NULL, NULL, TO_ROOM);
dam += UMAX(0 ,(armor-150)/2);
dam += UMAX(0, (armor - 200));
dam = UMIN(300, dam);
//And we apply damage.
if ( vch != ch && !is_area_safe(ch,vch))
{
m_yell(ch,vch,FALSE);
damage( ch, vch, dam, sn, DAM_LIGHTNING,TRUE);
}
}
}
void spell_esuna( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
bool found = FALSE;
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (IS_EVIL(victim))
{
sendf(ch,"Your god does not like %s.\n\r",PERS(victim,ch));
return;
}
if (victim != ch)
{
act("$n soothes you with a glow of white light.",ch,NULL,victim,TO_VICT);
act("You cure $N of $S ailments.",ch,NULL,victim,TO_CHAR);
}
if (check_dispel(level+2,victim,gsn_poison))
found = TRUE;
if (check_dispel(level+2,victim,gsn_death_grasp))
found = TRUE;
if (check_dispel(level+2,victim,gsn_plague))
found = TRUE;
if (!is_song_affected(victim,gsn_unforgiven) && check_dispel(level+2,victim,gsn_curse))
found = TRUE;
if (check_dispel(level+2,victim,gsn_blindness))
found = TRUE;
if (check_dispel(level+2,victim,gsn_sleep))
found = TRUE;
if (check_dispel(level+2,victim,gsn_silence))
found = TRUE;
if (check_dispel(level+2,victim,gsn_blasphemy))
found = TRUE;
if (check_dispel(level+2,victim,gsn_hysteria))
found = TRUE;
if (check_dispel(level+2,victim,skill_lookup("weaken")))
found = TRUE;
if (check_dispel(level+2,victim,gsn_insomnia))
found = TRUE;
if (check_dispel(level+2,victim,skill_lookup("dysentery")))
found = TRUE;
if (check_dispel(level,victim,gsn_ecstacy))
found = TRUE;
if (check_dispel(level,victim,gsn_drug_use))
found = TRUE;
if (found)
{
act("$n looks more relieved.",victim,NULL,NULL,TO_ROOM);
send_to_char("A warm glow runs through your body.\n\r",victim);
if (!IS_NPC(ch) && !IS_NPC(victim) && ch->class == class_lookup("healer") && ch != victim)
gain_exp(ch,number_range(1,ch->level/8));
}
else
{
act("$N does not seem to be affected.",ch,NULL,victim,TO_CHAR);
send_to_char("You don't feel any different.\n\r",victim);
}
}
void spell_holy_water(int sn,int level,CHAR_DATA *ch, void *vo,int target)
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
AFFECT_DATA af;
int liquid = obj->value[2];
if( is_affected(ch,sn) )
{
send_to_char("You are not ready to bless more water yet.\n\r",ch);
return;
}
if (obj->item_type != ITEM_DRINK_CON)
{
send_to_char("That isn't a drink container.\n\r",ch);
return;
}
if (obj->wear_loc != -1)
{
send_to_char("The item must be carried to be blessed.\n\r",ch);
return;
}
if ( obj->value[1] <= 0 )
{
send_to_char( "It is already empty.\n\r", ch );
return;
}
if ( obj->value[1] > 250 )
{
send_to_char( "There is too much water for you to bless.\n\r", ch );
return;
}
if ( liquid != 0 )
{
send_to_char("You can only bless pure water.\n\r",ch);
return;
}
act("The water in $p glows as you bless it with your faith.",ch,obj,NULL,TO_CHAR);
act("The water in $p glows as $n prays with $s hand over it.",ch,obj,NULL,TO_ROOM);
obj->value[2] = 1;
obj->value[3] = 0;
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = 48;
af.modifier = 0;
af.location = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
}
void spell_barrier( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected(victim, sn))
{
send_to_char("You are already surrounded by a shield.\n\r",ch);
return;
}
if (is_affected(victim, skill_lookup("divine retribution")))
{
send_to_char("You must wait for your divine retribution to wear off.\n\r",ch);
return;
}
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level/9);
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_BARRIER;
affect_to_char( victim, &af );
act( "You are enclosed in a physical barrier.", ch, NULL, NULL, TO_CHAR );
act( "$n is encased by a transparent sphere.", ch, NULL, NULL, TO_ROOM );
}
void spell_vitalize( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,sn))
{
if (ch != victim)
send_to_char("Their metabolism has already been increased.\n\r",ch);
else
send_to_char("Your metabolism is at its peak!\n\r",ch);
return;
}
if (IS_GOOD(ch) && IS_EVIL(victim))
{
sendf(ch,"Your god does not like %s.\n\r",PERS(victim,ch));
return;
}
if (IS_GOOD(victim) && IS_EVIL(ch))
{
sendf(ch,"Your god does not like %s.\n\r",PERS(victim,ch));
return;
}
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level/5);
af.location = APPLY_CON;
af.modifier = 2;
af.bitvector = 0;
affect_to_char( victim, &af );
if (ch != victim)
act("You vitalize $N's metabolism.",ch,NULL,victim,TO_CHAR);
send_to_char("You are filled with energy as your metabolism increases!\n\r",victim);
act("$n seems to be more energetic.",victim,NULL,NULL,TO_ROOM);
}
void spell_sacrifice( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(ch,sn))
{
send_to_char("Your body has not recovered from the last sacrifice!\n\r",ch);
return;
}
if (ch == victim)
{
send_to_char("This spell must be casted on someone else.\n\r",ch);
return;
}
if (ch->hit < ch->max_hit/3 || ch->mana < ch->max_mana/3 || ch->move < ch->max_move/3)
{
send_to_char("You body is in no condition to perform a sacrifice.\n\r",ch);
return;
}
if (IS_EVIL(victim))
{
sendf(ch,"Your god does not like %s.\n\r",PERS(victim,ch));
return;
}
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = 24;
af.location = 0;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
af.type = gsn_drained;
af.duration = 5;
affect_to_char( ch, &af );
ch->hit = UMAX(1,ch->max_hit * .05);
ch->mana = UMAX(1,ch->max_mana * .05);
ch->move = UMAX(1,ch->max_move * .05);
ch->position = POS_RESTING;
affect_strip(victim,gsn_plague);
affect_strip(victim,gsn_poison);
affect_strip(victim,gsn_blindness);
victim->hit = victim->max_hit;
victim->mana = victim->max_mana;
victim->move = victim->max_move;
update_pos(victim);
act("You sacrifice your own health to restore $N!",ch,NULL,victim,TO_CHAR);
act("$n passes on $s life energy into your body!",ch,NULL,victim,TO_VICT);
act("$n slumps to the ground as $e passes $s life onto $N.",ch,NULL,victim,TO_NOTVICT);
}
void spell_heavens_gate( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
char arg[MIL];
bool gate_pet;
ROOM_INDEX_DATA *room;
if (IS_NPC(ch))
return;
one_argument(target_name, arg);
if (arg[0] == '\0')
{
if (ch->pcdata->beacon == 0 || (room = get_room_index(ch->pcdata->beacon)) == NULL)
{
send_to_char("You do not have a marker set.\n\r",ch);
return;
}
if (!IS_NPC(ch) && ch->pcdata->pStallion != NULL)
{
send_to_char("Your mount refuses to enter the gate.\n\r",ch);
return;
}
if ( IS_SET(room->room_flags, ROOM_SAFE)
|| IS_SET(room->room_flags, ROOM_PRIVATE)
|| IS_SET(room->room_flags, ROOM_SOLITARY)
|| IS_SET(room->room_flags, ROOM_NO_GATEIN)
|| IS_SET(ch->in_room->room_flags, ROOM_NO_GATEOUT)
|| IS_SET(ch->in_room->room_flags, ROOM_NO_INOUT)
|| is_affected(ch, gsn_tele_lock)
|| IS_SET(room->room_flags, ROOM_NO_INOUT))
{
send_to_char("You failed to create a portal.\n\r",ch);
return;
}
else if (is_affected(ch,gen_ensnare)){
send_to_char("You sense a powerful magical field preventing your departure.\n\r", ch);
return;
}
if (ch->pet != NULL && ch->in_room == ch->pet->in_room)
gate_pet = TRUE;
else
gate_pet = FALSE;
act("$n steps through a dark portal and vanishes.",ch,NULL,NULL,TO_ROOM);
act("You step through a dark portal and vanish.",ch,NULL,NULL,TO_CHAR);
char_from_room(ch);
char_to_room(ch,room);
act("$n has arrived through a gate.",ch,NULL,NULL,TO_ROOM);
do_look(ch,"auto");
if (gate_pet)
{
act("$n steps through a dark portal and vanishes.",ch->pet,NULL,NULL,TO_ROOM);
act("You step through a dark portal and vanish.",ch->pet,NULL,NULL,TO_CHAR);
char_from_room(ch->pet);
char_to_room(ch->pet,room);
act("$n has arrived through a gate.",ch->pet,NULL,NULL,TO_ROOM);
do_look(ch->pet,"auto");
}
}
else if (!str_cmp(arg, "marker"))
{
if (ch->in_room == NULL)
return;
if ( IS_SET(ch->in_room->room_flags, ROOM_SAFE)
|| IS_SET(ch->in_room->room_flags, ROOM_PRIVATE)
|| IS_SET(ch->in_room->room_flags, ROOM_SOLITARY)
|| IS_SET(ch->in_room->room_flags, ROOM_NO_GATEIN)
|| IS_SET(ch->in_room->room_flags, ROOM_NO_INOUT))
{
send_to_char("You failed to set a marker.\n\r",ch);
return;
}
send_to_char("You mark the area for future use.\n\r",ch);
ch->pcdata->beacon = ch->in_room->vnum;
}
else
send_to_char("To place a marker, <syntax: ca 'portal' marker>.\n\r",ch);
}
void spell_rejuvenate( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal = dice(3, 20) + level + 30;
victim->hit = UMIN( victim->hit + heal, victim->max_hit );
update_pos( victim );
act_new("A jolt of energy runs through you!", ch,NULL,victim,TO_CHARVICT,POS_DEAD );
if ( ch != victim )
act("You rejuvenate $N's health.", ch,NULL,victim,TO_CHAR );
}
void spell_prayer( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_NPC(victim))
return;
if (IS_AFFECTED(victim,AFF_RAGE) || IS_AFFECTED(victim,AFF_BERSERK) || is_affected(victim,skill_lookup("frenzy")))
{
if (victim == ch)
send_to_char("Your prayers cannot reach your gods in your state of mind.",ch);
else
send_to_char("Your prayer will not reach one in an unstable state of mind.\n\r",ch);
return;
}
if (is_affected(victim,sn))
{
if (victim == ch)
send_to_char("You are already blessed with a prayer.\n\r",ch);
else
act("$N is already blessed with a prayer.",ch,NULL,victim,TO_CHAR);
return;
}
if (!IS_GOOD(victim))
{
act("Your god doesn't seem to like $N",ch,NULL,victim,TO_CHAR);
return;
}
if ( is_affected( victim, gsn_blasphemy ) )
{
sendf(ch, "%s's faith have been lost.\n\r", PERS(victim,ch));
return;
}
if (is_fight_delay(victim,90))
{
if (ch == victim)
send_to_char("You are too worked up to start a prayer.\n\r",ch);
else
act("$N is too worked up to listen to your prayer.",ch,NULL,victim,TO_CHAR);
return;
}
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = level / 2;
af.modifier = level / 2;
af.bitvector = 0;
af.location = APPLY_MANA;
affect_to_char(victim,&af);
af.modifier = -level / 10;
af.location = APPLY_DAMROLL;
affect_to_char(victim,&af);
af.modifier = level / 12;
af.location = APPLY_LUCK;
affect_to_char(victim,&af);
af.modifier = -10 * (level / 12);
af.location = APPLY_AC;
affect_to_char(victim,&af);
act_new("You are filled with serenity by the prayer.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n's eyes are filled with serenity.",victim,NULL,NULL,TO_ROOM);
}
void spell_spirit_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,sn))
{
send_to_char("You already have a spirit shield.\n\r",victim);
return;
}
act_new("You create a spirit shield on your arm.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n creates a spirit shield on $s arm.",victim,NULL,NULL,TO_ROOM);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = level/10;
af.modifier = 0;
af.bitvector = 0;
af.location = 0;
affect_to_char(victim,&af);
}
void spell_invigorate( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *vch, *vch_next;
for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
{
vch_next = vch->next_in_room;
if (vch->master == ch || is_same_group(vch, ch))
{
if (IS_EVIL(vch))
{
sendf(ch,"Your god does not like %s.\n\r",PERS(vch,ch));
return;
}
vch->move = vch->max_move;
check_dispel(level,vch,skill_lookup("enfeeblement"));
act_new("Your weariness is alleviated from your feet.", ch,NULL,vch,TO_CHARVICT,POS_DEAD );
if ( ch != vch )
act("You renergize the strength of $N's feet.", ch,NULL,vch,TO_CHAR );
}
}
}
void spell_group_recall( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *vch, *vch_next;
for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
{
vch_next = vch->next_in_room;
if ( vch->pCabal && IS_CABAL(get_parent(vch->pCabal), CABAL_NOMAGIC))
continue;
if (vch->master == ch || is_same_group(vch, ch))
spell_word_of_recall(skill_lookup("word of recall"),level,ch,(void *) vch,TARGET_CHAR);
}
}
void spell_blasphemy( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected(victim, sn))
{
act("$N's faith has already been shaken.",ch,NULL,victim,TO_CHAR);
return;
}
if ( saves_spell(level, victim, DAM_OTHER,skill_table[sn].spell_type) )
{
if ( ch != victim )
act("You fail to taint $N's faith.",ch,NULL,victim,TO_CHAR);
send_to_char("You remain true to your faith.\n\r",victim);
return;
}
act_new("Your faith shatters as you have doubts about your religion!",ch,NULL,victim,TO_CHARVICT,POS_DEAD);
if ( ch != victim )
act("$N is plagued by doubts of $s own faith!",ch,NULL,victim,TO_CHAR);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.location = 0;
af.duration = level/8;
af.bitvector = 0;
af.modifier = 0;
affect_to_char(victim,&af);
}
void spell_demonic_visage( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
OBJ_DATA *obj;
AFFECT_DATA af;
if ( ch == victim )
{
send_to_char("You try to scare yourself without much success.\n\r",ch);
return;
}
if ( is_affected(victim, sn))
{
act("$N still cannot shake the images of demons from $s mind.",ch,NULL,victim,TO_CHAR);
return;
}
if (!can_see(victim,ch) || ch->position <= POS_SLEEPING)
{
act("$N cannot see your demonic visage.",ch,NULL,victim,TO_CHAR);
return;
}
send_to_char("You peel away your face to reveal your demonic image.\n\r",ch);
act("$n peels $s face away to reveal $s demonic image.",ch,NULL,NULL,TO_ROOM);
if ( ( obj = get_eq_char( victim, WEAR_WIELD ) ) == NULL && ( obj = get_eq_char( victim, WEAR_SECONDARY ) ) == NULL )
{
send_to_char("Your opponent is not using a weapon.\n\r",ch);
return;
}
if ( saves_spell(level, victim, DAM_OTHER,skill_table[sn].spell_type) )
{
act("$N is not affected by your demonic appearance.",ch,NULL,victim,TO_CHAR);
act("$n's demonic appearance does not affect you.",ch,NULL,victim,TO_VICT);
return;
}
send_to_char("You drop your weapon as you are taken back by the horrifying image!\n\r",victim);
act( "$n almost drops $p.", victim, obj, NULL, TO_ROOM );
unequip_char( ch, obj );
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.location = 0;
af.duration = 2;
af.bitvector = 0;
af.modifier = 0;
affect_to_char(victim,&af);
}
void spell_blanket_darkness( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
ROOM_INDEX_DATA * room;
AFFECT_DATA af;
int np = number_percent();
if (ch->in_room == NULL)
return;
room = ch->in_room;
if (is_affected(ch,sn))
{
send_to_char("You are not ready to blanket another room.\n\r",ch);
return;
}
if (room->sector_type == SECT_CITY || IS_SET(room->area->area_flags,AREA_CITY))
{
send_to_char("There are too many lights in the city.\n\r",ch);
return;
}
if (room->pCabal)
{
send_to_char("Not in a cabal.\n\r",ch);
return;
}
if (np - 2*(get_curr_stat(ch,STAT_LUCK) - 16) < 50)
{
send_to_char("You failed to blanket this room in darkness.\n\r",ch);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.location = 0;
af.duration = 12;
af.bitvector = 0;
af.modifier = 0;
affect_to_char(ch,&af);
return;
}
if (IS_SET(room->room_flags,ROOM_NO_SCAN))
{
send_to_char("This room is already covered in darkness.\n\r",ch);
return;
}
send_to_char("You enshroud the room with a blanket of darkness.\n\r",ch);
act("A blanket of darkness enshrouds the room.",ch,NULL,NULL,TO_ROOM);
SET_BIT(room->room_flags,ROOM_NO_SCAN);
SET_BIT(room->room_flags,ROOM_DARK);
SET_BIT(room->room_flags,ROOM_NOWHERE);
SET_BIT(room->room_flags,ROOM_INDOORS);
SET_BIT(room->room_flags,ROOM_NO_INOUT);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.location = 0;
af.duration = 100;
af.bitvector = 0;
af.modifier = 0;
affect_to_char(ch,&af);
}
void spell_enfeeblement( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
int dam;
if ( ch != victim )
act("You drain the strength from $N's legs!",ch,NULL,victim,TO_CHAR);
send_to_char("Your legs feel sluggish as their strength are drained.\n\r",victim);
dam = UMAX( 1 * victim->move / 10, 15);
victim->move = UMAX(0, (victim->move - dam));
if ( !is_affected(victim, sn) && !saves_spell(level, victim, DAM_OTHER,skill_table[sn].spell_type) )
{
if (ch != victim )
act("$N's legs are exhausted by your enfeeblement.",ch,NULL,victim,TO_CHAR);
send_to_char("Your legs collapse from exhaustion.\n\r",victim);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.location = 0;
af.duration = level / 8;
af.bitvector = 0;
af.modifier = 0;
affect_to_char(victim,&af);
}
}
void spell_hysteria( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected(victim, sn))
{
act("$N is already in hysteria.",ch,NULL,victim,TO_CHAR);
return;
}
if ( saves_spell(level - 3, victim, DAM_OTHER,skill_table[sn].spell_type) )
{
if ( ch != victim )
act("You fail to bring $N into hysteria.",ch,NULL,victim,TO_CHAR);
send_to_char("You momentarily filled with anxiety but manage to keep your wits together.\n\r",victim);
return;
}
act_new("You start to panic as you enter a state of hysteria!",ch,NULL,victim,TO_CHARVICT,POS_DEAD);
if ( ch != victim )
act("$N starts to panic from $S hysteria!",ch,NULL,victim,TO_CHAR);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.location = 0;
af.duration = 5;
af.bitvector = 0;
af.modifier = 0;
affect_to_char(victim,&af);
}
/* SPELL MASS HYSTERIA
General effects: hysteria, area.
Coded By: Athaekeetha
*/
void spell_mass_hysteria (int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
CHAR_DATA *vch, *vch_next;
/* first hit the target */
spell_hysteria( gsn_hysteria, level, ch, victim, target) ;
/* then anyone grouped with target */
for (vch = victim->in_room->people; vch; vch = vch_next){
vch_next = vch->next_in_room;
if (!is_same_group(vch, victim))
continue;
else if (vch == victim)
continue;
else if (is_area_safe_quiet( vch, ch))
continue;
else
spell_hysteria( gsn_hysteria, level, ch, vch, target) ;
m_yell(ch,vch,FALSE);
if (vch->fighting == NULL)
set_fighting(vch, ch );
}
}
void spell_ethereal_passage( int sn, int level, CHAR_DATA *ch, void *vo,int target) {
ROOM_INDEX_DATA* old;
char arg[MIL];
int door;
bool fClear = TRUE;
target_name = one_argument( target_name, arg );
if ( arg[0] == '\0' ){
send_to_char("What direction? <north/east/south/west/up/down>\n\r",ch);
return;
}
if (!IS_NPC(ch) && ch->pcdata->pStallion != NULL){
send_to_char("Your mount refuses to enter the passage.\n\r",ch);
return;
}
if (!str_cmp(arg,"north") || !str_cmp(arg,"n"))
door = DIR_NORTH;
else if (!str_cmp(arg,"east") || !str_cmp(arg,"e"))
door = DIR_EAST;
else if (!str_cmp(arg,"south") || !str_cmp(arg,"s"))
door = DIR_SOUTH;
else if (!str_cmp(arg,"west") || !str_cmp(arg,"w"))
door = DIR_WEST;
else if (!str_cmp(arg,"up") || !str_cmp(arg,"u"))
door = DIR_UP;
else if (!str_cmp(arg,"down") || !str_cmp(arg,"d"))
door = DIR_DOWN;
else
{
send_to_char("That direction does not exist. <north/east/south/west/up/down>\n\r",ch);
return;
}
act("$n creates an ethereal passage.",ch,NULL,NULL,TO_ROOM);
act("You create an ethereal passage.",ch,NULL,NULL,TO_CHAR);
if (!IS_AFFECTED(ch, AFF_PASS_DOOR)){
SET_BIT(ch->affected_by, AFF_PASS_DOOR );
fClear = TRUE;
}
old = ch->in_room;
move_char( ch, door, FALSE );
if (fClear){
REMOVE_BIT(ch->affected_by, AFF_PASS_DOOR );
affect_check(ch, TO_AFFECTS, AFF_PASS_DOOR);
}
if (ch->in_room == old)
act("An ethereal passage fizzles and closes.",ch,NULL,NULL,TO_ALL);
else
act("An ethereal passage opens and $n steps out.",ch,NULL,NULL,TO_ROOM);
}
void spell_insomnia( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected(victim, sn))
{
act("$N already has insomnia.",ch,NULL,victim,TO_CHAR);
return;
}
if ( saves_spell(level, victim, DAM_OTHER,skill_table[sn].spell_type) )
{
if ( ch != victim )
act("You fail to deprive $N of sleep.",ch,NULL,victim,TO_CHAR);
send_to_char("You resist the plague of insomnia.\n\r",victim);
return;
}
act_new("You no longer feel the need to sleep!",ch,NULL,victim,TO_CHARVICT,POS_DEAD);
if ( ch != victim )
act("You manage to infect $N with insomnia!",ch,NULL,victim,TO_CHAR);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.location = 0;
af.duration = 12;
af.bitvector = 0;
af.modifier = 0;
affect_to_char(victim,&af);
}
void spell_dysentery( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af, *paf;
if ( is_affected(victim, sn))
{
act("$N already has dysentery.",ch,NULL,victim,TO_CHAR);
return;
}
if (IS_NPC(victim))
{
send_to_char("Mobs are not affected by nutrition.\n\r",ch);
return;
}
if ( ch == victim || saves_spell(level, victim, DAM_DISEASE,skill_table[sn].spell_type) )
{
if ( ch != victim )
act("You fail to disrupt $N's bowel movements.",ch,NULL,victim,TO_CHAR);
send_to_char("Your stomach rumbles softly, but you manage to suppress the urge.\n\r",victim);
return;
}
victim->position = POS_SITTING;
update_pos(victim);
act_new("You feel drained as your intestinal tracks goes haywire!",ch,NULL,victim,TO_CHARVICT,POS_DEAD);
act("$n's face changes color as $e grabs $s stomach in agonizing pain!",victim,NULL,NULL,TO_ROOM);
send_to_char("You quickly crouch on the ground as fecal matter explodes from your rear.\n\r",victim);
act("$n crouches on the ground wincing painfully as fecal matter is expelled from $s rear.",victim,NULL,NULL,TO_ROOM);
act("A strong odor fills the room.",victim,NULL,NULL,TO_ROOM);
victim->pcdata->condition[COND_HUNGER] = 2;
defecate(victim);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.location = 0;
af.duration = 8;
af.bitvector = 0;
af.modifier = 0;
paf = affect_to_char(victim,&af);
if (!IS_NPC(ch))
string_to_affect( paf, ch->name );
}
void spell_phantom_grasp( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af, *paf;
int dam = number_range( 1, 5);
int mod = (get_skill(ch, sn ) - 75) * 2;
int chance = 50 + mod;
act("You consume $N with the phantoms of the underworld.",ch,NULL,victim,TO_CHAR);
act("You are consumed by the phantoms of the underworld.",victim,NULL,NULL,TO_CHAR);
act("$N is consumed by the phantoms of the underworld.",ch,NULL,victim,TO_NOTVICT);
paf = affect_find(victim->affected,sn);
if ( saves_spell( level + (mod / 10), victim,DAM_NEGATIVE,skill_table[sn].spell_type) ){
chance /= 2;
}
damage( ch, victim, dam, sn, DAM_NEGATIVE ,TRUE);
if (number_percent() < chance ){
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = number_range(1, 3);
af.location = APPLY_SAVING_SPELL;
af.modifier = number_range(1, 3);;
af.bitvector = 0;
if (paf == NULL){
affect_to_char( victim, &af );
}
else{
if (paf->duration > 24)
af.duration = 0;
if (paf->modifier > 14)
af.modifier = 0;
else{
act("The phantoms drains $n of $s magical resistence.",victim,NULL,NULL,TO_ROOM);
act("The phantoms drains you of your magical resistence.",victim,NULL,NULL,TO_CHAR);
}
affect_join( victim, &af );
}
}
else{
send_to_char("You failed.\n\r", ch);
}
}
void spell_dark_shroud( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected(victim, sn))
{
send_to_char("You are already surrounded by a dark shroud.\n\r",victim);
return;
}
send_to_char("You envelop yourself in a dark shroud.\n\r",ch);
act("$n is enveloped in a dark shroud.",ch,NULL,NULL,TO_ROOM);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.location = 0;
af.modifier = 0;
af.duration = level/2;
af.bitvector = 0;
affect_to_char(victim,&af);
}
void spell_deteriorate( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
int saves = 0;
if ( is_affected(victim, sn))
{
act("$N is already deteriorated.",ch,NULL,victim,TO_CHAR);
return;
}
//calc_saves reports saves chance with the base 40 included (5-95)
saves = URANGE(0, calc_saves(level, victim, DAM_OTHER, skill_table[sn].spell_type) - 40, 55);
/* the spell level increases past 30 saves at rate of 2 level for 3 saves over 30.
this results in final svs change of -2 per save over 30.
At 0: 0 + 60 = 60
At 10: 10 + 40 = 50
At 20: 20 + 20 = 40
At 30: 30 - 0 = 30
At 40: 40 - 20 = 20
At 50: 50 - 40 = 10
At 55: 55 - 50 = 5
*/
if ( saves_spell(level + 2 * (saves - 30) / 3, victim, DAM_OTHER, skill_table[sn].spell_type) ){
if ( ch != victim )
act("You fail to deteriorate $N.",ch,NULL,victim,TO_CHAR);
act("You resist $n's deterioration.",ch,NULL,victim,TO_VICT);
return;
}
if (ch != victim )
act("You deteriorate $N's defenses.",ch,NULL,victim,TO_CHAR);
send_to_char("You defense lowers from deterioration.\n\r",victim);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.location = APPLY_AC;
af.modifier = level;
af.duration = number_range(10, 24);
af.bitvector = 0;
affect_to_char(victim,&af);
af.location = APPLY_SAVING_SPELL;
af.modifier = 4 * saves / 10;
affect_to_char( victim, &af );
}
void spell_cure_dysentery( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if ( !is_affected( victim, skill_lookup("dysentery") ) )
{
if (victim == ch)
act("You don't have dysentery.",ch,NULL,victim,TO_CHAR);
else
act("$N doesn't seem to have dysentery.",ch,NULL,victim,TO_CHAR);
return;
}
if (check_dispel(level - 3,victim,skill_lookup("dysentery")))
{
act_new("A feeling of relieve runs through your body.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n looks relieved.",victim,NULL,NULL,TO_ROOM);
}
else
act("You failed to cure $N of dysentery.",ch,NULL,victim,TO_CHAR);
}
void spell_cure_insomnia( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if ( !is_affected( victim, gsn_insomnia ) )
{
if (victim == ch)
act("You don't have insomnia.",ch,NULL,victim,TO_CHAR);
else
act("$N doesn't seem to have insomnia.",ch,NULL,victim,TO_CHAR);
return;
}
if (check_dispel(level-3,victim,gsn_insomnia))
{
act_new("A familiar feeling of fatigue returns to your body.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n looks more relaxed.",victim,NULL,NULL,TO_ROOM);
}
else
act("You failed to cure $N of insomnia.",ch,NULL,victim,TO_CHAR);
}
void spell_remove_hysteria( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if ( !is_affected( victim, gsn_hysteria ) )
{
if (victim == ch)
act("You are not affected by hysteria.",ch,NULL,victim,TO_CHAR);
else
act("$N doesn't appear to be affected by hysteria.",ch,NULL,victim,TO_CHAR);
return;
}
if (check_dispel(level,victim,gsn_hysteria))
{
act_new("You recollect your thoughts and your wits.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n looks steadier.",victim,NULL,NULL,TO_ROOM);
}
else
act("You failed to remove $N of $s hysteria.",ch,NULL,victim,TO_CHAR);
}
void spell_accession( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
AFFECT_DATA af;
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dur;
if (IS_NPC(victim))
{
send_to_char("Mobs cannot be affected.\n\r",ch);
return;
}
if ( is_affected( victim, sn ) )
{
if (victim == ch)
act("You are not ready tap into your hidden potential.",ch,NULL,victim,TO_CHAR);
else
act("$N is not ready to tap into $S hidden potential.",ch,NULL,victim,TO_CHAR);
return;
}
if (IS_EVIL(victim))
{
send_to_char("It is against your belief to help evils.\n\r",ch);
return;
}
send_to_char("Your hidden potential is unleashed.\n\r",victim);
dur = number_fuzzy(level/7);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.location = 0;
af.modifier = 0;
af.duration = dur+6;
af.bitvector = 0;
affect_to_char( victim, &af );
af.duration = dur;
if (ch == victim )
{
af.location = APPLY_DAMROLL;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = - level / 5;
affect_to_char( victim, &af );
af.location = APPLY_AC;
af.modifier = - level;
affect_to_char(victim,&af);
af.location = APPLY_MOVE;
af.modifier = 2*level;
affect_to_char( victim, &af );
af.location = APPLY_MANA;
af.modifier = level;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = level;
victim->hit += level;
victim->mana += level;
victim->move += 2*level;
affect_to_char( victim, &af );
af.location = APPLY_CON;
af.modifier = level / 25;
affect_to_char( victim, &af );
af.location = APPLY_DEX;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_WIS;
af.modifier = level / 8;
affect_to_char( victim, &af );
af.location = APPLY_INT;
af.modifier = level / 10;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = level / 20;
affect_to_char( victim, &af );
}
else
{
act("You unleash $N's hidden potential.",ch,NULL,victim,TO_CHAR);
level = victim->level;
if (victim->class == class_lookup("warrior"))
{
af.location = APPLY_DAMROLL;
af.modifier = level / 10;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = level / 7;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = - level / 10;
affect_to_char( victim, &af );
af.location = APPLY_AC;
af.modifier = - level / 2;
affect_to_char(victim,&af);
af.location = APPLY_MOVE;
af.modifier = level / 2;
affect_to_char( victim, &af );
af.location = APPLY_MANA;
af.modifier = level / 5;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = level/2;
affect_to_char( victim, &af );
victim->hit += level/2;
victim->mana += level/5;
victim->move += level/2;
af.location = APPLY_CON;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_DEX;
af.modifier = level / 18;
affect_to_char( victim, &af );
af.location = APPLY_WIS;
af.modifier = level / 20;
affect_to_char( victim, &af );
af.location = APPLY_INT;
af.modifier = level / 20;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = level / 12;
affect_to_char( victim, &af );
}
else if (victim->class == class_lookup("berserker"))
{
af.location = APPLY_DAMROLL;
af.modifier = level / 7;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = level / 20;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = - level / 12;
affect_to_char( victim, &af );
af.location = APPLY_AC;
af.modifier = - level/3;
affect_to_char(victim,&af);
af.location = APPLY_MOVE;
af.modifier = level / 3;
affect_to_char( victim, &af );
af.location = APPLY_MANA;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = level;
affect_to_char( victim, &af );
victim->hit += level;
victim->mana += level/15;
victim->move += level/3;
af.location = APPLY_CON;
af.modifier = level / 12;
affect_to_char( victim, &af );
af.location = APPLY_DEX;
af.modifier = level / 20;
affect_to_char( victim, &af );
af.location = APPLY_WIS;
af.modifier = level / 25;
affect_to_char( victim, &af );
af.location = APPLY_INT;
af.modifier = level / 25;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = level / 10;
affect_to_char( victim, &af );
}
else if (victim->class == class_lookup("thief") || victim->class == class_lookup("bard"))
{
af.location = APPLY_DAMROLL;
af.modifier = level / 12;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = level / 10;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = - level / 7;
affect_to_char( victim, &af );
af.location = APPLY_AC;
af.modifier = - level;
affect_to_char(victim,&af);
af.location = APPLY_MOVE;
af.modifier = 3*level/2 ;
affect_to_char( victim, &af );
af.location = APPLY_MANA;
af.modifier = level / 3;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = level / 3;
affect_to_char( victim, &af );
victim->hit += level/3;
victim->mana += level/3;
victim->move += level/2;
af.location = APPLY_CON;
af.modifier = level / 20;
affect_to_char( victim, &af );
af.location = APPLY_DEX;
af.modifier = level / 10;
affect_to_char( victim, &af );
af.location = APPLY_WIS;
af.modifier = level / 18;
affect_to_char( victim, &af );
af.location = APPLY_INT;
af.modifier = level / 18;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = level / 15;
affect_to_char( victim, &af );
}
else if (victim->class == class_lookup("ranger"))
{
af.location = APPLY_DAMROLL;
af.modifier = level / 11;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = level / 11;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = - level / 6;
affect_to_char( victim, &af );
af.location = APPLY_AC;
af.modifier = - 2*level/3;
affect_to_char(victim,&af);
af.location = APPLY_MOVE;
af.modifier = level;
affect_to_char( victim, &af );
af.location = APPLY_MANA;
af.modifier = level / 4;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = level / 2;
affect_to_char( victim, &af );
victim->hit += level;
victim->mana += level/4;
victim->move += level/2;
af.location = APPLY_CON;
af.modifier = level / 10;
affect_to_char( victim, &af );
af.location = APPLY_DEX;
af.modifier = level / 17;
affect_to_char( victim, &af );
af.location = APPLY_WIS;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_INT;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = level / 12;
affect_to_char( victim, &af );
}
else if (victim->class == class_lookup("ninja"))
{
af.location = APPLY_DAMROLL;
af.modifier = level / 12;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = level / 12;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = - level / 5;
affect_to_char( victim, &af );
af.location = APPLY_AC;
af.modifier = - 2*level/3;
affect_to_char(victim,&af);
af.location = APPLY_MOVE;
af.modifier = level / 2;
affect_to_char( victim, &af );
af.location = APPLY_MANA;
af.modifier = level / 3;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = level / 3;
affect_to_char( victim, &af );
victim->hit += level/3;
victim->mana += level/3;
victim->move += level/2;
af.location = APPLY_CON;
af.modifier = level / 17;
affect_to_char( victim, &af );
af.location = APPLY_DEX;
af.modifier = level / 12;
affect_to_char( victim, &af );
af.location = APPLY_WIS;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_INT;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = level / 15;
affect_to_char( victim, &af );
}
else if (victim->class == class_lookup("paladin"))
{
af.location = APPLY_DAMROLL;
af.modifier = level / 10;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = level / 10;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = - level / 8;
affect_to_char( victim, &af );
af.location = APPLY_AC;
af.modifier = - level/2;
affect_to_char(victim,&af);
af.location = APPLY_MOVE;
af.modifier = level / 2;
affect_to_char( victim, &af );
af.location = APPLY_MANA;
af.modifier = level / 3;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = level / 3;
affect_to_char( victim, &af );
victim->hit += level/3;
victim->mana += level/3;
victim->move += level/2;
af.location = APPLY_CON;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_DEX;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_WIS;
af.modifier = level / 12;
affect_to_char( victim, &af );
af.location = APPLY_INT;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = level / 15;
affect_to_char( victim, &af );
}
else if (victim->class == class_lookup("healer"))
{
af.location = APPLY_DAMROLL;
af.modifier = level / 20;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = level / 20;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = - level / 7;
affect_to_char( victim, &af );
af.location = APPLY_AC;
af.modifier = - level/2;
affect_to_char(victim,&af);
af.location = APPLY_MOVE;
af.modifier = level;
affect_to_char( victim, &af );
af.location = APPLY_MANA;
af.modifier = level/2;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = level/2;
affect_to_char( victim, &af );
victim->hit += level/2;
victim->mana += level/2;
victim->move += level;
af.location = APPLY_CON;
af.modifier = level / 20;
affect_to_char( victim, &af );
af.location = APPLY_DEX;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_WIS;
af.modifier = level / 12;
affect_to_char( victim, &af );
af.location = APPLY_INT;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = level / 20;
affect_to_char( victim, &af );
}
else if (victim->class == class_lookup("battlemage") || victim->class == class_lookup("invoker"))
{
af.location = APPLY_DAMROLL;
af.modifier = level / 20;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = level / 20;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = - level / 4;
affect_to_char( victim, &af );
af.location = APPLY_AC;
af.modifier = - level;
affect_to_char(victim,&af);
af.location = APPLY_MOVE;
af.modifier = level;
affect_to_char( victim, &af );
af.location = APPLY_MANA;
af.modifier = level;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = level / 5;
affect_to_char( victim, &af );
victim->hit += level/5;
victim->mana += level;
victim->move += level;
af.location = APPLY_CON;
af.modifier = level / 20;
affect_to_char( victim, &af );
af.location = APPLY_DEX;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_WIS;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_INT;
af.modifier = level / 10;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = level / 25;
affect_to_char( victim, &af );
}
else{
af.location = APPLY_DAMROLL;
af.modifier = level / 10;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = level / 7;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = - level / 10;
affect_to_char( victim, &af );
af.location = APPLY_AC;
af.modifier = - level / 2;
affect_to_char(victim,&af);
af.location = APPLY_MOVE;
af.modifier = level / 2;
affect_to_char( victim, &af );
af.location = APPLY_MANA;
af.modifier = level / 5;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = level/2;
affect_to_char( victim, &af );
victim->hit += level/2;
victim->mana += level/5;
victim->move += level/2;
af.location = APPLY_CON;
af.modifier = level / 15;
affect_to_char( victim, &af );
af.location = APPLY_DEX;
af.modifier = level / 18;
affect_to_char( victim, &af );
af.location = APPLY_WIS;
af.modifier = level / 20;
affect_to_char( victim, &af );
af.location = APPLY_INT;
af.modifier = level / 20;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = level / 12;
affect_to_char( victim, &af );
}
}
}
void spell_morph( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
char arg[MIL];
int chance = number_percent();
AFFECT_DATA af;
target_name = one_argument(target_name, arg);
if (is_affected(ch,gsn_bat_form) || is_affected(ch,gsn_wolf_form) || is_affected(ch,gsn_mist_form))
{
send_to_char("You are already morphed.\n\r",ch);
return;
}
if (arg[0] == '\0')
{
send_to_char("syntax: cast 'morph' <form>.\n\r",ch);
return;
}
chance -= 2*(get_curr_stat(ch,STAT_LUCK) - 16);
if (!str_cmp(arg, "bat") && chance < get_skill(ch,gsn_bat_form))
{
const int cost = skill_table[gsn_bat_form].min_mana;
if (ch->mana < cost){
send_to_char("You cannot concentrate sufficiently.\n\r", ch);
return;
}
else
ch->mana -= cost;
affect_strip(ch, gen_conceal);
send_to_char("You submit yourself to the sweet agony of transformation and take form of a bat.\n\r",ch);
act("Shadows thicken around $n as his flesh melds itself into a bat.",ch,NULL,NULL,TO_ROOM);
af.where = TO_AFFECTS;
af.type = gsn_bat_form;
af.level = level;
af.duration = 12;
af.location = APPLY_SIZE;
af.modifier = -2;
af.bitvector = 0;
affect_to_char( ch, &af );
af.where = TO_AFFECTS;
af.location = APPLY_DAMROLL;
af.modifier = -20;
af.bitvector = AFF_FLYING;
affect_to_char( ch, &af );
af.where = TO_VULN;
af.bitvector = VULN_SOUND;
af.location = APPLY_HITROLL;
af.modifier = -15;
affect_to_char( ch, &af );
af.location = APPLY_CON;
af.modifier = -7;
affect_to_char( ch, &af );
af.location = APPLY_DEX;
af.modifier = 5;
affect_to_char( ch, &af );
af.location = APPLY_STR;
af.modifier = -10;
affect_to_char( ch, &af );
ch->short_descr = str_dup("a vampire bat");
ch->dam_type = 10;
check_improve(ch,gsn_bat_form,TRUE,1);
return;
}
else if (!str_cmp(arg, "wolf") && chance < get_skill(ch,gsn_wolf_form))
{
const int cost = skill_table[gsn_wolf_form].min_mana;
if (ch->mana < cost){
send_to_char("You cannot concentrate sufficiently.\n\r", ch);
return;
}
else
ch->mana -= cost;
affect_strip(ch, gen_conceal);
send_to_char("You submit yourself to the sweet agony of transformation and take form of a wolf.\n\r",ch);
act("Shadows thicken around $n as his flesh melds itself into a giant wolf.",ch,NULL,NULL,TO_ROOM);
check_social(ch, "howl", "");
af.where = TO_AFFECTS2;
af.type = gsn_wolf_form;
af.level = level;
af.duration = 12;
af.modifier = 0;
af.location = APPLY_NONE;
af.bitvector = AFF_KEEN_SIGHT;
affect_to_char( ch, &af );
af.bitvector = 0;
af.location = APPLY_DAMROLL;
af.modifier = - ch->level / 5;
affect_to_char( ch, &af );
af.location = APPLY_HITROLL;
af.modifier = ch->level/4;
affect_to_char( ch, &af );
af.location = APPLY_AC;
af.modifier = -ch->level*3;
affect_to_char( ch, &af );
af.location = APPLY_DEX;
af.modifier = 5;
affect_to_char( ch, &af );
af.location = APPLY_STR;
af.modifier = -1;
affect_to_char( ch, &af );
ch->short_descr = str_dup("a vampire wolf");
ch->dam_type = 5;
check_improve(ch,gsn_wolf_form,TRUE,1);
return;
}
else if (!str_cmp(arg, "mist") && chance < get_skill(ch,gsn_mist_form))
{
const int cost = skill_table[gsn_mist_form].min_mana;
if (ch->mana < cost){
send_to_char("You cannot concentrate sufficiently.\n\r", ch);
return;
}
else
ch->mana -= cost;
affect_strip(ch, gen_conceal);
send_to_char("You submit yourself to the sweet agony of transformation and disperse into fine mist.\n\r",ch);
act("$n evaporates into a fine cloud of mist.",ch,NULL,NULL,TO_ROOM);
af.where = TO_AFFECTS;
af.type = gsn_mist_form;
af.level = level;
af.duration = 12;
af.modifier = 0;
af.location = APPLY_NONE;
af.bitvector = AFF_PASS_DOOR;
affect_to_char( ch, &af );
af.bitvector = 0;
af.location = APPLY_DAMROLL;
af.modifier = -ch->damroll;
af.bitvector = AFF_FLYING;
affect_to_char( ch, &af );
af.location = APPLY_HITROLL;
af.modifier = -ch->hitroll;
affect_to_char( ch, &af );
af.location = APPLY_CON;
af.modifier = -5;
affect_to_char( ch, &af );
af.location = APPLY_DEX;
af.modifier = -5;
affect_to_char( ch, &af );
af.location = APPLY_STR;
af.modifier = -10;
affect_to_char( ch, &af );
ch->short_descr = str_dup("a cloud of mist");
check_improve(ch,gsn_mist_form,TRUE,1);
return;
}
else
{
send_to_char("You failed to begin the Transformation.\n\r",ch);
return;
}
}
void spell_dark_meta( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
AFFECT_DATA af;
AFFECT_DATA* paf;
OBJ_DATA* obj = (OBJ_DATA*) vo;
if (obj->item_type != ITEM_WEAPON)
{
send_to_char("That item is not a weapon.\n\r",ch);
return;
}
if (obj->wear_loc == WEAR_NONE)
{
send_to_char("You must have the item equipped.\n\r", ch);
return;
}
if ( (paf = affect_find(obj->affected, gen_dark_meta)) != NULL)
{
if (paf->modifier++ < 3)
{
act("You fortify your link to $p.",ch, obj, NULL, TO_CHAR);
act("$p's surface ripples slightly.", ch, obj, NULL, TO_ROOM);
paf->duration += 2;
}
else
send_to_char("You have reached the limit of your abilities.\n\r", ch);
return;
}
act("You transform $p and attune it to your hunger.",ch, obj, NULL, TO_CHAR);
act("$p's surface ripples and it seems to meld itself into $n's hand.", ch, obj, NULL, TO_ROOM);
af.where = TO_NONE;
af.type = gen_dark_meta;
af.level = level;
af.duration = 6;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = 0;
affect_to_obj( obj, &af );
}
void spell_soul_steal( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
if ( obj->item_type != ITEM_CORPSE_PC && obj->item_type != ITEM_CORPSE_NPC)
{
send_to_char( "There is no life force in that.\n\r",ch);
return;
}
if ( obj->condition < 2)
{
send_to_char( "There is no life force in that.\n\r",ch);
return;
}
if (obj->item_type == ITEM_CORPSE_PC && obj->level < 15 && !IS_IMMORTAL(ch))
{
send_to_char("Not that corpse.\n\r",ch);
return;
}
if (obj->pIndexData->vnum == OBJ_VNUM_FAKE_CORPSE)
{
send_to_char("Not that corpse.\n\r",ch);
return;
}
if (!can_loot(ch, obj)){
act("$g's power shields $p from your greedy maw.", ch, obj, NULL, TO_CHAR);
return;
}
act("You suck the life force from $p.",ch,obj,NULL,TO_CHAR);
act("$n sucks the life force from $p.",ch,obj,NULL,TO_ROOM);
act("You are empowered by cosuming their life force.", ch,NULL,NULL,TO_CHAR);
ch->mana = UMIN( ch->mana + number_range(obj->level, 3 * obj->level), ch->max_mana );
update_pos( ch );
act("$p withers into a desiccated carcass.",ch,obj,NULL,TO_ALL);
free_string(obj->description);
obj->description = str_dup("A desiccated corpse lies here.");
obj->condition = 1;
}
void spell_bloodlust( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = NULL, *vch, *vch_next;
AFFECT_DATA af;
bool found = FALSE;
if (is_affected( ch, sn ) )
{
send_to_char("You are already in a rage of lust.\n\r",ch);
return;
}
if (IS_NPC(ch))
return;
for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
{
vch_next = vch->next_in_room;
if ( vch != ch && !is_safe(ch,vch) && !IS_SET(vch->act,ACT_UNDEAD))
{
victim = vch;
found = TRUE;
break;
}
}
if (!found)
{
send_to_char("Nothing here interests you.\n\r",ch);
return;
}
send_to_char("Your senses goes haywire as you lust for blood amplifies!\n\r",ch);
act("$n's eyes flood crimson red.",ch,NULL,NULL,TO_ROOM);
m_yell(ch,victim,FALSE);
multi_hit(ch,victim,TYPE_UNDEFINED);
ch->pcdata->condition[COND_HUNGER] = 0;
af.where = TO_AFFECTS2;
af.type = sn;
af.level = level;
af.duration = number_fuzzy(level/5);
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_KEEN_SIGHT;
affect_to_char( ch, &af );
af.where = TO_AFFECTS;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_DETECT_HIDDEN;
affect_to_char( ch, &af );
af.bitvector = AFF_DETECT_INVIS;
af.location = APPLY_DAMROLL;
af.modifier = ch->level/6;
af.bitvector = 0;
affect_to_char( ch, &af );
af.location = APPLY_HITROLL;
affect_to_char( ch, &af );
}
void spell_twilight_shift( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
char arg[MIL];
CHAR_DATA *victim = NULL, *mob;
int chance = number_percent(), skill =get_skill(ch,skill_lookup("twilight shift")) ;
ROOM_INDEX_DATA *pRoomIndex = NULL;
int count = 0, number = number_argument( target_name, arg );
if (target_name == NULL)
{
send_to_char("Shift to what?\n\r", ch);
return;
}
if (chance > skill)
{
send_to_char("You fail to complete the Transformation.\n\r", ch);
return;
}
if (chance < 100 - skill){
int e_r1[] = {ROOM_NO_TELEPORTIN, ROOM_NO_GATEIN, ROOM_NO_SUMMONIN};
int va = ch->in_room->area->vnum;
int area_pool = 1;
/* get the random room */
pRoomIndex = get_rand_room(va,va, //area range (0 to ignore)
0,0, //room ramge (0 to ignore)
NULL,0, //areas to choose from
NULL,0, //areas to exclude
NULL,0, //sectors required
NULL,0, //sectors to exlude
NULL,0, //room1 flags required
e_r1,2, //room1 flags to exclude
NULL,0, //room2 flags required
NULL,0, //room2 flags to exclude
area_pool, //number of seed areas
FALSE, //exit required?
FALSE, //Safe?
ch); //Character for room checks
}
/* scan through the mobs in this area and see if we match anyone */
for (mob = char_list; mob; mob = mob->next){
if (mob->in_room == NULL || mob->in_room->area != ch->in_room->area)
continue;
else if ( !can_see( ch, mob ) )
continue;
else if (!is_auto_name(arg, mob->name) )
continue;
if ( ++count == number ){
victim = mob;
break;
}
}
if(victim == NULL){
send_to_char("You fail to locate your target\n\r", ch);
return;
}
else if ( (victim == ch || victim->in_room == NULL)
|| IS_SET(victim->in_room->room_flags, ROOM_PRIVATE)
|| IS_SET(victim->in_room->room_flags, ROOM_SOLITARY)
|| IS_SET(victim->in_room->room_flags, ROOM_NO_GATEIN)
|| IS_SET(ch->in_room->room_flags, ROOM_NO_GATEOUT)
|| IS_SET(victim->in_room->room_flags, ROOM_NO_INOUT)
|| IS_SET(ch->in_room->room_flags, ROOM_NO_INOUT)){
send_to_char("You fail to locate a safe path to your target\n\r", ch);
return;
}
else if ( (victim->level >= level + 5)
|| (!IS_NPC(victim) && victim->level > LEVEL_HERO)
|| (!IS_IMMORTAL(ch) && IS_IMMORTAL(victim))
|| is_affected(victim,gsn_coffin)
|| is_affected(victim,gsn_entomb)
|| is_affected(victim, gsn_tele_lock)
|| is_affected(victim, gsn_burrow)){
send_to_char("Something interferes with your spell.\n\r",ch);
return;
}
else if (pRoomIndex == NULL)
pRoomIndex = victim->in_room;
act("$n scatters into a swarm of bats and disperses into the night.",ch,NULL,NULL,TO_ROOM);
act("Your body dissolves into a swarm of bats.",ch,NULL,NULL,TO_CHAR);
char_from_room(ch);
char_to_room(ch,pRoomIndex);
do_look(ch,"auto");
act("Your body takes shape as the bats rejoins to mold your form.",ch,NULL,NULL,TO_CHAR);
act("The sky darkens as a swarm of bats swoop in and converges into the form of $n.",ch,NULL,NULL,TO_ROOM);
}
void spell_ecstacy( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
int opp = 0;
bool fElder = get_skill(ch, gsn_unholy_gift) > 1;
if ( is_affected(victim, sn) )
{
act( "$N is already in a state of ecstacy.", ch, NULL, victim, TO_CHAR);
return;
}
if ( victim == ch )
{
send_to_char( "You can't fool yourself!\n\r", ch );
return;
}
if (is_affected(victim, gen_watchtower)){
sendf( ch, "%s is shielded within the Watchtower.\n\r", PERS(victim, ch ));
return;
}
if ( (ch->sex == 1 && victim->sex == 2) || (ch->sex == 2 && victim->sex == 1))
opp = 3;
else if ( (ch->sex == 1 && victim->sex == 1) || (ch->sex == 2 && victim->sex == 2))
opp = 0;
if (IS_AWAKE(victim) || IS_UNDEAD(victim)){
if ( victim->fighting != NULL
|| (IS_NPC(victim)
&& IS_SET(victim->act,ACT_UNDEAD))
|| (IS_NPC(victim)
&& IS_SET(victim->act,ACT_TOO_BIG))
|| saves_spell( level + 2 * opp, victim, DAM_CHARM, skill_table[sn].spell_type) )
{
act( "You fail to induce $N into ecstacy.", ch, NULL, victim, TO_CHAR);
return;
}
if (is_affected(victim, gsn_horse) && monk_good(victim, WEAR_HEAD) && !IS_NPC(victim) && !IS_IMMORTAL(ch))
{
if (fElder){
act( "You try to reverse $n's attempt to charm you, and fail!", ch, NULL, victim, TO_VICT );
act("$N tries to reverse your charm, and fails!", ch, NULL, victim, TO_CHAR );
}
else{
act( "You reverse $n's attempt to charm you, and charm $M instead!", ch, NULL, victim, TO_VICT );
act("$N reverses your charm, and charms you instead!", ch, NULL, victim, TO_CHAR );
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = 0;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
send_to_char( "Your wildest fantasy comes true right in front of your eyes!\n\r", ch );
act("$n's eyes wanders dreamily as a wide grin stretches across $s face.",ch,NULL,NULL,TO_ROOM);
stop_follower(ch);
return;
}
}
}
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = 1 + number_fuzzy( level / 15);
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( victim, &af );
send_to_char( "Your wildest fantasy comes true right in front of your eyes!\n\r", victim );
act("$n's eyes wanders dreamily as a wide grin stretches across $s face.",victim,NULL,NULL,TO_ROOM);
stop_follower(victim);
}
void spell_shadowstalk( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
CHAR_DATA *shadow;
OBJ_DATA *wield;
int i;
char buf[MSL];
char *name;
bool fElder = get_skill(ch, gsn_unholy_gift) > 1;
if ( is_affected(ch, sn) )
{
send_to_char("You are not ready to give life to another shadow yet.\n\r",ch);
return;
}
if ( ( victim = get_char_world( ch, target_name ) ) == NULL
|| victim == ch || IS_NPC(victim) || is_safe(ch,victim))
{
send_to_char("You failed.\n\r", ch);
return;
}
send_to_char("You mark a mystical symbol on the ground, and your shadow takes form!\n\r",ch);
act("$n marks a strange symbol on the ground, and $s shadow comes to life!",ch,NULL,NULL,TO_ROOM);
shadow = create_mobile( get_mob_index(MOB_VNUM_SHADOW) );
for (i=0;i < MAX_STATS; i++)
shadow->perm_stat[i] = ch->perm_stat[i];
//We spiff up some of the stats as mobs are weaker by nature.
shadow->max_hit = (4 * ch->max_hit) / 3;
shadow->hit = shadow->max_hit;
shadow->max_mana = (4 * ch->max_mana) / 3;
shadow->mana = shadow->max_mana;
shadow->level = fElder ? ch->level + 3: ch->level;
for (i=0; i < 3; i++)
shadow->armor[i] = ch->armor[i];
shadow->armor[3] =ch->armor[3];
shadow->sex = ch->sex;
shadow->gold = 0;
//Now we copy over little things like weapon stats.
shadow->damroll = ch->damroll;
shadow->hitroll = ch->hitroll;
if ( (wield = get_eq_char(ch,WEAR_WIELD)) != NULL)
{
shadow->damage[DICE_NUMBER] = wield->value[1];
shadow->damage[DICE_TYPE] = wield->value[2];
shadow->dam_type = wield->value[3];
}
name = IS_NPC(ch) ? ch->short_descr : ch->name;
sprintf( buf, shadow->short_descr, name );
free_string( shadow->short_descr );
shadow->short_descr = str_dup( buf );
sprintf( buf, shadow->long_descr, name );
free_string( shadow->long_descr );
shadow->long_descr = str_dup( buf );
sprintf( buf, shadow->description, name );
free_string( shadow->description );
shadow->description = str_dup( buf );
char_to_room(shadow,ch->in_room);
shadow->hunting = victim;
shadow->pCabal = ch->pCabal;
shadow->leader = ch;
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = fElder ? 12 : 24;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
/* make sure its killed in 24 hours, if not by sun */
af.type = gsn_timer;
af.where = TO_AFFECTS;
af.level = level;
af.duration = fElder ? 48 : 24;
af.modifier = 0;
af.location = 0;
af.bitvector = 0;
affect_to_char( shadow, &af );
}
void spell_restore_faith( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if ( !is_affected( victim, gsn_blasphemy ) )
{
if (victim == ch)
act("You did not lose your faith.",ch,NULL,victim,TO_CHAR);
else
act("$N doesn't seem to have lost $s faith.",ch,NULL,victim,TO_CHAR);
return;
}
if (check_dispel(level-5,victim,gsn_blasphemy))
{
act_new("You once again have faith in your religion.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
act("$n looks more determined.",victim,NULL,NULL,TO_ROOM);
}
else
act("You failed to restore $N's faith.",ch,NULL,victim,TO_CHAR);
}
//03-25 13:00 Viri: Changed bat morp messages, will do the rest once
//I get to those forms.
//03-31-00 Added Arms_of_gaia spell for druids. -Shadow
//03-1-23:00 Viri: remmed out arms_of_gaia code so I can compile my stuff:)
//rem it back in when you debug it:)
//04-01 9:00 Ath: Added spell_mass_hysteria
//04-03 23:00 Viri: Fixed the bug in blood lust that removed detet invis.
//04-03 23:50 viri: Added Keensight to wolf_form for vamps.
//04-13 10:30 Viri: Made thnder storm do bonus damage for high AC.
//04-13 11:00 Viri: Gave ice storm chance to crumble a weapon.
//created effect_freeze_weapon(..) for that.
//04-24 Viri: modfifed iceball for steadied damage
//04-24 Viri: reworked Hellstream for different item busting effect.