/***************************************************************************
* 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. *
* *
* Thanks to abaddon for proof-reading our comm.c and pointing out bugs. *
* Any remaining bugs are, of course, our work, not his. :) *
* *
* 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-1996 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 Tartarus/doc/rom.license *
***************************************************************************/
/***************************************************************************
* Tartarus code is copyright (C) 1997-1998 by Daniel Graham *
* In using this code you agree to comply with the Tartarus license *
* found in the file /Tartarus/doc/tartarus.doc *
***************************************************************************/
#include "include.h"
char *target_name;
void spell_hex(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA hex;
int severity = 0;
if(is_affected(victim,sn))
return send_to_char("They are already hexed.\n\r",ch);
act("$n grins maniacally and spits out an archaic word, unleashing a hex upon $N!",ch,0,victim,TO_NOTVICT);
act("$n grins maniacally and spits out an archaic word, unleashing a hex upon you!",ch,0,victim,TO_VICT);
act("You grin maniacally and spit out an archaic word, unleashing a hex upon $N!",ch,0,victim,TO_CHAR);
if(saves_spell(level+4,victim,DAM_NEGATIVE) && number_percent()>35)
{
act("$n staggers for a moment, but resists the hex.",victim,0,0,TO_ROOM);
act("You stagger as the power of the hex strikes you, but manage to resist it.",victim,0,0,TO_CHAR);
return;
}
init_affect(&hex);
hex.where = TO_AFFECTS;
hex.type = sn;
hex.level = level;
hex.owner_name = str_dup(ch->original_name);
hex.location = APPLY_SAVING_SPELL;
hex.modifier = 10;
hex.duration = level/4;
hex.bitvector = AFF_CURSE;
severity++;
if(number_percent()>75)
{
hex.bitvector += AFF_BLIND;
severity++;
}
affect_to_char(victim, &hex);
if(number_percent()>70)
{
//plague
hex.location = APPLY_STR;
hex.modifier = -5;
hex.bitvector = AFF_PLAGUE;
affect_to_char(victim, &hex);
severity++;
}
if(number_percent()>66)
{
//poison
hex.location = APPLY_STR;
hex.modifier = -6;
hex.bitvector = AFF_POISON;
affect_to_char(victim, &hex);
severity++;
}
if(severity>1 && severity<4)
{
act("$n sags as the hex strikes him powerfully!",victim,0,0,TO_ROOM);
act("You slump as the hex strikes you powerfully.",victim,0,0,TO_CHAR);
}
if(severity==4)
{
act("$n screams in utter agony as the full power of the hex strangles $s soul!",victim,0,0,TO_ROOM);
act("You scream in utter agony as the full power of the hex strangles your soul!",victim,0,0,TO_CHAR);
}
act("You feel drained from the power of your hex.",ch,0,0,TO_CHAR);
ch->hit *= (98 - (severity * 3.0)) / 100.1;
}
void spell_black_circle(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *pet;
AFFECT_DATA af;
bool found = FALSE;
if(is_affected(ch,sn))
return send_to_char("You cannot summon your minions again yet.\n\r",ch);
act("$n draws a black circle on the ground and falls into deep concentration.",ch,0,0,TO_ROOM);
act("You draw a black circle on the ground and fall into deep concentration.",ch,0,0,TO_CHAR);
for(pet = char_list; pet!= NULL; pet=pet->next)
if(IS_NPC(pet) && IS_AFFECTED(pet,AFF_CHARM) && (IS_SET(pet->act, ACT_UNDEAD) || (pet->pIndexData->vnum == MOB_VNUM_L_GOLEM || pet->pIndexData->vnum==MOB_VNUM_G_GOLEM)) && pet->master == ch)
{
stop_fighting(pet,TRUE);
act("$n disappears suddenly.",pet,0,0,TO_ROOM);
char_from_room(pet);
char_to_room(pet, ch->in_room);
act("$n arrives suddenly, kneeling before $N outside the circle.",pet,0,ch,TO_ROOM);
found = TRUE;
}
if(!found)
return send_to_char("Your summonings went unanswered.\n\r",ch);
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.modifier = 0;
af.location = 0;
af.duration = 10;
af.owner_name = str_dup(ch->original_name);
af.affect_list_msg = str_dup("unable to perform the summoning ritual");
af.level = ch->level;
af.bitvector = 0;
af.end_fun = NULL;
affect_to_char(ch,&af);
}
void spell_banshee_call(int sn, int level, CHAR_DATA *ch, void *vo, int target) {
CHAR_DATA *zombie;
CHAR_DATA *check;
AFFECT_DATA af;
char buf1[MSL], buf2[MSL];
int count = 0;
for (check = char_list; check != NULL; check = check->next) {
if (IS_NPC(check) && IS_AFFECTED(check,AFF_CHARM) && IS_SET(check->act,ACT_UNDEAD) && check->master == ch)
count++;
}
if (count >= 5) return send_to_char("You already control an army of banshees.\n\r",ch);
if (is_affected(ch,skill_lookup("banshee call"))) return send_to_char("You cannot yet summon an army of banshees.\n\r",ch);
while (count < 5) {
zombie = create_mobile(get_mob_index(MOB_VNUM_ZOMBIE));
int z_level = number_range(47,49);
zombie->level = z_level;
zombie->max_hit = (dice(z_level, 15));
zombie->max_hit += (z_level * 20);
zombie->hit = zombie->max_hit;
zombie->damroll += (z_level*7/10);
zombie->alignment = -1000;
zombie->name = str_dup("banshee spirit");
sprintf( buf1, "a banshee spirit");
sprintf( buf2, "A banshee spirit is standing here.\n\r");
free_string(zombie->short_descr);
free_string(zombie->long_descr);
zombie->short_descr = str_dup(buf1);
zombie->long_descr = str_dup(buf2);
char_to_room(zombie,ch->in_room);
SET_BIT(zombie->affected_by, AFF_CHARM);
add_follower(zombie,ch);
zombie->leader = ch;
act("A banshee rises from the earth before $n.",ch,0,0,TO_ROOM);
act("A banshee rises from the earth before you.",ch,0,0,TO_CHAR);
count++;
}
init_affect(&af);
af.type = skill_lookup("banshee call");
af.affect_list_msg = str_dup("unable to summon an army of banshees");
af.duration = 35;
af.aftype = AFT_SPELL;
affect_to_char(ch,&af);
}
void spell_minion_tactics( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *gch;
for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
{
if ( !is_same_group(gch, ch) || !(IS_NPC(gch)))
continue;
if ((IS_AFFECTED(gch,AFF_CHARM)) && (gch->pIndexData->vnum==MOB_VNUM_ZOMBIE) && (gch->master == ch)) {
act("$n's eyes widen with newly-acquired tactics.", gch, NULL, NULL, TO_ROOM );
send_to_char("Your eyes widen with newly-acquired tactics.\n\r", gch );
SET_BIT(gch->off_flags,OFF_BASH);
SET_BIT(gch->off_flags,OFF_TRIP);
SET_BIT(gch->off_flags,OFF_CRUSH);
}
}
send_to_char( "Ok.\n\r", ch );
return;
}
void spell_minion_sanc( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *gch;
sn = skill_lookup("sanctuary");
for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
{
if ( !is_same_group(gch, ch) || !(IS_NPC(gch)))
continue;
if ((IS_AFFECTED(gch,AFF_CHARM)) && (gch->pIndexData->vnum==MOB_VNUM_ZOMBIE) && (gch->master == ch)) {
spell_sanctuary(sn,ch->level,ch,gch,TARGET_CHAR);
}
}
send_to_char( "Ok.\n\r", ch );
return;
}
void spell_minion_flight( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *gch;
sn= skill_lookup("fly");
for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
{
if ( !is_same_group(gch, ch) || !(IS_NPC(gch)))
continue;
if ((IS_AFFECTED(gch,AFF_CHARM)) && (gch->pIndexData->vnum==MOB_VNUM_ZOMBIE) && (gch->master == ch)) {
spell_fly(sn,ch->level,ch,gch,TARGET_CHAR);
}
}
send_to_char( "Ok.\n\r", ch );
return;
}
void spell_minion_sneak( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *gch;
for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
{
if ( !is_same_group(gch, ch) || !(IS_NPC(gch)))
continue;
if ((IS_AFFECTED(gch,AFF_CHARM)) && (gch->pIndexData->vnum==MOB_VNUM_ZOMBIE) && (gch->master == ch)) {
act("$n begins moving silently.", gch, NULL, NULL, TO_ROOM );
send_to_char("You begin moving silently.\n\r", gch );
SET_BIT(gch->affected_by,AFF_SNEAK);
}
}
act("$n begins moving silently.", ch, NULL, NULL, TO_ROOM );
return;
}
void spell_minion_recall( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *gch, *gch_next;
ROOM_INDEX_DATA *room;
sn= skill_lookup("word of recall");
room = ch->in_room;
spell_word_of_recall(sn,ch->level,ch,ch,TARGET_CHAR);
for ( gch = room->people; gch != NULL; gch = gch_next)
{
gch_next = gch->next_in_room;
if ( !is_same_group(gch, ch) || !(IS_NPC(gch)))
continue;
if ((IS_AFFECTED(gch,AFF_CHARM)) && (gch->pIndexData->vnum==MOB_VNUM_ZOMBIE || gch->pIndexData->vnum==MOB_VNUM_G_GOLEM || gch->pIndexData->vnum==MOB_VNUM_L_GOLEM) && (gch->master == ch)) {
char_from_room(gch);
char_to_room(gch,ch->in_room);
act("$n appears in the room.", gch, NULL, NULL, TO_ROOM );
}
}
send_to_char( "Ok.\n\r", ch );
return;
}
void spell_minion_haste( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *gch;
sn= skill_lookup("haste");
for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
{
if ( !is_same_group(gch, ch) || !(IS_NPC(gch)))
continue;
if ((IS_AFFECTED(gch,AFF_CHARM)) && (gch->pIndexData->vnum==MOB_VNUM_ZOMBIE) && (gch->master == ch)) {
spell_haste(sn,ch->level,ch,gch,TARGET_CHAR);
}
}
send_to_char( "Ok.\n\r", ch );
return;
}
void spell_minion_trans( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *gch;
sn= skill_lookup("pass door");
for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
{
if ( !is_same_group(gch, ch) || !(IS_NPC(gch)))
continue;
if ((IS_AFFECTED(gch,AFF_CHARM)) && (gch->pIndexData->vnum==MOB_VNUM_ZOMBIE) && (gch->master == ch)) {
spell_pass_door(sn,ch->level,gch,gch,TARGET_CHAR);
}
}
send_to_char( "Ok.\n\r", ch );
return;
}
void do_lich( CHAR_DATA *ch, char *argument )
{
char arg1[MAX_INPUT_LENGTH];
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim;
if (IS_NPC(ch))
return;
argument = one_argument( argument, arg1 );
if ((ch->level < 56 && ch->pcdata->induct != CABAL_LEADER) || IS_NPC(ch))
{
send_to_char("Huh?\n\r", ch);
return;
}
if ( arg1[0] == '\0' )
{
buf[0] = '\0';
send_to_char( "Syntax: lich <char>\n\r",ch);
return;
}
if ((victim = get_char_world(ch, arg1)) == NULL)
{
send_to_char("They aren't playing.\n\r", ch);
return;
}
if (victim->race==race_lookup("lich"))
{
send_to_char("They are lich already.\n\r", ch);
return;
}
sprintf(buf,"%s is now a Lich.\n\r", victim->name);
send_to_char(buf,ch);
sprintf(buf,"Your mortal body begins to decompose as you gain unholy power!\n\r");
send_to_char(buf,victim);
victim->pcdata->learned[skill_lookup("minion tactics")] = 1;
victim->pcdata->learned[skill_lookup("minion sanc")] =1;
victim->pcdata->learned[skill_lookup("minion flight")] =1;
victim->pcdata->learned[skill_lookup("minion sneak")] =1;
victim->pcdata->learned[skill_lookup("minion recall")] =1;
victim->pcdata->learned[skill_lookup("minion haste")] =1;
victim->pcdata->learned[skill_lookup("minion trans")] =1;
victim->pcdata->learned[skill_lookup("ritual of abominations")] = 1;
victim->pcdata->learned[skill_lookup("vampiric touch")] = 1;
victim->race = race_lookup("lich");
victim->perm_stat[STAT_STR]=pc_race_table[ch->race].max_stats[STAT_STR];
victim->perm_stat[STAT_INT]=pc_race_table[ch->race].max_stats[STAT_INT];
victim->perm_stat[STAT_WIS]=pc_race_table[ch->race].max_stats[STAT_WIS];
victim->perm_stat[STAT_DEX]=pc_race_table[ch->race].max_stats[STAT_DEX];
victim->perm_stat[STAT_CON]=pc_race_table[ch->race].max_stats[STAT_CON];
victim->mod_stat[STAT_STR]=0;
victim->mod_stat[STAT_INT]=0;
victim->mod_stat[STAT_WIS]=0;
victim->mod_stat[STAT_DEX]=0;
victim->mod_stat[STAT_CON]=0;
sprintf(buf, "Your stats are Str: %2d Int: %2d Wis: %2d Dex: %2d Con: %2d\n\r",
ch->perm_stat[STAT_STR],
ch->perm_stat[STAT_INT],
ch->perm_stat[STAT_WIS],
ch->perm_stat[STAT_DEX],
ch->perm_stat[STAT_CON]);
send_to_char(buf,victim);
}
void do_ritual_of_abominations( CHAR_DATA *ch, char *argument )
{
OBJ_DATA *corpse, *phylactery;
AFFECT_DATA af;
char buf[MSL];
int phylacRoll = number_percent();
OBJ_INDEX_DATA *phylac;
if (ch->mana < 300)
return send_to_char("You don't have the 300 mana required to perform the Ritual of Abominations.\n\r",ch);
if (argument[0] == '\0')
return send_to_char("Which corpse do you wish to perform it on?\n\r",ch);
corpse = get_obj_here(ch,argument);
if (corpse == NULL)
return send_to_char("That corpse is not here.\n\r",ch);
if (corpse->pIndexData->vnum != OBJ_VNUM_CORPSE_PC || corpse->noPhylactery)
return send_to_char("You cannot perform the Ritual of Abominations on that.\n\r",ch);
if (is_affected(ch,skill_lookup("ritual of abominations")))
return send_to_char("Your mind is still too weary from your previous Ritual.\n\r",ch);
ch->mana -= 300;
corpse->noPhylactery = TRUE;
act("You kneel over $p and begin reciting unholy and forbidden incantations.",ch,corpse,0,TO_CHAR);
act("Resting your bony hand on its already-rotting chest, you begin to drain its life energy.",ch,corpse,0,TO_CHAR);
act("A phylactery formed from $p's own energy pulses into existence before you!",ch,corpse,0,TO_CHAR);
act("$n kneels over $p and begins reciting unholy and forbidden incantations.",ch,corpse,0,TO_ROOM);
act("Pulsing with energy, a phylactery appears before $n, surrounded in a hazy, dark aura.",ch,corpse,0,TO_ROOM);
act("$p grows charred and black, devoid of anything beyond rotting flesh and bones.",ch,corpse,0,TO_CHAR);
act("$p grows charred and black, devoid of anything beyond rotting flesh and bones.",ch,corpse,0,TO_ROOM);
sprintf(buf,"A corpse is charred and blackened beyond recognition here.");
corpse->description = str_dup(buf);
if (corpse->owner_class == class_lookup("necromancer"))
{
if (phylacRoll >= 90)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_DIAMOND);
else if (phylacRoll >= 80)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE_AGATE);
else if (phylacRoll >= 65)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_ROUNDED_JADE);
else if (phylacRoll >= 50)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_BLACK_SAPPHIRE);
else if (phylacRoll >= 25)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_FACETED_JASPER);
else
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE);
}
else if (corpse->owner_class == class_lookup("healer"))
{
if (phylacRoll >= 90)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_BLACK_DIAMOND);
else if (phylacRoll >= 80)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_AMETHYST);
else if (phylacRoll >= 60)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_PALE_AQUAMARINE);
else if (phylacRoll >= 40)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_STAR_DIOPSIDE);
else
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE);
}
else if (corpse->owner_class == class_lookup("elementalist"))
{
if (phylacRoll >= 90)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_RAINBOW_MOONSTONE);
else if (phylacRoll >= 75)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_BASALT);
else if (phylacRoll >= 60)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_STRIPED_GLASS);
else if (phylacRoll >= 45)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_ZIRCON);
else if (phylacRoll >= 35)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_MALACHITE_DISC);
else if (phylacRoll >= 25)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_VIOLET_GARNET);
else
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE);
}
else if (corpse->owner_class == class_lookup("channeler"))
{
if (phylacRoll >= 90)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_SPHERICAL_MALACHITE);
else if (phylacRoll >= 80)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE_AGATE);
else if (phylacRoll >= 65)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_SOMETHING_OILY);
else if (phylacRoll >= 50)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_PALE_AQUAMARINE);
else if (phylacRoll >= 40)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_SOAPSTONE);
else if (phylacRoll >= 25)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_TAUROIDAL_BERYL);
else
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE);
}
else if (corpse->owner_class == class_lookup("ranger"))
{
if (phylacRoll >= 90)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_FIRE_OPAL);
else if (phylacRoll >= 75)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_JADE);
else if (phylacRoll >= 60)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_BASALT);
else if (phylacRoll >= 45)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_STRIPED_GLASS);
else if (phylacRoll >= 30)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_ZIRCON);
else
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE);
}
else if (corpse->owner_class == class_lookup("assassin"))
{
if (phylacRoll >= 95)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_FIRE_OPAL);
else if (phylacRoll >= 85)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_MALACHITE_DISC);
else if (phylacRoll >= 65)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_ANGLED_JASPER);
else if (phylacRoll >= 45)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_MILKY_QUARTZ);
else if (phylacRoll >= 25)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_BLACK_OPAL);
else
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE);
}
else if (corpse->owner_class == class_lookup("thief"))
{
if (phylacRoll >= 90)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE_AGATE);
else if (phylacRoll >= 80)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_ROUNDED_JADE);
else if (phylacRoll >= 60)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_ANGLED_JASPER);
else if (phylacRoll >= 40)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_MILKY_QUARTZ);
else if (phylacRoll >= 25)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_PALE_AQUAMARINE);
else
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE);
}
else if (corpse->owner_class == class_lookup("warrior"))
{
if (phylacRoll >= 90)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_FIRE_OPAL);
else if (phylacRoll >= 80)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_GRANITE);
else if (phylacRoll >= 60)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_ROUNDED_JADE);
else if (phylacRoll >= 40)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_BASALT);
else if (phylacRoll >= 25)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_ZIRCON);
else
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE);
}
else if (corpse->owner_class == class_lookup("zealot"))
{
if (phylacRoll >= 90)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_SPHERICAL_MALACHITE);
else if (phylacRoll >= 75)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_MALACHITE_DISC);
else if (phylacRoll >= 60)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_PALE_JADE);
else if (phylacRoll >= 45)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_BLOODSTONE);
else if (phylacRoll >= 35)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_BLACK_OPAL);
else if (phylacRoll >= 25)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_BLACK_SAPPHIRE);
else
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE);
}
else if (corpse->owner_class == class_lookup("anti-paladin"))
{
if (phylacRoll >= 90)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_BLACK_PEARL);
else if (phylacRoll >= 70)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_PALE_JADE);
else if (phylacRoll >= 55)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_SUNSTONE);
else if (phylacRoll >= 35)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_STAR_DIOPSIDE);
else if (phylacRoll >= 25)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_FIRE_OPAL);
else
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE);
}
else if (corpse->owner_class == class_lookup("paladin"))
{
if (phylacRoll >= 90)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_BLACK_PEARL);
else if (phylacRoll >= 70)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_PALE_JADE);
else if (phylacRoll >= 55)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_SUNSTONE);
else if (phylacRoll >= 45)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_BASALT);
else if (phylacRoll >= 35)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_ZIRCON);
else if (phylacRoll >= 25)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_PALE_AQUAMARINE);
else
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE);
}
else if (corpse->owner_class == class_lookup("druid"))
{
if (phylacRoll >= 90)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_GRANITE);
else if (phylacRoll >= 70)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_JADE);
else if (phylacRoll >= 60)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_TAUROIDAL_BERYL);
else if (phylacRoll >= 50)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_BASALT);
else if (phylacRoll >= 40)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_STRIPED_GLASS);
else if (phylacRoll >= 30)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_ZIRCON);
else if (phylacRoll >= 25)
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_AMETHYST);
else
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE);
}
else
phylac = get_obj_index(OBJ_VNUM_PHYLACTERY_CATS_EYE);
phylactery = create_object(phylac,0);
obj_to_char(phylactery,ch);
act("A sickening aura surrounds you as you stand, your hand wrapped around $p.",ch,phylactery,0,TO_CHAR);
act("A sickening aura surrounds $n as $e stands, $s hand wrapped around $p.",ch,phylactery,0,TO_ROOM);
init_affect(&af);
af.where = TO_AFFECTS;
af.type = skill_lookup("ritual of abominations");
af.name = str_dup("ritual of abominatio");
af.level = 60;
af.duration = 80;
af.aftype = AFT_POWER;
af.affect_list_msg = str_dup("inability to perform the Ritual of Abominations");
af.dispel_at_death = FALSE;
affect_to_char(ch,&af);
}
void spell_maledict_corpse( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
OBJ_DATA *corpse;
char *obj_name;
if (target_name[0] == '\0')
{
send_to_char("Maledict which corpse?\n\r",ch);
return;
}
obj_name = str_dup(target_name);
corpse = get_obj_here(ch,obj_name);
if (corpse == NULL)
{
send_to_char("You don't see that here.\n\r",ch);
return;
}
if (corpse->pIndexData->vnum != OBJ_VNUM_CORPSE_PC)
{
send_to_char("You can only maledict player corpses.\n\r",ch);
return;
}
act("You kneel down and pronounce a maledictive curse upon $p.", ch, corpse, 0, TO_CHAR);
act("$n kneels down and pronounces a maledictive curse upon $p.", ch, corpse, 0, TO_ROOM);
set_bit(&corpse->extra_flags, ITEM_MALEDICTED);
return;
}
void spell_decay_corpse(int sn,int level,CHAR_DATA *ch,void *vo,int target)
{
char buf1[MSL], buf2[MSL];
OBJ_DATA *obj, *obj_next, *corpse, *skeleton;
char *name, *last_name, *obj_name;
int chance;
if (target_name[0] == '\0')
{
send_to_char("Decay which corpse?\n\r",ch);
return;
}
obj_name = str_dup(target_name);
corpse = get_obj_here(ch,obj_name);
if (corpse == NULL)
{
send_to_char("You can't find that object.\n\r",ch);
return;
}
if ((corpse->item_type != ITEM_CORPSE_NPC) && (corpse->item_type != ITEM_CORPSE_PC) )
{
send_to_char("You can't decay that.\n\r",ch);
return;
}
name = corpse->short_descr;
for (obj = corpse->contains; obj != NULL; obj = obj_next)
{
obj_next = obj->next_content;
obj_from_obj(obj);
obj_to_room(obj,ch->in_room);
}
chance = get_skill(ch,sn);
if (number_percent() > chance)
{
act("Your decaying becomes uncontrolled and you destroy $p.", ch,corpse,NULL,TO_CHAR);
act("$n tries to decay $p but reduces it to a puddle of slime.",ch,corpse,NULL,TO_ROOM);
extract_obj(corpse);
return;
}
act("$n decays the flesh off $p.",ch,corpse,NULL,TO_ROOM);
act("You decay the flesh off $p and reduce it to a skeleton.",ch,corpse,NULL,TO_CHAR);
skeleton = create_object(get_obj_index(OBJ_VNUM_SKELETON),1);
obj_to_room(skeleton,ch->in_room);
skeleton->level = corpse->level;
last_name = name;
last_name = one_argument(corpse->short_descr,name);
last_name = one_argument(last_name,name);
last_name = one_argument(last_name,name);
name = last_name;
extract_obj(corpse);
sprintf(buf1,"the skeleton of %s",name);
sprintf(buf2,"A skeleton of %s is lying here in a puddle of decayed flesh.",name);
free_string(skeleton->short_descr);
free_string(skeleton->description);
skeleton->short_descr = str_dup(buf1);
skeleton->description = str_dup(buf2);
skeleton->item_type = ITEM_SKELETON;
return;
}
void spell_preserve(int sn,int level,CHAR_DATA *ch,void *vo,int target)
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
long vnum, chance;
vnum = obj->pIndexData->vnum;
if (vnum != OBJ_VNUM_SEVERED_HEAD && vnum != OBJ_VNUM_TORN_HEART && vnum != OBJ_VNUM_SLICED_ARM && vnum != OBJ_VNUM_SLICED_LEG
&& vnum != OBJ_VNUM_GUTS && vnum != OBJ_VNUM_BRAINS)
{
send_to_char("You can't preserve that.\n\r",ch);
return;
}
if (obj->timer > 10)
{
send_to_char("It's already in very well preserved condition.\n\r",ch);
WAIT_STATE(ch,PULSE_VIOLENCE);
return;
}
chance = get_skill(ch,sn);
chance *= 90;
if (number_percent() > chance)
{
act("$n destroys $p.",ch,obj,NULL,TO_ROOM);
act("You fail and destroy $p.",ch,obj,NULL,TO_CHAR);
extract_obj(obj);
WAIT_STATE(ch,PULSE_VIOLENCE);
return;
}
act("You surround $p with necromantic magic to slow it's decay.",ch,obj,NULL,TO_CHAR);
WAIT_STATE(ch,PULSE_VIOLENCE);
obj->timer += number_range(level/2,level);
return;
}
void spell_lesser_golem(int sn,int level, CHAR_DATA *ch,void *vo,int target)
{
CHAR_DATA *golem;
AFFECT_DATA af;
CHAR_DATA *check;
OBJ_DATA *part;
OBJ_DATA *part_next;
int parts, lvl;
parts = 0;
if (is_affected(ch,sn))
{
send_to_char("You aren't up to fashioning another golem yet.\n\r",ch);
return;
}
for (check = char_list; check != NULL; check = check->next)
{
if (IS_NPC(check))
if ( (check->master == ch) && (check->pIndexData->vnum == MOB_VNUM_L_GOLEM) )
{
send_to_char("You already have a golem under your command.\n\r",ch);
return;
}
}
for (part = ch->carrying; part != NULL; part = part_next)
{
part_next = part->next_content;
if (part->pIndexData->vnum != OBJ_VNUM_SEVERED_HEAD && part->pIndexData->vnum != OBJ_VNUM_TORN_HEART
&& part->pIndexData->vnum != OBJ_VNUM_SLICED_ARM && part->pIndexData->vnum != OBJ_VNUM_SLICED_LEG
&& part->pIndexData->vnum != OBJ_VNUM_GUTS && part->pIndexData->vnum != OBJ_VNUM_BRAINS)
continue;
parts++;
}
if (parts == 0)
{
send_to_char("You don't have any body parts to animate.\n\r",ch);
return;
}
else if (parts <= 1)
{
send_to_char("You don't have enough parts to build a flesh golem.\n\r",ch);
return;
}
for (part = ch->carrying; part != NULL; part = part_next)
{
part_next = part->next_content;
if (part->pIndexData->vnum != OBJ_VNUM_SEVERED_HEAD && part->pIndexData->vnum != OBJ_VNUM_TORN_HEART
&& part->pIndexData->vnum != OBJ_VNUM_SLICED_ARM && part->pIndexData->vnum != OBJ_VNUM_SLICED_LEG
&& part->pIndexData->vnum != OBJ_VNUM_GUTS && part->pIndexData->vnum != OBJ_VNUM_BRAINS)
continue;
extract_obj(part);
}
if (parts >= ch->level/5)
parts = ch->level/5;
lvl = (level - 3 + parts);
init_affect(&af);
af.where = TO_AFFECTS;
af.level = level;
af.location = 0;
af.modifier = 0;
af.duration = 35;
af.bitvector = 0;
af.type = sn;
af.affect_list_msg = str_dup("unable to summon a lesser golem");
af.aftype = AFT_SPELL;
affect_to_char(ch,&af);
act("$n fashions a flesh golem!",ch,0,0,TO_ROOM);
send_to_char("You fashion a flesh golem to serve you!\n\r",ch);
golem = create_mobile(get_mob_index(MOB_VNUM_L_GOLEM) );
golem->level = lvl;
golem->damroll += level/2 + parts;
if (parts <= 3)
golem->max_hit = ((lvl*lvl/2) + dice(lvl,10));
else if (parts == 4) golem->max_hit = ((lvl*lvl/2) + dice(lvl,12));
else if (parts == 5) golem->max_hit = ((lvl*lvl/2) + dice(lvl,13));
else if (parts == 6) golem->max_hit = ((lvl*lvl/2) + dice(lvl,15));
else if (parts == 7) golem->max_hit = ((lvl*lvl/2) + dice(lvl,18));
else golem->max_hit = ((lvl*lvl/2) + dice(lvl,20));
golem->hit = golem->max_hit;
golem->max_move = ch->max_move;
golem->move = golem->max_move;
char_to_room(golem,ch->in_room);
SET_BIT(golem->affected_by, AFF_CHARM);
add_follower(golem, ch);
golem->leader = ch;
return;
}
void spell_greater_golem(int sn,int level, CHAR_DATA *ch,void *vo,int target)
{
CHAR_DATA *golem, *check;
AFFECT_DATA af;
if (is_affected(ch,sn))
{
send_to_char("You aren't up to fashioning another golem yet.\n\r",ch);
return;
}
for (check = char_list; check != NULL; check = check->next)
{
if (IS_NPC(check))
if ( (check->master == ch) && (check->pIndexData->vnum == MOB_VNUM_G_GOLEM) )
{
send_to_char("You already have a golem under your command.\n\r",ch);
return;
}
}
init_affect(&af);
af.where = TO_AFFECTS;
af.level = level;
af.location = 0;
af.modifier = 0;
af.duration = 35;
af.bitvector = 0;
af.type = sn;
af.aftype = AFT_SPELL;
af.affect_list_msg = str_dup("unable to summon a greater golem");
affect_to_char(ch,&af);
act("$n fashions an iron golem!",ch,0,0,TO_ROOM);
send_to_char("You fashion an iron golem to serve you!\n\r",ch);
golem = create_mobile(get_mob_index(MOB_VNUM_G_GOLEM) );
golem->level = ch->level;
golem->damroll = (5 + 2*level/3);
golem->max_hit = level*level;
golem->hit = golem->max_hit;
golem->max_move = ch->max_move;
golem->move = golem->max_move;
char_to_room(golem,ch->in_room);
SET_BIT(golem->affected_by, AFF_CHARM);
add_follower(golem, ch);
golem->leader = ch;
return;
}
void spell_animate_dead( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *zombie, *search;
OBJ_DATA *corpse, *obj, *obj_next;
AFFECT_DATA af;
char *name, *last_name;
char *obj_name;
char buf1[MSL], buf2[MSL];
int chance, z_level, control;
if (level == 72)
target_name = "corpse";
if ((is_affected(ch,sn) || is_affected(ch,skill_lookup("mummify"))) && level < 70)
{
send_to_char("You have not yet regained your powers over the dead.\n\r",ch);
return;
}
control = 0;
for (search = char_list; search != NULL; search = search->next)
{
if (IS_NPC(search) && (search->master == ch) && search->pIndexData->vnum == MOB_VNUM_ZOMBIE)
control += 6;
else if (IS_NPC(search) && (search->master == ch) && search->pIndexData->vnum == MOB_VNUM_SKELETON)
control += 4;
else if (IS_NPC(search) && (search->master == ch) && search->pIndexData->vnum == MOB_VNUM_MUMMY)
control += 12;
}
control += 4;
if ((ch->level < 30 && control > 12) || (ch->level < 35 && control > 18)
|| (ch->level < 40 && control > 24) || (ch->level < 52 && control > 30)
|| control >= 36)
{
send_to_char("You already control as many undead as you can.\n\r",ch);
return;
}
if (target_name[0] == '\0')
{
send_to_char("Animate which corpse?\n\r",ch);
return;
}
obj_name = str_dup(target_name);
corpse = get_obj_here(ch, obj_name);
if (corpse == NULL)
{
send_to_char("You can't animate that.\n\r",ch);
return;
}
if ((corpse->item_type != ITEM_CORPSE_NPC) && (corpse->item_type != ITEM_CORPSE_PC) )
{
send_to_char("You can't animate that.\n\r",ch);
return;
}
if (is_set(&corpse->extra_flags,CORPSE_NO_ANIMATE))
{
send_to_char("That corpse can not sustain further life beyond the grave.\n\r",ch);
return;
}
name = corpse->short_descr;
for (obj = corpse->contains; obj != NULL; obj = obj_next)
{
obj_next = obj->next_content;
obj_from_obj(obj);
obj_to_room(obj,ch->in_room);
}
init_affect(&af);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = 12;
af.modifier = 0;
af.location = 0;
af.bitvector = 0;
af.affect_list_msg = str_dup("unable to attempt animating the dead");
af.aftype = AFT_SPELL;
if (level < 70)
affect_to_char(ch,&af);
chance = get_skill(ch,sn);
if (ch->level < corpse->level)
{
chance += (3*ch->level);
chance -= (3*corpse->level);
}
chance = URANGE(20,chance,90);
if (number_percent() > chance)
{
act("You fail and destroy $p",ch,corpse,NULL,TO_CHAR);
act("$n tries to animate a corpse but destroys it.",ch,NULL,NULL,TO_ROOM);
extract_obj(corpse);
return;
}
act("$n utters an incantation and a burning red glow flares into the eyes of $p.",ch,corpse,NULL,TO_ROOM);
act("$p shudders and comes to life!",ch,corpse,NULL,TO_ROOM);
act("You call upon the powers of the dark to give life to $p.",ch,corpse,NULL,TO_CHAR);
zombie = create_mobile(get_mob_index(MOB_VNUM_ZOMBIE));
z_level = UMAX(1,corpse->level - number_range(3,6));
zombie->level = z_level;
zombie->max_hit = (dice(z_level, 15));
zombie->max_hit += (z_level * 20);
zombie->hit = zombie->max_hit;
zombie->damroll += (z_level*7/10);
zombie->alignment = -1000;
last_name = name;
last_name = one_argument(corpse->short_descr, name);
last_name = one_argument(last_name,name);
last_name = one_argument(last_name,name);
name = last_name;
extract_obj(corpse);
sprintf( buf1, "the zombie of %s", name);
sprintf( buf2, "A zombie of %s is standing here.\n\r", name);
free_string(zombie->short_descr);
free_string(zombie->long_descr);
zombie->short_descr = str_dup(buf1);
zombie->long_descr = str_dup(buf2);
char_to_room(zombie,ch->in_room);
SET_BIT(zombie->affected_by, AFF_CHARM);
add_follower(zombie,ch);
zombie->leader = ch;
return;
}
void spell_mummify( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *mummy, *search;
OBJ_DATA *corpse, *obj, *obj_next;
AFFECT_DATA af;
char *name, *last_name, *obj_name;
char buf1[MSL], buf2[MSL];
int chance, z_level, control;
if ( (is_affected(ch,skill_lookup("animate dead")) || is_affected(ch,sn)) && level < 70)
{
send_to_char("You have not yet regained your powers to over the dead.\n\r",ch);
return;
}
control = 0;
for (search = char_list; search != NULL; search = search->next)
{
if (IS_NPC(search) && (search->master == ch) && search->pIndexData->vnum == MOB_VNUM_ZOMBIE)
control += 6;
else if (IS_NPC(search) && (search->master == ch) && search->pIndexData->vnum == MOB_VNUM_SKELETON)
control += 4;
else if (IS_NPC(search) && (search->master == ch) && search->pIndexData->vnum == MOB_VNUM_MUMMY)
control += 12;
}
control += 4;
if ((ch->level < 30 && control > 12) || (ch->level < 35 && control > 18)
|| (ch->level < 40 && control > 24) || (ch->level < 52 && control > 30)
|| control >= 36)
{
send_to_char("You already control as many undead as you can.\n\r",ch);
return;
}
if (level >= 70)
target_name = "corpse";
if (target_name[0] == '\0')
{
send_to_char("Attempt to mummify which corpse?\n\r",ch);
return;
}
obj_name = str_dup(target_name);
corpse = get_obj_here(ch, obj_name);
if (corpse == NULL)
{
send_to_char("You can't mummify that.\n\r",ch);
return;
}
if ((corpse->item_type != ITEM_CORPSE_NPC) && (corpse->item_type != ITEM_CORPSE_PC) )
{
send_to_char("You can't mummify and animate that.\n\r",ch);
return;
}
if (is_set(&corpse->extra_flags,CORPSE_NO_ANIMATE))
{
send_to_char("That corpse does not have the stability to be animated anymore.\n\r",ch);
return;
}
name = corpse->short_descr;
for (obj = corpse->contains; obj != NULL; obj = obj_next)
{
obj_next = obj->next_content;
obj_from_obj(obj);
obj_to_room(obj,ch->in_room);
}
init_affect(&af);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = 20;
af.modifier = 0;
af.location = 0;
af.bitvector = 0;
af.aftype = AFT_SPELL;
if (level < 70)
affect_to_char(ch,&af);
chance = get_skill(ch,sn);
if (ch->level < corpse->level)
{
chance += (2*ch->level);
chance -= (2*corpse->level);
}
chance = URANGE(10,chance,90);
if (number_percent() > chance)
{
act("You fail and destroy $p",ch,corpse,NULL,TO_CHAR);
act("$n tries to mummify $p but destroys it.",ch,corpse,NULL,TO_ROOM);
extract_obj(corpse);
return;
}
act("$n utters an incantation and $p slowly stumbles to it's feet.",ch,corpse,NULL,TO_ROOM);
act("$p shudders and slowly stumbles to it's feet!",ch,corpse,NULL,TO_ROOM);
act("You invoke the powers of death and $p slowly rises to it's feet.",ch,corpse,NULL,TO_CHAR);
mummy = create_mobile(get_mob_index(MOB_VNUM_MUMMY));
z_level = UMAX(1,corpse->level - number_range(0,2));
mummy->level = z_level;
mummy->max_hit = (dice(z_level, 25));
mummy->max_hit += (z_level * 25);
mummy->hit = mummy->max_hit;
mummy->damroll += (z_level*4/5);
mummy->alignment = -1000;
last_name = name;
last_name = one_argument(corpse->short_descr, name);
last_name = one_argument(last_name,name);
last_name = one_argument(last_name,name);
name = last_name;
extract_obj(corpse);
sprintf( buf1, "the mummy of %s", name);
sprintf( buf2, "A torn and shredded mummy of %s is standing here.\n\r", name);
free_string(mummy->short_descr);
free_string(mummy->long_descr);
mummy->short_descr = str_dup(buf1);
mummy->long_descr = str_dup(buf2);
char_to_room(mummy,ch->in_room);
add_follower(mummy,ch);
mummy->leader = ch;
af.type = skill_lookup("animate dead");
af.duration = -1;
af.bitvector = AFF_CHARM;
affect_to_char(mummy,&af);
return;
}
void spell_animate_skeleton( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *skeleton, *search;
OBJ_DATA *corpse, *obj, *obj_next;
AFFECT_DATA af;
char *name, *last_name, *obj_name;
char buf1[MSL], buf2[MSL];
int chance, z_level, control = 0, num_skeletons = 0;
if (is_affected(ch,sn))
{
send_to_char("You have not yet regained your powers to animate bones.\n\r",ch);
return;
}
for (search = char_list; search != NULL; search = search->next)
{
if (IS_NPC(search) && (search->master == ch) && search->pIndexData->vnum == MOB_VNUM_ZOMBIE)
control += 6;
else if (IS_NPC(search) && (search->master == ch) && search->pIndexData->vnum == MOB_VNUM_SKELETON)
{
control += 4;
num_skeletons++;
}
else if (IS_NPC(search) && (search->master == ch) && search->pIndexData->vnum == MOB_VNUM_MUMMY)
control += 12;
}
control += 4;
if ((ch->level < 30 && control > 12) || (ch->level < 35 && control > 18)
|| (ch->level < 40 && control > 24) || (ch->level < 52 && control > 30)
|| control >= 36)
{
send_to_char("You already control as many undead as you can.\n\r",ch);
return;
}
if (num_skeletons >= 3)
{
send_to_char("You cannot control any more skeletons.\n\r",ch);
return;
}
if (target_name[0] == '\0')
{
send_to_char("Animate which skeleton?\n\r",ch);
return;
}
obj_name = str_dup(target_name);
corpse = get_obj_here(ch, obj_name);
if (corpse == NULL)
{
send_to_char("You can't animate that.\n\r",ch);
return;
}
if (corpse->item_type != ITEM_SKELETON)
{
send_to_char("You can't animate that.\n\r",ch);
return;
}
if (is_set(&corpse->extra_flags,CORPSE_NO_ANIMATE))
{
send_to_char("That skeleton does not have the stability to be animated anymore.\n\r",ch);
return;
}
name = corpse->short_descr;
for (obj = corpse->contains; obj != NULL; obj = obj_next)
{
obj_next = obj->next_content;
obj_from_obj(obj);
obj_to_room(obj,ch->in_room);
}
chance = get_skill(ch,sn);
if (ch->level < corpse->level)
{
chance += (4*ch->level);
chance -= (3*corpse->level);
}
chance = URANGE(10,chance,95);
if (number_percent() > chance)
{
act("You fail and destroy $p",ch,corpse,NULL,TO_CHAR);
act("$n tries to animate a skeleton but destroys it.",ch,NULL,NULL,TO_ROOM);
extract_obj(corpse);
return;
}
act("$n utters an incantation and $p slowly stumbles to it's feet.",ch,corpse,NULL,TO_ROOM);
act("$p shudders and slowly stumbles to it's feet!",ch,corpse,NULL,TO_ROOM);
act("You invoke the powers of death and $p slowly rises to it's feet.",ch,corpse,NULL,TO_CHAR);
skeleton = create_mobile(get_mob_index(MOB_VNUM_SKELETON));
z_level = UMAX(1,corpse->level - number_range(6,11));
skeleton->level = z_level;
skeleton->max_hit = (dice(z_level, 12));
skeleton->max_hit += (z_level * 15);
skeleton->hit = skeleton->max_hit;
skeleton->damroll += (z_level*2/3);
skeleton->alignment = -1000;
last_name = name;
last_name = one_argument(corpse->short_descr, name);
last_name = one_argument(last_name,name);
last_name = one_argument(last_name,name);
name = last_name;
extract_obj(corpse);
sprintf( buf1, "the skeleton of %s", name);
sprintf( buf2, "A skeleton of %s is standing here.\n\r", name);
free_string(skeleton->short_descr);
free_string(skeleton->long_descr);
skeleton->short_descr = str_dup(buf1);
skeleton->long_descr = str_dup(buf2);
char_to_room(skeleton,ch->in_room);
add_follower(skeleton,ch);
skeleton->leader = ch;
init_affect(&af);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.duration = 8;
af.modifier = 0;
af.location = 0;
af.bitvector = 0;
affect_to_char(ch,&af);
af.type = skill_lookup("animate dead");
af.duration = -1;
af.bitvector = AFF_CHARM;
affect_to_char(skeleton,&af);
return;
}