EmberMUD/
EmberMUD/clan/
EmberMUD/classes/
EmberMUD/gods/
EmberMUD/log/
EmberMUD/player/
EmberMUD/player/temp/
EmberMUD/src/MSVC/
EmberMUD/src/Sleep/
EmberMUD/src/StartMUD/
EmberMUD/src/Win32Common/
/***************************************************************************
 *  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.                                                  *
 ***************************************************************************/

/***************************************************************************
 * MudProgs has been completely rewritten by Zane.  The only thing that    *
 * remains the same is how triggers are handled.  -Zane                    *
 *                                                                         *
 * Original MobProgs by N'Atas-ha.                                         *
 ***************************************************************************/

#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "merc.h"
#include "mud_progs.h"

/*
 * MudProgs Command table.
 *
 * Format:  { <proc name>,    <proc pointer>,    <arg type> },
 * 
 * Argtype can be one of:
 *
 *     'C'  - Character Pointer (CHAR_DATA *)
 *     'O'  - Object Pointer (OBJ_DATA *)
 *     'I'  - Numeric Value
 *     'S'  - String (char *)
 *     'N'  - No args
 * 
 * Execproc guarantees that the proper argument type is passed to avoid
 * crashes.  If you specify the wrong argtype here and expect a different argtype
 * in your proc then you will crash.  All arguments passed to these procs are of
 * type (void *) and need to be cast to the proper type before used.
 *
 * -Zane
 */

const   struct  mprog_cmd_type        mprog_cmd_table       [] =
{
    { "alignment",      mprog_alignment,   'C' },
    { "class",          mprog_class,       'C' },
    { "crimethief",     mprog_crimethief,  'C' },
    { "fightinroom",    mprog_level,       'N' },
    { "getrand",        mprog_getrand,     'I' },
    { "goldamount",     mprog_goldamount,  'C' },
    { "hasmemory",      mprog_hasmemory,   'N' },
    { "hitpercent",     mprog_hitpercent,  'C' },
    { "hour",           mprog_hour,        'N' },
    { "immune",         mprog_immune,      'C' },
    { "isawake",        mprog_isawake,     'C' },
    { "ischarmed",      mprog_ischarmed,   'C' },
    { "isfight",        mprog_isfight,     'C' },
    { "isfollow",       mprog_isfollow,    'C' },
    { "isimmort",       mprog_isimmort,    'C' },
    { "isgood",         mprog_isgood,      'C' },
    { "isnpc",          mprog_isnpc,       'C' },
    { "ispc",           mprog_ispc,        'C' },
    { "level",          mprog_level,       'C' },
    { "memory",         mprog_memory,      'C' },
    { "mobvnum",        mprog_mobvnum,     'C' },
    { "objtype",        mprog_objtype,     'O' },
    { "objval0",        mprog_objval0,     'O' },
    { "objval1",        mprog_objval1,     'O' },
    { "objval2",        mprog_objval2,     'O' },
    { "objval3",        mprog_objval3,     'O' },
    { "position",       mprog_position,    'C' },
    { "rand",           mprog_rand,        'I' },
    { "roomvnum",       mprog_roomvnum,    'N' },
    { "sex",            mprog_sex,         'C' },
    { "sgetrand",       mprog_sgetrand,    'I' },
    { "sreset",         mprog_sreset,      'N' },
    /*
     * End of list.
     */
    { "",               0,					0, }
};

int mprog_alignment( void *vo )
{
    if ( !vo )
        return FALSE;

    return ((CHAR_DATA *)vo)->alignment;
}

int mprog_class( void *vo )
{
    if ( !vo )
        return FALSE;

    return ((CHAR_DATA *)vo)->Class;
}

int mprog_crimethief( void *vo )
{
    if ( !vo )
        return FALSE;

    return IS_SET(((CHAR_DATA *)vo)->act, PLR_THIEF);
}

int mprog_fightinroom( void *vo )
{
    CHAR_DATA *ch;

    if ( !ProgSource->in_room )
        return FALSE;

    for ( ch = ProgSource->in_room->people; ch; ch = ch->next_in_room )
        if ( ch->fighting )
            return TRUE;

    return FALSE;
}

int mprog_getrand( void *vo )
{
    if ( !vo )
        return FALSE;

    return number_range(1, *((int *)vo));
}

int mprog_goldamount( void *vo )
{
    if ( !vo )
        return FALSE;

    return ((CHAR_DATA *)vo)->gold;
}

int mprog_hasmemory( void *vo )
{
    if ( ProgSource->memory )
        return TRUE;
    else
        return FALSE;
}

