/************************************************************	/************************************************************
 *  file: act_soc.c , Implementation of commands.          Pa |	*		 MEDIEVIA CyberSpace Code and Data files
 *  Usage : Social commands.                                  |	*       Copyright (C) 1992, 1995 INTENSE Software(tm) and Mik
 *  Copyright (C) 1990, 1991 - see 'license.doc' for complete |	*			   All rights reserved		
 *                                                            |	*************************************************************
 *  Copyright (C) 1992, 1993 Michael Chastain, Michael Quan,  <
 *  Performance optimization and bug fixes by MERC Industries <
 *  You can use our stuff in any way you like whatsoever so l <
 *  copyright notice remains intact.  If you like it please d <
 *  to mec@garnet.berkeley.edu.                               <
 *                                                            <
 *  This is free software and you are benefitting.  We hope t <
 *  share your changes too.  What goes around, comes around.  <
 ************************************************************ <

#include <stdlib.h>						#include <stdlib.h>
#include <stdio.h>						#include <stdio.h>
#include <string.h>						#include <string.h>
#include <memory.h>						#include <memory.h>

#include "structs.h"						#include "structs.h"
#include "mob.h"						#include "mob.h"
#include "obj.h"						#include "obj.h"
#include "utils.h"						#include "utils.h"
#include "interp.h"						#include "interp.h"
#include "handler.h"						#include "handler.h"
#include "db.h"							#include "db.h"
#include "spells.h"						#include "spells.h"

/* extern variables */						/* extern variables */
							      |	extern char global_color;
extern struct room_data *world;				      |	extern struct room_data *world[MAX_ROOM]; /* array of rooms  
extern struct descriptor_data *descriptor_list;			extern struct descriptor_data *descriptor_list;

/* extern functions */						/* extern functions */

void parse_string(char *input, char *output, struct char_data	void parse_string(char *input, char *output, struct char_data
    struct char_data *ch2, struct char_data *to);		    struct char_data *ch2, struct char_data *to);
int action(int cmd);						int action(int cmd);
char *fread_action(FILE *fl);					char *fread_action(FILE *fl);
							      >	int number_socials;
							      >	extern void FreightMobsToRoom(int iRoom);
							      >	extern void FreightMobsFromRoom(int iRoom);

#define MAX_SOCIAL  256						#define MAX_SOCIAL  256

struct social_messg						struct social_messg
{								{
    char *name;							    char *name;
    int hide;							    int hide;
    int min_victim_position; /* Position of victim */		    int min_victim_position; /* Position of victim */

    /* No argument was supplied */				    /* No argument was supplied */
    char *char_no_arg;						    char *char_no_arg;
    char *others_no_arg;					    char *others_no_arg;

    /* An argument was there, and a victim was found */		    /* An argument was there, and a victim was found */
    char *char_found;       /* if NULL, read no further, igno	    char *char_found;       /* if NULL, read no further, igno
    char *others_found;						    char *others_found;
    char *vict_found;						    char *vict_found;

    /* An argument was there, but no victim was found */	    /* An argument was there, but no victim was found */
    char *not_found;						    char *not_found;

    /* The victim turned out to be the character */		    /* The victim turned out to be the character */
    char *char_auto;						    char *char_auto;
    char *others_auto;						    char *others_auto;
} soc_mess_list[MAX_SOCIAL];					} soc_mess_list[MAX_SOCIAL];



struct pose_type						struct pose_type
{								{
    int level;          /* minimum level for poser */		    int level;          /* minimum level for poser */
    char *poser_msg[4];  /* message to poser        */		    char *poser_msg[4];  /* message to poser        */
    char *room_msg[4];   /* message to room         */		    char *room_msg[4];   /* message to room         */
} pose_messages[MAX_MESSAGES];					} pose_messages[MAX_MESSAGES];

static int list_top = -1;					static int list_top = -1;


