From: Bloodbath <ajetter@topeka.cjnetworks.com>

                              Smite Code!

   Here's how it works:
   Immortals use "retribution" to create a message of what the players see
   when they are smited, it works the same way description does. To smite
   someone, you type: smite <victim> <hp> <mana> <move> <position> <equipment>
   Where <victim> is the person to be smited, <hp> <mana> amd <move> are the
   percentages from 1 - 95 of how much damage you want to do to the player.
   Position is what position you want to set the victim to, currently only
   "stun", "sleep", "rest", "sit", and "stand" are allowed, "dead", "mortal",
   "incap", and "fight" are just there so the system works correctly. Finally,
   equipment is one piece of equipment you want to knock off from the player.

   This code isn't perfect, but please be considerate since I spent long hours
   coding this correctly. Thanks =)


   In Merc.h, since we need to save the smite somewhere, stick this
   in pc_data:

   char * smite;

   You need to declare smite once in Interp.c, and also Interp.h. Just use
   the other code as an example, it's pretty easy.

   In Save.c, so that we can save smite to the pfile, under the function
   fwrite_char put this in around where bamfin and bamout are:

   if (ch->pcdata->smite[0] != '\0')
            fprintf( fp, "Smite %s~\n",     ch->pcdata->smite);

   Also in Save.c, under the function load_char_obj, stick this next to
   bamfin and bamfout:

   ch->pcdata->smite                   = str_dup( "" );

   Finally in Save.c, under the function fread_char, next to the case 's':
   thing, stick this in:

   KEY( "Smite",       ch->pcdata->smite,      fread_string( fp ) );

   In recycle.c, in the free_pcdata function, add this in next to bamfin and
   bamfout:

   free_string(pcdata->smite);

   Now for the REAL code. I have this in fight.c, but I can see it in
   act_wiz.c too, it doesn't really matter. First of all, add these tables to
   the top of fight.c (or where ever you're putting the smite code):  

/*
 *  Tables for smite
 */
char *const pos_table[]=
{
"dead", "mortal", "incap", "stun", "sleep", "rest", "sit", "fight", "stand",
NULL
};

char *const eq_table[]=
{
"light", "finger_l", "finger_r", "neck_1", "neck_2", "torso", "head", "legs",
"feet", "hands", "arms", "shield", "body", "waist", "wrist_l", "wrist_r",
"wield", "hold", "float", NULL
};


NOTE - Don't rearrange the tables above unless you know what you're doing!
       How smite works is based on how these are set up, check merc.h where
       it defines positions and equipment to see what I'm talking about...

Now, put all this code at the bottom of the file (act_wiz.c or fight.c):

/* This code was developed and made by Bloodbath, with the help and ideas of
   Guyver. */

void do_retribution( CHAR_DATA *ch, char *argument )
{
    char buf[MAX_STRING_LENGTH];

    if ( IS_NPC(ch) )
        return;

    if ( argument[0] != '\0' )
    {
	buf[0] = '\0';
	smash_tilde( argument );

    	if (argument[0] == '-')
    	{
            int len;
            bool found = FALSE;
 
            if (ch->pcdata->smite == NULL || ch->pcdata->smite[0] == '\0')
            {
                send_to_char("No lines left to remove.\n\r",ch);
                return;
            }
	
            strcpy(buf,ch->pcdata->smite);
 
            for (len = strlen(buf); len > 0; len--)
            {
                if (buf[len] == '\r')
                {
                    if (!found)  /* back it up */
                    {
                        if (len > 0)
                            len--;
                        found = TRUE;
                    }
                    else /* found the second one */
                    {
                        buf[len + 1] = '\0';
                        free_string(ch->pcdata->smite);
                        ch->pcdata->smite = str_dup(buf);
                        send_to_char( "Your divine fury takes the form of:\n\r", ch );
                        send_to_char( ch->pcdata->smite ? ch->pcdata->smite : 
			    "(None).\n\r", ch );
                        return;
                    }
                }
            }
            buf[0] = '\0';
            free_string(ch->pcdata->smite);
            ch->pcdata->smite = str_dup(buf);
            send_to_char("Mortals no longer need fear your mark upon them.\n\r",ch);
	    return;
        }
	if ( argument[0] == '+' )
	{
            if ( ch->pcdata->smite != NULL )
                strcat( buf, ch->pcdata->smite );
	    argument++;
	    while ( isspace(*argument) )
		argument++;
	}

        if ( strlen(buf) >= 1024)
	{
            send_to_char( "Your fury is great indeed, too great.  Use less lines.\n\r", ch );
	    return;
	}

	strcat( buf, argument );
	strcat( buf, "\n\r" );
        free_string( ch->pcdata->smite );
        ch->pcdata->smite = str_dup( buf );
    }

    send_to_char( "Your divine fury takes the form of:\n\r", ch );
    send_to_char( ch->pcdata->smite ? ch->pcdata->smite : "(None).\n\r", ch );
    return;
}


void do_smite( CHAR_DATA *ch, char *argument )
{
    char arg1 [MAX_INPUT_LENGTH];  /* Lot of arguments */
    char arg2 [MAX_INPUT_LENGTH];
    char arg3 [MAX_INPUT_LENGTH];
    char arg4 [MAX_INPUT_LENGTH];
    char arg5 [MAX_INPUT_LENGTH];
    char arg6 [MAX_INPUT_LENGTH];
    char buf[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;
    OBJ_DATA *SmittenEQ;
    const int MAX_SMITE_FRACTION = 95;  /* You can change this if you want */
    int hp_percent = 0;
    int mana_percent = 0;
    int move_percent = 0;
    int pos = 0;
    int eq = 0;

    argument = one_argument( argument, arg1 );  /* Combine the arguments */
    argument = one_argument( argument, arg2 );
    argument = one_argument( argument, arg3 );
    argument = one_argument( argument, arg4 );
    argument = one_argument( argument, arg5 );
    argument = one_argument( argument, arg6 );

    if ( IS_NPC(ch) )  /* NPCs may get to be smited, but switch immortals can't */
        return;

    if ( arg1[0] == '\0' )
    {
	send_to_char( "Syntax:\n\r",ch);
        send_to_char( "Smite <victim> <hp> <mana> <move> <position> <equipment>\n\r",ch);
	return;
    }

    if ( ( victim = get_char_world( ch, arg1 ) ) == NULL )
    {
        send_to_char( "They are saved only through their abscence.\n\r",ch);
	return;
    }

    if (!IS_NPC(victim) && victim->level >= get_trust(ch))
    {
        send_to_char("Your reach exceeds your grasp.\n\r",ch);
        return;
    }

    if ( arg2[0] != '\0' )
        hp_percent = atoi( arg2 );
    else
        hp_percent = 50;

    if ( hp_percent > MAX_SMITE_FRACTION || hp_percent < 0 )
    {
        send_to_char("Hp percent must be between 0 and 95.\n\r", ch );
        return;
    }
 
    if ( arg3[0] != '\0' )
        mana_percent = atoi( arg3 );
    else
        mana_percent = 0;

    if ( mana_percent > MAX_SMITE_FRACTION || mana_percent < 0 )
    {
        send_to_char("Mana percent must be between 0 and 95.\n\r", ch );
        return;
    }
    
    if ( arg4[0] != '\0' )
        move_percent = atoi( arg4 );
    else
        move_percent = 0;

    if ( move_percent > MAX_SMITE_FRACTION || move_percent < 0 )
    {
        send_to_char("Move percent must be between 0 and 95.\n\r", ch );
        return;
    }
    
    /* Customize stuff by alignment */

    if (ch->alignment > 300)
    {                                                                                                                                   
        act_new("Your actions have brought the holy power of $n upon you!",ch,NULL,victim,TO_VICT,POS_DEAD);
        act_new("$N has brought the holy power of $n upon themselves!",ch,NULL,victim,TO_NOTVICT,POS_DEAD);                                              
    }
    if (ch->alignment > -301 && ch->alignment < 301)
    {
        act_new("Your actions have called the divine fury of $n upon you!",ch,NULL,victim,TO_VICT,POS_DEAD);
        act_new("$N has called the divine fury of $n upon themselves!",ch,NULL,victim,TO_NOTVICT,POS_DEAD);
    }
    if (ch->alignment < -300)
    {
        act_new("You are struck down by the infernal power of $n!!",ch,NULL,victim,TO_VICT,POS_DEAD);
        act_new("The hellspawned, infernal power of $n has struck down $N!!",ch,NULL,victim,TO_NOTVICT,POS_DEAD);
    }

    /* This is where the thing we did in retribution is used */

    if ( ch->pcdata->smite[0] != '\0' )
    {
        send_to_char( ch->pcdata->smite, victim );
    }

    /* If it REALLY hurt */

    if ( hp_percent > 75 && victim->hit > victim->max_hit / 4 )
        send_to_char( "{RThat really did HURT!{x\n\r", victim );

    /* Let's see if equipment needs to be 'blown away' */

    for ( eq = 0; eq_table[eq] != NULL; eq++ )
    {
        if ( !str_prefix( eq_table[eq], arg6 ) )
        {
            if ( ( SmittenEQ = get_eq_char( victim, eq ) ) != NULL )
            {
                sprintf( buf, "$n's %s is blown away!", SmittenEQ->short_descr);
                act( buf, victim, NULL, NULL, TO_ROOM);
                sprintf( buf, "Your %s is blown away!\n\r", SmittenEQ->short_descr);
                send_to_char( buf, victim );

                unequip_char( victim, SmittenEQ );
                obj_from_char( SmittenEQ );
                obj_to_room( SmittenEQ, victim->in_room );
            }
            break;
        }
    }

    /* Let's see what position to put the victim in */

    for ( pos = 0; pos_table[pos] != NULL; pos++ )
    {
        if ( !str_prefix( pos_table[pos], arg5 ) )
        {
            victim->position = pos;                 /* This only works because of the way the pos_table is arranged. */
            if ( victim->position == POS_FIGHTING ) 
                victim->position = POS_STANDING;     /* POS_FIGHTING is bad */

            if ( victim->position < POS_STUNNED )
                victim->position = POS_STUNNED;

            if ( victim->position == POS_STUNNED )
            {
                act( "$n is stunned, but will probably recover.",victim, NULL, NULL, TO_ROOM );
                send_to_char("You are stunned, but will probably recover.\n\r",victim );
            }    

            if ( victim->position == POS_RESTING || victim->position == POS_SITTING )
            {
                act("$n is knocked onto $s butt!", victim, NULL, NULL, TO_ROOM );
                send_to_char("You are knocked onto your butt!\n\r", victim );
            }
            break;
        }
    }

    /* Calculate total hp loss */
    victim->hit -= ( ( victim->hit * hp_percent ) / 100 );
    if ( victim->hit < 1 )
        victim->hit = 1;

    /* Calculate total mana loss */
    victim->mana -= ( ( victim->mana * mana_percent ) / 100 );
    if ( victim->mana < 1 )
       victim->mana = 1;

    /* Calculate total move loss */
    victim->move -= ( ( victim->move * move_percent ) / 100 );
    if ( victim->move < 1 )
        victim->move = 1;

    send_to_char("Your will is done, your power felt.\n\r",ch);
    return;
}



   That's it! Feel free to use this code how you please :)
   A little credit here and there would be nice, but not
   really necessary. If you find any bugs or add some
   improvents, please send me an E-mail! ( ajetter@cjnetworks.com )
   -- Bloodbath

