#include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #include "magic.h" #include "recycle.h" #include "interp.h" extern char *target_name; void spell_isolate( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { /* The spell when saves are failed does one of the following: - If cast on leader ONE of the followers is nuked. - If cast on follower he is unlinked from leader. - Save is vs Mental, if NPC it is based on master/leader if any. */ CHAR_DATA* victim = (CHAR_DATA*) vo; CHAR_DATA* leader = NULL; CHAR_DATA* follower = victim; //Select the leader. if (victim->leader != NULL) leader = victim->leader; //if no leader, check for master (person being followed) if (leader == NULL && victim->master != NULL) leader = victim->master; //if there is no leader at this point we check if someone is following victim if (leader == NULL) { CHAR_DATA* vch; bool fFound = FALSE; for (vch = victim->in_room->people; vch != NULL; vch = vch->next_in_room) { if (IS_IMMORTAL(victim)) continue; if (victim == vch->leader) fFound = TRUE; else if (victim == vch->master) fFound = TRUE; if (fFound) { leader = victim; follower = vch; break; } }//end follower search. //check if not found. if (leader == NULL) { act("There is no point, $N is already utterly alone.", ch, NULL, victim, TO_CHAR); return; } }//end if no leader. // sendf(ch, "master: %s victim: %s\n\r", leader->name, victim->name); //we try to stop target from following leader. if (IS_NPC(follower)) { if (check_immune(follower, DAM_CHARM, TRUE) == IS_IMMUNE){ act("$N ignores your attempt.", ch, NULL, follower, TO_CHAR); return; } if(!saves_spell(level, leader, DAM_CHARM, sn)) { act("$N loses all interest in you and returns from where $E came.", leader, NULL, follower, TO_CHAR); act("$N loses all interest in $n and returns from where $E came.", leader, NULL, follower, TO_ROOM); stop_follower(follower); extract_char(follower, TRUE); set_fighting(ch, leader); return; } } else { if (!saves_spell(level, follower, DAM_CHARM, sn)) { act("You suddenly lose all interest in following anyone.", follower, NULL, NULL, TO_CHAR); act("$N suddenly wonders off from the group.", victim, NULL, follower, TO_ROOM); stop_follower(follower); return; } } act("$N resists your attempt.", ch, NULL, follower, TO_CHAR); return; }//end isolate. void spell_minister( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { /* The good cleric spell that causes victims mana to be sapped each turn. */ CHAR_DATA* victim = (CHAR_DATA* ) vo; AFFECT_DATA af; AFFECT_DATA* paf; if (is_affected(victim, gen_seremon)) { act("You have already gifted $N with your teachings.", ch, NULL, victim, TO_CHAR); return; } if (!saves_spell(level, victim, DAM_MENTAL, sn)) { act("You place your teachings in $N's mind.", ch, NULL, victim, TO_CHAR); af.type = gen_seremon; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.level = ch->level; af.modifier = af.level;//how much mana to lose on first tick (-5 there after) af.duration = number_fuzzy(af.level / 8); paf = affect_to_char(victim, &af); string_to_affect(paf, PERS2( ch )); } else act("You failed in your righteous misson.", ch, NULL, victim, TO_CHAR); } void spell_bless_arms( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { /* another run of the mill spell, basicly adds teh bless/evil flag on the item. */ OBJ_DATA* obj = (OBJ_DATA*) vo; AFFECT_DATA* paf; //bool bool fIsGood = TRUE; bool fFound = FALSE; //const const int magic_mod = -10; const int glow_mod = -20; const int hum_mod = -30; //data int chance = get_skill(ch, sn); int g_type = 0; //EZ if (obj->item_type != ITEM_WEAPON && !(obj->item_type == ITEM_ARMOR && CAN_WEAR(obj, ITEM_WEAR_SHIELD)) ) { act("$g will only place his blessing onto weapons and shields.", ch, NULL, NULL, TO_CHAR); return; } if (is_affected_obj(obj, sn)){ send_to_char("This item has already been blessed. Your prayers ring silent.\n\r", ch); return; } if (is_affected(ch, skill_lookup("calm"))) { send_to_char("You are in far to peacefull mood to think of violence.", ch); return; } if (IS_EVIL(ch)) fIsGood = FALSE; //get the chance. if (IS_OBJ_STAT(obj,ITEM_MAGIC)) chance += magic_mod; if (IS_OBJ_STAT(obj,ITEM_GLOW)) chance += glow_mod; if (IS_OBJ_STAT(obj,ITEM_HUM)) chance += hum_mod; act("You begin the prayer and call onto your faith in $g.", ch, obj, NULL, TO_CHAR); //now we enchant. if (number_percent() < chance) { AFFECT_DATA af; if (fIsGood) act("A holy white aura envelops $p.", ch, obj, NULL, TO_ALL); else act("A dark ominous aura envelops $p.", ch, obj, NULL, TO_ALL); SET_BIT(obj->extra_flags, (fIsGood? ITEM_BLESS : ITEM_EVIL)); //special deity based effects now: if (IS_NPC(ch)) return; af.type = sn; af.where = TO_NONE; af.bitvector = 0; af.level = ch->level; af.duration = -1; af.location = APPLY_NONE; //Select the god by number. g_type = deity_table[IS_NPC(ch) ? 0 : ch->pcdata->way].path; /* LIFE */ if (g_type == PATH_LIFE) { af.location = APPLY_HIT; af.modifier = 5; } /* UNDEAD */ else if (g_type == PATH_DEATH) { if (obj->item_type == ITEM_ARMOR) { af.location = APPLY_SAVING_MENTAL; af.modifier = -3; } else { af.location = APPLY_MANA; af.modifier = -5; obj->value[3] = attack_lookup("drain"); } } /* KNOWLEDGE */ else if (g_type == PATH_KNOW) { af.location = APPLY_SAVING_SPELL; af.modifier = -1; } /* CHANCE */ else if (g_type == PATH_CHANCE) { af.location = APPLY_LUCK; af.modifier = 1; } else{ af.location = APPLY_AC; af.modifier = -5; } if (af.location == APPLY_NONE) return; //we do a whole enchant thing. if (!obj->enchanted) { AFFECT_DATA *af_new; obj->enchanted = TRUE; for (paf = obj->pIndexData->affected; paf != NULL; paf = paf->next) { af_new = new_affect(); af_new->next = obj->affected; obj->affected = af_new; af_new->where= paf->where; af_new->type = UMAX(0,paf->type); af_new->level= paf->level; af_new->duration= paf->duration; af_new->location= paf->location; af_new->modifier= paf->modifier; af_new->bitvector= paf->bitvector; af_new->has_string = paf->has_string; af_new->string = paf->string; } } //now we check if we should amplify effects or just add them. for(paf = obj->affected; paf != NULL; paf = paf->next) { if (paf->location == af.location) { fFound = TRUE; paf->modifier += af.modifier; break; } } if (!fFound) affect_to_obj(obj, &af); }//end enchant/bless else act("Nothing seems to happen.", ch, NULL, NULL, TO_ALL); } void spell_holy_hands( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { /* This is the initilizaer for the gen_holy_hands effect. */ //the only decision we make here is setting modifier to the god. AFFECT_DATA af; int g_type = 0; if (get_eq_char(ch, WEAR_WIELD) != NULL) { send_to_char("You may not hold a weapon while your hands are empowered.\n\r", ch); return; } if (is_affected(ch, gen_holy_hands)) { act("$g's power already courses through your hands.", ch, NULL, NULL, TO_CHAR); return; } if (is_affected(ch, skill_lookup("calm"))) { send_to_char("You feel far to peacefull.", ch); return; } g_type = deity_table[IS_NPC(ch) ? 0 : ch->pcdata->way].path; af.type = gen_holy_hands; af.bitvector = 0; af.where = TO_AFFECTS; af.location = APPLY_NONE; af.modifier = g_type; af.duration = number_fuzzy(level / 5); af.level = level; affect_to_char(ch, &af); } bool eff_turn_undead(int level, CHAR_DATA *vch) { /* This is the effect for new turn undead. */ CHAR_DATA* save_ch = vch; //npcs's save on teh leaders. if (vch->leader != NULL && IS_NPC(vch)) save_ch = vch->leader; if (saves_spell(level + 5, save_ch, DAM_MENTAL,skill_table[gsn_turn_undead].spell_type) || is_affected(vch, gsn_turn_undead) ) return FALSE; //anti abuse check for terror. if (IS_NPC(vch) && (IS_SET(vch->act, ACT_TOO_BIG) || IS_SET(vch->act, ACT_PRACTICE) || IS_SET(vch->act, ACT_TRAIN) || !IS_SET(vch->act, ACT_UNDEAD) || IS_SET(vch->act, ACT_NOPURGE) || IS_SET(vch->act, ACT_IS_HEALER) || IS_SET(vch->act, ACT_GAIN) ) ) return FALSE; else return TRUE; }//end effect. void spell_turn_undead( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { CHAR_DATA *vch, *vch_next; AFFECT_DATA af; int i = 0; act("$n brandishes $s holy symbol and utters words summoning $g's divine power!",ch,NULL,NULL,TO_ROOM); act("You brandish your holy symbol and utter words summoning $g's divine power!",ch,NULL,NULL,TO_CHAR); 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) && IS_SET(vch->act,ACT_UNDEAD) ) { m_yell(ch,vch,FALSE); if (!eff_turn_undead(level, vch)) { act("$N resists $g's power!.", ch, NULL, vch, TO_CHAR); act("You shrug off $n's feeble attempts.", ch, NULL, vch, TO_VICT); damage(ch, vch, level, sn, DAM_HOLY,TRUE); } else { int dam = number_range(level, 3 * level); if (IS_NPC(vch)) dam *= 2; damage(ch, vch, dam, sn, DAM_HOLY,TRUE); act("$n's eyes widen in fear of $G's power.", vch, NULL, ch, TO_ROOM); send_to_char("You panic and try to flee!\n\r", vch); af.type = sn; af.duration = number_fuzzy(2); af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_HITROLL; af.modifier = -level/5; affect_to_char(vch, &af); af.location = APPLY_DAMROLL; af.modifier = -level/5; affect_to_char(vch, &af); af.location = APPLY_SAVING_SPELL; af.modifier = level/5; affect_to_char(vch, &af); vch->fighting = ch; for (i = 0; i < 3; i++) { if (vch->in_room != ch->in_room) break; else do_flee(vch, ""); } }//end if turned }//end if area save. }//end for }//end turn undead //DEITY EFFECTS FOR DIVINE INTERVENSION /* FAITH (remove harmful spells) */ void divine_faith(CHAR_DATA* ch, int level, int sn) { AFFECT_DATA* paf; //called only if god answers :) act("The soft peacefull aura of $g envelops you as your body and soul is restored.", ch, NULL, NULL, TO_CHAR); act("A soft white light envelops $n as $g manifests his love for $m.\n\r You could almost hear ring of bells and angels singing.", ch, NULL, NULL, TO_ROOM); broadcast(ch, "A sense of serenity and calm fills you momentraly."); ch->hit += 4 * level; //start healing. for (paf = ch->affected; paf != NULL; paf = paf->next){ if (IS_GNBIT(paf->type, GN_HAR)) paf->duration = 0; } affect_strip(ch, gsn_embrace_poison); affect_strip(ch, gen_unlife); } /* COMBAT, (enlarge and haste) */ void divine_combat(CHAR_DATA* ch, int level, int sn) { AFFECT_DATA af; act("$g's strength and power suffocates your body as it grows in size.", ch, NULL, NULL, TO_CHAR); act("Thunder rumbles in the distance even as $n seems to grow in size and power.", ch, NULL, NULL, TO_ROOM); broadcast(ch, "A rumbling thunder rolls in the distance."); af.type = sn; af.duration = number_fuzzy(12); af.level = level; af.where = TO_AFFECTS; af.bitvector = AFF_HASTE; af.location = APPLY_DAMROLL; af.modifier = 3 * af.duration / 4; affect_to_char(ch, &af); af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_HITROLL; affect_to_char(ch, &af); } /* KNOWLDGE-NATURE/MYSTIC */ void divine_knowledge(CHAR_DATA* ch, int level, int sn) { AFFECT_DATA* paf; //called only if god answers :) act("The air around you hums and crackles with potent energies as giant vortex of magic surrounds you briefly.", ch, NULL, NULL, TO_CHAR); act("Crackling with titanic energies a shimmering vortex of magic surrounds $n then dissapates quickly.", ch, NULL, NULL, TO_ROOM); broadcast(ch, "Your skin tingles as potent arcane forces are released near by."); ch->mana += 12 * level; //extend spell duration of any beneficial spell for (paf = ch->affected; paf != NULL; paf = paf->next) { if (!IS_GNBIT(paf->type, GN_EXTEND)) continue; else if (paf->duration > 0 && paf->duration < 120) paf->duration = UMIN( paf->duration + 23, paf->duration * 2); } } /* LIFE (powerful turn undead) */ void divine_life(CHAR_DATA* ch, int level, int sn) { CHAR_DATA* vch, *vch_next; int diff = 0; int dam = 0; act("The air around you sizzles as a solid beam of white light errupts at your feet and engulfs you within.", ch, NULL, NULL, TO_CHAR); act("Flooding the room with terrible radiance, a solid column of white light engulfs $n!", ch, NULL, NULL, TO_ROOM); broadcast(ch, "The area brightens up momentraly from an unkown source."); for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { bool fAuto = FALSE; vch_next = vch->next_in_room; if (!is_area_safe(ch,vch) && IS_UNDEAD(vch) && ch != vch) { if (vch != ch) m_yell(ch,vch,FALSE); diff = vch->level - level; //different effects based on level diff. if (diff > 25) dam = 1; else if (diff > 9) { if (!saves_spell(level,vch,DAM_HOLY,skill_table[sn].spell_type) ) dam = dice (level, 12) / diff; else dam = 1; } else if (IS_NPC(ch) && (vch->pIndexData->vnum == MOB_VNUM_SHADOW || vch->pIndexData->vnum == MOB_VNUM_NIGHTWALKER)) fAuto = TRUE; else if (diff >= -4) { if (!saves_spell(level,vch,DAM_HOLY,skill_table[sn].spell_type) ) dam = dice (2 * level, 5); else dam = dice (level, 4); } else if (diff < -4 && IS_NPC(vch)) { if ((!saves_spell(level,vch,DAM_HOLY,skill_table[sn].spell_type) || diff <= -5) && !(IS_SET(vch->act, ACT_TOO_BIG) || IS_SET(vch->act, ACT_PRACTICE) || IS_SET(vch->act, ACT_TRAIN) || IS_SET(vch->act, ACT_NOPURGE) || IS_SET(vch->act, ACT_IS_HEALER) || IS_SET(vch->act, ACT_GAIN) ) ) fAuto = TRUE; else dam = dice (2 * level, 6); } else dam = dice (level, 12); if (fAuto) { act("$g's power envelops $N and $E disintegrates into smoldering ashes!",ch,NULL,vch,TO_ALL); act( "$n is DEAD!!", vch, NULL, NULL, TO_ROOM ); act_new( "You have been KILLED!!", vch, NULL, NULL, TO_CHAR, POS_DEAD ); raw_kill(ch, vch); do_autos(ch); } else{ /* make sure this is not akiller vs pc's */ if (!IS_NPC(vch) && dam > 450) dam = 450; damage(ch, vch, dam, sn, DAM_HOLY, TRUE); } }//end if UNDEAD }//END FOR }//END HELAMAN /* CHANCE-GREED (gain gold, cps, and blackjack threats in the room) */ void divine_greed( CHAR_DATA* ch,int level, int sn ){ AFFECT_DATA af; CHAR_DATA* vch; int gain = 0; bool fFound = FALSE; /* gain 3-8 points per PC in the room up to 30 points. */ for (vch = ch->in_room->people; vch; vch = vch->next_in_room){ if (IS_NPC(vch)) continue; gain += number_range(3, 8); if (is_area_safe_quiet(ch, vch) || ch == vch) continue; /* slit their purses */ af.where = TO_NONE; af.type = gen_gold_loss; af.level = ch->level; af.duration = 6; af.modifier = 0; af.location = 0; af.bitvector = 0; affect_to_char(vch,&af); } act("An giggle is heard in the room as something moves in the shadows.", ch, NULL, NULL, TO_ALL); if (gain){ CP_GAIN(ch, gain, TRUE ); ch->in_bank += gain * 500; sendf(ch, "`8A Bank squire hands you a stub and gallops away.``\n\r Deposit: %d by: [%s]. Current total: %d\n\r", gain * 500, "Someone", ch->in_bank); } if (fFound) send_to_char("You notice a few purses around you develop sizable cuts.\n\r", ch); } /* CHANCE-GUILE (shadowform) */ void divine_guile( CHAR_DATA* ch,int level, int sn ){ spell_shadowform( gsn_shadowform, level, ch, ch, 0); } /* CHANCE-DISCORD (fire shield/res magic) */ void divine_discord(CHAR_DATA* ch, int level, int sn) { AFFECT_DATA af; act("You scream in agony as black flames errupt around your flesh.", ch, NULL, NULL, TO_CHAR); act("$n screams in pain as black flames errupt from $s flesh.", ch, NULL, NULL, TO_ROOM); broadcast(ch, "Your vision blurs and shifts for a moment, then all is back to normal."); affect_strip(ch, sn ); af.type = sn; af.duration = number_fuzzy(12); af.level = level; af.where = TO_RESIST; af.bitvector = RES_MAGIC; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); af.where = TO_AFFECTS2; af.bitvector = AFF_FIRE_SHIELD; affect_to_char(ch, &af); send_to_char("You are now resistant to magic.\n\r", ch); check_dispel(-99, ch, skill_lookup("fire shield")); check_dispel(-99, ch, gsn_steel_wall); } /* DEATH */ void divine_death(CHAR_DATA* ch, int level, int sn) { CHAR_DATA* vch, *vch_next; OBJ_DATA* obj; CHAR_DATA* victim; bool fFail = FALSE; bool fFound = FALSE; act("The ground around you cracks and erupts with a black cloud of sinister mist!", ch, NULL, NULL, TO_ALL); broadcast(ch, "The slight breeze carries in stench of death and decay."); for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; if (vch != ch && !is_safe_quiet(ch, vch)){ m_yell(ch, vch, TRUE); spell_plague(gsn_plague, level, ch, vch, TARGET_CHAR); damage(ch, vch, level, gsn_plague, DAM_DISEASE, TRUE); } } if ( (obj = get_obj_list(ch, "corpse", ch->in_room->contents)) == NULL) { act("The vile mist slowly disappears leaving behind a carpet of disgusting maggots.", ch, NULL, NULL, TO_ALL); return; } if (get_summoned(ch, MOB_VNUM_ZOMBIE) >= 1 && !IS_IMMORTAL(ch)) fFail = TRUE; if ((obj->item_type != ITEM_CORPSE_PC && obj->item_type != ITEM_CORPSE_NPC) || (obj->owner == 0 || obj->pIndexData->vnum == OBJ_VNUM_FAKE_CORPSE)) fFail = TRUE; if (obj->item_type == ITEM_CORPSE_PC) { if( (obj->level < 15 || obj->level > ch->level + 10) && !IS_IMMORTAL(ch)) { act("The vile mist slowly disappears leaving behind a carpet of disgusting maggots.", ch, NULL, NULL, TO_ALL); return; } else for (victim = player_list; victim != NULL; victim = victim->next_player) if (victim->id == obj->owner) { fFound = TRUE; break; } if (!fFound) { act("The vile mist slowly disappears leaving behind a carpet of disgusting maggots.", ch, NULL, NULL, TO_ALL); return; } }//end if PC else if (obj->item_type == ITEM_CORPSE_NPC && obj->owner == 3) fFail = TRUE; else if (!fFail) victim = create_mobile( get_mob_index( obj->owner ) ); fFail = TRUE; if (fFail) { act("The vile mist slowly disappears leaving behind a carpet of disgusting maggots.", ch, NULL, NULL, TO_ALL); return; } //now we can make the zombie. act("The jet black cloud swirls around $p only to disappear suddenly as if blown away.", ch, obj, NULL, TO_ALL); vch = create_zombie(ch, victim, obj); act("$N comes back from the dead to do $n's bidding.",ch, NULL, victim, TO_ROOM); act("$N comes back from the dead to do your bidding.",ch, NULL, victim, TO_CHAR); if (IS_NPC(victim)) extract_char(victim,TRUE); obj_from_room ( obj ); extract_obj ( obj ); } void spell_divine_int( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { //this is the divine intervension spell. preatty humdrum except different effects for each diety. //cast at self only. int g_type = 0; int dur = 0; char* way_str; g_type = deity_table[IS_NPC(ch) ? 0 : ch->pcdata->way].path; way_str = deity_table[IS_NPC(ch) ? 0 : ch->pcdata->way].way; //messages. act("You call onto $g to help you in your cause.", ch, NULL, NULL, TO_CHAR); if (!is_affected(ch, sn)) { AFFECT_DATA af; CHAR_DATA* vch; for ( vch = char_list; vch != NULL; vch = vch->next ) { if ( vch->in_room == NULL ) continue; if ( vch->in_room->area == ch->in_room->area ) act("The ground trembles and shivers as powers of $t sweeps through the area.", vch, way_str, ch, TO_CHAR); } switch (g_type) { default: case PATH_FAITH: /* ONE GOD/FAITH */ divine_faith(ch, level, sn); dur = number_range(24, 36);break; case PATH_KNOW: /* KNOWLEDGE */ if (str_cmp(way_str, "Combat")){ divine_knowledge(ch, level, sn); dur = number_range(24, 36);break; } else{ /* COMBAT */ divine_combat(ch, level, skill_lookup("haste")); dur = number_range(12, 24);break; } case PATH_LIFE: /* LIFE */ divine_life(ch, level, sn); dur = number_range(4, 8);break; case PATH_CHANCE: /* GREED */ if (!str_cmp(way_str, "Greed")){ divine_greed(ch, level, sn); dur = number_range(8, 16);break; } /* GUILE */ else if (!str_cmp(way_str, "Guile")){ divine_guile(ch, level, sn); dur = number_range(8, 16);break; } /* DISCORD */ else if (!str_cmp(way_str, "Discord")){ divine_discord(ch, level, skill_lookup("demonfire")); dur = number_range(12, 24);break; } case PATH_DEATH: /* DEATH */ divine_death(ch, level, sn); dur = number_range(36, 72);break; } af.type = sn; af.level = level; af.duration = dur; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } else send_to_char("The heavens are silent.\n\r", ch); } /* BATTLE MAGE STUFF */ void spell_forcefield( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; /* this is BGM version of protective shield, acts as protective sheld AND limits the amount of blunt damage that acn be done BEFORE sanc etc. */ //const const int min_ceil = 60;//lowest lvl of bash dam shielding const int base_ceil = 260;//base shielding const int lvl_mod = 11;//base_ceil - (lvl / lvl_mod) * lvl_mult = ceiling const int lvl_mult = 50; if ( is_affected( ch, sn ) ) { send_to_char("You are already shielded.\n\r",ch); return; } if ( is_affected( ch, gsn_mana_lock)) { send_to_char("Your manalock seems to interfere.\n\r",ch); return; } if ( is_affected( ch, gen_ref_shield)) { send_to_char("Your reflective shield seems to interfere.\n\r",ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = number_fuzzy( level/5); af.location = APPLY_NONE; af.modifier = UMAX(min_ceil,base_ceil - ((level / lvl_mod) * lvl_mult)); af.bitvector = 0; affect_to_char( victim, &af ); act( "You weave air and energy together into a thick, flexible forcefield.", ch, NULL, NULL, TO_CHAR ); act( "$n is surrounded by a flexible forcefield.", ch, NULL, NULL, TO_ROOM ); } void spell_terra_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { AFFECT_DATA af; int sector = ch->in_room->sector_type; int skill = get_skill(ch, sn); if (is_affected(ch, gen_terra_shield)){ send_to_char("You already hold the ground to your bidding.\n\r", ch); return; } //check for sector. if (sector == SECT_AIR || sector == SECT_WATER_SWIM || sector == SECT_WATER_NOSWIM) { send_to_char("There is no ground here for you to animate.\n\r", ch); return; } af.type = gen_terra_shield; af.level = level; af.duration = UMAX(0, skill - 75)/5 + level / 6; af.duration += (level * skill / 100) > 35? 5 : 0; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_rust( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { AFFECT_DATA af; AFFECT_DATA* paf, *paf_next; CHAR_DATA* victim = (CHAR_DATA*) vo; //data int change = 0; int skill = get_skill(ch, sn); int armor = 0; int hit = 0; int dam = 0; int dur = (skill > 85? 1 : 0); const int max_dur = 5 + level / 10; bool is_new = FALSE; //now we calculate the reduction. change = level / 5 + (level > 35? 1: 0) + (level > 40 ? 2 : 0) + (level > 45 ? 2 : 0) + (level > 49 ? 3 : 0); if (saves_spell(level + UMAX(0, (skill - 75) / 8 ), victim, DAM_DROWNING, skill_table[sn].spell_type)) { act("$N possesions seems to resist the spell.", ch, NULL, victim, TO_CHAR); act("Your items seems to resist the spell slightly.", ch, NULL, victim, TO_VICT); change = 2 * change / 3; } if ( (paf = affect_find(victim->affected, gsn_rust)) == NULL) is_new = TRUE; //we check if target is affected by rust. if (is_new) { send_to_char("A layer of rust sprouts on your weapons and armor.\n\r", victim); act("$n's possessions redden with rust.", victim, NULL, NULL, TO_ROOM); dur += 2; } else if (paf->duration < max_dur) { send_to_char("The layer of rust on your items thickens.\n\r", victim); act("$n's weapons and armor thicken with rust.", victim, NULL, NULL, TO_ROOM); } else { act("$N's items are as rusty as they are going to get.", ch, NULL, victim, TO_CHAR); return; } dam = dur; hit = dur; armor = change; // sendf(ch, "change: %d hit %d dam %d armor %d\n\r", change, hit, dam, armor); if (is_new) { af.type = sn; af.duration = dur; af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; if (hit > 0) { af.duration = dur; af.location = APPLY_HITROLL; af.modifier = - hit; affect_to_char(victim, &af); } if (dam > 0) { af.duration = dur; af.location = APPLY_DAMROLL; af.modifier = - dam; affect_to_char(victim, &af); } if (armor > 0) { af.duration = dur; af.location = APPLY_AC; af.modifier = armor; affect_to_char(victim, &af); } return; } //Else we enhance existing efffects. for (paf = victim->affected; paf != NULL; paf = paf_next) { AFFECT_DATA af_new; paf_next = paf->next; if (paf->type != sn) continue; af_new.type = paf->type; af_new.duration = paf->duration; af_new.level = paf->level; af_new.where = paf->where; af_new.bitvector = paf->bitvector; af_new.location = paf->location; af_new.modifier = paf->modifier; if (paf->location == APPLY_AC){ if (paf->modifier < 150) af_new.modifier += armor; } else if (paf->location == APPLY_HITROLL){ if (paf->modifier > -max_dur) af_new.modifier -= 2 * hit; } else if (paf->location == APPLY_DAMROLL){ if (paf->modifier > -max_dur) af_new.modifier -= 2 * dam; } if (paf->duration < max_dur){ af_new.duration += 3; } affect_remove( victim, paf); affect_to_char(victim, &af_new); } } void spell_loc_grav( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { CHAR_DATA *victim; OBJ_DATA* obj = NULL; OBJ_DATA* wield; OBJ_DATA* sec; OBJ_DATA* hold; OBJ_DATA* shield; char arg1[MIL]; char arg2[MIL]; //data int chance = 15 + UMAX(-5, get_skill(ch, sn) - 80); int wear_loc = WEAR_NONE; //const const int weight_mod = 10;//divisor const int level_mod = 5; const int str_med = 22; //median const int str_mod = 10;//multiplier const int luck_mod = 2; //bool bool prim = FALSE; //first we check for prim/sec target_name = one_argument(target_name, arg1); target_name = one_argument(target_name, arg2); //check for args. if (str_prefix(arg1, "secondary") || arg1[0] == '\0') prim = TRUE; if ( (victim = ch->fighting) == NULL){ send_to_char("With no opponent in combat range the spell fails.\n\r", ch); return; } //now we run through items looking for something to grab. /* prim: - wield, hold. !prim: - secondary, hold, shield. */ //we grab the pointers first for simplicity. wield = get_eq_char(victim, WEAR_WIELD); sec = get_eq_char(victim, WEAR_SECONDARY); hold = get_eq_char(victim, WEAR_HOLD); shield = get_eq_char(victim, WEAR_SHIELD); if (prim) { if (wield != NULL) {obj = wield; wear_loc = WEAR_WIELD;} else if (shield != NULL && hold != NULL) {obj = hold;wear_loc = WEAR_HOLD;} } else { if (shield != NULL) {obj = shield;wear_loc = WEAR_SHIELD;} else if (sec != NULL) {obj = sec;wear_loc = WEAR_SECONDARY;} else if (hold != NULL) {obj = hold;wear_loc = WEAR_HOLD;} } //final check. if (obj == NULL) { act("$N has nothing in that hand.", ch, NULL, victim, TO_CHAR); return; } //messages act("You begin to focus forces of gravity on $p.", ch, obj, victim, TO_CHAR); //now we get a chance. chance += obj->weight / weight_mod; chance += (str_med - get_curr_stat(ch, STAT_STR)) * str_mod; chance += (level - victim->level) * level_mod; chance += (get_curr_stat(ch, STAT_LUCK) - get_curr_stat(ch, STAT_LUCK)) * luck_mod; chance = URANGE(5, chance, 95); if (number_percent() < chance) { act("$p seems to take on the weight of a mountain!", ch, obj, victim, TO_VICT); if (wear_loc == WEAR_WIELD) disarm(ch, victim); else if (wear_loc == WEAR_SECONDARY) disarm_offhand(ch, victim); else if (wear_loc == WEAR_SHIELD) shield_disarm(ch, victim); else if (wear_loc == WEAR_HOLD) { if (obj->item_type == ITEM_KEY){ send_to_char("That item is too small for you to focus on properly.\n\r", ch); return; } if (IS_OBJ_STAT(obj, ITEM_NOREMOVE)) { act("It wont even budge!", ch, NULL, NULL, TO_ALL); return; } act("$p slams to the ground.", victim, obj, victim, TO_ROOM); act("Counter to your efforts $p slams to the ground.", victim, obj, NULL, TO_CHAR); obj_from_char(obj); if (IS_OBJ_STAT(obj, ITEM_NODROP)) obj_to_char(obj, victim); else obj_to_room(obj, ch->in_room); }//END HOLD return; }//END SUCCESS act("You miscalculate the focus.", ch, NULL, victim, TO_CHAR); act("$p seems a bit heavier momentarly.", ch, obj, victim, TO_VICT); } void spell_air_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { AFFECT_DATA af; int skill = get_skill(ch, sn); if (is_affected(ch, sn)) { send_to_char("You are already protected by an air shield.\n\r", ch); return; } send_to_char("You compress the air around you into a thick protective layer.\n\r", ch); act("$n's image turns cloudy as air thickens around him.", ch, NULL, NULL, TO_ROOM); af.type = sn; af.level = level; af.duration = UMAX(0, skill - 75) + level / 5; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_AC; af.modifier = -level; affect_to_char(ch, &af); } void spell_blades( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { AFFECT_DATA af; if (is_affected(ch, gen_blades)) { send_to_char("Given the angular velocity of the blades, the safe limit is 2 blades at a time.\n\r", ch); return; } af.type = gen_blades; af.level = level; af.duration = level/5 + (level >= 40? 1 : 0) + (level >= 45? 1 : 0) + (level >= 48? 3 : 0); af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_sharpmetal( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { //We damage the victim, then search for more targets to hit. CHAR_DATA* victim = (CHAR_DATA*) vo; CHAR_DATA* vch, *vch_next; static const sh_int dam_each[] = {0, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 30, 40, 45, 46, 47, 50, 52, 55, 57, 60, 65, 70, 70, 75, 80, 80, 83, 85, 88, 90, 91, 92, 93, 94, 95, 105,110,115,120,125, }; int dam_type = number_range(1, 3); //(PIERCE, SLASH, BASH) int dam_lvl = 0; int dam = 0; int up = 0;//upkeep dam_lvl = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1); dam_lvl = UMAX(0, dam_lvl); dam = number_range(2 * dam_each[dam_lvl] / 3, dam_each[dam_lvl]); act("You create a mass of metal shards and sends them hurling!", ch, NULL, victim, TO_CHAR); act("$n creates a mass of metal shards and sends them hurling!", ch, NULL, victim, TO_ROOM); act("$n directs the stream of deadly metal in your direction!", ch, NULL, victim, TO_VICT); //no we start damaging. if (saves_spell(level, victim, dam_type, skill_table[sn].spell_type)) dam = 4 * dam / 5; damage(ch, victim, dam, sn, dam_type, TRUE); //now we hit the rest that are in combat. for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; //dont hit the original twice if (vch == victim) continue; //only if target is fighting us. if (vch->fighting == NULL) continue; //dont hit area safes. if (is_area_safe_quiet(ch, vch)) continue; //only if target is in combat with us or our mates. if (vch->fighting != ch && !is_same_group(ch, vch->fighting) ) continue; if (!IS_NPC(ch) && ch->mana < (up = _mana_cost(ch, sn)) ) { send_to_char("You lack the power to sustain the spray.\n\r", ch); break; } else if (!IS_NPC(ch)) ch->mana -= up; act("$n directs the stream of deadly metal in your direction!", ch, NULL, victim, TO_VICT); dam = number_range(2 * dam_each[dam_lvl] / 3, dam_each[dam_lvl]); dam_type = number_range(1, 3); //(PIERCE, SLASH, BASH) if (saves_spell(level, vch, dam_type, skill_table[sn].spell_type)) dam = 4 * dam / 5; damage(ch, vch, dam, sn, dam_type, TRUE); }//end for }//END SPELL void spell_plumbum( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { // CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; int skill = get_skill(ch, sn); if (is_affected(ch, gen_plumbum)) { send_to_char("You are already intensifying the gravity in the area.\n\r", ch); return; } af.type = gen_plumbum; af.level = level; af.duration = UMAX(0, skill - 75)/5 + level / 8; af.duration += (level * skill / 100) > 35? 5 : 0; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_sear( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { CHAR_DATA* victim = (CHAR_DATA*) vo; static const sh_int dam_each[] = {0, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 30, 30, 30, 30, 30, 31, 32, 33, 34, 35, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 85, 95, 110,120, }; int time = mud_data.time_info.hour; int dam_lvl = 0; int dam = 0; bool fAdv = get_skill( ch, sn ) > 100; dam_lvl = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1); dam_lvl = UMAX(0, dam_lvl); dam = number_range(dam_each[dam_lvl], 2 * dam_each[dam_lvl]); if ( !IS_OUTSIDE(ch) ) { if (fAdv) send_to_char("Your mind throbbing with effort, you try to reach the distant sun rays.\n\r", ch ); else{ send_to_char("The rays of the sun do not reach here.\n\r", ch); return; } } if (time < 7 || time > 18) { send_to_char("Without the sun, you lack a power source.\n\r", ch); return; } else if (time > 10 && time < 14) { send_to_char("With the sun near its zenith, you release a deadly beam of light.\n\r", ch); act("With sun near its zenith, $n releases a deadly beam of light.", ch, NULL, NULL, TO_ROOM); dam = 3 * dam / 2; level = level + 3; } else { send_to_char("You focus the sunlight into a searing beam.\n\r", ch); act("$n focuses the sun's rays into a searing beam.", ch, NULL, NULL, TO_CHAR); } if (saves_spell(level, victim, DAM_LIGHT, skill_table[sn].spell_type)) dam /= 2; spell_blindness(gsn_blindness, level, ch, victim, TARGET_CHAR); damage(ch, victim, dam, sn, DAM_LIGHT, TRUE); } void spell_dan_blade( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { OBJ_DATA* obj = (OBJ_DATA*) vo; AFFECT_DATA af; AFFECT_DATA* paf; char buf[MIL]; /* This is the dancing blades spell. - The gen_dan_balde is set onto the character to run the effects - teh gsn_Dan_blade is set ontot hte object as a link between the char. and obj. - modifier stores the common key, to give singularity. - Only weapons are valid. - Spears, Maces, Flails and whips are not valid targets. */ //data int key = number_range(-32768, 32768); int dur = 0; strcpy(buf, ch->name); if (is_affected(ch, gen_dan_blade)) { send_to_char("You may only control one blade at a time.\n\r", ch); return; } //Carried? if (obj->wear_loc != -1) { send_to_char("The item must be carried to be enchanted.\n\r",ch); return; } //check for weapons. if (obj->item_type != ITEM_WEAPON) { send_to_char("That item is not a weapon.\n\r",ch); return; } //Weapon type if (obj->value[0] == WEAPON_MACE || obj->value[0] == WEAPON_FLAIL || obj->value[0] == WEAPON_SPEAR || obj->value[0] == WEAPON_WHIP ) { send_to_char("You may only place this spell on bladed weapons.\n\r", ch); return; } //Misc factors if (affect_find(obj->affected, gen_malform)) { act("$p soaks the spell right up.", ch, obj, NULL, TO_CHAR); return; } if (is_affected_obj(obj, sn)) { act("$p is already your servant.", ch, obj, NULL, TO_CHAR); return; } //all seems ok. dur = number_fuzzy(8) + (level > 49? 4 : 0); //we place the affect on object first. af.type = sn; af.level = number_fuzzy(level); af.duration = dur; af.where = TO_NONE; af.bitvector = 1;//VERY IMPORTANT, WEAPON IS VISIBLE ONLY IF bitvector != 0; af.location = APPLY_NONE; af.modifier = key;//VERY IMPORTANT, the key is the link between gen and gsn. if ( (paf = affect_to_obj(obj, &af)) != NULL) string_to_affect(paf, ch->name); af.where = TO_AFFECTS; af.bitvector = 0; af.type = gen_dan_blade; if ( (paf = affect_to_char(ch, &af)) != NULL) string_to_affect(paf, obj->short_descr); } void spell_manalock( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { AFFECT_DATA af; if (is_affected(ch, gsn_forcefield) ) { send_to_char("Your forcefield seems to interfere.\n\r", ch); return; } if (is_affected(ch, gen_ref_shield)) { send_to_char("Your reflective shield seems to interfere.\n\r", ch); return; } if (is_affected(ch, gsn_mana_lock)) { send_to_char("Your enchantements are already locked.\n\r", ch); return; } send_to_char("You place a protective ward on your enchantements.\n\r", ch); act("The air around $n humms and crackles briefly.", ch, NULL, NULL, TO_ROOM); af.type = sn; af.duration = number_fuzzy(24); af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_SAVING_SPELL; af.modifier = -level/10; affect_to_char(ch, &af); } void spell_ref_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { // humdrum spell gen does all the work. AFFECT_DATA af, *paf; if (is_affected(ch, gsn_forcefield) ) { send_to_char("Your forcefield seems to interfere.\n\r", ch); return; } if (is_affected(ch, gsn_mana_lock)) { send_to_char("Your manalock seems to interfere.\n\r", ch); return; } if ( (paf = affect_find( ch->affected, gen_ref_shield)) != NULL){ if (get_skill(ch, sn ) < 86){ send_to_char("You are already surrouned by a reflective field.\n\r", ch); return; } else if (paf->modifier < 75){ send_to_char("You boost the charge on your reflective shield.\n\r", ch ); act("The air around $n sizzles with energy.", ch, NULL, NULL, TO_ROOM); paf->modifier += 10; } else{ send_to_char("The charge on your reflective shield is too high to handle safely.\n\r",ch ); } return; } af.type = gen_ref_shield; af.duration = number_fuzzy(2 + level / 5); af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } /* shows the global meteor swarm messages */ void m_swarm_msg(CHAR_DATA* ch, bool d_head) { CHAR_DATA* vch; AFFECT_DATA* paf; //room messge for d_head if (d_head) { act("$n has summoned Death's Head, may your god have mercy on your soul.", ch, NULL, NULL, TO_ROOM); act("You have summoned Death's Head, may $g have mercy on your soul.", ch, NULL, NULL, TO_CHAR); } for ( vch = char_list; vch != NULL; vch = vch->next ) { if ( vch->in_room == NULL ) continue; //deaths head message. if (vch->in_room != ch->in_room && d_head) send_to_char("On the horizon you see an ominous red streak descend towards the ground."\ "\n\rMoments later the ground trembles with astonishing force.\n\r", vch); if ( (paf = affect_find(vch->affected, gsn_burrow)) != NULL) { if (paf->modifier == ch->in_room->vnum && !is_safe_quiet(ch, vch)) { send_to_char("The ground begins to heave and collapse around you!\n\r", vch); do_unburrow(vch, ""); } } if ( vch->in_room->area == ch->in_room->area && ch->in_room != vch->in_room && !d_head) send_to_char( "The ground shudders under heavy impacts.\n\r", vch ); }//end if same area. } void spell_meteor_swarm( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { /* spell runs throuh all valid targets giving them a cell number for mteors brouth down, each meteor hits a cell, we run through all ch's and if the cell matches the metoer we damage. */ const int max_cell = 4; const int max_tar = 12; int targets = 0; CHAR_DATA* vch; struct _target_ch { CHAR_DATA* ch; sh_int cell; }cells[max_tar]; bool d_head = ( (mud_data.time_info.month == mud_data.time_info.day && mud_data.time_info.hour%12 == 0)? TRUE : FALSE); bool ffield = FALSE; bool fAdv = get_skill( ch, sn ) > 100; static const sh_int dam_each[] = {0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14,//2 rock 20, 21, 22, 23, 25, 30, 31, 32, 33, 35,//3 rock 35, 40, 40, 45, 45, 50, 55, 55, 60, 60,//4 rocks 62, 64, 68, 72, 75, 76, 77, 78, 80, 85,//6 rocks 90, 92, 96,100,110, 115,120,130,140,150,//8 rocks }; int dam = 0; int dam_lvl = 0; int i = 0; int rocks = 1; int rocks_max = 2 + (level > 15 ? 1: 0) + (level > 30 ? 1: 0) + (level > 40 ? 2: 0) + (level > 45 ? 2: 0) + (level > 48? number_range(0, (get_curr_stat(ch, STAT_LUCK) - 8) / 2): 0); int rocks_min = UMAX(1, rocks_max / 2); int dam_mult = 100; dam_lvl = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1); dam_lvl = UMAX(0, dam_lvl); dam = d_head && level > 45? 600 + number_range(0, 200) : number_range(dam_each[dam_lvl] / 2, dam_each[dam_lvl]); if (!IS_OUTSIDE(ch)) { if (fAdv) act("Sucking all wind into it, a dark pulsating rift opens overhead!\n\r", ch, NULL, NULL, TO_ALL); else{ send_to_char("Without clear path to the heavens the spell fails.\n\r", ch); return; } } //we get the number of rocks we are bringing down. if (!d_head) rocks = number_range(rocks_min, rocks_max); //DEBUG // sendf(ch, "min: %d, max:%d, rocks:%d", rocks_min, rocks_max, rocks); if (ch->mana > 20 && is_affected(ch, gsn_forcefield)) { send_to_char("You pump energy into your forcefield for your protection.\n\r", ch); act("The forcfield around $n hums and crackles.", ch, NULL, NULL, TO_ROOM); ch->mana -= 20; ffield = TRUE; } //show messages. m_swarm_msg(ch, d_head); //zero the array just in case. for (i = 0; i < max_tar; i ++) {cells[i].ch = NULL;cells[i].cell = 0;} //now we select targets for (vch = ch->in_room->people;vch != NULL; vch = vch->next_in_room) { if (targets >= max_tar ) break; if (ch != vch && is_safe_quiet(ch, vch)) continue; if (is_same_group(ch, vch) && ffield && !d_head) continue; cells[targets].ch = vch; cells[targets].cell = number_range(1, max_cell); targets++; }//END target selection //Death head attack. if (d_head) { for(i = 0; i <= targets; i++) { vch = cells[i].ch; if (vch != NULL) damage(ch, vch, dam, sn, DAM_INTERNAL, TRUE); } return; } //show damage messgae. switch (number_range(0, 3)) { case 0: case 1: act("Amall skyrocks shower the area.", ch, NULL, ch, TO_ALL); dam_mult = 80; break; case 2: dam_mult = 100; act("The sky darkens as flaming boulders begin to impact in the area.", ch, NULL, ch, TO_ALL); break; case 3: dam_mult = 130; act("You vainly look for cover as small astroids level the area.", ch, NULL, ch, TO_ALL); break; }//END SWITCH //start hitting people now. for (i = 0; i < rocks; i++) { int j = 0; //each meteor gets a cell number int cell_hit = number_range(1, max_cell); //we now run through all cahracters checking if the character is in the cell hit. for (j = 0; j < max_tar; j++) { //check if the cell is hit. if (cells[j].cell != cell_hit) continue; if ( (vch = cells[j].ch) == NULL) continue; //hit the char. if ( vch->in_room != ch->in_room || (is_area_safe_quiet(ch, vch) && vch != ch) || is_ghost(vch, 600) ) continue; //Hit now. if (saves_spell(level, vch, DAM_BASH, skill_table[sn].spell_type)) dam /= 2; dam = dam_mult * dam / 100; damage(ch, vch, dam, sn, DAM_BASH, TRUE); dam = number_range(dam_each[dam_lvl] / 2, dam_each[dam_lvl]); }//end cell check }//end rocks }//end spell void spell_comprehend_lan( 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("The enchantement is already in effect.\n\r", ch); return; } af.type = sn; af.level = level; af.duration = 2* level; af.location = APPLY_NONE; af.modifier = 0; af.where = TO_AFFECTS; af.bitvector = 0; send_to_char("You begin to understand all manner of speech.\n\r", victim); if (ch != victim) act("$N begins to understand all manner of speech.\n\r", ch, NULL, victim, TO_CHAR); affect_to_char(victim, &af); } /* Item spell to purge embrace poison */ void spell_purge_unlife( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { CHAR_DATA *victim = ch; if ( !is_affected( victim, gsn_embrace_poison ) ){ act("You aren't infected with vampire's bite.",victim,NULL,victim,TO_CHAR); return; } if (check_dispel(level - 3, victim,gsn_embrace_poison)) act("The bite wound sizzles, smokes and then quickly heals and disappears.", victim, NULL, victim, TO_ALL); else{ act("The bite wound smokes momentarly then explodes in a fountain of puss.", ch, NULL, victim, TO_ROOM); damage(victim, victim, UMAX(1, level / 2), gsn_embrace_poison, DAM_POISON, TRUE); } WAIT_STATE2(ch, 4 * PULSE_VIOLENCE); } void spell_sacred_runes( int sn, int level, CHAR_DATA *ch, void *vo,int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (victim != ch){ act("You may only submit your own flesh to $g.", ch, NULL, NULL, TO_CHAR); return; } if (victim->class == class_lookup("psionicist")) { send_to_char("Strangly nothing happens...\n\r", ch); return; } if (is_affected(ch, gsn_sacred_runes)){ send_to_char("You are already protected by the sacred runes.\n\r", ch); return; } if ( IS_AFFECTED(victim, AFF_SANCTUARY) ) { send_to_char("The sanctuary seems to negate the effect.\n\r", ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = UMAX(1, level - 8); af.duration = number_fuzzy( level / 10); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = 0; affect_to_char( victim, &af ); damage(ch, ch, number_range(level / 2, level), gsn_sacred_runes, DAM_INTERNAL, TRUE); act("Bloody runes of $g's power begin to cover your flesh.", ch, NULL, ch, TO_CHAR); act("Bloody runes of $g's power begin to cover $n's flesh.", ch, NULL, ch, TO_ROOM); } void spell_visitation( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { CHAR_DATA* victim = (CHAR_DATA*) vo; AFFECT_DATA af; AFFECT_DATA* paf; if ( is_affected( victim, gen_visit ) ) { act("$N's soul is already marked.",ch,NULL,victim,TO_CHAR); return; } if (saves_spell(level,victim,DAM_NEGATIVE,skill_table[sn].spell_type)) { act_new("You feel uneasy but it passes.",victim,NULL,NULL,TO_CHAR,POS_DEAD); if (ch != victim) act("$N seems to be unaffected.",ch,NULL,victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = gen_visit; af.level = level; af.duration = number_range(2, 5); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = 0; paf = affect_to_char(victim,&af); string_to_affect(paf, ch->name); act("You mark $N's soul for your demonic servants.", ch, NULL, victim, TO_CHAR); } // Endorphin rush, ripped down cure serious, but physical (for warmasters) // Coded by: Athaekeetha void spell_endorphin_rush( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int heal = dice(3, 4); act_new("You feel a rush of endorphins, numbing your pain.", ch,NULL, victim,TO_CHARVICT,POS_DEAD ); if ( ch != victim ) { act("You cause $N's endorphins to surge.", ch,NULL,victim,TO_CHAR ); } victim->hit = UMIN( victim->hit + (heal/2), victim->max_hit ); victim->mana = UMIN( victim->mana + (heal/2), victim->max_mana ); update_pos( victim ); } //Lifeforce spell for Druids. 12-02-00 Shadow void spell_lifeforce( 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 (victim->class == class_lookup("psionicist")) { send_to_char("Strangely nothing happens...\n\r", ch); return; } if (ch->in_room->sector_type != SECT_FOREST) { send_to_char("A lifeforce can only be instilled within a forest!\n\r",ch); return; } if (is_affected(ch, gsn_sacred_runes)){ send_to_char("The vile runes seem to negate the effect.\n\r", ch); return; } if ( IS_AFFECTED(victim, AFF_SANCTUARY) ) { if (victim == ch) act("Not with sanctuary.",ch,NULL,victim,TO_CHAR); else act("$N is already protected by a lifeforce.",ch,NULL,victim,TO_CHAR); return; } if (is_affected(victim, sn)) { if (victim == ch) act("You are already harnessing the lifeforce.",ch,NULL,victim,TO_CHAR); else act("$N is already harnessing the lifeforce.",ch,NULL,victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = number_fuzzy( level / 6); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = 0; affect_to_char( victim, &af ); act_new( "You are surrounded by a green aura.", victim, NULL, NULL, TO_CHAR, POS_DEAD ); act( "$n is surrounded by a green aura.", victim, NULL, NULL, TO_ROOM ); } void spell_thorn_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 are already protected by a shield of thorns.\n\r",ch); return; } if ( is_affected(victim,skill_lookup("protective shield"))) { send_to_char("Not with protective shield.\n\r",ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = number_fuzzy( level/6); af.location = 0; af.modifier = 0; af.bitvector = 0; affect_to_char( victim, &af ); send_to_char( "You are protected by a shield of thorns.\n\r",ch); act( "$n's skin becomes covered in thorns.", ch, NULL, NULL, TO_ROOM); } //=====Circle of Protection=====// //12-02-00 -Shadow void spell_circle_of_protection( int sn, int level, CHAR_DATA *ch, void *vo,int target){ CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; char arg[MIL]; if (ch->in_room->sector_type != SECT_FOREST) { send_to_char("Circles of protection must be formed in a forest.\n\r",ch); return; } if (is_affected(ch, sn)) { send_to_char("You are already protected.\n\r", ch); return; } target_name = one_argument(target_name, arg); if (arg[0] == '\0'){ send_to_char("Circle of Protection :\n\r"\ "Syntax: cast 'circle of protection' <red/blue/green/white/black>\n\r", ch); return; } if (victim != NULL) { send_to_char ("Circles of protection can only be created around you.\n\r", ch); return; } affect_strip(ch, gsn_circle_of_protection); af.type = sn; af.level = level; af.duration = 24; af.where = TO_AFFECTS; af.modifier = 0; af.location = APPLY_NONE; /* set type of prtection */ if (!str_prefix(arg, "red")) { af.where = TO_AFFECTS2; af.bitvector = AFF_FIRE_SHIELD; affect_to_char( ch, &af ); act_new( "You surround yourself in a red circle of protection.",ch,NULL,ch,TO_CHARVICT,POS_DEAD ); act("$N surrounds $mself in a red circle of protection.",ch,NULL,ch,TO_ROOM); return; } if (!str_prefix(arg, "blue")) { af.where = TO_AFFECTS2; af.bitvector = AFF_ICE_SHIELD; affect_to_char( ch, &af ); act_new( "You surround yourself in a blue circle of protection.",ch,NULL,ch,TO_CHARVICT,POS_DEAD ); act("$N surrounds $mself in a blue circle of protection.",ch,NULL,ch,TO_ROOM); return; } if (!str_prefix(arg, "green")) { af.where = TO_AFFECTS; af.bitvector = 0; affect_to_char( ch, &af ); act_new( "You surround yourself in a green circle of protection.",ch,NULL,ch,TO_CHARVICT,POS_DEAD ); act("$N surrounds $mself in a green circle of protection.",ch,NULL,ch,TO_ROOM); return; } if (!str_prefix(arg, "white")) { af.where = TO_AFFECTS; af.bitvector = AFF_PROTECT_GOOD; affect_to_char( ch, &af ); act_new( "You surround yourself in a white circle of protection.",ch,NULL,ch,TO_CHARVICT,POS_DEAD ); act("$N surrounds $mself in a white circle of protection.",ch,NULL,ch,TO_ROOM); return; } else { af.where = TO_AFFECTS; af.bitvector = AFF_PROTECT_EVIL; affect_to_char( ch, &af ); act_new( "You surround yourself in a black circle of protection.",ch,NULL,ch,TO_CHARVICT,POS_DEAD ); act("$N surrounds $mself in a black circle of protection.",ch,NULL,ch,TO_ROOM); return; } } void spell_forest_mist( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (ch->in_room->sector_type == SECT_AIR || ch->in_room->sector_type == SECT_DESERT || ch->in_room->sector_type == SECT_CITY || ch->in_room->sector_type == SECT_INSIDE){ send_to_char("You cannot form enough mist in city, indoors, deserts or air.\n\r",ch); return; } if ( is_affected( victim, sn ) ) { if (victim == ch) act("You can see nothing through the thick mist!",ch,NULL,victim,TO_CHAR); else act("$N is already shrouded in the forest mists!", ch,NULL,victim,TO_CHAR); return; } if ( saves_spell( level, victim, DAM_MALED,skill_table[sn].spell_type)) { sendf(ch, "You failed to call forth the forest mists around %s.\n\r", PERS(victim,ch)); return; } af.where = TO_AFFECTS2; af.type = sn; af.level = level; af.duration = (level / 12) + 1; af.location = 0; af.modifier = 0; /* There isas slight trick here to speed up the checks in act_move and such */ /* Instead of whole new bit flag, the code first checks for terrain, then if present */ /* checks if terrain due to forest mist */ af.bitvector = AFF_TERRAIN; affect_to_char( victim, &af ); act("Heavy forest mists rise and form all around $n.", victim, NULL, NULL, TO_ROOM); act("A heavy forest mist rises, obscuring any vision.",ch, NULL, victim, TO_VICT); } void spell_restoration( 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,"The Earth Mother does not like %s.\n\r",PERS(victim,ch)); return; } if (ch->in_room->sector_type != SECT_FOREST) { send_to_char("Restorative healing can only occur in a forest.\n\r",ch); return; } if (is_affected(ch, sn)){ send_to_char("You are not ready yet to perform a restoration.\n\r", ch); return; } if (victim != ch) { act("$n touches you with a green aura, instilling earth energy into you.",ch,NULL,victim,TO_VICT); act("You touch $N with a green aura, restoring $S health.",ch,NULL,victim,TO_CHAR); } if (check_dispel(-99,victim,gsn_poison)) found = TRUE; if (check_dispel(-99,victim,gsn_plague)) found = TRUE; if (check_dispel(-99,victim,skill_lookup("weaken"))) found = TRUE; if (found || victim->hit < victim->max_hit){ AFFECT_DATA af; act("$n is restored to health.",victim,NULL,NULL,TO_ROOM); send_to_char("A warm green aura surrounds your body, then fades.\n\r",victim); if (!IS_NPC(ch) && !IS_NPC(victim) && ch->class == class_lookup("druid") && ch != victim) gain_exp(ch,number_range(1,ch->level/8)); victim->hit = UMIN( victim->hit + 100, victim->max_hit ); update_pos( victim ); af.type = sn; af.duration = 24; af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char( ch, &af); } else { act("$N does not seem to be affected by the green aura.",ch,NULL,victim,TO_CHAR); send_to_char("You don't seem to feel any different.\n\r",victim); } } void spell_treeform( 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 a tree.\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 = level / 6; af.location = 0; af.modifier = 0; af.bitvector = AFF_TREEFORM; affect_to_char( victim, &af ); af.where = TO_AFFECTS2; af.bitvector = AFF_BARRIER; af.modifier = -20 * (level / 12); af.location = APPLY_AC; affect_to_char(victim,&af); act( "Your body twists and forms into the shape of a tree.", ch, NULL, NULL, TO_CHAR); act( "A large oak tree forms, shuddering and twisting.", ch, NULL, NULL, TO_ROOM); } void spell_druid_gate( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { ROOM_INDEX_DATA *pRoomIndex; int e_r1[] = {ROOM_NO_TELEPORTIN, ROOM_NO_GATEIN}; int i_se[] = {SECT_FOREST}; int area_pool = 10; if (!IS_NPC(ch) && ch->pcdata->pStallion != NULL){ sendf(ch, "You cannot gate while on %s!\n\r",ch->pcdata->pStallion->short_descr); return; } if ( ch->in_room == NULL || ch->fighting || IS_SET(ch->in_room->room_flags, ROOM_NO_GATEOUT) || IS_SET(ch->in_room->room_flags, ROOM_NO_TELEPORTOUT) || IS_SET(ch->in_room->room_flags, ROOM_NO_INOUT) || ( ch != ch && IS_SET(ch->imm_flags,IMM_SUMMON)) || is_affected(ch, gsn_tele_lock) || ( !IS_NPC(ch) && ch->fighting != NULL )) { send_to_char("You failed to invoke a druid gate.\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; } pRoomIndex = get_rand_room(0,0, //area range (0 to ignore) 0,0, //room ramge (0 to ignore) NULL,0, //areas to choose from NULL,0, //areas to exclude i_se,1, //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 TRUE, //exit required? FALSE, //Safe? ch); //Character for room checks if (!pRoomIndex || IS_SET(pRoomIndex->area->area_flags, AREA_NOMORTAL) ){ send_to_char("You failed to invoke a druid gate.\n\r", ch); return; } send_to_char("You invoke a druid gate, and vanish!\n\r",ch); act( "$n invokes a druid gate, and vanishes!", ch, NULL, NULL, TO_ROOM ); char_from_room( ch ); char_to_room( ch, pRoomIndex ); act( "$n arrives from a druid gate.", ch, NULL, NULL, TO_ROOM ); do_look( ch, "auto" ); } void spell_mirror_image( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { CHAR_DATA *victim = (CHAR_DATA*) vo; CHAR_DATA* gch; AFFECT_DATA af; int tot_mi = 0; char long_buf[MIL], short_buf[MIL]; if (IS_NPC(victim)){ send_to_char("Why would you do that?.\n\r",ch); return; } if (is_affected(ch, sn) || is_affected(victim,gsn_doppelganger)){ send_to_char("You do not have enough power to create the mirror.\n\r",ch); return; } /* count current mirrors */ for (gch = char_list; gch != NULL; gch = gch->next){ if (IS_NPC(gch) && is_affected(gch,gsn_mirror_image)) { tot_mi++; } } /* check for max */ if (tot_mi >= level/10){ send_to_char("You cannot have any more mirrors.\n\r",ch); } sprintf(long_buf, "A mirror image stands here.\n\r"); sprintf(short_buf, "a mirror image"); /* create the image */ gch = create_mobile( get_mob_index(MOB_VNUM_DUMMY) ); /* copy strings */ free_string(gch->name); free_string(gch->short_descr); free_string(gch->long_descr); gch->name = str_dup(victim->name); gch->short_descr = str_dup(short_buf); gch->long_descr = str_dup(long_buf); /* set proper sex */ gch->sex = victim->sex; /* move to room */ char_to_room(gch,victim->in_room); /* set stats */ gch->max_hit = gch->hit = 1; gch->level = 1; gch->master = victim; if (ch == victim){ act("A mirror image of yourself appears beside you!",ch,NULL,NULL,TO_CHAR); act("A mirror image of $n appears beside $M!",ch,NULL,victim,TO_ROOM); } else{ act("A mirror of $N appears beside $M!",ch,NULL,victim,TO_CHAR); act("A mirror of $N appears beside $M!",ch,NULL,victim,TO_NOTVICT); act("A mirror image of yourself appears beside you!",ch,NULL,victim,TO_VICT); } /* set timer on the image and the user */ af.type = gsn_mirror_image; af.level = level; af.duration = -1; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(gch,&af); /* set wait time on user */ af.type = sn; af.duration = 5; affect_to_char(ch, &af); /* set timer so mirror expires */ af.type = gsn_timer; af.duration = 24; affect_to_char(gch,&af); } /* Songbird (group haste) Written By: Ath */ void spell_songbird( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { AFFECT_DATA af; CHAR_DATA *gch; /* send the song to the caster */ act("A songbird sings '`6A graceful sight not seen by all,``'",ch,NULL,NULL,TO_CHAR); act("A songbird sings '`6Who's feathers shine and liven us all,``'",ch,NULL,NULL,TO_CHAR); act("A songbird sings '`6With great swoops of tremendous haste,``'",ch,NULL,NULL,TO_CHAR); act("A songbird sings '`6Grant us your blessing with grace.``'",ch,NULL,NULL,TO_CHAR); /* send the song to everyone else in the room */ for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room ) { act("A songbird sings '`6A graceful sight not seen by all,``'",ch,NULL,gch,TO_VICT); act("A songbird sings '`6Who's feathers shine and liven us all,``'",ch,NULL,gch,TO_VICT); act("A songbird sings '`6With great swoops of tremendous haste,``'",ch,NULL,gch,TO_VICT); act("A songbird sings '`6Grant us your blessing with grace.``'",ch,NULL,gch,TO_VICT); } /* loop over everyone else in the room */ for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room ) { /* if the person is not in casters group, or is already hasted, ignore them */ if (!is_same_group (gch, ch) || IS_AFFECTED (gch, AFF_HASTE)) { continue; } /* if the person is not of caster's align, and caster is not imm, ignore them */ if (((IS_GOOD(ch) && IS_EVIL(gch)) || (IS_EVIL(ch) && IS_GOOD(gch))) && !IS_IMMORTAL(ch)) { continue; } /* if the person is FAST ignore them */ if (IS_SET(gch->off_flags,OFF_FAST)) { continue; } /* otherwise give them the (slightly weakened) haste affect */ af.where = TO_AFFECTS; af.type = skill_lookup ("haste"); af.level = level; if (gch == ch) af.duration = level/4; else af.duration = level/6; af.location = APPLY_DEX; af.modifier = 1 + (level >= 18) + (level >= 25) + (level >= 32); af.bitvector = AFF_HASTE; affect_to_char( gch, &af ); act_new( "You feel yourself moving more quickly.", gch,NULL,NULL,TO_CHAR,POS_DEAD); } } /* Written by: Virigoth * * Returns: void * * Used: magic.c, magic4.c * * Comment: A dispell magic like spell, except on failed save prevents * * any defensive spells (TAR_SELF, TAR_CHAR_DEFENSIVE) from casting. */ void spell_reveal_hidden( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ /* basicly this is an inverse "where" list showing only those that are not seen by character (camo/hidden/invis only) */ CHAR_DATA* victim; bool found = FALSE; AFFECT_DATA af; if (is_affected(ch, sn)){ send_to_char("You fail sensing its still too early for new attempt.\n\r", ch); return; } send_to_char("You scan your immediate area for anything unseen.\n\r", ch); for ( victim = player_list; victim != NULL; victim = victim->next_player ) if ( (!IS_NPC(victim) || is_affected(victim,gsn_doppelganger)) && !IS_IMMORTAL(victim) && victim->in_room != NULL && !IS_SET(victim->in_room->room_flags,ROOM_NOWHERE) && !room_is_private(victim->in_room) && victim->in_room->area == ch->in_room->area && (!IS_AFFECTED2(victim,AFF_SHADOWFORM) || IS_IMMORTAL(ch)) && !IS_AFFECTED2(victim,AFF_TREEFORM) && !is_affected(victim,gsn_bat_form) && !is_affected(victim,gsn_coffin) && !is_affected(victim,gsn_entomb) && !IS_AFFECTED2(victim,AFF_CATALEPSY) && !can_see( ch, victim ) && (IS_AFFECTED(victim, AFF_HIDE) || IS_AFFECTED(victim, AFF_INVISIBLE) || IS_AFFECTED2(victim, AFF_CAMOUFLAGE)) ) { found = TRUE; if (victim->invis_level < 1 || victim->incog_level < 1) sendf( ch, "%s%-28s %s\n\r", is_pk(ch,victim) ? "<`1PK``> " : " ", PERS2(victim), victim->in_room->name); } if ( !found ) send_to_char( "But find nothing..\n\r", ch ); if (IS_IMMORTAL(ch)) return; af.type = sn; af.duration = number_fuzzy(3); af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } /* Written by: Virigoth * * Returns: void * * Used: magic4.c * * Comment: Sets the resurrection gsn onto the owner of the corpse, the * * target char still needs to "accept" the resurection. */ void spell_resurrection( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ OBJ_DATA *obj = (OBJ_DATA *) vo; AFFECT_DATA af, *paf; CHAR_DATA *victim; 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->item_type != ITEM_CORPSE_PC){ send_to_char("That corpse has no trace of a soul in it.\n\r", ch); return; } if (obj->owner == 0 || obj->pIndexData->vnum == OBJ_VNUM_FAKE_CORPSE){ send_to_char("That corpse has no trace of a soul in it.\n\r", ch); return; } if (obj->condition < 2){ send_to_char("The remains are far too damaged to be resurrected.\n\r",ch); return; } /* check for paf from death */ if ( (paf = affect_find(obj->affected, gsn_resurrection)) == NULL || !paf->has_string){ send_to_char("You are too late, for the soul has departed already.\n\r", ch); return; } /* grab the owner of the corpse */ if ( (victim = get_char(paf->string)) == NULL){ sendf(ch, "%s's soul has departed the lands already.\n\r", paf->string); return; } if ( (IS_GOOD(victim) && IS_EVIL(ch)) || (IS_GOOD(ch) && IS_EVIL(victim)) ){ act("$N is too different from you.\n\r", ch, NULL, victim, TO_CHAR); return; } if (ch == victim){ act("Not even $g's power can allow you to resurrect yourself.", ch, NULL, NULL, TO_CHAR); return; } /* check for ghost */ if (!is_ghost(victim, 600)){ act("$N is no longer a ghost and not subject to resurrection.", ch, NULL, victim, TO_CHAR); act("You feel a gentle tug on your soul from $N's resurrection.", victim, NULL,ch, TO_CHAR); return; } /* check if not already resurrecting himself */ if (is_affected(victim, sn)){ send_to_char("That person has already been given the choice of new life.\n\r", ch); return; } /* messages */ act("You call onto $g to grant $N new life.", ch, NULL, victim, TO_CHAR); act("$n calls onto $g to grant $N a new life.", ch, NULL, victim, TO_ROOM); /* there is a cost */ af.type = gsn_drained; af.duration = 6; af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_STR; af.modifier = -3; affect_join(ch, &af); if (number_percent() > 2 * get_skill(ch, sn) / 3){ act("$n's prayers seem to fail.", ch, NULL, NULL, TO_ROOM); act("Your prayers fail to gain you attention.", ch, NULL, NULL, TO_CHAR); return; } /* all seems ok, set an affect to let the player accept */ af.type = sn; af.duration = 6; af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; paf = affect_to_char(victim, &af); string_to_affect(paf, ch->name); act("$n has called onto $g to grant you a chance for a new life.\n\r"\ "Use \"accept\" to accept the resurrection.", ch, NULL, victim, TO_VICT); } void resurrection_accept(CHAR_DATA* ch){ CHAR_DATA* och; OBJ_DATA* corpse = NULL; OBJ_DATA* obj, *next_obj; AFFECT_DATA* paf = NULL, af, *taf; char buf[MIL]; int exp; /* check if affected by resurrection */ if ( (paf = affect_find(ch->affected, gsn_resurrection)) == NULL){ send_to_char("You have not been given a chance to be brought back.\n\r", ch); return; } if (paf->has_string) och = get_char(paf->string); else och = NULL; if (!is_ghost(ch, 600)){ send_to_char("You are no longer a ghost\n\r", ch); affect_strip(ch, gsn_resurrection); return; } /* locate the corpse */ for ( obj = object_list; obj != NULL; obj = next_obj ){ next_obj = obj->next; if (obj->item_type != ITEM_CORPSE_PC) continue; if (!obj->in_room) continue; if ( (taf = affect_find(obj->affected, gsn_resurrection)) == NULL || !taf->has_string) continue; if (str_cmp(taf->string, ch->name)) continue; //get the first corpse, preferably at caster's feet if (corpse == NULL && (och == NULL || obj->in_room == och->in_room)){ corpse = obj; paf = taf; } else{ affect_strip_obj( obj, gsn_resurrection ); } } if (!corpse || !paf){ send_to_char("Your remains are no longer avaliable for resurrection.\n\r", ch); affect_strip(ch, gsn_resurrection); return; } /* move char to corpse */ if (IS_SET(ch->in_room->room_flags, ROOM_NO_INOUT)){ send_to_char("The nature of your immediate area prevents the your resurrection.\n\r", ch); return; } /* move objects over */ for (obj = corpse->contains; obj != NULL; obj = next_obj){ next_obj = obj->next_content; obj_from_obj(obj); obj_to_ch(obj, ch); } sprintf(buf, "Accepted resurrection into room %d.", corpse->in_room->vnum); log_event(ch, buf); /* grant the death back only if exp was lost (NPC KILL) */ if (paf->modifier > 0) ch->pcdata->dall = UMAX(0, ch->pcdata->dall - 1); /* check con loss */ if (paf->level && ch->perm_stat[STAT_CON] < get_max_train(ch, STAT_CON)){ send_to_char("You feel healthier.\n\r", ch); ch->perm_stat[STAT_CON]++; } /* give back exp */ exp = UMIN(paf->modifier * paf->duration / paf->bitvector, paf->modifier); gain_exp( ch, exp ); /* move the char */ char_from_room(ch); char_to_room(ch, corpse->in_room); /* Few messages now */ act("Suddenly color and life returns to $p and $e arises from death!", ch, corpse, NULL, TO_ROOM); act("Your vision blurs and you feel yourself being pulled rapidly.\n\r"\ "With great effort your body heaves as your heart begins to beat once again!\n\r", ch, NULL, NULL, TO_CHAR); /* heal char. */ ch->hit = UMAX(ch->hit, 3 * ch->max_hit / 4); ch->move = UMAX(ch->move, 3 * ch->max_move / 4); /* set calm */ af.where = TO_AFFECTS; af.type = skill_lookup("calm"); af.level = ch->level; af.duration = 24; af.location = APPLY_HITROLL; af.modifier = -10; af.bitvector = AFF_CALM; if (!is_affected(ch, af.type)){ affect_to_char(ch,&af); af.location = APPLY_DAMROLL; affect_to_char(ch,&af); } /* set ghost to run out */ ch->pcdata->ghost = (time_t)(mud_data.current_time - 520); send_to_char("You begin to quickly lose your ghost form.\n\r", ch); /* destroy the corpse */ extract_obj(corpse); affect_strip(ch, gsn_resurrection); do_look(ch, "auto"); /* we reward original caster stored in the paf */ if (och == NULL) return; else{ AFFECT_DATA af, *paf; int gain = number_range(1000, 5000); act("You feel $g's blessing fill your soul as $N is resurrected!", och, NULL, ch, TO_CHAR); if (!is_affected(och, gsn_timer)){ AFFECT_DATA af; af.type = gsn_timer; af.level = 60; af.duration = 240; af.where = TO_NONE; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; /* Viri: Hopefully we will not need this but for now its in */ affect_to_char(och, &af); if (och->level < 50){ sendf(och, "You gain %d experience!\n\r", gain); gain_exp(och, gain); } gain = number_range(20, 75); CP_GAIN(och, gain, TRUE); } if ( (paf = affect_find(och->affected, gsn_mystic_healing)) != NULL && paf->modifier >= 50) return; if (!paf){ af.type = gsn_mystic_healing; af.level = 50; af.duration = -1; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_MOVE_GAIN; af.modifier = 10; affect_to_char(och, &af); af.location = APPLY_HIT_GAIN; affect_to_char(och, &af); af.location = APPLY_MANA_GAIN; affect_to_char(och, &af); } else{ for (paf = och->affected; paf; paf = paf->next){ if (paf->type == gsn_mystic_healing){ paf->modifier += 10; } } } } } /* accepts various things like resurrection */ void do_accept(CHAR_DATA *ch, char *argument){ if (is_affected(ch, gsn_resurrection)){ if (ch->pCabal && IS_CABAL(ch->pCabal, CABAL_NOMAGIC)){ send_to_char("You are not allowed to use magic!\n\r", ch); return; } resurrection_accept(ch); return; } } // life-insurance: For healer mobs, secores all items on death // Coded by: Athaekeetha // // This is just a stub function that is never called. void spell_life_insurance( int sn, int level, CHAR_DATA *ch, void *vo,int target ) { } /* Written by: Virigoth * * Returns: void * * Used: magic4.c * * Comment: A spell that creates a virtual attacked based on casters mana. */ void spell_light_sword( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ CHAR_DATA* victim = (CHAR_DATA*) vo; //data int thac0 = 0; int ac = 0; int dam = 0; int dam_type = DAM_ENERGY; int dt = attack_lookup("slice") + TYPE_HIT; int d1 = 0; int d2 = 0; int h_roll = 0 ; int d_roll = 0 ; int diceroll = 0; if (ch->mana < 300){ act("The light sword sputters and goes out.", ch, NULL, NULL, TO_CHAR); act("The light sword sputters and goes out.", ch, NULL, victim, TO_VICT); return; } // the hit/dam h_roll = URANGE(0, (ch->mana - 300) / 40, 25); d_roll = URANGE(0, (ch->mana - 300) / 20, 50); d1 = URANGE(0, (ch->mana - 200) / 100, 8); d2 = URANGE(0, (ch->mana - 200) / 100, 7); //add dice roll for damage dam = d_roll + dice(d1, d2); dam = UMIN(125, dam); //get thaco and AC thac0 = get_THAC0(ch, victim, NULL, dt, FALSE, IS_NPC(ch), ACT_WARRIOR, TRUE, gsn_ancient_lore, level); ac = get_AC(ch, victim, dt, dam_type, TRUE); //We roll for miss while ( ( diceroll = number_bits( 5 ) ) >= 20 ); if ( diceroll == 0 || ( diceroll != 19 && diceroll < thac0 - ac ) ) dam = 0; //and we make an attack. // sendf(ch, "d_roll: %d, dam: %d, h_roll: %d\n\r", d_roll, dam, h_roll); if (ch->fighting != NULL && victim->hit > 0 && victim->position > POS_STUNNED && victim->in_room == ch->in_room && !is_safe_quiet(ch, victim)) virtual_damage(ch, victim, NULL, dam, dt, dam_type, h_roll, level, TRUE, TRUE, gsn_ancient_lore); check_improve(ch, gsn_ancient_lore, TRUE, 1); } /* used in spell_psi_blast to influence the chance to do some type of damage */ void spell_psi_control( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ int i = 0; bool fFound = FALSE; // CHAR_DATA* victim = (CHAR_DATA*) vo; AFFECT_DATA af; static char * const type [] = { "water", "cold", "fire", "shock", "light", "energy" }; if (is_affected(ch, sn)){ send_to_char("You are already exerting control over your constructs.\n\r", ch); return; } if (IS_NULLSTR(target_name)){ send_to_char("syntax: psionic control <element>\n\r"\ "Following are valid choices for element.\n\r", ch); for (i = 0; i < 6; i ++){ sendf(ch, "%s\n\r", type[i]); } return; } /* check for valid choice */ for (i = 0; i < 6; i ++){ if (!str_prefix(target_name, type[i])){ fFound = TRUE; break; } } if (!fFound){ send_to_char("syntax: psionic control <element>\n\r"\ "Following are valid choices for element.\n\r", ch); for (i = 0; i < 6; i ++){ sendf(ch, "%s\n\r", type[i]); } return; } /* the way this works is we store the position of attack type that we selected by taking the value of i and adding attack positon of "hydrokinesis" */ sendf(ch, "Your psionic blast will now tend towards element of %s.\n\r", type[i]); i += attack_lookup("hydrokinesis"); af.type = sn; af.level = level; af.duration = 12; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = i; affect_to_char(ch, &af); } void spell_unholy_gift( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ CHAR_DATA* victim = (CHAR_DATA*) vo; AFFECT_DATA af; /* This is a spell that used unlife effect for two purposes 1) Tatto ability for tattoo of namless to give a person ability to appear as undead (No vuln to holy, 12h duration) 2) Elder Vamp ability (Vuln to holy, 480 duration) */ if (IS_UNDEAD(victim) || is_affected(victim, gen_unlife)) return; af.where = TO_RESIST; af.type = gen_unlife; af.level= ch->level; af.duration = ch == victim ? 12 : 240; af.location = APPLY_NONE; /* Normal processing in gen but no sleep*/ af.modifier = ch == victim ? 1 : 0; af.bitvector = RES_COLD | RES_POISON | RES_DISEASE; affect_to_char( victim, &af ); if (victim != ch){ af.where = TO_VULN; /* ignored in gen */ af.modifier = -1; af.bitvector = VULN_HOLY; affect_to_char( victim, &af ); } } void spell_drug_use( int sn, int level, CHAR_DATA *ch, void *vo,int target){ CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af, *paf; int chance, dur = 720; if ( (paf = affect_find(ch->affected, gen_addiction)) != NULL && paf->modifier != 0){ send_to_char("Your withdrawal pains subside.\n\r",victim); paf->modifier = 0; return; } chance = 80 + (get_curr_stat(ch, STAT_CON) - 15); if (number_percent() < chance || paf != NULL) return; act_new("You have become addicted to drugs!",ch,NULL,victim,TO_CHARVICT, POS_DEAD ); act("$n begins to shudder and shake as $e is overcome with addiction.",victim,NULL,NULL,TO_ROOM ); send_to_char("You begin to shudder and shake from your addiction!\n\r",victim); af.where = TO_AFFECTS; af.type = gen_addiction; af.level = level; af.duration = dur; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = -1; affect_to_char(ch, &af); } void spell_death_cube( int sn, int level, CHAR_DATA *ch, void *vo,int target){ OBJ_DATA* cube = (OBJ_DATA*) vo; OBJ_DATA* obj, *obj_next; /* all we do here is check for multiple death cubes */ for (obj = ch->carrying; obj != NULL; obj = obj_next){ obj_next = obj->next_content; if (obj != cube && obj->pIndexData->vnum == cube->pIndexData->vnum){ act("$p crumbles to dust.", ch, obj, NULL, TO_ALL); extract_obj(obj); } } /* check if cube has 5 cost */ if (cube->cost < 5) return; /* send a note about it */ { BUFFER *buffer; NOTE_DATA *note; char buf[MIL]; char arg[MIL]; char* sender = "`!HAL 1000``"; char* namelist, *strtime; buffer = new_buf(); sprintf(buf,"`!Following generated at %s.``\n\r",((char *) ctime( &mud_data.current_time ))); add_buf(buffer,buf); sprintf(buf, "%s's %s has achived charge of %d, and has been extracted.", ch->name, cube->short_descr, cube->cost); add_buf(buffer, buf); namelist = str_dup("immortal"); for (;;) { namelist = one_argument(namelist,arg); if (arg[0] == '\0') break; note = new_note(); note->prefix = 0; note->next = NULL; note->type = NOTE_NOTE; free_string(note->sender); note->sender = str_dup( sender ); free_string(note->subject); note->subject = str_dup("RP Quest Update (Soul Cube)"); free_string(note->text); note->text = str_dup(buf_string(buffer)); strtime = ctime( &mud_data.current_time ); strtime[strlen(strtime)-1] = '\0'; note->date = str_dup( strtime ); note->date_stamp = mud_data.current_time; free_string(note->to_list); note->to_list = str_dup(arg); append_note(note); } free_buf(buffer); } act("$p rises into the air and with a flash of dark light.. Disappears!.", ch, cube, NULL, TO_ALL); extract_obj(cube); } void spell_doomsday(int sn, int level, CHAR_DATA *ch, void *vo,int target) { if (strcmp(ch->name, "Crypticant")) { act("`!You attempt to harness the dark forces around the Doomsday Cube, but to no avail!``", ch, NULL, NULL, TO_CHAR); act("`!$n attempts to harness the dark forces around the Doomsday Cube, but fails!``", ch, NULL, NULL, TO_ROOM); vo = ch; } if (vo != NULL) { act("`8The Doomsday Cube drains another soul!", ch , NULL, vo, TO_CHAR); act("`8You feel your soul pulled from your body...``", ch , NULL, vo, TO_VICT); act("`8$N's body collapses in the throes of death, as $s soul is drawn into the cube!\n\r``", ch, NULL, vo, TO_NOTVICT); act("`8The world blackens as your mortal body dies...``", ch, NULL, vo, TO_VICT); raw_kill(ch, vo); } } void spell_fired_projectile( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { OBJ_DATA *obj = (OBJ_DATA *) vo; CHAR_DATA *victim; int dam; int weight = get_obj_weight(obj); if ((victim = ch->fighting) == NULL) { send_to_char("You are not in combat.\n\r", ch); return; } if (!CAN_WEAR(obj, ITEM_TAKE) || CAN_WEAR(obj, ITEM_NO_SAC) || obj->item_type == ITEM_CABAL || is_affected_obj(obj, gsn_gravitate) || weight > 1000 ) { send_to_char("You cannot lift that object.\n\r", ch); return; } dam = dice(level / 5, 8); dam += UMIN(weight, 500) / 3; if ( saves_spell( level, victim,DAM_PIERCE,skill_table[sn].spell_type) ) dam /= 2; act( "You fire $p straight at $N!", ch, obj, victim, TO_CHAR); act( "$n fires a $p straight at you!", ch, obj, victim, TO_VICT ); act( "$n fires a $p straight at $N!", ch, obj, victim, TO_NOTVICT ); damage( ch, victim, dam, sn, DAM_PIERCE ,TRUE); /* move the object from where it is to the ground */ if (!ch->in_room) return; if (obj->carried_by) obj_from_char(obj); else if (obj->in_obj) obj_from_obj(obj); else if (obj->in_room) obj_from_room(obj); obj_to_ch(obj, victim); } /* PSALMS */ void spell_righteous( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)) return ; af.type = sn; af.level = level; af.duration = 96; af.where = TO_AFFECTS; af.bitvector = 0; af.modifier = number_fuzzy(level / 7); af.location = APPLY_HITROLL; affect_to_char(ch,&af); af.location = APPLY_DAMROLL; affect_to_char(ch,&af); } void spell_dvoid( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, gen_dvoid)) return; af.type = gen_dvoid; af.level = level; af.duration = 120; af.where = TO_AFFECTS; af.bitvector = 0; af.modifier = -2; af.location = APPLY_SAVING_SPELL; affect_to_char(ch,&af); } void spell_insight( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, gen_dvoid)) return; af.type = sn; af.level = level; af.duration = 300; af.where = TO_AFFECTS; af.bitvector = AFF_DETECT_INVIS | AFF_DETECT_EVIL | AFF_DETECT_GOOD; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch,&af); } void spell_dwrath( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ OBJ_DATA *obj = get_eq_char(ch, WEAR_WIELD); AFFECT_DATA af; if (obj == NULL) return; if (is_affected_obj(obj, sn)) return; af.type = sn; af.level = level; af.duration = 24; af.where = TO_WEAPON; af.bitvector = 0; af.modifier = attack_lookup("divine"); af.location = APPLY_O_DTYPE; affect_to_obj(obj, &af); af.type = sn; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_sbane( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ OBJ_DATA *obj = get_eq_char(ch, WEAR_WIELD); AFFECT_DATA af; if (obj == NULL) return; if (is_affected_obj(obj, sn)) return; af.type = sn; af.level = level; af.duration = 24; af.where = TO_WEAPON; af.bitvector = 0; af.modifier = attack_lookup("rays"); af.location = APPLY_O_DTYPE; affect_to_obj(obj, &af); af.type = sn; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_pwater( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ OBJ_DATA *obj = get_eq_char(ch, WEAR_WIELD); AFFECT_DATA af; if (obj == NULL) return; if (is_affected_obj(obj, sn)) return; af.type = sn; af.level = level; af.duration = 24; af.where = TO_WEAPON; af.bitvector = 0; af.modifier = attack_lookup("spray"); af.location = APPLY_O_DTYPE; affect_to_obj(obj, &af); af.type = sn; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_icefire( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ OBJ_DATA *obj = get_eq_char(ch, WEAR_WIELD); AFFECT_DATA af; if (obj == NULL) return; if (is_affected_obj(obj, sn)) return; af.type = sn; af.level = level; af.duration = 24; af.where = TO_WEAPON; af.bitvector = 0; af.modifier = attack_lookup("icefire"); af.location = APPLY_O_DTYPE; affect_to_obj(obj, &af); af.type = sn; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_smight( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ OBJ_DATA *obj = get_eq_char(ch, WEAR_WIELD); AFFECT_DATA af; if (obj == NULL) return; if (is_affected_obj(obj, sn)) return; af.type = sn; af.level = level; af.duration = 24; af.where = TO_WEAPON; af.bitvector = WEAPON_FLAMING; af.modifier = attack_lookup("flame"); af.location = APPLY_O_DTYPE; affect_to_obj(obj, &af); af.type = sn; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_dmight( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ OBJ_DATA *obj = get_eq_char(ch, WEAR_WIELD); AFFECT_DATA af; if (obj == NULL) return; if (is_affected_obj(obj, sn)) return; af.type = sn; af.level = level; af.duration = 24; af.where = TO_WEAPON; af.bitvector = WEAPON_PARALYZE; af.modifier = attack_lookup("shbite"); af.location = APPLY_O_DTYPE; affect_to_obj(obj, &af); af.type = sn; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_vitality( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)) return; af.type = sn; af.level = level; af.duration = 300; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_HIT; af.modifier = level; affect_to_char(ch, &af); af.location = APPLY_HIT_GAIN; af.modifier = 30; affect_to_char(ch, &af); } void spell_sretrib( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)) return; af.type = sn; af.level = level; af.duration = 48; af.where = TO_AFFECTS; af.bitvector = 0; af.modifier = 30; af.location = APPLY_MOVE_GAIN; affect_to_char(ch,&af); } void spell_virtues( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)) return; af.type = sn; af.level = level; af.duration = -1; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 1; affect_to_char(ch, &af); } void spell_preserve( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)) return; af.type = sn; af.level = level; af.duration = 46; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_fpart( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)) return; af.type = sn; af.level = level; af.duration = 48; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_vredem( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)) return; af.type = sn; af.level = level; af.duration = 240; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_ogtrium( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)) return; af.type = sn; af.level = level; af.duration = 240; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_strium( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)) return; af.type = sn; af.level = level; af.duration = 240; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); af.type = gen_strium; af.where = TO_NONE; affect_to_char(ch, &af); } void spell_ptrium( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)) return; af.type = sn; af.level = level; af.duration = 240; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); send_to_char("A feeling of divine purity fills your flesh.\n\r", ch); } void spell_uorder( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; bool fMsg = FALSE; int gsn_behead = skill_lookup("behead"); if (is_affected(ch, sn)) return; send_to_char("A high official of the Order of Crusades walks up to you.\n\r", ch); send_to_char("The official says '`#Know that as long as you remain true to our Holy Mission``\n\r", ch); send_to_char("The official says '`#the Order will overlook the rare adornments you place upon yourself.``\n\r", ch); af.type = sn; af.level = level; af.duration = -1; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); /* check for skill boost */ if (get_skill(ch, gsn_crusade) < 100){ int sn = gsn_crusade; SKILL_DATA* nsk; if ( (nsk = nskill_find(ch->pcdata->newskills,sn)) != NULL){ nsk->learned = 100; } else ch->pcdata->learned[sn] = 100; fMsg = TRUE; } if (get_skill(ch, gsn_avenger) < 100){ int sn = gsn_avenger; SKILL_DATA* nsk; if ( (nsk = nskill_find(ch->pcdata->newskills,sn)) != NULL){ nsk->learned = 100; } else ch->pcdata->learned[sn] = 100; fMsg = TRUE; } if (get_skill(ch, gsn_behead) < 100){ int sn = gsn_behead; SKILL_DATA* nsk; if ( (nsk = nskill_find(ch->pcdata->newskills,sn)) != NULL){ nsk->learned = 100; fMsg = TRUE; } } if (fMsg) send_to_char("Your soul soars and you are enlighted in the ways of the Order of Crusades!", ch); } void spell_istrength( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)) return; af.type = sn; af.level = level; af.duration = 240; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_STR; af.modifier = 25; affect_to_char(ch, &af); } void spell_dheal( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)) return; if (!ch->fighting){ send_to_char("You feel your body quickly regenerate itsself.\n\r", ch); ch->hit = ch->max_hit; update_pos(ch); } else send_to_char("Your concentration is disturbed.\n\r", ch); af.type = sn; af.level = level; af.duration = 4; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_HIT_GAIN; af.modifier = 200; affect_to_char(ch, &af); } void spell_purity( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af, *paf; if ( (paf = affect_find(ch->affected, gen_ward)) != NULL && paf->has_string && !IS_NULLSTR(paf->string) && !str_cmp(paf->string, skill_table[gsn_poison].name)) return; af.type = gen_ward; af.level = level; af.duration = 96; af.where = TO_NONE; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; paf = affect_to_char(ch,&af); string_to_affect(paf, skill_table[gsn_poison].name); af.type = sn; af.where = TO_AFFECTS; paf = affect_to_char(ch,&af); } void spell_const( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af, *paf; if ( (paf = affect_find(ch->affected, gen_ward)) != NULL && paf->has_string && !IS_NULLSTR(paf->string) && !str_cmp(paf->string, skill_table[gsn_plague].name)) return; af.type = gen_ward; af.level = level; af.duration = 96; af.where = TO_NONE; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; paf = affect_to_char(ch,&af); string_to_affect(paf, skill_table[gsn_plague].name); af.type = sn; af.where = TO_AFFECTS; paf = affect_to_char(ch,&af); } void spell_epal( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af, *paf; if ( (paf = affect_find(ch->affected, gen_ward)) != NULL && paf->has_string && !IS_NULLSTR(paf->string) && !str_cmp(paf->string, skill_table[gsn_blindness].name)) return; af.type = gen_ward; af.level = level; af.duration = 96; af.where = TO_NONE; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; paf = affect_to_char(ch,&af); string_to_affect(paf, skill_table[gsn_blindness].name); af.type = sn; af.where = TO_AFFECTS; paf = affect_to_char(ch,&af); } void spell_baptize( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; int i = 0; if (is_affected(ch, sn)) return; send_to_char("As you complete the psalm your memories begin to grow cloudy.\n\r", ch); act("$n's eyes cloud over and $e gets a dreamy look on $s face.", ch, NULL, NULL, TO_ROOM); send_to_char("You've lost knowledge of all your Psalms!\n\r", ch); if (IS_NPC(ch)) return; /* lower max psalm by one */ if (get_skill(ch, skill_lookup("psalm master")) < 1) ch->pcdata->psalm_pen += 1; /* wipe all the psalms clean */ for (i = 0; i < MAX_PSALM; i ++){ ch->pcdata->psalms[i] = 0; } af.type = sn; af.level = level; af.duration = 10; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_INT; af.modifier = -10; affect_to_char(ch, &af); } void spell_icalm( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)) return; send_to_char("As you complete the psalm a wave of holiness washes over you.\n\r", ch); act("$n's face beams with inner light for a moment then fades.", ch, NULL, NULL, TO_ROOM); if (IS_NPC(ch)) return; /* raise holy weapon by 2 */ hwep_gain(ch, ch, 0 ); af.type = sn; af.level = level; af.duration = 10; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } void spell_webcaster( 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_OTHER, skill_table[sn].spell_type) ){ act("A sticky web falls on $n but $e breaks free.", victim, NULL, NULL, TO_ROOM); act("A sticky web falls on you but you manage to break free.", victim, NULL, NULL, TO_CHAR); WAIT_STATE2(victim, skill_table[sn].beats / 2); return; } act("A sticky web falls on $n enveloping $m tightly.", victim, NULL, NULL, TO_ROOM); act("A sticky web falls on you enveloping you tightly.", victim, NULL, NULL, TO_CHAR); if (!IS_NPC(victim) && victim->pcdata->pStallion ){ do_dismount(victim, ""); } WAIT_STATE2(victim, skill_table[sn].beats ); if (is_affected(victim, gsn_thrash)) return; af.type = gsn_thrash; af.level = ch->level; af.duration = 1; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_DEX; af.modifier = -2; affect_to_char(victim,&af); if (IS_AFFECTED(victim, AFF_FLYING)){ act("You can't seem to get back into the air",victim,NULL,NULL,TO_CHAR); act("$n can't seem to get back into the air",victim,NULL,NULL,TO_ROOM); } } void spell_bind_spirit(int sn,int level,CHAR_DATA *ch, void *vo,int target){ AFFECT_DATA af; OBJ_DATA *obj = (OBJ_DATA *) vo; CHAR_DATA* victim = NULL; bool found = FALSE; if ( is_affected( ch, gen_spirit ) ){ send_to_char("You've already bound a spirit to yourself.\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 || is_affected_obj(obj, sn )){ 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 (victim == NULL){ send_to_char("The spirits have already departed that corpse.\n\r", ch ); return; } else{ af.type = gen_spirit; af.level = victim->level + 10; af.duration = 1 + number_fuzzy(ch->level / 5); af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_HIT_GAIN; af.modifier = -25; affect_to_char( ch, &af ); af.location = APPLY_MANA_GAIN; af.modifier = -25; affect_to_char( ch, &af ); act ("You bind the spirit of $N to your will!", ch, NULL, victim, TO_CHAR); act ("$n binds the spirit of $N to his will!", ch, NULL, victim, TO_ROOM); if (IS_NPC(victim)) extract_char(victim,TRUE); af.duration = -1; af.location = 0; af.modifier = 0; af.type = sn; affect_to_obj( obj, &af ); } } void spell_stallion( int sn, int level, CHAR_DATA *ch, void *vo, int target ) { AFFECT_DATA af; CHAR_DATA *mob; if ( is_affected( ch, gsn_mounted ) ){ send_to_char("You already have a mount.\n\r",ch); return; } if (IS_SET(ch->in_room->room_flags,ROOM_INDOORS)) { send_to_char("You cannot call onto the Goliath indoors!\n\r",ch); return; } mob = create_mobile( get_mob_index(MOB_VNUM_STALLION) ); act("The ground shaking under its hoofs $N comes to your side!", ch,NULL,mob, TO_CHAR); act("The ground shaking under its hoofs, a giant warhorse comes to $n's side!", ch,NULL, mob, TO_ROOM); af.type = gsn_mounted; af.level = level; af.duration = 24; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = mob->pIndexData->vnum; affect_to_char( ch, &af ); } bool defuse_traps(CHAR_DATA* ch, TRAP_DATA* ptrap){ bool fFound = FALSE; //run through traps and disable them. for (;ptrap; ptrap = ptrap->next_trap){ act("You defuse $t.", ch, ptrap->name, NULL, TO_CHAR); act("$n defuses $t.", ch, ptrap->name, NULL, TO_ROOM); ptrap->armed = FALSE; fFound = TRUE; /* make sure to take care of delay traps here */ REMOVE_BIT(ptrap->flags, TRAP_DELAY); /* owned traps get removed */ if (ptrap->owner){ if (ptrap->owner != ch && IS_TRAP(ptrap, TRAP_NOTIFY)) sendf(ptrap->owner, "You sense %s has defused %s.\n\r", PERS2(ch), ptrap->name); else if (ch != ptrap->owner) sendf(ptrap->owner, "You sense %s has been defused.\n\r", ptrap->name); extract_trap( ptrap ); } }//end for traps return fFound; } void spell_defusion( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ OBJ_DATA* obj; TRAP_DATA* ptrap; EXIT_DATA* pexit; int door = 0; bool fFound = FALSE; //check room traps first for (door = 0; door < MAX_DOOR; door++){ if ( (pexit = ch->in_room->exit[door]) == NULL) continue; else if ( (ptrap = pexit->traps) == NULL) continue; else fFound |= defuse_traps( ch, ptrap ); }//end for room exists for (obj = ch->in_room->contents; obj; obj = obj->next_content){ if ( (ptrap = obj->traps) == NULL) continue; else fFound |= defuse_traps( ch, ptrap); } if (!fFound){ send_to_char("There aren't any traps here.\n\r", ch); } } void spell_steel_wall( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, gsn_mimic)){ send_to_char("You must first get rid of the reflective shield protecting you.\n\r", ch); return; } if (is_affected(ch,sn)){ send_to_char("You are already protected by the wall of steel.\n\r", ch); return; } if (IS_AFFECTED2(ch, AFF_FIRE_SHIELD)){ send_to_char("The magical flames around you seem to interfere!\n\r", ch); return; } af.type = sn; af.level = level; af.duration = number_fuzzy(level/8); af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_AC; af.modifier = -1 * (level + level / number_fuzzy( 3 )); affect_to_char(ch,&af); send_to_char("You summon mass of steel shards to whirl around you.\n\r",ch); act("A mass of whirling steel shards forms a deadly wall around $n.", ch, NULL, NULL, TO_ROOM); } /* BLADEMASTER SPELLS */ void spell_deathweaver( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)){ send_to_char("You're already in this stance.\n\r", ch); return; } else if (is_affected(ch, gsn_deathweaver) || is_affected(ch, gsn_doomsinger) || is_affected(ch, gsn_shadowdancer) || is_affected(ch, gsn_puppet_master) || is_affected(ch, gsn_bladestorm) || is_affected(ch, gsn_ironarm) || is_affected(ch, gsn_iron_curtain)){ send_to_char("You may enter only a single stance at a time.\n\r", ch); return; } send_to_char("You clear your mind and focus on the secrets of Deathweaver.\n\r", ch); act("$n meditates briefly and looks far more stable and sure of $s footing.", ch, NULL, NULL, TO_ROOM); af.type = sn; af.duration = 12; af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char( ch, &af); } void spell_bladestorm( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)){ send_to_char("You're already in this stance.\n\r", ch); return; } else if (is_affected(ch, gsn_deathweaver) || is_affected(ch, gsn_doomsinger) || is_affected(ch, gsn_shadowdancer) || is_affected(ch, gsn_puppet_master) || is_affected(ch, gsn_bladestorm) || is_affected(ch, gsn_ironarm) || is_affected(ch, gsn_iron_curtain)){ send_to_char("You may enter only a single stance at a time.\n\r", ch); return; } else if ( get_eq_char(ch, WEAR_SECONDARY) == NULL){ send_to_char("You must use two weapons with this stance.\n\r", ch); return; } send_to_char("You clear your mind and focus on the secrets of Bladestorm.\n\r", ch); act("$n meditates briefly and begins to move much faster.", ch, NULL, NULL, TO_ROOM); af.type = sn; af.duration = 12; af.level = level; af.where = TO_AFFECTS; af.bitvector = AFF_HASTE; af.location = APPLY_AC; af.modifier = 25 + number_fuzzy(level); affect_to_char( ch, &af); } void spell_ironarm( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)){ send_to_char("You're already in this stance.\n\r", ch); return; } else if (is_affected(ch, gsn_deathweaver) || is_affected(ch, gsn_doomsinger) || is_affected(ch, gsn_shadowdancer) || is_affected(ch, gsn_puppet_master) || is_affected(ch, gsn_bladestorm) || is_affected(ch, gsn_ironarm) || is_affected(ch, gsn_iron_curtain)){ send_to_char("You may enter only a single stance at a time.\n\r", ch); return; } else if ( get_eq_char(ch, WEAR_SECONDARY) == NULL){ send_to_char("You must use two weapons with this stance.\n\r", ch); return; } send_to_char("You clear your mind and focus on the secrets of Ironarm.\n\r", ch); act("$n meditates briefly then steps into a fighting stance.", ch, NULL, NULL, TO_ROOM); af.type = sn; af.duration = 12; af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_DAMROLL; af.modifier = number_fuzzy(level / 10); affect_to_char( ch, &af); } void spell_iron_curtain( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)){ send_to_char("You're already in this stance.\n\r", ch); return; } else if (is_affected(ch, gsn_deathweaver) || is_affected(ch, gsn_doomsinger) || is_affected(ch, gsn_shadowdancer) || is_affected(ch, gsn_puppet_master) || is_affected(ch, gsn_bladestorm) || is_affected(ch, gsn_ironarm) || is_affected(ch, gsn_iron_curtain)){ send_to_char("You may enter only a single stance at a time.\n\r", ch); return; } else if ( get_eq_char(ch, WEAR_SECONDARY) == NULL){ send_to_char("You must use two weapons with this stance.\n\r", ch); return; } send_to_char("You clear your mind and focus on the secrets of Kyousanken.\n\r", ch); act("$n meditates briefly then moves $s weapons to cover $mself.", ch, NULL, NULL, TO_ROOM); af.type = sn; af.duration = 12; af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_HIT; af.modifier = level; affect_to_char( ch, &af); } void spell_doomsinger( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)){ send_to_char("You're already in this stance.\n\r", ch); return; } else if (is_affected(ch, gsn_deathweaver) || is_affected(ch, gsn_doomsinger) || is_affected(ch, gsn_shadowdancer) || is_affected(ch, gsn_puppet_master) || is_affected(ch, gsn_bladestorm) || is_affected(ch, gsn_ironarm) || is_affected(ch, gsn_iron_curtain)){ send_to_char("You may enter only a single stance at a time.\n\r", ch); return; } else if ( has_twohanded(ch) == NULL){ send_to_char("You must use a two handed weapon with this stance.\n\r", ch); return; } send_to_char("You clear your mind and focus on the secrets of Doomsinger.\n\r", ch); act("$n meditates briefly then swings $s weapon which emits a strange tone.", ch, NULL, NULL, TO_ROOM); af.type = sn; af.duration = 12; af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_HITROLL; af.modifier = number_fuzzy(level / 10); affect_to_char( ch, &af); } void spell_shadowdancer( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)){ send_to_char("You're already in this stance.\n\r", ch); return; } else if (is_affected(ch, gsn_deathweaver) || is_affected(ch, gsn_doomsinger) || is_affected(ch, gsn_shadowdancer) || is_affected(ch, gsn_puppet_master) || is_affected(ch, gsn_bladestorm) || is_affected(ch, gsn_ironarm) || is_affected(ch, gsn_iron_curtain)){ send_to_char("You may enter only a single stance at a time.\n\r", ch); return; } else if ( has_twohanded(ch) == NULL){ send_to_char("You must use a two handed weapon with this stance.\n\r", ch); return; } send_to_char("You clear your mind and focus on the secrets of Shadowdancer.\n\r", ch); act("$n meditates briefly and begins to move in a strange alien way.", ch, NULL, NULL, TO_ROOM); af.type = sn; af.duration = 12; af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_AC; af.modifier = -level; affect_to_char( ch, &af); } void spell_puppet_master( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; OBJ_DATA* obj; int wep; if (is_affected(ch, sn)){ send_to_char("You're already in this stance.\n\r", ch); return; } else if (is_affected(ch, gsn_deathweaver) || is_affected(ch, gsn_doomsinger) || is_affected(ch, gsn_shadowdancer) || is_affected(ch, gsn_puppet_master) || is_affected(ch, gsn_bladestorm) || is_affected(ch, gsn_ironarm) || is_affected(ch, gsn_iron_curtain)){ send_to_char("You may enter only a single stance at a time.\n\r", ch); return; } else if (IS_NULLSTR(target_name)){ send_to_char("Imitate which weapon type?\n\r", ch); return; } else if ( (wep = weapon_lookup( target_name)) < 0){ send_to_char("No such weapon type.\n\r", ch); return; } else if ( (obj = has_twohanded(ch)) == NULL){ send_to_char("You must use a two handed weapon with this stance.\n\r", ch); return; } send_to_char("You clear your mind and focus on the secrets of Kairishi.\n\r", ch); act("$n meditates briefly then changes $s hold on $s weapon.", ch, NULL, NULL, TO_ROOM); af.type = sn; af.duration = 12; af.level = level; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = wep; affect_to_obj( obj, &af); af.location = APPLY_HITROLL; af.modifier = number_fuzzy(level / 7); affect_to_char( ch, &af); } //blademaster blood vow for their weapon void spell_blood_vow( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ OBJ_DATA* obj = (OBJ_DATA*) vo; AFFECT_DATA af; const int dur = 120; if (obj->item_type != ITEM_WEAPON){ send_to_char("You can only swear a blood vow onto a weapon.\n\r", ch); return; } else if (obj->wear_loc != -1){ send_to_char("The weapon must be in your inventory.\n\r",ch); return; } else if (is_affected(ch, sn) && !is_affected_obj(obj, sn)){ send_to_char("You're not yet ready to swear a new blood vow.\n\r", ch); return; } //strip the bloodvow from the weapon affect_strip_obj(obj, sn); //strip it from us affect_strip(ch, sn); //object affects af.type = sn; af.level = level; af.duration = dur; //bless-evil and hitroll af.where = IS_GOOD(ch) || IS_EVIL(ch) ? TO_OBJECT : TO_WEAPON; af.bitvector = IS_GOOD(ch) ? ITEM_BLESS : IS_EVIL(ch) ? ITEM_EVIL : WEAPON_SHARP; af.location = APPLY_HITROLL; af.modifier = level / 5; affect_to_obj(obj, &af); //nodrop and hp af.where = TO_OBJECT; af.bitvector = ITEM_NODROP; af.location = APPLY_NONE; af.modifier = 0; affect_to_obj(obj, &af); //mana and sharp af.where = TO_OBJECT; af.bitvector = ITEM_NOUNCURSE; af.location = APPLY_NONE; af.modifier = 0; affect_to_obj(obj, &af); //take off the mana/hp from the character af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); act("You slice your palms on $p and swear the blood vow.", ch, obj, NULL, TO_CHAR); act("$n slices $s palms on $p and swears the blood vow.", ch, obj, NULL, TO_ROOM); damage(ch, ch, number_range(1, 3), sn, DAM_INTERNAL, TRUE ); } //warcry like spell void spell_battlesphere( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)){ send_to_char("You've already focus your mind on your battle sphere.\n\r",ch); return; } if (IS_AFFECTED(ch,AFF_CALM)){ send_to_char("You can't get worked up in your calm state.\n\r",ch); return; } act("You empty your mind and focus on your sphere of battle.",ch,NULL,NULL,TO_CHAR); act("$n closes $s eyes and meditates briefly.", ch, NULL, NULL, TO_ROOM); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.modifier = UMAX(1, ch->level / 8);; af.location = APPLY_HITROLL; af.bitvector = 0; affect_to_char(ch,&af); af.modifier = 0 - (ch->level /8); af.location = APPLY_SAVING_SPELL; affect_to_char(ch,&af); } //allows counters etc. while blinded void spell_battlefocus( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)){ send_to_char("You've already focused on battle.\n\r",ch); return; } else if (!is_affected(ch, gsn_battlesphere)){ send_to_char("You must first enter the battlesphere.\n\r", ch); return; } if (IS_AFFECTED(ch,AFF_CALM)){ send_to_char("You can't get worked up in your calm state.\n\r",ch); return; } act("You empty your mind and focus only on battle and possible attacks.",ch,NULL,NULL,TO_CHAR); act("$n closes $s eyes and meditates briefly.", ch, NULL, NULL, TO_ROOM); af.type = sn; af.level = level; af.duration = level / 2; af.where = TO_AFFECTS; af.bitvector = 0; af.modifier = -ch->level; af.location = APPLY_AC; affect_to_char(ch,&af); } //negates blind penalties void spell_battletrance( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ AFFECT_DATA af; if (is_affected(ch, sn)){ send_to_char("You've already entered the battletrance.\n\r",ch); return; } else if (!is_affected(ch, gsn_battlefocus)){ send_to_char("You must first enter the battlefocus.\n\r", ch); return; } if (IS_AFFECTED(ch,AFF_CALM)){ send_to_char("You can't get worked up in your calm state.\n\r",ch); return; } act("You empty your mind and enter a deep trance.",ch,NULL,NULL,TO_CHAR); act("$n closes $s eyes and seems to enter a deep trance.", ch, NULL, NULL, TO_ROOM); af.type = sn; af.level = level; af.duration = level / 3; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch,&af); } void spell_soul_tap( int sn, int level, CHAR_DATA *ch, void *vo, int target ){ OBJ_DATA* soul; AFFECT_DATA af; const int dur = 72; if (is_affected(ch, sn)){ send_to_char("You're still tapping the energies in the last soul!\n\r", ch); return; } else if ( (soul = get_eq_char(ch, WEAR_SHROUD)) == NULL){ send_to_char("You must first wear a soul.\n\r", ch); return; } act("A dark vortex of negative energy consumes $p!", ch, soul, NULL, TO_ALL); af.type = sn; af.level = level; af.duration = number_range(dur, 3 * dur / 2); af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_MALED_LEVEL; af.modifier = 1; affect_to_char( ch, &af); soul->timer = 1; }