char *fread_action(FILE *fl)					char *fread_action(FILE *fl)
{								{
    char buf[MAX_STRING_LENGTH], *rslt;				    char buf[MAX_STRING_LENGTH], *rslt;

    for (;;)							    for (;;)
    {								    {
	fgets(buf, MAX_STRING_LENGTH, fl);				fgets(buf, MAX_STRING_LENGTH, fl);
	if (feof(fl))							if (feof(fl))
	{								{
	    log("Fread_action - unexpected EOF.");	      |		    log_hd("Fread_action - unexpected EOF.");
	    exit(0);							    exit(0);
	}								}

	if (*buf == '#')						if (*buf == '#')
	    return(0);							    return(0);
	{								{
	    *(buf + strlen(buf) - 1) = '\0';				    *(buf + strlen(buf) - 1) = '\0';
	    CREATE(rslt, char, strlen(buf) + 1);			    CREATE(rslt, char, strlen(buf) + 1);
	    strcpy(rslt, buf);						    strcpy(rslt, buf);
	    return(rslt);						    return(rslt);
	}								}
    }								    }
}								}



void boot_social_messages(void)					void boot_social_messages(void)
{								{
    FILE *fl;							    FILE *fl;
    char tmp[MAX_INPUT_LENGTH];					    char tmp[MAX_INPUT_LENGTH];
    int hide, min_pos;						    int hide, min_pos;

    if (!(fl = fopen(SOCIAL_FILE, "r")))			    if (!(fl = fopen(SOCIAL_FILE, "r")))
    {								    {
	perror("boot_social_messages");					perror("boot_social_messages");
	exit(0);							exit(0);
    }								    }

							      >		open_files++;
    for (;;)							    for (;;)
    {								    {
	fscanf(fl, " %s ", tmp);					fscanf(fl, " %s ", tmp);
	if ( feof(fl) )							if ( feof(fl) )
	    break;							    break;
	fscanf(fl, " %d ", &hide);					fscanf(fl, " %d ", &hide);
	fscanf(fl, " %d \n", &min_pos);					fscanf(fl, " %d \n", &min_pos);

	list_top++;							list_top++;
	if ( list_top >= MAX_SOCIAL )					if ( list_top >= MAX_SOCIAL )
	{								{
	    perror( "Too many socials.\n" );				    perror( "Too many socials.\n" );
	    exit( 0 );							    exit( 0 );
	}								}

	/* read the stuff */						/* read the stuff */
	soc_mess_list[list_top].name                = str_dup		soc_mess_list[list_top].name                = str_dup
	soc_mess_list[list_top].hide                = hide;		soc_mess_list[list_top].hide                = hide;
	soc_mess_list[list_top].min_victim_position = min_pos		soc_mess_list[list_top].min_victim_position = min_pos
	soc_mess_list[list_top].char_no_arg         = fread_a		soc_mess_list[list_top].char_no_arg         = fread_a
	soc_mess_list[list_top].others_no_arg       = fread_a		soc_mess_list[list_top].others_no_arg       = fread_a
	soc_mess_list[list_top].char_found          = fread_a		soc_mess_list[list_top].char_found          = fread_a

	/* if no char_found, the rest is to be ignored */		/* if no char_found, the rest is to be ignored */
	if (!soc_mess_list[list_top].char_found)			if (!soc_mess_list[list_top].char_found)
	    continue;							    continue;

	soc_mess_list[list_top].others_found        = fread_a		soc_mess_list[list_top].others_found        = fread_a
	soc_mess_list[list_top].vict_found          = fread_a		soc_mess_list[list_top].vict_found          = fread_a
	soc_mess_list[list_top].not_found           = fread_a		soc_mess_list[list_top].not_found           = fread_a
	soc_mess_list[list_top].char_auto           = fread_a		soc_mess_list[list_top].char_auto           = fread_a
	soc_mess_list[list_top].others_auto         = fread_a		soc_mess_list[list_top].others_auto         = fread_a
    }								    }
    fclose(fl);							    fclose(fl);
							      >		open_files--;
							      >	    number_socials=list_top;
}								}

							      >	void do_socials(struct char_data *ch, char *argument, int com
							      >	{
							      >	int cmd;
							      >	    send_to_char("     CURRENT SOCIALS COMMANDS LISTING\n\r",
							      >	    for ( cmd = 0; cmd <= list_top; cmd++ ){
							      >			sprintf(log_buf,"%s, ",soc_mess_list[cmd].nam
							      >			send_to_char(log_buf,ch);
							      >	    }
							      >	    send_to_char("\n\r",ch);	
							      >	}


bool check_social( struct char_data *ch, char *pcomm, int len	bool check_social( struct char_data *ch, char *pcomm, int len
{								{
    char buf[MAX_INPUT_LENGTH];					    char buf[MAX_INPUT_LENGTH];
    struct social_messg *action;			      |	    struct social_messg *action=NULL;
    struct char_data *vict;				      |	    struct char_data *vict=NULL;
    int cmd;							    int cmd;

    for ( cmd = 0; cmd <= list_top; cmd++ )			    for ( cmd = 0; cmd <= list_top; cmd++ )
    {								    {
	if ( memcmp( pcomm, soc_mess_list[cmd].name, length )		if ( memcmp( pcomm, soc_mess_list[cmd].name, length )
	    goto LCmdFound;						    goto LCmdFound;
    }								    }
    return FALSE;						    return FALSE;

 LCmdFound:							 LCmdFound:
    if ( !IS_NPC(ch) && IS_SET(ch->specials.act, PLR_NOEMOTE)	    if ( !IS_NPC(ch) && IS_SET(ch->specials.act, PLR_NOEMOTE)
    {								    {
	send_to_char( "You are anti-social!\n\r", ch );	      |			send_to_char( "You are anti-social!\n\r", ch 
	return TRUE;					      |			return TRUE;
    }								    }

    switch( GET_POS(ch) )					    switch( GET_POS(ch) )
    {								    {
    case POSITION_DEAD:						    case POSITION_DEAD:
	send_to_char( "Lie still; you are DEAD.\n\r", ch );		send_to_char( "Lie still; you are DEAD.\n\r", ch );
	return TRUE;							return TRUE;

    case POSITION_INCAP:					    case POSITION_INCAP:
    case POSITION_MORTALLYW:					    case POSITION_MORTALLYW:
	send_to_char( "You are hurt far too bad for that.\n\r		send_to_char( "You are hurt far too bad for that.\n\r
	return TRUE;							return TRUE;

    case POSITION_STUNNED:					    case POSITION_STUNNED:
	send_to_char( "You are too stunned to do that.\n\r", 		send_to_char( "You are too stunned to do that.\n\r", 
	return TRUE;							return TRUE;

    case POSITION_SLEEPING:					    case POSITION_SLEEPING:
	send_to_char( "In your dreams, or what?\n\r", ch );		send_to_char( "In your dreams, or what?\n\r", ch );
	return TRUE;							return TRUE;
    }								    }

    action = &soc_mess_list[cmd];				    action = &soc_mess_list[cmd];

    if (action->char_found)					    if (action->char_found)
	one_argument(arg, buf);						one_argument(arg, buf);
    else							    else
	*buf = '\0';							*buf = '\0';

    if (!*buf)							    if (!*buf)
    {								    {
							      >		global_color=32;
	send_to_char(action->char_no_arg, ch);				send_to_char(action->char_no_arg, ch);
	send_to_char("\n\r", ch);					send_to_char("\n\r", ch);
	act(action->others_no_arg, action->hide, ch, 0, 0, TO		act(action->others_no_arg, action->hide, ch, 0, 0, TO
							      >		global_color=0;
	return TRUE;							return TRUE;
    }								    }
							      |		FreightMobsToRoom(ch->in_room);
    if (!(vict = get_char_room_vis(ch, buf)))			    if (!(vict = get_char_room_vis(ch, buf)))
    {								    {
	send_to_char(action->not_found, ch);		      |			global_color=32;
	send_to_char("\n\r", ch);			      |			send_to_char(action->not_found, ch);
							      >			send_to_char("\n\r", ch);
							      >			global_color=0;
    }								    }
    else if (vict == ch)					    else if (vict == ch)
    {								    {
	send_to_char(action->char_auto, ch);		      |			global_color=32;
	send_to_char("\n\r", ch);			      |			send_to_char(action->char_auto, ch);
	act(action->others_auto, action->hide, ch, 0, 0, TO_R |			send_to_char("\n\r", ch);
							      >			act(action->others_auto, action->hide, ch, 0,
							      >			global_color=0;
    }								    }
    else if (GET_POS(vict) < action->min_victim_position)	    else if (GET_POS(vict) < action->min_victim_position)
    {								    {
	act("$N is not in a proper position for that.",	      |			act("$N is not in a proper position for that.
	    FALSE,ch,0,vict,TO_CHAR);			      |			    FALSE,ch,0,vict,TO_CHAR);
    }								    }
    else							    else
    {								    {
	act(action->char_found, 0, ch, 0, vict, TO_CHAR);     |			global_color=32;
	act(action->others_found, action->hide, ch, 0, vict,  |			act(action->char_found, 0, ch, 0, vict, TO_CH
	act(action->vict_found, action->hide, ch, 0, vict, TO |			act(action->others_found, action->hide, ch, 0
							      >			act(action->vict_found, action->hide, ch, 0, 
							      >			global_color=0;
    }								    }
							      |		FreightMobsFromRoom(ch->in_room);
    return TRUE;						    return TRUE;
}								}



void do_insult(struct char_data *ch, char *argument, int cmd)	void do_insult(struct char_data *ch, char *argument, int cmd)
{								{
    char buf[100];						    char buf[100];
    char arg[MAX_STRING_LENGTH];				    char arg[MAX_STRING_LENGTH];
    struct char_data *victim;					    struct char_data *victim;

    one_argument(argument, arg);				    one_argument(argument, arg);

    if(*arg) {							    if(*arg) {
	if(!(victim = get_char_room_vis(ch, arg))) {			if(!(victim = get_char_room_vis(ch, arg))) {
	    send_to_char("Can't hear you!\n\r", ch);			    send_to_char("Can't hear you!\n\r", ch);
	} else {							} else {
	    if(victim != ch) { 						    if(victim != ch) { 
		sprintf(buf, "You insult %s.\n\r",GET_NAME(vi			sprintf(buf, "You insult %s.\n\r",GET_NAME(vi
		send_to_char(buf,ch);						send_to_char(buf,ch);

		switch(number(0,2)) {						switch(number(0,2)) {
		    case 0 : {							    case 0 : {
			if (GET_SEX(ch) == SEX_MALE) {					if (GET_SEX(ch) == SEX_MALE) {
			    if (GET_SEX(victim) == SEX_MALE)				    if (GET_SEX(victim) == SEX_MALE)
				act(								act(
				"$n accuses you of fighting l					"$n accuses you of fighting l
				    FALSE, ch, 0, victim, TO_					    FALSE, ch, 0, victim, TO_
			else								else
				act("$n says that women can't					act("$n says that women can't
				  FALSE, ch, 0, victim, TO_VI					  FALSE, ch, 0, victim, TO_VI
			} else { /* Ch == Woman */					} else { /* Ch == Woman */
			    if (GET_SEX(victim) == SEX_MALE)				    if (GET_SEX(victim) == SEX_MALE)
				act(								act(
			"$n accuses you of having the smalles				"$n accuses you of having the smalles
				FALSE, ch, 0, victim, TO_VICT					FALSE, ch, 0, victim, TO_VICT
			else								else
				act(								act(
	    "$n tells you that you'd loose a beauty contest a		    "$n tells you that you'd loose a beauty contest a
				FALSE, ch, 0, victim, TO_VICT					FALSE, ch, 0, victim, TO_VICT
			}								}
		    } break;							    } break;
		    case 1 : {							    case 1 : {
			act("$n calls your mother a bitch!",				act("$n calls your mother a bitch!",
			FALSE, ch, 0, victim, TO_VICT );				FALSE, ch, 0, victim, TO_VICT );
		    } break;							    } break;
		    default : {							    default : {
			act("$n tells you to get lost!",				act("$n tells you to get lost!",
			FALSE,ch,0,victim,TO_VICT);					FALSE,ch,0,victim,TO_VICT);
		    } break;							    } break;
		} /* end switch */						} /* end switch */

		act("$n insults $N.", TRUE, ch, 0, victim, TO			act("$n insults $N.", TRUE, ch, 0, victim, TO
	    } else { /* ch == victim */					    } else { /* ch == victim */
		send_to_char("You feel insulted.\n\r", ch);			send_to_char("You feel insulted.\n\r", ch);
	    }								    }
	}								}
    } else send_to_char("Sure you don't want to insult everyb	    } else send_to_char("Sure you don't want to insult everyb
}								}



void boot_pose_messages(void)					void boot_pose_messages(void)
{								{
  FILE *fl;							  FILE *fl;
  int counter;							  int counter;
  int class;							  int class;

  if (!(fl = fopen(POSEMESS_FILE, "r")))			  if (!(fl = fopen(POSEMESS_FILE, "r")))
  {								  {
    perror("boot_pose_messages");				    perror("boot_pose_messages");
    exit(0);							    exit(0);
  }								  }

							      >	  open_files++;
  for (counter = 0;;counter++)					  for (counter = 0;;counter++)
  {								  {
    fscanf(fl, " %d ", &pose_messages[counter].level);		    fscanf(fl, " %d ", &pose_messages[counter].level);
    if (pose_messages[counter].level < 0)			    if (pose_messages[counter].level < 0)
      break;							      break;
	for (class = 0;class < 4;class++)				for (class = 0;class < 4;class++)
	{								{
	    pose_messages[counter].poser_msg[class] = fread_a		    pose_messages[counter].poser_msg[class] = fread_a
	    pose_messages[counter].room_msg[class] = fread_ac		    pose_messages[counter].room_msg[class] = fread_ac
	}								}
    }								    }
  								  
    fclose(fl);							    fclose(fl);
							      >		open_files--;
}								}


void do_pose(struct char_data *ch, char *argument, int cmd)	void do_pose(struct char_data *ch, char *argument, int cmd)
{								{
    int to_pose;						    int to_pose;
    int counter;						    int counter;

    if ((GET_LEVEL(ch) < pose_messages[0].level) || IS_NPC(ch	    if ((GET_LEVEL(ch) < pose_messages[0].level) || IS_NPC(ch
    {								    {
	send_to_char("You can't do that.\n\r", ch);			send_to_char("You can't do that.\n\r", ch);
	return;								return;
    }								    }

    for (counter = 0; (pose_messages[counter].level <= GET_LE	    for (counter = 0; (pose_messages[counter].level <= GET_LE
		     (pose_messages[counter].level >= 0); cou			     (pose_messages[counter].level >= 0); cou
    counter--;							    counter--;
  								  
    to_pose = number(0, counter);				    to_pose = number(0, counter);
    							      |	    global_color=35;    
    act(pose_messages[to_pose].poser_msg[GET_CLASS(ch)-1],	    act(pose_messages[to_pose].poser_msg[GET_CLASS(ch)-1],
	0, ch, 0, 0, TO_CHAR);						0, ch, 0, 0, TO_CHAR);
    act(pose_messages[to_pose].room_msg[GET_CLASS(ch)-1],	    act(pose_messages[to_pose].room_msg[GET_CLASS(ch)-1],
   	 0, ch, 0, 0, TO_ROOM);					   	 0, ch, 0, 0, TO_ROOM);
							      >	    global_color=0;
}								}
