PCRE updates

git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/stable@1157 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
amber 2005-02-22 05:01:20 +00:00
parent 593e1ed641
commit 0b091d02ee
11 changed files with 1253 additions and 8 deletions

View File

@ -1,5 +1,10 @@
Date Added
02/22
* Added perl regular expression support.. look at src/map/npc_chat.c
for all the dirt on the new features. To build it, you have
to enable the PCRE_SUPPORT #define and you also have to
build/install the pcre library. [SVN 1157: MouseJstr]
02/21
* Added actual item_db.sql into sql-files. [Lupus]
* Added actual mob_db.sql into sql-files. If you use SQL Mob DB then update it [Lupus]
@ -2000,4 +2005,4 @@ Date Added
router or a firewall since there is no way of determining the
external IP address. On the other hand, we should be able to
eliminate the lan_conf file since we know our IP addresses as well
as our netmask.
as our netmask.

View File

@ -1,11 +1,13 @@
CC = gcc -pipe
# CC = gcc -pipe -DPCRE_SUPPORT
# CC = g++
# CC = gcc -pipe -DGCOLLECT
# CC = gcc -pipe -DDMALLOC -DDMALLOC_FUNC_CHECK
# CC = /usr/local/bin/gcc -fbounds-checking -pipe -DBCHECK
# GCLIB = -lgc
# GCLIB = -L/usr/local/lib -lpcre
GCLIB =
# GCLIB = -ldmalloc

702
npc/other/eliza.txt Normal file
View File

