/*--------------------------------------------------------------------------*
* ** 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;
}