int mprog_hitpercent( void *vo )
{
    CHAR_DATA *ch = (CHAR_DATA *)vo;

    if ( !vo )
        return FALSE;

    return (ch->hit/ch->max_hit) * 100;
}

int mprog_hour( void *vo )
{
    return time_info.hour;
}

int mprog_immune( void *vo )
{
    if ( !vo )
        return FALSE;

    return check_immune( (CHAR_DATA *)vo, 
        attack_table[ProgObjectSource->value[3]].damage );
}

int mprog_isawake( void *vo )
{
    if ( !vo )
        return FALSE;

    return IS_AWAKE( ((CHAR_DATA *)vo) );
}

int mprog_ischarmed( void *vo )
{
    if ( !vo )
        return FALSE;

    return IS_SET( ((CHAR_DATA *)vo)->affected_by , AFF_CHARM );
}


int mprog_isfight( void *vo )
{
    if ( !vo )
        return FALSE;

    if ( ((CHAR_DATA *)vo)->fighting )
        return TRUE;

    return FALSE;
}

int mprog_isfollow( void *vo )
{
    CHAR_DATA *ch = (CHAR_DATA *)vo;

    if ( !vo )
        return FALSE;

    return ( ch->master != NULL && ch->master->in_room == ch->in_room );
}

int mprog_isimmort( void *vo )
{
    if ( !vo )
        return FALSE;

    return ( get_trust( (CHAR_DATA *)vo ) >= LEVEL_IMMORTAL );
}

int mprog_isgood( void *vo )
{
    if ( !vo )
        return FALSE;

    return IS_GOOD( ((CHAR_DATA *)vo) );
}

int mprog_isnpc( void *vo )
{
    if ( !vo )
        return FALSE;

    return ( IS_NPC( (CHAR_DATA *)vo ) );
}

int mprog_ispc( void *vo )
{
    if ( !vo )
        return FALSE;

    return ( !IS_NPC( (CHAR_DATA *)vo ) );
}

int mprog_level( void *vo )
{
    if ( !vo )
        return FALSE;

    return ((CHAR_DATA *)vo)->level;
}

int mprog_memory( void *vo )
{
    if ( !vo )
        return FALSE;

    if ( !ProgSource->memory || ProgSource->memory == ProgSource )
        return FALSE;

    return ( ProgSource->memory == vo );
}

int mprog_mobvnum( void *vo )
{
    CHAR_DATA *ch = (CHAR_DATA *)vo;

    if ( !vo )
        return FALSE;

    if ( IS_NPC(ch) )
        return ch->pIndexData->vnum;

    return FALSE;
}

int mprog_objtype( void *vo )
{
    if ( !vo )
        return FALSE;

    return ((OBJ_DATA *)vo)->item_type;
}

int mprog_objval0( void *vo )
{
    if ( !vo )
        return FALSE;

    return ((OBJ_DATA *)vo)->value[0];
}

int mprog_objval1( void *vo )
{
    if ( !vo )
        return FALSE;

    return ((OBJ_DATA *)vo)->value[1];
}

int mprog_objval2( void *vo )
{
    if ( !vo )
        return FALSE;

    return ((OBJ_DATA *)vo)->value[2];
}

int mprog_objval3( void *vo )
{
    if ( !vo )
        return FALSE;

    return ((OBJ_DATA *)vo)->value[3];
}

int mprog_position( void *vo )
{
    if ( !vo )
        return FALSE;

    return ((CHAR_DATA *)vo)->position;
}

int mprog_rand( void *vo )
{
    if ( !vo )
        return FALSE;

    return ( number_percent() <= *((int *)vo) );
}

int mprog_roomvnum( void *vo )
{
    if ( !ProgSource->in_room )
        return FALSE;

    return ProgSource->in_room->vnum;
}

int mprog_sex( void *vo )
{
    if ( !vo )
        return FALSE;

    return ((CHAR_DATA *)vo)->sex;
}

int mprog_sgetrand( void *vo )
{
    static int lastarg = 0;
    static int lastrand = 0;
    static int lastprogid = 0;
    int arg = *((int *)vo);

    if ( !vo )
        return FALSE;
    
    if ( arg != lastarg || lastprogid != ExecMudProgID )
    {
        lastrand = number_range(1, arg);
        lastprogid = ExecMudProgID;
        lastarg = arg;
    }

    return lastrand;
}

int mprog_sreset( void *vo )
{
    ExecMudProgID++;

    return TRUE;
}