mirror of
https://github.com/tbamud/tbamud.git
synced 2025-12-23 02:30:13 +01:00
341 lines
9.8 KiB
C
341 lines
9.8 KiB
C
|
|
/* ************************************************************************
|
||
|
|
* File: act.social.c Part of CircleMUD *
|
||
|
|
* Usage: Functions to handle socials *
|
||
|
|
* *
|
||
|
|
* All rights reserved. See license.doc 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);
|
||
|
|
ACMD(do_insult);
|
||
|
|
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);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
ACMD(do_insult)
|
||
|
|
{
|
||
|
|
char arg[MAX_INPUT_LENGTH];
|
||
|
|
struct char_data *victim;
|
||
|
|
|
||
|
|
one_argument(argument, arg);
|
||
|
|
|
||
|
|
if (*arg) {
|
||
|
|
if (!(victim = get_char_vis(ch, arg, NULL, FIND_CHAR_ROOM)))
|
||
|
|
send_to_char(ch, "Can't hear you!\r\n");
|
||
|
|
else {
|
||
|
|
if (victim != ch) {
|
||
|
|
send_to_char(ch, "You insult %s.\r\n", GET_NAME(victim));
|
||
|
|
|
||
|
|
switch (rand_number(0, 2)) {
|
||
|
|
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 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;
|
||
|
|
} /* end switch */
|
||
|
|
|
||
|
|
act("$n insults $N.", TRUE, ch, 0, victim, TO_NOTVICT);
|
||
|
|
} else { /* ch == victim */
|
||
|
|
send_to_char(ch, "You feel insulted.\r\n");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else
|
||
|
|
send_to_char(ch, "I'm sure you don't want to insult *everybody*...\r\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 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) {
|
||
|
|
send_to_char(ch, "That's not a social!\r\n");
|
||
|
|
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);
|
||
|
|
}
|