/***************************************************************************							/***************************************************************************
 *  file: act_soc.c , Implementation of commands.          Part of DIKUMUD *						      |	*		 MEDIEVIA CyberSpace Code and Data files		   *
 *  Usage : Social commands.                                               *						      |	*       Copyright (C) 1992, 1995 INTENSE Software(tm) and Mike Krause	   *
 *  Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *						      |	*			   All rights reserved				   *
 *                                                                         *						      |	***************************************************************************/
 *  Copyright (C) 1992, 1993 Michael Chastain, Michael Quan, Mitchell Tse  *						      <
 *  Performance optimization and bug fixes by MERC Industries.             *						      <
 *  You can use our stuff in any way you like whatsoever so long as this   *						      <
 *  copyright notice remains intact.  If you like it please drop a line    *						      <
 *  to mec@garnet.berkeley.edu.                                            *						      <
 *                                                                         *						      <
 *  This is free software and you are benefitting.  We hope that you       *						      <
 *  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 *ch1,								void parse_string(char *input, char *output, struct char_data *ch1,
    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, ignore args */								    char *char_found;       /* if NULL, read no further, ignore args */
    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(tmp);									soc_mess_list[list_top].name                = str_dup(tmp);
	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_action(fl);									soc_mess_list[list_top].char_no_arg         = fread_action(fl);
	soc_mess_list[list_top].others_no_arg       = fread_action(fl);									soc_mess_list[list_top].others_no_arg       = fread_action(fl);
	soc_mess_list[list_top].char_found          = fread_action(fl);									soc_mess_list[list_top].char_found          = fread_action(fl);

	/* 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_action(fl); 								soc_mess_list[list_top].others_found        = fread_action(fl); 
	soc_mess_list[list_top].vict_found          = fread_action(fl);									soc_mess_list[list_top].vict_found          = fread_action(fl);
	soc_mess_list[list_top].not_found           = fread_action(fl);									soc_mess_list[list_top].not_found           = fread_action(fl);
	soc_mess_list[list_top].char_auto           = fread_action(fl);									soc_mess_list[list_top].char_auto           = fread_action(fl);
	soc_mess_list[list_top].others_auto         = fread_action(fl);									soc_mess_list[list_top].others_auto         = fread_action(fl);
    }																    }
    fclose(fl);															    fclose(fl);
															      >		open_files--;
															      >	    number_socials=list_top;
}																}

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


bool check_social( struct char_data *ch, char *pcomm, int length, char *arg )							bool check_social( struct char_data *ch, char *pcomm, int length, char *arg )
{																{
    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 ) == 0 )									if ( memcmp( pcomm, soc_mess_list[cmd].name, length ) == 0 )
	    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", ch );									send_to_char( "You are hurt far too bad for that.\n\r", ch );
	return TRUE;															return TRUE;

    case POSITION_STUNNED:													    case POSITION_STUNNED:
	send_to_char( "You are too stunned to do that.\n\r", ch );									send_to_char( "You are too stunned to do that.\n\r", ch );
	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_ROOM);									act(action->others_no_arg, action->hide, ch, 0, 0, TO_ROOM);
															      >		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_ROOM);							      |			send_to_char("\n\r", ch);
															      >			act(action->others_auto, action->hide, ch, 0, 0, TO_ROOM);
															      >			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, TO_NOTVICT);						      |			act(action->char_found, 0, ch, 0, vict, TO_CHAR);
	act(action->vict_found, action->hide, ch, 0, vict, TO_VICT);							      |			act(action->others_found, action->hide, ch, 0, vict, TO_NOTVICT);
															      >			act(action->vict_found, action->hide, ch, 0, vict, TO_VICT);
															      >			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(victim) );										sprintf(buf, "You insult %s.\n\r",GET_NAME(victim) );
		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 like a woman!",											"$n accuses you of fighting like a woman!",
				    FALSE, ch, 0, victim, TO_VICT);												    FALSE, ch, 0, victim, TO_VICT);
			else																else
				act("$n says that women can't fight.",												act("$n says that women can't fight.",
				  FALSE, ch, 0, victim, TO_VICT);												  FALSE, ch, 0, victim, TO_VICT);
			} 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 smallest.... (brain?)",										"$n accuses you of having the smallest.... (brain?)",
				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 against a troll.",								    "$n tells you that you'd loose a beauty contest against a troll.",
				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_NOTVICT);										act("$n insults $N.", TRUE, ch, 0, victim, TO_NOTVICT);
	    } 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 everybody?\n\r", ch);							    } else send_to_char("Sure you don't want to insult everybody?\n\r", ch);
}																}



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_action(fl);									    pose_messages[counter].poser_msg[class] = fread_action(fl);
	    pose_messages[counter].room_msg[class] = fread_action(fl);									    pose_messages[counter].room_msg[class] = fread_action(fl);
	}																}
    }																    }
  																  
    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_LEVEL(ch)) && 							    for (counter = 0; (pose_messages[counter].level <= GET_LEVEL(ch)) && 
		     (pose_messages[counter].level >= 0); counter++);										     (pose_messages[counter].level >= 0); counter++);
    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;
}																}
