/************************************************************************** * File: act.social.c Part of tbaMUD * * Usage: Functions to handle socials. * * * * All rights reserved. See license for complete information. * * * * 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" #include "spells.h" /* local functions */ int find_action(int cmd); ACMD(do_action); void free_social_messages(void); void free_action(struct social_messg *mess); void free_command_list(void); void create_command_list(void); ACMD(do_gmote); ACMD(do_action) { char arg[MAX_INPUT_LENGTH], part[MAX_INPUT_LENGTH]; int act_nr; struct social_messg *action; struct char_data *vict; struct obj_data *targ; if ((act_nr = find_action(cmd)) < 0) { send_to_char(ch, "That action is not supported.\r\n"); return; } action = &soc_mess_list[act_nr]; if (!argument || !*argument) { send_to_char(ch, "%s\r\n", action->char_no_arg); act(action->others_no_arg, action->hide, ch, 0, 0, TO_ROOM); return; } two_arguments(argument, arg, part); if ((!action->char_body_found) && (*part)) { send_to_char(ch, "Sorry, this social does not support body parts.\r\n"); return; } if (!action->char_found) *arg = '\0'; if (action->char_found && argument) one_argument(argument, arg); else *arg = '\0'; vict = get_char_vis(ch, arg, NULL, FIND_CHAR_ROOM); if (!vict) { if (action->char_obj_found) { targ = get_obj_in_list_vis(ch, arg, NULL, ch->carrying); if (!targ) targ = get_obj_in_list_vis(ch, arg, NULL, world[IN_ROOM(ch)].contents); if (targ) { act(action->char_obj_found, action->hide, ch, targ, 0, TO_CHAR); act(action->others_obj_found, action->hide, ch, targ, 0, TO_ROOM); return; } } if (action->not_found) send_to_char(ch, "%s\r\n", action->not_found); else send_to_char(ch, "I don't see anything by that name here.\r\n"); return; } if (vict == ch) { if (action->char_auto) send_to_char(ch, "%s\r\n", action->char_auto); else send_to_char(ch, "Erm, no."); act(action->others_auto, action->hide, ch, 0, 0, TO_ROOM); return; } if (GET_POS(vict) < action->min_victim_position) act("$N is not in a proper position for that.", FALSE, ch, 0, vict, TO_CHAR | TO_SLEEP); else { if (*part) { act(action->char_body_found, 0, ch, (struct obj_data *)part, vict, TO_CHAR | TO_SLEEP); act(action->others_body_found, action->hide, ch, (struct obj_data *)part, vict, TO_NOTVICT); act(action->vict_body_found, action->hide, ch, (struct obj_data *)part, vict, TO_VICT); } 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); } } } /* this function adds in the loaded socials and assigns them a command # */ void create_command_list(void) { int i, j, k; struct social_messg temp; extern struct command_info cmd_info[]; /* free up old command list */ if (complete_cmd_info) free_command_list(); /* re check the sort on the socials */ for (j = 0; j < top_of_socialt; j++) { k = j; for (i = j + 1; i <= top_of_socialt; i++) if (str_cmp(soc_mess_list[i].sort_as, soc_mess_list[k].sort_as) < 0) k = i; if (j != k) { temp = soc_mess_list[j]; soc_mess_list[j] = soc_mess_list[k]; soc_mess_list[k] = temp; } } /* count the commands in the command list */ i = 0; while(*cmd_info[i].command != '\n') i++; i++; CREATE(complete_cmd_info, struct command_info, top_of_socialt + i + 2); /* this loop sorts the socials and commands together into one big list */ i = 0; j = 0; k = 0; while ((*cmd_info[i].command != '\n') || (j <= top_of_socialt)) { if ((i < RESERVE_CMDS) || (j > top_of_socialt) || (str_cmp(cmd_info[i].sort_as, soc_mess_list[j].sort_as) < 1)) complete_cmd_info[k++] = cmd_info[i++]; else { soc_mess_list[j].act_nr = k; complete_cmd_info[k].command = soc_mess_list[j].command; complete_cmd_info[k].sort_as = soc_mess_list[j].sort_as; complete_cmd_info[k].minimum_position = soc_mess_list[j].min_char_position; complete_cmd_info[k].command_pointer = do_action; complete_cmd_info[k].minimum_level = soc_mess_list[j++].min_level_char; complete_cmd_info[k++].subcmd = 0; } } complete_cmd_info[k].command = strdup("\n"); complete_cmd_info[k].sort_as = strdup("zzzzzzz"); complete_cmd_info[k].minimum_position = 0; complete_cmd_info[k].command_pointer = 0; complete_cmd_info[k].minimum_level = 0; complete_cmd_info[k].subcmd = 0; log("Command info rebuilt, %d total commands.", k); } void free_command_list(void) { int i; for (i = 0;*complete_cmd_info[i].command !='\n';i++); free((char *)complete_cmd_info[i].command); /* special case, the terminator */ free((char *)complete_cmd_info[i].sort_as); free(complete_cmd_info); complete_cmd_info = NULL; } void free_social_messages(void) { struct social_messg *mess; int i; for (i = 0;i <= top_of_socialt;i++) { mess = &soc_mess_list[i]; free_action(mess); } free(soc_mess_list); } void free_action(struct social_messg *mess) { if (mess->command) free(mess->command); if (mess->sort_as) free(mess->sort_as); if (mess->char_no_arg) free(mess->char_no_arg); if (mess->others_no_arg) free(mess->others_no_arg); if (mess->char_found) free(mess->char_found); if (mess->others_found) free(mess->others_found); if (mess->vict_found) free(mess->vict_found); if (mess->char_body_found) free(mess->char_body_found); if (mess->others_body_found) free(mess->others_body_found); if (mess->vict_body_found) free(mess->vict_body_found); if (mess->not_found) free(mess->not_found); if (mess->char_auto) free(mess->char_auto); if (mess->others_auto) free(mess->others_auto); if (mess->char_obj_found) free(mess->char_obj_found); if (mess->others_obj_found) free(mess->others_obj_found); memset(mess, 0, sizeof(struct social_messg)); } int find_action(int cmd) { int bot, top, mid; bot = 0; top = top_of_socialt; 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_gmote) { int act_nr, length; char arg[MAX_INPUT_LENGTH], buf[MAX_INPUT_LENGTH]; struct social_messg *action; struct char_data *vict = NULL; half_chop(argument, buf, arg); if(subcmd) for (length = strlen(buf), cmd = 0; *complete_cmd_info[cmd].command != '\n'; cmd++) if (!strncmp(complete_cmd_info[cmd].command, buf, length)) break; if ((act_nr = find_action(cmd)) < 0) { snprintf(buf, sizeof(buf), "Gossip: $n%s", argument); act(buf, FALSE, ch, 0, vict, TO_GMOTE); return; } if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_SOUNDPROOF)) { send_to_char(ch, "The walls seem to absorb your actions.\r\n"); return; } action = &soc_mess_list[act_nr]; if (!action->char_found) *arg = '\0'; if (!*arg) { if(!action->others_no_arg || !*action->others_no_arg) { send_to_char(ch, "Who are you going to do that to?\r\n"); return; } snprintf(buf, sizeof(buf), "Gossip: %s", action->others_no_arg); } else if (!(vict = get_char_vis(ch, arg, NULL, FIND_CHAR_WORLD))) { send_to_char(ch, "%s\r\n", action->not_found); return; } else if (vict == ch) { if(!action->others_auto || !*action->others_auto) { send_to_char(ch, "%s\r\n", action->char_auto); return; } snprintf(buf, sizeof(buf), "Gossip: %s", action->others_auto); } 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 | TO_SLEEP); return; } snprintf(buf, sizeof(buf), "Gossip: %s", action->others_found); } act(buf, FALSE, ch, 0, vict, TO_GMOTE); }