/* * $Id: magic2.c,v 1.98 1999/04/16 15:52:18 fjoe Exp $ */ /*************************************************************************** * ANATOLIA 2.1 is copyright 1996-1997 Serdar BULUT, Ibrahim CANPUNAR * * ANATOLIA has been brought to you by ANATOLIA consortium * * Serdar BULUT {Chronos} bulut@rorqual.cc.metu.edu.tr * * Ibrahim Canpunar {Asena} canpunar@rorqual.cc.metu.edu.tr * * Murat BICER {KIO} mbicer@rorqual.cc.metu.edu.tr * * D.Baris ACAR {Powerman} dbacar@rorqual.cc.metu.edu.tr * * By using this code, you have agreed to follow the terms of the * * ANATOLIA license, in the file Anatolia/anatolia.licence * ***************************************************************************/ /*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ /*************************************************************************** * ROM 2.4 is copyright 1993-1995 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@pacinfo.com) * * Gabrielle Taylor (gtaylor@pacinfo.com) * * Brian Moore (rom@rom.efn.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * ***************************************************************************/ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #include "fight.h" #include "quest.h" #include "rating.h" #include "fight.h" DECLARE_DO_FUN(do_scan2); /* command procedures needed */ DECLARE_DO_FUN(do_look ); DECLARE_DO_FUN(do_yell ); DECLARE_DO_FUN(do_say ); DECLARE_DO_FUN(do_murder ); DECLARE_DO_FUN(do_kill ); DECLARE_DO_FUN(do_wear ); int find_door (CHAR_DATA *ch, char *arg); int check_exit (const char *argument); extern const char *target_name; ROOM_INDEX_DATA * check_place(CHAR_DATA *ch, const char *argument) { EXIT_DATA *pExit; ROOM_INDEX_DATA *dest_room; int number,door; int range = (ch->level / 10) + 1; char arg[MAX_INPUT_LENGTH]; number = number_argument(argument, arg, sizeof(arg)); if ((door = check_exit(arg)) == -1) return NULL; dest_room = ch->in_room; while (number > 0) { number--; if (--range < 1) return NULL; if ((pExit = dest_room->exit[door]) == NULL || (dest_room = pExit->to_room.r) == NULL || IS_SET(pExit->exit_info,EX_CLOSED)) break; if (number < 1) return dest_room; } return NULL; } void spell_portal(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim; OBJ_DATA *portal, *stone; if ((victim = get_char_world(ch, target_name)) == NULL || victim->level >= level + 3 || saves_spell(level, victim, DAM_NONE) || !can_gate(ch, victim)) { char_puts("You failed.\n", ch); return; } stone = get_eq_char(ch,WEAR_HOLD); if (!IS_IMMORTAL(ch) && (stone == NULL || stone->pIndexData->item_type != ITEM_WARP_STONE)) { char_puts("You lack the proper component for this spell.\n",ch); return; } if (stone != NULL && stone->pIndexData->item_type == ITEM_WARP_STONE) { act("You draw upon the power of $p.",ch,stone,NULL,TO_CHAR); act("It flares brightly and vanishes!",ch,stone,NULL,TO_CHAR); extract_obj(stone, 0); } portal = create_obj(get_obj_index(OBJ_VNUM_PORTAL),0); portal->timer = 2 + level / 25; portal->value[3] = victim->in_room->vnum; obj_to_room(portal,ch->in_room); act("$p rises up from the ground.",ch,portal,NULL,TO_ROOM); act("$p rises up before you.",ch,portal,NULL,TO_CHAR); } void spell_nexus(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim; OBJ_DATA *portal, *stone; ROOM_INDEX_DATA *to_room, *from_room; from_room = ch->in_room; if ((victim = get_char_world(ch, target_name)) == NULL || victim->level >= level + 3 || !can_see_room(ch, from_room) || saves_spell(level, victim, DAM_NONE) || !can_gate(ch, victim)) { char_puts("You failed.\n", ch); return; } to_room = victim->in_room; stone = get_eq_char(ch,WEAR_HOLD); if (!IS_IMMORTAL(ch) && (stone == NULL || stone->pIndexData->item_type != ITEM_WARP_STONE)) { char_puts("You lack the proper component for this spell.\n",ch); return; } if (stone != NULL && stone->pIndexData->item_type == ITEM_WARP_STONE) { act("You draw upon the power of $p.",ch,stone,NULL,TO_CHAR); act("It flares brightly and vanishes!",ch,stone,NULL,TO_CHAR); extract_obj(stone, 0); } /* portal one */ portal = create_obj(get_obj_index(OBJ_VNUM_PORTAL),0); portal->timer = 1 + level / 10; portal->value[3] = to_room->vnum; obj_to_room(portal,from_room); act("$p rises up from the ground.",ch,portal,NULL,TO_ROOM); act("$p rises up before you.",ch,portal,NULL,TO_CHAR); /* no second portal if rooms are the same */ if (to_room == from_room) return; /* portal two */ portal = create_obj(get_obj_index(OBJ_VNUM_PORTAL),0); portal->timer = 1 + level/10; portal->value[3] = from_room->vnum; obj_to_room(portal,to_room); if (to_room->people != NULL) { act("$p rises up from the ground.",to_room->people,portal,NULL,TO_ROOM); act("$p rises up from the ground.",to_room->people,portal,NULL,TO_CHAR); } } void spell_disintegrate(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; CHAR_DATA *tmp_ch; OBJ_DATA *obj; OBJ_DATA *obj_next; int i,dam=0; OBJ_DATA *tattoo, *clanmark; if (saves_spell(level-2, victim, DAM_ENERGY) || number_bits(1) == 0 || IS_IMMORTAL(victim) || IS_CLAN_GUARD(victim)) { dam = dice(level, 24) ; damage(ch, victim, dam, sn, DAM_ENERGY, TRUE); return; } act_puts("$N's thin light ray ###DISINTEGRATES### you!", victim, NULL, ch, TO_CHAR, POS_RESTING); act_puts("$n's thin light ray ###DISINTEGRATES### $N!", ch, NULL, victim, TO_NOTVICT, POS_RESTING); act_puts("Your thin light ray ###DISINTEGRATES### $N!", ch, NULL, victim, TO_CHAR, POS_RESTING); char_puts("You have been KILLED!\n", victim); act("$N does not exist anymore!\n", ch, NULL, victim, TO_CHAR); act("$N does not exist anymore!\n", ch, NULL, victim, TO_ROOM); char_puts("You turn into an invincible ghost for a few minutes.\n", victim); char_puts("As long as you don't attack anything.\n", victim); quest_handle_death(ch, victim); /* disintegrate the objects... */ tattoo = get_eq_char(victim, WEAR_TATTOO); /* keep tattoos for later */ if (tattoo != NULL) obj_from_char(tattoo); if ((clanmark = get_eq_char(victim, WEAR_CLANMARK)) != NULL) obj_from_char(clanmark); victim->gold = 0; victim->silver = 0; for (obj = victim->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; extract_obj(obj, 0); } if (IS_NPC(victim)) { victim->pIndexData->killed++; extract_char(victim, 0); return; } rating_update(ch, victim); extract_char(victim, XC_F_INCOMPLETE); while (victim->affected) affect_remove(victim, victim->affected); victim->affected_by = 0; for (i = 0; i < 4; i++) victim->armor[i]= 100; victim->position = POS_RESTING; victim->hit = 1; victim->mana = 1; REMOVE_BIT(victim->plr_flags, PLR_WANTED | PLR_BOUGHT_PET); victim->pcdata->condition[COND_THIRST] = 40; victim->pcdata->condition[COND_HUNGER] = 40; victim->pcdata->condition[COND_FULL] = 40; victim->pcdata->condition[COND_BLOODLUST] = 40; victim->pcdata->condition[COND_DESIRE] = 40; if (tattoo != NULL) { obj_to_char(tattoo, victim); equip_char(victim, tattoo, WEAR_TATTOO); } if (clanmark != NULL) { obj_to_char(clanmark, victim); equip_char(victim, clanmark, WEAR_CLANMARK); } for (tmp_ch = npc_list; tmp_ch; tmp_ch = tmp_ch->next) if (tmp_ch->last_fought == victim) tmp_ch->last_fought = NULL; } void spell_bark_skin(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)) { if (victim == ch) char_puts("Your skin is already covered in bark.\n",ch); else act("$N is already as hard as can be.",ch,NULL,victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_AC; af.modifier = -(level * 1.5); af.bitvector = 0; affect_to_char(victim, &af); act("$n's skin becomes covered in bark.", victim, NULL, NULL, TO_ROOM); char_puts("Your skin becomes covered in bark.\n", victim); } void spell_ranger_staff(int sn, int level, CHAR_DATA *ch, void *vo, int target) { OBJ_DATA *staff; AFFECT_DATA tohit; AFFECT_DATA todam; staff = create_obj(get_obj_index(OBJ_VNUM_RANGER_STAFF), 0); staff->level = ch->level; staff->value[1] = 4 + level / 15; staff->value[2] = 4 + level / 15; char_puts("You create a ranger's staff!\n",ch); act("$n creates a ranger's staff!",ch,NULL,NULL,TO_ROOM); tohit.where = TO_OBJECT; tohit.type = sn; tohit.level = ch->level; tohit.duration = -1; tohit.location = APPLY_HITROLL; tohit.modifier = 2 + level/5; tohit.bitvector = 0; affect_to_obj(staff,&tohit); todam.where = TO_OBJECT; todam.type = sn; todam.level = ch->level; todam.duration = -1; todam.location = APPLY_DAMROLL; todam.modifier = 2 + level/5; todam.bitvector = 0; affect_to_obj(staff,&todam); staff->timer = level; staff->level = ch->level; obj_to_char(staff,ch); } void spell_transform(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (is_affected(ch,sn) || ch->hit > ch->max_hit) { char_puts("You are already overflowing with health.\n",ch); return; } ch->hit += UMIN(30000 - ch->max_hit, ch->max_hit); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.location = APPLY_HIT; af.modifier = UMIN(30000 - ch->max_hit, ch->max_hit); af.bitvector = 0; affect_to_char(ch,&af); char_puts("Your mind clouds as your health increases.\n",ch); } void spell_mana_transfer(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; if (victim == ch) { char_puts("You would implode if you tried to transfer mana to yourself.\n",ch); return; } if (ch->clan != victim->clan) { char_puts("You may only cast this spell on fellow clan members.\n",ch); return; } if (ch->hit < 50) damage(ch,ch,50,sn,DAM_NONE, TRUE); else { victim->mana = UMIN(victim->max_mana, victim->mana + number_range(20,120)); damage(ch,ch,50,sn,DAM_NONE, TRUE); } } void spell_mental_knife(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; if (ch->level < 40) dam = dice(level,8); else if (ch->level < 65) dam = dice(level,11); else dam = dice(level,14); if (saves_spell(level,victim, DAM_MENTAL)) dam /= 2; damage(ch,victim,dam,sn,DAM_MENTAL, TRUE); if (JUST_KILLED(victim)) return; if (!is_affected(victim,sn) && !saves_spell(level, victim, DAM_MENTAL)) { af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_INT; af.modifier = -7; af.bitvector = 0; affect_to_char(victim,&af); af.location = APPLY_WIS; affect_to_char(victim,&af); act("Your mental knife sears $N's mind!",ch,NULL,victim,TO_CHAR); act("$n's mental knife sears your mind!",ch,NULL,victim,TO_VICT); act("$n's mental knife sears $N's mind!",ch,NULL,victim,TO_NOTVICT); } } void spell_demon_summon(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *gch; CHAR_DATA *demon; AFFECT_DATA af; int i; if (is_affected(ch,sn)) { char_puts("You lack the power to summon another demon right now.\n", ch); return; } char_puts("You attempt to summon a demon.\n",ch); act("$n attempts to summon a demon.",ch,NULL,NULL,TO_ROOM); for (gch = npc_list; gch; gch = gch->next) { if (IS_AFFECTED(gch,AFF_CHARM) && gch->master == ch && gch->pIndexData->vnum == MOB_VNUM_DEMON) { char_puts("Two demons are more than you can control!\n", ch); return; } } demon = create_mob(get_mob_index(MOB_VNUM_DEMON)); for (i=0;i < MAX_STATS; i++) { demon->perm_stat[i] = ch->perm_stat[i]; } demon->max_hit = IS_NPC(ch)? URANGE(ch->max_hit,1 * ch->max_hit,30000) : URANGE(ch->pcdata->perm_hit,ch->hit,30000); demon->hit = demon->max_hit; demon->max_mana = IS_NPC(ch)? ch->max_mana : ch->pcdata->perm_mana; demon->mana = demon->max_mana; demon->level = ch->level; for (i=0; i < 3; i++) demon->armor[i] = interpolate(demon->level,100,-100); demon->armor[3] = interpolate(demon->level,100,0); demon->gold = 0; demon->timer = 0; demon->damage[DICE_NUMBER] = number_range(level/15, level/10); demon->damage[DICE_TYPE] = number_range(level/3, level/2); demon->damage[DICE_BONUS] = number_range(level/8, level/6); char_puts("A demon arrives from the underworld!\n",ch); act("A demon arrives from the underworld!",ch,NULL,NULL,TO_ROOM); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); char_to_room(demon,ch->in_room); if (JUST_KILLED(demon)) return; if (number_percent() < 40) { if (can_see(demon, ch)) do_say(demon, "You dare disturb me??!!!"); else do_say(demon, "Who dares disturb me??!!!"); do_murder(demon, ch->name); } else { SET_BIT(demon->affected_by, AFF_CHARM); demon->master = demon->leader = ch; } } void spell_scourge(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *vch; CHAR_DATA *vch_next; int dam; if (ch->level < 40) dam = dice(level, 6); else if (ch->level < 65) dam = dice(level, 9); else dam = dice(level, 12); for (vch = ch->in_room->people; vch; vch = vch_next) { vch_next = vch->next_in_room; if (is_safe_spell(ch, vch, TRUE) || is_affected(vch, sn)) /* XXX ??? */ continue; if (number_percent() < level) spell_poison(gsn_poison, level, ch, vch, TARGET_CHAR); if (number_percent() < level) spell_blindness(gsn_blindness,level,ch,vch, TARGET_CHAR); if (number_percent() < level) spell_weaken(gsn_weaken, level, ch, vch, TARGET_CHAR); if (saves_spell(level,vch, DAM_FIRE)) dam /= 2; damage(ch, vch, dam, sn, DAM_FIRE, TRUE); } } void spell_benediction(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; int strength = 0; if (is_affected(victim, sn)) { if (victim == ch) act("You are already blessed.", ch, NULL, NULL, TO_CHAR); else act("$N is already blessed.", ch, NULL, victim, TO_CHAR); return; } if (IS_EVIL(victim)) strength = IS_EVIL(ch) ? 2 : (IS_GOOD(ch) ? 0 : 1); if (IS_GOOD(victim)) strength = IS_GOOD(ch) ? 2 : (IS_EVIL(ch) ? 0 : 1); if (IS_NEUTRAL(victim)) strength = IS_NEUTRAL(ch) ? 2 : 1; if (!strength) { act("Your god does not seems to like $N", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 5+level/2; af.location = APPLY_HITROLL; af.modifier = level / 8 * strength; af.bitvector = 0; affect_to_char(victim, &af); af.location = APPLY_SAVING_SPELL; af.modifier = 0 - level / 8 * strength; affect_to_char(victim, &af); af.location = APPLY_LEVEL; af.modifier = strength; affect_to_char(victim, &af); act("You feel righteous.\n", victim, NULL, NULL, TO_CHAR); if (victim != ch) act("You grant $N favor of your god.", ch, NULL, victim, TO_CHAR); } void spell_manacles(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; if (!IS_SET(victim->plr_flags, PLR_WANTED)) { act("But $N is not wanted.", ch, NULL, victim, TO_CHAR); return; } if (!is_affected(victim, sn) && !saves_spell(ch->level, victim,DAM_CHARM)) { AFFECT_DATA af; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 5 + level/5; af.bitvector = 0; af.modifier = 0 - (get_curr_stat(victim, STAT_DEX)-4); af.location = APPLY_DEX; affect_to_char(victim, &af); af.modifier = -5; af.location = APPLY_HITROLL; affect_to_char(victim, &af); af.modifier = -10; af.location = APPLY_DAMROLL; affect_to_char(victim, &af); spell_charm_person(gsn_charm_person, level, ch, vo, TARGET_CHAR); } } void spell_shield_of_ruler(int sn, int level, CHAR_DATA *ch, void *vo, int target) { int shield_vnum; OBJ_DATA *shield; AFFECT_DATA af; if (level >= 71) shield_vnum = OBJ_VNUM_RULER_SHIELD4; else if (level >= 51) shield_vnum = OBJ_VNUM_RULER_SHIELD3; else if (level >= 31) shield_vnum = OBJ_VNUM_RULER_SHIELD2; else shield_vnum = OBJ_VNUM_RULER_SHIELD1; shield = create_obj(get_obj_index(shield_vnum), 0); shield->level = ch->level; shield->timer = level; shield->cost = 0; obj_to_char(shield, ch); af.where = TO_OBJECT; af.type = sn; af.level = level; af.duration = -1; af.modifier = level / 8; af.bitvector = 0; af.location = APPLY_HITROLL; affect_to_obj(shield, &af); af.location = APPLY_DAMROLL; affect_to_obj(shield, &af); af.modifier = -level/2; af.location = APPLY_AC; affect_to_obj(shield, &af); af.modifier = UMAX(1, level / 30); af.location = APPLY_CHA; affect_to_obj(shield, &af); act("You create $p!", ch, shield, NULL, TO_CHAR); act("$n creates $p!", ch, shield, NULL, TO_ROOM); } void spell_guard_call(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *gch; CHAR_DATA *guard; CHAR_DATA *guard2; AFFECT_DATA af; int i; if (is_affected(ch,sn)) { char_puts("You lack the power to call another two guards now.\n",ch); return; } do_yell(ch, "Guards! Guards!"); for (gch = npc_list; gch; gch = gch->next) { if (IS_AFFECTED(gch,AFF_CHARM) && gch->master == ch && gch->pIndexData->vnum == MOB_VNUM_SPECIAL_GUARD) { do_say(gch, "What? I'm not good enough?"); return; } } guard = create_mob(get_mob_index(MOB_VNUM_SPECIAL_GUARD)); for (i=0;i < MAX_STATS; i++) guard->perm_stat[i] = ch->perm_stat[i]; guard->max_hit = 2*ch->max_hit; guard->hit = guard->max_hit; guard->max_mana = ch->max_mana; guard->mana = guard->max_mana; guard->alignment = ch->alignment; guard->level = ch->level; for (i=0; i < 3; i++) guard->armor[i] = interpolate(guard->level,100,-200); guard->armor[3] = interpolate(guard->level,100,-100); guard->sex = ch->sex; guard->gold = 0; guard->timer = 0; guard->damage[DICE_NUMBER] = number_range(level/18, level/14); guard->damage[DICE_TYPE] = number_range(level/4, level/3); guard->damage[DICE_BONUS] = number_range(level/10, level/8); guard2 = create_mob(guard->pIndexData); clone_mob(guard,guard2); SET_BIT(guard->affected_by, AFF_CHARM); SET_BIT(guard2->affected_by, AFF_CHARM); guard->master = guard2->master = ch; guard->leader = guard2->leader = ch; char_puts("Two guards come to your rescue!\n",ch); act("Two guards come to $n's rescue!",ch,NULL,NULL,TO_ROOM); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 12; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); char_to_room(guard,ch->in_room); char_to_room(guard2,ch->in_room); } void spell_nightwalker(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *gch; CHAR_DATA *walker; AFFECT_DATA af; int i; if (is_affected(ch,sn)) { act_puts("You feel too weak to summon a Nightwalker now.", ch, NULL, NULL, TO_CHAR, POS_DEAD); return; } act_puts("You attempt to summon a Nightwalker.", ch, NULL, NULL, TO_CHAR, POS_DEAD); act("$n attempts to summon a Nightwalker.", ch, NULL, NULL, TO_ROOM); for (gch = npc_list; gch; gch = gch->next) { if (IS_AFFECTED(gch, AFF_CHARM) && gch->master == ch && gch->pIndexData->vnum == MOB_VNUM_NIGHTWALKER) { act_puts("Two Nightwalkers are more than " "you can control!", ch, NULL, NULL, TO_CHAR, POS_DEAD); return; } } walker = create_mob(get_mob_index(MOB_VNUM_NIGHTWALKER)); for (i = 0; i < MAX_STATS; i++) walker->perm_stat[i] = ch->perm_stat[i]; walker->max_hit = IS_NPC(ch) ? ch->max_hit : ch->pcdata->perm_hit; walker->hit = walker->max_hit; walker->max_mana = ch->max_mana; walker->mana = walker->max_mana; walker->level = ch->level; for (i = 0; i < 3; i++) walker->armor[i] = interpolate(walker->level, 100, -100); walker->armor[3] = interpolate(walker->level, 100, 0); walker->gold = 0; walker->timer = 0; walker->damage[DICE_NUMBER] = number_range(level/15, level/10); walker->damage[DICE_TYPE] = number_range(level/3, level/2); walker->damage[DICE_BONUS] = 0; act_puts("$N rises from the shadows!", ch, NULL, walker, TO_CHAR, POS_DEAD); act("$N rises from the shadows!", ch, NULL, walker, TO_ROOM); act_puts("$N kneels before you.", ch, NULL, walker, TO_CHAR, POS_DEAD); act("$N kneels before $n!", ch, NULL, walker, TO_ROOM); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); walker->master = walker->leader = ch; char_to_room(walker, ch->in_room); } void spell_eyes_of_intrigue(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim; if ((victim = get_char_world(ch, target_name)) == NULL) { char_puts("Your spy network reveals no such player.\n",ch); return; } if ((victim->level > ch->level + 7) && saves_spell(level, victim, DAM_NONE)) { char_puts("Your spy network cannot find that player.\n",ch); return; } if (ch->in_room == victim->in_room) do_look(ch, str_empty); else look_at(ch, victim->in_room); } void spell_shadow_cloak(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (ch->clan != victim->clan) { char_puts("You may only use this spell on fellow clan members.\n",ch); return; } if (is_affected(victim, sn)) { if (victim == ch) char_puts("You are already protected by a shadow cloak.\n",ch); else act("$N is already protected by a shadow cloak.",ch,NULL,victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.modifier = -level; af.location = APPLY_AC; af.bitvector = 0; affect_to_char(victim, &af); char_puts("You feel the shadows protect you.\n", victim); if (ch != victim) act("A cloak of shadows protect $N.",ch,NULL,victim,TO_CHAR); return; } void spell_nightfall(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *vch; OBJ_DATA *obj; AFFECT_DATA af; if (is_affected(ch, sn)) { char_puts("You can't find the power to control objs.\n", ch); return; } for (vch = ch->in_room->people; vch; vch = vch->next_in_room) { if (is_same_group(ch, vch)) continue; for (obj = vch->carrying; obj; obj = obj->next_content) { if (obj->pIndexData->item_type != ITEM_LIGHT || obj->value[2] == 0 || saves_spell(level, vch, DAM_ENERGY)) continue; act("$p flickers and goes out!", ch, obj, NULL, TO_ALL); obj->value[2] = 0; if (obj->wear_loc == WEAR_LIGHT && ch->in_room->light > 0) ch->in_room->light--; } } for (obj = ch->in_room->contents; obj; obj = obj->next_content) { if (obj->pIndexData->item_type != ITEM_LIGHT || obj->value[2] == 0) continue; act("$p flickers and goes out!", ch, obj, NULL, TO_ALL); obj->value[2] = 0; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 2; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = 0; affect_to_char(ch, &af); } void spell_garble(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (ch == victim) { char_puts("Garble whose speech?\n",ch); return; } if (is_affected(victim,sn)) { act("$N's speech is already garbled.",ch,NULL,victim,TO_CHAR); return; } if (is_safe_nomessage(ch,victim)) { char_puts("You cannot garble that person.\n",ch); return; } if (saves_spell(level,victim, DAM_MENTAL)) return; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 10; af.modifier = 0; af.location = 0; af.bitvector = 0; affect_to_char(victim,&af); act("You have garbled $N's speech!",ch,NULL,victim,TO_CHAR); char_puts("You feel your tongue contort.\n",victim); } void spell_confuse(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; CHAR_DATA *rch; int count=0; if (is_affected(victim,gsn_confuse)) { act("$N is already thoroughly confused.",ch,NULL,victim,TO_CHAR); return; } if (saves_spell(level,victim, DAM_MENTAL)) return; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 10; af.modifier = 0; af.location = 0; af.bitvector = 0; affect_to_char(victim,&af); for (rch = ch->in_room->people; rch; rch = rch->next_in_room) if (rch == ch && !can_see(ch, rch)) count++; for (rch = ch->in_room->people; rch; rch = rch->next_in_room) { if (rch != ch && can_see(ch, rch) && number_range(1, count) == 1) break; } if (rch) do_murder(victim, rch->name); do_murder(victim, ch->name); } void spell_terangreal(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_NPC(victim)) return; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 10; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_SLEEP; affect_join(victim, &af); if (IS_AWAKE(victim)) { char_puts("You are overcome by a sudden surge of fatigue.\n", victim); act("$n falls into a deep sleep.", victim, NULL, NULL, TO_ROOM); victim->position = POS_SLEEPING; } return; } void spell_kassandra(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (is_affected(ch, sn)) { char_puts ("The kassandra has been used for this purpose too recently.\n", ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 5; af.location = 0; af.modifier = 0; af.bitvector = 0; affect_to_char(ch, &af); ch->hit = UMIN(ch->hit + 150, ch->max_hit); update_pos(ch); char_puts("A warm feeling fills your body.\n", ch); act("$n looks better.", ch, NULL, NULL, TO_ROOM); return; } void spell_sebat(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (is_affected(ch, sn)) { char_puts("The kassandra has been used for that too recently.\n" ,ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_AC; af.modifier = -30; af.bitvector = 0; affect_to_char(ch, &af); act("$n is surrounded by a mystical shield.",ch, NULL,NULL,TO_ROOM); char_puts("You are surrounded by a mystical shield.\n", ch); return; } void spell_matandra(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; AFFECT_DATA af; if (is_affected(ch, sn)) { char_puts ("The kassandra has been used for this purpose too recently.\n", ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 5; af.location = 0; af.modifier = 0; af.bitvector = 0; affect_to_char(ch, &af); dam = dice(level, 7); damage(ch,victim,dam,sn,DAM_HOLY, TRUE); } void spell_amnesia(int sn, int level, CHAR_DATA *ch, void *vo, int target) { int i; CHAR_DATA *victim = (CHAR_DATA *) vo; if (IS_NPC(victim)) return; for (i = 0; i < ch->pcdata->learned.nused; i++) { pcskill_t *ps = VARR_GET(&ch->pcdata->learned, i); ps->percent /= 2; } act("You feel your memories slip away.",victim,NULL,NULL,TO_CHAR); act("$n gets a blank look on $s face.",victim,NULL,NULL,TO_ROOM); } void spell_chaos_blade(int sn, int level, CHAR_DATA *ch, void *vo, int target) { OBJ_DATA *blade; AFFECT_DATA af; blade = create_obj(get_obj_index(OBJ_VNUM_CHAOS_BLADE), 0); blade->level = ch->level; blade->timer = level * 2; blade->value[2] = (ch->level / 10) + 3; char_puts("You create a blade of chaos!\n",ch); act("$n creates a blade of chaos!",ch,NULL,NULL,TO_ROOM); af.where = TO_OBJECT; af.type = sn; af.level = level; af.duration = -1; af.modifier = level / 6; af.bitvector = 0; af.location = APPLY_HITROLL; affect_to_obj(blade,&af); af.location = APPLY_DAMROLL; affect_to_obj(blade,&af); obj_to_char(blade,ch); } void spell_tattoo(int sn, int level, CHAR_DATA *ch, void *vo, int target) { OBJ_DATA *tattoo; CHAR_DATA *victim = (CHAR_DATA *) vo; int i; if (IS_NPC(victim)) { act("$N is too dumb to worship you!", ch, NULL, victim, TO_CHAR); return; } for (i = 0; i < MAX_RELIGION; i++) { if (!str_cmp(ch->name, religion_table[i].leader)) { tattoo = get_eq_char(victim, WEAR_TATTOO); if (tattoo != NULL) { act("$N is already tattooed! You'll have to remove it first.", ch, NULL, victim, TO_CHAR); act("$n tried to give you another tattoo but failed.", ch, NULL, victim, TO_VICT); act("$n tried to give $N another tattoo but failed.", ch, NULL, victim, TO_NOTVICT); return; } else { tattoo = create_obj(get_obj_index(religion_table[i].vnum),0); act("You tattoo $N with $p!",ch, tattoo, victim, TO_CHAR); act("$n tattoos $N with $p!",ch,tattoo,victim,TO_NOTVICT); act("$n tattoos you with $p!",ch,tattoo,victim,TO_VICT); obj_to_char(tattoo,victim); equip_char(victim, tattoo, WEAR_TATTOO); return; } } } char_puts("You don't have a religious tattoo.\n", ch); return; } void spell_remove_tattoo(int sn, int level, CHAR_DATA *ch, void *vo, int target) { OBJ_DATA *tattoo; CHAR_DATA *victim = (CHAR_DATA *) vo; tattoo = get_eq_char(victim, WEAR_TATTOO); if (tattoo != NULL) { extract_obj(tattoo, 0); act("Through a painful process, your tattoo has been destroyed by $n.", ch, NULL, victim, TO_VICT); act("You remove the tattoo from $N.", ch, NULL, victim, TO_CHAR); act("$N's tattoo is destroyed by $n.", ch, NULL, victim, TO_NOTVICT); } else act("$N doesn't have any tattoos.", ch, NULL, victim, TO_CHAR); } void spell_wrath(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; AFFECT_DATA af; if (!IS_NPC(ch) && IS_EVIL(ch)) victim = ch; if (IS_GOOD(victim)) { act("The gods protect $N.", ch, NULL, victim, TO_ROOM); return; } if (IS_NEUTRAL(victim)) { act("$N does not seem to be affected.", ch, NULL, victim, TO_CHAR); return; } dam = dice(level, 12); if (saves_spell(level, victim, DAM_HOLY)) dam /= 2; damage(ch, victim, dam, sn, DAM_HOLY, TRUE); if (JUST_KILLED(victim)) return; if (IS_AFFECTED(victim, AFF_CURSE) || saves_spell(level, victim, DAM_HOLY)) return; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 2*level; af.location = APPLY_HITROLL; af.modifier = -1 * (level / 8); af.bitvector = AFF_CURSE; affect_to_char(victim, &af); af.location = APPLY_SAVING_SPELL; af.modifier = level / 8; affect_to_char(victim, &af); char_puts("You feel unclean.\n", victim); if (ch != victim) act("$N looks very uncomfortable.",ch,NULL,victim,TO_CHAR); } void spell_stalker(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim; CHAR_DATA *stalker; AFFECT_DATA af; int i; if ((victim = get_char_world(ch, target_name)) == NULL || victim == ch || victim->in_room == NULL || IS_NPC(victim) || !IS_SET(victim->plr_flags, PLR_WANTED)) { char_puts("You failed.\n", ch); return; } if (is_affected(ch,sn)) { char_puts("This power is used too recently.\n", ch); return; } char_puts("You attempt to summon a stalker.\n",ch); act("$n attempts to summon a stalker.",ch,NULL,NULL,TO_ROOM); stalker = create_mob(get_mob_index(MOB_VNUM_STALKER)); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 6; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); for (i=0;i < MAX_STATS; i++) { stalker->perm_stat[i] = victim->perm_stat[i]; } stalker->max_hit = UMIN(30000,2 * victim->max_hit); stalker->hit = stalker->max_hit; stalker->max_mana = victim->max_mana; stalker->mana = stalker->max_mana; stalker->level = victim->level; stalker->damage[DICE_NUMBER] = number_range(victim->level/18, victim->level/14); stalker->damage[DICE_TYPE] = number_range(victim->level/4, victim->level/3); stalker->damage[DICE_BONUS] = number_range(victim->level/10, victim->level/8); for (i=0; i < 3; i++) stalker->armor[i] = interpolate(stalker->level,100,-100); stalker->armor[3] = interpolate(stalker->level,100,0); stalker->gold = 0; stalker->invis_level = LEVEL_HERO; stalker->affected_by |= (AFF_DETECT_IMP_INVIS | AFF_DETECT_FADE | AFF_DETECT_EVIL | AFF_DETECT_INVIS | AFF_DETECT_MAGIC | AFF_DETECT_HIDDEN | AFF_DETECT_GOOD | AFF_DARK_VISION); stalker->target = victim; stalker->clan = ch->clan; char_puts("An invisible stalker arrives to stalk you!\n",victim); act("An invisible stalker arrives to stalk $n!",victim,NULL,NULL,TO_ROOM); char_puts("An invisible stalker has been sent.\n", ch); char_to_room(stalker,victim->in_room); } static inline void tesseract_other(CHAR_DATA *ch, CHAR_DATA *victim, ROOM_INDEX_DATA *to_room) { transfer_char(victim, ch, to_room, NULL, "$n utters some strange words and, " "with a sickening lurch, you feel time\n" "and space shift around you.", "$N arrives suddenly."); } void spell_tesseract(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA*) vo; CHAR_DATA *wch; CHAR_DATA *wch_next; CHAR_DATA *pet = NULL; if ((victim = get_char_world(ch,target_name)) == NULL || saves_spell(level, victim, DAM_OTHER) || !can_gate(ch, victim)) { char_puts("You failed.\n", ch); return; } if (ch->pet != NULL && ch->in_room == ch->pet->in_room) pet = ch->pet; for (wch = ch->in_room->people; wch; wch = wch_next) { wch_next = wch->next_in_room; if (wch != ch && wch != pet && is_same_group(wch, ch)) tesseract_other(ch, wch, victim->in_room); } act("With a sudden flash of light, $n and $s friends disappear!", ch, NULL, NULL, TO_ROOM); transfer_char(ch, NULL, victim->in_room, NULL, "As you utter the words, time and space seem to blur.\n." "You feel as though space and time are shifting.\n" "all around you while you remain motionless.", "$N arrives suddenly."); if (pet) tesseract_other(ch, pet, victim->in_room); } void spell_brew(int sn, int level, CHAR_DATA *ch, void *vo, int target) { OBJ_DATA *obj = (OBJ_DATA *) vo; OBJ_DATA *potion; OBJ_DATA *vial; int spell; if (obj->pIndexData->item_type != ITEM_TRASH && obj->pIndexData->item_type != ITEM_TREASURE && obj->pIndexData->item_type != ITEM_KEY) { char_puts("That can't be transformed into a potion.\n",ch); return; } if (obj->wear_loc != -1) { char_puts("The item must be carried to be brewed.\n",ch); return; } for(vial=ch->carrying; vial != NULL; vial=vial->next_content) if (vial->pIndexData->vnum == OBJ_VNUM_POTION_VIAL) break; if ( vial == NULL) { char_puts("You don't have any vials to brew the potion into.\n" , ch); return; } if (number_percent() < 50) { char_puts("You failed and destroyed it.\n", ch); extract_obj(obj, 0); return; } if (obj->pIndexData->item_type == ITEM_TRASH) potion = create_obj(get_obj_index(OBJ_VNUM_POTION_SILVER), 0); else if (obj->pIndexData->item_type == ITEM_TREASURE) potion = create_obj(get_obj_index(OBJ_VNUM_POTION_GOLDEN), 0); else potion = create_obj(get_obj_index(OBJ_VNUM_POTION_SWIRLING), 0); potion->level = ch->level; potion->value[0] = level; spell = 0; switch (obj->pIndexData->item_type) { case ITEM_TRASH: switch(number_bits(3)) { case 0: spell = sn_lookup("fireball"); break; case 1: spell = sn_lookup("cure poison"); break; case 2: spell = sn_lookup("cure blind"); break; case 3: spell = sn_lookup("cure disease"); break; case 4: spell = sn_lookup("word of recall"); break; case 5: spell = sn_lookup("protection good"); break; case 6: spell = sn_lookup("protection evil"); break; case 7: spell = sn_lookup("sanctuary"); break; }; break; case ITEM_TREASURE: switch(number_bits(3)) { case 0: spell = sn_lookup("cure critical"); break; case 1: spell = sn_lookup("haste"); break; case 2: spell = gsn_frenzy; break; case 3: spell = sn_lookup("create spring"); break; case 4: spell = sn_lookup("holy word"); break; case 5: spell = sn_lookup("invis"); break; case 6: spell = sn_lookup("cure light"); break; case 7: spell = sn_lookup("cure serious"); break; }; break; case ITEM_KEY: switch (number_bits(3)) { case 0: spell = sn_lookup("detect magic"); break; case 1: spell = sn_lookup("detect invis"); break; case 2: spell = sn_lookup("pass door"); break; case 3: spell = sn_lookup("detect hidden"); break; case 4: spell = sn_lookup("improved detect"); break; case 5: spell = sn_lookup("acute vision"); break; case 6: spell = sn_lookup("detect good"); break; case 7: spell = sn_lookup("detect evil"); break; }; }; potion->value[1] = spell; extract_obj(obj, 0); act("You brew $p from your resources!", ch, potion, NULL, TO_CHAR); act("$n brews $p from $s resources!", ch, potion, NULL, TO_ROOM); obj_to_char(potion, ch); extract_obj(vial, 0); } void spell_shadowlife(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; CHAR_DATA *shadow; AFFECT_DATA af; int i; if (IS_NPC(victim)) { char_puts("Now, why would you want to do that?!?\n", ch); return; } if (is_affected(ch,sn)) { char_puts("You don't have the strength to raise a Shadow now.\n", ch); return; } act("You give life to $N's shadow!", ch, NULL, victim, TO_CHAR); act("$n gives life to $N's shadow!", ch, NULL, victim, TO_NOTVICT); act("$n gives life to your shadow!", ch, NULL, victim, TO_VICT); shadow = create_mob_of(get_mob_index(MOB_VNUM_SHADOW), victim->short_descr); for (i = 0; i < MAX_STATS; i++) shadow->perm_stat[i] = ch->perm_stat[i]; shadow->max_hit = (3 * ch->max_hit) / 4; shadow->hit = shadow->max_hit; shadow->max_mana = (3 * ch->max_mana) / 4; shadow->mana = shadow->max_mana; shadow->alignment = ch->alignment; shadow->level = ch->level; for (i=0; i < 3; i++) shadow->armor[i] = interpolate(shadow->level,100,-100); shadow->armor[3] = interpolate(shadow->level,100,0); shadow->sex = victim->sex; shadow->gold = 0; shadow->target = victim; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); char_to_room(shadow, ch->in_room); do_murder(shadow, victim->name); } void spell_ruler_badge(int sn, int level, CHAR_DATA *ch, void *vo, int target) { OBJ_DATA *badge; CHAR_DATA *victim = (CHAR_DATA *) vo; OBJ_DATA *obj_next; AFFECT_DATA af; if ((get_eq_char(ch, WEAR_NECK_1) != NULL) && (get_eq_char(ch, WEAR_NECK_2) != NULL)) { char_puts("But you are wearing something else.\n", ch); return; } for (badge = ch->carrying; badge != NULL; badge = obj_next) { obj_next = badge->next_content; if (badge->pIndexData->vnum == OBJ_VNUM_DEPUTY_BADGE || badge->pIndexData->vnum == OBJ_VNUM_RULER_BADGE) { act("Your $p vanishes.",ch, badge, NULL, TO_CHAR); obj_from_char(badge); extract_obj(badge, 0); continue; } } badge = create_obj(get_obj_index(OBJ_VNUM_RULER_BADGE), 0); badge->level = ch->level; af.where = TO_OBJECT; af.type = sn; af.level = level; af.duration = -1; af.modifier = level; af.bitvector = 0; af.location = APPLY_HIT; affect_to_obj(badge,&af); af.location = APPLY_MANA; affect_to_obj(badge,&af); af.where = TO_OBJECT; af.type = sn; af.level = level; af.duration = -1; af.modifier = level / 8; af.bitvector = 0; af.location = APPLY_HITROLL; affect_to_obj(badge,&af); af.location = APPLY_DAMROLL; affect_to_obj(badge,&af); badge->timer = 200; act("You wear the ruler badge!",ch, NULL, NULL, TO_CHAR); act("$n wears the $s ruler badge!", ch, NULL, NULL, TO_ROOM); obj_to_char(badge,victim); if (get_eq_char(ch, WEAR_NECK_1) == NULL) equip_char(ch, badge, WEAR_NECK_1); else if (get_eq_char(ch, WEAR_NECK_2) == NULL) equip_char(ch, badge, WEAR_NECK_2); else { char_puts("But you are wearing something else.\n", ch); return; } } void spell_remove_badge(int sn, int level, CHAR_DATA *ch, void *vo, int target) { OBJ_DATA *badge; CHAR_DATA *victim = (CHAR_DATA *) vo; OBJ_DATA *obj_next; badge = 0; for (badge = victim->carrying; badge != NULL; badge = obj_next) { obj_next = badge->next_content; if (badge->pIndexData->vnum == OBJ_VNUM_DEPUTY_BADGE || badge->pIndexData->vnum == OBJ_VNUM_RULER_BADGE) { act("Your $p vanishes.",ch, badge, NULL, TO_CHAR); act("$n's $p vanishes.", ch, badge, NULL, TO_ROOM); obj_from_char(badge); extract_obj(badge, 0); continue; } } return; } void spell_shield_ruler(int sn,int level,CHAR_DATA* ch,void *vo, int target) { int shield_vnum; OBJ_DATA *shield; AFFECT_DATA af; if (level >= 71) shield_vnum = OBJ_VNUM_RULER_SHIELD4; else if (level >= 51) shield_vnum = OBJ_VNUM_RULER_SHIELD3; else if (level >= 31) shield_vnum = OBJ_VNUM_RULER_SHIELD2; else shield_vnum = OBJ_VNUM_RULER_SHIELD1; shield = create_obj(get_obj_index(shield_vnum), 0); shield->level = ch->level; shield->timer = level; shield->cost = 0; obj_to_char(shield, ch); af.where = TO_OBJECT; af.type = sn; af.level = level; af.duration = -1; af.modifier = level/8; af.bitvector = 0; af.location = APPLY_HITROLL; affect_to_obj(shield,&af); af.location = APPLY_DAMROLL; affect_to_obj(shield,&af); af.where = TO_OBJECT; af.type = sn; af.level = level; af.duration = -1; af.modifier = -level/2; af.bitvector = 0; af.location = APPLY_AC; affect_to_obj(shield,&af); af.where = TO_OBJECT; af.type = sn; af.level = level; af.duration = -1; af.modifier = UMAX(1,level/30); af.bitvector = 0; af.location = APPLY_CHA; affect_to_obj(shield,&af); act("You create $p!",ch,shield,NULL,TO_CHAR); act("$n creates $p!",ch,shield,NULL,TO_ROOM); } void spell_dragon_strength(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (is_affected(ch, sn)) { char_puts("You are already full of the strength of the dragon.\n", ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 3; af.bitvector = 0; af.modifier = 2; af.location = APPLY_HITROLL; affect_to_char(ch, &af); af.modifier = 2; af.location = APPLY_DAMROLL; affect_to_char(ch, &af); af.modifier = 10; af.location = APPLY_AC; affect_to_char(ch, &af); af.modifier = 2; af.location = APPLY_STR; affect_to_char(ch, &af); af.modifier = -2; af.location = APPLY_DEX; affect_to_char(ch, &af); char_puts("The strength of the dragon enters you.\n", ch); act("$n looks a bit meaner now.", ch, NULL, NULL, TO_ROOM); } void spell_dragon_breath(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; dam = dice(level , 6); if (!is_safe_spell(ch, victim, TRUE)) { if (saves_spell(level, victim, DAM_FIRE)) dam /= 2; damage(ch, victim, dam, sn, DAM_FIRE, TRUE); } } void spell_golden_aura(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; CHAR_DATA *vch = vo; for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room) { if (!is_same_group(vch, ch)) continue; if (is_affected(vch, sn) || is_affected(vch, gsn_bless) || IS_AFFECTED(vch, AFF_PROTECT_EVIL)) { if (vch == ch) char_puts("You are already protected by a golden aura.\n",ch); else act("$N is already protected by a golden aura.",ch,NULL,vch,TO_CHAR); continue; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 6 + level; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_PROTECT_EVIL; affect_to_char(vch, &af); af.modifier = level/8; af.location = APPLY_HITROLL; af.bitvector = 0; affect_to_char(vch, &af); af.modifier = 0 - level/8; af.location = APPLY_SAVING_SPELL; affect_to_char(vch, &af); char_puts("You feel a golden aura around you.\n", vch); if (ch != vch) act("A golden aura surrounds $N.",ch,NULL,vch,TO_CHAR); } } void spell_dragonplate(int sn, int level, CHAR_DATA *ch, void *vo, int target) { OBJ_DATA *plate; AFFECT_DATA af; plate = create_obj(get_obj_index(OBJ_VNUM_PLATE), 0); plate->level = ch->level; plate->timer = 2 * level; plate->cost = 0; plate->level = ch->level; af.where = TO_OBJECT; af.type = sn; af.level = level; af.duration = -1; af.modifier = level / 8; af.bitvector = 0; af.location = APPLY_HITROLL; affect_to_obj(plate,&af); af.location = APPLY_DAMROLL; affect_to_obj(plate,&af); obj_to_char(plate, ch); act("You create $p!",ch,plate,NULL,TO_CHAR); act("$n creates $p!",ch,plate,NULL,TO_ROOM); } void spell_squire(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *gch; CHAR_DATA *squire; AFFECT_DATA af; int i; if (is_affected(ch, sn)) { char_puts("You cannot command another squire right now.\n", ch); return; } char_puts("You attempt to summon a squire.\n",ch); act("$n attempts to summon a squire.", ch, NULL, NULL, TO_ROOM); for (gch = npc_list; gch; gch = gch->next) { if (IS_AFFECTED(gch, AFF_CHARM) && gch->master == ch && gch->pIndexData->vnum == MOB_VNUM_SQUIRE) { char_puts("Two squires are more than you need!\n",ch); return; } } squire = create_mob(get_mob_index(MOB_VNUM_SQUIRE)); for (i=0;i < MAX_STATS; i++) squire->perm_stat[i] = ch->perm_stat[i]; squire->max_hit = ch->max_hit; squire->hit = squire->max_hit; squire->max_mana = ch->max_mana; squire->mana = squire->max_mana; squire->level = ch->level; for (i=0; i < 3; i++) squire->armor[i] = interpolate(squire->level,100,-100); squire->armor[3] = interpolate(squire->level,100,0); squire->gold = 0; squire->damage[DICE_NUMBER] = number_range(level/20, level/15); squire->damage[DICE_TYPE] = number_range(level/4, level/3); squire->damage[DICE_BONUS] = number_range(level/10, level/8); char_puts("A squire arrives from nowhere!\n",ch); act("A squire arrives from nowhere!",ch,NULL,NULL,TO_ROOM); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); squire->master = squire->leader = ch; char_to_room(squire,ch->in_room); } void spell_dragonsword(int sn, int level, CHAR_DATA *ch, void *vo, int target) { int sword_vnum; OBJ_DATA *sword; char arg[MAX_INPUT_LENGTH]; AFFECT_DATA af; target_name = one_argument(target_name, arg, sizeof(arg)); sword_vnum = 0; if (!str_cmp(arg, "sword")) sword_vnum = OBJ_VNUM_DRAGONSWORD; else if (!str_cmp(arg, "mace")) sword_vnum = OBJ_VNUM_DRAGONMACE; else if (!str_cmp(arg, "dagger")) sword_vnum = OBJ_VNUM_DRAGONDAGGER; else if (!str_cmp(arg, "lance")) sword_vnum = OBJ_VNUM_DRAGONLANCE; else { char_puts("You can't make a DragonSword like that!", ch); return; } sword = create_obj(get_obj_index(sword_vnum), 0); sword->level = ch->level; sword->timer = level * 2; sword->cost = 0; if (ch->level < 50) sword->value[2] = (ch->level / 10); else sword->value[2] = (ch->level / 6) - 3; sword->level = ch->level; af.where = TO_OBJECT; af.type = sn; af.level = level; af.duration = -1; af.modifier = level / 5; af.bitvector = 0; af.location = APPLY_HITROLL; affect_to_obj(sword,&af); af.location = APPLY_DAMROLL; affect_to_obj(sword,&af); if (IS_GOOD(ch)) SET_BIT(sword->extra_flags,(ITEM_ANTI_NEUTRAL | ITEM_ANTI_EVIL)); else if (IS_NEUTRAL(ch)) SET_BIT(sword->extra_flags,(ITEM_ANTI_GOOD | ITEM_ANTI_EVIL)); else if (IS_EVIL(ch)) SET_BIT(sword->extra_flags,(ITEM_ANTI_NEUTRAL | ITEM_ANTI_GOOD)); obj_to_char(sword, ch); act("You create $p!",ch,sword,NULL,TO_CHAR); act("$n creates $p!",ch,sword,NULL,TO_ROOM); } void spell_entangle(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; if (ch->in_room->sector_type == SECT_INSIDE || ch->in_room->sector_type == SECT_CITY || ch->in_room->sector_type == SECT_DESERT || ch->in_room->sector_type == SECT_AIR) { char_puts("No plants can grow here.\n", ch); return; } dam = number_range(level, 4 * level); if (saves_spell(level, victim, DAM_PIERCE)) dam /= 2; damage(ch, victim, dam, sn, DAM_PIERCE, TRUE); if (JUST_KILLED(victim)) return; act("The thorny plants spring up around $n, entangling $s legs!", victim, NULL, NULL, TO_ROOM); act("The thorny plants spring up around you, entangling your legs!", victim, NULL, NULL, TO_CHAR); if (saves_spell(level+2, victim, DAM_PIERCE)) victim->move = victim->move / 3; else victim->move = 0; if (!is_affected(victim, sn)) { AFFECT_DATA todex; todex.type = sn; todex.level = level; todex.duration = level / 10; todex.location = APPLY_DEX; todex.modifier = -1; todex.bitvector = 0; affect_to_char(victim, &todex); } } void spell_holy_armor(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (is_affected(ch, sn)) { char_puts("You are already protected from harm.",ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_AC; af.modifier = - UMAX(10, 10 * (level / 5)); af.bitvector = 0; affect_to_char(ch, &af); act("$n is protected from harm.",ch,NULL,NULL,TO_ROOM); char_puts("Your are protected from harm.\n", ch); } void spell_love_potion(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 50; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); char_puts("You feel like looking at people.\n", ch); } void spell_protective_shield(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (is_affected(victim, sn)) { if (victim == ch) char_puts("You are already surrounded by a protective shield.\n", ch); else act("$N is already surrounded by a protective shield.",ch,NULL, victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = number_fuzzy(level / 30) + 3; af.location = APPLY_AC; af.modifier = 20; af.bitvector = 0; affect_to_char(victim, &af); act("$n is surrounded by a protective shield.",victim,NULL,NULL,TO_ROOM); char_puts("You are surrounded by a protective shield.\n", victim); return; } void spell_deafen(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (ch == victim) { char_puts("Deafen who?\n",ch); return; } if (is_affected(victim,sn)) { act("$N is already deaf.",ch,NULL,victim,TO_CHAR); return; } if (is_safe_nomessage(ch,victim)) { char_puts("You cannot deafen that person.\n",ch); return; } if (saves_spell(level,victim, DAM_NONE)) return; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 10; af.modifier = 0; af.location = 0; af.bitvector = 0; affect_to_char(victim,&af); act("You have deafened $N!",ch,NULL,victim,TO_CHAR); char_puts("A loud ringing fills your ears...you can't hear anything!\n", victim); } void spell_disperse(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *vch; CHAR_DATA *vch_next; AFFECT_DATA af; if (is_affected(ch, sn)) { char_puts("You aren't up to dispersing this crowd.\n",ch); return; } for (vch = ch->in_room->people; vch; vch = vch_next) { vch_next = vch->next_in_room; if (vch == ch || !vch->in_room || IS_SET(vch->in_room->room_flags, ROOM_NORECALL) || IS_SET(vch->imm_flags, IMM_SUMMON) || IS_IMMORTAL(vch)) continue; if (IS_NPC(vch)) { if (IS_SET(vch->pIndexData->act, ACT_AGGRESSIVE)) continue; } else { if (is_safe_nomessage(ch, vch)) continue; } transfer_char(vch, NULL, get_random_room(vch, NULL), "$N vanishes!", "The world spins around you!", "$N slowly fades into existence."); } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 15; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = 0; affect_to_char(ch, &af); } void spell_honor_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)) { if (victim == ch) char_puts("But you're already protected by your honor.\n", ch); else char_puts("They're already protected by their honor.\n", ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.modifier = -30; af.location = APPLY_AC; af.bitvector = 0; affect_to_char(victim, &af); spell_remove_curse(sn_lookup("remove curse"), level, ch, victim, TARGET_CHAR); spell_bless(sn_lookup("bless"), level, ch, victim, TARGET_CHAR); char_puts("Your honor protects you.\n", victim); act("$n's Honor protects $m.", victim, NULL, NULL, TO_ROOM); } void spell_acute_vision(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_AFFECTED(victim, AFF_ACUTE_VISION)) { if (victim == ch) char_puts("Your vision is already acute. \n",ch); else act("$N already sees acutely.", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 3 + level / 5; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_ACUTE_VISION; affect_to_char(victim, &af); char_puts("Your vision sharpens.\n", victim); if (ch != victim) char_puts("Ok.\n", ch); } void spell_dragons_breath(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; CHAR_DATA *vch, *vch_next; int dam,hp_dam,dice_dam; int hpch; act("You call the dragon lord to help you.", ch, NULL, NULL, TO_CHAR); act("$n start to breath like a dragon.", ch, NULL, victim, TO_NOTVICT); act("$n breath disturbs you!", ch, NULL, victim, TO_VICT); act("You breath the breath of lord of Dragons.", ch, NULL, NULL, TO_CHAR); hpch = UMAX(10, ch->hit); hp_dam = number_range(hpch/9+1, hpch/5); dice_dam = dice(level,20); dam = UMAX(hp_dam + dice_dam / 5, dice_dam + hp_dam / 5); switch(dice(1, 5)) { case 1: fire_effect(victim->in_room, level, dam/2, TARGET_ROOM); for (vch = victim->in_room->people; vch; vch = vch_next) { vch_next = vch->next_in_room; if (is_safe_spell(ch, vch, TRUE) || (IS_NPC(vch) && IS_NPC(ch) && (ch->fighting != vch || vch->fighting != ch))) continue; if (vch == victim) { /* full damage */ if (saves_spell(level,vch,DAM_FIRE)) { fire_effect(vch,level/2,dam/4,TARGET_CHAR); damage(ch,vch,dam/2,sn,DAM_FIRE,TRUE); } else { fire_effect(vch,level,dam,TARGET_CHAR); damage(ch,vch,dam,sn,DAM_FIRE,TRUE); } } else /* partial damage */ { if (saves_spell(level - 2,vch,DAM_FIRE)) { fire_effect(vch,level/4,dam/8,TARGET_CHAR); damage(ch,vch,dam/4,sn,DAM_FIRE,TRUE); } else { fire_effect(vch,level/2,dam/4,TARGET_CHAR); damage(ch,vch,dam/2,sn,DAM_FIRE,TRUE); } } } break; case 2: if (saves_spell(level,victim,DAM_ACID)) { acid_effect(victim, level/2, dam/4, TARGET_CHAR); damage(ch, victim, dam/2, sn, DAM_ACID,TRUE); } else { acid_effect(victim, level, dam, TARGET_CHAR); damage(ch, victim, dam, sn, DAM_ACID,TRUE); } break; case 3: cold_effect(victim->in_room, level, dam/2, TARGET_ROOM); for (vch = victim->in_room->people; vch; vch = vch_next) { vch_next = vch->next_in_room; if (is_safe_spell(ch, vch, TRUE) || (IS_NPC(vch) && IS_NPC(ch) && (ch->fighting != vch || vch->fighting != ch))) continue; if (vch == victim) /* full damage */ { if (saves_spell(level,vch,DAM_COLD)) { cold_effect(vch,level/2,dam/4,TARGET_CHAR); damage(ch,vch,dam/2,sn,DAM_COLD,TRUE); } else { cold_effect(vch,level,dam,TARGET_CHAR); damage(ch,vch,dam,sn,DAM_COLD,TRUE); } } else { if (saves_spell(level - 2,vch,DAM_COLD)) { cold_effect(vch,level/4,dam/8,TARGET_CHAR); damage(ch,vch,dam/4,sn,DAM_COLD,TRUE); } else { cold_effect(vch,level/2,dam/4,TARGET_CHAR); damage(ch,vch,dam/2,sn,DAM_COLD,TRUE); } } } break; case 4: poison_effect(ch->in_room, level, dam, TARGET_ROOM); for (vch = ch->in_room->people; vch; vch = vch_next) { vch_next = vch->next_in_room; if (is_safe_spell(ch,vch,TRUE) || (IS_NPC(ch) && IS_NPC(vch) && (ch->fighting == vch || vch->fighting == ch))) continue; if (saves_spell(level,vch,DAM_POISON)) { poison_effect(vch,level/2,dam/4,TARGET_CHAR); damage(ch,vch,dam/2,sn,DAM_POISON,TRUE); } else { poison_effect(vch,level,dam,TARGET_CHAR); damage(ch,vch,dam,sn,DAM_POISON,TRUE); } } break; case 5: if (saves_spell(level, victim, DAM_LIGHTNING)) { shock_effect(victim, level/2, dam/4, TARGET_CHAR); damage(ch, victim, dam/2, sn, DAM_LIGHTNING, TRUE); } else { shock_effect(victim, level, dam, TARGET_CHAR); damage(ch, victim, dam, sn, DAM_LIGHTNING, TRUE); } break; } } void spell_sand_storm(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *vch, *vch_next; int dam,hp_dam,dice_dam; int hpch; if ((ch->in_room->sector_type == SECT_AIR) || (ch->in_room->sector_type == SECT_WATER_SWIM) || (ch->in_room->sector_type == SECT_WATER_NOSWIM)) { char_puts("You don't find any sand here to make storm.\n",ch); ch->wait = 0; return; } act("$n creates a storm with sands on the floor.",ch,NULL,NULL,TO_ROOM); act("You create the ..sand.. storm.",ch,NULL,NULL,TO_CHAR); hpch = UMAX(10, ch->hit); hp_dam = number_range(hpch/9+1, hpch/5); dice_dam = dice(level,20); dam = UMAX(hp_dam + dice_dam /10, dice_dam + hp_dam / 10); sand_effect(ch->in_room,level,dam/2,TARGET_ROOM); for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; if (is_safe_spell(ch,vch,TRUE) || (IS_NPC(vch) && IS_NPC(ch) && (ch->fighting != vch /*|| vch->fighting != ch*/))) continue; if (saves_spell(level,vch,DAM_COLD)) { sand_effect(vch,level/2,dam/4,TARGET_CHAR); damage(ch,vch,dam/2,sn,DAM_COLD,TRUE); } else { sand_effect(vch,level,dam,TARGET_CHAR); damage(ch,vch,dam,sn,DAM_COLD,TRUE); } } } void spell_scream(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *vch, *vch_next; int dam=0,hp_dam,dice_dam; int hpch; act("$n screams with a disturbing NOISE!.",ch,NULL,NULL,TO_ROOM); act("You scream with a powerful sound.",ch,NULL,NULL,TO_CHAR); hpch = UMAX(10, ch->hit); hp_dam = number_range(hpch/9+1, hpch/5); dice_dam = dice(level,20); dam = UMAX(hp_dam + dice_dam /10 , dice_dam + hp_dam /10); scream_effect(ch->in_room,level,dam/2,TARGET_ROOM); for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; if (is_safe_spell(ch,vch,TRUE)) continue; if (saves_spell(level,vch,DAM_ENERGY)) { scream_effect(vch,level/2,dam/4,TARGET_CHAR); /* damage(ch,vch,dam/2,sn,DAM_ENERGY,TRUE); */ if (vch->fighting) stop_fighting(vch , TRUE); } else { scream_effect(vch,level,dam,TARGET_CHAR); /* damage(ch,vch,dam,sn,DAM_ENERGY,TRUE); */ if (vch->fighting) stop_fighting(vch , TRUE); } } } void spell_attract_other(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; if (ch->sex == victim->sex) { char_puts("You'd better try your chance on other sex!\n", ch); return; } spell_charm_person(sn, level+2, ch, vo, target); } static void cb_strip(int lang, const char **p, void *arg) { char buf[MAX_STRING_LENGTH]; const char *r = mlstr_val((mlstring*) arg, lang); const char *q; if (IS_NULLSTR(*p) || (q = strstr(r, "%s")) == NULL) return; strnzncpy(buf, sizeof(buf), r, q-r); if (!str_prefix(buf, *p)) { const char *s = strdup(*p + strlen(buf)); free_string(*p); *p = s; } } void spell_animate_dead(int sn,int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim; CHAR_DATA *undead; OBJ_DATA *obj,*obj2,*next; AFFECT_DATA af; int i; int chance; int u_level; /* deal with the object case first */ if (target == TARGET_OBJ) { MOB_INDEX_DATA *undead_idx; mlstring *ml; obj = (OBJ_DATA *) vo; if (!(obj->pIndexData->item_type == ITEM_CORPSE_NPC || obj->pIndexData->item_type == ITEM_CORPSE_PC)) { char_puts("You can animate only corpses!\n", ch); return; } if (is_affected(ch, sn)) { char_puts("You cannot summon the strength " "to handle more undead bodies.\n", ch); return; } if (count_charmed(ch)) return; if (ch->in_room != NULL && IS_SET(ch->in_room->room_flags, ROOM_NOMOB)) { char_puts("You can't animate deads here.\n", ch); return; } /* can't animate PC corpses in ROOM_BATTLE_ARENA */ if (obj->pIndexData->item_type == ITEM_CORPSE_PC && obj->in_room && IS_SET(obj->in_room->room_flags, ROOM_BATTLE_ARENA) && !IS_OWNER(ch, obj)) { char_puts("You cannot do that.\n", ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_SAFE | ROOM_PEACE | ROOM_PRIVATE | ROOM_SOLITARY)) { char_puts("You can't animate here.\n", ch); return; } chance = URANGE(5, get_skill(ch, sn)+(level-obj->level)*7, 95); if (number_percent() > chance) { act_puts("You failed and destroyed it.\n", ch, NULL, NULL, TO_CHAR, POS_DEAD); act("$n tries to animate $p, but fails and destroys it.", ch, obj, NULL, TO_ROOM); for (obj2 = obj->contains; obj2; obj2 = next) { next = obj2->next_content; obj_from_obj(obj2); obj_to_room(obj2, ch->in_room); } extract_obj(obj, 0); return; } undead_idx = get_mob_index(MOB_VNUM_UNDEAD); ml = mlstr_dup(obj->owner); /* * strip "The undead body of " */ mlstr_for_each(&ml, undead_idx->short_descr, cb_strip); undead = create_mob_of(undead_idx, ml); mlstr_free(ml); for (i = 0; i < MAX_STATS; i++) undead->perm_stat[i] = UMIN(25, 15+obj->level/10); u_level = UMIN (obj->level, level+((obj->level-level)/3)*2); undead->max_hit = dice(20,u_level*2)+u_level*20; undead->hit = undead->max_hit; undead->max_mana = dice(u_level,10)+100; undead->mana = undead->max_mana; undead->alignment = -1000; undead->level = u_level; for (i = 0; i < 3; i++) undead->armor[i] = interpolate(undead->level,100,-100); undead->armor[3] = interpolate(undead->level, 50, -200); undead->sex = ch->sex; undead->gold = 0; undead->damage[DICE_NUMBER] = 11; undead->damage[DICE_TYPE] = 5; undead->damage[DICE_BONUS] = u_level/2 +10; undead->master = ch; undead->leader = ch; undead->name = str_printf(undead->name, obj->name); for (obj2 = obj->contains; obj2; obj2 = next) { next = obj2->next_content; obj_from_obj(obj2); obj_to_char(obj2, undead); } af.where = TO_AFFECTS; af.type = sn; af.level = ch->level; af.duration = (ch->level / 10); af.modifier = 0; af.bitvector = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); act_puts("With mystic power, you animate it!", ch, NULL, NULL, TO_CHAR, POS_DEAD); act("With mystic power, $n animates $p!", ch, obj, NULL, TO_ROOM); act_puts("$N looks at you and plans to make you " "pay for distrurbing its rest!", ch, NULL, undead, TO_CHAR, POS_DEAD); extract_obj(obj, 0); char_to_room(undead, ch->in_room); if (!JUST_KILLED(undead)) do_wear(undead, "all"); return; } victim = (CHAR_DATA *) vo; if (victim == ch) { char_puts("But you aren't dead!!\n", ch); return; } char_puts("But it ain't dead!!\n", ch); return; } void spell_enhanced_armor(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (is_affected(victim, sn)) { if (victim == ch) char_puts("You are already enhancedly armored.\n",ch); else act("$N is already enhancedly armored.",ch,NULL,victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.modifier = -60; af.location = APPLY_AC; af.bitvector = 0; affect_to_char(victim, &af); char_puts("You feel protected from all attacks.\n", victim); if (ch != victim) act("$N is protected by your magic.",ch,NULL,victim,TO_CHAR); return; } void spell_meld_into_stone(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (is_affected(victim, sn)) { if (victim == ch) char_puts("Your skin is already covered with stone.\n", ch); else act("$N's skin is already covered with stone.",ch,NULL, victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 10; af.location = APPLY_AC; af.modifier = -100; af.bitvector = 0; affect_to_char(victim, &af); act("$n's skin melds into stone.",victim,NULL,NULL,TO_ROOM); char_puts("Your skin melds into stone.\n", victim); return; } void spell_web(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)) return; if (is_affected(victim, sn)) { if (victim == ch) char_puts("You are already webbed.\n",ch); else act("$N is already webbed.",ch,NULL,victim,TO_CHAR); return; } af.type = sn; af.level = level; af.duration = 1; af.location = APPLY_HITROLL; af.modifier = -1 * (level / 6); af.where = TO_AFFECTS; af.bitvector = AFF_DETECT_WEB; affect_to_char(victim, &af); af.location = APPLY_DEX; af.modifier = -2; affect_to_char(victim, &af); af.location = APPLY_DAMROLL; af.modifier = -1 * (level / 6); affect_to_char(victim, &af); char_puts("You are emeshed in thick webs!\n", victim); if (ch != victim) act("You emesh $N in a bundle of webs!",ch,NULL,victim,TO_CHAR); return; } void spell_group_defense(int sn, int level, CHAR_DATA *ch, void *vo , int target) { CHAR_DATA *gch; AFFECT_DATA af; int shield_sn, armor_sn; shield_sn = sn_lookup("shield"); armor_sn = sn_lookup("armor"); for(gch=ch->in_room->people; gch != NULL; gch=gch->next_in_room) { if(!is_same_group(gch, ch)) continue; if(is_affected(gch, armor_sn)) { if(gch == ch) char_puts("You are already armored.\n",ch); else act("$N is already armored.", ch, NULL, gch, TO_CHAR); continue; } af.type = armor_sn; af.level = level; af.duration = level; af.location = APPLY_AC; af.modifier = -20; af.bitvector = 0; affect_to_char(gch, &af); char_puts("You feel someone protecting you.\n",gch); if(ch != gch) act("$N is protected by your magic.", ch, NULL, gch, TO_CHAR); if(!is_same_group(gch, ch)) continue; if(is_affected(gch, shield_sn)) { if(gch == ch) char_puts("You are already shielded.\n",ch); else act("$N is already shielded.", ch, NULL, gch, TO_CHAR); continue; } af.type = shield_sn; af.level = level; af.duration = level; af.location = APPLY_AC; af.modifier = -20; af.bitvector = 0; affect_to_char(gch, &af); char_puts("You are surrounded by a force shield.\n",gch); if(ch != gch) act("$N is surrounded by a force shield.", ch, NULL, gch, TO_CHAR); } } void spell_inspire(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *gch; AFFECT_DATA af; int bless_sn; bless_sn = sn_lookup("bless"); for(gch=ch->in_room->people; gch != NULL; gch=gch->next_in_room) { if(!is_same_group(gch, ch)) continue; if (is_affected(gch, bless_sn)) { if(gch == ch) char_puts("You are already inspired.\n",ch); else act("$N is already inspired.", ch, NULL, gch, TO_CHAR); continue; } af.type = bless_sn; af.level = level; af.duration = 6 + level; af.location = APPLY_HITROLL; af.modifier = level/12; af.bitvector = 0; affect_to_char(gch, &af); af.location = APPLY_SAVING_SPELL; af.modifier = 0 - level/12; affect_to_char(gch, &af); char_puts("You feel inspired!\n", gch); if(ch != gch) act("You inspire $N with the Creator's power!", ch, NULL, gch, TO_CHAR); } } void spell_mass_sanctuary(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *gch; for (gch = ch->in_room->people; gch; gch = gch->next_in_room) { if (is_same_group(ch, gch)) { spell_sanctuary(gsn_sanctuary, level, ch, (void*) gch, TARGET_CHAR); } } } void spell_mend(int sn, int level, CHAR_DATA *ch, void *vo, int target) { OBJ_DATA *obj = (OBJ_DATA *) vo; int result,skill; if (obj->condition > 99) { char_puts("That item is not in need of mending.\n",ch); return; } if (obj->wear_loc != -1) { char_puts("The item must be carried to be mended.\n",ch); return; } skill = get_skill(ch,gsn_mend) / 2; result = number_percent () + skill; if (IS_OBJ_STAT(obj,ITEM_GLOW)) result -= 5; if (IS_OBJ_STAT(obj,ITEM_MAGIC)) result += 5; if (result >= 50) { act("$p glows brightly, and is whole again. Good Job!",ch,obj,NULL,TO_CHAR); act("$p glows brightly, and is whole again.",ch,obj,NULL,TO_ROOM); obj->condition += result; obj->condition = UMIN(obj->condition , 100); return; } else if (result >=10) { char_puts("Nothing seemed to happen.\n",ch); return; } else { act("$p flares blindingly... and evaporates!",ch,obj,NULL,TO_CHAR); act("$p flares blindingly... and evaporates!",ch,obj,NULL,TO_ROOM); extract_obj(obj, 0); return; } } void spell_shielding(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_NONE)) { act("$N shivers slightly, but it passes quickly.", ch, NULL, victim, TO_CHAR); char_puts("You shiver slightly, but it passes quickly.\n", victim); return; } if (is_affected(victim, sn)) { af.type = sn; af.level = level; af.duration = level / 20; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = 0; affect_to_char(victim, &af); act("You wrap $N in more flows of Spirit.", ch, NULL, victim, TO_CHAR); char_puts("You feel the shielding get stronger.\n",victim); return; } af.type = sn; af.level = level; af.duration = level / 15; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = 0; affect_join(victim, &af); char_puts("You feel as if you have lost touch with something.\n", victim); act("You shield $N from the True Source.", ch, NULL, victim, TO_CHAR); } void spell_link(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int random, tmpmana; random = number_percent (); tmpmana = ch->mana; ch->mana = 0; ch->endur /= 2; tmpmana = (.5 * tmpmana); tmpmana = ((tmpmana + random)/2); victim->mana = victim->mana + tmpmana; } void spell_power_word_kill(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; act_puts("A stream of darkness from your finger surrounds $N.", ch, NULL, victim, TO_CHAR, POS_RESTING); act_puts("A stream of darkness from $n's finger surrounds $N.", ch, NULL, victim, TO_NOTVICT, POS_RESTING); act_puts("A stream of darkness from $N's finger surrounds you.", victim, NULL, ch, TO_CHAR, POS_RESTING); if (saves_spell(level-2, victim, DAM_MENTAL) || IS_IMMORTAL(victim) || IS_CLAN_GUARD(victim)) { dam = dice(level , 24) ; damage(ch, victim , dam , sn, DAM_MENTAL, TRUE); return; } char_puts("You have been KILLED!\n", victim); act("$N has been killed!\n", ch, NULL, victim, TO_CHAR); act("$N has been killed!\n", ch, NULL, victim, TO_ROOM); raw_kill(ch, victim); return; } void spell_eyed_sword(int sn, int level, CHAR_DATA *ch, void *vo, int target) { OBJ_DATA *eyed; int i; /* if (IS_SET(ch->quest,QUEST_EYE) { char_puts("You created your sword ,before.\n",ch); return; } SET_BIT(ch->quest,QUEST_EYE); */ if (IS_GOOD(ch)) i=0; else if (IS_EVIL(ch)) i=2; else i = 1; eyed = create_obj_of(get_obj_index(OBJ_VNUM_EYED_SWORD), ch->short_descr); eyed->level = ch->level; eyed->owner = mlstr_dup(ch->short_descr); eyed->ed = ed_new2(eyed->pIndexData->ed, ch->name); eyed->value[2] = (ch->level / 10) + 3; eyed->cost = 0; obj_to_char(eyed, ch); char_puts("You create YOUR sword with your name.\n",ch); char_puts("Don't forget that you won't be able to create this weapon anymore.\n",ch); } void spell_lion_help(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *lion; CHAR_DATA *victim; AFFECT_DATA af; char arg[MAX_INPUT_LENGTH]; int i; target_name = one_argument(target_name, arg, sizeof(arg)); if (arg[0] == '\0') { char_puts("Whom do you want to have killed.\n",ch); return; } if ((victim = get_char_area(ch,arg)) == NULL) { char_puts("Noone around with that name.\n", ch); return; } if (is_safe_nomessage(ch, victim)) { char_puts("God protects your victim.\n", ch); return; } char_puts("You call for a hunter lion.\n", ch); act("$n shouts a hunter lion.", ch, NULL, NULL, TO_ROOM); if (is_affected(ch, sn)) { char_puts("You cannot summon the strength to handle more " "lions right now.\n", ch); return; } if (ch->in_room != NULL && IS_SET(ch->in_room->room_flags, ROOM_NOMOB)) { char_puts("No lions can listen you.\n", ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_SAFE | ROOM_PEACE | ROOM_PRIVATE | ROOM_SOLITARY) || (ch->in_room->exit[0] == NULL && ch->in_room->exit[1] == NULL && ch->in_room->exit[2] == NULL && ch->in_room->exit[3] == NULL && ch->in_room->exit[4] == NULL && ch->in_room->exit[5] == NULL) || (ch->in_room->sector_type != SECT_FIELD && ch->in_room->sector_type != SECT_FOREST && ch->in_room->sector_type != SECT_MOUNTAIN && ch->in_room->sector_type != SECT_HILLS)) { char_puts("No hunter lion can come to you.\n", ch); return; } lion = create_mob(get_mob_index(MOB_VNUM_HUNTER)); for (i=0;i < MAX_STATS; i++) lion->perm_stat[i] = UMIN(25,2 * ch->perm_stat[i]); lion->max_hit = UMIN(30000,ch->max_hit * 1.2); lion->hit = lion->max_hit; lion->max_mana = ch->max_mana; lion->mana = lion->max_mana; lion->alignment = ch->alignment; lion->level = UMIN(100,ch->level); for (i=0; i < 3; i++) lion->armor[i] = interpolate(lion->level,100,-100); lion->armor[3] = interpolate(lion->level,100,0); lion->sex = ch->sex; lion->gold = 0; lion->damage[DICE_NUMBER] = number_range(level/15, level/10); lion->damage[DICE_TYPE] = number_range(level/3, level/2); lion->damage[DICE_BONUS] = number_range(level/8, level/6); char_puts("A hunter lion comes to kill your victim!\n", ch); act("A hunter lion comes to kill $n's victim!", ch, NULL, NULL, TO_ROOM); af.where = TO_AFFECTS; af.type = sn; af.level = ch->level; af.duration = 24; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); lion->hunting = victim; char_to_room(lion, ch->in_room); if (!JUST_KILLED(lion)) return; hunt_victim(lion); } void spell_magic_jar(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; OBJ_DATA *vial; OBJ_DATA *fire; int i; if (victim == ch) { char_puts("You like yourself even better.\n",ch); return; } if (IS_NPC(victim)) { char_puts("Your victim is a npc. Not necessary!.\n",ch); return; } if (saves_spell(level ,victim,DAM_MENTAL)) { char_puts("You failed.\n",ch); return; } for(vial=ch->carrying; vial != NULL; vial=vial->next_content) if (vial->pIndexData->vnum == OBJ_VNUM_POTION_VIAL) break; if ( vial == NULL) { char_puts("You don't have any vials to put your victim's spirit.\n" , ch); return; } extract_obj(vial, 0); if (IS_GOOD(ch)) i=0; else if (IS_EVIL(ch)) i=2; else i = 1; fire = create_obj_of(get_obj_index(OBJ_VNUM_MAGIC_JAR), victim->short_descr); fire->level = ch->level; fire->owner = mlstr_dup(ch->short_descr); fire->ed = ed_new2(fire->pIndexData->ed, victim->name); fire->cost = 0; obj_to_char(fire , ch); SET_BIT(victim->plr_flags, PLR_NOEXP); char_printf(ch,"You catch %s's spirit in to your vial.\n", victim->name); } DO_FUN(do_flee); void turn_spell(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam, align; if (IS_EVIL(ch)) { victim = ch; char_puts("The energy explodes inside you!\n", ch); } if (victim != ch) { act("$n raises $s hand, and a blinding ray of light " "shoots forth!", ch, NULL, NULL, TO_ROOM); char_puts("You raise your hand and a blinding ray of light " "shoots forth!\n", ch); } if (IS_GOOD(victim) || IS_NEUTRAL(victim)) { act("$n seems unharmed by the light.", victim, NULL, victim, TO_ROOM); char_puts("The light seems powerless to affect you.\n", victim); return; } dam = dice(level, 10); if (saves_spell(level, victim, DAM_HOLY)) dam /= 2; align = victim->alignment; align -= 350; if (align < -1000) align = -1000 + (align + 1000) / 3; dam = (dam * align * align) / 1000000; damage(ch, victim, dam, sn, DAM_HOLY, TRUE); if (!JUST_KILLED(victim)) do_flee(victim, str_empty); } void spell_turn(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *vch; CHAR_DATA *vch_next; AFFECT_DATA af; if (is_affected(ch, sn)) { char_puts("This power is used too recently.",ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 5; af.modifier = 0; af.location = 0; af.bitvector = 0; affect_to_char(ch, &af); for (vch = ch->in_room->people; vch; vch = vch_next) { vch_next = vch->next_in_room; if (is_safe_spell(ch, vch, TRUE)) continue; turn_spell(sn, ch->level, ch, vch, target); } } void spell_fear(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; class_t *vcl; if ((vcl = class_lookup(victim->class)) && !CAN_FLEE(victim, vcl)) { if (victim == ch) char_puts("You are beyond this power.\n", ch); else char_puts("Your victim is beyond this power.\n", ch); return; } if (is_affected(victim,gsn_fear) || saves_spell(level, victim,DAM_OTHER)) return; af.where = TO_AFFECTS; af.type = gsn_fear; af.level = level; af.duration = level / 10; af.location = 0; af.modifier = 0; af.bitvector = AFF_DETECT_FEAR; affect_to_char(victim, &af); char_puts("You are afraid as much as a rabbit.\n", victim); act("$n looks with afraid eyes.", victim, NULL, NULL, TO_ROOM); } void spell_protection_heat (int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (is_affected(victim, gsn_protection_heat)) { if (victim == ch) char_puts("You are already protected from heat.\n",ch); else act("$N is already protected from heat.",ch,NULL,victim,TO_CHAR); return; } if (is_affected(victim, gsn_protection_cold)) { if (victim == ch) char_puts("You are already protected from cold.\n",ch); else act("$N is already protected from cold.",ch,NULL,victim,TO_CHAR); return; } if (is_affected(victim, gsn_fire_shield)) { if (victim == ch) char_puts("You are already using fire shield.\n",ch); else act("$N is already using fire shield.",ch,NULL,victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = gsn_protection_heat; af.level = level; af.duration = 24; af.location = APPLY_SAVING_SPELL; af.modifier = -1; af.bitvector = 0; affect_to_char(victim, &af); char_puts("You feel strengthed against heat.\n", victim); if (ch != victim) act("$N is protected against heat.",ch,NULL,victim,TO_CHAR); return; } void spell_protection_cold (int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (is_affected(victim, gsn_protection_cold)) { if (victim == ch) char_puts("You are already protected from cold.\n",ch); else act("$N is already protected from cold.",ch,NULL,victim,TO_CHAR); return; } if (is_affected(victim, gsn_protection_heat)) { if (victim == ch) char_puts("You are already protected from heat.\n",ch); else act("$N is already protected from heat.",ch,NULL,victim,TO_CHAR); return; } if (is_affected(victim, gsn_fire_shield)) { if (victim == ch) char_puts("You are already using fire shield.\n",ch); else act("$N is already using fire shield.",ch,NULL,victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = gsn_protection_cold; af.level = level; af.duration = 24; af.location = APPLY_SAVING_SPELL; af.modifier = -1; af.bitvector = 0; affect_to_char(victim, &af); char_puts("You feel strengthed against cold.\n", victim); if (ch != victim) act("$N is protected against cold.",ch,NULL,victim,TO_CHAR); return; } void spell_fire_shield (int sn, int level, CHAR_DATA *ch, void *vo, int target) { OBJ_INDEX_DATA *pObjIndex; char arg[MAX_INPUT_LENGTH]; OBJ_DATA *fire; int i; target_name = one_argument(target_name, arg, sizeof(arg)); if (str_cmp(arg, "cold") && str_cmp(arg, "fire")) { char_puts("You must specify the type.\n",ch); return; } if (IS_GOOD(ch)) i = 0; else if (IS_EVIL(ch)) i = 2; else i = 1; pObjIndex = get_obj_index(OBJ_VNUM_FIRE_SHIELD); fire = create_obj(pObjIndex, 0); fire->level = ch->level; name_add(&fire->name, arg, NULL, NULL); fire->owner = mlstr_dup(ch->short_descr); fire->ed = ed_new2(fire->pIndexData->ed, arg); fire->cost = 0; fire->timer = 5 * ch->level ; if (IS_GOOD(ch)) SET_BIT(fire->extra_flags,(ITEM_ANTI_NEUTRAL | ITEM_ANTI_EVIL)); else if (IS_NEUTRAL(ch)) SET_BIT(fire->extra_flags,(ITEM_ANTI_GOOD | ITEM_ANTI_EVIL)); else if (IS_EVIL(ch)) SET_BIT(fire->extra_flags,(ITEM_ANTI_NEUTRAL | ITEM_ANTI_GOOD)); obj_to_char(fire, ch); char_puts("You create the fire shield.\n",ch); } void spell_witch_curse(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; CHAR_DATA *victim = (CHAR_DATA *) vo; if (is_affected(victim, gsn_witch_curse)) { char_puts("It has already underflowing with health.\n",ch); return; } if (IS_IMMORTAL(victim) || IS_CLAN_GUARD(victim)) { damage(ch, victim, dice(level, 8), sn, DAM_NEGATIVE, TRUE); return; } ch->hit -= (2 * level); af.where = TO_AFFECTS; af.type = gsn_witch_curse; af.level = level; af.duration = 24; af.location = APPLY_HIT; af.modifier = - level; af.bitvector = 0; affect_to_char(victim, &af); act("Now $n got the path to death.", victim, NULL, NULL, TO_ROOM); act("Now you got the path to death.", victim, NULL, NULL, TO_CHAR); } void spell_knock (int sn, int level, CHAR_DATA *ch, void *vo, int target) { char arg[MAX_INPUT_LENGTH]; int chance=0; int door; const int rev_dir [] = { 2, 3, 0, 1, 5, 4 }; target_name = one_argument(target_name, arg, sizeof(arg)); if (arg[0] == '\0') { char_puts("Knock which door or direction.\n",ch); return; } if (ch->fighting) { char_puts("Wait until the fight finishes.\n",ch); return; } if ((door = find_door(ch, arg)) >= 0) { ROOM_INDEX_DATA *to_room; EXIT_DATA *pexit; EXIT_DATA *pexit_rev; pexit = ch->in_room->exit[door]; if (!IS_SET(pexit->exit_info, EX_CLOSED)) { char_puts("It's already open.\n", ch); return; } if (!IS_SET(pexit->exit_info, EX_LOCKED)) { char_puts("Just try to open it.\n", ch); return; } if (IS_SET(pexit->exit_info, EX_NOPASS)) { char_puts("A mystical shield protects the exit.\n",ch); return; } chance = ch->level / 5 + get_curr_stat(ch,STAT_INT) + get_skill(ch,sn) / 5; act("You knock $d, and try to open $d!", ch,NULL,pexit->keyword,TO_CHAR); act("You knock $d, and try to open $d!", ch,NULL,pexit->keyword,TO_ROOM); if (room_dark(ch->in_room)) chance /= 2; /* now the attack */ if (number_percent() < chance) { REMOVE_BIT(pexit->exit_info, EX_LOCKED); REMOVE_BIT(pexit->exit_info, EX_CLOSED); act("$n knocks the the $d and opens the lock.", ch, NULL, pexit->keyword, TO_ROOM); act_puts("You successed to open the door.", ch, NULL, NULL, TO_CHAR, POS_DEAD); /* open the other side */ if ((to_room = pexit->to_room.r ) != NULL && (pexit_rev = to_room->exit[rev_dir[door]]) != NULL && pexit_rev->to_room.r == ch->in_room) { CHAR_DATA *rch; REMOVE_BIT(pexit_rev->exit_info, EX_CLOSED); REMOVE_BIT(pexit_rev->exit_info, EX_LOCKED); for (rch = to_room->people; rch != NULL; rch = rch->next_in_room) act("The $d opens.", rch, NULL, pexit_rev->keyword, TO_CHAR); } } else { act("You couldn't knock the $d!", ch,NULL,pexit->keyword,TO_CHAR); act("$n failed to knock $d.", ch,NULL,pexit->keyword,TO_ROOM); } return; } char_puts("You can't see that here.\n",ch); } void spell_magic_resistance (int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (!is_affected(ch, sn)) { char_puts("You are now resistive to magic.\n", ch); af.where = TO_RESIST; af.type = sn; af.duration = level / 10; af.level = ch->level; af.bitvector = RES_MAGIC; af.location = 0; af.modifier = 0; affect_to_char(ch, &af); } else char_puts("You are already resistive to magic.\n", ch); return; } void spell_hallucination (int sn, int level, CHAR_DATA *ch, void *vo, int target) { char_puts("That spell is under construction.\n",ch); return; } void spell_wolf(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *gch; CHAR_DATA *demon; AFFECT_DATA af; int i; if (is_affected(ch,sn)) { char_puts("You lack the power to summon another wolf right now.\n",ch); return; } char_puts("You attempt to summon a wolf.\n",ch); act("$n attempts to summon a wolf.",ch,NULL,NULL,TO_ROOM); for (gch = npc_list; gch; gch = gch->next) { if (IS_AFFECTED(gch, AFF_CHARM) && gch->master == ch && gch->pIndexData->vnum == MOB_VNUM_WOLF) { char_puts("Two wolfs are more than you can control!\n", ch); return; } } demon = create_mob(get_mob_index(MOB_VNUM_WOLF)); for (i=0;i < MAX_STATS; i++) { demon->perm_stat[i] = ch->perm_stat[i]; } demon->max_hit = IS_NPC(ch)? URANGE(ch->max_hit,1 * ch->max_hit,30000) : URANGE(ch->pcdata->perm_hit,ch->hit,30000); demon->hit = demon->max_hit; demon->max_mana = IS_NPC(ch)? ch->max_mana : ch->pcdata->perm_mana; demon->mana = demon->max_mana; demon->level = ch->level; for (i=0; i < 3; i++) demon->armor[i] = interpolate(demon->level,100,-100); demon->armor[3] = interpolate(demon->level,100,0); demon->gold = 0; demon->timer = 0; demon->damage[DICE_NUMBER] = number_range(level/15, level/10); demon->damage[DICE_TYPE] = number_range(level/3, level/2); demon->damage[DICE_BONUS] = number_range(level/8, level/6); char_puts("The wolf arrives and bows before you!\n",ch); act("A wolf arrives from somewhere and bows!",ch,NULL,NULL,TO_ROOM); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); demon->master = demon->leader = ch; char_to_room(demon,ch->in_room); } void spell_vampiric_blast(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; dam = dice(level, 12); if (saves_spell(level, victim, DAM_ACID)) dam /= 2; damage(ch, victim, dam, sn,DAM_ACID,TRUE); return; } void spell_dragon_skin(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (is_affected(victim, sn)) { if (victim == ch) char_puts("Your skin is already hard as rock.\n", ch); else act("$N's skin is already hard as rock.",ch,NULL, victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_AC; af.modifier = - (2 * level); af.bitvector = 0; affect_to_char(victim, &af); act("$n's skin is now hard as rock.",victim,NULL,NULL,TO_ROOM); char_puts("Your skin is now hard as rock.\n", victim); return; } void spell_mind_light(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af,af2; if (is_affected_room(ch->in_room, sn)) { char_puts("This room has already had booster of mana.\n",ch); return; } af.where = TO_ROOM_CONST; af.type = sn; af.level = level; af.duration = level / 30; af.location = APPLY_ROOM_MANA; af.modifier = level; af.bitvector = 0; affect_to_room(ch->in_room, &af); af2.where = TO_AFFECTS; af2.type = sn; af2.level = level; af2.duration = level / 10; af2.modifier = 0; af2.location = APPLY_NONE; af2.bitvector = 0; affect_to_char(ch, &af2); char_puts("The room starts to be filled with mind light.\n", ch); act("The room starts to be filled with $n's mind light.",ch,NULL,NULL,TO_ROOM); return; } void spell_insanity (int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_NPC(victim)) { char_puts("This spell can cast on PC's only.\n",ch); return; } if (IS_AFFECTED(victim,AFF_BLOODTHIRST) || saves_spell(level, victim,DAM_OTHER)) return; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 10; af.location = 0; af.modifier = 0; af.bitvector = AFF_BLOODTHIRST; affect_to_char(victim, &af); char_puts("You are aggressive as a battlerager.\n", victim); act("$n looks with red eyes.",victim,NULL,NULL,TO_ROOM); return; } void spell_power_stun (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) || saves_spell(level, victim,DAM_OTHER)) return; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 90; af.location = APPLY_DEX; af.modifier = - 3; af.bitvector = AFF_STUN; affect_to_char(victim, &af); char_puts("You are stunned.\n", victim); act_puts("$n is stunned.",victim,NULL,NULL,TO_ROOM,POS_SLEEPING); return; } void spell_improved_invis(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_AFFECTED(victim, AFF_IMP_INVIS)) return; act("$n fades out of existence.", victim, NULL, NULL, TO_ROOM); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 10 ; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_IMP_INVIS; affect_to_char(victim, &af); char_puts("You fade out of existence.\n", victim); return; } void spell_improved_detect(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_AFFECTED(victim, AFF_DETECT_IMP_INVIS)) { if (victim == ch) char_puts("You can already see improved invisible.\n",ch); else act("$N can already see improved invisible mobiles.",ch,NULL,victim,TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 3; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_DETECT_IMP_INVIS; affect_to_char(victim, &af); char_puts("Your eyes tingle.\n", victim); if (ch != victim) char_puts("Ok.\n", ch); return; } void spell_severity_force(int sn, int level, CHAR_DATA *ch, void *vo, int target ) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; char_printf(ch,"You cracked the ground towards the %s.\n",victim->name); act("$n cracked the ground towards you!.", ch, NULL, victim, TO_VICT); dam = dice(level , 12); damage(ch,victim,dam,sn,DAM_NONE,TRUE); } void spell_randomizer(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af,af2; if (is_affected(ch, sn)) { char_puts ("Your power of randomness has been exhausted for now.\n", ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_LAW)) { char_puts( "This room is far too orderly for your powers to work on it.\n", ch); return; } if (is_affected_room(ch->in_room, sn)) { char_puts("This room has already been randomized.\n",ch); return; } if (number_bits(1) == 0) { char_puts("Despite your efforts, the universe resisted chaos.\n",ch); af2.where = TO_AFFECTS; af2.type = sn; af2.level = ch->level; af2.duration = level / 10; af2.modifier = 0; af2.location = APPLY_NONE; af2.bitvector = 0; affect_to_char(ch, &af2); return; } af.where = TO_ROOM_AFFECTS; af.type = sn; af.level = ch->level; af.duration = level / 15; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = RAFF_RANDOMIZER; affect_to_room(ch->in_room, &af); af2.where = TO_AFFECTS; af2.type = sn; af2.level = ch->level; af2.duration = level / 5; af2.modifier = 0; af2.location = APPLY_NONE; af2.bitvector = 0; affect_to_char(ch, &af2); char_puts("The room was successfully randomized!\n", ch); char_puts("You feel very drained from the effort.\n", ch); ch->hit -= UMIN(200, ch->hit/2); act("The room starts to randomize exits.",ch,NULL,NULL,TO_ROOM); return; } void spell_bless_weapon(int sn,int level,CHAR_DATA *ch, void *vo, int target) { OBJ_DATA *obj = (OBJ_DATA *) vo; AFFECT_DATA af; if (obj->pIndexData->item_type != ITEM_WEAPON) { char_puts("That isn't a weapon.\n",ch); return; } if (obj->wear_loc != -1) { char_puts("The item must be carried to be blessed.\n",ch); return; } if (obj->pIndexData->item_type == ITEM_WEAPON) { if (IS_WEAPON_STAT(obj,WEAPON_FLAMING) || IS_WEAPON_STAT(obj,WEAPON_FROST) || IS_WEAPON_STAT(obj,WEAPON_VAMPIRIC) || IS_WEAPON_STAT(obj,WEAPON_SHARP) || IS_WEAPON_STAT(obj,WEAPON_VORPAL) || IS_WEAPON_STAT(obj,WEAPON_SHOCKING) || IS_WEAPON_STAT(obj,WEAPON_HOLY) || IS_OBJ_STAT(obj,ITEM_BLESS) || IS_OBJ_STAT(obj,ITEM_BURN_PROOF)) { act("You can't seem to bless $p.",ch,obj,NULL,TO_CHAR); return; } } if (IS_WEAPON_STAT(obj,WEAPON_HOLY)) { act("$p is already blessed for holy attacks.",ch,obj,NULL,TO_CHAR); return; } af.where = TO_WEAPON; af.type = sn; af.level = level / 2; af.duration = level/8; af.location = 0; af.modifier = 0; af.bitvector = WEAPON_HOLY; affect_to_obj(obj,&af); act("$p is prepared for holy attacks.",ch,obj,NULL,TO_ALL); return; } void spell_resilience(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (!is_affected(ch, sn)) { char_puts("You are now resistive to draining attacks.\n", ch); af.where = TO_RESIST; af.type = sn; af.duration = level / 10; af.level = ch->level; af.bitvector = RES_ENERGY; af.location = 0; af.modifier = 0; affect_to_char(ch, &af); } else char_puts("You are already resistive to draining attacks.\n",ch); return; } void spell_superior_heal(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int bonus = 170 + level + dice(1,20); victim->hit = UMIN(victim->hit + bonus, victim->max_hit); update_pos(victim); char_puts("A warm feeling fills your body.\n", victim); if (ch != victim) char_puts("Ok.\n", ch); return; } void spell_master_healing(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int bonus = 300 + level + dice(1,40); victim->hit = UMIN(victim->hit + bonus, victim->max_hit); update_pos(victim); char_puts("A warm feeling fills your body.\n", victim); if (ch != victim) char_puts("Ok.\n", ch); return; } void spell_group_heal(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *gch; int heal_sn, refresh_sn; heal_sn = sn_lookup("master healing"); refresh_sn = sn_lookup("refresh"); if (heal_sn < 0 || refresh_sn < 0) return; for (gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room) { if (is_same_group(ch, gch)) { spell_heal(heal_sn, level, ch, gch, TARGET_CHAR); spell_refresh(refresh_sn, level, ch, gch, TARGET_CHAR); } } } void spell_restoring_light(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int nsn, mana_add; if (IS_AFFECTED(victim,AFF_BLIND)) { nsn = sn_lookup("cure blindness"); spell_cure_blindness(nsn,level,ch,(void *)victim,TARGET_CHAR); } if (IS_AFFECTED(victim,AFF_CURSE)) { nsn = sn_lookup("remove curse"); spell_remove_curse(nsn,level,ch,(void *)victim,TARGET_CHAR); } if (IS_AFFECTED(victim,AFF_POISON)) { spell_cure_poison(gsn_cure_poison,level,ch,(void *)victim,TARGET_CHAR); } if (IS_AFFECTED(victim,AFF_PLAGUE)) { nsn = sn_lookup("cure disease"); spell_cure_disease(nsn,level,ch,(void *)victim,TARGET_CHAR); } if (victim->hit != victim->max_hit) { mana_add = UMIN((victim->max_hit - victim->hit), ch->mana); victim->hit = UMIN(victim->hit + mana_add, victim->max_hit); ch->mana -= mana_add; } update_pos(victim); char_puts("A warm feeling fills your body.\n", victim); if (ch != victim) char_puts("Ok.\n", ch); return; } void spell_lesser_golem(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *gch; CHAR_DATA *golem; AFFECT_DATA af; int i=0; if (is_affected(ch,sn)) { char_puts("You lack the power to create another golem right now.\n", ch); return; } char_puts("You attempt to create a lesser golem.\n",ch); act("$n attempts to create a lesser golem.",ch,NULL,NULL,TO_ROOM); for (gch = npc_list; gch; gch = gch->next) { if (IS_AFFECTED(gch,AFF_CHARM) && gch->master == ch && gch->pIndexData->vnum == MOB_VNUM_LESSER_GOLEM) { i++; if (i > 2) { char_puts("More golems are more than you can " "control!\n",ch); return; } } } golem = create_mob(get_mob_index(MOB_VNUM_LESSER_GOLEM)); for (i = 0; i < MAX_STATS; i ++) golem->perm_stat[i] = UMIN(25,15 + ch->level/10); golem->perm_stat[STAT_STR] += 3; golem->perm_stat[STAT_INT] -= 1; golem->perm_stat[STAT_CON] += 2; golem->max_hit = IS_NPC(ch)? URANGE(ch->max_hit,1 * ch->max_hit,30000) : UMIN((2 * ch->pcdata->perm_hit) + 400,30000); golem->hit = golem->max_hit; golem->max_mana = IS_NPC(ch)? ch->max_mana : ch->pcdata->perm_mana; golem->mana = golem->max_mana; golem->level = ch->level; for (i=0; i < 3; i++) golem->armor[i] = interpolate(golem->level,100,-100); golem->armor[3] = interpolate(golem->level,100,0); golem->gold = 0; golem->timer = 0; golem->damage[DICE_NUMBER] = 3; golem->damage[DICE_TYPE] = 10; golem->damage[DICE_BONUS] = ch->level / 2; char_puts("You created a lesser golem!\n",ch); act("$n creates a lesser golem!",ch,NULL,NULL,TO_ROOM); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); golem->master = golem->leader = ch; char_to_room(golem,ch->in_room); } void spell_stone_golem(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *gch; CHAR_DATA *golem; AFFECT_DATA af; int i=0; if (is_affected(ch,sn)) { char_puts("You lack the power to create another golem right now.\n", ch); return; } char_puts("You attempt to create a stone golem.\n",ch); act("$n attempts to create a stone golem.",ch,NULL,NULL,TO_ROOM); for (gch = npc_list; gch; gch = gch->next) { if (IS_AFFECTED(gch, AFF_CHARM) && gch->master == ch && gch->pIndexData->vnum == MOB_VNUM_STONE_GOLEM) { i++; if (i > 2) { char_puts("More golems are more than you can " "control!\n",ch); return; } } } golem = create_mob(get_mob_index(MOB_VNUM_STONE_GOLEM)); for (i = 0; i < MAX_STATS; i ++) golem->perm_stat[i] = UMIN(25,15 + ch->level/10); golem->perm_stat[STAT_STR] += 3; golem->perm_stat[STAT_INT] -= 1; golem->perm_stat[STAT_CON] += 2; golem->max_hit = IS_NPC(ch)? URANGE(ch->max_hit,1 * ch->max_hit,30000) : UMIN((5 * ch->pcdata->perm_hit) + 2000, 30000); golem->hit = golem->max_hit; golem->max_mana = IS_NPC(ch)? ch->max_mana : ch->pcdata->perm_mana; golem->mana = golem->max_mana; golem->level = ch->level; for (i=0; i < 3; i++) golem->armor[i] = interpolate(golem->level,100,-100); golem->armor[3] = interpolate(golem->level,100,0); golem->gold = 0; golem->timer = 0; golem->damage[DICE_NUMBER] = 8; golem->damage[DICE_TYPE] = 4; golem->damage[DICE_BONUS] = ch->level / 2; char_puts("You created a stone golem!\n",ch); act("$n creates a stone golem!",ch,NULL,NULL,TO_ROOM); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); golem->master = golem->leader = ch; char_to_room(golem,ch->in_room); } void spell_iron_golem(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *gch; CHAR_DATA *golem; AFFECT_DATA af; int i = 0; if (is_affected(ch,sn)) { char_puts("You lack the power to create another golem right now.\n", ch); return; } char_puts("You attempt to create an iron golem.\n",ch); act("$n attempts to create an iron golem.",ch,NULL,NULL,TO_ROOM); for (gch = npc_list; gch; gch = gch->next) { if (IS_AFFECTED(gch, AFF_CHARM) && gch->master == ch && gch->pIndexData->vnum == MOB_VNUM_IRON_GOLEM) { char_puts("More golems are more than you " "can control!\n", ch); return; } } golem = create_mob(get_mob_index(MOB_VNUM_IRON_GOLEM)); for (i = 0; i < MAX_STATS; i ++) golem->perm_stat[i] = UMIN(25,15 + ch->level/10); golem->perm_stat[STAT_STR] += 3; golem->perm_stat[STAT_INT] -= 1; golem->perm_stat[STAT_CON] += 2; golem->max_hit = IS_NPC(ch)? URANGE(ch->max_hit,1 * ch->max_hit,30000) : UMIN((10 * ch->pcdata->perm_hit) + 1000, 30000); golem->hit = golem->max_hit; golem->max_mana = IS_NPC(ch)? ch->max_mana : ch->pcdata->perm_mana; golem->mana = golem->max_mana; golem->level = ch->level; for (i=0; i < 3; i++) golem->armor[i] = interpolate(golem->level,100,-100); golem->armor[3] = interpolate(golem->level,100,0); golem->gold = 0; golem->timer = 0; golem->damage[DICE_NUMBER] = 11; golem->damage[DICE_TYPE] = 5; golem->damage[DICE_BONUS] = ch->level / 2 + 10; char_puts("You created an iron golem!\n",ch); act("$n creates an iron golem!",ch,NULL,NULL,TO_ROOM); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); golem->master = golem->leader = ch; char_to_room(golem, ch->in_room); } void spell_adamantite_golem(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *gch; CHAR_DATA *golem; AFFECT_DATA af; int i = 0; if (is_affected(ch,sn)) { char_puts("You lack the power to create another golem right now.\n", ch); return; } char_puts("You attempt to create an Adamantite golem.\n",ch); act("$n attempts to create an Adamantite golem.",ch,NULL,NULL,TO_ROOM); for (gch = npc_list; gch; gch = gch->next) { if (IS_AFFECTED(gch, AFF_CHARM) && gch->master == ch && gch->pIndexData->vnum == MOB_VNUM_ADAMANTITE_GOLEM) { char_puts("More golems are more than you " "can control!\n", ch); return; } } golem = create_mob(get_mob_index(MOB_VNUM_ADAMANTITE_GOLEM)); for (i = 0; i < MAX_STATS; i ++) golem->perm_stat[i] = UMIN(25,15 + ch->level/10); golem->perm_stat[STAT_STR] += 3; golem->perm_stat[STAT_INT] -= 1; golem->perm_stat[STAT_CON] += 2; golem->max_hit = IS_NPC(ch)? URANGE(ch->max_hit,1 * ch->max_hit,30000) : UMIN((10 * ch->pcdata->perm_hit) + 4000, 30000); golem->hit = golem->max_hit; golem->max_mana = IS_NPC(ch)? ch->max_mana : ch->pcdata->perm_mana; golem->mana = golem->max_mana; golem->level = ch->level; for (i=0; i < 3; i++) golem->armor[i] = interpolate(golem->level,100,-100); golem->armor[3] = interpolate(golem->level,100,0); golem->gold = 0; golem->timer = 0; golem->damage[DICE_NUMBER] = 13; golem->damage[DICE_TYPE] = 9; golem->damage[DICE_BONUS] = ch->level / 2 + 10; char_puts("You created an Adamantite golem!\n",ch); act("$n creates an Adamantite golem!",ch,NULL,NULL,TO_ROOM); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); golem->master = golem->leader = ch; char_to_room(golem,ch->in_room); } void spell_sanctify_lands(int sn, int level, CHAR_DATA *ch, void *vo, int target) { if (number_bits(1) == 0) { char_puts("You failed.\n",ch); return; } if (IS_RAFFECTED(ch->in_room,RAFF_CURSE)) { affect_strip_room(ch->in_room,gsn_cursed_lands); char_puts("The curse of the land wears off.\n",ch); act("The curse of the land wears off.\n",ch,NULL,NULL,TO_ROOM); } if (IS_RAFFECTED(ch->in_room,RAFF_POISON)) { affect_strip_room(ch->in_room,gsn_deadly_venom); char_puts("The land seems more healthy.\n",ch); act("The land seems more healthy.\n",ch,NULL,NULL,TO_ROOM); } if (IS_RAFFECTED(ch->in_room,RAFF_SLEEP)) { char_puts("The land wake up from mysterious dream.\n",ch); act("The land wake up from mysterious dream.\n",ch,NULL,NULL,TO_ROOM); affect_strip_room(ch->in_room,gsn_mysterious_dream); } if (IS_RAFFECTED(ch->in_room,RAFF_PLAGUE)) { char_puts("The disease of the land has been treated.\n",ch); act("The disease of the land has been treated.\n",ch,NULL,NULL,TO_ROOM); affect_strip_room(ch->in_room,gsn_black_death); } if (IS_RAFFECTED(ch->in_room,RAFF_SLOW)) { char_puts("The lethargic mist dissolves.\n",ch); act("The lethargic mist dissolves.\n",ch,NULL,NULL,TO_ROOM); affect_strip_room(ch->in_room,gsn_lethargic_mist); } return; } void spell_deadly_venom(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (IS_SET(ch->in_room->room_flags, ROOM_LAW)) { char_puts("This room is protected by gods.\n", ch); return; } if (is_affected_room(ch->in_room, sn)) { char_puts("This room has already been effected by deadly venom.\n",ch); return; } af.where = TO_ROOM_AFFECTS; af.type = sn; af.level = ch->level; af.duration = level / 15; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = RAFF_POISON; affect_to_room(ch->in_room, &af); char_puts("The room starts to be filled by poison.\n",ch); act("The room starts to be filled by poison.\n",ch,NULL,NULL,TO_ROOM); } void spell_cursed_lands(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (IS_SET(ch->in_room->room_flags, ROOM_LAW)) { char_puts("This room is protected by gods.\n",ch); return; } if (is_affected_room(ch->in_room, sn)) { char_puts("This room has already been cursed.\n",ch); return; } af.where = TO_ROOM_AFFECTS; af.type = sn; af.level = ch->level; af.duration = level / 15; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = RAFF_CURSE; affect_to_room(ch->in_room, &af); char_puts("The gods has forsaken the room.\n",ch); act("The gos has forsaken the room.\n",ch,NULL,NULL,TO_ROOM); } void spell_lethargic_mist(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (IS_SET(ch->in_room->room_flags, ROOM_LAW)) { char_puts("This room is protected by gods.\n", ch); return; } if (is_affected_room(ch->in_room, sn)) { char_puts("This room has already been full of lethargic mist.\n",ch); return; } af.where = TO_ROOM_AFFECTS; af.type = sn; af.level = ch->level; af.duration = level / 15; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = RAFF_SLOW; affect_to_room(ch->in_room, &af); char_puts("The air in the room makes you slowing down.\n",ch); act("The air in the room makes you slowing down.\n",ch,NULL,NULL,TO_ROOM); } void spell_black_death(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (IS_SET(ch->in_room->room_flags, ROOM_LAW)) { char_puts("This room is protected by gods.\n",ch); return; } if (is_affected_room(ch->in_room, sn)) { char_puts("This room has already been diseased.\n",ch); return; } af.where = TO_ROOM_AFFECTS; af.type = sn; af.level = ch->level; af.duration = level / 15; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = RAFF_PLAGUE; affect_to_room(ch->in_room, &af); char_puts("The room starts to be filled by disease.\n",ch); act("The room starts to be filled by disease.\n",ch,NULL,NULL,TO_ROOM); } void spell_mysterious_dream(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (IS_SET(ch->in_room->room_flags, ROOM_LAW)) { char_puts("This room is protected by gods.\n", ch); return; } if (is_affected_room(ch->in_room, sn)) { char_puts("This room has already been affected by sleep gas.\n",ch); return; } af.where = TO_ROOM_AFFECTS; af.type = sn; af.level = ch->level; af.duration = level / 15; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = RAFF_SLEEP; affect_to_room(ch->in_room, &af); char_puts("The room starts to be seen good place to sleep.\n",ch); act("The room starts to be seen good place to you.\n",ch,NULL,NULL,TO_ROOM); } void spell_polymorph(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; int race; race_t *r; if (is_affected(ch, sn)) { char_puts("You are already polymorphed.\n",ch); return; } if (target_name == NULL || target_name[0]=='\0') { char_puts("Usage: cast 'polymorph' <pcracename>.\n",ch); return; } race = rn_lookup(target_name); r = RACE(race); if (!r->pcdata) { char_puts("That is not a valid race to polymorph.\n",ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level/10; af.location = APPLY_RACE; af.modifier = race; af.bitvector = 0; affect_to_char(ch, &af); act("$n polymorphes $mself to $t.", ch, r->name, NULL, TO_ROOM); act("You polymorph yourself to $t.", ch, r->name, NULL, TO_CHAR); } void spell_plant_form(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (!ch->in_room || IS_SET(ch->in_room->room_flags, ROOM_PRIVATE) || IS_SET(ch->in_room->room_flags, ROOM_SOLITARY) || (ch->in_room->sector_type != SECT_FOREST && ch->in_room->sector_type != SECT_FIELD) || IS_SET(ch->in_room->room_flags, ROOM_NORECALL)) { char_puts("Not here.\n",ch); return; } af.where = TO_AFFECTS; af.type = gsn_fear; af.level = level; af.duration = level / 10; af.location = 0; af.modifier = 0; if (ch->in_room->sector_type == SECT_FOREST) { char_puts("You starts to be seen a nearby tree!\n",ch); act("$n starts to be seen a nearby tree!", ch, NULL, NULL,TO_ROOM); af.bitvector = AFF_DETECT_FORM_TREE; } else { char_puts("You starts to be seen some grass!\n",ch); act("$n starts to be seen some grass!", ch, NULL, NULL, TO_ROOM); af.bitvector = AFF_DETECT_FORM_GRASS; } affect_to_char(ch, &af); return; } void spell_blade_barrier(int sn,int level,CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; act("Many sharp blades appear around $n and crash $N.", ch,NULL,victim,TO_ROOM); act("Many sharp blades appear around you and crash $N.", ch,NULL,victim,TO_CHAR); act("Many sharp blades appear around $n and crash you!", ch,NULL,victim,TO_VICT); dam = dice(level,5); if (saves_spell(level,victim,DAM_PIERCE)) dam /= 3; damage(ch,victim,dam,sn,DAM_PIERCE,TRUE); act("The blade barriers crash $n!",victim,NULL,NULL,TO_ROOM); dam = dice(level,4); if (saves_spell(level,victim,DAM_PIERCE)) dam /= 3; damage(ch,victim,dam,sn,DAM_PIERCE,TRUE); act("The blade barriers crash you!",victim,NULL,NULL,TO_CHAR); if (number_percent() < 75) return; act("The blade barriers crash $n!",victim,NULL,NULL,TO_ROOM); dam = dice(level,2); if (saves_spell(level,victim,DAM_PIERCE)) dam /= 3; damage(ch,victim,dam,sn,DAM_PIERCE,TRUE); act("The blade barriers crash you!",victim,NULL,NULL,TO_CHAR); if (number_percent() < 50) return; act("The blade barriers crash $n!",victim,NULL,NULL,TO_ROOM); dam = dice(level,3); if (saves_spell(level,victim,DAM_PIERCE)) dam /= 3; damage(ch,victim,dam,sn,DAM_PIERCE,TRUE); act("The blade barriers crash you!",victim,NULL,NULL,TO_CHAR); } void spell_protection_negative (int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (!is_affected(ch, sn)) { char_puts("You are now immune to negative attacks.\n", ch); af.where = TO_IMMUNE; af.type = sn; af.duration = level / 4; af.level = ch->level; af.bitvector = IMM_NEGATIVE; af.location = 0; af.modifier = 0; affect_to_char(ch, &af); } else char_puts("You are already immune to negative attacks.\n", ch); return; } void spell_ruler_aura(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; if (!is_affected(ch, sn)) { char_puts("You now feel more self confident in rulership.\n", ch); af.where = TO_IMMUNE; af.type = sn; af.duration = level / 4; af.level = ch->level; af.bitvector = IMM_CHARM; af.location = 0; af.modifier = 0; affect_to_char(ch, &af); } else char_puts("You are as much self confident as you can.\n", ch); return; } void spell_evil_spirit(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AREA_DATA *pArea = ch->in_room->area; ROOM_INDEX_DATA *room; AFFECT_DATA af,af2; int i; if (IS_RAFFECTED(ch->in_room, RAFF_ESPIRIT) || is_affected_room(ch->in_room,sn)) { char_puts("The zone is already full of evil spirit.\n",ch); return; } if (is_affected(ch, sn)) { char_puts("Your power of evil spirit is less for you, now.\n",ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_LAW)) { char_puts("Holy aura in this room prevents your powers to work on it.\n",ch); return; } af2.where = TO_AFFECTS; af2.type = sn; af2.level = ch->level; af2.duration = level / 5; af2.modifier = 0; af2.location = APPLY_NONE; af2.bitvector = 0; affect_to_char(ch, &af2); af.where = TO_ROOM_AFFECTS; af.type = sn; af.level = ch->level; af.duration = level / 25; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = RAFF_ESPIRIT; for (i=pArea->min_vnum; i<pArea->max_vnum; i++) { if ((room = get_room_index(i)) == NULL) continue; affect_to_room(room, &af); if (room->people) act("The zone is starts to be filled with evil spirit.",room->people,NULL,NULL,TO_ALL); } } void spell_disgrace(int sn, int level, CHAR_DATA *ch, void *vo, int target) { AFFECT_DATA af; CHAR_DATA *victim = (CHAR_DATA *) vo; if (!is_affected(victim,sn) && !saves_spell(level, victim, DAM_MENTAL)) { af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_CHA; af.modifier = - (5 + level / 10); af.bitvector = 0; affect_to_char(victim,&af); act("$N feels $M less confident!",ch,NULL,victim,TO_ALL); } else char_puts("You failed.\n",ch); } void spell_control_undead(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; if (!IS_NPC(victim) || !IS_SET(victim->pIndexData->act, ACT_UNDEAD)) { act("$N doesn't seem to be an undead.",ch,NULL,victim,TO_CHAR); return; } spell_charm_person(sn,level,ch,vo,target); } void spell_assist(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)) { char_puts("This power is used too recently.\n",ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 50; af.location = 0; af.modifier = 0; af.bitvector = 0; affect_to_char(ch, &af); victim->hit += 100 + level * 5; update_pos(victim); char_puts("A warm feeling fills your body.\n", victim); act("$n looks better.", victim, NULL, NULL, TO_ROOM); if (ch != victim) char_puts("Ok.\n", ch); return; } void spell_aid(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)) { char_puts("This power is used too recently.\n",ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 50; af.location = 0; af.modifier = 0; af.bitvector = 0; affect_to_char(ch, &af); victim->hit += level * 5; update_pos(victim); char_puts("A warm feeling fills your body.\n", victim); act("$n looks better.", victim, NULL, NULL, TO_ROOM); if (ch != victim) char_puts("Ok.\n", ch); return; } void spell_summon_shadow(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *gch; CHAR_DATA *shadow; AFFECT_DATA af; int i; if (is_affected(ch,sn)) { char_puts("You lack the power to summon another shadow right now.\n", ch); return; } char_puts("You attempt to summon a shadow.\n",ch); act("$n attempts to summon a shadow.",ch,NULL,NULL,TO_ROOM); for (gch = npc_list; gch; gch = gch->next) { if (IS_AFFECTED(gch,AFF_CHARM) && gch->master == ch && gch->pIndexData->vnum == MOB_VNUM_SUM_SHADOW) { char_puts("Two shadows are more than you " "can control!\n",ch); return; } } shadow = create_mob(get_mob_index(MOB_VNUM_SUM_SHADOW)); for (i=0;i < MAX_STATS; i++) { shadow->perm_stat[i] = ch->perm_stat[i]; } shadow->max_hit = IS_NPC(ch)? URANGE(ch->max_hit,1 * ch->max_hit,30000) : URANGE(ch->pcdata->perm_hit,ch->hit,30000); shadow->hit = shadow->max_hit; shadow->max_mana = IS_NPC(ch)? ch->max_mana : ch->pcdata->perm_mana; shadow->mana = shadow->max_mana; shadow->level = ch->level; for (i=0; i < 3; i++) shadow->armor[i] = interpolate(shadow->level,100,-100); shadow->armor[3] = interpolate(shadow->level,100,0); shadow->gold = 0; shadow->timer = 0; shadow->damage[DICE_NUMBER] = number_range(level/15, level/10); shadow->damage[DICE_TYPE] = number_range(level/3, level/2); shadow->damage[DICE_BONUS] = number_range(level/8, level/6); act("A shadow conjures!",ch,NULL,NULL,TO_ALL); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); shadow->master = shadow->leader = ch; char_to_room(shadow,ch->in_room); } void spell_farsight(int sn, int level, CHAR_DATA *ch, void *vo, int target) { ROOM_INDEX_DATA *room; if ((room = check_place(ch, target_name)) == NULL) { char_puts("You cannot see that much far.\n", ch); return; } if (ch->in_room == room) do_look(ch, "auto"); else look_at(ch, room); } void spell_remove_fear(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; if (check_dispel(level,victim,gsn_fear)) { char_puts("You feel more brave.\n",victim); act("$n looks more conscious.",victim,NULL,NULL,TO_ROOM); } else char_puts("You failed.\n",ch); } void spell_desert_fist(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam; if ((ch->in_room->sector_type != SECT_HILLS) && (ch->in_room->sector_type != SECT_MOUNTAIN) && (ch->in_room->sector_type != SECT_DESERT)) { char_puts("You don't find any sand here to create a fist.\n", ch); ch->wait = 0; return; } act("An existing parcel of sand rises up and forms a fist and pummels $n.", victim, NULL, NULL, TO_ROOM); act("An existing parcel of sand rises up and forms a fist and pummels you.", victim, NULL, NULL, TO_CHAR); dam = dice(level, 14); sand_effect(victim, level, dam, TARGET_CHAR); damage(ch, victim, dam, sn, DAM_OTHER, TRUE); } void spell_mirror(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; int mirrors, new_mirrors; CHAR_DATA *gch; CHAR_DATA *tmp_vict; int order; if (IS_NPC(victim)) { send_to_char("Only players can be mirrored.\n",ch); return; } for (mirrors = 0, gch = npc_list; gch; gch = gch->next) if (is_affected(gch, gsn_mirror) && is_affected(gch, gsn_doppelganger) && gch->doppel == victim) mirrors++; if (mirrors >= level/5) { if (ch == victim) char_puts("You cannot be further mirrored.\n", ch); else act("$N cannot be further mirrored.", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS; af.level = level; af.modifier = 0; af.location = 0; af.bitvector = 0; for (tmp_vict = victim; is_affected(tmp_vict, gsn_doppelganger); tmp_vict = tmp_vict->doppel); order = number_range(0, level/5 - mirrors); for (new_mirrors = 0; mirrors + new_mirrors < level/5; new_mirrors++) { gch = create_mob(get_mob_index(MOB_VNUM_MIRROR_IMAGE)); free_string(gch->name); mlstr_free(gch->short_descr); mlstr_free(gch->long_descr); mlstr_free(gch->description); gch->name = str_qdup(tmp_vict->name); gch->short_descr = mlstr_dup(tmp_vict->short_descr); gch->long_descr = mlstr_printf(gch->pIndexData->long_descr, tmp_vict->name, tmp_vict->pcdata->title); gch->description = mlstr_dup(tmp_vict->description); gch->sex = tmp_vict->sex; af.type = gsn_doppelganger; af.duration = level; affect_to_char(gch, &af); af.type = gsn_mirror; af.duration = -1; affect_to_char(gch,&af); gch->max_hit = gch->hit = 1; gch->level = 1; gch->doppel = victim; gch->master = victim; if (ch == victim) { char_puts("A mirror image of yourself appears beside you!\n", ch); 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); char_puts("A mirror image of yourself appears beside you!\n", victim); } char_to_room(gch, victim->in_room); if (new_mirrors == order) { char_from_room(victim); char_to_room(victim, gch->in_room); if (JUST_KILLED(victim)) break; } } } void spell_doppelganger(int sn, int level, CHAR_DATA *ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (ch == victim || (is_affected(ch, sn) && ch->doppel == victim)) { act("You already look like $M.", ch, NULL, victim, TO_CHAR); return; } if (IS_NPC(victim)) { act("$N is too different from yourself to mimic.", ch, NULL, victim, TO_CHAR); return; } if (IS_IMMORTAL(victim)) { char_puts("Yeah, sure. And I'm the Pope.\n",ch); return; } if (saves_spell(level, victim, DAM_CHARM)) { char_puts("You failed.\n", ch); return; } act("You change form to look like $N.", ch, NULL, victim, TO_CHAR); act("$n changes form to look like YOU!", ch, NULL, victim, TO_VICT); act("$n changes form to look like $N!", ch, NULL, victim, TO_NOTVICT); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 2 * level / 3; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = 0; affect_to_char(ch, &af); ch->doppel = victim; } void spell_hunger_weapon(int sn, int level, CHAR_DATA *ch, void *vo, int target) { OBJ_DATA *obj = (OBJ_DATA *) vo; AFFECT_DATA af; int chance; if (obj->pIndexData->item_type != ITEM_WEAPON) { char_puts("That's not a weapon.\n", ch); return; } if (obj->wear_loc != WEAR_NONE) { char_puts("The item must be carried to be cursed.\n", ch); return; } if (IS_WEAPON_STAT(obj, WEAPON_HOLY) || IS_OBJ_STAT(obj, ITEM_BLESS) || IS_OBJ_STAT(obj, ITEM_ANTI_EVIL)) { act("The gods are infuriated!", ch, NULL, NULL, TO_ALL); damage(ch, ch, (ch->hit - 1) > 1000 ? 1000 : (ch->hit - 1), TYPE_HIT, DAM_HOLY, TRUE); return; } if (IS_WEAPON_STAT(obj, WEAPON_VAMPIRIC)) { act("$p is already hungry for enemy life.", ch, obj, NULL, TO_CHAR); return; } chance = get_skill(ch, sn); if (IS_WEAPON_STAT(obj, WEAPON_FLAMING)) chance /= 2; if (IS_WEAPON_STAT(obj, WEAPON_FROST)) chance /= 2; if (IS_WEAPON_STAT(obj, WEAPON_SHARP)) chance /= 2; if (IS_WEAPON_STAT(obj, WEAPON_VORPAL)) chance /= 2; if (IS_WEAPON_STAT(obj, WEAPON_SHOCKING)) chance /= 2; if (number_percent() < chance) { af.where = TO_WEAPON; af.type = sn; af.level = level / 2; af.duration = level/8; af.location = 0; af.modifier = 0; af.bitvector = WEAPON_VAMPIRIC; affect_to_obj(obj, &af); SET_BIT(obj->extra_flags, ITEM_ANTI_GOOD | ITEM_ANTI_NEUTRAL); act("You transmit part of your hunger to $p.", ch, obj, NULL, TO_CHAR); } else act("You failed.", ch, obj, NULL, TO_ALL); }