/* * $Id: magic2.c 933 2006-11-19 22:37:00Z zsuzsu $ */ /*************************************************************************** * 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 "debug.h" #include "fight.h" #include "quest.h" #include "rating.h" #include "fight.h" #include "healer.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); DECLARE_DO_FUN(do_clan); 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; AFFECT_DATA af; if (!IS_IMMORTAL(ch) && is_affected(ch, sn)) { char_puts ("You cannot muster the strength to focus on that yet.\n", ch); return; } 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); } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = number_fuzzy(8); af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); portal = create_obj(get_obj_index(OBJ_VNUM_PORTAL), 0); portal->timer = 2 + level / 25; portal->value[ITEM_PORTAL_DEST] = 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; AFFECT_DATA af; 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 (!IS_IMMORTAL(ch) && is_affected(ch, sn)) { char_puts ("You cannot muster the strength to focus on that yet.\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); } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = number_fuzzy(6); af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); /* portal one */ portal = create_obj(get_obj_index(OBJ_VNUM_PORTAL), 0); portal->timer = 1 + level / 10; portal->value[ITEM_PORTAL_DEST] = 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[ITEM_PORTAL_DEST] = 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->state_flags, STATE_WANTED | STATE_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 char_puts("You can't cast that on another.\n", ch); 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 {ybark{x.", victim, NULL, NULL, TO_ROOM); char_puts("Your skin becomes covered in {ybark{x.\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 + 15; staff->timer = level; autoweapon(staff, 110); act("You fashion $p.\n", ch, staff, NULL, TO_CHAR); act("$n fashions $p!", ch, staff, NULL, TO_ROOM); tohit.where = TO_OBJECT; tohit.type = sn; tohit.level = ch->level; tohit.duration = -1; tohit.location = APPLY_HITROLL; tohit.modifier = level / 10 + 3; 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 = level / 10 + 3; todam.bitvector = 0; affect_to_obj(staff, &todam); 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; } if (IS_NPC(ch)) ch->hit += UMIN(30000 - ch->max_hit, ch->max_hit); else ch->hit += ch->pcdata->perm_hit / 2; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; af.location = APPLY_HIT; if (IS_NPC(ch)) af.modifier = UMIN(30000 - ch->max_hit, ch->max_hit); else af.modifier = ch->pcdata->perm_hit / 2; 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("On that path lies insanity.\n", ch); return; } if (ch->clan != victim->clan) { char_puts("You may only bestow this gift on clanmates.\n", ch); return; } if (ch->hit < 50) damage(ch, ch, 50, sn, DAM_NONE, TRUE); else { act("You bestow your psychic energy upon $N.\n", ch, NULL, victim, TO_CHAR); act("$n bestows $s psychic energy upon you.\n", ch, NULL, victim, TO_VICT); act("$n and $N seem to share some link.\n", ch, NULL, victim, TO_NOTVICT); 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, 7); else if (ch->level < 65) dam = dice(level, 9); else dam = dice(level, 12); 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 / 15; af.location = APPLY_INT; af.modifier = -3; 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?!"); do_murder(demon, ch->name); } else do_say(demon, "Who dares disturb me?!"); } 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; int adj_level = 0; if (ch->level < 40) dam = dice(level, 5); else if (ch->level < 65) dam = dice(level, 7); else dam = dice(level, 9); 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 (IS_NPC(vch)) adj_level = level; else adj_level = level - (level / 10); if (number_percent() < UMIN(50, adj_level)) spell_poison(gsn_poison, adj_level, ch, vch, TARGET_CHAR); if (saves_spell(adj_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 receiving benediction.", ch, NULL, NULL, TO_CHAR); else act("$N is already already receiving benediction.", 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're filled with righteous might.", victim, NULL, NULL, TO_CHAR); if (victim != ch) { act("You grant $N favor of your god.", ch, NULL, victim, TO_CHAR); act("$N is filled with the righteous might of $n's god.", ch, NULL, victim, TO_NOTVICT); } else act("$N is filled with the righteous might of $s god.", ch, NULL, victim, TO_NOTVICT); } 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 / 10 + 3; 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; AFFECT_DATA af; if (is_affected(ch, sn)) { char_puts ("Your spies are not back from their last assignment yet.\n", ch); return; } if ((victim = get_char_world(ch, target_name)) == NULL) { char_puts("Your spy network reveals no such person.\n", ch); return; } if (IS_IMMORTAL(victim) || (IS_NPC(victim) && IS_SET(victim->pIndexData->attr_flags, MOB_ATTR_NOFIND)) || saves_spell(level, victim, DAM_NONE)) { char_puts("Your spy network cannot find that mark.\n", ch); if (number_percent() < 5) char_puts("The hairs stand up on the back of your neck!\n", victim); return; } if (ch->in_room == victim->in_room) do_look(ch, str_empty); else look_at(ch, victim->in_room); if (number_percent() < 40) char_puts("You suspect someone is watching you!\n", victim); af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 1; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); } 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_snuff_light(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 extinquish within you.\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[ITEM_LIGHT_DURATION] == 0 || saves_spell(level, vch, DAM_ENERGY)) continue; act("$p flickers and goes out!", ch, obj, NULL, TO_ALL); obj->value[ITEM_LIGHT_DURATION] = 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[ITEM_LIGHT_DURATION] == 0) continue; act("$p flickers and goes out!", ch, obj, NULL, TO_ALL); obj->value[ITEM_LIGHT_DURATION] = 0; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = 24; 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_NPC(victim) && IS_CLAN_GUARD(victim)) { act("$N's elocution is beyond reproach.", ch, NULL, victim, TO_CHAR); 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 + 2, victim, DAM_MENTAL)) { act("$N's elocution remains unadulterated.", ch, NULL, victim, TO_CHAR); char_puts("Your tongue grows thick for a moment.\n", victim); act("Is that a lisp in $N's voice?", ch, NULL, victim, TO_NOTVICT); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = number_fuzzy(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); heal(ch, NULL, ch, sn, level, 150); 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); if (IS_EVIL(ch)) damage(ch, ch, dam, sn, DAM_HOLY, TRUE); else if (IS_GOOD(victim)) damage(ch, ch, 0, sn, DAM_HOLY, TRUE); else if (!IS_EVIL(ch)) damage(ch, victim, dam / 2, 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) { int blade_vnum; OBJ_DATA *blade; AFFECT_DATA af; char arg[MAX_INPUT_LENGTH]; target_name = one_argument(target_name, arg, sizeof(arg)); blade_vnum = 0; if (!str_cmp(arg, "sword")) blade_vnum = OBJ_VNUM_CHAOS_SWORD; else if (!str_cmp(arg, "mace")) blade_vnum = OBJ_VNUM_CHAOS_MACE; else if (!str_cmp(arg, "dagger")) blade_vnum = OBJ_VNUM_CHAOS_DAGGER; else if (!str_cmp(arg, "staff")) blade_vnum = OBJ_VNUM_CHAOS_STAFF; else if (!str_cmp(arg, "axe")) blade_vnum = OBJ_VNUM_CHAOS_AXE; else { char_puts("You can't make a chaos weapon like that!\n", ch); return; } blade = create_obj(get_obj_index(blade_vnum), 0); blade->timer = level * 2; blade->level = ch->level + 10; autoweapon(blade, 110); af.where = TO_OBJECT; af.type = sn; af.level = level; af.duration = -1; af.modifier = level / 10 + 3; 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); act("You create $p!", ch, blade, NULL, TO_CHAR); act("$n creates $p!", ch, blade, NULL, TO_ROOM); } 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_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 = level / 5 + 1; 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, *saved_stalker = NULL; AFFECT_DATA af; int i; if ((victim = get_char_world(ch, target_name)) == NULL || victim == ch || victim->in_room == NULL || IS_SET(victim->in_room->room_flags, ROOM_SAFE | ROOM_PEACE) || IS_SET(ch->in_room->room_flags, ROOM_SAFE | ROOM_PEACE) || IS_NPC(victim) || !IS_SET(victim->state_flags, STATE_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] - 10; } 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->hitroll = victim->hitroll; stalker->damroll = victim->damroll; if (in_PK(ch, victim)) stalker->level = victim->level - 1; else { stalker->level = victim->level; stalker->level -= (ML - victim->level) / 10; } stalker->level -= victim->pcdata->saved_stalkers; stalker->level = UMAX(stalker->level, 2); stalker->damage[DICE_NUMBER] = UMAX(2, number_range(stalker->level / 18, stalker->level / 14)); stalker->damage[DICE_TYPE] = UMAX(2, number_range(stalker->level / 4, stalker->level / 3)); stalker->damage[DICE_BONUS] = UMAX(2, number_range(stalker->level / 10, stalker->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 + 1; 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; DEBUG(DEBUG_SKILL_STALKER, "stalker: %s[%d] vs %s[%d] saved[%d] level[%d]", ch->name, ch->level, victim->name, victim->level, victim->pcdata->saved_stalkers, stalker->level); char_to_room(stalker, victim->in_room); if (victim->pcdata->saved_stalkers > 0) { char_puts("A posse of stalkers has renewed the hunt!\n", ch); doprintf(do_yell, stalker, "I've found the CRIMINAL, boys! Over here!"); doprintf(do_clan, stalker, "A posse of %d, and I, have %s cornered in %s!", victim->pcdata->saved_stalkers, victim->name, victim->in_room->area->name); char_puts ("A posse of stalkers has finally caught up with you!\n", victim); act("A posse of stalkers has caught up with $n!", victim, NULL, NULL, TO_ROOM); } while (victim->pcdata->saved_stalkers > 0) { saved_stalker = create_mob(stalker->pIndexData); clone_mob(stalker, saved_stalker); saved_stalker->target = victim; char_to_room(saved_stalker, victim->in_room); victim->pcdata->saved_stalkers--; } if (saved_stalker == NULL) { 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); doprintf(do_clan, stalker, "I have %s cornered in %s!", victim->name, victim->in_room->area->name); } } 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; AFFECT_DATA af; CHAR_DATA *wch; CHAR_DATA *wch_next; CHAR_DATA *pet = NULL; if (is_affected(ch, sn)) { char_puts("You cannot summon the strength to bend time" " and space at the moment.\n", ch); return; } 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; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = number_fuzzy(6); af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); 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 {Ylight{x, $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[ITEM_POTION_LEVEL] = 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("dragon skin"); 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 undead"); break; case 4: spell = sn_lookup("armor"); break; case 5: spell = sn_lookup("know alignment"); break; case 6: spell = sn_lookup("detect good"); break; case 7: spell = sn_lookup("detect evil"); break; }; }; potion->value[ITEM_POTION_SPELL1] = 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->master = ch; 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 / 10 + 3; 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 / 10 + 3; 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 {Yg{yo{Yld{yen{x aura.\n", ch); else act("$N is already protected by a {Yg{yo{Yld{yen{x 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 / 10 + 3; 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 {Yg{yo{Yld{yen{x aura around you.\n", vch); if (ch != vch) act("A {Yg{yo{Yld{yen{x 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 / 10 + 3; 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->timer = level * 2; sword->cost = 0; sword->level = ch->level + 10; autoweapon(sword, 110); af.where = TO_OBJECT; af.type = sn; af.level = level; af.duration = -1; af.modifier = level / 10 + 3; 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 - (victim->move / 3); else victim->move = victim->move / 2; 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 = level / 8; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = 0; affect_to_char(victim, &af); act("$n is surrounded by a {Cs{wh{Wi{wn{Cy {xaura.", victim, NULL, NULL, TO_ROOM); char_puts("You are surrounded by a {Cs{wh{Wi{wn{Cy{x aura.\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_NPC(victim) && IS_CLAN_GUARD(victim)) { act("$N has a mystical charm protecting $S ears.", ch, NULL, victim, TO_CHAR); 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 - (IS_NPC(victim) ? 0 : 3), victim, DAM_SOUND)) return; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = number_fuzzy(1); 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); act("A dark aura forms around $N's ears, and vanishes.", ch, NULL, victim, TO_NOTVICT); } 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) || ch->in_room == NULL) { char_puts("You aren't up to dispersing this crowd.\n", ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_NORECALL) || IS_SET(ch->in_room->room_flags, ROOM_SAFE) || IS_SET(ch->in_room->room_flags, ROOM_PEACE)) { char_puts("The powers of this room resist your dispersal.\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_IMMORTAL(vch) || IS_SET(vch->imm_flags, IMM_SUMMON)) continue; if (IS_NPC(vch)) { if (IS_AGGRO(vch, NULL)) continue; if (vch->master && is_safe_nomessage(ch, vch->master)) 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); act("$n's eyes sharpen.", victim, NULL, NULL, TO_ROOM); } 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; AFFECT_DATA af; if (ch->sex == victim->sex) { char_puts("You'd better try your chance on the other sex.\n", ch); return; } spell_charm_person(sn, level + 2, ch, vo, target); af.where = TO_AFFECTS; af.type = sn; af.level = ch->level + 10; af.duration = ch->level / 20 + 1; af.modifier = 0; af.bitvector = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); } 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; char_puts ("<<{WThis spell is temporarily disabled, try 'summon zombie'{x>>\n", ch); return; /* 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; } if (obj->pIndexData->item_type == ITEM_CORPSE_PC && !IS_OWNER(ch, obj) && obj->contains != NULL) { char_puts("You need to strip the body first.\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(100, 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); /* drop all objects on the floor */ for (obj2 = obj->contains; obj2; obj2 = next) { next = obj2->next_content; obj_from_obj(obj2); obj_to_room(obj2, ch->in_room); /*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("$p's worldy belongings drop to the ground.", ch, obj, NULL, TO_CHAR); act("$p's worldy belongings drop to the ground.", 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(ch, AFF_ENHANCED_ARMOR)) { if (victim == ch) char_puts("Your armor is already enhanced.\n", ch); else act("You cannot cast that spell upon another.", ch, NULL, victim, TO_CHAR); return; } if (IS_AFFECTED(victim, AFF_SANCTUARY) || IS_AFFECTED(victim, AFF_MINOR_SANCTUARY) || is_affected(victim, gsn_minor_sanctuary) || is_affected(victim, gsn_sanctuary)) { if (victim == ch) char_puts("You are already enveloped in godly grace.\n", ch); else act("$n already looks to be enveloped in godly grace.", victim, NULL, NULL, TO_ROOM); return; } if (IS_AFFECTED(victim, AFF_BLACK_SHROUD) || IS_AFFECTED(victim, AFF_MINOR_BLACK_SHROUD) || is_affected(victim, gsn_minor_black_shroud) || is_affected(victim, gsn_black_shroud)) { if (victim == ch) char_puts("Your demonic aura repels the enhancement.\n", ch); else act("$n looks to be enveloped in a demonic aura.", victim, NULL, NULL, TO_ROOM); return; } if (is_affected(victim, gsn_resistance)) { if (victim == ch) char_puts("Your already benefit from resistance.\n", ch); else act("$n seems to already benefit from some mystical shield.", victim, NULL, NULL, TO_ROOM); } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 6; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_ENHANCED_ARMOR; affect_to_char(victim, &af); char_puts("A {Ct{cranslucent{x aura coats your armor.\n", victim); act("A {Ct{cranslucent{x aura coats $n's armor.", victim, NULL, NULL, TO_ROOM); } 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)) { act("$N struggles through your {Wweb{x and breaks free.", ch, NULL, victim, TO_CHAR); act("You struggle through $n's {Wweb{x break free.", ch, NULL, victim, TO_VICT); act("$N struggles through $n's {Wweb{x and breaks free.", ch, NULL, victim, TO_NOTVICT); 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 tangled in thick {Wwebs{x!\n", victim); act("$n is tangled in {Wwebs{x!", victim, NULL, NULL, TO_ROOM); 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 (IS_NPC(victim) && IS_CLAN_GUARD(victim)) { act("$N's existance seems bound to the Source.", ch, NULL, victim, TO_CHAR); return; } 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; act("You channel your remaining energies into $N.", ch, NULL, victim, TO_CHAR); act("You feel $n's energies surge through your body.", ch, NULL, victim, TO_VICT); act("$n weakens as $N looks to grow stronger.", ch, NULL, victim, TO_NOTVICT); } void spell_power_word_kill(int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; int dam; if (IS_AFFECTED(ch, AFF_FEAR)) { char_puts("You too scare to do this!", ch); return; } if (is_affected(ch, sn)) { char_puts("You have no strength to command death.", ch); return; } act_puts("A stream of {Ddarkness{x from your finger surrounds $N.", ch, NULL, victim, TO_CHAR, POS_RESTING); act_puts("A stream of {Ddarkness{x from $n's finger surrounds $N.", ch, NULL, victim, TO_NOTVICT, POS_RESTING); act_puts("A stream of {Ddarkness{x from $N's finger surrounds you.", victim, NULL, ch, TO_CHAR, POS_RESTING); if (!IS_IMMORTAL(ch) && (victim->level > ch->level - 15 || IS_IMMORTAL(victim) || IS_CLAN_GUARD(victim) || IS_UNDEAD(victim))) { act("$N's control over death is too powerful for you to overcome.\n", ch, NULL, victim, TO_CHAR); act("$N smirks at your jesture.\n", ch, NULL, victim, TO_CHAR); act("$N isn't impressed.\n", ch, NULL, victim, TO_ROOM); return; } af.where = TO_AFFECTS; af.type = sn; af.level = ch->level; af.duration = number_range(8, 14); af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; affect_to_char(ch, &af); if (saves_spell(level - 2, victim, DAM_NEGATIVE)) { dam = dice(level, 24); damage(ch, victim, dam, sn, DAM_NEGATIVE, TRUE); return; } handle_death(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[ITEM_WEAPON_DICE_SIZE] = (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 for 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(100, 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("Now, that would be stupid.\n", ch); return; } if (IS_NPC(victim)) { char_puts("Your victim has no soul worth capturing.\n", ch); return; } if (saves_spell(level, victim, DAM_MENTAL)) { char_puts("That soul is too strong to capture.\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->state_flags, STATE_NOEXP); char_printf(ch, "You catch %s's spirit in to your vial.\n", victim->name); act("$n channels $N's spirit into a vial.", ch, NULL, victim, TO_NOTVICT); act("$n has sucked your sould into a vial!", ch, NULL, victim, TO_VICT); } 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; 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_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_RESIST; af.type = sn; af.duration = level / 4; af.level = ch->level; af.bitvector = RES_FIRE; af.location = 0; af.modifier = 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_RESIST; af.type = sn; af.duration = level / 4; af.level = ch->level; af.bitvector = RES_COLD; af.location = 0; af.modifier = 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)) { act("$N is already on the path to death.\n", ch, NULL, victim, TO_CHAR); return; } /*damage to the witch herself */ ch->hit -= (1 * level); level = (IS_NPC(victim)) ? level - 5 : level - 12; if (saves_spell(level, victim, DAM_OTHER)) { act("$N resists your vexation.", ch, NULL, victim, TO_CHAR); act("You resist $n's vexation.", ch, NULL, victim, TO_VICT); act("$n's vexation isn't strong enough to take hold of $N.", ch, NULL, victim, TO_NOTVICT); return; } if (IS_IMMORTAL(victim) || IS_CLAN_GUARD(victim)) { damage(ch, victim, dice(level, 8), sn, DAM_NEGATIVE, TRUE); return; } af.where = TO_AFFECTS; af.type = gsn_witch_curse; af.level = level; af.duration = 99; af.location = APPLY_HIT; if (IS_NPC(victim)) af.modifier = -100; /* the spell does a geometric progression */ else af.modifier = -1; /* the spell does a geometric progression */ af.bitvector = 0; affect_to_char(victim, &af); victim->cursed_by_witch = ch; act("Now $n is on the path to {Ddeath{x.", victim, NULL, NULL, TO_ROOM); act("$N has set you on the path to {Ddeath{x.\n" "Kill $M to save yourself!", victim, NULL, ch, 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)/4 + 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 succeeded in opening 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("An unctious film spreads over your skin.\n", ch); act("An unctious film spreads over $n's skin.", ch, NULL, NULL, TO_ROOM); af.where = TO_RESIST; af.type = sn; af.duration = level / 10; af.level = ch->level; af.bitvector = RES_MAGIC; af.location = APPLY_NONE; af.modifier = 0; affect_to_char(ch, &af); } else { char_puts("You are already resistive to magic.\n", ch); } } 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_phantasm(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 shadow phantom right now.\n", ch); return; } char_puts("You attempt to summon a shadow phantom.\n", ch); act("$n attempts to summon a shadow phantom.", 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_PHANTOM) { char_puts ("Two shadow phantoms are more than you can control!\n", ch); return; } } demon = create_mob(get_mob_index(MOB_VNUM_PHANTOM)); 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 shadow phantom arrives from the shadows and bows before you!\n", ch); act("A shadow phantom arrives from the shadows 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_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, 10); if (saves_spell(level, victim, DAM_COLD)) dam /= 2; damage(ch, victim, dam, sn, DAM_COLD, 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("Surely you can find a more worth mind to affect.\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 filled with uncontrolable rage.\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_FAERIE_FIRE)) { if (ch == victim) char_puts("The glow of faerie fire makes" " invisibility impossible.\n", ch); else act("The glow around $N makes" " invisibility impossible.", ch, NULL, victim, TO_CHAR); return; } if (IS_NPC(victim) && IS_SET(victim->pIndexData->act, ACT_CLAN_GUARD)) { act("For some reason your spell won't mask $N's presence!", ch, NULL, victim, TO_CHAR); return; } 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 people.", 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 vision takes on a {mviolet{x hue.\n", victim); act("$n's eyes flash {mviolet{x for a moment.", victim, NULL, NULL, TO_ROOM); } 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 crack the ground towards %s.\n", victim->name); act("$n cracks 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 you remove the following, clan entrances will be vulnerable too */ if (IS_SET(ch->in_room->room_flags, ROOM_NORANDOM) || 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 (is_quest_item(obj->pIndexData)) { char_puts("That item is beyond your ability to curse.\n", ch); return; } if (obj->pIndexData->item_type == ITEM_WEAPON) { if (IS_WEAPON_STAT(obj, WEAPON_FLAMING) || IS_WEAPON_STAT(obj, WEAPON_SHARP) || IS_WEAPON_STAT(obj, WEAPON_FROST) || IS_WEAPON_STAT(obj, WEAPON_VAMPIRIC) || IS_WEAPON_STAT(obj, WEAPON_VORPAL) || IS_WEAPON_STAT(obj, WEAPON_SHOCKING) || IS_WEAPON_STAT(obj, WEAPON_HOLY) || IS_OBJ_STAT(obj, ITEM_BURN_PROOF) || obj->value[ITEM_WEAPON_TYPE] == WEAPON_KATANA || obj->pIndexData->vnum == OBJ_VNUM_KATANA_SWORD) { 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); act("$n's face looks rosey and plump.", ch, NULL, NULL, TO_ROOM); 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_skeleton_mage(int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *gch; CHAR_DATA *mage; AFFECT_DATA af; int i = 0; if (is_affected(ch, sn)) { char_puts ("You lack the power to create another skeletal mage right now.\n", ch); return; } char_puts("You attempt to create a skeletal mage.\n", ch); act("$n attempts to create a skeletal mage.", 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_SKELETON_MAGE) { i++; if (i > 0) { char_puts ("One More skeleton mage is more than you can " "control!\n", ch); return; } } } mage = create_mob(get_mob_index(MOB_VNUM_SKELETON_MAGE)); for (i = 0; i < MAX_STATS; i++) mage->perm_stat[i] = UMIN(100, ch->level); mage->perm_stat[STAT_STR] += 10; mage->perm_stat[STAT_INT] -= 10; mage->perm_stat[STAT_CON] += 10; mage->max_hit = IS_NPC(ch) ? URANGE(ch->max_hit, 1 * ch->max_hit, 30000) : UMIN((2 * ch->pcdata->perm_hit) + 400, 30000); mage->hit = mage->max_hit; mage->max_mana = IS_NPC(ch) ? ch->max_mana : ch->pcdata->perm_mana; mage->mana = mage->max_mana; mage->level = ch->level; for (i = 0; i < 3; i++) mage->armor[i] = interpolate(mage->level, 100, -100); mage->armor[3] = interpolate(mage->level, 100, 0); mage->gold = 0; mage->timer = 0; mage->damage[DICE_NUMBER] = 3; mage->damage[DICE_TYPE] = 10; mage->damage[DICE_BONUS] = ch->level / 2; act("You create $N!\n", ch, NULL, mage, TO_CHAR); act("$n creates $N!", ch, NULL, mage, 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); mage->master = mage->leader = ch; char_to_room(mage, ch->in_room); } void spell_skeleton_warrior(int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *gch; CHAR_DATA *warrior; AFFECT_DATA af; int i = 0; if (is_affected(ch, sn)) { char_puts ("You lack the power to create another skeletal warrior right now.\n", ch); return; } char_puts("You attempt to create a skeleton warrior.\n", ch); act("$n attempts to create a skeleton warrior.", 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_SKELETON_WARRIOR) { i++; if (i > 0) { char_puts ("More skeletal warriors are more than you can " "control!\n", ch); return; } } } warrior = create_mob(get_mob_index(MOB_VNUM_SKELETON_WARRIOR)); for (i = 0; i < MAX_STATS; i++) warrior->perm_stat[i] = UMIN(100, ch->level); warrior->perm_stat[STAT_STR] += 20; warrior->perm_stat[STAT_INT] -= 20; warrior->perm_stat[STAT_CON] += 15; warrior->max_hit = IS_NPC(ch) ? URANGE(ch->max_hit, 1 * ch->max_hit, 30000) : UMIN((5 * ch->pcdata->perm_hit) + 2000, 30000); warrior->hit = warrior->max_hit; warrior->max_mana = IS_NPC(ch) ? ch->max_mana : ch->pcdata->perm_mana; warrior->mana = warrior->max_mana; warrior->level = ch->level; for (i = 0; i < 3; i++) warrior->armor[i] = interpolate(warrior->level, 100, -100); warrior->armor[3] = interpolate(warrior->level, 100, 0); warrior->gold = 0; warrior->timer = 0; warrior->damage[DICE_NUMBER] = 8; warrior->damage[DICE_TYPE] = 4; warrior->damage[DICE_BONUS] = ch->level / 2; act("You create $N!\n", ch, NULL, warrior, TO_CHAR); act("$n creates $N!", ch, NULL, warrior, 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); warrior->master = warrior->leader = ch; char_to_room(warrior, ch->in_room); } void spell_flesh_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 flesh golem right now.\n", ch); return; } char_puts("You attempt to create an flesh golem.\n", ch); act("$n attempts to create an flesh 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_FLESH_GOLEM) { char_puts("More flesh golems are more than you " "can control!\n", ch); return; } } golem = create_mob(get_mob_index(MOB_VNUM_FLESH_GOLEM)); for (i = 0; i < MAX_STATS; i++) golem->perm_stat[i] = UMIN(100, ch->level); golem->perm_stat[STAT_STR] += 30; golem->perm_stat[STAT_INT] = 20; golem->perm_stat[STAT_CON] += 30; 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; act("You create $N!\n", ch, NULL, golem, TO_CHAR); act("$n creates $N!", ch, NULL, golem, 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_blood_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 blood golem right now.\n", ch); return; } char_puts("You attempt to create a Blood golem.\n", ch); act("$n attempts to create a Blood 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_BLOOD_GOLEM) { char_puts("More blood golems are more than you " "can control!\n", ch); return; } } golem = create_mob(get_mob_index(MOB_VNUM_BLOOD_GOLEM)); for (i = 0; i < MAX_STATS; i++) golem->perm_stat[i] = UMIN(100, ch->level); golem->perm_stat[STAT_STR] += 30; golem->perm_stat[STAT_INT] = 20; golem->perm_stat[STAT_CON] += 30; 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; act("You create $N!\n", ch, NULL, golem, TO_CHAR); act("$n creates $N!", ch, NULL, golem, 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 the 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 as a good place to sleep.\n", ch); act("The room starts to be seen as a 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 (race == -1 || !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_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 secure your spirit against the negativity around you.\n", ch); act("$n seems to adopt a positive attitude.", ch, NULL, NULL, TO_ROOM); af.where = TO_RESIST; af.type = sn; af.duration = level / 4; af.level = ch->level; af.bitvector = RES_NEGATIVE; af.location = 0; af.modifier = 0; affect_to_char(ch, &af); } else char_puts ("You are already protected against 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_midnight(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_MIDNIGHT) || is_affected_room(ch->in_room, sn)) { char_puts("Oppressive darkness already fills this land.\n", ch); return; } if (is_affected(ch, sn)) { char_puts("You cannot bring darkness to the land yet.\n", ch); return; } if (IS_SET(ch->in_room->room_flags, ROOM_LAW) || IS_SET(ch->in_room->room_flags, ROOM_SAFE)) { char_puts("The light of order is too bright here.\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 = 2 + level / 25; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = RAFF_MIDNIGHT; 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("A veil of oppressive {Ddarkness{x shrouds the sky!", room->people, NULL, NULL, TO_ALL); } } 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_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); act("$n gets a vague look about the eyes.", ch, NULL, NULL, TO_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 couragous.", victim, NULL, NULL, TO_ROOM); } else char_puts("You cannot remove a fear that strong.\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; } if (is_affected(ch, sn)) { send_to_char("You're kinda tired of looking at yourself.\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 / 9 + 1) { 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.type = sn; af.level = level; af.bitvector = 0; af.modifier = 0; af.location = APPLY_NONE; af.duration = level; if (!IS_IMMORTAL(ch)) { af.duration = number_range(6, 14); af.location = APPLY_NONE; affect_to_char(ch, &af); } for (tmp_vict = victim; is_affected(tmp_vict, gsn_doppelganger); tmp_vict = tmp_vict->doppel); order = number_range(0, (level / 9 + 1) - mirrors); for (new_mirrors = 0; mirrors + new_mirrors < (level / 9 + 1); 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) { affect_strip(victim, gsn_doppelganger); act("You return to your natural form.", ch, NULL, victim, TO_CHAR); return; } if (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; int num; 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_quest_item(obj->pIndexData)) { char_puts("That item is beyond your ability to curse.\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 ((obj->pIndexData->value[ITEM_WEAPON_TYPE] == WEAPON_KATANA) || obj->pIndexData->vnum == OBJ_VNUM_KATANA_SWORD) { act("$p can't be tainted with such magic.", ch, obj, NULL, TO_CHAR); 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 (IS_WEAPON_STAT(obj, WEAPON_TAINTED)) chance /= 2; num = number_percent(); if (num < 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); SET_BIT(obj->extra_flags, ITEM_MAGIC); SET_BIT(obj->extra_flags, ITEM_EVIL); act("You transmit part of your hunger to $p.", ch, obj, NULL, TO_CHAR); } else if (num > 90) { /* item destroyed */ act("$p shivers violently and explodes!", ch, obj, NULL, TO_CHAR); act("$p shivers violently and explodeds!", ch, obj, NULL, TO_ROOM); extract_obj(obj, 0); return; } else act("You failed.", ch, obj, NULL, TO_CHAR); } void spell_purify_weapon(int sn, int level, CHAR_DATA * ch, void *vo, int target) { OBJ_DATA *obj = (OBJ_DATA *) vo; AFFECT_DATA af; int chance; int num; 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_quest_item(obj->pIndexData)) { char_puts("That item is beyond your ability to purify.\n", ch); return; } if (IS_WEAPON_STAT(obj, ITEM_ANTI_GOOD) || IS_OBJ_STAT(obj, ITEM_DARK)) { 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 ((obj->pIndexData->value[ITEM_WEAPON_TYPE] == WEAPON_KATANA) || obj->pIndexData->vnum == OBJ_VNUM_KATANA_SWORD) { act("$p is as pure as it can get.", ch, obj, NULL, TO_CHAR); return; } if (IS_WEAPON_STAT(obj, WEAPON_HOLY)) { act("$p was already purified by the gods.", 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_TAINTED)) chance /= 4; num = number_percent(); if (num < chance) { af.where = TO_WEAPON; af.type = sn; af.level = level; af.duration = level / 8; af.location = 0; af.modifier = 0; af.bitvector = WEAPON_HOLY; affect_to_obj(obj, &af); if (IS_GOOD(ch)) SET_BIT(obj->extra_flags, ITEM_ANTI_EVIL); act("You transmit part of your holiness to $p.", ch, obj, NULL, TO_CHAR); act("$p is surrounded by a holy light!", ch, obj, NULL, TO_ROOM); if (num > 75 && chance > 78) { act("$p shines with a bright white light!", ch, obj, NULL, TO_CHAR); act("$p shines with a bright white light!", ch, obj, NULL, TO_ROOM); SET_BIT(obj->extra_flags, ITEM_BLESS); SET_BIT(obj->extra_flags, ITEM_GLOW); } } else if (num > 90) { /* item destroyed */ act("$p shivers violently and explodes!", ch, obj, NULL, TO_CHAR); act("$p shivers violently and explodeds!", ch, obj, NULL, TO_ROOM); extract_obj(obj, 0); return; } else act("You failed.", ch, obj, NULL, TO_CHAR); } void spell_bone_dagger(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, "bone dagger")) */ sword_vnum = OBJ_VNUM_BONE_DAGGER; /*else { char_puts("You can't make a Bone Dagger!", ch); return; } */ sword = create_obj(get_obj_index(sword_vnum), 0); sword->timer = level * 2; sword->cost = 0; sword->level = ch->level + 10; autoweapon(sword, 100); af.where = TO_OBJECT; af.type = sn; af.level = level; af.duration = -1; af.modifier = level / 10 + 3; 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_holy_cloak(int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (victim != ch) { act("You cannot bestow this ability upon another.", ch, NULL, victim, TO_CHAR); return; } if (is_affected(ch, gsn_holy_cloak)) { char_puts("You are already surrounded by a holy cloak.\n", ch); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 6; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = 0; affect_to_char(victim, &af); char_puts("Your body flashes {Wwhite{x for a moment.\n", victim); act("$n's body flashes {Wwhite{x for a moment.", ch, NULL, NULL, TO_ROOM); return; } void spell_take_revenge(int sn, int level, CHAR_DATA * ch, void *vo, int target) { OBJ_DATA *obj; OBJ_DATA *in_obj; ROOM_INDEX_DATA *room = NULL; bool found = FALSE; if (IS_NPC(ch) && !IS_SET(ch->state_flags, STATE_GHOST)) { char_puts("It is too late to take revenge.\n", ch); return; } for (obj = object_list; obj; obj = obj->next) { if (obj->pIndexData->vnum != OBJ_VNUM_CORPSE_PC || !IS_OWNER(ch, obj)) continue; found = TRUE; for (in_obj = obj; in_obj->in_obj; in_obj = in_obj->in_obj); if (in_obj->carried_by != NULL) room = in_obj->carried_by->in_room; else room = in_obj->in_room; break; } if (!found || room == NULL) char_puts("Unluckily your corpse is devoured.\n", ch); else transfer_char(ch, NULL, room, "$N vanishes in a puff of {rviolent{x smoke.", "Your need for vengence wisks you to your corpse.", "In a puff of {rviolent{x smoke, $N arrives."); } void spell_judgement(int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *vch; CHAR_DATA *vch_next; int dam, align; for (vch = ch->in_room->people; vch; vch = vch_next) { vch_next = vch->next_in_room; if (is_safe_spell(ch, vch, TRUE)) continue; if (IS_GOOD(vch)) { act("The light passes over $n harmlessly.", vch, NULL, vch, TO_ROOM); char_puts("The light washes over you pleasantly.\n", vch); continue; } if (IS_EVIL(vch) && vch != ch) { char_puts("A brilliant {Wlight{x fills your eyes," " and sears your impure soul!\n", vch); } align = vch->alignment; align -= 350; if (align < -1000) align = -1000 + (align + 1000) / 3; dam = dice(level, 8); dam = (dam * align * align) / 1000000; if (saves_spell(level - 6, vch, DAM_HOLY)) dam /= 2; if (number_percent() < 50) { spell_blindness(gsn_blindness, 3 * level / 4, ch, vch, TARGET_CHAR); } else if (number_percent() < 50) { fire_effect(vch, level / 2, dam, TARGET_CHAR); } damage(ch, vch, dam, sn, DAM_HOLY, TRUE); } }