summaryrefslogtreecommitdiff
path: root/src/map/npc_chat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/npc_chat.c')
-rw-r--r--src/map/npc_chat.c238
1 files changed, 117 insertions, 121 deletions
diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c
index c7faa2df6..8bc246819 100644
--- a/src/map/npc_chat.c
+++ b/src/map/npc_chat.c
@@ -2,25 +2,33 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifdef PCRE_SUPPORT
+#define HERCULES_CORE
-#include "../common/timer.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/showmsg.h"
-#include "../common/strlib.h"
+#ifdef PCRE_SUPPORT
-#include "mob.h" // struct mob_data
#include "npc.h" // struct npc_data
-#include "pc.h" // struct map_session_data
-#include "script.h" // set_var()
-
-#include "../../3rdparty/pcre/include/pcre.h"
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <stdarg.h>
+
+#include "../../3rdparty/pcre/include/pcre.h"
+
+#include "mob.h" // struct mob_data
+#include "pc.h" // struct map_session_data
+#include "script.h" // set_var()
+#include "../common/malloc.h"
+#include "../common/nullpo.h"
+#include "../common/showmsg.h"
+#include "../common/strlib.h"
+#include "../common/timer.h"
+
+/**
+ * interface sources
+ **/
+struct npc_chat_interface npc_chat_s;
+struct pcre_interface libpcre_s;
/**
@@ -41,7 +49,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.
@@ -51,7 +59,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
@@ -70,47 +78,16 @@
* deletes a pset
*/
-/* 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;
-};
-
-/* 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;
-};
-
-/*
- * Entire data structure hung off a NPC
- *
- * The reason I have done it this way (a void * in npc_data and then
- * this) was to reduce the number of patches that needed to be applied
- * to a ragnarok distribution to bring this code online. I
- * also wanted people to be able to grab this one file to get updates
- * without having to do a large number of changes.
- */
-struct npc_parse {
- struct pcrematch_set* active;
- struct pcrematch_set* inactive;
-};
-
/**
- * delete everythign associated with a entry
+ * delete everything associated with a entry
*
* This does NOT do the list management
*/
void finalize_pcrematch_entry(struct pcrematch_entry* e)
{
- pcre_free(e->pcre_);
- pcre_free(e->pcre_extra_);
+ libpcre->free(e->pcre_);
+ libpcre->free(e->pcre_extra_);
aFree(e->pattern);
aFree(e->label);
}
@@ -118,12 +95,11 @@ void finalize_pcrematch_entry(struct pcrematch_entry* e)
/**
* 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* 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);
+ struct npc_parse *npcParse = nd->chatdb;
+ if (npcParse == NULL)
+ nd->chatdb = npcParse = (struct npc_parse *)aCalloc(sizeof(struct npc_parse), 1);
pcreset = npcParse->active;
@@ -132,7 +108,7 @@ static struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int setid)
break;
pcreset = pcreset->next;
}
- if (pcreset == NULL)
+ if (pcreset == NULL)
pcreset = npcParse->inactive;
while (pcreset != NULL) {
@@ -142,7 +118,7 @@ static struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int setid)
}
if (pcreset == NULL) {
- pcreset = (struct pcrematch_set *) aCalloc(sizeof(struct pcrematch_set), 1);
+ pcreset = (struct pcrematch_set *)aCalloc(sizeof(struct pcrematch_set), 1);
pcreset->next = npcParse->inactive;
if (pcreset->next != NULL)
pcreset->next->prev = pcreset;
@@ -159,11 +135,11 @@ 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)
+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)
+ struct npc_parse *npcParse = nd->chatdb;
+ if (npcParse == NULL)
return; // Nothing to activate...
pcreset = npcParse->inactive;
while (pcreset != NULL) {
@@ -177,7 +153,7 @@ static void activate_pcreset(struct npc_data* nd, int setid)
pcreset->next->prev = pcreset->prev;
if (pcreset->prev != NULL)
pcreset->prev->next = pcreset->next;
- else
+ else
npcParse->inactive = pcreset->next;
pcreset->prev = NULL;
@@ -192,15 +168,15 @@ 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)
+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)
+ struct npc_parse *npcParse = nd->chatdb;
+ if (npcParse == NULL)
return; // Nothing to deactivate...
if (setid == -1) {
while(npcParse->active != NULL)
- deactivate_pcreset(nd, npcParse->active->setid);
+ npc_chat->deactivate_pcreset(nd, npcParse->active->setid);
return;
}
pcreset = npcParse->active;
@@ -215,7 +191,7 @@ static void deactivate_pcreset(struct npc_data* nd, int setid)
pcreset->next->prev = pcreset->prev;
if (pcreset->prev != NULL)
pcreset->prev->next = pcreset->next;
- else
+ else
npcParse->active = pcreset->next;
pcreset->prev = NULL;
@@ -228,12 +204,12 @@ static void deactivate_pcreset(struct npc_data* nd, int setid)
/**
* delete a set of patterns.
*/
-static void delete_pcreset(struct npc_data* nd, int setid)
+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)
+ struct npc_parse *npcParse = nd->chatdb;
+ if (npcParse == NULL)
return; // Nothing to deactivate...
pcreset = npcParse->active;
while (pcreset != NULL) {
@@ -250,7 +226,7 @@ static void delete_pcreset(struct npc_data* nd, int setid)
pcreset = pcreset->next;
}
}
- if (pcreset == NULL)
+ if (pcreset == NULL)
return;
if (pcreset->next != NULL)
@@ -268,8 +244,8 @@ static void delete_pcreset(struct npc_data* nd, int setid)
while (pcreset->head) {
struct pcrematch_entry* n = pcreset->head->next;
- finalize_pcrematch_entry(pcreset->head);
- aFree(pcreset->head); // Cleanin' the last ones.. [Lance]
+ npc_chat->finalize_pcrematch_entry(pcreset->head);
+ aFree(pcreset->head); // Cleaning the last ones.. [Lance]
pcreset->head = n;
}
@@ -277,9 +253,9 @@ static void delete_pcreset(struct npc_data* nd, int setid)
}
/**
- * create a new pattern entry
+ * create a new pattern entry
*/
-static struct pcrematch_entry* create_pcrematch_entry(struct pcrematch_set* set)
+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;
@@ -313,31 +289,31 @@ void npc_chat_def_pattern(struct npc_data* nd, int setid, const char* pattern, c
const char *err;
int erroff;
- struct pcrematch_set * s = lookup_pcreset(nd, setid);
- struct pcrematch_entry *e = create_pcrematch_entry(s);
+ struct pcrematch_set * s = npc_chat->lookup_pcreset(nd, setid);
+ struct pcrematch_entry *e = npc_chat->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);
+ e->pcre_ = libpcre->compile(pattern, PCRE_CASELESS, &err, &erroff, NULL);
+ e->pcre_extra_ = libpcre->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?
+ * this could be more efficient but.. how often do you do this?
*/
void npc_chat_finalize(struct npc_data* nd)
{
- struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb;
+ struct npc_parse *npcParse = nd->chatdb;
if (npcParse == NULL)
return;
while(npcParse->active)
- delete_pcreset(nd, npcParse->active->setid);
+ npc_chat->delete_pcreset(nd, npcParse->active->setid);
while(npcParse->inactive)
- delete_pcreset(nd, npcParse->inactive->setid);
+ npc_chat->delete_pcreset(nd, npcParse->inactive->setid);
// Additional cleaning up [Lance]
aFree(npcParse);
@@ -348,8 +324,8 @@ void npc_chat_finalize(struct npc_data* nd)
*/
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;
+ struct npc_data *nd = (struct npc_data *) bl;
+ struct npc_parse *npcParse = nd->chatdb;
char* msg;
int len, i;
struct map_session_data* sd;
@@ -368,13 +344,13 @@ int npc_chat_sub(struct block_list* bl, va_list ap)
// iterate across all active sets
for (pcreset = npcParse->active; pcreset != NULL; pcreset = pcreset->next)
{
- // interate across all patterns in that set
+ // n 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
+ int offsets[2*10 + 10]; // 1/3 reserved for temp space required by pcre_exec
// perform pattern match
- int r = pcre_exec(e->pcre_, e->pcre_extra_, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets));
+ int r = libpcre->exec(e->pcre_, e->pcre_extra_, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets));
if (r > 0)
{
// save out the matched strings
@@ -382,20 +358,20 @@ int npc_chat_sub(struct block_list* bl, va_list ap)
{
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);
+ libpcre->copy_substring(msg, offsets, r, i, val, sizeof(val));
+ script->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);
+ ShowWarning("npc_chat_sub: 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);
+ script->run(nd->u.scr.script,lst[i].pos,sd->bl.id,nd->bl.id);
return 0;
}
}
@@ -404,48 +380,68 @@ int npc_chat_sub(struct block_list* bl, va_list ap)
return 0;
}
-// Various script builtins used to support these functions
+// Various script built-ins used to support these functions
+BUILDIN(defpattern) {
+ int setid = script_getnum(st,2);
+ const char* pattern = script_getstr(st,3);
+ const char* label = script_getstr(st,4);
+ struct npc_data* nd = (struct npc_data *)map->id2bl(st->oid);
+
+ npc_chat->def_pattern(nd, setid, pattern, label);
-int buildin_defpattern(struct script_state* st)
-{
- int setid = script->conv_num(st,& (st->stack->stack_data[st->start+2]));
- const char* pattern = script->conv_str(st,& (st->stack->stack_data[st->start+3]));
- const char* label = script->conv_str(st,& (st->stack->stack_data[st->start+4]));
- struct npc_data* nd = (struct npc_data *)iMap->id2bl(st->oid);
-
- npc_chat_def_pattern(nd, setid, pattern, label);
-
- return 1;
+ return true;
}
-int buildin_activatepset(struct script_state* st)
-{
- int setid = script->conv_num(st,& (st->stack->stack_data[st->start+2]));
- struct npc_data* nd = (struct npc_data *)iMap->id2bl(st->oid);
-
- activate_pcreset(nd, setid);
+BUILDIN(activatepset) {
+ int setid = script_getnum(st,2);
+ struct npc_data* nd = (struct npc_data *)map->id2bl(st->oid);
- return 1;
+ npc_chat->activate_pcreset(nd, setid);
+
+ return true;
}
-int buildin_deactivatepset(struct script_state* st)
-{
- int setid = script->conv_num(st,& (st->stack->stack_data[st->start+2]));
- struct npc_data* nd = (struct npc_data *)iMap->id2bl(st->oid);
+BUILDIN(deactivatepset) {
+ int setid = script_getnum(st,2);
+ struct npc_data* nd = (struct npc_data *)map->id2bl(st->oid);
- deactivate_pcreset(nd, setid);
+ npc_chat->deactivate_pcreset(nd, setid);
- return 1;
+ return true;
}
-int buildin_deletepset(struct script_state* st)
-{
- int setid = script->conv_num(st,& (st->stack->stack_data[st->start+2]));
- struct npc_data* nd = (struct npc_data *)iMap->id2bl(st->oid);
-
- delete_pcreset(nd, setid);
+BUILDIN(deletepset) {
+ int setid = script_getnum(st,2);
+ struct npc_data* nd = (struct npc_data *)map->id2bl(st->oid);
- return 1;
+ npc_chat->delete_pcreset(nd, setid);
+
+ return true;
+}
+
+void npc_chat_defaults(void) {
+ npc_chat = &npc_chat_s;
+
+ npc_chat->sub = npc_chat_sub;
+ npc_chat->finalize = npc_chat_finalize;
+ npc_chat->def_pattern = npc_chat_def_pattern;
+ npc_chat->create_pcrematch_entry = create_pcrematch_entry;
+ npc_chat->delete_pcreset = delete_pcreset;
+ npc_chat->deactivate_pcreset = deactivate_pcreset;
+ npc_chat->activate_pcreset = activate_pcreset;
+ npc_chat->lookup_pcreset = lookup_pcreset;
+ npc_chat->finalize_pcrematch_entry = finalize_pcrematch_entry;
+
+ libpcre = &libpcre_s;
+
+ libpcre->compile = pcre_compile;
+ libpcre->study = pcre_study;
+ libpcre->exec = pcre_exec;
+ libpcre->free = pcre_free;
+ libpcre->copy_substring = pcre_copy_substring;
+ libpcre->free_substring = pcre_free_substring;
+ libpcre->copy_named_substring = pcre_copy_named_substring;
+ libpcre->get_substring = pcre_get_substring;
}
#endif //PCRE_SUPPORT