Palrich
red@smileyface.com
Head Imp, Divine Blood telnet://divineblood.tetradine.com:4000
I hacked this up to do what one of my builders wanted. It's kind of neat, so
I rewrote it to work with stock code+OLC1.81. I'm not sure how it'll do with
other OLC's. Basically it uses the phrase of a mobprog as a regular expression,
checks it against speech text, and stores the first 3 matches in $a, $b, and
$c.
So you add the prog with trigger REGEX and phrase "my name is (\w+)"
Then the body of the prog is,
say Why hello there, $a.
When the player says "My name is bob", the mob says "Why hello there, bob"
Pretty simple and all.
If you use something like this a lot, you should store the compiled regexprec
rather than building and freeing it every time, because this here is hugely
inefficient.
// At the top of mob_prog.c
#include <regex.h>
// ... then in the global scope
char match[3][MAX_INPUT_LENGTH];
// Inside expand_arg
case 'a':
i = match[0]; break;
case 'b':
i = match[1]; break;
case 'c':
i = match[2]; break;
//somewhere toward the bottom of mob_prog.c
void mp_regex_trigger(char *argument, CHAR_DATA *mob, CHAR_DATA *ch)
{
regex_t exprec;
int nmemb = 3, i;
regmatch_t memb[nmemb];
MPROG_LIST *prg;
for (prg = mob->pIndexData->mprogs; prg != NULL; prg = prg->next)
if ( prg->trig_type == TRIG_REGEXP)
{
regcomp(&exprec, prg->trig_phrase, REG_EXTENDED|REG_ICASE);
if (!regexec(&exprec, argument, nmemb, memb, 0))
{
for (i = 0; i < nmemb && memb[i+1].rm_so > -1; i++)
{
memcpy(match[i], argument+memb[i+1].rm_so,
memb[i+1].rm_eo-memb[i+1].rm_so);
match[i][memb[i+1].rm_eo-memb[i+1].rm_so] = '\0';
}
program_flow(prg->vnum, prg->code, mob, ch, arg1, arg2);
}
regfree(&exprec);
return;
}
}
// merc.h, with the other TRIG_*s
#define TRIG_REGEX (Q)
// merc.h, with the other mp trigger function definitions
void mp_regex_trigger(char *argument, CHAR_DATA *mob, CHAR_DATA *ch);
// tables.c, in mprog_flags
{ "regex", TRIG_REGEX, TRUE },
//mob_cmds.c, inside mprog_type_to_name
case TRIG_REGEX: return "REGEX";
//act_comm.c, under the check for TRIG_SPEECH
if (IS_NPC(mob) && HAS_TRIGGER( mob, TRIG_REGEX))
mp_regex_trigger(argument,mob,ch);