wolfpaw4.0-release/area/
wolfpaw4.0-release/backup/
wolfpaw4.0-release/bin/
wolfpaw4.0-release/boards/
wolfpaw4.0-release/clans/
wolfpaw4.0-release/councils/
wolfpaw4.0-release/deity/
wolfpaw4.0-release/finger/
wolfpaw4.0-release/gods/
wolfpaw4.0-release/guilds/
wolfpaw4.0-release/lockers/
wolfpaw4.0-release/log/
wolfpaw4.0-release/log/Clean/
wolfpaw4.0-release/maps/
wolfpaw4.0-release/offline_data/
wolfpaw4.0-release/player-obj/
wolfpaw4.0-release/player-obj/a/
wolfpaw4.0-release/player/
wolfpaw4.0-release/player/a/
wolfpaw4.0-release/plog/
wolfpaw4.0-release/save-rooms/
wolfpaw4.0-release/secure/
wolfpaw4.0-release/source/
wolfpaw4.0-release/source/betasrc/system/
wolfpaw4.0-release/source/betasrc/util/
wolfpaw4.0-release/system/clean-source/
wolfpaw4.0-release/system/clean-source/grux/
/*--------------------------------------------------------------------------*
 *                         ** WolfPaw 1.0 **                                *
 *--------------------------------------------------------------------------*
 *               WolfPaw 1.0 (c) 1997,1998 by Dale Corse                    *
 *--------------------------------------------------------------------------*
 *            The WolfPaw Coding Team is headed by: Greywolf                *
 *  With the Assitance from: Callinon, Dhamon, Sentra, Wyverns, Altrag      *
 *  Scryn, Thoric, Justice, Tricops and Mask.                               *
 *--------------------------------------------------------------------------*
 *			Personal Social Handling Module			    *
 *--------------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include "mud.h"

void load_char_social( FILE *fp, CHAR_DATA *ch );
void save_char_socials( FILE *fp, CHAR_DATA *ch );
void setup_char_socials(CHAR_DATA *ch);
SOCIALTYPE *personal_social_check(CHAR_DATA *ch, char *name );
bool social_syntax_check( CHAR_DATA *ch, char *txt, int type );
bool SOCIALTYPE_HAS_VICT(int type);
PSOC_DATA *get_char_social( CHAR_DATA *ch, char *name );
bool social_name_check( CHAR_DATA *ch, char *name );
void create_psocial( CHAR_DATA *ch, char *name );
void delete_psocial( CHAR_DATA *ch,PSOC_DATA *social );

#define SOCIAL_OK(social)	\
	(IS_SET((social)->flags, PSOC_CNOARG) && \
	 IS_SET((social)->flags, PSOC_ONOARG) && \
	 IS_SET((social)->flags, PSOC_CFOUND) && \
	 IS_SET((social)->flags, PSOC_OFOUND) && \
	 IS_SET((social)->flags, PSOC_VFOUND) && \
	 IS_SET((social)->flags, PSOC_CAUTO) && \
	 IS_SET((social)->flags, PSOC_OAUTO) ) 

#define MAX_PSOCIALS 10 /* Max PSocials Allowed per Player */

#if defined(KEY)
#undef KEY
#endif

#define KEY( literal, field, value )                                    \
                                if ( !str_cmp( word, literal ) )        \
                                {                                       \
                                    field  = value;                     \
                                    fMatch = TRUE;                      \
                                    break;                              \
                               }

/*
 * User interface, sets everything up --GW 
 * Syntax:
 * psocial <view/create/set/delete> <name> <field> <string>
 */