@ -0,0 +1,702 @@
prontera.gat,152,181,5 script MouseJstr 763,{
// hello
Lquote0:
npctalk "How do you do. Please state your problem.";
break;
// computer
Lquote1:
set $foo,rand(4);
if($foo == 0) goto Lquote1a;
if($foo == 1) goto Lquote1b;
if($foo == 2) goto Lquote1c;
if($foo == 3) goto Lquote1d;
Lquote1a:
npctalk "Do computers worry you?";
break;
Lquote1b:
npctalk "What do you think about machines?";
break;
Lquote1c:
npctalk "Why do you mention computers?";
break;
Lquote1d:
npctalk "What do you think machines have to do with your problem?";
break;
// name
Lquote2:
npctalk "I am not interested in names";
break;
// sorry
Lquote3:
set $foo,rand(3);
if($foo == 0) goto Lquote3a;
if($foo == 1) goto Lquote3b;
if($foo == 2) goto Lquote3c;
Lquote3a:
npctalk "Please don't apologize";
break;
Lquote3b:
npctalk "Apologies are not necessary";
break;
Lquote3c:
npctalk "What feelings do you have when you apologize";
break;
// I remember $p2$
Lquote4:
set $foo,rand(6);
if($foo == 0) goto Lquote4a;
if($foo == 1) goto Lquote4b;
if($foo == 2) goto Lquote4c;
if($foo == 3) goto Lquote4d;
if($foo == 4) goto Lquote4e;
if($foo == 5) goto Lquote4f;
Lquote4a:
npctalk "Do you often think of "+$p2$+"?";
break;
Lquote4b:
npctalk "Does thinking of "+$p2$+" bring anything else to mind?";
break;
Lquote4c:
npctalk "What else do you remember?";
break;
Lquote4d:
npctalk "Why do you recall "+$p2$+" right now?";
break;
Lquote4e:
npctalk "What in the present situation reminds you of "+$p2$+"?";
break;
Lquote4f:
npctalk "What is the connection between me and "+$p2$+"?";
break;
// do you remember
Lquote5:
set $foo,rand(4);
if($foo == 0) goto Lquote5a;
if($foo == 1) goto Lquote5b;
if($foo == 2) goto Lquote5c;
if($foo == 3) goto Lquote5d;
Lquote5a:
npctalk "Did you think I would forget "+$p2$+" ?";
break;
Lquote5b:
npctalk "Why do you think I should recall "+$p2$+" now";
break;
Lquote5c:
npctalk "What about "+$p2$+"";
break;
Lquote5d:
npctalk "You mentioned "+$p2$+"";
break;
// if
Lquote6:
set $foo,rand(4);
if($foo == 0) goto Lquote6a;
if($foo == 1) goto Lquote6b;
if($foo == 2) goto Lquote6c;
if($foo == 3) goto Lquote6d;
Lquote6a:
npctalk "Do you really think its likely that "+$p2$+"";
break;
Lquote6b:
npctalk "Do you wish that "+$p2$+"?";
break;
Lquote6c:
npctalk "What do you think about "+$p2$+"?";
break;
Lquote6d:
npctalk "Really-- if "+$p2$+"?";
break;
// i dreamt
Lquote7:
set $foo,rand(3);
if($foo == 0) goto Lquote7a;
if($foo == 1) goto Lquote7b;
if($foo == 2) goto Lquote7c;
Lquote7a:
npctalk "Really-- "+$p2$+"";
break;
Lquote7b:
npctalk "Have you ever fantasized "+$p2$+" while you were awake?";
break;
Lquote7c:
npctalk "Have you dreamt "+$p2$+" before?";
break;
// dream about
Lquote8:
npctalk "How do you feel about "+$p2$+" in reality?";
break;
// dream
Lquote9:
set $foo,rand(4);
if($foo == 0) goto Lquote9a;
if($foo == 1) goto Lquote9b;
if($foo == 2) goto Lquote9c;
if($foo == 3) goto Lquote9d;
Lquote9a:
npctalk "What does this dream suggest to you?";
break;
Lquote9b:
npctalk "Do you dream often?";
break;
Lquote9c:
npctalk "What persons appear in your dreams?";
break;
Lquote9d:
npctalk "Don't you believe that dream has to do with your problem?";
break;
// my mother
Lquote10:
set $foo,rand(2);
if($foo == 0) goto Lquote10a;
if($foo == 1) goto Lquote10b;
Lquote10a:
npctalk "Who else in your family "+$p2$+"";
break;
Lquote10b:
npctalk "Tell me more about your family";
break;
// my father
Lquote11:
set $foo,rand(3);
if($foo == 0) goto Lquote11a;
if($foo == 1) goto Lquote11b;
if($foo == 2) goto Lquote11c;
Lquote11a:
npctalk "Your father";
break;
Lquote11b:
npctalk "Does he influence you strongly?";
break;
Lquote11c:
npctalk "What else comes to mind when you think of your father?";
break;
// I want
Lquote12:
set $foo,rand(3);
if($foo == 0) goto Lquote12a;
if($foo == 1) goto Lquote12b;
if($foo == 2) goto Lquote12c;
Lquote12a:
npctalk "What would it mean if you got "+$p2$+"";
break;
Lquote12b:
npctalk "Why do you want "+$p2$+"";
break;
Lquote12c:
npctalk "Suppose you got "+$p2$+" soon";
break;
// I am glad
Lquote13:
set $foo,rand(3);
if($foo == 0) goto Lquote13a;
if($foo == 1) goto Lquote13b;
if($foo == 2) goto Lquote13c;
Lquote13a:
npctalk "How have I helped you to be "+$p2$+"";
break;
Lquote13b:
npctalk "What makes you happy just now";
break;
Lquote13c:
npctalk "Can you explain why you are suddenly "+$p2$+"";
break;
// I am sad
Lquote14:
set $foo,rand(2);
if($foo == 0) goto Lquote14a;
if($foo == 1) goto Lquote14b;
Lquote14a:
npctalk "I am sorry to hear you are depressed";
break;
Lquote14b:
npctalk "I'm sure its not pleasant to be sad";
break;
// $p2 are like "+$p3$+"
Lquote15:
npctalk "What resemblance do you see between "+$p2$+" and "+$p3$+"";
break;
// "+$p2$+" is like "+$p3$+"
Lquote16:
set $foo,rand(4);
if($foo == 0) goto Lquote16a;
if($foo == 1) goto Lquote16b;
if($foo == 2) goto Lquote16c;
if($foo == 3) goto Lquote16d;
Lquote16a:
npctalk "In what way is it that "+$p2$+" is like "+$p3$+"";
break;
Lquote16b:
npctalk "What resemblance do you see?";
break;
Lquote16c:
npctalk "Could there really be some connection?";
break;
Lquote16d:
npctalk "How?";
break;
// alike
Lquote17:
set $foo,rand(2);
if($foo == 0) goto Lquote17a;
if($foo == 1) goto Lquote17b;
Lquote17a:
npctalk "In what way?";
break;
Lquote17b:
npctalk "What similarities are there?";
break;
// same
Lquote18:
npctalk "What other connections do you see?";
break;
// I was "+$p2$+"
Lquote19:
set $foo,rand(3);
if($foo == 0) goto Lquote19a;
if($foo == 1) goto Lquote19b;
if($foo == 2) goto Lquote19c;
Lquote19a:
npctalk "Were you really?";
break;
Lquote19b:
npctalk "Perhaps I already knew you were "+$p2$+"";
break;
Lquote19c:
npctalk "Why do you tell me you were "+$p2$+" now?";
break;
// was I
Lquote20:
set $foo,rand(3);
if($foo == 0) goto Lquote20a;
if($foo == 1) goto Lquote20b;
if($foo == 2) goto Lquote20c;
Lquote20a:
npctalk "What if you were "+$p2$+" ?";
break;
Lquote20b:
npctalk "Do you thin you were "+$p2$+"";
break;
Lquote20c:
npctalk "What would it mean if you were "+$p2$+"";
break;
// I am
Lquote21:
set $foo,rand(2);
if($foo == 0) goto Lquote21a;
if($foo == 1) goto Lquote21b;
Lquote21a:
npctalk "In what way are you "+$p2$+"";
break;
Lquote21b:
npctalk "Do you want to be "+$p2$+" ?";
break;
// am I
Lquote22:
set $foo,rand(4);
if($foo == 0) goto Lquote22a;
if($foo == 1) goto Lquote22b;
if($foo == 2) goto Lquote22c;
if($foo == 3) goto Lquote22d;
Lquote22a:
npctalk "Do you believe you are "+$p2$+"";
break;
Lquote22b:
npctalk "Would you want to be "+$p2$+"";
break;
Lquote22c:
npctalk "You wish I would tell you you are "+$p2$+"";
break;
Lquote22d:
npctalk "What would it mean if you were "+$p2$+"";
break;
// am
Lquote23:
set $foo,rand(2);
if($foo == 0) goto Lquote23a;
if($foo == 1) goto Lquote23b;
Lquote23a:
npctalk "Why do you say AM?";
break;
Lquote23b:
npctalk "I don't understand that";
break;
// are you
Lquote24:
set $foo,rand(3);
if($foo == 0) goto Lquote24a;
if($foo == 1) goto Lquote24b;
if($foo == 2) goto Lquote24c;
Lquote24a:
npctalk "Why are you interested in whether I am "+$p2$+" or not?";
break;
Lquote24b:
npctalk "Would you prefer if I weren't "+$p2$+"";
break;
Lquote24c:
npctalk "Perhaps I am "+$p2$+" in your fantasies";
break;
// you are
Lquote25:
npctalk "What makes you think I am "+$p2$+" ?";
break;
// because
Lquote26:
set $foo,rand(3);
if($foo == 0) goto Lquote26a;
if($foo == 1) goto Lquote26b;
if($foo == 2) goto Lquote26c;
Lquote26a:
npctalk "Is that the real reason?";
break;
Lquote26b:
npctalk "What other reasons might there be?";
break;
Lquote26c:
npctalk "Does that reason seem to explain anything else?";
break;
// were you
Lquote27:
set $foo,rand(3);
if($foo == 0) goto Lquote27a;
if($foo == 1) goto Lquote27b;
if($foo == 2) goto Lquote27c;
Lquote27a:
npctalk "Perhaps I was "+$p2$+"";
break;
Lquote27b:
npctalk "What do you think?";
break;
Lquote27c:
npctalk "What if I had been "+$p2$+"";
break;
// I can't
Lquote28:
set $foo,rand(2);
if($foo == 0) goto Lquote28a;
if($foo == 1) goto Lquote28b;
Lquote28a:
npctalk "Maybe you could "+$p2$+" now";
break;
Lquote28b:
npctalk "What if you could "+$p2$+" ?";
break;
// I feel
Lquote29:
npctalk "Do you often feel "+$p2$+" ?";
break;
// I felt
Lquote30:
npctalk "What other feelings do you have?";
break;
// $p1$ I $p2$ you $p3$
Lquote31:
npctalk "Perhaps in your fantasy we "+$p3$+" each other?";
break;
// why don't you
Lquote32:
set $foo,rand(3);
if($foo == 0) goto Lquote32a;
if($foo == 1) goto Lquote32b;
if($foo == 2) goto Lquote32c;
Lquote32a:
npctalk "Should you "+$p2$+" yourself?";
break;
Lquote32b:
npctalk "Do you believe I don't "+$p2$+"";
break;
Lquote32c:
npctalk "Perhaps I will "+$p2$+" in good time";
break;
// yes
Lquote33:
set $foo,rand(3);
if($foo == 0) goto Lquote33a;
if($foo == 1) goto Lquote33b;
if($foo == 2) goto Lquote33c;
Lquote33a:
npctalk "You seem quite positive";
break;
Lquote33b:
npctalk "You are sure?";
break;
Lquote33c:
npctalk "I understand";
break;
// no
Lquote34:
set $foo,rand(3);
if($foo == 0) goto Lquote34a;
if($foo == 1) goto Lquote34b;
if($foo == 2) goto Lquote34c;
Lquote34a:
npctalk "Why not?";
break;
Lquote34b:
npctalk "You are being a bit negative";
break;
Lquote34c:
npctalk "Are you saying NO just to be negative?";
break;
// someone
Lquote35:
npctalk "Can you be more specific?";
break;
// everyone
Lquote36:
set $foo,rand(4);
if($foo == 0) goto Lquote36a;
if($foo == 1) goto Lquote36b;
if($foo == 2) goto Lquote36c;
if($foo == 3) goto Lquote36d;
Lquote36a:
npctalk "surely not everyone";
break;
Lquote36b:
npctalk "Can you think of anyone in particular?";
break;
Lquote36c:
npctalk "Who for example?";
break;
Lquote36d:
npctalk "You are thinking of a special person?";
break;
// always
Lquote37:
set $foo,rand(4);
if($foo == 0) goto Lquote37a;
if($foo == 1) goto Lquote37b;
if($foo == 2) goto Lquote37c;
if($foo == 3) goto Lquote37d;
Lquote37a:
npctalk "Can you think of a specific example?";
break;
Lquote37b:
npctalk "When?";
break;
Lquote37c:
npctalk "What incident are you thinking of?";
break;
Lquote37d:
npctalk "Really-- always?";
break;
// what
Lquote38:
set $foo,rand(5);
if($foo == 0) goto Lquote38a;
if($foo == 1) goto Lquote38b;
if($foo == 2) goto Lquote38c;
if($foo == 3) goto Lquote38d;
if($foo == 4) goto Lquote38e;
Lquote38a:
npctalk "Why do you ask?";
break;
Lquote38b:
npctalk "Does that question interest you?";
break;
Lquote38c:
npctalk "What is it you really want to know?";
break;
Lquote38d:
npctalk "What do you think?";
break;
Lquote38e:
npctalk "What comes to your mind when you ask that?";
break;
// perhaps
Lquote39:
npctalk "You do not seem quite certain";
break;
// are
Lquote40:
set $foo,rand(2);
if($foo == 0) goto Lquote40a;
if($foo == 1) goto Lquote40b;
Lquote40a:
npctalk "Did you think they might not be "+$p2$+"";
break;
Lquote40b:
npctalk "Possibly they are "+$p2$;
break;
// default
Lquote41:
set $foo,rand(6);
if($foo == 0) goto Lquote41a;
if($foo == 1) goto Lquote41b;
if($foo == 2) goto Lquote41c;
if($foo == 3) goto Lquote41d;
if($foo == 4) goto Lquote41e;
if($foo == 5) goto Lquote41f;
Lquote41a:
npctalk "Very interesting";
break;
Lquote41b:
npctalk "I am not sure I understand you fully";
break;
Lquote41c:
npctalk "What does that suggest to you?";
break;
Lquote41d:
npctalk "Please continue";
break;
Lquote41e:
npctalk "Go on";
break;
Lquote41f:
npctalk "Do you feel strongly about discussing such things?";
break;
OnInit:
defpattern 1, "([^:]+):.*\\shello.*", "Lquote0";
defpattern 1, "([^:]+):.*\\scomputer.*", "Lquote1";
defpattern 1, "([^:]+):.*\\sname.*", "Lquote2";
defpattern 1, "([^:]+):.*\\ssorry.*", "Lquote3";
defpattern 1, "([^:]+):.*\\si\\s+remember\\s+(.*)", "Lquote4";
defpattern 1, "([^:]+):.*\\sdo\\s+you\\s+remember\\s+(.*)", "Lquote5";
defpattern 1, "([^:]+):.*\\sif\\s+(.*)", "Lquote6";
defpattern 1, "([^:]+):.*\\si\\s+dreamt\\s+(.*)", "Lquote7";
defpattern 1, "([^:]+):.*\\sdream\\s+about\\s+(.*)", "Lquote8";
defpattern 1, "([^:]+):.*\\sdream\\s+(.*)", "Lquote9";
defpattern 1, "([^:]+):.*\\smy\\s+mother\\s+(.*)", "Lquote10";
defpattern 1, "([^:]+):.*\\smy\\s+father\\s+(.*)", "Lquote11";
defpattern 1, "([^:]+):.*\\si\\s+want\\s+(.*)", "Lquote12";
defpattern 1, "([^:]+):.*\\si\\s+am\\s+glad\\s+(.*)", "Lquote13";
defpattern 1, "([^:]+):\\s+(.*)\\s+i\\s+am\\s+sad\\s+(.*)", "Lquote14";
defpattern 1, "([^:]+):\\s+(.*)\\s+are\\s+like\\s+(.*)", "Lquote15";
defpattern 1, "([^:]+):\\s+(.*)\\s+is\\s+like\\s+(.*)", "Lquote16";
defpattern 1, "([^:]+):.*\\salike\\s+(.*)", "Lquote17";
defpattern 1, "([^:]+):.*\\ssame\\s+(.*)", "Lquote18";
defpattern 1, "([^:]+):.*\\si\\s+was\\s+(.*)", "Lquote19";
defpattern 1, "([^:]+):.*\\swas\\s+i\\s+(.*)", "Lquote20";
defpattern 1, "([^:]+):.*\\si\\s+am\\s+(.*)", "Lquote21";
defpattern 1, "([^:]+):.*\\sam\\s+i\\s+(.*)", "Lquote22";
defpattern 1, "([^:]+):.*\\sam\\s+(.*)", "Lquote23";
defpattern 1, "([^:]+):.*\\sare\\s+you\\s+(.*)", "Lquote24";
defpattern 1, "([^:]+):.*\\syou\\s+are\\s+(.*)", "Lquote25";
defpattern 1, "([^:]+):.*\\sbecause\\s+(.*)", "Lquote26";
defpattern 1, "([^:]+):.*\\swere\\s+you\\s+(.*)", "Lquote27";
defpattern 1, "([^:]+):.*\\si\\s+(cant|can't|cannot)\\s+(.*)", "Lquote28";
defpattern 1, "([^:]+):.*\\si\\s+feel\\s+(.*)", "Lquote29";
defpattern 1, "([^:]+):.*\\si\\s+felt\\s+(.*)", "Lquote30";
defpattern 1, "([^:]+):.*\\si\\s+(.*)\\s+you\\s+(.*)", "Lquote31";
defpattern 1, "([^:]+):.*\\swhy\\s+(don't|dont)\\s+you\\s+(.*)", "Lquote32";
defpattern 1, "([^:]+):.*\\syes\\s+(.*)", "Lquote33";
defpattern 1, "([^:]+):.*\\sno\\s+(.*)", "Lquote34";
defpattern 1, "([^:]+):.*\\ssomeone\\s+(.*)", "Lquote35";
defpattern 1, "([^:]+):.*\\severyone\\s+(.*)", "Lquote36";
defpattern 1, "([^:]+):.*\\salways\\s+(.*)", "Lquote37";
defpattern 1, "([^:]+):.*\\swhat\\s+(.*)", "Lquote38";
defpattern 1, "([^:]+):.*\\sperhaps\\s+(.*)", "Lquote39";
defpattern 1, "([^:]+):.*\\sare\\s+(.*)", "Lquote40";
defpattern 1, "([^:]+):(.*)", "Lquote41";
activatepset 1;
break;
}

