ackfuss-4.4.0/board/
ackfuss-4.4.0/help/e/
ackfuss-4.4.0/help/f/
ackfuss-4.4.0/help/h/
ackfuss-4.4.0/help/l/
ackfuss-4.4.0/help/n/
ackfuss-4.4.0/help/q/
ackfuss-4.4.0/help/s/
ackfuss-4.4.0/help/u/
ackfuss-4.4.0/help/v/
ackfuss-4.4.0/help/y/
ackfuss-4.4.0/help/z/
ackfuss-4.4.0/player/c/
/***************************************************************************
 *  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.                              *
 *                                                                         *
 *  Ack 2.2 improvements copyright (C) 1994 by Stephen Dooley              *
 *                                                                         *
 *  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.                                               *
 *                                                                         *
 *       _/          _/_/_/     _/    _/     _/    ACK! MUD is modified    *
 *      _/_/        _/          _/  _/       _/    Merc2.0/2.1/2.2 code    *
 *     _/  _/      _/           _/_/         _/    (c)Stephen Zepp 1998    *
 *    _/_/_/_/      _/          _/  _/             Version #: 4.3          *
 *   _/      _/      _/_/_/     _/    _/     _/                            *
 *                                                                         *
 *                        http://ackmud.nuc.net/                           *
 *                        zenithar@ackmud.nuc.net                          *
 *  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.                                                  *
 ***************************************************************************/
/***************************************************************************
 * _/_/_/_/  _/    _/  _/_/_/_/ _/_/_/_/ AckFUSS is modified ACK!MUD 4.3.1 *
 * _/        _/    _/  _/       _/       copyright Matt Goff (Kline) 2008  *
 * _/_/      _/    _/  _/_/_/_/ _/_/_/_/                                   *
 * _/        _/    _/        _/       _/ Support for this code is provided *
 * _/        _/_/_/_/  _/_/_/_/ _/_/_/_/ at www.ackmud.net -- check it out!*
 ***************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "globals.h"

#ifndef DEC_ACT_INFO_H
#include "h/act_info.h"
#endif

#ifndef DEC_ACT_MOVE_H
#include "h/act_move.h"
#endif

#ifndef DEC_COMM_H
#include "h/comm.h"
#endif

#ifndef DEC_DB_H
#include "h/db.h"
#endif

#ifndef DEC_FIGHT_H
#include "h/fight.h"
#endif

#ifndef DEC_HANDLER_H
#include "h/handler.h"
#endif

#ifndef DEC_MAGIC_H
#include "h/magic.h"
#endif

#ifndef DEC_SSM_H
#include "h/ssm.h"
#endif

extern bool deathmatch;

/*
 * This file should contain:
 *	o Vamp Spells
 *	o Vamp skills
 *
 */

bool spell_blood_leach( int sn, int level, CHAR_DATA * ch, void *vo, OBJ_DATA * obj )
{
   CHAR_DATA *victim = ( CHAR_DATA * ) vo;
   CHAR_DATA *check;
   std::list<CHAR_DATA *>::iterator li;
   AFFECT_DATA *paf;
   AFFECT_DATA af;

   /*
    * check for vamps 
    */
   if( !IS_VAMP( ch ) )
   {
      send_to_char( "Only vampires are evil enough to use this spell!\r\n", ch );
      return FALSE;
   }

   for( li = char_list.begin(); li != char_list.end(); li++ )
   {
      check = *li;
      for( paf = check->first_affect; paf != NULL; paf = paf->next )
         if( paf->type == sn && paf->caster == ch )
         {
            send_to_char( "You are already maintaining a blood leach on someone else!\r\n", ch );
            return FALSE;
         }
   }

   act( "You create a blood leach and hurl it at $N!", ch, NULL, victim, TO_CHAR );
   act( "$n creates a blood leach and hurls it at $N!", ch, NULL, victim, TO_NOTVICT );
   act( "$n creates a blood leach and hurls it at YOU!", ch, NULL, victim, TO_VICT );

   if( saves_spell( level, victim ) || IS_VAMP( victim ) || is_affected( victim, sn ) )
   {
      send_to_char( "The blood leach misses you, and vanishes!\r\n", victim );
      send_to_char( "The blood leach misses, and vanishes!\r\n", ch );
      act( "The blood leach misses $N, and vanishes!", ch, NULL, victim, TO_NOTVICT );
      return TRUE;
   }

   af.type = sn;
   af.duration = number_range( 2, UMAX( 4, level / 3 ) );
   af.location = APPLY_NONE;
   af.modifier = 0;
   af.bitvector = 0;
   af.caster = ch;

   affect_to_char( victim, &af );

   act( "The blood leach hits $N and burrows into $S skin!", ch, NULL, victim, TO_ROOM );
   send_to_char( "The blood leach hits you, and burrows into your skin!\r\n", victim );
   return TRUE;
}