void do_psocial( CHAR_DATA *ch, char *argument )
{
char arg1[MIL];
char arg2[MIL];
char arg3[MIL];
PSOC_DATA *social;

argument = one_argument( argument, arg1 ); /* Create/Set */
argument = one_argument( argument, arg2 ); /* Name */
argument = one_argument( argument, arg3 ); /* Field */
/* Left is raw string */
if ( arg1[0] == '\0' )
{
  send_to_char("Syntax: psocial <view/create/set/delete> <name> <field> <string>\n\r\n\r",ch);
  send_to_char("Field being one of:\n\r",ch);
  send_to_char("cnoarg onoarg cfound ofound vfound cauto oauto\n\r",ch);
  send_to_char("PLEASE READ HELP PSOCIAL BEFORE YOU USE THIS!\n\r",ch);
  send_to_char("Type 'psocials' for a list of the socials you have.\n\r",ch);
  return;
}

/* Make a new Social */
if ( !str_cmp( arg1, "create" ) )
{
  if ( arg2[0] == '\0' )
  {
  send_to_char("Syntax: psocial <view/create/set/delete> <name> <field> <string>\n\r\n\r",ch);
  send_to_char("Field being one of:\n\r",ch);
  send_to_char("cnoarg onoarg cfound ofound vfound cauto oauto\n\r",ch);
  send_to_char("PLEASE READ HELP PSOCIAL BEFORE YOU USE THIS!\n\r",ch);
  send_to_char("Type 'psocials' for a list of the socials you have.\n\r",ch);
  return;
  }

  if ( social_name_check(ch,arg2)==FALSE )
  {
    send_to_char("Unable to Create Social, read HELP PSOCIALS\n\r",ch);
    return;
  }

  if ( ch->pcdata->psocials == MAX_PSOCIALS )
  {
    ch_printf(ch,"Sorry, your only allowed %d Persoanl Socials!\n\r",MAX_PSOCIALS);
    return;
  }

  ch->pcdata->psocials++;
  create_psocial(ch,arg2);
  send_to_char("Social Created.\n\r",ch);
  return;
}

/* Remove a Social */
if ( !str_cmp( arg1, "delete" ) )
{
  if ( arg2[0] == '\0' )
  {
  send_to_char("Syntax: psocial <view/create/set/delete> <name> <field> <string>\n\r\n\r",ch);
  send_to_char("Field being one of:\n\r",ch);
  send_to_char("cnoarg onoarg cfound ofound vfound cauto oauto\n\r",ch);
  send_to_char("PLEASE READ HELP PSOCIAL BEFORE YOU USE THIS!\n\r",ch);
  send_to_char("Type 'psocials' for a list of the socials you have.\n\r",ch);
  return;
  }

   if ( !(social=get_char_social(ch,arg2)))
   {
     send_to_char("You have no Personal Social named that!\n\r",ch);
     return;
   }

   ch->pcdata->psocials--;
   delete_psocial(ch,social);
   send_to_char("Social Deleted.\n\r",ch);
   return;
}

/* Set stuff on a Social */
if ( !str_cmp( arg1, "set" ) )
{
  if ( arg2[0] == '\0' || arg3[0] == '\0' || !argument[0] || 
       isspace(argument[0]) )
  {
  send_to_char("Syntax: psocial <view/create/set/delete> <name> <field> <string>\n\r\n\r",ch);
  send_to_char("Field being one of:\n\r",ch);
  send_to_char("cnoarg onoarg cfound ofound vfound cauto oauto\n\r",ch);
  send_to_char("PLEASE READ HELP PSOCIAL BEFORE YOU USE THIS!\n\r",ch);
  send_to_char("Type 'psocials' for a list of the socials you have.\n\r",ch);
  return;
  }

   if ( !(social=get_char_social(ch,arg2)))
   {
     send_to_char("You have no Personal Social named that!\n\r",ch);
     return;
   }

   if ( !str_cmp( arg3, "cnoarg" ) )
   {
     if ( social_syntax_check(ch,argument,SOCTYPE_CNOARG)==FALSE ) 
       return;

     smash_tilde(argument);
     social->char_no_arg = STRALLOC(argument);    
     SET_BIT(social->flags, PSOC_CNOARG);
     send_to_char("Done.\n\r",ch);
     return;
   }
   if ( !str_cmp( arg3, "onoarg" ) )
   {
     if ( social_syntax_check(ch,argument,SOCTYPE_ONOARG)==FALSE ) 
       return;

     smash_tilde(argument);
     social->others_no_arg = STRALLOC(argument);    
     SET_BIT(social->flags, PSOC_ONOARG);
     send_to_char("Done.\n\r",ch);
     return;
   }
   if ( !str_cmp( arg3, "cfound" ) )
   {
     if ( social_syntax_check(ch,argument,SOCTYPE_CFOUND)==FALSE ) 
       return;

     smash_tilde(argument);
     social->char_found = STRALLOC(argument);    
     SET_BIT(social->flags, PSOC_CFOUND);
     send_to_char("Done.\n\r",ch);
     return;
   }
   if ( !str_cmp( arg3, "ofound" ) )
   {
     if ( social_syntax_check(ch,argument,SOCTYPE_OFOUND)==FALSE ) 
       return;

     smash_tilde(argument);
     social->others_found = STRALLOC(argument);    
     SET_BIT(social->flags, PSOC_OFOUND);
     send_to_char("Done.\n\r",ch);
     return;
   }
   if ( !str_cmp( arg3, "vfound" ) )
   {
     if ( social_syntax_check(ch,argument,SOCTYPE_VFOUND)==FALSE ) 
       return;

     smash_tilde(argument);
     social->vict_found = STRALLOC(argument);    
     SET_BIT(social->flags, PSOC_VFOUND);
     send_to_char("Done.\n\r",ch);
     return;
   }
   if ( !str_cmp( arg3, "cauto" ) )
   {
     if ( social_syntax_check(ch,argument,SOCTYPE_CAUTO)==FALSE ) 
       return;

     smash_tilde(argument);
     social->char_auto = STRALLOC(argument);    
     SET_BIT(social->flags, PSOC_CAUTO);
     send_to_char("Done.\n\r",ch);
     return;
   }
   if ( !str_cmp( arg3, "oauto" ) )
   {
     if ( social_syntax_check(ch,argument,SOCTYPE_OAUTO)==FALSE ) 
       return;

     smash_tilde(argument);
     social->others_auto = STRALLOC(argument);    
     SET_BIT(social->flags, PSOC_OAUTO);
     send_to_char("Done.\n\r",ch);
     return;
   }
}

if ( !str_cmp( arg1, "view" ) )
{
  if ( arg2[0] == '\0' )
  {
  send_to_char("Syntax: psocial <view/create/set/delete> <name> <field> <string>\n\r\n\r",ch);
  send_to_char("Field being one of:\n\r",ch);
  send_to_char("cnoarg onoarg cfound ofound vfound cauto oauto\n\r",ch);
  send_to_char("PLEASE READ HELP PSOCIAL BEFORE YOU USE THIS!\n\r",ch);
  send_to_char("Type 'psocials' for a list of the socials you have.\n\r",ch);
  return;
  }

   if ( !(social=get_char_social(ch,arg2)))
   {
     send_to_char("You have no Personal Social named that!\n\r",ch);
     return;
   }

  ch_printf(ch,"\n\rName  : %s\n\r",social->name );
  ch_printf(ch,"CNoArg:	%s\n\r",social->char_no_arg ? social->char_no_arg : "(None)" );
  ch_printf(ch,"ONoArg:	%s\n\r",social->others_no_arg ? social->others_no_arg : "(None)" ); 
  ch_printf(ch,"CFound:	%s\n\r",social->char_found ? social->char_found : "(None)" );
  ch_printf(ch,"OFound:	%s\n\r",social->others_found ? social->others_found : "(None)" );
  ch_printf(ch,"VFound:	%s\n\r",social->vict_found ? social->vict_found : "(None)" );
  ch_printf(ch,"CAuto :	%s\n\r",social->char_auto ? social->char_auto : "(None)");
  ch_printf(ch,"OAuto :	%s\n\r",social->others_auto ? social->others_auto : "(None)");
  if ( IS_IMP(ch) )
  ch_printf(ch,"Flags : %d\n\r",social->flags);

  return;
}

send_to_char("Syntax: psocial <view/create/delete/set> <name> <field> <string>\n\r\n\r",ch);
send_to_char("Field being one of:\n\r",ch);
send_to_char("cnoarg onoarg cfound ofound vfound cauto oauto\n\r",ch);
send_to_char("PLEASE READ HELP PSOCIAL BEFORE YOU USE THIS!\n\r",ch);
send_to_char("Type 'psocials' for a list of the socials you have.\n\r",ch);
return;
}

