/* ************************************************************************
* File: act.social.c Part of CircleMUD *
* Usage: Functions to handle socials *
* *
* All rights reserved. See license.doc for complete information. *
* *
* Copyright (C) 1993 by the Trustees of the Johns Hopkins University *
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
************************************************************************ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "db.h"
#include "spells.h"
/* extern variables */
extern struct room_data *world;
extern struct descriptor_data *descriptor_list;
extern struct room_data *world;
/* extern functions */
void parse_string(char *input, char *output, struct char_data *ch1,
struct char_data *ch2, struct char_data *to);
int action(int cmd);
char *fread_action(FILE *fl, int nr);
/* local globals */
static int list_top = -1;
struct social_messg {
int act_nr;
int hide;
int min_victim_position; /* Position of victim */
/* No argument was supplied */
char *char_no_arg;
char *others_no_arg;
/* An argument was there, and a victim was found */
char *char_found; /* if NULL, read no further, ignore args */
char *others_found;
char *vict_found;
/* An argument was there, but no victim was found */
char *not_found;
/* The victim turned out to be the character */
char *char_auto;
char *others_auto;
} *soc_mess_list = 0;
char *fread_action(FILE *fl, int nr)
{
char buf[MAX_STRING_LENGTH], *rslt;
fgets(buf, MAX_STRING_LENGTH, fl);
if (feof(fl)) {
sprintf(buf, "SYSERR: fread_action - unexpected EOF near action #%d", nr);
log(buf);
exit(0);
}
if (*buf == '#')
return(0);
else {
*(buf + strlen(buf) - 1) = '\0';
CREATE(rslt, char, strlen(buf) + 1);
strcpy(rslt, buf);
return(rslt);
}
}
void boot_social_messages(void)
{
FILE * fl;
int nr, tmp, hide, min_pos;
if (!(fl = fopen(SOCMESS_FILE, "r"))) {
perror("boot_social_messages");
exit(0);
}
for (; ; ) {
fscanf(fl, " %d ", &tmp);
if ((nr = tmp) < 0)
break;
fscanf(fl, " %d ", &hide);
fscanf(fl, " %d \n", &min_pos);
/* alloc a new cell */
if (!soc_mess_list) {
CREATE(soc_mess_list, struct social_messg, 1);
list_top = 0;
} else if (!(soc_mess_list = (struct social_messg *)
realloc(soc_mess_list, sizeof (struct social_messg ) *
(++list_top + 1)))) {
perror("boot_social_messages. realloc");
exit(1);
}
if (!tmp) {
if (!list_top)
fprintf(stderr, "Format error near beginning of socials file.\n");
else
fprintf(stderr, "Format error in social file near social #%d.\n",
soc_mess_list[list_top-1].act_nr);
exit(1);
}
if (list_top && soc_mess_list[list_top-1].act_nr > tmp) {
fprintf(stderr, "Format error or out-of-order social in socials file near #%d.\n",
soc_mess_list[list_top-1].act_nr);
exit(1);
}
/* read the stuff */
soc_mess_list[list_top].act_nr = tmp;
soc_mess_list[list_top].hide = hide;
soc_mess_list[list_top].min_victim_position = min_pos;
soc_mess_list[list_top].char_no_arg = fread_action(fl, nr);
soc_mess_list[list_top].others_no_arg = fread_action(fl, nr);
soc_mess_list[list_top].char_found = fread_action(fl, nr);
/* if no char_found, the rest is to be ignored */
if (!soc_mess_list[list_top].char_found)
continue;
soc_mess_list[list_top].others_found = fread_action(fl, nr);
soc_mess_list[list_top].vict_found = fread_action(fl, nr);
soc_mess_list[list_top].not_found = fread_action(fl, nr);
soc_mess_list[list_top].char_auto = fread_action(fl, nr);
soc_mess_list[list_top].others_auto = fread_action(fl, nr);
}
fclose(fl);
}
int find_action(int cmd)
{
int bot, top, mid;
bot = 0;
top = list_top;
if (top < 0)
return(-1);
for (; ; ) {
mid = (bot + top) / 2;
if (soc_mess_list[mid].act_nr == cmd)
return(mid);
if (bot >= top)
return(-1);
if (soc_mess_list[mid].act_nr > cmd)
top = --mid;
else
bot = ++mid;
}
}
ACMD(do_action)
{
int act_nr;
struct social_messg *action;
struct char_data *vict;
if ((act_nr = find_action(cmd)) < 0) {
send_to_char("That action is not supported.\n\r", ch);
return;
}
action = &soc_mess_list[act_nr];
if (action->char_found)
one_argument(argument, buf);
else
*buf = '\0';
if (!*buf) {
send_to_char(action->char_no_arg, ch);
send_to_char("\n\r", ch);
act(action->others_no_arg, action->hide, ch, 0, 0, TO_ROOM);
return;
}
if (!(vict = get_char_room_vis(ch, buf))) {
send_to_char(action->not_found, ch);
send_to_char("\n\r", ch);
} else if (vict == ch) {
send_to_char(action->char_auto, ch);
send_to_char("\n\r", ch);
act(action->others_auto, action->hide, ch, 0, 0, TO_ROOM);
} else {
if (GET_POS(vict) < action->min_victim_position) {
act("$N is not in a proper position for that.", FALSE, ch, 0, vict, TO_CHAR);
} else {
act(action->char_found, 0, ch, 0, vict, TO_CHAR);
act(action->others_found, action->hide, ch, 0, vict, TO_NOTVICT);
act(action->vict_found, action->hide, ch, 0, vict, TO_VICT);
}
}
}
ACMD(do_insult)
{
struct char_data *victim;
one_argument(argument, arg);
if (*arg) {
if (!(victim = get_char_room_vis(ch, arg))) {
send_to_char("Can't hear you!\n\r", ch);
} else {
if (victim != ch) {
sprintf(buf, "You insult %s.\n\r", GET_NAME(victim) );
send_to_char(buf, ch);
switch (random() % 3) {
case 0 :
{
if (GET_SEX(ch) == SEX_MALE) {
if (GET_SEX(victim) == SEX_MALE)
act(
"$n accuses you of fighting like a woman!", FALSE,
ch, 0, victim, TO_VICT);
else
act("$n says that women can't fight.",
FALSE, ch, 0, victim, TO_VICT);
} else { /* Ch == Woman */
if (GET_SEX(victim) == SEX_MALE)
act("$n accuses you of having the smallest.... (brain?)",
FALSE, ch, 0, victim, TO_VICT );
else
act("$n tells you that you'd loose a beautycontest against a troll.",
FALSE, ch, 0, victim, TO_VICT );
}
}
break;
case 1 :
{
act("$n calls your mother a bitch!",
FALSE, ch, 0, victim, TO_VICT );
}
break;
default :
{
act("$n tells you to get lost!", FALSE, ch, 0, victim, TO_VICT);
}
break;
} /* end switch */
act("$n insults $N.", TRUE, ch, 0, victim, TO_NOTVICT);
} else { /* ch == victim */
send_to_char("You feel insulted.\n\r", ch);
}
}
} else
send_to_char("I'm sure you don't want to insult *everybody*...\n\r", ch);
}