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