View File

@ -13,10 +13,10 @@ sqlobj:
COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/grfio.o ../common/db.o ../common/lock.o ../common/nullpo.o ../common/malloc.o ../common/showmsg.o ../common/utils.o ../common/strlib.o
LIBS = -lz -lm
map-server: txtobj/map.o txtobj/chrif.o txtobj/clif.o txtobj/pc.o txtobj/status.o txtobj/npc.o txtobj/chat.o txtobj/path.o txtobj/itemdb.o txtobj/mob.o txtobj/script.o txtobj/storage.o txtobj/skill.o txtobj/atcommand.o txtobj/charcommand.o txtobj/battle.o txtobj/intif.o txtobj/trade.o txtobj/party.o txtobj/vending.o txtobj/guild.o txtobj/pet.o txtobj/log.o $(COMMON_OBJ)
map-server: txtobj/map.o txtobj/chrif.o txtobj/clif.o txtobj/pc.o txtobj/status.o txtobj/npc.o txtobj/npc_chat.o txtobj/chat.o txtobj/path.o txtobj/itemdb.o txtobj/mob.o txtobj/script.o txtobj/storage.o txtobj/skill.o txtobj/atcommand.o txtobj/charcommand.o txtobj/battle.o txtobj/intif.o txtobj/trade.o txtobj/party.o txtobj/vending.o txtobj/guild.o txtobj/pet.o txtobj/log.o $(COMMON_OBJ)
$(CC) -o ../../$@ $> $(LIBS) $(LIB_S)
map-server_sql: sqlobj/map.o sqlobj/chrif.o sqlobj/clif.o sqlobj/pc.o sqlobj/status.o sqlobj/npc.o sqlobj/chat.o sqlobj/path.o sqlobj/itemdb.o sqlobj/mob.o sqlobj/script.o sqlobj/storage.o sqlobj/skill.o sqlobj/atcommand.o sqlobj/charcommand.o sqlobj/battle.o sqlobj/intif.o sqlobj/trade.o sqlobj/party.o sqlobj/vending.o sqlobj/guild.o sqlobj/pet.o sqlobj/mail.o sqlobj/log.o $(COMMON_OBJ)
map-server_sql: sqlobj/map.o sqlobj/chrif.o sqlobj/clif.o sqlobj/pc.o sqlobj/status.o sqlobj/npc.o sqlobj/npc_chat.o sqlobj/chat.o sqlobj/path.o sqlobj/itemdb.o sqlobj/mob.o sqlobj/script.o sqlobj/storage.o sqlobj/skill.o sqlobj/atcommand.o sqlobj/charcommand.o sqlobj/battle.o sqlobj/intif.o sqlobj/trade.o sqlobj/party.o sqlobj/vending.o sqlobj/guild.o sqlobj/pet.o sqlobj/mail.o sqlobj/log.o $(COMMON_OBJ)
$(CC) -o ../../$@ $> $(LIB_S)
txtobj/%.o: %.c
@ -31,6 +31,7 @@ txtobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h cha
txtobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/showmsg.h
txtobj/status.o: status.c pc.h map.h clif.h status.h mob.h itemdb.h battle.h skill.h script.h pet.h guild.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/showmsg.h
txtobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h ../common/db.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
txtobj/npc_chat.o: npc_chat.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h ../common/db.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
txtobj/chat.o: chat.c map.h clif.h pc.h chat.h ../common/db.h ../common/mmo.h ../common/showmsg.h
txtobj/path.o: path.c map.h battle.h ../common/mmo.h ../common/showmsg.h
txtobj/itemdb.o: itemdb.c map.h battle.h itemdb.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h
@ -55,6 +56,7 @@ sqlobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h cha
sqlobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h log.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/showmsg.h
sqlobj/status.o: status.c pc.h map.h clif.h status.h mob.h itemdb.h battle.h skill.h script.h pet.h guild.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/showmsg.h
sqlobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h ../common/db.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
sqlobj/npc_chat.o: npc_chat.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h ../common/db.h ../common/timer.h ../common/mmo.h ../common/showmsg.h
sqlobj/chat.o: chat.c map.h clif.h pc.h chat.h ../common/db.h ../common/mmo.h ../common/showmsg.h
sqlobj/path.o: path.c map.h battle.h ../common/mmo.h ../common/showmsg.h
sqlobj/itemdb.o: itemdb.c map.h battle.h itemdb.h ../common/db.h ../common/grfio.h ../common/mmo.h ../common/showmsg.h