/*
 * Load a Social from Pfile --GW
 */
void load_char_social( FILE *fp, CHAR_DATA *ch )
{
PSOC_DATA *social=NULL;
char *word=NULL;
bool fMatch=FALSE;
char buf[MSL];

CREATE( social, PSOC_DATA, 1 );

for( ; ; )
{
   word = feof(fp) ? "End" : fread_word(fp);
   fMatch = FALSE;
   
   switch ( UPPER(word[0]))
   {

     case '*':
     fMatch=TRUE;
     fread_to_eol(fp);
     return;

	case 'C':
	KEY("CNoArg",	social->char_no_arg,	fread_string(fp) );
	KEY("CFound",	social->char_found,	fread_string(fp) );
	KEY("CAuto",	social->char_auto,	fread_string(fp) );     
     	break;

	case 'E':
	if ( !str_cmp( word, "End" ) )
	{
          LINK(social,ch->pcdata->personal_socials->first_social,ch->pcdata->personal_socials->last_social,next,prev);
	  return;	   
	}
	break;

     	case 'F':
	KEY("Flags",	social->flags,		fread_number(fp) );	
    	break;

     	case 'O':
	KEY("ONoArg",	social->others_no_arg,	fread_string(fp) );
	KEY("OFound",	social->others_found,	fread_string(fp) );
	KEY("OAuto",	social->others_auto,	fread_string(fp) );
     	break;

     	case 'N':
	KEY("Name",	social->name,		fread_string(fp) );
     	break;

     	case 'V':
	KEY("VFound",	social->vict_found,	fread_string(fp) );
     	break;
   }
  
   if ( !fMatch )
   {
     sprintf(buf,"Load_char_psocals: no match for %s",word);
     bug( buf, 0 );
   }
}

return;
}