bool spell_shade( int sn, int level, CHAR_DATA * ch, void *vo, OBJ_DATA * obj )
{
   ROOM_INDEX_DATA *room;
   ROOM_AFFECT_DATA raf;

   room = ch->in_room;

   if( room == NULL )
      return FALSE;

   if( IS_SET( room->affected_by, ROOM_BV_SHADE ) )
   {
      send_to_char( "There is already a shade spell operating here!\r\n", ch );
      return FALSE;
   }

   if( !IS_OUTSIDE( ch ) )
   {
      send_to_char( "It might help if you tried this outside...\r\n", ch );
      return FALSE;
   }

   act( "$n throws a dark shadow into the air.", ch, NULL, NULL, TO_ROOM );
   send_to_char( "You throw a dark shadow into the air.\r\n", ch );

   raf.type = sn;
   raf.duration = ( level / 8 ) + number_range( 1, 3 );
   raf.level = level;
   raf.bitvector = ROOM_BV_SHADE;
   raf.caster = ch;
   affect_to_room( room, &raf );
   return TRUE;
}


bool spell_embrace( int sn, int level, CHAR_DATA * ch, void *vo, OBJ_DATA * obj )
{
   CHAR_DATA *victim = ( CHAR_DATA * ) vo;

   if( !IS_VAMP( ch ) )
   {
      send_to_char( "Better leave that to the REAL Vampyres, you wanna be!!!\r\n", ch );
      return FALSE;
   }
   if( ch->pcdata->super->bloodline == 0 )
   {
      send_to_char( "@@dRENEGADES@@n can't embrace!!!\r\n", ch );
      return FALSE;
   }

   if( IS_VAMP( victim ) )
   {
      send_to_char( "@@NYour @@dchosen@@N has already been @@eEmbraced@@N!!!.\r\n", ch );
      return FALSE;
   }

   if( IS_WOLF( victim ) )
   {
      send_to_char( "A sudden awareness comes over you, as you peer into their soul and see a @@bGarou@@N!!!\r\n", ch );
      if( !IS_AWAKE( victim ) )
         do_wake( victim, "" );
      if( victim->position < POS_STANDING )
         do_stand( victim, "" );
      if( ch->position < POS_STANDING )
         do_stand( ch, "" );
      one_hit( ch, victim, TYPE_UNDEFINED );
      return FALSE;
   }

   if( IS_NPC( victim ) )
   {
      send_to_char( "Fergit it bub!!\r\n", ch );
      return FALSE;
   }

/*    if ( victim->clan == 7 )
     {
       send_to_char( "@@mNO WAY!!!!!@@W They are @@dKindred @@eKillers!!!!!@@N\r\n", ch );
       return FALSE;
     }
*/
   if( victim->position > POS_SLEEPING )
   {
      /*
       * failure 
       */
      act( "$N is far too alert to let you do that!", ch, NULL, victim, TO_CHAR );
      return FALSE;
   }
   else

   {

      victim->pcdata->super->level = 1;
      victim->pcdata->super->exp = 0;
      victim->pcdata->super->skills_learned = 0;
      victim->pcdata->super->skills_max = 2;
      if( victim->pcdata->super->generation == -1 )
         victim->pcdata->super->generation = ch->pcdata->super->generation + 2;
      else
         victim->pcdata->super->generation = ch->pcdata->super->generation + 1;

      if( victim->pcdata->super->generation < 4 )
         victim->pcdata->super->generation = 5;
      victim->pcdata->super->bloodline = ch->pcdata->super->bloodline;
      victim->pcdata->super->energy = -10;
      victim->pcdata->super->energy_max = 20;
      victim->act.set(ACT_VAMPIRE);
      victim->pcdata->condition[COND_FULL] = 20;
      victim->pcdata->condition[COND_THIRST] = 20;
      victim->pcdata->super->pracs = 2;
      ch->pcdata->super->energy_max -= 5;
      victim->pcdata->recall_vnum = 9001;


      send_to_char( "@@NYou sink your fangs into your helpless victim.\r\n", ch );
      send_to_char( "Then, in the final death throes, you bite your own arm and allow the @@eblood@@N\r\n", ch );
      send_to_char( "to drip into their mouth, damning them to @@dETERNAL NIGHT@@N!!!\r\n", ch );
      send_to_char( "you feel some of your essential @@eblood@@N potential drain into your victim!\r\n", ch );
      send_to_char( "@@NYou feel your soul ripped asunder as the Vampyre draws your lifeblood into it's mouth!!\r\n",
                    victim );
      send_to_char( "As your last breath escapes you, and you begin to submit to death itself, you suddenly feel\r\n",
                    victim );
      send_to_char
         ( "a hot, coppery tasting fluid enter your mouth.  As the strength of the @@dKindred@@N begins to fill\r\n",
           victim );
      send_to_char( "your veins, your mind is flooded with the sudden knowledge of damnation and @@dEternal Night@@N!!!\r\n",
                    victim );
      send_to_char( "Awakening to a new knowledge of your status as a @@eChosen@@N, you know that upon your\r\n", victim );
      send_to_char( "first taste of mortal @@eblood@@N, you shall forever enter the ranks of the @@dKindred@@N!!\r\n",
                    victim );
      send_to_char( "A choice awaits you....shall you accept this destiny and feed upon mortals, or shall you\r\n", victim );
      send_to_char( "seek @@Wcleansing@@N from this @@dEternal Damnation@@N???\r\n", victim );

      victim->pcdata->learned[skill_lookup( "feed" )] = 90;
   }



   return TRUE;
}