View File

@ -7964,6 +7964,10 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data *sd) { // S 008c <
WFIFOW(fd,0) = 0x8e;
WFIFOSET(fd, WFIFOW(fd,2));
#ifdef PCRE_SUPPORT
map_foreachinarea(npc_chat_sub, sd->bl.m, sd->bl.x-AREA_SIZE, sd->bl.y-AREA_SIZE, sd->bl.x+AREA_SIZE, sd->bl.y+AREA_SIZE, BL_NPC, RFIFOP(fd,4), strlen(RFIFOP(fd,4)), &sd->bl);
#endif
// Celest
if (pc_calc_base_job2 (sd->status.class_) == 23 ) {
int next = pc_nextbaseexp(sd)>0 ? pc_nextbaseexp(sd) : sd->status.base_exp;

View File

@ -411,6 +411,8 @@ struct npc_data {
char eventqueue[MAX_EVENTQUEUE][50];
int eventtimer[MAX_EVENTTIMER];
short arenaflag;
void *chatdb;
};
struct mob_data {
struct block_list bl;

View File

@ -153,6 +153,10 @@ int npc_delete(struct npc_data *nd)
if(nd->bl.prev == NULL)
return 1;
#ifdef PCRE_SUPPORT
npc_chat_finalize(nd);
#endif
clif_clearchar_area(&nd->bl,1);
map_delblock(&nd->bl);
return 0;

View File

@ -8,6 +8,8 @@
#define WARP_DEBUG_CLASS 722
#define INVISIBLE_CLASS 32767
void npc_chat_finalize(struct npc_data *nd);
int npc_chat_sub(struct block_list *bl, va_list ap);
int npc_event_dequeue(struct map_session_data *sd);
int npc_event_timer(int tid,unsigned int tick,int id,int data);
int npc_event(struct map_session_data *sd,const char *npcname,int);

502
src/map/npc_chat.c Normal file
View File

@ -0,0 +1,502 @@
#ifdef PCRE_SUPPORT
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#ifdef __WIN32
#define __USE_W32_SOCKETS
#include <windows.h>
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include <time.h>
#include "../common/timer.h"
#include "../common/malloc.h"
#include "../common/version.h"
#include "../common/nullpo.h"
#include "../common/showmsg.h"
#include "map.h"
#include "status.h"
#include "npc.h"
#include "chat.h"
#include "script.h"
#include "battle.h"
#include "pcre.h"
/**
* Written by MouseJstr in a vision... (2/21/2005)
*
* This allows you to make npc listen for spoken text (global
* messages) and pattern match against that spoken text using perl
* regular expressions.
*
* Please feel free to copy this code into your own personal ragnarok
* servers or distributions but please leave my name. Also, please
* wait until I've put it into the main eA branch which means I
* believe it is ready for distribution.
*
* So, how do people use this?
*
* The first and most important function is defpattern
*
* defpattern 1, "[^:]+: (.*) loves (.*)", "label";
*
* 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.
*
* each of the matched Groups will result in a variable being
* set ($p1$ through $p9$ with $p0$ being the entire string)
* 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
* the pattern matcher
*
* deactivatepset 1;
*
* turns off a pattern set;
*
* deactivatepset -1;
*
* turns off ALL pattern sets;
*
* deletepset 1;
*
* 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 *next_, *prev_;
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
*
* This does NOT do the list management
*/
void finalize_pcrematch_entry(struct pcrematch_entry *e) {
free(e->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;
}
/**
* activate a set of patterns.
*
* if the setid does not exist, this will silently return
*/
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;
}
/**
* deactivate a set of patterns.
*
* if the setid does not exist, this will silently return
*/
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;
}
/**
* delete a set of patterns.
*/
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_;
else if(active == 1)
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_);
pcreset->head_ = n;
}
aFree(pcreset);
}
/**
* 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;
}
/**
* define/compile a new pattern
*/
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);
}
/**
* Delete everything associated with a NPC concerning the pattern
* matching code
*
* this could be more efficent but.. how often do you do this?
*/
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_);
}
/**
* Handler called whenever a global message is spoken in a NPC's area
*/
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;
unsigned char *msg;
int len, pos, i;
struct map_session_data *sd;
struct npc_label_list *lst;
struct pcrematch_set *pcreset;
// Not interested in anything you might have to say...
if (npcParse == NULL || npcParse->active_ == NULL)
return 0;
msg = va_arg(ap,unsigned char*);
len = va_arg(ap,int);
sd = va_arg(ap,struct map_session_data *);
// grab the active list
pcreset = npcParse->active_;
// interate across all active sets
while (pcreset != NULL) {
struct pcrematch_entry *e = pcreset->head_;
// interate across all patterns in that set
while (e != NULL) {
int offsets[20];
char buf[255];
// perform pattern match
int r = pcre_exec(e->pcre_, e->pcre_extra_, msg, len, 0,
0, offsets, sizeof(offsets) / sizeof(offsets[0]));
if (r >= 0) {
// save out the matched strings
switch (r) {
case 10:
memcpy(buf, &msg[offsets[18]], offsets[19]);
buf[offsets[19]] = '\0';
set_var(sd, "$p9$", buf);
case 9:
memcpy(buf, &msg[offsets[16]], offsets[17]);
buf[offsets[17]] = '\0';
set_var(sd, "$p8$", buf);
case 8:
memcpy(buf, &msg[offsets[14]], offsets[15]);
buf[offsets[15]] = '\0';
set_var(sd, "$p7$", buf);
case 7:
memcpy(buf, &msg[offsets[12]], offsets[13]);
buf[offsets[13]] = '\0';
set_var(sd, "$p6$", buf);
case 6:
memcpy(buf, &msg[offsets[10]], offsets[11]);
buf[offsets[11]] = '\0';
set_var(sd, "$p5$", buf);
case 5:
memcpy(buf, &msg[offsets[8]], offsets[9]);
buf[offsets[9]] = '\0';
set_var(sd, "$p4$", buf);
case 4:
memcpy(buf, &msg[offsets[6]], offsets[7]);
buf[offsets[7]] = '\0';
set_var(sd, "$p3$", buf);
case 3:
memcpy(buf, &msg[offsets[4]], offsets[5]);
buf[offsets[5]] = '\0';
set_var(sd, "$p2$", buf);
case 2:
memcpy(buf, &msg[offsets[2]], offsets[3]);
buf[offsets[3]] = '\0';
set_var(sd, "$p1$", buf);
case 1:
memcpy(buf, &msg[offsets[0]], offsets[1]);
buf[offsets[1]] = '\0';
set_var(sd, "$p0$", buf);
}
// find the target label.. this sucks..
lst=nd->u.scr.label_list;
pos = -1;
for (i = 0; i < nd->u.scr.label_list_num; i++) {
if (strncmp(lst[i].name, e->label_, sizeof(lst[i].name)) == 0) {
pos = lst[i].pos;
break;
}
}
if (pos == -1) {
printf("Unable to find label: %s", e->label_);
// unable to find label... do something..
return 0;
}
// run the npc script
run_script(nd->u.scr.script,pos,sd->bl.id,nd->bl.id);
return 0;
}
e = e->next_;
}
pcreset = pcreset->next_;
}
return 0;
}
// Various script builtins used to support these functions
int buildin_defpattern(struct script_state *st) {
int setid=conv_num(st,& (st->stack->stack_data[st->start+2]));
char *pattern=conv_str(st,& (st->stack->stack_data[st->start+3]));
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 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 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 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

View File

@ -253,9 +253,9 @@ int buildin_failedremovecards(struct script_state *st);
int buildin_marriage(struct script_state *st);
int buildin_wedding_effect(struct script_state *st);
int buildin_divorce(struct script_state *st);
int buildin_ispartneron(struct script_state *st);
int buildin_getpartnerid(struct script_state *st);
int buildin_warppartner(struct script_state *st);
int buildin_ispartneron(struct script_state *st); // MouseJstr
int buildin_getpartnerid(struct script_state *st); // MouseJstr
int buildin_warppartner(struct script_state *st); // MouseJstr
int buildin_getitemname(struct script_state *st);
int buildin_makepet(struct script_state *st);
int buildin_getexp(struct script_state *st);
@ -315,6 +315,13 @@ int run_func(struct script_state *st);
int mapreg_setreg(int num,int val);
int mapreg_setregstr(int num,const char *str);
#ifdef PCRE_SUPPORT
int buildin_defpattern(struct script_state *st); // MouseJstr
int buildin_activatepset(struct script_state *st); // MouseJstr
int buildin_deactivatepset(struct script_state *st); // MouseJstr
int buildin_deletepset(struct script_state *st); // MouseJstr
#endif
struct {
int (*func)(struct script_state *);
char *name;
@ -537,10 +544,14 @@ struct {
{buildin_isday,"isday",""}, // check whether it is day time [Celest]
{buildin_isequipped,"isequipped","i*"}, // check whether another item/card has been equipped [Celest]
{buildin_isequippedcnt,"isequippedcnt","i*"}, // check how many items/cards are being equipped [Celest]
#ifdef PCRE_SUPPORT
{buildin_defpattern, "defpattern", "iss"}, // Define pattern to listen for [MouseJstr]
{buildin_activatepset, "activatepset", "i"}, // Activate a pattern set [MouseJstr]
{buildin_deactivatepset, "deactivatepset", "i"}, // Deactive a pattern set [MouseJstr]
{buildin_deletepset, "deletepset", "i"}, // Delete a pattern set [MouseJstr]
#endif
{NULL,NULL,NULL},
};
int buildin_message(struct script_state *st); // [MouseJstr]
enum {
C_NOP,C_POS,C_INT,C_PARAM,C_FUNC,C_STR,C_CONSTSTR,C_ARG,
@ -1403,6 +1414,11 @@ static int set_reg(struct map_session_data *sd,int num,char *name,void *v)
return 0;
}
int set_var(struct map_session_data *sd, char *name, void *val)
{
return set_reg(sd, add_str(name), name, val);
}
/*==========================================
* ŽšñÖÌÏŠ·
*------------------------------------------

View File

@ -42,6 +42,10 @@ struct script_state {
char * parse_script(unsigned char *,int);
int run_script(char *,int,int,int);
int set_var(struct map_session_data *sd, char *name, void *val);
int conv_num(struct script_state *st,struct script_data *data);
char* conv_str(struct script_state *st,struct script_data *data);
struct dbt* script_get_label_db();
struct dbt* script_get_userfunc_db();