Code:
ACMD(do_say)
{
skip_spaces(&argument);
if (!*argument)
send_to_char(ch, "Yes, but WHAT do you want to say?\r\n");
else {
char buf[MAX_INPUT_LENGTH + 14], *msg;
struct char_data *vict;
if (CONFIG_SPECIAL_IN_COMM && legal_communication(argument))
parse_at(argument);
snprintf(buf, sizeof(buf), "$n\tn says, '%s'", argument);
msg = act(buf, FALSE, ch, 0, 0, TO_ROOM | DG_NO_TRIG);
for (vict = world[IN_ROOM(ch)].people; vict; vict = vict->next_in_room)
if (vict != ch && GET_POS(vict) > POS_SLEEPING)
add_history(vict, msg, HIST_SAY);
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_NOREPEAT))
send_to_char(ch, "%s", CONFIG_OK);
else {
sprintf(buf, "You say, '%s'", argument);
msg = act(buf, FALSE, ch, 0, 0, TO_CHAR | DG_NO_TRIG);
add_history(ch, msg, HIST_SAY);
}
}
That is do_say, the only thing in a for loop is the part that adds to everyone's history. The act is not in a for loop like it is in your code.
You can't send TO_ROOM, or else everyone will see it - regardless of whether they know the language/skill, so you do need to send it TO_VICT inside of a loop instead.
Making it so only people that know telepathy can use the skill would leave it functioning mostly like say, making it only understandable by those trained in it though makes it more like a multi-targeted tell.