/*
 * Write Personal Socials to pfile.. --GW
 */
void save_char_socials( FILE *fp, CHAR_DATA *ch )
{
PSOC_DATA *social, *next_social;

if ( !ch->pcdata->personal_socials )
setup_char_socials(ch);

for( social=ch->pcdata->personal_socials->first_social; social; social=next_social)
{
  next_social=social->next;

  fprintf(fp,"#PSOCIAL\n");
  fprintf(fp,"Name	%s~\n",social->name);
  fprintf(fp,"CNoArg    %s~\n",social->char_no_arg);
  fprintf(fp,"ONoArg	%s~\n",social->others_no_arg);
  fprintf(fp,"CFound	%s~\n",social->char_found);
  fprintf(fp,"OFound    %s~\n",social->others_found);
  fprintf(fp,"VFound	%s~\n",social->vict_found);
  fprintf(fp,"CAuto	%s~\n",social->char_auto);
  fprintf(fp,"OAuto	%s~\n",social->others_auto);
  fprintf(fp,"Flags	%d\n",social->flags);
  fprintf(fp,"End\n");
}

return;
}

/*
 * Setup a Characters PSocials --GW
 */
void setup_char_socials(CHAR_DATA *ch)
{
CREATE(ch->pcdata->personal_socials, PSOCIAL_DATA, 1 );
ch->pcdata->personal_socials->first_social = NULL;
ch->pcdata->personal_socials->last_social = NULL;
return;
}

void free_char_psocials(CHAR_DATA *ch)
{
PSOC_DATA *social, *next_social;

for(social=ch->pcdata->personal_socials->first_social;social;social=next_social)
{
  next_social=social->next;
  STRFREE(social->name);
 if ( social->char_no_arg )
  STRFREE(social->char_no_arg);
 if ( social->others_no_arg )
  STRFREE(social->others_no_arg);
 if ( social->char_found )
  STRFREE(social->char_found);
 if ( social->others_found )
  STRFREE(social->others_found);
 if ( social->vict_found )
  STRFREE(social->vict_found);
 if ( social->char_auto )
  STRFREE(social->char_auto);
 if ( social->others_auto )
  STRFREE(social->others_auto);

UNLINK(social,ch->pcdata->personal_socials->first_social,ch->pcdata->personal_socials->last_social,next,prev);
DISPOSE(social);
}

return;
}

/*
 * Internal Interface, checks for a personal Social, and if 
 * found, executes it, and returns TRUE, 
 * False if it is not Found. --GW
 */
SOCIALTYPE *personal_social_check(CHAR_DATA *ch, char *name )
{
PSOC_DATA *social, *next_social;
bool found = FALSE;
SOCIALTYPE *soc=NULL;

if ( IS_NPC(ch) )
return NULL;

for( social = ch->pcdata->personal_socials->first_social; social; social = next_social )
{
  next_social = social->next;

  if ( !social || !social->name )
   continue;

  if ( !str_cmp( social->name, name ) )
  {
    found = TRUE;
    break;
  }
}

if ( found )
{

if ( !SOCIAL_OK(social) )
return NULL;

CREATE(soc, SOCIALTYPE, 1 );
soc->name = 		STRALLOC(social->name);
soc->char_no_arg = 	STRALLOC(social->char_no_arg);
soc->others_no_arg = 	STRALLOC(social->others_no_arg);
soc->char_found = 	STRALLOC(social->char_found);
soc->others_found =     STRALLOC(social->others_found);
soc->vict_found = 	STRALLOC(social->vict_found);
soc->char_auto = 	STRALLOC(social->char_auto);
soc->others_auto = 	STRALLOC(social->others_auto);
return soc;
}

return NULL;
}

void free_socialtype_data( SOCIALTYPE *soc )
{
STRFREE(soc->name);
STRFREE(soc->char_no_arg);
STRFREE(soc->others_no_arg);
STRFREE(soc->char_found);
STRFREE(soc->others_found);
STRFREE(soc->vict_found);
STRFREE(soc->char_auto);
STRFREE(soc->others_auto);
DISPOSE(soc);
}