void do_family( CHAR_DATA * ch, char *argument )
{


   char buf[MAX_STRING_LENGTH];
   CHAR_DATA *victim;
   DESCRIPTOR_DATA *d;
   bool found;
   short index;

   if( ch->level < 85 )
      if( !IS_VAMP( ch ) )
      {
         send_to_char( "Huh?\r\n", ch );
         return;
      }
   if( get_trust( ch ) == 85 )
   {
      for( index = 0; index <= 4; index++ )
      {
         switch ( index )
         {
            case 0:
               snprintf( buf, MSL, "\r\n@@WNOT SET@@N\r\n" );
               break;
            case 1:
               snprintf( buf, MSL, "\r\n@@WNOT SET@@N\r\n" );
               break;
            case 2:
               snprintf( buf, MSL, "\r\n@@WNOT SET@@N\r\n" );
               break;
            case 3:
               snprintf( buf, MSL, "\r\n@@WNOT SET@@N\r\n" );
               break;
            case 4:
               snprintf( buf, MSL, "\r\n@@WNOT SET@@N\r\n" );
               break;
         }

         send_to_char( buf, ch );
         found = FALSE;
         for( d = first_desc; d != NULL; d = d->next )
         {
            if( d->connected == CON_PLAYING
                && ( victim = d->character ) != NULL && !IS_NPC( victim ) && victim->in_room != NULL )
            {
               if( IS_VAMP( victim ) && ( victim->pcdata->super->bloodline == index ) )
               {
                  found = TRUE;
               }
               else
                  continue;



               snprintf( buf, MSL, "%-15s @@NGen: @@r%d   @@NRank: @@d%d@@N  @@NBloodlust: @@e%d@@N/@@e%d@@N   %-15s\r\n",
                        victim->name, victim->pcdata->super->generation, victim->pcdata->super->level, victim->pcdata->super->energy,
                        victim->pcdata->super->energy_max, victim->in_room->name );
               send_to_char( buf, ch );
            }
         }

         if( !found )
            send_to_char( "@@NNo @@dKindred@@N Family members were found.\r\n", ch );

      }
   }
   else
   {

      snprintf( buf, MSL, "@@WMembers of the @@dKindred @@NFamily %s\r\n", get_family_name( ch ) );
      send_to_char( buf, ch );
      found = FALSE;
      for( d = first_desc; d != NULL; d = d->next )
      {
         if( d->connected == CON_PLAYING
             && ( victim = d->character ) != NULL
             && !IS_NPC( victim ) && victim->in_room != NULL && IS_VAMP( victim ) && !IS_IMMORTAL( victim ) )
         {
            if( victim->pcdata->super->bloodline != ch->pcdata->super->bloodline )
               continue;

            found = TRUE;
            snprintf( buf, MSL, "%-15s @@NGeneration: @@r%d     @@NRank: @@d%d@@N\r\n",
                     victim->name, victim->pcdata->super->generation, victim->pcdata->super->level );
            send_to_char( buf, ch );
         }
      }

      if( !found )
         send_to_char( "@@NNo other @@dKindred @@N Family members were found.\r\n", ch );

   }
   return;
}

