/* ************************************************************************ * File: act.social.c EmpireMUD AD 1.0 * * Usage: Functions to handle socials * * * * This file contains TBG code which is used under license from tbgMUD. * * See tbgc.lic in this directory for details. * * * * All rights reserved. See license.doc for complete information. * * * * Code base by Paul Clarke. EmpireMUD Project, a tbgMUD Production. * * Based upon CircleMUD 3.0, beta patch level 17, by Jeremy Elson. * * * * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * ************************************************************************ */ #include "conf.h" #include "sysdep.h" #include "structs.h" #include "utils.h" #include "comm.h" #include "interpreter.h" #include "handler.h" #include "db.h" void perform_action(Creature ch, int act_nr, char *argument); #define MAX_SOCIALS 350 /* * Today I'm rewriting act.social.c using the stock CircleMUD file more as * a template than anything. I like the idea of being able to add socials * without having to add to interpreter.c. It should be as simple as adding * lines in a text file. I don't have a snippet or anything to work with, * and despite the fact that I've chickened out every other time I've tried * to do this, I'm confident it'll work this time. -Paul, 1/27/99 */ /* extern functions */ extern char *fread_action(FILE * fl, int nr); /* local globals */ static int list_top = -1; struct social_messg { char *name; int hide; int min_char_position; /* Position of the character */ 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[MAX_SOCIALS]; int find_action(char *name) { int i; if (list_top < 0) return -1; for (i = 0; i < list_top; i++) if (is_abbrev(name, soc_mess_list[i].name)) return (i); return -1; } int check_social(Creature ch, char *string) { char arg1[MAX_STRING_LENGTH]; int action; skip_spaces(&string); half_chop(string, arg, arg1); if (!*arg) return FALSE; if ((action = find_action(arg)) < 0) return FALSE; if (DSC_FLAGGED(ch, DSC_EARTHMELD | DSC_BITUMENOUS_FLESH)) { msg_to_char(ch, "You can't do that right now!\r\n"); return TRUE; } perform_action(ch, action, arg1); return TRUE; } void perform_action(Creature ch, int act_nr, char *argument) { struct social_messg *action; Creature vict; action = &soc_mess_list[act_nr]; if (action->char_found) one_argument(argument, buf); else *buf = '\0'; if (GET_POS(ch) < action->min_char_position) { switch (GET_POS(ch)) { case POS_DEAD: send_to_char("Lie still; you are DEAD!!! :-(\r\n", ch); break; case POS_INCAP: case POS_MORTALLYW: send_to_char("You are in a pretty bad shape, unable to do anything!\r\n", ch); break; case POS_STUNNED: send_to_char("All you can do right now is think about the stars!\r\n", ch); break; case POS_SLEEPING: send_to_char("In your dreams, or what?\r\n", ch); break; case POS_RESTING: send_to_char("Nah... You feel too relaxed to do that..\r\n", ch); break; case POS_SITTING: send_to_char("Maybe you should get on your feet first?\r\n", ch); break; case POS_FIGHTING: send_to_char("No way! You're fighting for your life!\r\n", ch); break; } return; } if (!*buf) { send_to_char(action->char_no_arg, ch); send_to_char("\r\n", 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("\r\n", ch); } else if (vict == ch) { send_to_char(action->char_auto, ch); send_to_char("\r\n", ch); act(action->others_auto, action->hide, ch, 0, 0, TO_ROOM); } else { if (GET_POS(vict) < action->min_victim_position) { switch (GET_POS(vict)) { case POS_DEAD: act("$E's dead and you can't do much with $M.", FALSE, ch, 0, vict, TO_CHAR); break; case POS_INCAP: case POS_MORTALLYW: act("$E's in pretty bad shape.", FALSE, ch, 0, vict, TO_CHAR); break; case POS_STUNNED: act("$E's stunned right now.", FALSE, ch, 0, vict, TO_CHAR); break; case POS_SLEEPING: act("$E's too busy sleeping to bother with you.", FALSE, ch, 0, vict, TO_CHAR); break; case POS_RESTING: act("$E's resting right now.", FALSE, ch, 0, vict, TO_CHAR); break; case POS_SITTING: act("$E needs to be standing for that action.", FALSE, ch, 0, vict, TO_CHAR); break; case POS_FIGHTING: act("$E's too busy fighting.", FALSE, ch, 0, vict, TO_CHAR); break; } } else { act(action->char_found, 0, ch, 0, vict, TO_CHAR | TO_SLEEP); 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) { Creature victim; skip_spaces(&argument); one_argument(argument, arg); if (*arg) { if (!(victim = get_char_room_vis(ch, arg))) send_to_char(NOPERSON, ch); else { if (victim != ch) { sprintf(buf, "You insult %s.\r\n", PERS(victim, ch, 0)); send_to_char(buf, ch); switch (number(0, 2)) { case 0: if (GET_SEX(ch) == SEX_MALE) { if (GET_SEX(victim) == SEX_FEMALE) act("$n says that women can't fight.", FALSE, ch, 0, victim, TO_VICT); else act("$n accuses you of fighting like a woman!", FALSE, ch, 0, victim, TO_VICT); } else { if (GET_SEX(victim) != SEX_FEMALE) act("$n accuses you of having the smallest... (brain?)", FALSE, ch, 0, victim, TO_VICT); else act("$n tells you that you'd lose a beauty contest 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; } act("$n insults $N.", TRUE, ch, 0, victim, TO_NOTVICT); } else { send_to_char("You feel insulted.\r\n", ch); } } } else send_to_char("I'm sure you don't want to insult *everybody*...\r\n", ch); } char *fread_action(FILE * fl, int nr) { char buf[MAX_STRING_LENGTH], *rslt; fgets(buf, MAX_STRING_LENGTH, fl); if (feof(fl)) { log("SYSERR: fread_action - unexpected EOF near action #%d", nr+1); exit(1); } if (*buf == '#') return (NULL); 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, hide, min_vpos, min_cpos, curr_soc = -1; char next_soc[100]; /* open social file */ if (!(fl = fopen(SOCMESS_FILE, "r"))) { sprintf(buf, "SYSERR: Can't open socials file '%s'", SOCMESS_FILE); perror(buf); exit(1); } /* now read 'em */ for (nr = 0; nr < MAX_SOCIALS; nr++) { fscanf(fl, " %s ", next_soc); if (*next_soc == '*') { fscanf(fl, "%s\n", next_soc); continue; } if (*next_soc == '$') break; if (fscanf(fl, " %d %d %d \n", &hide, &min_cpos, &min_vpos) != 3) { log("SYSERR: Format error in social file near social '%s'", next_soc); exit(1); } /* read the stuff */ curr_soc++; soc_mess_list[curr_soc].name = strdup(next_soc); soc_mess_list[curr_soc].hide = hide; soc_mess_list[curr_soc].min_char_position = min_cpos; soc_mess_list[curr_soc].min_victim_position = min_vpos; soc_mess_list[curr_soc].char_no_arg = fread_action(fl, nr); soc_mess_list[curr_soc].others_no_arg = fread_action(fl, nr); soc_mess_list[curr_soc].char_found = fread_action(fl, nr); /* if no char_found, the rest is to be ignored */ if (!soc_mess_list[curr_soc].char_found) continue; soc_mess_list[curr_soc].others_found = fread_action(fl, nr); soc_mess_list[curr_soc].vict_found = fread_action(fl, nr); soc_mess_list[curr_soc].not_found = fread_action(fl, nr); soc_mess_list[curr_soc].char_auto = fread_action(fl, nr); soc_mess_list[curr_soc].others_auto = fread_action(fl, nr); } /* close file & set top */ fclose(fl); list_top = curr_soc; } int social_sort_info[MAX_SOCIALS]; void sort_socials(void) { int a, b, tmp; /* initialize array */ for (a = 0; a < list_top; a++) social_sort_info[a] = a; for (a = 0; a < list_top - 1; a++) for (b = a + 1; b < list_top; b++) if (strcmp(soc_mess_list[social_sort_info[a]].name, soc_mess_list[social_sort_info[b]].name) > 0) { tmp = social_sort_info[a]; social_sort_info[a] = social_sort_info[b]; social_sort_info[b] = tmp; } } ACMD(do_socials) { int sortpos, j = 0; /* Ugh, don't forget to sort... */ sort_socials(); sprintf(buf, "The following social commands are available:\r\n"); for (sortpos = 0; sortpos < list_top; sortpos++) sprintf(buf+strlen(buf), "%-11.11s%s", soc_mess_list[social_sort_info[sortpos]].name, (!(++j % 7)) ? "\r\n" : ""); strcat(buf, "\r\n"); page_string(ch->desc, buf, 1); }