/*
 * Checks the Syntax of a social, makes sure it wont bomb the MUD --GW
 * TRUE is Syntax is OK
 * False if not!
 */
bool social_syntax_check( CHAR_DATA *ch, char *txt, int type )
{
char buf[MSL];
int str=0;
bool error=FALSE;

sprintf(buf,"%s",txt);

for( str=0; buf[str]; str++ )
{

if ( buf[str] != '$' || buf[str+1] == '\0' )
continue;

switch( buf[str+1] )
{

/* These are ok if the conditions are met */

/* name of Victim */
   case 'N':
   if ( !SOCIALTYPE_HAS_VICT(type) )
    error=TRUE;
   break;

/* Name of Character */
   case 'n':
   break;

/* he/she/it of char */
   case 'e':
   break;

/* he/She/it of Victim */
   case 'E':
   if ( !SOCIALTYPE_HAS_VICT(type) )
    error=TRUE;
   break;

/* Him/Her/It of Victim */
   case 'M':
   if ( !SOCIALTYPE_HAS_VICT(type) )
    error=TRUE;
   break;

/* Him/Her/It of Character */
   case 'm':
   break;

/* His/hers/its of Char */
   case 's':
   break;

/* His/Hers/Its of Victim */
   case 'S':
   if ( !SOCIALTYPE_HAS_VICT(type) )
    error=TRUE;
   break;

/* Reject anything else */
   default:
   error=TRUE;
   break;
}

}

if ( !error )
  return TRUE;

return FALSE;
}


/*
 * Returns TRUE if the Social type HAS a Vict.
 * False if it doesn't
 */
bool SOCIALTYPE_HAS_VICT(int type)
{
if ( type == SOCTYPE_CNOARG )
return FALSE;
if ( type == SOCTYPE_ONOARG )
return FALSE;
if ( type == SOCTYPE_VFOUND )
return FALSE;
if ( type == SOCTYPE_CAUTO )
return FALSE;
if ( type == SOCTYPE_OAUTO )
return FALSE;

return TRUE;
}

PSOC_DATA *get_char_social( CHAR_DATA *ch, char *name )
{
PSOC_DATA *social, *next_social;

for ( social=ch->pcdata->personal_socials->first_social; social; social=next_social )
{
  next_social=social->next;

if ( !str_cmp( social->name, name ) )
return social;
}

return NULL;
}

bool social_name_check( CHAR_DATA *ch, char *name )
{
CMDTYPE *command;
SOCIALTYPE *social;

if ( (command=find_command( name ))!=NULL)
return FALSE;

if ( (social=find_social(ch,name,FALSE))!=NULL)
return FALSE;

if ( (social=find_social(ch,name,TRUE))!=NULL)
return FALSE;

return TRUE;
}

void create_psocial( CHAR_DATA *ch, char *name )
{
PSOC_DATA *social=NULL;

CREATE(social, PSOC_DATA, 1 );
social->name = STRALLOC(name);
social->flags = 0;
LINK(social,ch->pcdata->personal_socials->first_social,ch->pcdata->personal_socials->last_social,next,prev);
return;
}

void delete_psocial( CHAR_DATA *ch,PSOC_DATA *social )
{
STRFREE(social->name);
STRFREE(social->char_no_arg);
STRFREE(social->others_no_arg);
STRFREE(social->char_found);
STRFREE(social->others_found);
STRFREE(social->vict_found);
STRFREE(social->char_auto);
STRFREE(social->others_auto);
UNLINK(social,ch->pcdata->personal_socials->first_social,ch->pcdata->personal_socials->last_social, next, prev );
DISPOSE(social);
return;
}

void do_psocials( CHAR_DATA *ch, char *argument )
{
PSOC_DATA *social, *next_social;
bool found=FALSE;
int cnt=0;
char buf[MSL];

for( social=ch->pcdata->personal_socials->first_social; social; social=next_social)
{
  next_social=social->next;

  if ( social )
  {
    cnt++;
    sprintf(buf,"%d) %s\n\r",cnt,social->name);
    send_to_char(buf,ch);
    found=TRUE;
  }
}

if ( !found )
{
send_to_char("You have no Personal Socials.\n\r",ch);
return;
}
else
{
sprintf(buf,"%d social%s found.\n\r",cnt,(cnt > 1) ? "s" : "");
send_to_char(buf,ch);
}

return;
}