void do_instruct( CHAR_DATA * ch, char *argument )
{
   char arg[MAX_STRING_LENGTH];
   CHAR_DATA *victim;
   int sn;
   char buf[MAX_STRING_LENGTH];


   if( !IS_NPC( ch ) && ch->pcdata->learned[gsn_instruct] == 0 )
   {
      send_to_char( "You are not trained in this skill!\r\n", ch );
      return;
   }


   argument = one_argument( argument, arg );

   if( arg[0] == '\0' )
   {
      send_to_char( "Instruct who?\r\n", ch );
      return;
   }

   victim = get_char_room( ch, arg );
   if( victim == NULL )
   {
      send_to_char( "Couldn't find the target.\r\n", ch );
      return;
   }
   if( victim == ch )
   {
      send_to_char( "Oh yeah, that would help a lot!\r\n", ch );
      return;
   }

   if( !IS_VAMP( victim ) )
   {
      send_to_char( "@@eWHAT????@@N You want to teach @@dKindred@@N skills to someone not @@eCHOSEN@@N? NO WAY!!", ch );
      return;
   }

/* okay, we know the victim is good, and a vamp..check for skill known, levels, etc. */

   one_argument( argument, arg );
   sn = skill_lookup( arg );

   if( ch->pcdata->super->bloodline != victim->pcdata->super->bloodline )
   {
      send_to_char( "There not a member of your family!!\r\n", ch );
      return;
   }


   if( ch->pcdata->learned[sn] == 0 || skill_table[sn].flag2 != VAMP )

   {
      send_to_char( "@@NYou don't know that @@dKindred@@N skill!.\r\n", ch );
      return;
   }
   if( victim->pcdata->learned[sn] != 0 )
   {
      send_to_char( "They already know that skill.\r\n", ch );
      return;
   }

   if( victim->pcdata->super->level < skill_table[sn].skill_level[victim->pcdata->super->bloodline] )
   {
      send_to_char( "@@NThey are too inexperienced in the ways of the @@dKindred@@N to learn this skill.\r\n", ch );
      send_to_char( "@@NYou are to inexperienced in the ways of the @@dKindred@@N to learn this skill.\r\n", victim );
      return;
   }

   if( victim->pcdata->super->skills_learned >= victim->pcdata->super->skills_max )
   {
      send_to_char( "They seem unable to grasp the knowledge.\r\n", ch );
      send_to_char( "@@NYou are unable to learn any more @@dKindred@@N knowledge at this time.\r\n", victim );
      return;
   }

/* Okay, the skill is good, the instructor knows it, and the victim doesn't  */

   victim->pcdata->learned[sn] = 90;
   victim->pcdata->super->pracs -= 1;
   victim->pcdata->super->skills_learned += 1;

   send_to_char( "You have taught them another way of the @@dKindred@@N!!!\r\n", ch );
   snprintf( buf, MSL, "You are now learned in the way of @@e%s@@N!!!\r\n", skill_table[sn].name );
   send_to_char( buf, victim );


   return;
}

bool spell_mesmerise( int sn, int level, CHAR_DATA * ch, void *vo, OBJ_DATA * obj )
{
   CHAR_DATA *victim = ( CHAR_DATA * ) vo;
   /*
    * check for vamps 
    */
   if( !IS_VAMP( ch ) )
   {
      send_to_char( "Only vampires are evil enough to use this spell!\r\n", ch );
      return FALSE;
   }



   act( "You stare into $S eyes!", ch, NULL, victim, TO_CHAR );
   act( "$n stares into $S eyes!", ch, NULL, victim, TO_NOTVICT );
   act( "$n stares into your eyes!", ch, NULL, victim, TO_VICT );

   if( saves_spell( level, victim ) || IS_VAMP( victim ) || is_affected( victim, sn ) )
   {

      return TRUE;
   }
   send_to_char( " Spell removed for now.\r\n", ch );
   return FALSE;
   set_stun( victim, level / 1 );

   act( "$N seems to be mesmerized!", ch, NULL, victim, TO_ROOM );
   send_to_char( "You are mesmerised!\r\n", victim );
   return TRUE;
}

bool spell_cloak_darkness( int sn, int level, CHAR_DATA * ch, void *vo, OBJ_DATA * obj )
{

   AFFECT_DATA af;
   if( IS_NPC( ch ) )
   {
      send_to_char( "Not for NPCS!\r\n", ch );
      return FALSE;
   }

   if( is_affected( ch, sn ) )
      return FALSE;

   af.type = sn;
   af.duration = ch->pcdata->super->level;
   af.location = 0;
   af.modifier = 0;
   af.bitvector = 0;
   affect_to_char( ch, &af );

   return TRUE;
}


