mirror of
https://github.com/tbamud/tbamud.git
synced 2026-03-20 03:06:32 +01:00
Say/Talk/Whisper update
This commit is contained in:
parent
5dcc018fcd
commit
7a23aba72d
1 changed files with 311 additions and 82 deletions
393
src/act.comm.c
393
src/act.comm.c
|
|
@ -123,6 +123,133 @@ static void trim_whitespace(char *s) {
|
|||
s[--len] = '\0';
|
||||
}
|
||||
|
||||
static bool parse_speech_adornments(struct char_data *ch, char **text,
|
||||
char *bracket_raw, size_t bracket_sz, bool *has_bracket,
|
||||
char *paren_raw, size_t paren_sz, bool *has_paren)
|
||||
{
|
||||
char *p = *text;
|
||||
|
||||
if (bracket_raw && bracket_sz > 0)
|
||||
bracket_raw[0] = '\0';
|
||||
if (paren_raw && paren_sz > 0)
|
||||
paren_raw[0] = '\0';
|
||||
if (has_bracket)
|
||||
*has_bracket = FALSE;
|
||||
if (has_paren)
|
||||
*has_paren = FALSE;
|
||||
|
||||
while (TRUE) {
|
||||
skip_spaces(&p);
|
||||
|
||||
if (*p == '[' && has_bracket && !*has_bracket) {
|
||||
const char *close = strchr(p, ']');
|
||||
if (!close) {
|
||||
send_to_char(ch, "You need a closing ']'.\r\n");
|
||||
return FALSE;
|
||||
}
|
||||
size_t len = (size_t)(close - p - 1);
|
||||
if (len >= bracket_sz)
|
||||
len = bracket_sz - 1;
|
||||
if (len > 0 && bracket_raw) {
|
||||
strncpy(bracket_raw, p + 1, len);
|
||||
bracket_raw[len] = '\0';
|
||||
trim_whitespace(bracket_raw);
|
||||
} else if (bracket_raw && bracket_sz > 0)
|
||||
bracket_raw[0] = '\0';
|
||||
*has_bracket = TRUE;
|
||||
p = (char *)close + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*p == '(' && has_paren && !*has_paren) {
|
||||
const char *close = strchr(p, ')');
|
||||
if (!close) {
|
||||
send_to_char(ch, "You need a closing ')'.\r\n");
|
||||
return FALSE;
|
||||
}
|
||||
size_t len = (size_t)(close - p - 1);
|
||||
if (len >= paren_sz)
|
||||
len = paren_sz - 1;
|
||||
if (len > 0 && paren_raw) {
|
||||
strncpy(paren_raw, p + 1, len);
|
||||
paren_raw[len] = '\0';
|
||||
trim_whitespace(paren_raw);
|
||||
} else if (paren_raw && paren_sz > 0)
|
||||
paren_raw[0] = '\0';
|
||||
*has_paren = TRUE;
|
||||
p = (char *)close + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*text = p;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void wrap_line(const char *src, char *dst, size_t dstsz, int width)
|
||||
{
|
||||
size_t out = 0;
|
||||
int col = 0;
|
||||
const char *p = src;
|
||||
bool first_word = TRUE;
|
||||
|
||||
if (!dst || dstsz == 0)
|
||||
return;
|
||||
|
||||
dst[0] = '\0';
|
||||
|
||||
while (*p && out < dstsz - 1) {
|
||||
while (*p && isspace((unsigned char)*p) && *p != '\n' && *p != '\r')
|
||||
p++;
|
||||
if (!*p)
|
||||
break;
|
||||
|
||||
const char *word_start = p;
|
||||
size_t word_len = 0;
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
word_len++, p++;
|
||||
|
||||
if (word_len == 0)
|
||||
continue;
|
||||
|
||||
if (!first_word && col + 1 + (int)word_len > width) {
|
||||
if (out < dstsz - 2) {
|
||||
dst[out++] = '\r';
|
||||
dst[out++] = '\n';
|
||||
}
|
||||
col = 0;
|
||||
first_word = TRUE;
|
||||
}
|
||||
|
||||
if (!first_word) {
|
||||
if (out < dstsz - 1) {
|
||||
dst[out++] = ' ';
|
||||
col++;
|
||||
}
|
||||
}
|
||||
|
||||
size_t copy = MIN(word_len, dstsz - 1 - out);
|
||||
memcpy(dst + out, word_start, copy);
|
||||
out += copy;
|
||||
col += word_len;
|
||||
first_word = FALSE;
|
||||
|
||||
while (*p && (*p == '\n' || *p == '\r')) {
|
||||
if (out < dstsz - 2) {
|
||||
dst[out++] = '\r';
|
||||
dst[out++] = '\n';
|
||||
}
|
||||
p++;
|
||||
col = 0;
|
||||
first_word = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
dst[out] = '\0';
|
||||
}
|
||||
|
||||
ACMD(do_say)
|
||||
{
|
||||
char *p = argument;
|
||||
|
|
@ -135,39 +262,10 @@ ACMD(do_say)
|
|||
bool has_paren = FALSE;
|
||||
|
||||
skip_spaces(&p);
|
||||
|
||||
if (*p == '[') {
|
||||
const char *close = strchr(p, ']');
|
||||
if (!close) {
|
||||
send_to_char(ch, "You need a closing ']'.\r\n");
|
||||
return;
|
||||
}
|
||||
size_t len = (size_t)(close - p - 1);
|
||||
if (len >= sizeof(bracket_raw))
|
||||
len = sizeof(bracket_raw) - 1;
|
||||
strncpy(bracket_raw, p + 1, len);
|
||||
bracket_raw[len] = '\0';
|
||||
trim_whitespace(bracket_raw);
|
||||
p = (char *)close + 1;
|
||||
}
|
||||
|
||||
skip_spaces(&p);
|
||||
|
||||
if (*p == '(') {
|
||||
const char *close = strchr(p, ')');
|
||||
if (!close) {
|
||||
send_to_char(ch, "You need a closing ')'.\r\n");
|
||||
return;
|
||||
}
|
||||
size_t len = (size_t)(close - p - 1);
|
||||
if (len >= sizeof(paren_raw))
|
||||
len = sizeof(paren_raw) - 1;
|
||||
strncpy(paren_raw, p + 1, len);
|
||||
paren_raw[len] = '\0';
|
||||
trim_whitespace(paren_raw);
|
||||
p = (char *)close + 1;
|
||||
}
|
||||
|
||||
if (!parse_speech_adornments(ch, &p,
|
||||
bracket_raw, sizeof(bracket_raw), &has_bracket,
|
||||
paren_raw, sizeof(paren_raw), &has_paren))
|
||||
return;
|
||||
skip_spaces(&p);
|
||||
|
||||
if (!*p) {
|
||||
|
|
@ -238,11 +336,13 @@ ACMD(do_say)
|
|||
}
|
||||
|
||||
strlcat(first_line, ":", sizeof(first_line));
|
||||
send_to_char(vict, "%s\r\n \"%s\"\r\n", first_line, speech);
|
||||
char wrapped_line[MAX_STRING_LENGTH];
|
||||
wrap_line(first_line, wrapped_line, sizeof(wrapped_line), 80);
|
||||
send_to_char(vict, "%s\r\n \"%s\"\r\n", wrapped_line, speech);
|
||||
|
||||
if (!self || !suppress_self) {
|
||||
char hist_buf[MAX_STRING_LENGTH];
|
||||
snprintf(hist_buf, sizeof(hist_buf), "%s\r\n \"%s\"", first_line, speech);
|
||||
snprintf(hist_buf, sizeof(hist_buf), "%s\r\n \"%s\"", wrapped_line, speech);
|
||||
add_history(vict, hist_buf, HIST_SAY);
|
||||
}
|
||||
}
|
||||
|
|
@ -282,38 +382,10 @@ ACMD(do_talk)
|
|||
}
|
||||
|
||||
skip_spaces(&p);
|
||||
if (*p == '[') {
|
||||
const char *close = strchr(p, ']');
|
||||
if (!close) {
|
||||
send_to_char(ch, "You need a closing ']'.\r\n");
|
||||
return;
|
||||
}
|
||||
size_t len = (size_t)(close - p - 1);
|
||||
if (len >= sizeof(bracket_raw))
|
||||
len = sizeof(bracket_raw) - 1;
|
||||
strncpy(bracket_raw, p + 1, len);
|
||||
bracket_raw[len] = '\0';
|
||||
trim_whitespace(bracket_raw);
|
||||
p = (char *)close + 1;
|
||||
}
|
||||
|
||||
skip_spaces(&p);
|
||||
|
||||
if (*p == '(') {
|
||||
const char *close = strchr(p, ')');
|
||||
if (!close) {
|
||||
send_to_char(ch, "You need a closing ')'.\r\n");
|
||||
return;
|
||||
}
|
||||
size_t len = (size_t)(close - p - 1);
|
||||
if (len >= sizeof(paren_raw))
|
||||
len = sizeof(paren_raw) - 1;
|
||||
strncpy(paren_raw, p + 1, len);
|
||||
paren_raw[len] = '\0';
|
||||
trim_whitespace(paren_raw);
|
||||
p = (char *)close + 1;
|
||||
}
|
||||
|
||||
if (!parse_speech_adornments(ch, &p,
|
||||
bracket_raw, sizeof(bracket_raw), &has_bracket,
|
||||
paren_raw, sizeof(paren_raw), &has_paren))
|
||||
return;
|
||||
skip_spaces(&p);
|
||||
|
||||
if (!*p) {
|
||||
|
|
@ -386,10 +458,12 @@ ACMD(do_talk)
|
|||
snprintf(locbuf, sizeof(locbuf), "at %s,", furn_name);
|
||||
strlcat(first_line, locbuf, sizeof(first_line));
|
||||
|
||||
send_to_char(tch, "%s\r\n \"%s\"\r\n", first_line, speech);
|
||||
char wrapped_line[MAX_STRING_LENGTH];
|
||||
wrap_line(first_line, wrapped_line, sizeof(wrapped_line), 80);
|
||||
send_to_char(tch, "%s\r\n \"%s\"\r\n", wrapped_line, speech);
|
||||
|
||||
char hist_buf[MAX_STRING_LENGTH];
|
||||
snprintf(hist_buf, sizeof(hist_buf), "%s\r\n \"%s\"", first_line, speech);
|
||||
snprintf(hist_buf, sizeof(hist_buf), "%s\r\n \"%s\"", wrapped_line, speech);
|
||||
add_history(tch, hist_buf, HIST_SAY);
|
||||
delivered = TRUE;
|
||||
}
|
||||
|
|
@ -428,9 +502,11 @@ ACMD(do_talk)
|
|||
snprintf(locbuf, sizeof(locbuf), "at %s,", furn_name);
|
||||
strlcat(first_line, locbuf, sizeof(first_line));
|
||||
|
||||
send_to_char(ch, "%s\r\n \"%s\"\r\n", first_line, speech);
|
||||
char wrapped_line[MAX_STRING_LENGTH];
|
||||
wrap_line(first_line, wrapped_line, sizeof(wrapped_line), 80);
|
||||
send_to_char(ch, "%s\r\n \"%s\"\r\n", wrapped_line, speech);
|
||||
char hist_buf[MAX_STRING_LENGTH];
|
||||
snprintf(hist_buf, sizeof(hist_buf), "%s\r\n \"%s\"", first_line, speech);
|
||||
snprintf(hist_buf, sizeof(hist_buf), "%s\r\n \"%s\"", wrapped_line, speech);
|
||||
add_history(ch, hist_buf, HIST_SAY);
|
||||
}
|
||||
|
||||
|
|
@ -473,7 +549,9 @@ ACMD(do_talk)
|
|||
}
|
||||
strlcat(line, ".", sizeof(line));
|
||||
|
||||
send_to_char(onlooker, "%s\r\n", line);
|
||||
char wrapped_line[MAX_STRING_LENGTH];
|
||||
wrap_line(line, wrapped_line, sizeof(wrapped_line), 80);
|
||||
send_to_char(onlooker, "%s\r\n", wrapped_line);
|
||||
}
|
||||
|
||||
speech_mtrigger(ch, speech);
|
||||
|
|
@ -716,19 +794,170 @@ ACMD(do_spec_comm)
|
|||
else if (vict == ch)
|
||||
send_to_char(ch, "You can't get your mouth close enough to your ear...\r\n");
|
||||
else {
|
||||
char buf1[MAX_STRING_LENGTH];
|
||||
if (subcmd == SCMD_WHISPER) {
|
||||
char bracket_raw[MAX_INPUT_LENGTH] = "";
|
||||
char paren_raw[MAX_INPUT_LENGTH] = "";
|
||||
struct targeted_phrase bracket_phrase;
|
||||
struct targeted_phrase paren_phrase;
|
||||
bool has_bracket = FALSE, has_paren = FALSE;
|
||||
char speech[MAX_INPUT_LENGTH];
|
||||
char *p = buf2;
|
||||
|
||||
if (CONFIG_SPECIAL_IN_COMM && legal_communication(argument))
|
||||
parse_at(buf2);
|
||||
skip_spaces(&p);
|
||||
if (!parse_speech_adornments(ch, &p,
|
||||
bracket_raw, sizeof(bracket_raw), &has_bracket,
|
||||
paren_raw, sizeof(paren_raw), &has_paren))
|
||||
return;
|
||||
skip_spaces(&p);
|
||||
|
||||
snprintf(buf1, sizeof(buf1), "$n %s you, '%s'", action_plur, buf2);
|
||||
act(buf1, FALSE, ch, 0, vict, TO_VICT);
|
||||
if (!*p) {
|
||||
send_to_char(ch, "Whisper what?\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!IS_NPC(ch)) && (PRF_FLAGGED(ch, PRF_NOREPEAT)))
|
||||
send_to_char(ch, "%s", CONFIG_OK);
|
||||
else
|
||||
send_to_char(ch, "You %s %s, '%s'\r\n", action_sing, GET_NAME(vict), buf2);
|
||||
act(action_others, FALSE, ch, 0, vict, TO_NOTVICT);
|
||||
strlcpy(speech, p, sizeof(speech));
|
||||
|
||||
if (CONFIG_SPECIAL_IN_COMM && legal_communication(speech))
|
||||
parse_at(speech);
|
||||
|
||||
if (*bracket_raw) {
|
||||
if (!build_targeted_phrase(ch, bracket_raw, FALSE, &bracket_phrase))
|
||||
return;
|
||||
has_bracket = TRUE;
|
||||
}
|
||||
if (*paren_raw) {
|
||||
if (!build_targeted_phrase(ch, paren_raw, FALSE, &paren_phrase))
|
||||
return;
|
||||
has_paren = TRUE;
|
||||
}
|
||||
|
||||
/* Message to victim */
|
||||
{
|
||||
char prefix[MAX_STRING_LENGTH] = "";
|
||||
char suffix[MAX_STRING_LENGTH] = "";
|
||||
char first_line[MAX_STRING_LENGTH];
|
||||
|
||||
if (has_bracket)
|
||||
render_targeted_phrase(ch, &bracket_phrase, FALSE, vict, prefix, sizeof(prefix));
|
||||
if (has_paren)
|
||||
render_targeted_phrase(ch, &paren_phrase, FALSE, vict, suffix, sizeof(suffix));
|
||||
|
||||
const char *speaker = get_char_sdesc(ch);
|
||||
if (*prefix) {
|
||||
char capped[MAX_STRING_LENGTH];
|
||||
strlcpy(capped, prefix, sizeof(capped));
|
||||
CAP(capped);
|
||||
strlcpy(first_line, capped, sizeof(first_line));
|
||||
strlcat(first_line, ", ", sizeof(first_line));
|
||||
strlcat(first_line, speaker ? speaker : PERS(ch, vict), sizeof(first_line));
|
||||
} else {
|
||||
strlcpy(first_line, speaker ? speaker : PERS(ch, vict), sizeof(first_line));
|
||||
}
|
||||
|
||||
strlcat(first_line, " whispers to you", sizeof(first_line));
|
||||
if (*suffix) {
|
||||
strlcat(first_line, ", ", sizeof(first_line));
|
||||
strlcat(first_line, suffix, sizeof(first_line));
|
||||
}
|
||||
strlcat(first_line, ":", sizeof(first_line));
|
||||
|
||||
char wrapped_line[MAX_STRING_LENGTH];
|
||||
wrap_line(first_line, wrapped_line, sizeof(wrapped_line), 80);
|
||||
send_to_char(vict, "%s\r\n \"%s\"\r\n", wrapped_line, speech);
|
||||
}
|
||||
|
||||
/* Message to self */
|
||||
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_NOREPEAT)) {
|
||||
send_to_char(ch, "%s", CONFIG_OK);
|
||||
} else {
|
||||
char prefix[MAX_STRING_LENGTH] = "";
|
||||
char suffix[MAX_STRING_LENGTH] = "";
|
||||
char first_line[MAX_STRING_LENGTH];
|
||||
|
||||
if (has_bracket)
|
||||
render_targeted_phrase(ch, &bracket_phrase, FALSE, ch, prefix, sizeof(prefix));
|
||||
if (has_paren)
|
||||
render_targeted_phrase(ch, &paren_phrase, FALSE, ch, suffix, sizeof(suffix));
|
||||
|
||||
if (*prefix) {
|
||||
char capped[MAX_STRING_LENGTH];
|
||||
strlcpy(capped, prefix, sizeof(capped));
|
||||
CAP(capped);
|
||||
strlcpy(first_line, capped, sizeof(first_line));
|
||||
strlcat(first_line, ", you", sizeof(first_line));
|
||||
} else {
|
||||
strlcpy(first_line, "you", sizeof(first_line));
|
||||
CAP(first_line);
|
||||
}
|
||||
|
||||
strlcat(first_line, " whisper to ", sizeof(first_line));
|
||||
strlcat(first_line, get_char_sdesc(vict), sizeof(first_line));
|
||||
if (*suffix) {
|
||||
strlcat(first_line, ", ", sizeof(first_line));
|
||||
strlcat(first_line, suffix, sizeof(first_line));
|
||||
}
|
||||
strlcat(first_line, ":", sizeof(first_line));
|
||||
|
||||
char wrapped_line[MAX_STRING_LENGTH];
|
||||
wrap_line(first_line, wrapped_line, sizeof(wrapped_line), 80);
|
||||
send_to_char(ch, "%s\r\n \"%s\"\r\n", wrapped_line, speech);
|
||||
}
|
||||
|
||||
/* Onlookers */
|
||||
for (struct char_data *onlooker = world[IN_ROOM(ch)].people; onlooker; onlooker = onlooker->next_in_room) {
|
||||
if (onlooker == ch || onlooker == vict)
|
||||
continue;
|
||||
if (GET_POS(onlooker) <= POS_SLEEPING)
|
||||
continue;
|
||||
|
||||
char prefix[MAX_STRING_LENGTH] = "";
|
||||
char suffix[MAX_STRING_LENGTH] = "";
|
||||
char line[MAX_STRING_LENGTH];
|
||||
|
||||
if (has_bracket)
|
||||
render_targeted_phrase(ch, &bracket_phrase, FALSE, onlooker, prefix, sizeof(prefix));
|
||||
if (has_paren)
|
||||
render_targeted_phrase(ch, &paren_phrase, FALSE, onlooker, suffix, sizeof(suffix));
|
||||
|
||||
if (*prefix) {
|
||||
char capped[MAX_STRING_LENGTH];
|
||||
strlcpy(capped, prefix, sizeof(capped));
|
||||
CAP(capped);
|
||||
strlcpy(line, capped, sizeof(line));
|
||||
strlcat(line, ", ", sizeof(line));
|
||||
strlcat(line, PERS(ch, onlooker), sizeof(line));
|
||||
} else {
|
||||
strlcpy(line, PERS(ch, onlooker), sizeof(line));
|
||||
}
|
||||
|
||||
strlcat(line, " whispers something to ", sizeof(line));
|
||||
strlcat(line, PERS(vict, onlooker), sizeof(line));
|
||||
|
||||
if (*suffix) {
|
||||
strlcat(line, ", ", sizeof(line));
|
||||
strlcat(line, suffix, sizeof(line));
|
||||
}
|
||||
strlcat(line, ".", sizeof(line));
|
||||
|
||||
char wrapped_line[MAX_STRING_LENGTH];
|
||||
wrap_line(line, wrapped_line, sizeof(wrapped_line), 80);
|
||||
send_to_char(onlooker, "%s\r\n", wrapped_line);
|
||||
}
|
||||
} else {
|
||||
char buf1[MAX_STRING_LENGTH];
|
||||
|
||||
if (CONFIG_SPECIAL_IN_COMM && legal_communication(argument))
|
||||
parse_at(buf2);
|
||||
|
||||
snprintf(buf1, sizeof(buf1), "$n %s you, '%s'", action_plur, buf2);
|
||||
act(buf1, FALSE, ch, 0, vict, TO_VICT);
|
||||
|
||||
if ((!IS_NPC(ch)) && (PRF_FLAGGED(ch, PRF_NOREPEAT)))
|
||||
send_to_char(ch, "%s", CONFIG_OK);
|
||||
else
|
||||
send_to_char(ch, "You %s %s, '%s'\r\n", action_sing, GET_NAME(vict), buf2);
|
||||
act(action_others, FALSE, ch, 0, vict, TO_NOTVICT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue