diff options
Diffstat (limited to 'src/map/npc_chat.c')
-rw-r--r-- | src/map/npc_chat.c | 568 |
1 files changed, 287 insertions, 281 deletions
diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c index c0a965e9d..39a3a8584 100644 --- a/src/map/npc_chat.c +++ b/src/map/npc_chat.c @@ -40,7 +40,7 @@ * * defpattern 1, "[^:]+: (.*) loves (.*)", "label"; * - * this defines a new pattern in set 1 using perl syntax + * this defines a new pattern in set 1 using perl syntax * (http://www.troubleshooters.com/codecorn/littperl/perlreg.htm) * and tells it to jump to the supplied label when the pattern * is matched. @@ -50,7 +50,7 @@ * before the script gets executed. * * activatepset 1; - * + * * This activates a set of patterns.. You can have many pattern * sets defined and many active all at once. This feature allows * you to set up "conversations" and ever changing expectations of @@ -71,22 +71,22 @@ /* Structure containing all info associated with a single pattern block */ struct pcrematch_entry { - struct pcrematch_entry *next; - char *pattern; - pcre *pcre_; - pcre_extra *pcre_extra_; - char *label; + struct pcrematch_entry* next; + char* pattern; + pcre* pcre_; + pcre_extra* pcre_extra_; + char* label; }; /* A set of patterns that can be activated and deactived with a single command */ struct pcrematch_set { - struct pcrematch_set *prev; - struct pcrematch_set *next; - struct pcrematch_entry *head; - int setid; + struct pcrematch_set* prev; + struct pcrematch_set* next; + struct pcrematch_entry* head; + int setid; }; -/* +/* * Entire data structure hung off a NPC * * The reason I have done it this way (a void * in npc_data and then @@ -96,8 +96,8 @@ struct pcrematch_set { * without having to do a large number of changes. */ struct npc_parse { - struct pcrematch_set *active; - struct pcrematch_set *inactive; + struct pcrematch_set* active; + struct pcrematch_set* inactive; }; @@ -106,50 +106,51 @@ struct npc_parse { * * This does NOT do the list management */ -void finalize_pcrematch_entry(struct pcrematch_entry *e) +void finalize_pcrematch_entry(struct pcrematch_entry* e) { - pcre_free(e->pcre_); - pcre_free(e->pcre_extra_); - aFree(e->pattern); - aFree(e->label); + pcre_free(e->pcre_); + pcre_free(e->pcre_extra_); + aFree(e->pattern); + aFree(e->label); } /** * Lookup (and possibly create) a new set of patterns by the set id */ -static struct pcrematch_set *lookup_pcreset(struct npc_data *nd, int setid) { - struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) - nd->chatdb = npcParse = (struct npc_parse *) aCalloc(sizeof(struct npc_parse), 1); - - pcreset = npcParse->active; - - while (pcreset != NULL) { - if (pcreset->setid == setid) - break; - pcreset = pcreset->next; - } - if (pcreset == NULL) - pcreset = npcParse->inactive; - - while (pcreset != NULL) { - if (pcreset->setid == setid) - break; - pcreset = pcreset->next; - } - - if (pcreset == NULL) { - pcreset = (struct pcrematch_set *) aCalloc(sizeof(struct pcrematch_set), 1); - pcreset->next = npcParse->inactive; - if (pcreset->next != NULL) - pcreset->next->prev = pcreset; - pcreset->prev = 0; - npcParse->inactive = pcreset; - pcreset->setid = setid; - } - - return pcreset; +static struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int setid) +{ + struct pcrematch_set *pcreset; + struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; + if (npcParse == NULL) + nd->chatdb = npcParse = (struct npc_parse *) aCalloc(sizeof(struct npc_parse), 1); + + pcreset = npcParse->active; + + while (pcreset != NULL) { + if (pcreset->setid == setid) + break; + pcreset = pcreset->next; + } + if (pcreset == NULL) + pcreset = npcParse->inactive; + + while (pcreset != NULL) { + if (pcreset->setid == setid) + break; + pcreset = pcreset->next; + } + + if (pcreset == NULL) { + pcreset = (struct pcrematch_set *) aCalloc(sizeof(struct pcrematch_set), 1); + pcreset->next = npcParse->inactive; + if (pcreset->next != NULL) + pcreset->next->prev = pcreset; + pcreset->prev = 0; + npcParse->inactive = pcreset; + pcreset->setid = setid; + } + + return pcreset; } /** @@ -157,32 +158,32 @@ static struct pcrematch_set *lookup_pcreset(struct npc_data *nd, int setid) { * * if the setid does not exist, this will silently return */ -static void activate_pcreset(struct npc_data *nd, int setid) +static void activate_pcreset(struct npc_data* nd, int setid) { - struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) - return; // Nothing to activate... - pcreset = npcParse->inactive; - while (pcreset != NULL) { - if (pcreset->setid == setid) - break; - pcreset = pcreset->next; - } - if (pcreset == NULL) - return; // not in inactive list - if (pcreset->next != NULL) - pcreset->next->prev = pcreset->prev; - if (pcreset->prev != NULL) - pcreset->prev->next = pcreset->next; - else - npcParse->inactive = pcreset->next; - - pcreset->prev = NULL; - pcreset->next = npcParse->active; - if (pcreset->next != NULL) - pcreset->next->prev = pcreset; - npcParse->active = pcreset; + struct pcrematch_set *pcreset; + struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; + if (npcParse == NULL) + return; // Nothing to activate... + pcreset = npcParse->inactive; + while (pcreset != NULL) { + if (pcreset->setid == setid) + break; + pcreset = pcreset->next; + } + if (pcreset == NULL) + return; // not in inactive list + if (pcreset->next != NULL) + pcreset->next->prev = pcreset->prev; + if (pcreset->prev != NULL) + pcreset->prev->next = pcreset->next; + else + npcParse->inactive = pcreset->next; + + pcreset->prev = NULL; + pcreset->next = npcParse->active; + if (pcreset->next != NULL) + pcreset->next->prev = pcreset; + npcParse->active = pcreset; } /** @@ -190,255 +191,260 @@ static void activate_pcreset(struct npc_data *nd, int setid) * * if the setid does not exist, this will silently return */ -static void deactivate_pcreset(struct npc_data *nd, int setid) +static void deactivate_pcreset(struct npc_data* nd, int setid) { - struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) - return; // Nothing to deactivate... - if (setid == -1) { - while (npcParse->active != NULL) - deactivate_pcreset(nd, npcParse->active->setid); - return; - } - pcreset = npcParse->active; - while (pcreset != NULL) { - if (pcreset->setid == setid) - break; - pcreset = pcreset->next; - } - if (pcreset == NULL) - return; // not in active list - if (pcreset->next != NULL) - pcreset->next->prev = pcreset->prev; - if (pcreset->prev != NULL) - pcreset->prev->next = pcreset->next; - else - npcParse->active = pcreset->next; - - pcreset->prev = NULL; - pcreset->next = npcParse->inactive; - if (pcreset->next != NULL) - pcreset->next->prev = pcreset; - npcParse->inactive = pcreset; + struct pcrematch_set *pcreset; + struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; + if (npcParse == NULL) + return; // Nothing to deactivate... + if (setid == -1) { + while(npcParse->active != NULL) + deactivate_pcreset(nd, npcParse->active->setid); + return; + } + pcreset = npcParse->active; + while (pcreset != NULL) { + if (pcreset->setid == setid) + break; + pcreset = pcreset->next; + } + if (pcreset == NULL) + return; // not in active list + if (pcreset->next != NULL) + pcreset->next->prev = pcreset->prev; + if (pcreset->prev != NULL) + pcreset->prev->next = pcreset->next; + else + npcParse->active = pcreset->next; + + pcreset->prev = NULL; + pcreset->next = npcParse->inactive; + if (pcreset->next != NULL) + pcreset->next->prev = pcreset; + npcParse->inactive = pcreset; } /** * delete a set of patterns. */ -static void delete_pcreset(struct npc_data *nd, int setid) +static void delete_pcreset(struct npc_data* nd, int setid) { - int active = 1; - struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) - return; // Nothing to deactivate... - pcreset = npcParse->active; - while (pcreset != NULL) { - if (pcreset->setid == setid) - break; - pcreset = pcreset->next; - } - if (pcreset == NULL) { - active = 0; - pcreset = npcParse->inactive; - while (pcreset != NULL) { - if (pcreset->setid == setid) - break; - pcreset = pcreset->next; - } - } - if (pcreset == NULL) - return; - - if (pcreset->next != NULL) - pcreset->next->prev = pcreset->prev; - if (pcreset->prev != NULL) - pcreset->prev->next = pcreset->next; - - if (active) - npcParse->active = pcreset->next; - else - npcParse->inactive = pcreset->next; - - pcreset->prev = NULL; - pcreset->next = NULL; - - while (pcreset->head) { - struct pcrematch_entry *n = pcreset->head->next; - finalize_pcrematch_entry(pcreset->head); - aFree(pcreset->head); // Cleanin' the last ones.. [Lance] - pcreset->head = n; - } - - aFree(pcreset); + int active = 1; + struct pcrematch_set *pcreset; + struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; + if (npcParse == NULL) + return; // Nothing to deactivate... + pcreset = npcParse->active; + while (pcreset != NULL) { + if (pcreset->setid == setid) + break; + pcreset = pcreset->next; + } + if (pcreset == NULL) { + active = 0; + pcreset = npcParse->inactive; + while (pcreset != NULL) { + if (pcreset->setid == setid) + break; + pcreset = pcreset->next; + } + } + if (pcreset == NULL) + return; + + if (pcreset->next != NULL) + pcreset->next->prev = pcreset->prev; + if (pcreset->prev != NULL) + pcreset->prev->next = pcreset->next; + + if(active) + npcParse->active = pcreset->next; + else + npcParse->inactive = pcreset->next; + + pcreset->prev = NULL; + pcreset->next = NULL; + + while (pcreset->head) { + struct pcrematch_entry* n = pcreset->head->next; + finalize_pcrematch_entry(pcreset->head); + aFree(pcreset->head); // Cleanin' the last ones.. [Lance] + pcreset->head = n; + } + + aFree(pcreset); } /** - * create a new pattern entry + * create a new pattern entry */ -static struct pcrematch_entry *create_pcrematch_entry(struct pcrematch_set *set) { - struct pcrematch_entry *e = (struct pcrematch_entry *) aCalloc(sizeof(struct pcrematch_entry), 1); - struct pcrematch_entry *last = set->head; - - // Normally we would have just stuck it at the end of the list but - // this doesn't sink up with peoples usage pattern. They wanted - // the items defined first to have a higher priority then the - // items defined later. as a result, we have to do some work up front. - - /* if we are the first pattern, stick us at the end */ - if (last == NULL) { - set->head = e; - return e; - } - - /* Look for the last entry */ - while (last->next != NULL) - last = last->next; - - last->next = e; - e->next = NULL; - - return e; +static struct pcrematch_entry* create_pcrematch_entry(struct pcrematch_set* set) +{ + struct pcrematch_entry * e = (struct pcrematch_entry *) aCalloc(sizeof(struct pcrematch_entry), 1); + struct pcrematch_entry * last = set->head; + + // Normally we would have just stuck it at the end of the list but + // this doesn't sink up with peoples usage pattern. They wanted + // the items defined first to have a higher priority then the + // items defined later. as a result, we have to do some work up front. + + /* if we are the first pattern, stick us at the end */ + if (last == NULL) { + set->head = e; + return e; + } + + /* Look for the last entry */ + while (last->next != NULL) + last = last->next; + + last->next = e; + e->next = NULL; + + return e; } /** * define/compile a new pattern */ -void npc_chat_def_pattern(struct npc_data *nd, int setid, const char *pattern, const char *label) +void npc_chat_def_pattern(struct npc_data* nd, int setid, const char* pattern, const char* label) { - const char *err; - int erroff; - - struct pcrematch_set *s = lookup_pcreset(nd, setid); - struct pcrematch_entry *e = create_pcrematch_entry(s); - e->pattern = aStrdup(pattern); - e->label = aStrdup(label); - e->pcre_ = pcre_compile(pattern, PCRE_CASELESS, &err, &erroff, NULL); - e->pcre_extra_ = pcre_study(e->pcre_, 0, &err); + const char *err; + int erroff; + + struct pcrematch_set * s = lookup_pcreset(nd, setid); + struct pcrematch_entry *e = create_pcrematch_entry(s); + e->pattern = aStrdup(pattern); + e->label = aStrdup(label); + e->pcre_ = pcre_compile(pattern, PCRE_CASELESS, &err, &erroff, NULL); + e->pcre_extra_ = pcre_study(e->pcre_, 0, &err); } /** * Delete everything associated with a NPC concerning the pattern - * matching code + * matching code * * this could be more efficent but.. how often do you do this? */ -void npc_chat_finalize(struct npc_data *nd) +void npc_chat_finalize(struct npc_data* nd) { - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - if (npcParse == NULL) - return; - - while (npcParse->active) - delete_pcreset(nd, npcParse->active->setid); - - while (npcParse->inactive) - delete_pcreset(nd, npcParse->inactive->setid); - - // Additional cleaning up [Lance] - aFree(npcParse); + struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; + if (npcParse == NULL) + return; + + while(npcParse->active) + delete_pcreset(nd, npcParse->active->setid); + + while(npcParse->inactive) + delete_pcreset(nd, npcParse->inactive->setid); + + // Additional cleaning up [Lance] + aFree(npcParse); } /** * Handler called whenever a global message is spoken in a NPC's area */ -int npc_chat_sub(struct block_list *bl, va_list ap) +int npc_chat_sub(struct block_list* bl, va_list ap) { - struct npc_data *nd = (struct npc_data *) bl; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; - char *msg; - int len, i; - struct map_session_data *sd; - struct npc_label_list *lst; - struct pcrematch_set *pcreset; - struct pcrematch_entry *e; - - // Not interested in anything you might have to say... - if (npcParse == NULL || npcParse->active == NULL) - return 0; - - msg = va_arg(ap,char *); - len = va_arg(ap,int); - sd = va_arg(ap,struct map_session_data *); - - // iterate across all active sets - for (pcreset = npcParse->active; pcreset != NULL; pcreset = pcreset->next) { - // interate across all patterns in that set - for (e = pcreset->head; e != NULL; e = e->next) { - int offsets[2*10 + 10]; // 1/3 reserved for temp space requred by pcre_exec - - // perform pattern match - int r = pcre_exec(e->pcre_, e->pcre_extra_, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets)); - if (r > 0) { - // save out the matched strings - for (i = 0; i < r; i++) { - char var[6], val[255]; - snprintf(var, sizeof(var), "$@p%i$", i); - pcre_copy_substring(msg, offsets, r, i, val, sizeof(val)); - set_var(sd, var, val); - } - - // find the target label.. this sucks.. - lst = nd->u.scr.label_list; - ARR_FIND(0, nd->u.scr.label_list_num, i, strncmp(lst[i].name, e->label, sizeof(lst[i].name)) == 0); - if (i == nd->u.scr.label_list_num) { - ShowWarning("Unable to find label: %s\n", e->label); - return 0; - } - - // run the npc script - run_script(nd->u.scr.script,lst[i].pos,sd->bl.id,nd->bl.id); - return 0; - } - } - } - - return 0; + struct npc_data* nd = (struct npc_data *) bl; + struct npc_parse* npcParse = (struct npc_parse *) nd->chatdb; + char* msg; + int len, i; + struct map_session_data* sd; + struct npc_label_list* lst; + struct pcrematch_set* pcreset; + struct pcrematch_entry* e; + + // Not interested in anything you might have to say... + if (npcParse == NULL || npcParse->active == NULL) + return 0; + + msg = va_arg(ap,char*); + len = va_arg(ap,int); + sd = va_arg(ap,struct map_session_data *); + + // iterate across all active sets + for (pcreset = npcParse->active; pcreset != NULL; pcreset = pcreset->next) + { + // interate across all patterns in that set + for (e = pcreset->head; e != NULL; e = e->next) + { + int offsets[2*10 + 10]; // 1/3 reserved for temp space requred by pcre_exec + + // perform pattern match + int r = pcre_exec(e->pcre_, e->pcre_extra_, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets)); + if (r > 0) + { + // save out the matched strings + for (i = 0; i < r; i++) + { + char var[6], val[255]; + snprintf(var, sizeof(var), "$@p%i$", i); + pcre_copy_substring(msg, offsets, r, i, val, sizeof(val)); + set_var(sd, var, val); + } + + // find the target label.. this sucks.. + lst = nd->u.scr.label_list; + ARR_FIND(0, nd->u.scr.label_list_num, i, strncmp(lst[i].name, e->label, sizeof(lst[i].name)) == 0); + if (i == nd->u.scr.label_list_num) { + ShowWarning("Unable to find label: %s\n", e->label); + return 0; + } + + // run the npc script + run_script(nd->u.scr.script,lst[i].pos,sd->bl.id,nd->bl.id); + return 0; + } + } + } + + return 0; } // Various script builtins used to support these functions -int buildin_defpattern(struct script_state *st) +int buildin_defpattern(struct script_state* st) { - int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); - const char *pattern = conv_str(st,& (st->stack->stack_data[st->start+3])); - const char *label = conv_str(st,& (st->stack->stack_data[st->start+4])); - struct npc_data *nd = (struct npc_data *)map_id2bl(st->oid); - - npc_chat_def_pattern(nd, setid, pattern, label); - - return 0; + int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); + const char* pattern = conv_str(st,& (st->stack->stack_data[st->start+3])); + const char* label = conv_str(st,& (st->stack->stack_data[st->start+4])); + struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid); + + npc_chat_def_pattern(nd, setid, pattern, label); + + return 0; } -int buildin_activatepset(struct script_state *st) +int buildin_activatepset(struct script_state* st) { - int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); - struct npc_data *nd = (struct npc_data *)map_id2bl(st->oid); - - activate_pcreset(nd, setid); - - return 0; + int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); + struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid); + + activate_pcreset(nd, setid); + + return 0; } -int buildin_deactivatepset(struct script_state *st) +int buildin_deactivatepset(struct script_state* st) { - int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); - struct npc_data *nd = (struct npc_data *)map_id2bl(st->oid); - - deactivate_pcreset(nd, setid); - - return 0; + int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); + struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid); + + deactivate_pcreset(nd, setid); + + return 0; } -int buildin_deletepset(struct script_state *st) +int buildin_deletepset(struct script_state* st) { - int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); - struct npc_data *nd = (struct npc_data *)map_id2bl(st->oid); - - delete_pcreset(nd, setid); - - return 0; + int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); + struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid); + + delete_pcreset(nd, setid); + + return 0; } #endif //PCRE_SUPPORT |