bool spell_blood_walk( int sn, int level, CHAR_DATA * ch, void *vo, OBJ_DATA * obj )
{


   CHAR_DATA *victim = ( CHAR_DATA * ) vo;

   if( deathmatch )
   {
      send_to_char( "Not during a @@eDeath Match@@N!!\r\n", ch );
      return FALSE;
   }
   if( ( victim = get_char_world( ch, target_name ) ) == NULL
       || victim == ch
       || !IS_NPC( victim )
       || victim->in_room == NULL
       || victim->in_room->room_flags.test(RFLAG_PRIVATE)
       || victim->in_room->room_flags.test(RFLAG_SOLITARY)
       || victim->in_room->room_flags.test(RFLAG_SAFE)
       || victim->act.test(ACT_NO_BLOOD)
       || victim->in_room->room_flags.test(RFLAG_NO_BLOODWALK)
       || ( ( get_psuedo_level( victim ) - get_psuedo_level( ch ) ) > 20 ) )
   {
      send_to_char( "Your @@eblood@@N burns with rage, as your efforts are shaken off.\r\n", ch );
      return TRUE;
   }
   if( ( time_info.hour < 19 ) && ( time_info.hour > 5 ) )
   {
      send_to_char( "@@NYou may only @@eblood walk@@N at night!!\r\n", ch );
      return FALSE;
   }


   if( victim->act.test(ACT_NO_VISIT) )
   {
      send_to_char( "You cannot sense your target's @@eblood@@N!\r\n", ch );
      return TRUE;
   }

   if( victim->in_room->room_flags.test(RFLAG_NO_BLOODWALK) )
   {
      send_to_char( "You cannot sense your target's @@eblood@@N!\r\n", ch );
      return FALSE;
   }

   if( victim->act.test(ACT_NO_BLOOD) )
   {
      send_to_char( "You cannot sense your target's @@eblood@@N!\r\n", ch );
      return FALSE;
   }

   act( "$n fades into the darkness.", ch, NULL, NULL, TO_ROOM );
   char_from_room( ch );
   char_to_room( ch, victim->in_room );
   act( "$n steps forth from the shadows.", ch, NULL, NULL, TO_ROOM );
   send_to_char( "@@NYou feel yourself drawn to the @@eblood@@N within your victim!\r\n", ch );
   do_look( ch, "auto" );
   return TRUE;
}

bool spell_blood_sign( int sn, int level, CHAR_DATA * ch, void *vo, OBJ_DATA * obj )
{

   MARK_DATA *mark;
   char buf[MSL];
   char *costring;

   if( IS_NPC( ch ) || ( !IS_VAMP( ch ) ) )
      return FALSE;

   if( target_name[0] == '\0' )
   {
    send_to_char("You can't leave an empty sign!\r\n",ch);
    return FALSE;
   }

   mark = new MARK_DATA;

   mark->room_vnum = ch->in_room->vnum;
   mark->message = str_dup( target_name );
   switch ( ( int )ch->pcdata->super->level / 4 )
   {
      case 0:
         costring = "@@a";
         break;
      case 1:
         costring = "@@c";
         break;
      case 2:
         costring = "@@R";
         break;
      case 3:
         costring = "@@m";
         break;
      case 4:
         costring = "@@e";
         break;
      default:
         costring = "@@m";
         break;
   }
   snprintf( buf, MSL, "%s%s @@W: %s", costring, ch->name, get_family_name( ch ) );
   mark->author = str_dup( buf );
   mark->duration = ( ( MAX_VAMP_LEVEL ) - ch->pcdata->super->generation ) * ( ch->pcdata->super->level );
   mark->type = VAMP;
   ch->in_room->mark_list.push_back(mark);
   save_marks();
   return TRUE;
}

bool spell_blood_sense( int sn, int level, CHAR_DATA * ch, void *vo, OBJ_DATA * obj )
{
   std::list<MARK_DATA *>::iterator li;
   MARK_DATA *mk = NULL;

   if( IS_NPC( ch ) || ( !IS_VAMP( ch ) ) )
   {
      send_to_char( "Huh?\r\n", ch );
      return FALSE;
   }

   if( ch->in_room->mark_list.empty() )
   {
      send_to_char( "You do not sense any @@eBloodSign@@N here.\r\n", ch );
      return FALSE;
   }

   for( li = ch->in_room->mark_list.begin(); li != ch->in_room->mark_list.end(); li++ )
   {
      char buf[MSL];
      mk = *li;
      if( mk->type != VAMP )
         continue;

      snprintf( buf, MSL, "%s : %s\r\n", mk->author, mk->message );
      send_to_char( buf, ch );
   }
   return TRUE;
}