summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-07-27 21:00:19 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-07-27 21:00:19 +0000
commit6384f1dd85e311f1456351388f9a94a32ac1fad4 (patch)
tree19209d56704842750a50114e386b8e5490df73ca
parent3e29ca7edd4e8618fa24e6a2c65e35a3baeddad8 (diff)
downloadhercules-6384f1dd85e311f1456351388f9a94a32ac1fad4.tar.gz
hercules-6384f1dd85e311f1456351388f9a94a32ac1fad4.tar.bz2
hercules-6384f1dd85e311f1456351388f9a94a32ac1fad4.tar.xz
hercules-6384f1dd85e311f1456351388f9a94a32ac1fad4.zip
- Synced the script.c file with as much data as possible from jA's:
- A lot of functions were moved around, a bunch of indentation and space-usage changes were done to make it easier to diff against their files. - Miscellanous addition and corrections were applied. - Largest one is likely a restructuring of run_script_main, which hopes to solve the memory leaks. - script engine now uses the setjmp functions to restore memory state when there's an error parsing scripts, which means that script errors won't cause the map-server to inmediately bail out anymore. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@7926 54d463be-8e91-2dee-dedb-b68131a5f0ec
-rw-r--r--Changelog-Trunk.txt14
-rw-r--r--src/map/itemdb.c22
-rw-r--r--src/map/npc.c33
-rw-r--r--src/map/pet.c2
-rw-r--r--src/map/script.c4207
-rw-r--r--src/map/script.h20
6 files changed, 2175 insertions, 2123 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index a0438a7e5..85963221f 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,6 +4,20 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/07/27
+ * Synced the script.c file with as much data as possible from jA's:
+ [Skotlex]
+ - A lot of functions were moved around, a bunch of indentation and
+ space-usage changes were done to make it easier to diff against their
+ files.
+ - Miscellanous addition and corrections were applied.
+ - Largest one is likely a restructuring of run_script_main, which hopes to
+ solve the memory leaks.
+ - script engine now uses the setjmp functions to restore memory state when
+ there's an error parsing scripts, which means that script errors won't
+ cause the map-server to inmediately bail out anymore.
+ - NOTE that the amount of changes is pretty extensive, so DON'T USE THIS on
+ a live server. Update only to help test and debug to see if the script
+ engine memory leaks are gone.
* Added a cleanup routine on shutdown to remove all characters from memory
for whom the save ack has not returned from the char-server yet. [Skotlex]
* Now when you set the guardian's HP, if the guardian is spawned, it's HP
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 4972f2452..728ea0108 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -956,10 +956,10 @@ static int itemdb_read_sqldb(void)
script_free_code(id->script);
if (sql_row[19] != NULL) {
if (sql_row[19][0] == '{')
- id->script = parse_script((unsigned char *) sql_row[19], 0);
+ id->script = parse_script((unsigned char *) sql_row[19],item_db_name[i], 0);
else {
sprintf(script, "{%s}", sql_row[19]);
- id->script = parse_script((unsigned char *) script, 0);
+ id->script = parse_script((unsigned char *) script, item_db_name[i], 0);
}
} else id->script = NULL;
@@ -967,10 +967,10 @@ static int itemdb_read_sqldb(void)
script_free_code(id->equip_script);
if (sql_row[20] != NULL) {
if (sql_row[20][0] == '{')
- id->equip_script = parse_script((unsigned char *) sql_row[20], 0);
+ id->equip_script = parse_script((unsigned char *) sql_row[20], item_db_name[i], 0);
else {
sprintf(script, "{%s}", sql_row[20]);
- id->equip_script = parse_script((unsigned char *) script, 0);
+ id->equip_script = parse_script((unsigned char *) script, item_db_name[i], 0);
}
} else id->equip_script = NULL;
@@ -978,10 +978,10 @@ static int itemdb_read_sqldb(void)
script_free_code(id->unequip_script);
if (sql_row[21] != NULL) {
if (sql_row[21][0] == '{')
- id->unequip_script = parse_script((unsigned char *) sql_row[21], 0);
+ id->unequip_script = parse_script((unsigned char *) sql_row[21],item_db_name[i], 0);
else {
sprintf(script, "{%s}", sql_row[21]);
- id->unequip_script = parse_script((unsigned char *) script, 0);
+ id->unequip_script = parse_script((unsigned char *) script, item_db_name[i], 0);
}
} else id->unequip_script = NULL;
@@ -1148,11 +1148,11 @@ static int itemdb_readdb(void)
np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
if (!np || !np[1]) {
//Couldn't find the end of the script field.
- id->script = parse_script((unsigned char *) str[19],lines);
+ id->script = parse_script((unsigned char *) str[19],filename[i],lines);
continue;
}
np[1] = '\0'; //Set end of script
- id->script = parse_script((unsigned char *) str[19],lines);
+ id->script = parse_script((unsigned char *) str[19],filename[i],lines);
np+=2; //Skip to next field
if(!np || (p=strchr(np,'{'))==NULL)
@@ -1165,18 +1165,18 @@ static int itemdb_readdb(void)
np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
if (!np || !np[1]) {
//Couldn't find the end of the script field.
- id->equip_script = parse_script((unsigned char *) str[20],lines);
+ id->equip_script = parse_script((unsigned char *) str[20],filename[i],lines);
continue;
}
np[1] = '\0'; //Set end of script
- id->equip_script = parse_script((unsigned char *) str[20],lines);
+ id->equip_script = parse_script((unsigned char *) str[20],filename[i],lines);
np+=2; //Skip comma, to next field
if(!np || (p=strchr(np,'{'))==NULL)
continue;
//Unequip script, last column.
- id->unequip_script = parse_script((unsigned char *) p,lines);
+ id->unequip_script = parse_script((unsigned char *) p,filename[i],lines);
}
fclose(fp);
if (ln > 0) {
diff --git a/src/map/npc.c b/src/map/npc.c
index 626344881..6f5649654 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -1023,9 +1023,6 @@ int npc_checknear2(struct map_session_data *sd,struct block_list *bl)
if(sd->state.using_fake_npc && sd->npc_id == bl->id)
return 0;
-// if (bl->type!=BL_NPC) //Disguised character or something else...
-// return 1;
-
if (status_get_class(bl)<0) //Class-less npc, enable click from anywhere.
return 0;
@@ -1817,7 +1814,7 @@ static int npc_skip_script (char *w1,char *w2,char *w3,char *w4,char *first_line
return 0;
}
-static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_line,FILE *fp,int *lines)
+static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line,FILE *fp,int *lines,const char* file)
{
int x, y, dir = 0, m, xs = 0, ys = 0, class_ = 0; // [Valaris] thanks to fov
char mapname[MAP_NAME_LENGTH];
@@ -1840,7 +1837,7 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
// 引数の個数チェック
if (sscanf(w1, "%15[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 ||
(strcmp(w2, "script") == 0 && strchr(w4,',') == NULL)) {
- ShowError("bad script line (in file %s): %s\n", current_file, w3);
+ ShowError("bad script line (in file %s): %s\n", file, w3);
return 1;
}
m = map_mapname2mapid(mapname);
@@ -1876,11 +1873,11 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
strcat((char *) srcbuf, (const char *) line);
}
if(curly_count > 0) {
- ShowError("Missing right curly at file %s, line %d\n",current_file, *lines);
+ ShowError("Missing right curly at file %s, line %d\n",file, *lines);
script = NULL;
} else {
// printf("Ok line %d\n",*lines);
- script = parse_script((unsigned char *) srcbuf, startline);
+ script = parse_script((unsigned char *) srcbuf, file, startline);
}
if (script == NULL) {
// script parse error?
@@ -1892,11 +1889,11 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
char srcname[128];
struct npc_data *dnd;
if (sscanf(w2, "duplicate(%[^)])", srcname) != 1) {
- ShowError("bad duplicate name (in %s)! : %s", current_file, w2);
+ ShowError("bad duplicate name (in %s)! : %s", file, w2);
return 0;
}
if ((dnd = npc_name2id(srcname)) == NULL) {
- ShowError("bad duplicate name (in %s)! (not exist) : %s\n", current_file, srcname);
+ ShowError("bad duplicate name (in %s)! (not exist) : %s\n", file, srcname);
return 0;
}
script = dnd->u.scr.script;
@@ -2019,7 +2016,7 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
// and already overwritten if this is here is reached
// I leave the check anyway but place it correctly to npc_convertlabel_db
if (strlen(lname)>NAME_LENGTH-1) {
- ShowError("npc_parse_script: label name longer than %d chars! '%s' (%s)\n", NAME_LENGTH-1, lname, current_file);
+ ShowError("npc_parse_script: label name longer than %d chars! '%s' (%s)\n", NAME_LENGTH-1, lname, file);
exit(1);
} else {
struct event_data *ev;
@@ -2033,7 +2030,7 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
ev->nd=nd;
ev->pos=pos;
if (strdb_put(ev_db,buf,ev) != NULL) //There was already another event of the same name?
- ShowWarning("npc_parse_script : duplicate event %s (%s)\n",buf, current_file);
+ ShowWarning("npc_parse_script : duplicate event %s (%s)\n",buf, file);
}
}
}
@@ -2073,7 +2070,7 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
* function行解析
*------------------------------------------
*/
-static int npc_parse_function (char *w1, char *w2, char *w3, char *w4, char *first_line, FILE *fp, int *lines)
+static int npc_parse_function (char *w1, char *w2, char *w3, char *w4, char *first_line, FILE *fp, int *lines,const char* file)
{
unsigned char *srcbuf, *p;
struct script_code *script;
@@ -2112,10 +2109,10 @@ static int npc_parse_function (char *w1, char *w2, char *w3, char *w4, char *fir
strcat(srcbuf,line);
}
if(curly_count > 0) {
- ShowError("Missing right curly at file %s, line %d\n",current_file, *lines);
+ ShowError("Missing right curly at file %s, line %d\n",file, *lines);
script = NULL;
} else {
- script = parse_script(srcbuf, startline);
+ script = parse_script(srcbuf, file, startline);
}
if (script == NULL) {
// script parse error?
@@ -2516,7 +2513,7 @@ static int npc_parse_mapflag (char *w1, char *w2, char *w3, char *w4)
else if (strcmpi(w3,"nochat")==0) { // Skotlex
map[m].flag.nochat=state;
}
-
+
return 0;
}
@@ -2619,12 +2616,12 @@ void npc_parsesrcfile (char *name)
npc_parse_shop(w1,w2,w3,w4);
} else if (strcmpi(w2,"script") == 0 && count > 3) {
if (strcmpi(w1,"function") == 0) {
- npc_parse_function(w1,w2,w3,w4,line+w4pos,fp,&lines);
+ npc_parse_function(w1,w2,w3,w4,line+w4pos,fp,&lines,name);
} else {
- npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines);
+ npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines,name);
}
} else if ((i = 0, sscanf(w2,"duplicate%n",&i), (i > 0 && w2[i] == '(')) && count > 3) {
- npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines);
+ npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines,name);
} else if (strcmpi(w2,"monster") == 0 && count > 3) {
npc_parse_mob(w1,w2,w3,w4);
} else if (strcmpi(w2,"mapflag") == 0 && count >= 3) {
diff --git a/src/map/pet.c b/src/map/pet.c
index 317145cb7..bb9e26dbc 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -1352,7 +1352,7 @@ int read_petdb()
pet_db[j].script = NULL;
if((np=strchr(p,'{'))==NULL)
continue;
- pet_db[j].script = parse_script((unsigned char *) np,lines);
+ pet_db[j].script = parse_script((unsigned char *) np, filename[i], lines);
j++;
}
if (j >= MAX_PET_DB)
diff --git a/src/map/script.c b/src/map/script.c
index 1571d7d5d..2458cc840 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -12,10 +12,10 @@
#include <math.h>
#ifndef _WIN32
-#include <sys/time.h>
+ #include <sys/time.h>
#endif
-
#include <time.h>
+#include <setjmp.h>
#include "../common/socket.h"
#include "../common/timer.h"
@@ -49,24 +49,24 @@
#include "unit.h"
#include "irc.h"
#include "pet.h"
-#define SCRIPT_BLOCK_SIZE 256
#define FETCH(n, t) \
if(st->end>st->start+(n)) \
(t)=conv_num(st,&(st->stack->stack_data[st->start+(n)]));
+#define SCRIPT_BLOCK_SIZE 512
enum { LABEL_NEXTLINE=1,LABEL_START };
static unsigned char * script_buf = NULL;
static int script_pos,script_size;
-char *str_buf;
-int str_pos,str_size;
+static char *str_buf;
+static int str_pos,str_size;
static struct str_data_struct {
int type;
int str;
int backpatch;
int label;
- int (*func)(struct script_state *);
+ int (*func)(struct script_state *st);
int val;
int next;
} *str_data = NULL;
@@ -77,20 +77,22 @@ static struct dbt *mapreg_db=NULL;
static struct dbt *mapregstr_db=NULL;
static int mapreg_dirty=-1;
char mapreg_txt[256]="save/mapreg.txt";
-#define MAPREG_AUTOSAVE_INTERVAL (10*1000)
+#define MAPREG_AUTOSAVE_INTERVAL (300*1000)
static struct dbt *scriptlabel_db=NULL;
static struct dbt *userfunc_db=NULL;
-
struct dbt* script_get_label_db(){ return scriptlabel_db; }
struct dbt* script_get_userfunc_db(){ return userfunc_db; }
static char pos[11][100] = {"頭","体","左手","右手","ローブ","靴","アクセサリー1","アクセサリー2","頭2","頭3","装着していない"};
struct Script_Config script_config;
-
static int parse_cmd;
+static jmp_buf error_jump;
+static char* error_msg;
+static char* error_pos;
+
// for advanced scripting support ( nested if, switch, while, for, do-while, function, etc )
// [Eoe / jA 1080, 1081, 1094, 1164]
enum { TYPE_NULL = 0 , TYPE_IF , TYPE_SWITCH , TYPE_WHILE , TYPE_FOR , TYPE_DO , TYPE_USERFUNC};
@@ -125,6 +127,15 @@ char tmp_sql[65535];
// --------------------------------------------------------
#endif
+int get_com(unsigned char *script,int *pos);
+int get_num(unsigned char *script,int *pos);
+
+extern struct script_function {
+ int (*func)(struct script_state *st);
+ char *name;
+ char *arg;
+} buildin_func[];
+
static struct linkdb_node *sleep_db;
#define not_server_variable(prefix) (prefix != '$' && prefix != '.')
@@ -133,664 +144,12 @@ static struct linkdb_node *sleep_db;
*------------------------------------------
*/
unsigned char* parse_subexpr(unsigned char *,int);
-#ifndef TXT_ONLY
-int buildin_query_sql(struct script_state *st);
-int buildin_escape_sql(struct script_state *st);
-#endif
-int buildin_atoi(struct script_state *st);
-int buildin_axtoi(struct script_state *st);
-int buildin_mes(struct script_state *st);
-int buildin_goto(struct script_state *st);
-int buildin_callsub(struct script_state *st);
-int buildin_callfunc(struct script_state *st);
-int buildin_return(struct script_state *st);
-int buildin_getarg(struct script_state *st);
-int buildin_next(struct script_state *st);
-int buildin_close(struct script_state *st);
-int buildin_close2(struct script_state *st);
-int buildin_menu(struct script_state *st);
-int buildin_rand(struct script_state *st);
-int buildin_warp(struct script_state *st);
-int buildin_areawarp(struct script_state *st);
-int buildin_warpchar(struct script_state *st); // [LuzZza]
-int buildin_warpparty(struct script_state *st); //[Fredzilla]
-int buildin_warpguild(struct script_state *st); //[Fredzilla]
-int buildin_heal(struct script_state *st);
-int buildin_itemheal(struct script_state *st);
-int buildin_percentheal(struct script_state *st);
-int buildin_jobchange(struct script_state *st);
-int buildin_input(struct script_state *st);
-int buildin_setlook(struct script_state *st);
-int buildin_set(struct script_state *st);
-int buildin_setarray(struct script_state *st);
-int buildin_cleararray(struct script_state *st);
-int buildin_copyarray(struct script_state *st);
-int buildin_getarraysize(struct script_state *st);
-int buildin_deletearray(struct script_state *st);
-int buildin_getelementofarray(struct script_state *st);
-int buildin_getitem(struct script_state *st);
-int buildin_getitem2(struct script_state *st);
-int buildin_getnameditem(struct script_state *st);
-int buildin_grouprandomitem(struct script_state *st);
-int buildin_makeitem(struct script_state *st);
-int buildin_delitem(struct script_state *st);
-int buildin_delitem2(struct script_state *st);
-int buildin_enableitemuse(struct script_state *st);
-int buildin_disableitemuse(struct script_state *st);
-int buildin_viewpoint(struct script_state *st);
-int buildin_countitem(struct script_state *st);
-int buildin_countitem2(struct script_state *st);
-int buildin_checkweight(struct script_state *st);
-int buildin_readparam(struct script_state *st);
-int buildin_getcharid(struct script_state *st);
-int buildin_getpartyname(struct script_state *st);
-int buildin_getpartymember(struct script_state *st);
-int buildin_getguildname(struct script_state *st);
-int buildin_getguildmaster(struct script_state *st);
-int buildin_getguildmasterid(struct script_state *st);
-int buildin_strcharinfo(struct script_state *st);
-int buildin_getequipid(struct script_state *st);
-int buildin_getequipname(struct script_state *st);
-int buildin_getbrokenid(struct script_state *st); // [Valaris]
-int buildin_repair(struct script_state *st); // [Valaris]
-int buildin_getequipisequiped(struct script_state *st);
-int buildin_getequipisenableref(struct script_state *st);
-int buildin_getequipisidentify(struct script_state *st);
-int buildin_getequiprefinerycnt(struct script_state *st);
-int buildin_getequipweaponlv(struct script_state *st);
-int buildin_getequippercentrefinery(struct script_state *st);
-int buildin_successrefitem(struct script_state *st);
-int buildin_failedrefitem(struct script_state *st);
-int buildin_cutin(struct script_state *st);
-int buildin_cutincard(struct script_state *st);
-int buildin_statusup(struct script_state *st);
-int buildin_statusup2(struct script_state *st);
-int buildin_bonus(struct script_state *st);
-int buildin_bonus2(struct script_state *st);
-int buildin_bonus3(struct script_state *st);
-int buildin_bonus4(struct script_state *st);
-int buildin_skill(struct script_state *st);
-int buildin_addtoskill(struct script_state *st); // [Valaris]
-int buildin_guildskill(struct script_state *st);
-int buildin_getskilllv(struct script_state *st);
-int buildin_getgdskilllv(struct script_state *st);
-int buildin_basicskillcheck(struct script_state *st);
-int buildin_getgmlevel(struct script_state *st);
-int buildin_end(struct script_state *st);
-int buildin_checkoption(struct script_state *st);
-int buildin_setoption(struct script_state *st);
-int buildin_setcart(struct script_state *st);
-int buildin_checkcart(struct script_state *st); // check cart [Valaris]
-int buildin_setfalcon(struct script_state *st);
-int buildin_checkfalcon(struct script_state *st); // check falcon [Valaris]
-int buildin_setriding(struct script_state *st);
-int buildin_checkriding(struct script_state *st); // check for pecopeco [Valaris]
-int buildin_savepoint(struct script_state *st);
-int buildin_gettimetick(struct script_state *st);
-int buildin_gettime(struct script_state *st);
-int buildin_gettimestr(struct script_state *st);
-int buildin_openstorage(struct script_state *st);
-int buildin_guildopenstorage(struct script_state *st);
-int buildin_itemskill(struct script_state *st);
-int buildin_produce(struct script_state *st);
-int buildin_monster(struct script_state *st);
-int buildin_areamonster(struct script_state *st);
-int buildin_killmonster(struct script_state *st);
-int buildin_killmonsterall(struct script_state *st);
-int buildin_clone(struct script_state *st);
-int buildin_doevent(struct script_state *st);
-int buildin_donpcevent(struct script_state *st);
-int buildin_addtimer(struct script_state *st);
-int buildin_deltimer(struct script_state *st);
-int buildin_addtimercount(struct script_state *st);
-int buildin_initnpctimer(struct script_state *st);
-int buildin_stopnpctimer(struct script_state *st);
-int buildin_startnpctimer(struct script_state *st);
-int buildin_setnpctimer(struct script_state *st);
-int buildin_getnpctimer(struct script_state *st);
-int buildin_attachnpctimer(struct script_state *st); // [celest]
-int buildin_detachnpctimer(struct script_state *st); // [celest]
-int buildin_playerattached(struct script_state *st); // [Skotlex]
-int buildin_announce(struct script_state *st);
-int buildin_mapannounce(struct script_state *st);
-int buildin_areaannounce(struct script_state *st);
-int buildin_getusers(struct script_state *st);
-int buildin_getmapusers(struct script_state *st);
-int buildin_getareausers(struct script_state *st);
-int buildin_getareadropitem(struct script_state *st);
-int buildin_enablenpc(struct script_state *st);
-int buildin_disablenpc(struct script_state *st);
-int buildin_enablearena(struct script_state *st); // Added by RoVeRT
-int buildin_disablearena(struct script_state *st); // Added by RoVeRT
-int buildin_hideoffnpc(struct script_state *st);
-int buildin_hideonnpc(struct script_state *st);
-int buildin_sc_start(struct script_state *st);
-int buildin_sc_start2(struct script_state *st);
-int buildin_sc_start4(struct script_state *st);
-int buildin_sc_end(struct script_state *st);
-int buildin_getscrate(struct script_state *st);
-int buildin_debugmes(struct script_state *st);
-int buildin_catchpet(struct script_state *st);
-int buildin_birthpet(struct script_state *st);
-int buildin_resetlvl(struct script_state *st);
-int buildin_resetstatus(struct script_state *st);
-int buildin_resetskill(struct script_state *st);
-int buildin_skillpointcount(struct script_state *st);
-int buildin_changebase(struct script_state *st);
-int buildin_changesex(struct script_state *st);
-int buildin_waitingroom(struct script_state *st);
-int buildin_delwaitingroom(struct script_state *st);
-int buildin_enablewaitingroomevent(struct script_state *st);
-int buildin_disablewaitingroomevent(struct script_state *st);
-int buildin_getwaitingroomstate(struct script_state *st);
-int buildin_warpwaitingpc(struct script_state *st);
-int buildin_attachrid(struct script_state *st);
-int buildin_detachrid(struct script_state *st);
-int buildin_isloggedin(struct script_state *st);
-int buildin_setmapflagnosave(struct script_state *st);
-int buildin_setmapflag(struct script_state *st);
-int buildin_removemapflag(struct script_state *st);
-int buildin_pvpon(struct script_state *st);
-int buildin_pvpoff(struct script_state *st);
-int buildin_gvgon(struct script_state *st);
-int buildin_gvgoff(struct script_state *st);
-int buildin_emotion(struct script_state *st);
-int buildin_maprespawnguildid(struct script_state *st);
-int buildin_agitstart(struct script_state *st); // <Agit>
-int buildin_agitend(struct script_state *st);
-int buildin_agitcheck(struct script_state *st); // <Agitcheck>
-int buildin_flagemblem(struct script_state *st); // Flag Emblem
-int buildin_getcastlename(struct script_state *st);
-int buildin_getcastledata(struct script_state *st);
-int buildin_setcastledata(struct script_state *st);
-int buildin_requestguildinfo(struct script_state *st);
-int buildin_getequipcardcnt(struct script_state *st);
-int buildin_successremovecards(struct script_state *st);
-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); // MouseJstr
-int buildin_getpartnerid(struct script_state *st); // MouseJstr
-int buildin_getchildid(struct script_state *st); // Skotlex
-int buildin_getmotherid(struct script_state *st); // Lupus
-int buildin_getfatherid(struct script_state *st); // Lupus
-int buildin_warppartner(struct script_state *st); // MouseJstr
-int buildin_getitemname(struct script_state *st);
-int buildin_getitemslots(struct script_state *st);
-int buildin_makepet(struct script_state *st);
-int buildin_getexp(struct script_state *st);
-int buildin_getinventorylist(struct script_state *st);
-int buildin_getskilllist(struct script_state *st);
-int buildin_clearitem(struct script_state *st);
-int buildin_classchange(struct script_state *st);
-int buildin_misceffect(struct script_state *st);
-int buildin_soundeffect(struct script_state *st);
-int buildin_soundeffectall(struct script_state *st);
-int buildin_setcastledata(struct script_state *st);
-int buildin_mapwarp(struct script_state *st);
-int buildin_inittimer(struct script_state *st);
-int buildin_stoptimer(struct script_state *st);
-int buildin_cmdothernpc(struct script_state *st);
-int buildin_mobcount(struct script_state *st);
-int buildin_strmobinfo(struct script_state *st); // Script for displaying mob info [Valaris]
-int buildin_guardian(struct script_state *st); // Script for displaying mob info [Valaris]
-int buildin_guardianinfo(struct script_state *st); // Script for displaying mob info [Valaris]
-int buildin_petskillbonus(struct script_state *st); // petskillbonus [Valaris]
-int buildin_petrecovery(struct script_state *st); // pet skill for curing status [Valaris]
-int buildin_petloot(struct script_state *st); // pet looting [Valaris]
-int buildin_petheal(struct script_state *st); // pet healing [Valaris]
-//int buildin_petmag(struct script_state *st); // pet magnificat [Valaris]
-int buildin_petskillattack(struct script_state *st); // pet skill attacks [Skotlex]
-int buildin_petskillattack2(struct script_state *st); // pet skill attacks [Skotlex]
-int buildin_petskillsupport(struct script_state *st); // pet support skill [Valaris]
-int buildin_skilleffect(struct script_state *st); // skill effects [Celest]
-int buildin_npcskilleffect(struct script_state *st); // skill effects for npcs [Valaris]
-int buildin_specialeffect(struct script_state *st); // special effect script [Valaris]
-int buildin_specialeffect2(struct script_state *st); // special effect script [Valaris]
-int buildin_nude(struct script_state *st); // nude [Valaris]
-int buildin_atcommand(struct script_state *st); // [MouseJstr]
-int buildin_charcommand(struct script_state *st); // [MouseJstr]
-int buildin_movenpc(struct script_state *st); // [MouseJstr]
-int buildin_message(struct script_state *st); // [MouseJstr]
-int buildin_npctalk(struct script_state *st); // [Valaris]
-int buildin_hasitems(struct script_state *st); // [Valaris]
-int buildin_getlook(struct script_state *st); //Lorky [Lupus]
-int buildin_getsavepoint(struct script_state *st); //Lorky [Lupus]
-int buildin_npcspeed(struct script_state *st); // [Valaris]
-int buildin_npcwalkto(struct script_state *st); // [Valaris]
-int buildin_npcstop(struct script_state *st); // [Valaris]
-int buildin_getmapxy(struct script_state *st); //get map position for player/npc/pet/mob by Lorky [Lupus]
-int buildin_checkoption1(struct script_state *st); // [celest]
-int buildin_checkoption2(struct script_state *st); // [celest]
-int buildin_guildgetexp(struct script_state *st); // [celest]
-int buildin_guildchangegm(struct script_state *st); // [Skotlex]
-int buildin_logmes(struct script_state *st); // [Lupus]
-int buildin_summon(struct script_state *st); // [celest]
-int buildin_isnight(struct script_state *st); // [celest]
-int buildin_isday(struct script_state *st); // [celest]
-int buildin_isequipped(struct script_state *st); // [celest]
-int buildin_isequippedcnt(struct script_state *st); // [celest]
-int buildin_cardscnt(struct script_state *st); // [Lupus]
-int buildin_getrefine(struct script_state *st); // [celest]
-int buildin_adopt(struct script_state *st);
-int buildin_night(struct script_state *st);
-int buildin_day(struct script_state *st);
-int buildin_getusersname(struct script_state *st); //jA commands added [Lupus]
-int buildin_dispbottom(struct script_state *st);
-int buildin_recovery(struct script_state *st);
-int buildin_getpetinfo(struct script_state *st);
-int buildin_checkequipedcard(struct script_state *st);
-int buildin_globalmes(struct script_state *st);
-int buildin_jump_zero(struct script_state *st);
-int buildin_select(struct script_state *st);
-int buildin_getmapmobs(struct script_state *st); //jA addition end
-int buildin_unequip(struct script_state *st); // unequip [Spectre]
-int buildin_getstrlen(struct script_state *st); //strlen [valaris]
-int buildin_charisalpha(struct script_state *st);//isalpha [valaris]
-int buildin_fakenpcname(struct script_state *st); // [Lance]
-int buildin_compare(struct script_state *st); // Lordalfa, to bring strstr to Scripting Engine
-int buildin_getiteminfo(struct script_state *st); //[Lupus] returns Items Buy / sell Price, etc info
-int buildin_getequipcardid(struct script_state *st); //[Lupus] returns card id from quipped item card slot N
-// [zBuffer] List of mathematics commands --->
-int buildin_sqrt(struct script_state *st);
-int buildin_pow(struct script_state *st);
-int buildin_distance(struct script_state *st);
-int buildin_checkcell(struct script_state *st);
-// <--- [zBuffer] List of mathematics commands
-// [zBuffer] List of dynamic var commands --->
-int buildin_getd(struct script_state *st);
-int buildin_setd(struct script_state *st);
-// <--- [zBuffer] List of dynamic var commands
-int buildin_petstat(struct script_state *st); // [Lance] Pet Stat Rq: Dubby
-int buildin_callshop(struct script_state *st); // [Skotlex]
-int buildin_npcshopitem(struct script_state *st); // [Lance]
-int buildin_npcshopadditem(struct script_state *st);
-int buildin_npcshopdelitem(struct script_state *st);
-int buildin_equip(struct script_state *st);
-int buildin_autoequip(struct script_state *st);
-int buildin_setbattleflag(struct script_state *st);
-int buildin_getbattleflag(struct script_state *st);
-// [zBuffer] List of player cont commands --->
-int buildin_rid2name(struct script_state *st);
-int buildin_pcfollow(struct script_state *st);
-int buildin_pcstopfollow(struct script_state *st);
-int buildin_pcblockmove(struct script_state *st);
-// <--- [zBuffer] List of player cont commands
-// [zBuffer] List of mob control commands --->
-int buildin_mobspawn(struct script_state *st);
-int buildin_mobremove(struct script_state *st);
-int buildin_getmobdata(struct script_state *st);
-int buildin_setmobdata(struct script_state *st);
-int buildin_mobassist(struct script_state *st);
-int buildin_mobattach(struct script_state *st);
-int buildin_unitwalk(struct script_state *st);
-int buildin_unitkill(struct script_state *st);
-int buildin_unitwarp(struct script_state *st);
-int buildin_unitattack(struct script_state *st);
-int buildin_unitstop(struct script_state *st);
-int buildin_unittalk(struct script_state *st);
-int buildin_unitemote(struct script_state *st);
-int buildin_unitdeadsit(struct script_state *st);
-int buildin_unitskilluseid(struct script_state *st); // originally by Qamera [celest]
-int buildin_unitskillusepos(struct script_state *st); // originally by Qamera [celest]
-// <--- [zBuffer] List of mob control commands
-int buildin_sleep(struct script_state *st);
-int buildin_sleep2(struct script_state *st);
-int buildin_awake(struct script_state *st);
-int buildin_getvariableofnpc(struct script_state *st);
-// [blackhole89] -->
-int buildin_warpportal(struct script_state *st);
-// <-- [blackhole89]
-int buildin_homunculus_evolution(struct script_state *st) ; //[orn]
void push_val(struct script_stack *stack,int type,int val);
int run_func(struct script_state *st);
int mapreg_setreg(int num,int val);
int mapreg_setregstr(int num,const char *str);
-int buildin_setitemscript(struct script_state *st);
-int buildin_disguise(struct script_state *st);
-int buildin_undisguise(struct script_state *st);
-int buildin_getmonsterinfo(struct script_state *st); // [Lupus]
-
-#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;
- char *arg;
-} buildin_func[]={
- {buildin_axtoi,"axtoi","s"},
-#ifndef TXT_ONLY
- {buildin_query_sql, "query_sql", "s*"},
- {buildin_escape_sql, "escape_sql", "s"},
-#endif
- {buildin_atoi,"atoi","s"},
- {buildin_mes,"mes","s"},
- {buildin_next,"next",""},
- {buildin_close,"close",""},
- {buildin_close2,"close2",""},
- {buildin_menu,"menu","*"},
- {buildin_goto,"goto","l"},
- {buildin_callsub,"callsub","i*"},
- {buildin_callfunc,"callfunc","s*"},
- {buildin_return,"return","*"},
- {buildin_getarg,"getarg","i"},
- {buildin_jobchange,"jobchange","i*"},
- {buildin_input,"input","*"},
- {buildin_warp,"warp","sii"},
- {buildin_areawarp,"areawarp","siiiisii"},
- {buildin_warpchar,"warpchar","siii"}, // [LuzZza]
- {buildin_warpparty,"warpparty","siii"}, // [Fredzilla]
- {buildin_warpguild,"warpguild","siii"}, // [Fredzilla]
- {buildin_setlook,"setlook","ii"},
- {buildin_set,"set","ii"},
- {buildin_setarray,"setarray","ii*"},
- {buildin_cleararray,"cleararray","iii"},
- {buildin_copyarray,"copyarray","iii"},
- {buildin_getarraysize,"getarraysize","i"},
- {buildin_deletearray,"deletearray","ii"},
- {buildin_getelementofarray,"getelementofarray","ii"},
- {buildin_getitem,"getitem","ii**"},
- {buildin_getitem2,"getitem2","iiiiiiiii*"},
- {buildin_getnameditem,"getnameditem","is"},
- {buildin_grouprandomitem,"groupranditem","i"},
- {buildin_makeitem,"makeitem","iisii"},
- {buildin_delitem,"delitem","ii"},
- {buildin_delitem2,"delitem2","iiiiiiiii"},
- {buildin_enableitemuse,"enable_items",""},
- {buildin_disableitemuse,"disable_items",""},
- {buildin_cutin,"cutin","si"},
- {buildin_cutincard,"cutincard","i"},
- {buildin_viewpoint,"viewpoint","iiiii"},
- {buildin_heal,"heal","ii"},
- {buildin_itemheal,"itemheal","ii"},
- {buildin_percentheal,"percentheal","ii"},
- {buildin_rand,"rand","i*"},
- {buildin_countitem,"countitem","i"},
- {buildin_countitem2,"countitem2","iiiiiiii"},
- {buildin_checkweight,"checkweight","ii"},
- {buildin_readparam,"readparam","i*"},
- {buildin_getcharid,"getcharid","i*"},
- {buildin_getpartyname,"getpartyname","i"},
- {buildin_getpartymember,"getpartymember","i*"},
- {buildin_getguildname,"getguildname","i"},
- {buildin_getguildmaster,"getguildmaster","i"},
- {buildin_getguildmasterid,"getguildmasterid","i"},
- {buildin_strcharinfo,"strcharinfo","i"},
- {buildin_getequipid,"getequipid","i"},
- {buildin_getequipname,"getequipname","i"},
- {buildin_getbrokenid,"getbrokenid","i"}, // [Valaris]
- {buildin_repair,"repair","i"}, // [Valaris]
- {buildin_getequipisequiped,"getequipisequiped","i"},
- {buildin_getequipisenableref,"getequipisenableref","i"},
- {buildin_getequipisidentify,"getequipisidentify","i"},
- {buildin_getequiprefinerycnt,"getequiprefinerycnt","i"},
- {buildin_getequipweaponlv,"getequipweaponlv","i"},
- {buildin_getequippercentrefinery,"getequippercentrefinery","i"},
- {buildin_successrefitem,"successrefitem","i"},
- {buildin_failedrefitem,"failedrefitem","i"},
- {buildin_statusup,"statusup","i"},
- {buildin_statusup2,"statusup2","ii"},
- {buildin_bonus,"bonus","ii"},
- {buildin_bonus2,"bonus2","iii"},
- {buildin_bonus3,"bonus3","iiii"},
- {buildin_bonus4,"bonus4","iiiii"},
- {buildin_skill,"skill","ii*"},
- {buildin_addtoskill,"addtoskill","ii*"}, // [Valaris]
- {buildin_guildskill,"guildskill","ii"},
- {buildin_getskilllv,"getskilllv","i"},
- {buildin_getgdskilllv,"getgdskilllv","ii"},
- {buildin_basicskillcheck,"basicskillcheck","*"},
- {buildin_getgmlevel,"getgmlevel","*"},
- {buildin_end,"end",""},
-// {buildin_end,"break",""}, this might confuse advanced scripting support [Eoe]
- {buildin_checkoption,"checkoption","i"},
- {buildin_setoption,"setoption","i*"},
- {buildin_setcart,"setcart",""},
- {buildin_checkcart,"checkcart","*"}, //fixed by Lupus (added '*')
- {buildin_setfalcon,"setfalcon",""},
- {buildin_checkfalcon,"checkfalcon","*"}, //fixed by Lupus (fixed wrong pointer, added '*')
- {buildin_setriding,"setriding",""},
- {buildin_checkriding,"checkriding","*"}, //fixed by Lupus (fixed wrong pointer, added '*')
- {buildin_savepoint,"save","sii"},
- {buildin_savepoint,"savepoint","sii"},
- {buildin_gettimetick,"gettimetick","i"},
- {buildin_gettime,"gettime","i"},
- {buildin_gettimestr,"gettimestr","si"},
- {buildin_openstorage,"openstorage",""},
- {buildin_guildopenstorage,"guildopenstorage","*"},
- {buildin_itemskill,"itemskill","iis"},
- {buildin_produce,"produce","i"},
- {buildin_monster,"monster","siisii*"},
- {buildin_areamonster,"areamonster","siiiisii*"},
- {buildin_killmonster,"killmonster","ss"},
- {buildin_killmonsterall,"killmonsterall","s"},
- {buildin_clone,"clone","siisi*"},
- {buildin_doevent,"doevent","s"},
- {buildin_donpcevent,"donpcevent","s"},
- {buildin_addtimer,"addtimer","is"},
- {buildin_deltimer,"deltimer","s"},
- {buildin_addtimercount,"addtimercount","si"},
- {buildin_initnpctimer,"initnpctimer","*"},
- {buildin_stopnpctimer,"stopnpctimer","*"},
- {buildin_startnpctimer,"startnpctimer","*"},
- {buildin_setnpctimer,"setnpctimer","*"},
- {buildin_getnpctimer,"getnpctimer","i*"},
- {buildin_attachnpctimer,"attachnpctimer","*"}, // attached the player id to the npc timer [Celest]
- {buildin_detachnpctimer,"detachnpctimer","*"}, // detached the player id from the npc timer [Celest]
- {buildin_playerattached,"playerattached",""}, // returns id of the current attached player. [Skotlex]
- {buildin_announce,"announce","si*"},
- {buildin_mapannounce,"mapannounce","ssi*"},
- {buildin_areaannounce,"areaannounce","siiiisi*"},
- {buildin_getusers,"getusers","i"},
- {buildin_getmapusers,"getmapusers","s"},
- {buildin_getareausers,"getareausers","siiii"},
- {buildin_getareadropitem,"getareadropitem","siiiii"},
- {buildin_enablenpc,"enablenpc","s"},
- {buildin_disablenpc,"disablenpc","s"},
- {buildin_enablearena,"enablearena",""}, // Added by RoVeRT
- {buildin_disablearena,"disablearena",""}, // Added by RoVeRT
- {buildin_hideoffnpc,"hideoffnpc","s"},
- {buildin_hideonnpc,"hideonnpc","s"},
- {buildin_sc_start,"sc_start","iii*"},
- {buildin_sc_start2,"sc_start2","iiii*"},
- {buildin_sc_start4,"sc_start4","iiiiii*"},
- {buildin_sc_end,"sc_end","i"},
- {buildin_getscrate,"getscrate","ii*"},
- {buildin_debugmes,"debugmes","s"},
- {buildin_catchpet,"pet","i"},
- {buildin_birthpet,"bpet",""},
- {buildin_resetlvl,"resetlvl","i"},
- {buildin_resetstatus,"resetstatus",""},
- {buildin_resetskill,"resetskill",""},
- {buildin_skillpointcount,"skillpointcount",""},
- {buildin_changebase,"changebase","i"},
- {buildin_changesex,"changesex",""},
- {buildin_waitingroom,"waitingroom","si*"},
- {buildin_warpwaitingpc,"warpwaitingpc","sii"},
- {buildin_delwaitingroom,"delwaitingroom","*"},
- {buildin_enablewaitingroomevent,"enablewaitingroomevent","*"},
- {buildin_disablewaitingroomevent,"disablewaitingroomevent","*"},
- {buildin_getwaitingroomstate,"getwaitingroomstate","i*"},
- {buildin_warpwaitingpc,"warpwaitingpc","sii*"},
- {buildin_attachrid,"attachrid","i"},
- {buildin_detachrid,"detachrid",""},
- {buildin_isloggedin,"isloggedin","i"},
- {buildin_setmapflagnosave,"setmapflagnosave","ssii"},
- {buildin_setmapflag,"setmapflag","si*"},
- {buildin_removemapflag,"removemapflag","si"},
- {buildin_pvpon,"pvpon","s"},
- {buildin_pvpoff,"pvpoff","s"},
- {buildin_gvgon,"gvgon","s"},
- {buildin_gvgoff,"gvgoff","s"},
- {buildin_emotion,"emotion","i*"},
- {buildin_maprespawnguildid,"maprespawnguildid","sii"},
- {buildin_agitstart,"agitstart",""}, // <Agit>
- {buildin_agitend,"agitend",""},
- {buildin_agitcheck,"agitcheck","i"}, // <Agitcheck>
- {buildin_flagemblem,"flagemblem","i"}, // Flag Emblem
- {buildin_getcastlename,"getcastlename","s"},
- {buildin_getcastledata,"getcastledata","si*"},
- {buildin_setcastledata,"setcastledata","sii"},
- {buildin_requestguildinfo,"requestguildinfo","i*"},
- {buildin_getequipcardcnt,"getequipcardcnt","i"},
- {buildin_successremovecards,"successremovecards","i"},
- {buildin_failedremovecards,"failedremovecards","ii"},
- {buildin_marriage,"marriage","s"},
- {buildin_wedding_effect,"wedding",""},
- {buildin_divorce,"divorce",""},
- {buildin_ispartneron,"ispartneron",""},
- {buildin_getpartnerid,"getpartnerid",""},
- {buildin_getchildid,"getchildid",""},
- {buildin_getmotherid,"getmotherid",""},
- {buildin_getfatherid,"getfatherid",""},
- {buildin_warppartner,"warppartner","sii"},
- {buildin_getitemname,"getitemname","i"},
- {buildin_getitemslots,"getitemslots","i"},
- {buildin_makepet,"makepet","i"},
- {buildin_getexp,"getexp","ii"},
- {buildin_getinventorylist,"getinventorylist",""},
- {buildin_getskilllist,"getskilllist",""},
- {buildin_clearitem,"clearitem",""},
- {buildin_classchange,"classchange","ii"},
- {buildin_misceffect,"misceffect","i"},
- {buildin_soundeffect,"soundeffect","si"},
- {buildin_soundeffectall,"soundeffectall","si*"}, // SoundEffectAll [Codemaster]
- {buildin_strmobinfo,"strmobinfo","ii"}, // display mob data [Valaris]
- {buildin_guardian,"guardian","siisii*i"}, // summon guardians
- {buildin_guardianinfo,"guardianinfo","i"}, // display guardian data [Valaris]
- {buildin_petskillbonus,"petskillbonus","iiii"}, // [Valaris]
- {buildin_petrecovery,"petrecovery","ii"}, // [Valaris]
- {buildin_petloot,"petloot","i"}, // [Valaris]
- {buildin_petheal,"petheal","iiii"}, // [Valaris]
-// {buildin_petmag,"petmag","iiii"}, // [Valaris]
- {buildin_petskillattack,"petskillattack","iiii"}, // [Skotlex]
- {buildin_petskillattack2,"petskillattack2","iiiii"}, // [Valaris]
- {buildin_petskillsupport,"petskillsupport","iiiii"}, // [Skotlex]
- {buildin_skilleffect,"skilleffect","ii"}, // skill effect [Celest]
- {buildin_npcskilleffect,"npcskilleffect","iiii"}, // npc skill effect [Valaris]
- {buildin_specialeffect,"specialeffect","i*"}, // npc skill effect [Valaris]
- {buildin_specialeffect2,"specialeffect2","i*"}, // skill effect on players[Valaris]
- {buildin_nude,"nude",""}, // nude command [Valaris]
- {buildin_mapwarp,"mapwarp","ssii"}, // Added by RoVeRT
- {buildin_inittimer,"inittimer",""},
- {buildin_stoptimer,"stoptimer",""},
- {buildin_cmdothernpc,"cmdothernpc","ss"},
- {buildin_atcommand,"atcommand","*"}, // [MouseJstr]
- {buildin_charcommand,"charcommand","*"}, // [MouseJstr]
- {buildin_movenpc,"movenpc","sii"}, // [MouseJstr]
- {buildin_message,"message","s*"}, // [MouseJstr]
- {buildin_npctalk,"npctalk","*"}, // [Valaris]
- {buildin_hasitems,"hasitems","*"}, // [Valaris]
- {buildin_mobcount,"mobcount","ss"},
- {buildin_getlook,"getlook","i"},
- {buildin_getsavepoint,"getsavepoint","i"},
- {buildin_npcspeed,"npcspeed","i"}, // [Valaris]
- {buildin_npcwalkto,"npcwalkto","ii"}, // [Valaris]
- {buildin_npcstop,"npcstop",""}, // [Valaris]
- {buildin_getmapxy,"getmapxy","siii*"}, //by Lorky [Lupus]
- {buildin_checkoption1,"checkoption1","i"},
- {buildin_checkoption2,"checkoption2","i"},
- {buildin_guildgetexp,"guildgetexp","i"},
- {buildin_guildchangegm,"guildchangegm","is"},
- {buildin_logmes,"logmes","s"}, //this command actls as MES but rints info into LOG file either SQL/TXT [Lupus]
- {buildin_summon,"summon","si*"}, // summons a slave monster [Celest]
- {buildin_isnight,"isnight",""}, // check whether it is night time [Celest]
- {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]
- {buildin_cardscnt,"cardscnt","i*"}, // check how many items/cards are being equipped in the same arm [Lupus]
- {buildin_getrefine,"getrefine","*"}, // returns the refined number of the current item, or an item with index specified [celest]
- {buildin_adopt,"adopt","sss"}, // allows 2 parents to adopt a child
- {buildin_night,"night",""}, // sets the server to night time
- {buildin_day,"day",""}, // sets the server to day time
-#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
- {buildin_dispbottom,"dispbottom","s"}, //added from jA [Lupus]
- {buildin_getusersname,"getusersname","*"},
- {buildin_recovery,"recovery",""},
- {buildin_getpetinfo,"getpetinfo","i"},
- {buildin_checkequipedcard,"checkequipedcard","i"},
- {buildin_jump_zero,"jump_zero","ii"}, //for future jA script compatibility
- {buildin_select,"select","*"}, //for future jA script compatibility
- {buildin_globalmes,"globalmes","s*"},
- {buildin_getmapmobs,"getmapmobs","s"}, //end jA addition
- {buildin_unequip,"unequip","i"}, // unequip command [Spectre]
- {buildin_getstrlen,"getstrlen","s"}, //strlen [Valaris]
- {buildin_charisalpha,"charisalpha","si"}, //isalpha [Valaris]
- {buildin_fakenpcname,"fakenpcname","ssi"}, // [Lance]
- {buildin_compare,"compare","ss"}, // Lordalfa - To bring strstr to scripting Engine.
- {buildin_getiteminfo,"getiteminfo","ii"}, //[Lupus] returns Items Buy / sell Price, etc info
- {buildin_getequipcardid,"getequipcardid","ii"}, //[Lupus] returns CARD ID or other info from CARD slot N of equipped item
- // [zBuffer] List of mathematics commands --->
- {buildin_sqrt,"sqrt","i"},
- {buildin_pow,"pow","ii"},
- {buildin_distance,"distance","iiii"},
- {buildin_checkcell,"checkcell","siii"},
- // <--- [zBuffer] List of mathematics commands
- // [zBuffer] List of dynamic var commands --->
- {buildin_getd,"getd","*"},
- {buildin_setd,"setd","*"},
- // <--- [zBuffer] List of dynamic var commands
- {buildin_petstat,"petstat","i"},
- {buildin_callshop,"callshop","si"}, // [Skotlex]
- {buildin_npcshopitem,"npcshopitem","sii*"}, // [Lance]
- {buildin_npcshopadditem,"npcshopadditem","sii*"},
- {buildin_npcshopdelitem,"npcshopdelitem","si*"},
- {buildin_equip,"equip","i"},
- {buildin_autoequip,"autoequip","ii"},
- {buildin_setbattleflag,"setbattleflag","ss"},
- {buildin_getbattleflag,"getbattleflag","s"},
- {buildin_setitemscript,"setitemscript","is"}, //Set NEW item bonus script. Lupus
- {buildin_disguise,"disguise","i"}, //disguise player. Lupus
- {buildin_undisguise,"undisguise","i"}, //undisguise player. Lupus
- {buildin_getmonsterinfo,"getmonsterinfo","ii"}, //Lupus
- // [zBuffer] List of player cont commands --->
- {buildin_rid2name,"rid2name","i"},
- {buildin_pcfollow,"pcfollow","ii"},
- {buildin_pcstopfollow,"pcstopfollow","i"},
- {buildin_pcblockmove,"pcblockmove","ii"},
- // <--- [zBuffer] List of player cont commands
- // [zBuffer] List of mob control commands --->
- {buildin_mobspawn,"mobspawn","*"},
- {buildin_mobremove,"mobremove","i"},
- {buildin_getmobdata,"getmobdata","i*"},
- {buildin_setmobdata,"setmobdata","iii"},
- {buildin_mobassist,"mobassist","i*"},
- {buildin_mobattach,"mobattach","i*"},
- {buildin_unitwalk,"unitwalk","i*"},
- {buildin_unitkill,"unitkill","i"},
- {buildin_unitwarp,"unitwarp","isii"},
- {buildin_unitattack,"unitattack","i*"},
- {buildin_unitstop,"unitstop","i"},
- {buildin_unittalk,"unittalk","is"},
- {buildin_unitemote,"unitemote","ii"},
- {buildin_unitdeadsit,"unitdeadsit","ii"},
- {buildin_unitskilluseid,"unitskilluseid","iii*"}, // originally by Qamera [Celest]
- {buildin_unitskillusepos,"unitskillusepos","iiiii"}, // [Celest]
-// <--- [zBuffer] List of mob control commands
- {buildin_sleep,"sleep","i"},
- {buildin_sleep2,"sleep2","i"},
- {buildin_awake,"awake","s"},
- {buildin_getvariableofnpc,"getvariableofnpc","is"},
- // [blackhole89] -->
- {buildin_warpportal,"warpportal","iisii"},
- // <--- [blackhole89]
- {buildin_homunculus_evolution,"homevolution",""}, //[orn]
- {NULL,NULL,NULL},
-};
-
enum {
C_NOP,C_POS,C_INT,C_PARAM,C_FUNC,C_STR,C_CONSTSTR,C_ARG,
C_NAME,C_EOL, C_RETINFO,
@@ -800,6 +159,53 @@ enum {
C_XOR,C_OR,C_AND,C_ADD,C_SUB,C_MUL,C_DIV,C_MOD,C_NEG,C_LNOT,C_NOT,C_R_SHIFT,C_L_SHIFT
};
+enum {
+ MF_NOMEMO,
+ MF_NOTELEPORT,
+ MF_NOSAVE,
+ MF_NOBRANCH,
+ MF_NOPENALTY,
+ MF_NOZENYPENALTY,
+ MF_PVP,
+ MF_PVP_NOPARTY,
+ MF_PVP_NOGUILD,
+ MF_GVG,
+ MF_GVG_NOPARTY,
+ MF_NOTRADE,
+ MF_NOSKILL,
+ MF_NOWARP,
+ MF_FREE,
+ MF_NOICEWALL,
+ MF_SNOW,
+ MF_FOG,
+ MF_SAKURA,
+ MF_LEAVES,
+ MF_RAIN,
+ MF_INDOORS,
+ MF_NOGO,
+ MF_CLOUDS,
+ MF_CLOUDS2,
+ MF_FIREWORKS,
+ MF_GVG_CASTLE,
+ MF_GVG_DUNGEON,
+ MF_NIGHTENABLED,
+ MF_NOBASEEXP,
+ MF_NOJOBEXP,
+ MF_NOMOBLOOT,
+ MF_NOMVPLOOT,
+ MF_NORETURN,
+ MF_NOWARPTO,
+ MF_NIGHTMAREDROP,
+ MF_RESTRICTED,
+ MF_NOCOMMAND,
+ MF_NODROP,
+ MF_JEXP,
+ MF_BEXP,
+ MF_NOVENDING,
+ MF_LOADEVENT,
+ MF_NOCHAT
+};
+
//Reports on the console the src of an script error.
static void report_src(struct script_state *st) {
struct block_list *bl;
@@ -898,7 +304,7 @@ int add_str(const unsigned char *p)
}
if(str_num>=str_data_size){
str_data_size+=128;
- str_data=(struct str_data_struct *) aRealloc(str_data,sizeof(str_data[0])*str_data_size);
+ str_data=aRealloc(str_data,sizeof(str_data[0])*str_data_size);
memset(str_data + (str_data_size - 128), '\0', 128);
}
while(str_pos+(int)strlen((char *) p)+1>=str_size){
@@ -936,11 +342,16 @@ static void check_script_buf(int size)
* スクリプトバッファに1バイト書き込む
*------------------------------------------
*/
+
+#define add_scriptb(a) if( script_pos+1>=script_size ) check_script_buf(1); script_buf[script_pos++]=(a);
+
+#if 0
static void add_scriptb(int a)
{
check_script_buf(1);
script_buf[script_pos++]=a;
}
+#endif
/*==========================================
* スクリプトバッファにデータタイプを書き込む
@@ -1063,59 +474,27 @@ static unsigned char *skip_word(unsigned char *p)
if(*p=='#') p++; // account変数用
if(*p=='#') p++; // ワールドaccount変数用
- while(isalnum(*p)||*p=='_'|| *p>=0x81)
+ while(isalnum(*p)||*p=='_'|| *p>=0x81) {
if(*p>=0x81 && p[1]){
p+=2;
} else
p++;
-
+ }
// postfix
if(*p=='$') p++; // 文字列変数
return p;
}
-static unsigned char *startptr;
-static int startline;
-
/*==========================================
* エラーメッセージ出力
*------------------------------------------
*/
-static void disp_error_message(const char *mes,const unsigned char *pos)
+static void disp_error_message(const char *mes,unsigned char *pos)
{
- int line,c=0,i;
- unsigned char *p,*linestart,*lineend;
-
- for(line=startline,p=startptr;p && *p;line++){
- linestart=p;
- lineend=(unsigned char *) strchr((char *) p,'\n');
- if(lineend){
- c=*lineend;
- *lineend=0;
- }
- if(lineend==NULL || pos<lineend){
- fprintf(stderr, "\r"); //To not printout the error next to the spinner...
- ShowError(" "); //Better error display [Skotlex]
- if (current_file) {
- printf("%s in "CL_WHITE"\'%s\'"CL_RESET" line "CL_WHITE"\'%d\'"CL_RESET" : ", mes, current_file, line);
- } else {
- printf("%s line "CL_WHITE"\'%d\'"CL_RESET" : ", mes, line);
- }
- for(i=0;(linestart[i]!='\r') && (linestart[i]!='\n') && linestart[i];i++){
- if(linestart+i!=pos)
- printf("%c",linestart[i]);
- else
- printf("\'%c\'",linestart[i]);
- }
- printf("\a\n");
- if(lineend)
- *lineend=c;
- return;
- }
- *lineend=c;
- p=lineend+1;
- }
+ error_msg = aStrdup(mes);
+ error_pos = pos;
+ longjmp( error_jump, 1 );
}
/*==========================================
@@ -1136,7 +515,6 @@ unsigned char* parse_simpleexpr(unsigned char *p)
exit(1);
}
if(*p=='('){
-
p=parse_subexpr(p+1,-1);
p=skip_space(p);
if((*p++)!=')'){
@@ -1170,7 +548,8 @@ unsigned char* parse_simpleexpr(unsigned char *p)
int c,l;
char *p2;
// label , register , function etc
- if(skip_word(p)==p && !(*p==')' && p[-1]=='(')){
+ //From what I read, jA figured a better way to handle empty parenthesis '()'
+ if(skip_word(p)==p/* && !(*p==')' && p[-1]=='(')*/){
disp_error_message("unexpected character",p);
exit(1);
}
@@ -1189,6 +568,7 @@ unsigned char* parse_simpleexpr(unsigned char *p)
add_scriptl(search_str((unsigned char *) "getelementofarray"));
add_scriptc(C_ARG);
add_scriptl(l);
+
p=parse_subexpr(p+1,-1);
p=skip_space(p);
if((*p++)!=']'){
@@ -1242,7 +622,8 @@ unsigned char* parse_subexpr(unsigned char *p,int limit)
} else
p=parse_simpleexpr(p);
p=skip_space(p);
- while(((op=C_ADD,opl=6,len=1,*p=='+') ||
+ while((
+ (op=C_ADD,opl=6,len=1,*p=='+') ||
(op=C_SUB,opl=6,len=1,*p=='-') ||
(op=C_MUL,opl=7,len=1,*p=='*') ||
(op=C_DIV,opl=7,len=1,*p=='/') ||
@@ -1281,7 +662,7 @@ unsigned char* parse_subexpr(unsigned char *p,int limit)
}
func=parse_cmd;
- do {
+ while(*p && *p!=')' && i<128) {
plist[i]=(char *) p;
p=parse_subexpr(p,-1);
p=skip_space(p);
@@ -1291,14 +672,14 @@ unsigned char* parse_subexpr(unsigned char *p,int limit)
}
p=skip_space(p);
i++;
- } while(*p && *p!=')' && i<128);
+ };
plist[i]=(char *) p;
if(*(p++)!=')'){
disp_error_message("func request '(' ')'",p);
exit(1);
}
- if (str_data[func].type == C_FUNC && script_config.warn_func_mismatch_paramnum) {
+ if( str_data[func].type==C_FUNC && script_config.warn_func_mismatch_paramnum){
const char *arg = buildin_func[str_data[func].val].arg;
int j = 0;
for (; arg[j]; j++) if (arg[j] == '*') break;
@@ -1335,6 +716,12 @@ unsigned char* parse_expr(unsigned char *p)
disp_error_message("unexpected char",p);
exit(1);
}
+ if(*p == '(') {
+ unsigned char *p2 = skip_space(p + 1);
+ if(*p2 == ')') {
+ return p2 + 1;
+ }
+ }
p=parse_subexpr(p,-1);
#ifdef DEBUG_FUNCIN
if(battle_config.etc_log)
@@ -1355,8 +742,13 @@ unsigned char* parse_line(unsigned char *p)
char end;
p=skip_space(p);
- if(*p==';')
- return p + 1;
+ if(*p==';') {
+ // if(); for(); while(); のために閉じ判定
+ p = parse_syntax_close(p);
+ return p+1;
+ }
+ if(*p==')' && parse_syntax_for_flag)
+ return p+1;
p = skip_space(p);
if(p[0] == '{') {
@@ -1398,7 +790,7 @@ unsigned char* parse_line(unsigned char *p)
} else {
end = ';';
}
- while(p && *p && *p!=end && i<128){
+ while(p && *p && *p != end && i<128){
plist[i]=(char *) p;
p=parse_expr(p);
@@ -1437,12 +829,9 @@ unsigned char* parse_line(unsigned char *p)
disp_error_message("illegal number of parameters",(unsigned char *) (plist[(i<j)?i:j]));
}
}
-
-
return p;
}
-
// { ... } の閉じ処理
unsigned char* parse_curly_close(unsigned char *p) {
if(syntax.curly_count <= 0) {
@@ -1505,8 +894,8 @@ unsigned char* parse_curly_close(unsigned char *p) {
}
// 構文関連の処理
-// break, case, continue, default, do, for, function,
-// if, switch, while をこの内部で処理します。
+// break, case, continue, default, do, for, function,
+// if, switch, while をこの内部で処理します。
unsigned char* parse_syntax(unsigned char *p) {
switch(p[0]) {
case 'b':
@@ -1644,10 +1033,10 @@ unsigned char* parse_syntax(unsigned char *p) {
if(!strncmp(p,"default",7) && !isalpha(*(p + 7))) {
// switch - default の処理
if(syntax.curly_count <= 0 || syntax.curly[syntax.curly_count - 1].type != TYPE_SWITCH) {
- disp_error_message("unexpected 'delault'",p);
+ disp_error_message("unexpected 'default'",p);
return p+1;
} else if(syntax.curly[syntax.curly_count - 1].flag) {
- disp_error_message("dup 'delault'",p);
+ disp_error_message("dup 'default'",p);
return p+1;
} else {
char label[256];
@@ -1745,6 +1134,7 @@ unsigned char* parse_syntax(unsigned char *p) {
}
set_label(l,script_pos);
+ p=skip_space(p);
if(*p == ';') {
// for(;;) のパターンなので必ず真
;
@@ -1780,7 +1170,7 @@ unsigned char* parse_syntax(unsigned char *p) {
set_label(l,script_pos);
// 次のループに入る時の処理
- // for 最後の '(' を ';' として扱うフラグ
+ // for 最後の ')' を ';' として扱うフラグ
parse_syntax_for_flag = 1;
syntax.curly[syntax.curly_count++].type = TYPE_NULL;
p=parse_line(p);
@@ -1949,8 +1339,8 @@ unsigned char* parse_syntax_close(unsigned char *p) {
}
// if, for , while , do の閉じ判定
-// flag == 1 : 閉じられた
-// flag == 0 : 閉じられない
+// flag == 1 : 閉じられた
+// flag == 0 : 閉じられない
unsigned char* parse_syntax_close_sub(unsigned char *p,int *flag) {
unsigned char label[256];
int pos = syntax.curly_count - 1;
@@ -2185,123 +1575,197 @@ static void read_constdb(void)
}
/*==========================================
+ * エラー表示
+ *------------------------------------------
+ */
+
+const char* script_print_line( const char *p, const char *mark, int line );
+
+void script_error(char *src,const char *file,int start_line, const char *error_msg, const char *error_pos) {
+ // エラーが発生した行を求める
+ int j;
+ int line = start_line;
+ const char *p;
+ const char *linestart[5] = { NULL, NULL, NULL, NULL, NULL };
+
+ for(p=src;p && *p;line++){
+ char *lineend=strchr(p,'\n');
+ if(lineend==NULL || error_pos<lineend){
+ break;
+ }
+ for( j = 0; j < 4; j++ ) {
+ linestart[j] = linestart[j+1];
+ }
+ linestart[4] = p;
+ p=lineend+1;
+ }
+
+ printf("\a\n");
+ printf("script error on %s line %d\n", file, line);
+ printf(" %s\n", error_msg);
+ for(j = 0; j < 5; j++ ) {
+ script_print_line( linestart[j], NULL, line + j - 5);
+ }
+ p = script_print_line( p, error_pos, -line);
+ for(j = 0; j < 5; j++) {
+ p = script_print_line( p, NULL, line + j + 1 );
+ }
+}
+
+const char* script_print_line( const char *p, const char *mark, int line ) {
+ int i;
+ if( p == NULL || !p[0] ) return NULL;
+ if( line < 0 )
+ printf("*% 5d : ", -line);
+ else
+ printf(" % 5d : ", line);
+ for(i=0;p[i] && p[i] != '\n';i++){
+ if(p + i != mark)
+ printf("%c",p[i]);
+ else
+ printf("\'%c\'",p[i]);
+ }
+ printf("\n");
+ return p+i+(p[i] == '\n' ? 1 : 0);
+}
+
+/*==========================================
* スクリプトの解析
*------------------------------------------
*/
-struct script_code* parse_script(unsigned char *src,int line)
+
+struct script_code* parse_script(unsigned char *src,const char *file,int line)
{
- unsigned char *p, *tmpp;
+ unsigned char *p,*tmpp;
int i;
struct script_code *code;
- static int first = 1;
+ static int first=1;
- if (first) {
+ memset(&syntax,0,sizeof(syntax));
+ if(first){
add_buildin_func();
read_constdb();
}
- first = 0;
+ first=0;
-//////////////////////////////////////////////
-// additional check on the input to filter empty scripts ("{}" and "{ }")
- p = src;
- p = skip_space(p);
- if (*p != '{') {
- disp_error_message("not found '{'", p);
+ script_buf=(unsigned char *)aCalloc(SCRIPT_BLOCK_SIZE,sizeof(unsigned char));
+ script_pos=0;
+ script_size=SCRIPT_BLOCK_SIZE;
+ str_data[LABEL_NEXTLINE].type=C_NOP;
+ str_data[LABEL_NEXTLINE].backpatch=-1;
+ str_data[LABEL_NEXTLINE].label=-1;
+ for(i=LABEL_START;i<str_num;i++){
+ if(
+ str_data[i].type==C_POS || str_data[i].type==C_NAME ||
+ str_data[i].type==C_USERFUNC || str_data[i].type == C_USERFUNC_POS
+ ){
+ str_data[i].type=C_NOP;
+ str_data[i].backpatch=-1;
+ str_data[i].label=-1;
+ }
+ }
+
+ //Labels must be reparsed for the script....
+ scriptlabel_db->clear(scriptlabel_db, NULL);
+ if( setjmp( error_jump ) != 0 ) {
+ //Restore program state when script has problems. [from jA]
+ script_error(src,file,line,error_msg,error_pos);
+ aFree( error_msg );
+ aFree( script_buf );
+ script_pos = 0;
+ script_size = 0;
+ script_buf = NULL;
+ for(i=LABEL_START;i<str_num;i++){
+ if(str_data[i].type == C_NOP) str_data[i].type = C_NAME;
+ }
return NULL;
}
+
+ p=src;
+ p=skip_space(p);
+ if(*p!='{'){
+ disp_error_message("not found '{'",p);
+ exit(1);
+ }
p++;
p = skip_space(p);
- if (*p == '}') {
+ if (p && *p == '}') {
// an empty function, just return
+ aFree( script_buf );
+ script_pos = 0;
+ script_size = 0;
+ script_buf = NULL;
return NULL;
}
- script_buf = (unsigned char *) aCallocA(SCRIPT_BLOCK_SIZE, sizeof(unsigned char));
- script_pos = 0;
- script_size = SCRIPT_BLOCK_SIZE;
- str_data[LABEL_NEXTLINE].type = C_NOP;
- str_data[LABEL_NEXTLINE].backpatch = -1;
- str_data[LABEL_NEXTLINE].label = -1;
- for (i = LABEL_START; i < str_num; i++) {
- if (
- str_data[i].type == C_POS || str_data[i].type == C_NAME ||
- str_data[i].type == C_USERFUNC || str_data[i].type == C_USERFUNC_POS
- ) {
- str_data[i].type = C_NOP;
- str_data[i].backpatch = -1;
- str_data[i].label = -1;
- }
- }
-
- //Labels must be reparsed for the script....
- scriptlabel_db->clear(scriptlabel_db, NULL);
- // for error message
- startptr = src;
- startline = line;
-
- while (p && *p && (*p != '}' || syntax.curly_count != 0)) {
- p = skip_space(p);
+ while (p && *p && (*p!='}' || syntax.curly_count != 0)) {
+ p=skip_space(p);
// labelだけ特殊処理
- tmpp = skip_space(skip_word(p));
- if (*tmpp == ':' && !(!strncmp(p,"default",7) && !isalpha(*(p + 7)))) {
- int l, c;
- c = *skip_word(p);
- *skip_word(p) = 0;
- l = add_str(p);
- if (str_data[l].label != -1) {
- *skip_word(p) = c;
- disp_error_message("dup label ", p);
+ tmpp=skip_space(skip_word(p));
+ if(*tmpp==':' && !(!strncmp(p,"default:",8) && p + 7 == tmpp)){
+ int l,c;
+
+ c=*skip_word(p);
+ *skip_word(p)=0;
+ if(*p == 0) {
+ *skip_word(p)=c;
+ disp_error_message("label length 0 ",p);
+ exit(1);
+ }
+ l=add_str(p);
+ if(str_data[l].label!=-1){
+ *skip_word(p)=c;
+ disp_error_message("dup label ",p);
exit(1);
}
- set_label(l, script_pos);
+ set_label(l,script_pos);
strdb_put(scriptlabel_db, p, (void*)script_pos); // 外部用label db登録
- *skip_word(p) = c;
- p = tmpp + 1;
+ *skip_word(p)=c;
+ p=tmpp+1;
continue;
}
// 他は全部一緒くた
- p = parse_line(p);
- p = skip_space(p);
+ p=parse_line(p);
+ p=skip_space(p);
add_scriptc(C_EOL);
- set_label(LABEL_NEXTLINE, script_pos);
- str_data[LABEL_NEXTLINE].type = C_NOP;
- str_data[LABEL_NEXTLINE].backpatch = -1;
- str_data[LABEL_NEXTLINE].label = -1;
+ set_label(LABEL_NEXTLINE,script_pos);
+ str_data[LABEL_NEXTLINE].type=C_NOP;
+ str_data[LABEL_NEXTLINE].backpatch=-1;
+ str_data[LABEL_NEXTLINE].label=-1;
}
add_scriptc(C_NOP);
script_size = script_pos;
- script_buf = (unsigned char *)aRealloc(script_buf, script_pos + 1);
+ script_buf=(unsigned char *)aRealloc(script_buf,script_pos);
// 未解決のラベルを解決
- for (i = LABEL_START; i < str_num; i++) {
- if (str_data[i].type == C_NOP) {
- int j, next;
- str_data[i].type = C_NAME;
- str_data[i].label = i;
- for (j = str_data[i].backpatch; j >= 0 && j != 0x00ffffff; ) {
- next = (*(int*)(script_buf+j)) & 0x00ffffff;
- script_buf[j] = i;
- script_buf[j+1] = i>>8;
- script_buf[j+2] = i>>16;
- j = next;
+ for(i=LABEL_START;i<str_num;i++){
+ if(str_data[i].type==C_NOP){
+ int j,next;
+ str_data[i].type=C_NAME;
+ str_data[i].label=i;
+ for(j=str_data[i].backpatch;j>=0 && j!=0x00ffffff;){
+ next=(*(int*)(script_buf+j)) & 0x00ffffff;
+ script_buf[j]=i;
+ script_buf[j+1]=i>>8;
+ script_buf[j+2]=i>>16;
+ j=next;
}
}
}
#ifdef DEBUG_DISP
- for (i = 0; i < script_pos; i++) {
- if ((i & 15) == 0) printf("%04x : ", i);
- printf("%02x ", script_buf[i]);
- if((i&15) == 15) printf("\n");
+ for(i=0;i<script_pos;i++){
+ if((i&15)==0) printf("%04x : ",i);
+ printf("%02x ",script_buf[i]);
+ if((i&15)==15) printf("\n");
}
printf("\n");
#endif
- startptr = NULL; //Clear pointer to prevent future references to a src that may be free'd. [Skotlex]
code = aCalloc(1, sizeof(struct script_code));
code->script_buf = script_buf;
code->script_size = script_size;
@@ -2350,7 +1814,7 @@ int get_val(struct script_state*st,struct script_data* data)
data->type=C_CONSTSTR;
if( prefix=='@'){
if(sd)
- data->u.str = pc_readregstr(sd,data->u.num);
+ data->u.str = pc_readregstr(sd,data->u.num);
}else if(prefix=='$'){
data->u.str = (char *)idb_get(mapregstr_db,data->u.num);
}else if(prefix=='#'){
@@ -2389,19 +1853,19 @@ int get_val(struct script_state*st,struct script_data* data)
data->u.num = str_data[data->u.num&0x00ffffff].val;
}else if(str_data[data->u.num&0x00ffffff].type==C_PARAM){
if(sd)
- data->u.num = pc_readparam(sd,str_data[data->u.num&0x00ffffff].val);
+ data->u.num = pc_readparam(sd,str_data[data->u.num&0x00ffffff].val);
}else if(prefix=='@'){
if(sd)
- data->u.num = pc_readreg(sd,data->u.num);
+ data->u.num = pc_readreg(sd,data->u.num);
}else if(prefix=='$'){
data->u.num = (int)idb_get(mapreg_db,data->u.num);
}else if(prefix=='#'){
if( name[1]=='#'){
if(sd)
- data->u.num = pc_readaccountreg2(sd,name);
+ data->u.num = pc_readaccountreg2(sd,name);
}else{
if(sd)
- data->u.num = pc_readaccountreg(sd,name);
+ data->u.num = pc_readaccountreg(sd,name);
}
}else if(prefix=='.'){
struct linkdb_node **n;
@@ -2415,7 +1879,7 @@ int get_val(struct script_state*st,struct script_data* data)
data->u.num = (int)linkdb_search(n, (void*)data->u.num);
}else{
if(sd)
- data->u.num = pc_readglobalreg(sd,name);
+ data->u.num = pc_readglobalreg(sd,name);
}
}
}
@@ -2430,7 +1894,7 @@ void* get_val2(struct script_state*st,int num,struct linkdb_node **ref)
struct script_data dat;
dat.type=C_NAME;
dat.u.num=num;
- dat.ref = ref;
+ dat.ref=ref;
get_val(st,&dat);
if( dat.type==C_INT ) return (void*)dat.u.num;
else return (void*)dat.u.str;
@@ -2476,10 +1940,6 @@ static int set_reg(struct script_state*st,struct map_session_data *sd,int num,ch
}else{
pc_setglobalreg_str(sd,name,str);
} // [zBuffer]
-
- /*else{
- ShowWarning("script: set_reg: illegal scope string variable !");
- }*/
}else{
// 数値
int val = (int)v;
@@ -2676,17 +2136,13 @@ void script_free_vars(struct linkdb_node **node) {
* Free's the whole stack. Invoked when clearing a character. [Skotlex]
*------------------------------------------
*/
-void script_free_stack(struct script_stack* stack)
-{
+void script_free_stack(struct script_stack *stack) {
int i;
- for (i = 0; i < stack->sp; i++)
- {
- if(stack->stack_data[i].type==C_STR)
- {
- //ShowDebug ("script_free_stack: freeing %p at sp=%d.\n", stack->stack_data[i].u.str, i);
+ for(i = 0; i < stack->sp; i++) {
+ if( stack->stack_data[i].type == C_STR ) {
aFree(stack->stack_data[i].u.str);
stack->stack_data[i].type = C_INT;
- }else if( i > 0 && stack->stack_data[i].type == C_RETINFO ) {
+ } else if( i > 0 && stack->stack_data[i].type == C_RETINFO ) {
struct linkdb_node** n = (struct linkdb_node**)stack->stack_data[i-1].u.num;
script_free_vars( n );
aFree( n );
@@ -2694,8 +2150,8 @@ void script_free_stack(struct script_stack* stack)
}
script_free_vars( stack->var_function );
aFree(stack->var_function);
- aFree (stack->stack_data);
- aFree (stack);
+ aFree(stack->stack_data);
+ aFree(stack);
}
void script_free_code(struct script_code* code) {
@@ -2704,49 +2160,1796 @@ void script_free_code(struct script_code* code) {
aFree( code );
}
-int axtoi(char *hexStg) {
- int n = 0; // position in string
- int m = 0; // position in digit[] to shift
- int count; // loop index
- int intValue = 0; // integer value of hex string
- int digit[11]; // hold values to convert
- while (n < 10) {
- if (hexStg[n]=='\0')
+//
+// 実行部main
+//
+/*==========================================
+ * コマンドの読み取り
+ *------------------------------------------
+ */
+static int unget_com_data=-1;
+int get_com(unsigned char *script,int *pos)
+{
+ int i,j;
+ if(unget_com_data>=0){
+ i=unget_com_data;
+ unget_com_data=-1;
+ return i;
+ }
+ if(script[*pos]>=0x80){
+ return C_INT;
+ }
+ i=0; j=0;
+ while(script[*pos]>=0x40){
+ i=script[(*pos)++]<<j;
+ j+=6;
+ }
+ return i+(script[(*pos)++]<<j);
+}
+
+/*==========================================
+ * コマンドのプッシュバック
+ *------------------------------------------
+ */
+void unget_com(int c)
+{
+ if(unget_com_data!=-1){
+ if(battle_config.error_log)
+ ShowError("unget_com can back only 1 data\n");
+ }
+ unget_com_data=c;
+}
+
+/*==========================================
+ * 数値の所得
+ *------------------------------------------
+ */
+int get_num(unsigned char *script,int *pos)
+{
+ int i,j;
+ i=0; j=0;
+ while(script[*pos]>=0xc0){
+ i+=(script[(*pos)++]&0x7f)<<j;
+ j+=6;
+ }
+ return i+((script[(*pos)++]&0x7f)<<j);
+}
+
+/*==========================================
+ * スタックから値を取り出す
+ *------------------------------------------
+ */
+int pop_val(struct script_state* st)
+{
+ if(st->stack->sp<=0)
+ return 0;
+ st->stack->sp--;
+ get_val(st,&(st->stack->stack_data[st->stack->sp]));
+ if(st->stack->stack_data[st->stack->sp].type==C_INT)
+ return st->stack->stack_data[st->stack->sp].u.num;
+ return 0;
+}
+
+int isstr(struct script_data *c) {
+ if( c->type == C_STR || c->type == C_CONSTSTR )
+ return 1;
+ else if( c->type == C_NAME ) {
+ char *p = str_buf + str_data[c->u.num & 0xffffff].str;
+ char postfix = p[strlen(p)-1];
+ return (postfix == '$');
+ }
+ return 0;
+}
+
+/*==========================================
+ * 加算演算子
+ *------------------------------------------
+ */
+void op_add(struct script_state* st)
+{
+ st->stack->sp--;
+ get_val(st,&(st->stack->stack_data[st->stack->sp]));
+ get_val(st,&(st->stack->stack_data[st->stack->sp-1]));
+
+ if(isstr(&st->stack->stack_data[st->stack->sp]) || isstr(&st->stack->stack_data[st->stack->sp-1])){
+ conv_str(st,&(st->stack->stack_data[st->stack->sp]));
+ conv_str(st,&(st->stack->stack_data[st->stack->sp-1]));
+ }
+ if(st->stack->stack_data[st->stack->sp].type==C_INT){ // ii
+ int *i1 = &st->stack->stack_data[st->stack->sp-1].u.num;
+ int *i2 = &st->stack->stack_data[st->stack->sp].u.num;
+ int ret = *i1 + *i2;
+ double ret_double = (double)*i1 + (double)*i2;
+ if(ret_double > INT_MAX|| ret_double < INT_MIN) {
+ ShowWarning("script::op_add overflow detected op:%d\n",C_ADD);
+ report_src(st);
+ ret = cap_value(ret, INT_MIN, INT_MAX);
+ }
+ *i1 = ret;
+ } else { // ssの予定
+ char *buf;
+ buf=(char *)aMallocA((strlen(st->stack->stack_data[st->stack->sp-1].u.str)+
+ strlen(st->stack->stack_data[st->stack->sp].u.str)+1)*sizeof(char));
+ strcpy(buf,st->stack->stack_data[st->stack->sp-1].u.str);
+ strcat(buf,st->stack->stack_data[st->stack->sp].u.str);
+ if(st->stack->stack_data[st->stack->sp-1].type==C_STR)
+ {
+ aFree(st->stack->stack_data[st->stack->sp-1].u.str);
+ st->stack->stack_data[st->stack->sp-1].type=C_INT;
+ }
+ if(st->stack->stack_data[st->stack->sp].type==C_STR)
+ {
+ aFree(st->stack->stack_data[st->stack->sp].u.str);
+ st->stack->stack_data[st->stack->sp].type=C_INT;
+ }
+ st->stack->stack_data[st->stack->sp-1].type=C_STR;
+ st->stack->stack_data[st->stack->sp-1].u.str=buf;
+ }
+ st->stack->stack_data[st->stack->sp-1].ref = NULL;
+}
+
+/*==========================================
+ * 二項演算子(文字列)
+ *------------------------------------------
+ */
+void op_2str(struct script_state *st,int op,int sp1,int sp2)
+{
+ char *s1=st->stack->stack_data[sp1].u.str,
+ *s2=st->stack->stack_data[sp2].u.str;
+ int a=0;
+
+ switch(op){
+ case C_EQ:
+ a= (strcmp(s1,s2)==0);
+ break;
+ case C_NE:
+ a= (strcmp(s1,s2)!=0);
+ break;
+ case C_GT:
+ a= (strcmp(s1,s2)> 0);
+ break;
+ case C_GE:
+ a= (strcmp(s1,s2)>=0);
+ break;
+ case C_LT:
+ a= (strcmp(s1,s2)< 0);
+ break;
+ case C_LE:
+ a= (strcmp(s1,s2)<=0);
+ break;
+ default:
+ ShowWarning("script: illegal string operator\n");
+ break;
+ }
+
+ // Because push_val() overwrite stack_data[sp1], C_STR on stack_data[sp1] won't be freed.
+ // So, call push_val() after freeing strings. [jA1783]
+ // push_val(st->stack,C_INT,a);
+ if(st->stack->stack_data[sp1].type==C_STR)
+ {
+ aFree(s1);
+ st->stack->stack_data[sp1].type=C_INT;
+ }
+ if(st->stack->stack_data[sp2].type==C_STR)
+ {
+ aFree(s2);
+ st->stack->stack_data[sp2].type=C_INT;
+ }
+ push_val(st->stack,C_INT,a);
+}
+
+/*==========================================
+ * 二項演算子(数値)
+ *------------------------------------------
+ */
+void op_2num(struct script_state *st,int op,int i1,int i2)
+{
+ int ret = 0;
+ double ret_double = 0;
+ switch(op){
+ case C_MOD: ret = i1 % i2; break;
+ case C_AND: ret = i1 & i2; break;
+ case C_OR: ret = i1 | i2; break;
+ case C_XOR: ret = i1 ^ i2; break;
+ case C_LAND: ret = (i1 && i2); break;
+ case C_LOR: ret = (i1 || i2); break;
+ case C_EQ: ret = (i1 == i2); break;
+ case C_NE: ret = (i1 != i2); break;
+ case C_GT: ret = (i1 > i2); break;
+ case C_GE: ret = (i1 >= i2); break;
+ case C_LT: ret = (i1 < i2); break;
+ case C_LE: ret = (i1 <= i2); break;
+ case C_R_SHIFT: ret = i1>>i2; break;
+ case C_L_SHIFT: ret = i1<<i2; break;
+ default:
+ switch(op) {
+ case C_SUB: ret = i1 - i2; ret_double = (double)i1 - (double)i2; break;
+ case C_MUL: ret = i1 * i2; ret_double = (double)i1 * (double)i2; break;
+ case C_DIV:
+ if(i2 == 0) {
+ printf("script::op_2num division by zero.\n");
+ ret = INT_MAX;
+ ret_double = 0; // doubleの精度が怪しいのでオーバーフロー対策を飛ばす
+ } else {
+ ret = i1 / i2; ret_double = (double)i1 / (double)i2;
+ }
break;
- if (hexStg[n] > 0x29 && hexStg[n] < 0x40 ) //if 0 to 9
- digit[n] = hexStg[n] & 0x0f; //convert to int
- else if (hexStg[n] >='a' && hexStg[n] <= 'f') //if a to f
- digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int
- else if (hexStg[n] >='A' && hexStg[n] <= 'F') //if A to F
- digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int
- else break;
- n++;
+ }
+ if(ret_double > INT_MAX || ret_double < INT_MIN) {
+ printf("script::op_2num overflow detected op:%d\n",op);
+ report_src(st);
+ ret = cap_value(ret_double,INT_MAX,INT_MIN);
+ }
}
- count = n;
- m = n - 1;
- n = 0;
- while(n < count) {
- // digit[n] is value of hex digit at position n
- // (m << 2) is the number of positions to shift
- // OR the bits into return value
- intValue = intValue | (digit[n] << (m << 2));
- m--; // adjust the position to set
- n++; // next digit to process
+ push_val(st->stack,C_INT,ret);
+}
+
+/*==========================================
+ * 二項演算子
+ *------------------------------------------
+ */
+void op_2(struct script_state *st,int op)
+{
+ int i1,i2;
+ char *s1=NULL,*s2=NULL;
+
+ i2=pop_val(st);
+ if( isstr(&st->stack->stack_data[st->stack->sp]) )
+ s2=st->stack->stack_data[st->stack->sp].u.str;
+
+ i1=pop_val(st);
+ if( isstr(&st->stack->stack_data[st->stack->sp]) )
+ s1=st->stack->stack_data[st->stack->sp].u.str;
+
+ if( s1!=NULL && s2!=NULL ){
+ // ss => op_2str
+ op_2str(st,op,st->stack->sp,st->stack->sp+1);
+ }else if( s1==NULL && s2==NULL ){
+ // ii => op_2num
+ op_2num(st,op,i1,i2);
+ }else{
+ // si,is => error
+ ShowWarning("script: op_2: int&str, str&int not allow.\n");
+ report_src(st);
+ if(s1 && st->stack->stack_data[st->stack->sp].type == C_STR)
+ {
+ aFree(s1);
+ st->stack->stack_data[st->stack->sp].type = C_INT;
+ }
+ if(s2 && st->stack->stack_data[st->stack->sp+1].type == C_STR)
+ {
+ aFree(s2);
+ st->stack->stack_data[st->stack->sp+1].type = C_INT;
+ }
+ push_val(st->stack,C_INT,0);
}
- return (intValue);
}
-// [Lance] Hex string to integer converter
-int buildin_axtoi(struct script_state *st)
+/*==========================================
+ * 単項演算子
+ *------------------------------------------
+ */
+void op_1num(struct script_state *st,int op)
{
- char *hex = conv_str(st,& (st->stack->stack_data[st->start+2]));
- push_val(st->stack, C_INT, axtoi(hex));
+ int i1;
+ i1=pop_val(st);
+ switch(op){
+ case C_NEG:
+ i1=-i1;
+ break;
+ case C_NOT:
+ i1=~i1;
+ break;
+ case C_LNOT:
+ i1=!i1;
+ break;
+ }
+ push_val(st->stack,C_INT,i1);
+}
+
+
+/*==========================================
+ * 関数の実行
+ *------------------------------------------
+ */
+int run_func(struct script_state *st)
+{
+ int i,start_sp,end_sp,func;
+
+ end_sp=st->stack->sp;
+#ifdef DEBUG_RUN
+ if(battle_config.etc_log) {
+ ShowDebug("run_func : %s? (%d(%d)) sp=%d (%d...%d)\n",str_buf+str_data[func].str, func, str_data[func].type, st->stack->sp, st->start, st->end);
+ ShowDebug("stack dump :");
+ for(i=0;i<end_sp;i++){
+ switch(st->stack->stack_data[i].type){
+ case C_INT:
+ printf(" int(%d)",st->stack->stack_data[i].u.num);
+ break;
+ case C_NAME:
+ printf(" name(%s)",str_buf+str_data[st->stack->stack_data[i].u.num & 0xffffff].str);
+ break;
+ case C_ARG:
+ printf(" arg");
+ break;
+ case C_POS:
+ printf(" pos(%d)",st->stack->stack_data[i].u.num);
+ break;
+ case C_STR:
+ printf(" str(%s)",st->stack->stack_data[i].u.str);
+ break;
+ case C_CONSTSTR:
+ printf(" cstr(%s)",st->stack->stack_data[i].u.str);
+ break;
+ default:
+ printf(" etc(%d,%d)",st->stack->stack_data[i].type,st->stack->stack_data[i].u.num);
+ }
+ }
+ printf("\n");
+ }
+#endif
+ for(i=end_sp-1;i>=0 && st->stack->stack_data[i].type!=C_ARG;i--);
+ if(i==0){
+ if(battle_config.error_log)
+ ShowError("function not found\n");
+// st->stack->sp=0;
+ st->state=END;
+ report_src(st);
+ return 1;
+ }
+ start_sp=i-1;
+ st->start=i-1;
+ st->end=end_sp;
+
+ func=st->stack->stack_data[st->start].u.num;
+ if(str_data[func].type!=C_FUNC ){
+ ShowMessage ("run_func: '"CL_WHITE"%s"CL_RESET"' (type %d) is not function and command!\n");
+// st->stack->sp=0;
+ st->state=END;
+ report_src(st);
+ return 1;
+ }
+#ifdef DEBUG_RUN
+ ShowDebug("run_func : %s (func_no : %d , func_type : %d pos : 0x%x)\n",
+ str_buf+str_data[func].str,func,str_data[func].type,st->pos
+ );
+#endif
+ if(str_data[func].func){
+ if (str_data[func].func(st)) //Report error
+ report_src(st);
+ } else {
+ if(battle_config.error_log)
+ ShowError("run_func : %s? (%d(%d))\n",str_buf+str_data[func].str,func,str_data[func].type);
+ push_val(st->stack,C_INT,0);
+ report_src(st);
+ }
+
+ // Stack's datum are used when re-run functions [Eoe]
+ if(st->state != RERUNLINE) {
+ pop_stack(st->stack,start_sp,end_sp);
+ }
+
+ if(st->state==RETFUNC){
+ // ユーザー定義関数からの復帰
+ int olddefsp=st->stack->defsp;
+ int i;
+
+ pop_stack(st->stack,st->stack->defsp,start_sp); // 復帰に邪魔なスタック削除
+ if(st->stack->defsp<5 || st->stack->stack_data[st->stack->defsp-1].type!=C_RETINFO){
+ ShowWarning("script:run_func(return) return without callfunc or callsub!\n");
+ st->state=END;
+ report_src(st);
+ return 1;
+ }
+ script_free_vars( st->stack->var_function );
+ aFree(st->stack->var_function);
+
+ i = conv_num(st,& (st->stack->stack_data[st->stack->defsp-5])); // 引数の数所得
+ st->pos=conv_num(st,& (st->stack->stack_data[st->stack->defsp-1])); // スクリプト位置の復元
+ st->script=(struct script_code*)conv_num(st,& (st->stack->stack_data[st->stack->defsp-3])); // スクリプトを復元
+ st->stack->var_function = (struct linkdb_node**)st->stack->stack_data[st->stack->defsp-2].u.num; // 関数依存変数
+
+ st->stack->defsp=conv_num(st,& (st->stack->stack_data[st->stack->defsp-4])); // 基準スタックポインタを復元
+ pop_stack(st->stack,olddefsp-5-i,olddefsp); // 要らなくなったスタック(引数と復帰用データ)削除
+
+ st->state=GOTO;
+ }
+
+ return 0;
+}
+
+/*==========================================
+ * スクリプトの実行
+ *------------------------------------------
+ */
+void run_script_main(struct script_state *st);
+
+void run_script(struct script_code *rootscript,int pos,int rid,int oid)
+{
+ struct script_state *st;
+ struct map_session_data *sd=NULL;
+
+ if(rootscript==NULL || pos<0)
+ return;
+
+ if (rid) sd = map_id2sd(rid);
+ if (sd && sd->st && sd->st->scriptroot == rootscript && sd->st->pos == pos){
+ //Resume script.
+ st = sd->st;
+ } else {
+ st = aCalloc(sizeof(struct script_state), 1);
+ // the script is different, make new script_state and stack
+ st->stack = aMalloc (sizeof(struct script_stack));
+ st->stack->sp=0;
+ st->stack->sp_max=64;
+ st->stack->stack_data = (struct script_data *)aCalloc(st->stack->sp_max,sizeof(st->stack->stack_data[0]));
+ st->stack->defsp = st->stack->sp;
+ st->stack->var_function = aCalloc(1, sizeof(struct linkdb_node*));
+ st->state = RUN;
+ st->script = rootscript;
+ }
+ st->pos = pos;
+ st->rid = rid;
+ st->oid = oid;
+ st->sleep.timer = -1;
+ run_script_main(st);
+}
+
+/*==========================================
+ * 指定ノードをsleep_dbから削除
+ *------------------------------------------
+ */
+struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n)
+{
+ struct linkdb_node *retnode;
+
+ if( n == NULL)
+ return NULL;
+ if( n->prev == NULL )
+ sleep_db = n->next;
+ else
+ n->prev->next = n->next;
+ if( n->next )
+ n->next->prev = n->prev;
+ retnode = n->next;
+ aFree( n );
+ return retnode; // 次のノードを返す
+}
+
+/*==========================================
+ * sleep用タイマー関数
+ *------------------------------------------
+ */
+int run_script_timer(int tid, unsigned int tick, int id, int data)
+{
+ struct script_state *st = (struct script_state *)data;
+ struct linkdb_node *node = (struct linkdb_node *)sleep_db;
+ struct map_session_data *sd = map_id2sd(st->rid);
+
+ if((sd && sd->char_id != id) || (st->rid && !sd))
+ { //Character mismatch. Cancel execution.
+ st->rid = 0;
+ st->state = END;
+ }
+ while( node && st->sleep.timer != -1 ) {
+ if( (int)node->key == st->oid && ((struct script_state *)node->data)->sleep.timer == st->sleep.timer ) {
+ script_erase_sleepdb(node);
+ st->sleep.timer = -1;
+ break;
+ }
+ node = node->next;
+ }
+ run_script_main(st);
+ return 0;
+}
+
+/*==========================================
+ * スクリプトの実行メイン部分
+ *------------------------------------------
+ */
+void run_script_main(struct script_state *st)
+{
+ int c;
+ int cmdcount=script_config.check_cmdcount;
+ int gotocount=script_config.check_gotocount;
+ struct map_session_data *sd;
+ //For backing up purposes
+ struct script_state *bk_st = NULL;
+ int bk_npcid = 0;
+ struct script_stack *stack=st->stack;
+
+ if(st->rid) sd = map_id2sd(st->rid);
+ if(sd){
+ if(sd->st != st){
+ bk_st = sd->st;
+ bk_npcid = sd->npc_id;
+ }
+ sd->st = st;
+ sd->npc_id = st->oid;
+ }
+
+ if(st->state == RERUNLINE) {
+ st->state = RUN;
+ run_func(st);
+ if(st->state == GOTO)
+ st->state = RUN;
+ } else if(st->state != END)
+ st->state = RUN;
+
+ while(st->state == RUN){
+ c= get_com((unsigned char *) st->script->script_buf,&st->pos);
+ switch(c){
+ case C_EOL:
+ if(stack->sp!=stack->defsp){
+ if(stack->sp > stack->defsp)
+ { //sp > defsp is valid in cases when you invoke functions and don't use the returned value. [Skotlex]
+ //Since sp is supposed to be defsp in these cases, we could assume the extra stack elements are unneeded.
+ if (battle_config.etc_log)
+ ShowWarning("Clearing unused stack stack.sp(%d) -> default(%d)\n",stack->sp,stack->defsp);
+ pop_stack(stack, stack->defsp, stack->sp); //Clear out the unused stack-section.
+ } else if(battle_config.error_log)
+ ShowError("stack.sp(%d) != default(%d)\n",stack->sp,stack->defsp);
+ stack->sp=stack->defsp;
+ }
+ break;
+ case C_INT:
+ push_val(stack,C_INT,get_num((unsigned char *) st->script->script_buf,&st->pos));
+ break;
+ case C_POS:
+ case C_NAME:
+ push_val(stack,c,(*(int*)(st->script->script_buf+st->pos))&0xffffff);
+ st->pos+=3;
+ break;
+ case C_ARG:
+ push_val(stack,c,0);
+ break;
+ case C_STR:
+ push_str(stack,C_CONSTSTR,(unsigned char *) (st->script->script_buf+st->pos));
+ while(st->script->script_buf[st->pos++]);
+ break;
+ case C_FUNC:
+ run_func(st);
+ if(st->state==GOTO){
+ st->state = RUN;
+ if( gotocount>0 && (--gotocount)<=0 ){
+ ShowError("run_script: infinity loop !\n");
+ st->state=END;
+ }
+ }
+ break;
+
+ case C_ADD:
+ op_add(st);
+ break;
+
+ case C_SUB:
+ case C_MUL:
+ case C_DIV:
+ case C_MOD:
+ case C_EQ:
+ case C_NE:
+ case C_GT:
+ case C_GE:
+ case C_LT:
+ case C_LE:
+ case C_AND:
+ case C_OR:
+ case C_XOR:
+ case C_LAND:
+ case C_LOR:
+ case C_R_SHIFT:
+ case C_L_SHIFT:
+ op_2(st,c);
+ break;
+
+ case C_NEG:
+ case C_NOT:
+ case C_LNOT:
+ op_1num(st,c);
+ break;
+
+ case C_NOP:
+ st->state=END;
+ break;
+
+ default:
+ if(battle_config.error_log)
+ ShowError("unknown command : %d @ %d\n",c,pos);
+ st->state=END;
+ break;
+ }
+ if( cmdcount>0 && (--cmdcount)<=0 ){
+ ShowError("run_script: infinity loop !\n");
+ st->state=END;
+ }
+ }
+
+ if(st->sleep.tick > 0) {
+ //Delay execution
+ st->sleep.charid = sd?sd->char_id:0;
+ st->sleep.timer = add_timer(gettick()+st->sleep.tick,
+ run_script_timer, st->sleep.charid, (int)st);
+ linkdb_insert(&sleep_db, (void*)st->oid, st);
+ //Restore previous script
+ sd->st = bk_st;
+ sd->npc_id = bk_npcid;
+ bk_st = NULL; //Remove tag for removal.
+ }
+ else if(st->state != END && sd){
+ //Resume later (st is already attached to player).
+ if(bk_st && sd->st != bk_st)
+ ShowWarning("Unable to restore stack! Double continuation!\n");
+ } else {
+ //Dispose of script.
+ if (sd)
+ { //Restore previous stack and save char.
+ if(sd->state.using_fake_npc){
+ clif_clearchar_id(sd->npc_id, 0, sd->fd);
+ sd->state.using_fake_npc = 0;
+ }
+ //Restore previous script if any.
+ sd->st = bk_st;
+ sd->npc_id = bk_npcid;
+ if (!bk_st)
+ npc_event_dequeue(sd);
+ else
+ bk_st = NULL; //Remove tag for removal.
+ if (sd->state.reg_dirty&2)
+ intif_saveregistry(sd,2);
+ if (sd->state.reg_dirty&1)
+ intif_saveregistry(sd,1);
+ }
+ st->pos = -1;
+ script_free_stack (st->stack);
+ aFree(st);
+ }
+
+ if (bk_st)
+ { //Remove previous script
+ bk_st->pos = -1;
+ script_free_stack(bk_st->stack);
+ aFree(bk_st);
+ bk_st = NULL;
+ }
+
+
+
+}
+
+/*==========================================
+ * マップ変数の変更
+ *------------------------------------------
+ */
+int mapreg_setreg(int num,int val)
+{
+#if !defined(TXT_ONLY) && defined(MAPREGSQL)
+ int i=num>>24;
+ char *name=str_buf+str_data[num&0x00ffffff].str;
+ char tmp_str[64];
+#endif
+
+ if(val!=0) {
+ if(idb_put(mapreg_db,num,(void*)val))
+ ;
+#if !defined(TXT_ONLY) && defined(MAPREGSQL)
+ else if(name[1] != '@') {
+ sprintf(tmp_sql,"INSERT INTO `%s`(`%s`,`%s`,`%s`) VALUES ('%s','%d','%d')",mapregsql_db,mapregsql_db_varname,mapregsql_db_index,mapregsql_db_value,jstrescapecpy(tmp_str,name),i,val);
+ if(mysql_query(&mmysql_handle,tmp_sql)){
+ ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
+ ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+ }
+ }
+#endif
+ // else
+ } else { // [zBuffer]
+#if !defined(TXT_ONLY) && defined(MAPREGSQL)
+ if(name[1] != '@') { // Remove from database because it is unused.
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `%s`='%s' AND `%s`='%d'",mapregsql_db,mapregsql_db_varname,name,mapregsql_db_index,i);
+ if(mysql_query(&mmysql_handle,tmp_sql)){
+ ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
+ ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+ }
+ }
+#endif
+ idb_remove(mapreg_db,num);
+ }
+
+ mapreg_dirty=1;
+ return 0;
+}
+/*==========================================
+ * 文字列型マップ変数の変更
+ *------------------------------------------
+ */
+int mapreg_setregstr(int num,const char *str)
+{
+ char *p;
+#if !defined(TXT_ONLY) && defined(MAPREGSQL)
+ char tmp_str[64];
+ char tmp_str2[512];
+ int i=num>>24; // [zBuffer]
+ char *name=str_buf+str_data[num&0x00ffffff].str;
+#endif
+
+ if( str==NULL || *str==0 ){
+#if !defined(TXT_ONLY) && defined(MAPREGSQL)
+ if(name[1] != '@') {
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `%s`='%s' AND `%s`='%d'",mapregsql_db,mapregsql_db_varname,name,mapregsql_db_index,i);
+ if(mysql_query(&mmysql_handle,tmp_sql)){
+ ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
+ ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+ }
+ }
+#endif
+ idb_remove(mapregstr_db,num);
+ mapreg_dirty=1;
+ return 0;
+ }
+ p=(char *)aMallocA((strlen(str)+1)*sizeof(char));
+ strcpy(p,str);
+
+ if (idb_put(mapregstr_db,num,p))
+ ;
+#if !defined(TXT_ONLY) && defined(MAPREGSQL)
+ else if(name[1] != '@'){ //put returned null, so we must insert.
+ // Someone is causing a database size infinite increase here without name[1] != '@' [Lance]
+ sprintf(tmp_sql,"INSERT INTO `%s`(`%s`,`%s`,`%s`) VALUES ('%s','%d','%s')",mapregsql_db,mapregsql_db_varname,mapregsql_db_index,mapregsql_db_value,jstrescapecpy(tmp_str,name),i,jstrescapecpy(tmp_str2,p));
+ if(mysql_query(&mmysql_handle,tmp_sql)){
+ ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
+ ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+ }
+ }
+#endif
+ mapreg_dirty=1;
+ return 0;
+}
+
+/*==========================================
+ * 永続的マップ変数の読み込み
+ *------------------------------------------
+ */
+static int script_load_mapreg(void)
+{
+#if defined(TXT_ONLY) || !defined(MAPREGSQL)
+ FILE *fp;
+ char line[1024];
+
+ if( (fp=fopen(mapreg_txt,"rt"))==NULL )
+ return -1;
+
+ while(fgets(line,sizeof(line),fp)){
+ char buf1[256],buf2[1024],*p;
+ int n,v,s,i;
+ if( sscanf(line,"%255[^,],%d\t%n",buf1,&i,&n)!=2 &&
+ (i=0,sscanf(line,"%[^\t]\t%n",buf1,&n)!=1) )
+ continue;
+ if( buf1[strlen(buf1)-1]=='$' ){
+ if( sscanf(line+n,"%[^\n\r]",buf2)!=1 ){
+ ShowError("%s: %s broken data !\n",mapreg_txt,buf1);
+ continue;
+ }
+ p=(char *)aMallocA((strlen(buf2) + 1)*sizeof(char));
+ strcpy(p,buf2);
+ s= add_str((unsigned char *) buf1);
+ idb_put(mapregstr_db,(i<<24)|s,p);
+ }else{
+ if( sscanf(line+n,"%d",&v)!=1 ){
+ ShowError("%s: %s broken data !\n",mapreg_txt,buf1);
+ continue;
+ }
+ s= add_str((unsigned char *) buf1);
+ idb_put(mapreg_db,(i<<24)|s,(void*)v);
+ }
+ }
+ fclose(fp);
+ mapreg_dirty=0;
+ return 0;
+#else
+ // SQL mapreg code start [zBuffer]
+ /*
+ 0 1 2
+ +-------------------------+
+ | varname | index | value |
+ +-------------------------+
+ */
+ unsigned int perfomance = (unsigned int)time(NULL);
+ sprintf(tmp_sql,"SELECT * FROM `%s`",mapregsql_db);
+ ShowInfo("Querying script_load_mapreg ...\n");
+ if(mysql_query(&mmysql_handle, tmp_sql) ) {
+ ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
+ ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+ return -1;
+ }
+ ShowInfo("Success! Returning results ...\n");
+ sql_res = mysql_store_result(&mmysql_handle);
+ if (sql_res) {
+ while ((sql_row = mysql_fetch_row(sql_res))) {
+ char buf1[33], *p = NULL;
+ int i,v,s;
+ strcpy(buf1,sql_row[0]);
+ if( buf1[strlen(buf1)-1]=='$' ){
+ i = atoi(sql_row[1]);
+ p=(char *)aMallocA((strlen(sql_row[2]) + 1)*sizeof(char));
+ strcpy(p,sql_row[2]);
+ s= add_str((unsigned char *) buf1);
+ idb_put(mapregstr_db,(i<<24)|s,p);
+ }else{
+ s= add_str((unsigned char *) buf1);
+ v= atoi(sql_row[2]);
+ i = atoi(sql_row[1]);
+ idb_put(mapreg_db,(i<<24)|s,(void *)v);
+ }
+ }
+ }
+ ShowInfo("Freeing results...\n");
+ mysql_free_result(sql_res);
+ mapreg_dirty=0;
+ perfomance = ((unsigned int)time(NULL) - perfomance);
+ ShowInfo("SQL Mapreg Loading Completed Under %d Seconds.\n",perfomance);
+ return 0;
+#endif /* TXT_ONLY */
+}
+/*==========================================
+ * 永続的マップ変数の書き込み
+ *------------------------------------------
+ */
+static int script_save_mapreg_intsub(DBKey key,void *data,va_list ap)
+{
+#if defined(TXT_ONLY) || !defined(MAPREGSQL)
+ FILE *fp=va_arg(ap,FILE*);
+ int num=key.i&0x00ffffff, i=key.i>>24;
+ char *name=str_buf+str_data[num].str;
+ if( name[1]!='@' ){
+ if(i==0)
+ fprintf(fp,"%s\t%d\n", name, (int)data);
+ else
+ fprintf(fp,"%s,%d\t%d\n", name, i, (int)data);
+ }
+ return 0;
+#else
+ int num=key.i&0x00ffffff, i=key.i>>24; // [zBuffer]
+ char *name=str_buf+str_data[num].str;
+ if ( name[1] != '@') {
+ sprintf(tmp_sql,"UPDATE `%s` SET `%s`='%d' WHERE `%s`='%s' AND `%s`='%d'",mapregsql_db,mapregsql_db_value,(int)data,mapregsql_db_varname,name,mapregsql_db_index,i);
+ if(mysql_query(&mmysql_handle, tmp_sql) ) {
+ ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
+ ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+ }
+ }
+ return 0;
+#endif
+}
+static int script_save_mapreg_strsub(DBKey key,void *data,va_list ap)
+{
+#if defined(TXT_ONLY) || !defined(MAPREGSQL)
+ FILE *fp=va_arg(ap,FILE*);
+ int num=key.i&0x00ffffff, i=key.i>>24;
+ char *name=str_buf+str_data[num].str;
+ if( name[1]!='@' ){
+ if(i==0)
+ fprintf(fp,"%s\t%s\n", name, (char *)data);
+ else
+ fprintf(fp,"%s,%d\t%s\n", name, i, (char *)data);
+ }
+ return 0;
+#else
+ char tmp_str2[512];
+ int num=key.i&0x00ffffff, i=key.i>>24;
+ char *name=str_buf+str_data[num].str;
+ if ( name[1] != '@') {
+ sprintf(tmp_sql,"UPDATE `%s` SET `%s`='%s' WHERE `%s`='%s' AND `%s`='%d'",mapregsql_db,mapregsql_db_value,jstrescapecpy(tmp_str2,(char *)data),mapregsql_db_varname,name,mapregsql_db_index,i);
+ if(mysql_query(&mmysql_handle, tmp_sql) ) {
+ ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
+ ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+ }
+ }
+ return 0;
+#endif
+}
+static int script_save_mapreg(void)
+{
+#if defined(TXT_ONLY) || !defined(MAPREGSQL)
+ FILE *fp;
+ int lock;
+
+ if( (fp=lock_fopen(mapreg_txt,&lock))==NULL ) {
+ ShowError("script_save_mapreg: Unable to lock-open file [%s]\n",mapreg_txt);
+ return -1;
+ }
+ mapreg_db->foreach(mapreg_db,script_save_mapreg_intsub,fp);
+ mapregstr_db->foreach(mapregstr_db,script_save_mapreg_strsub,fp);
+ lock_fclose(fp,mapreg_txt,&lock);
+#else
+ unsigned int perfomance = (unsigned int)time(NULL);
+ mapreg_db->foreach(mapreg_db,script_save_mapreg_intsub); // [zBuffer]
+ mapregstr_db->foreach(mapregstr_db,script_save_mapreg_strsub);
+ perfomance = ((unsigned int)time(NULL) - perfomance);
+ if(perfomance > 2)
+ ShowWarning("Slow Query: MapregSQL Saving @ %d second(s).\n", perfomance);
+#endif
+ mapreg_dirty=0;
+ return 0;
+}
+static int script_autosave_mapreg(int tid,unsigned int tick,int id,int data)
+{
+ if(mapreg_dirty)
+ if (script_save_mapreg() == -1)
+ ShowError("Failed to save the mapreg data!\n");
return 0;
}
-//
-// 埋め込み関数
-//
+/*==========================================
+ *
+ *------------------------------------------
+ */
+static int set_posword(char *p)
+{
+ char* np,* str[15];
+ int i=0;
+ for(i=0;i<11;i++) {
+ if((np=strchr(p,','))!=NULL) {
+ str[i]=p;
+ *np=0;
+ p=np+1;
+ } else {
+ str[i]=p;
+ p+=strlen(p);
+ }
+ if(str[i])
+ strcpy(pos[i],str[i]);
+ }
+ return 0;
+}
+
+int script_config_read_sub(char *cfgName)
+{
+ int i;
+ char line[1024],w1[1024],w2[1024];
+ FILE *fp;
+
+
+ fp=fopen(cfgName,"r");
+ if(fp==NULL){
+ ShowError("file not found: [%s]\n", cfgName);
+ return 1;
+ }
+ while(fgets(line,sizeof(line)-1,fp)){
+ if(line[0] == '/' && line[1] == '/')
+ continue;
+ i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2);
+ if(i!=2)
+ continue;
+ if(strcmpi(w1,"refine_posword")==0) {
+ set_posword(w2);
+ }
+ else if(strcmpi(w1,"verbose_mode")==0) {
+ script_config.verbose_mode = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"warn_func_no_comma")==0) {
+ script_config.warn_func_no_comma = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"warn_cmd_no_comma")==0) {
+ script_config.warn_cmd_no_comma = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"warn_func_mismatch_paramnum")==0) {
+ script_config.warn_func_mismatch_paramnum = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"warn_cmd_mismatch_paramnum")==0) {
+ script_config.warn_cmd_mismatch_paramnum = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"check_cmdcount")==0) {
+ script_config.check_cmdcount = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"check_gotocount")==0) {
+ script_config.check_gotocount = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"event_script_type")==0) {
+ script_config.event_script_type = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"event_requires_trigger")==0) {
+ script_config.event_requires_trigger = battle_config_switch(w2);
+ }
+ else if(strcmpi(w1,"die_event_name")==0) {
+ strncpy(script_config.die_event_name, w2, NAME_LENGTH-1);
+ if (strlen(script_config.die_event_name) != strlen(w2))
+ ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.die_event_name);
+ }
+ else if(strcmpi(w1,"kill_pc_event_name")==0) {
+ strncpy(script_config.kill_pc_event_name, w2, NAME_LENGTH-1);
+ if (strlen(script_config.kill_pc_event_name) != strlen(w2))
+ ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.kill_pc_event_name);
+ }
+ else if(strcmpi(w1,"kill_mob_event_name")==0) {
+ strncpy(script_config.kill_mob_event_name, w2, NAME_LENGTH-1);
+ if (strlen(script_config.kill_mob_event_name) != strlen(w2))
+ ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.kill_mob_event_name);
+ }
+ else if(strcmpi(w1,"login_event_name")==0) {
+ strncpy(script_config.login_event_name, w2, NAME_LENGTH-1);
+ if (strlen(script_config.login_event_name) != strlen(w2))
+ ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.login_event_name);
+ }
+ else if(strcmpi(w1,"logout_event_name")==0) {
+ strncpy(script_config.logout_event_name, w2, NAME_LENGTH-1);
+ if (strlen(script_config.logout_event_name) != strlen(w2))
+ ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.logout_event_name);
+ }
+ else if(strcmpi(w1,"loadmap_event_name")==0) {
+ strncpy(script_config.loadmap_event_name, w2, NAME_LENGTH-1);
+ if (strlen(script_config.loadmap_event_name) != strlen(w2))
+ ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.loadmap_event_name);
+ }
+ else if(strcmpi(w1,"baselvup_event_name")==0) {
+ strncpy(script_config.baselvup_event_name, w2, NAME_LENGTH-1);
+ if (strlen(script_config.baselvup_event_name) != strlen(w2))
+ ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.baselvup_event_name);
+ }
+ else if(strcmpi(w1,"joblvup_event_name")==0) {
+ strncpy(script_config.joblvup_event_name, w2, NAME_LENGTH-1);
+ if (strlen(script_config.joblvup_event_name) != strlen(w2))
+ ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.joblvup_event_name);
+ }
+ else if(strcmpi(w1,"import")==0){
+ script_config_read_sub(w2);
+ }
+ }
+ fclose(fp);
+
+ return 0;
+}
+
+int script_config_read(char *cfgName)
+{ //Script related variables should be initialized once! [Skotlex]
+
+ memset (&script_config, 0, sizeof(script_config));
+ script_config.verbose_mode = 0;
+ script_config.warn_func_no_comma = 1;
+ script_config.warn_cmd_no_comma = 1;
+ script_config.warn_func_mismatch_paramnum = 1;
+ script_config.warn_cmd_mismatch_paramnum = 1;
+ script_config.check_cmdcount = 65535;
+ script_config.check_gotocount = 2048;
+
+ script_config.event_script_type = 0;
+ script_config.event_requires_trigger = 1;
+
+ return script_config_read_sub(cfgName);
+}
+
+
+static int do_final_userfunc_sub (DBKey key,void *data,va_list ap){
+ struct script_code *code = (struct script_code *)data;
+ if(code){
+ script_free_vars( &code->script_vars );
+ aFree( code->script_buf );
+ }
+ return 0;
+}
+
+/*==========================================
+ * 終了
+ *------------------------------------------
+ */
+int do_final_script()
+{
+ if(mapreg_dirty>=0)
+ script_save_mapreg();
+
+ mapreg_db->destroy(mapreg_db,NULL);
+ mapregstr_db->destroy(mapregstr_db,NULL);
+ scriptlabel_db->destroy(scriptlabel_db,NULL);
+ userfunc_db->destroy(userfunc_db,do_final_userfunc_sub);
+ if(sleep_db) {
+ struct linkdb_node *n = (struct linkdb_node *)sleep_db;
+ while(n) {
+ struct script_state *st = (struct script_state *)n->data;
+ script_free_stack(st->stack);
+ free(st);
+ n = n->next;
+ }
+ linkdb_final(&sleep_db);
+ }
+
+ if (str_data)
+ aFree(str_data);
+ if (str_buf)
+ aFree(str_buf);
+
+ return 0;
+}
+/*==========================================
+ * 初期化
+ *------------------------------------------
+ */
+int do_init_script()
+{
+ mapreg_db= db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_BASE,sizeof(int));
+ mapregstr_db=db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_RELEASE_DATA,sizeof(int));
+ userfunc_db=db_alloc(__FILE__,__LINE__,DB_STRING,DB_OPT_RELEASE_BOTH,50);
+ scriptlabel_db=db_alloc(__FILE__,__LINE__,DB_STRING,DB_OPT_ALLOW_NULL_DATA,50);
+
+ script_load_mapreg();
+
+ add_timer_func_list(script_autosave_mapreg,"script_autosave_mapreg");
+ add_timer_interval(gettick()+MAPREG_AUTOSAVE_INTERVAL,
+ script_autosave_mapreg,0,0,MAPREG_AUTOSAVE_INTERVAL);
+
+ return 0;
+}
+
+int script_reload()
+{
+ if(mapreg_dirty>=0)
+ script_save_mapreg();
+
+ mapreg_db->clear(mapreg_db, NULL);
+ mapregstr_db->clear(mapregstr_db, NULL);
+ userfunc_db->clear(userfunc_db,do_final_userfunc_sub);
+ scriptlabel_db->clear(scriptlabel_db, NULL);
+
+ if(sleep_db) {
+ struct linkdb_node *n = (struct linkdb_node *)sleep_db;
+ while(n) {
+ struct script_state *st = (struct script_state *)n->data;
+ script_free_stack(st->stack);
+ free(st);
+ n = n->next;
+ }
+ linkdb_final(&sleep_db);
+ }
+
+ script_load_mapreg();
+ return 0;
+}
+
+int buildin_mes(struct script_state *st);
+int buildin_goto(struct script_state *st);
+int buildin_callsub(struct script_state *st);
+int buildin_callfunc(struct script_state *st);
+int buildin_return(struct script_state *st);
+int buildin_getarg(struct script_state *st);
+int buildin_next(struct script_state *st);
+int buildin_close(struct script_state *st);
+int buildin_close2(struct script_state *st);
+int buildin_menu(struct script_state *st);
+int buildin_rand(struct script_state *st);
+int buildin_warp(struct script_state *st);
+int buildin_areawarp(struct script_state *st);
+int buildin_warpchar(struct script_state *st); // [LuzZza]
+int buildin_warpparty(struct script_state *st); //[Fredzilla]
+int buildin_warpguild(struct script_state *st); //[Fredzilla]
+int buildin_heal(struct script_state *st);
+int buildin_itemheal(struct script_state *st);
+int buildin_percentheal(struct script_state *st);
+int buildin_jobchange(struct script_state *st);
+int buildin_input(struct script_state *st);
+int buildin_setlook(struct script_state *st);
+int buildin_set(struct script_state *st);
+int buildin_setarray(struct script_state *st);
+int buildin_cleararray(struct script_state *st);
+int buildin_copyarray(struct script_state *st);
+int buildin_getarraysize(struct script_state *st);
+int buildin_deletearray(struct script_state *st);
+int buildin_getelementofarray(struct script_state *st);
+int buildin_getitem(struct script_state *st);
+int buildin_getitem2(struct script_state *st);
+int buildin_getnameditem(struct script_state *st);
+int buildin_grouprandomitem(struct script_state *st);
+int buildin_makeitem(struct script_state *st);
+int buildin_delitem(struct script_state *st);
+int buildin_delitem2(struct script_state *st);
+int buildin_enableitemuse(struct script_state *st);
+int buildin_disableitemuse(struct script_state *st);
+int buildin_viewpoint(struct script_state *st);
+int buildin_countitem(struct script_state *st);
+int buildin_countitem2(struct script_state *st);
+int buildin_checkweight(struct script_state *st);
+int buildin_readparam(struct script_state *st);
+int buildin_getcharid(struct script_state *st);
+int buildin_getpartyname(struct script_state *st);
+int buildin_getpartymember(struct script_state *st);
+int buildin_getguildname(struct script_state *st);
+int buildin_getguildmaster(struct script_state *st);
+int buildin_getguildmasterid(struct script_state *st);
+int buildin_strcharinfo(struct script_state *st);
+int buildin_getequipid(struct script_state *st);
+int buildin_getequipname(struct script_state *st);
+int buildin_getbrokenid(struct script_state *st); // [Valaris]
+int buildin_repair(struct script_state *st); // [Valaris]
+int buildin_getequipisequiped(struct script_state *st);
+int buildin_getequipisenableref(struct script_state *st);
+int buildin_getequipisidentify(struct script_state *st);
+int buildin_getequiprefinerycnt(struct script_state *st);
+int buildin_getequipweaponlv(struct script_state *st);
+int buildin_getequippercentrefinery(struct script_state *st);
+int buildin_successrefitem(struct script_state *st);
+int buildin_failedrefitem(struct script_state *st);
+int buildin_cutin(struct script_state *st);
+int buildin_cutincard(struct script_state *st);
+int buildin_statusup(struct script_state *st);
+int buildin_statusup2(struct script_state *st);
+int buildin_bonus(struct script_state *st);
+int buildin_bonus2(struct script_state *st);
+int buildin_bonus3(struct script_state *st);
+int buildin_bonus4(struct script_state *st);
+int buildin_skill(struct script_state *st);
+int buildin_addtoskill(struct script_state *st); // [Valaris]
+int buildin_guildskill(struct script_state *st);
+int buildin_getskilllv(struct script_state *st);
+int buildin_getgdskilllv(struct script_state *st);
+int buildin_basicskillcheck(struct script_state *st);
+int buildin_getgmlevel(struct script_state *st);
+int buildin_end(struct script_state *st);
+int buildin_checkoption(struct script_state *st);
+int buildin_setoption(struct script_state *st);
+int buildin_setcart(struct script_state *st);
+int buildin_checkcart(struct script_state *st); // check cart [Valaris]
+int buildin_setfalcon(struct script_state *st);
+int buildin_checkfalcon(struct script_state *st); // check falcon [Valaris]
+int buildin_setriding(struct script_state *st);
+int buildin_checkriding(struct script_state *st); // check for pecopeco [Valaris]
+int buildin_savepoint(struct script_state *st);
+int buildin_gettimetick(struct script_state *st);
+int buildin_gettime(struct script_state *st);
+int buildin_gettimestr(struct script_state *st);
+int buildin_openstorage(struct script_state *st);
+int buildin_guildopenstorage(struct script_state *st);
+int buildin_itemskill(struct script_state *st);
+int buildin_produce(struct script_state *st);
+int buildin_monster(struct script_state *st);
+int buildin_areamonster(struct script_state *st);
+int buildin_killmonster(struct script_state *st);
+int buildin_killmonsterall(struct script_state *st);
+int buildin_clone(struct script_state *st);
+int buildin_doevent(struct script_state *st);
+int buildin_donpcevent(struct script_state *st);
+int buildin_addtimer(struct script_state *st);
+int buildin_deltimer(struct script_state *st);
+int buildin_addtimercount(struct script_state *st);
+int buildin_initnpctimer(struct script_state *st);
+int buildin_stopnpctimer(struct script_state *st);
+int buildin_startnpctimer(struct script_state *st);
+int buildin_setnpctimer(struct script_state *st);
+int buildin_getnpctimer(struct script_state *st);
+int buildin_attachnpctimer(struct script_state *st); // [celest]
+int buildin_detachnpctimer(struct script_state *st); // [celest]
+int buildin_playerattached(struct script_state *st); // [Skotlex]
+int buildin_announce(struct script_state *st);
+int buildin_mapannounce(struct script_state *st);
+int buildin_areaannounce(struct script_state *st);
+int buildin_getusers(struct script_state *st);
+int buildin_getmapusers(struct script_state *st);
+int buildin_getareausers(struct script_state *st);
+int buildin_getareadropitem(struct script_state *st);
+int buildin_enablenpc(struct script_state *st);
+int buildin_disablenpc(struct script_state *st);
+int buildin_enablearena(struct script_state *st); // Added by RoVeRT
+int buildin_disablearena(struct script_state *st); // Added by RoVeRT
+int buildin_hideoffnpc(struct script_state *st);
+int buildin_hideonnpc(struct script_state *st);
+int buildin_sc_start(struct script_state *st);
+int buildin_sc_start2(struct script_state *st);
+int buildin_sc_start4(struct script_state *st);
+int buildin_sc_end(struct script_state *st);
+int buildin_getscrate(struct script_state *st);
+int buildin_debugmes(struct script_state *st);
+int buildin_catchpet(struct script_state *st);
+int buildin_birthpet(struct script_state *st);
+int buildin_resetlvl(struct script_state *st);
+int buildin_resetstatus(struct script_state *st);
+int buildin_resetskill(struct script_state *st);
+int buildin_skillpointcount(struct script_state *st);
+int buildin_changebase(struct script_state *st);
+int buildin_changesex(struct script_state *st);
+int buildin_waitingroom(struct script_state *st);
+int buildin_delwaitingroom(struct script_state *st);
+int buildin_enablewaitingroomevent(struct script_state *st);
+int buildin_disablewaitingroomevent(struct script_state *st);
+int buildin_getwaitingroomstate(struct script_state *st);
+int buildin_warpwaitingpc(struct script_state *st);
+int buildin_attachrid(struct script_state *st);
+int buildin_detachrid(struct script_state *st);
+int buildin_isloggedin(struct script_state *st);
+int buildin_setmapflagnosave(struct script_state *st);
+int buildin_setmapflag(struct script_state *st);
+int buildin_removemapflag(struct script_state *st);
+int buildin_pvpon(struct script_state *st);
+int buildin_pvpoff(struct script_state *st);
+int buildin_gvgon(struct script_state *st);
+int buildin_gvgoff(struct script_state *st);
+int buildin_emotion(struct script_state *st);
+int buildin_maprespawnguildid(struct script_state *st);
+int buildin_agitstart(struct script_state *st); // <Agit>
+int buildin_agitend(struct script_state *st);
+int buildin_agitcheck(struct script_state *st); // <Agitcheck>
+int buildin_flagemblem(struct script_state *st); // Flag Emblem
+int buildin_getcastlename(struct script_state *st);
+int buildin_getcastledata(struct script_state *st);
+int buildin_setcastledata(struct script_state *st);
+int buildin_requestguildinfo(struct script_state *st);
+int buildin_getequipcardcnt(struct script_state *st);
+int buildin_successremovecards(struct script_state *st);
+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); // MouseJstr
+int buildin_getpartnerid(struct script_state *st); // MouseJstr
+int buildin_getchildid(struct script_state *st); // Skotlex
+int buildin_getmotherid(struct script_state *st); // Lupus
+int buildin_getfatherid(struct script_state *st); // Lupus
+int buildin_warppartner(struct script_state *st); // MouseJstr
+int buildin_getitemname(struct script_state *st);
+int buildin_getitemslots(struct script_state *st);
+int buildin_makepet(struct script_state *st);
+int buildin_getexp(struct script_state *st);
+int buildin_getinventorylist(struct script_state *st);
+int buildin_getskilllist(struct script_state *st);
+int buildin_clearitem(struct script_state *st);
+int buildin_classchange(struct script_state *st);
+int buildin_misceffect(struct script_state *st);
+int buildin_soundeffect(struct script_state *st);
+int buildin_soundeffectall(struct script_state *st);
+int buildin_setcastledata(struct script_state *st);
+int buildin_mapwarp(struct script_state *st);
+int buildin_inittimer(struct script_state *st);
+int buildin_stoptimer(struct script_state *st);
+int buildin_cmdothernpc(struct script_state *st);
+int buildin_mobcount(struct script_state *st);
+int buildin_strmobinfo(struct script_state *st); // Script for displaying mob info [Valaris]
+int buildin_guardian(struct script_state *st); // Script for displaying mob info [Valaris]
+int buildin_guardianinfo(struct script_state *st); // Script for displaying mob info [Valaris]
+int buildin_petskillbonus(struct script_state *st); // petskillbonus [Valaris]
+int buildin_petrecovery(struct script_state *st); // pet skill for curing status [Valaris]
+int buildin_petloot(struct script_state *st); // pet looting [Valaris]
+int buildin_petheal(struct script_state *st); // pet healing [Valaris]
+//int buildin_petmag(struct script_state *st); // pet magnificat [Valaris]
+int buildin_petskillattack(struct script_state *st); // pet skill attacks [Skotlex]
+int buildin_petskillattack2(struct script_state *st); // pet skill attacks [Skotlex]
+int buildin_petskillsupport(struct script_state *st); // pet support skill [Valaris]
+int buildin_skilleffect(struct script_state *st); // skill effects [Celest]
+int buildin_npcskilleffect(struct script_state *st); // skill effects for npcs [Valaris]
+int buildin_specialeffect(struct script_state *st); // special effect script [Valaris]
+int buildin_specialeffect2(struct script_state *st); // special effect script [Valaris]
+int buildin_nude(struct script_state *st); // nude [Valaris]
+int buildin_atcommand(struct script_state *st); // [MouseJstr]
+int buildin_charcommand(struct script_state *st); // [MouseJstr]
+int buildin_movenpc(struct script_state *st); // [MouseJstr]
+int buildin_message(struct script_state *st); // [MouseJstr]
+int buildin_npctalk(struct script_state *st); // [Valaris]
+int buildin_hasitems(struct script_state *st); // [Valaris]
+int buildin_getlook(struct script_state *st); //Lorky [Lupus]
+int buildin_getsavepoint(struct script_state *st); //Lorky [Lupus]
+int buildin_npcspeed(struct script_state *st); // [Valaris]
+int buildin_npcwalkto(struct script_state *st); // [Valaris]
+int buildin_npcstop(struct script_state *st); // [Valaris]
+int buildin_getmapxy(struct script_state *st); //get map position for player/npc/pet/mob by Lorky [Lupus]
+int buildin_checkoption1(struct script_state *st); // [celest]
+int buildin_checkoption2(struct script_state *st); // [celest]
+int buildin_guildgetexp(struct script_state *st); // [celest]
+int buildin_guildchangegm(struct script_state *st); // [Skotlex]
+int buildin_logmes(struct script_state *st); // [Lupus]
+int buildin_summon(struct script_state *st); // [celest]
+int buildin_isnight(struct script_state *st); // [celest]
+int buildin_isday(struct script_state *st); // [celest]
+int buildin_isequipped(struct script_state *st); // [celest]
+int buildin_isequippedcnt(struct script_state *st); // [celest]
+int buildin_cardscnt(struct script_state *st); // [Lupus]
+int buildin_getrefine(struct script_state *st); // [celest]
+int buildin_adopt(struct script_state *st);
+int buildin_night(struct script_state *st);
+int buildin_day(struct script_state *st);
+int buildin_getusersname(struct script_state *st); //jA commands added [Lupus]
+int buildin_dispbottom(struct script_state *st);
+int buildin_recovery(struct script_state *st);
+int buildin_getpetinfo(struct script_state *st);
+int buildin_checkequipedcard(struct script_state *st);
+int buildin_globalmes(struct script_state *st);
+int buildin_jump_zero(struct script_state *st);
+int buildin_select(struct script_state *st);
+int buildin_getmapmobs(struct script_state *st); //jA addition end
+int buildin_unequip(struct script_state *st); // unequip [Spectre]
+int buildin_getstrlen(struct script_state *st); //strlen [valaris]
+int buildin_charisalpha(struct script_state *st);//isalpha [valaris]
+int buildin_fakenpcname(struct script_state *st); // [Lance]
+int buildin_compare(struct script_state *st); // Lordalfa, to bring strstr to Scripting Engine
+int buildin_getiteminfo(struct script_state *st); //[Lupus] returns Items Buy / sell Price, etc info
+int buildin_getequipcardid(struct script_state *st); //[Lupus] returns card id from quipped item card slot N
+// [zBuffer] List of mathematics commands --->
+int buildin_sqrt(struct script_state *st);
+int buildin_pow(struct script_state *st);
+int buildin_distance(struct script_state *st);
+int buildin_checkcell(struct script_state *st);
+// <--- [zBuffer] List of mathematics commands
+// [zBuffer] List of dynamic var commands --->
+int buildin_getd(struct script_state *st);
+int buildin_setd(struct script_state *st);
+// <--- [zBuffer] List of dynamic var commands
+int buildin_petstat(struct script_state *st); // [Lance] Pet Stat Rq: Dubby
+int buildin_callshop(struct script_state *st); // [Skotlex]
+int buildin_npcshopitem(struct script_state *st); // [Lance]
+int buildin_npcshopadditem(struct script_state *st);
+int buildin_npcshopdelitem(struct script_state *st);
+int buildin_equip(struct script_state *st);
+int buildin_autoequip(struct script_state *st);
+int buildin_setbattleflag(struct script_state *st);
+int buildin_getbattleflag(struct script_state *st);
+#ifndef TXT_ONLY
+int buildin_query_sql(struct script_state *st);
+int buildin_escape_sql(struct script_state *st);
+#endif
+int buildin_atoi(struct script_state *st);
+int buildin_axtoi(struct script_state *st);
+// [zBuffer] List of player cont commands --->
+int buildin_rid2name(struct script_state *st);
+int buildin_pcfollow(struct script_state *st);
+int buildin_pcstopfollow(struct script_state *st);
+int buildin_pcblockmove(struct script_state *st);
+// <--- [zBuffer] List of player cont commands
+// [zBuffer] List of mob control commands --->
+int buildin_mobspawn(struct script_state *st);
+int buildin_mobremove(struct script_state *st);
+int buildin_getmobdata(struct script_state *st);
+int buildin_setmobdata(struct script_state *st);
+int buildin_mobassist(struct script_state *st);
+int buildin_mobattach(struct script_state *st);
+int buildin_unitwalk(struct script_state *st);
+int buildin_unitkill(struct script_state *st);
+int buildin_unitwarp(struct script_state *st);
+int buildin_unitattack(struct script_state *st);
+int buildin_unitstop(struct script_state *st);
+int buildin_unittalk(struct script_state *st);
+int buildin_unitemote(struct script_state *st);
+int buildin_unitdeadsit(struct script_state *st);
+int buildin_unitskilluseid(struct script_state *st); // originally by Qamera [celest]
+int buildin_unitskillusepos(struct script_state *st); // originally by Qamera [celest]
+// <--- [zBuffer] List of mob control commands
+int buildin_sleep(struct script_state *st);
+int buildin_sleep2(struct script_state *st);
+int buildin_awake(struct script_state *st);
+int buildin_getvariableofnpc(struct script_state *st);
+// [blackhole89] -->
+int buildin_warpportal(struct script_state *st);
+// <-- [blackhole89]
+int buildin_homunculus_evolution(struct script_state *st) ; //[orn]
+int buildin_setitemscript(struct script_state *st);
+int buildin_disguise(struct script_state *st);
+int buildin_undisguise(struct script_state *st);
+int buildin_getmonsterinfo(struct script_state *st); // [Lupus]
+
+#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 script_function buildin_func[] = {
+ {buildin_mes,"mes","s"},
+ {buildin_next,"next",""},
+ {buildin_close,"close",""},
+ {buildin_close2,"close2",""},
+ {buildin_menu,"menu","*"},
+ {buildin_goto,"goto","l"},
+ {buildin_callsub,"callsub","i*"},
+ {buildin_callfunc,"callfunc","s*"},
+ {buildin_return,"return","*"},
+ {buildin_getarg,"getarg","i"},
+ {buildin_jobchange,"jobchange","i*"},
+ {buildin_input,"input","*"},
+ {buildin_warp,"warp","sii"},
+ {buildin_areawarp,"areawarp","siiiisii"},
+ {buildin_warpchar,"warpchar","siii"}, // [LuzZza]
+ {buildin_warpparty,"warpparty","siii"}, // [Fredzilla]
+ {buildin_warpguild,"warpguild","siii"}, // [Fredzilla]
+ {buildin_setlook,"setlook","ii"},
+ {buildin_set,"set","ii"},
+ {buildin_setarray,"setarray","ii*"},
+ {buildin_cleararray,"cleararray","iii"},
+ {buildin_copyarray,"copyarray","iii"},
+ {buildin_getarraysize,"getarraysize","i"},
+ {buildin_deletearray,"deletearray","ii"},
+ {buildin_getelementofarray,"getelementofarray","ii"},
+ {buildin_getitem,"getitem","ii**"},
+ {buildin_getitem2,"getitem2","iiiiiiiii*"},
+ {buildin_getnameditem,"getnameditem","is"},
+ {buildin_grouprandomitem,"groupranditem","i"},
+ {buildin_makeitem,"makeitem","iisii"},
+ {buildin_delitem,"delitem","ii"},
+ {buildin_delitem2,"delitem2","iiiiiiiii"},
+ {buildin_enableitemuse,"enable_items",""},
+ {buildin_disableitemuse,"disable_items",""},
+ {buildin_cutin,"cutin","si"},
+ {buildin_cutincard,"cutincard","i"},
+ {buildin_viewpoint,"viewpoint","iiiii"},
+ {buildin_heal,"heal","ii"},
+ {buildin_itemheal,"itemheal","ii"},
+ {buildin_percentheal,"percentheal","ii"},
+ {buildin_rand,"rand","i*"},
+ {buildin_countitem,"countitem","i"},
+ {buildin_countitem2,"countitem2","iiiiiiii"},
+ {buildin_checkweight,"checkweight","ii"},
+ {buildin_readparam,"readparam","i*"},
+ {buildin_getcharid,"getcharid","i*"},
+ {buildin_getpartyname,"getpartyname","i"},
+ {buildin_getpartymember,"getpartymember","i*"},
+ {buildin_getguildname,"getguildname","i"},
+ {buildin_getguildmaster,"getguildmaster","i"},
+ {buildin_getguildmasterid,"getguildmasterid","i"},
+ {buildin_strcharinfo,"strcharinfo","i"},
+ {buildin_getequipid,"getequipid","i"},
+ {buildin_getequipname,"getequipname","i"},
+ {buildin_getbrokenid,"getbrokenid","i"}, // [Valaris]
+ {buildin_repair,"repair","i"}, // [Valaris]
+ {buildin_getequipisequiped,"getequipisequiped","i"},
+ {buildin_getequipisenableref,"getequipisenableref","i"},
+ {buildin_getequipisidentify,"getequipisidentify","i"},
+ {buildin_getequiprefinerycnt,"getequiprefinerycnt","i"},
+ {buildin_getequipweaponlv,"getequipweaponlv","i"},
+ {buildin_getequippercentrefinery,"getequippercentrefinery","i"},
+ {buildin_successrefitem,"successrefitem","i"},
+ {buildin_failedrefitem,"failedrefitem","i"},
+ {buildin_statusup,"statusup","i"},
+ {buildin_statusup2,"statusup2","ii"},
+ {buildin_bonus,"bonus","ii"},
+ {buildin_bonus2,"bonus2","iii"},
+ {buildin_bonus3,"bonus3","iiii"},
+ {buildin_bonus4,"bonus4","iiiii"},
+ {buildin_skill,"skill","ii*"},
+ {buildin_addtoskill,"addtoskill","ii*"}, // [Valaris]
+ {buildin_guildskill,"guildskill","ii"},
+ {buildin_getskilllv,"getskilllv","i"},
+ {buildin_getgdskilllv,"getgdskilllv","ii"},
+ {buildin_basicskillcheck,"basicskillcheck","*"},
+ {buildin_getgmlevel,"getgmlevel","*"},
+ {buildin_end,"end",""},
+// {buildin_end,"break",""}, this might confuse advanced scripting support [Eoe]
+ {buildin_checkoption,"checkoption","i"},
+ {buildin_setoption,"setoption","i*"},
+ {buildin_setcart,"setcart",""},
+ {buildin_checkcart,"checkcart","*"}, //fixed by Lupus (added '*')
+ {buildin_setfalcon,"setfalcon",""},
+ {buildin_checkfalcon,"checkfalcon","*"}, //fixed by Lupus (fixed wrong pointer, added '*')
+ {buildin_setriding,"setriding",""},
+ {buildin_checkriding,"checkriding","*"}, //fixed by Lupus (fixed wrong pointer, added '*')
+ {buildin_savepoint,"save","sii"},
+ {buildin_savepoint,"savepoint","sii"},
+ {buildin_gettimetick,"gettimetick","i"},
+ {buildin_gettime,"gettime","i"},
+ {buildin_gettimestr,"gettimestr","si"},
+ {buildin_openstorage,"openstorage",""},
+ {buildin_guildopenstorage,"guildopenstorage","*"},
+ {buildin_itemskill,"itemskill","iis"},
+ {buildin_produce,"produce","i"},
+ {buildin_monster,"monster","siisii*"},
+ {buildin_areamonster,"areamonster","siiiisii*"},
+ {buildin_killmonster,"killmonster","ss"},
+ {buildin_killmonsterall,"killmonsterall","s"},
+ {buildin_clone,"clone","siisi*"},
+ {buildin_doevent,"doevent","s"},
+ {buildin_donpcevent,"donpcevent","s"},
+ {buildin_addtimer,"addtimer","is"},
+ {buildin_deltimer,"deltimer","s"},
+ {buildin_addtimercount,"addtimercount","si"},
+ {buildin_initnpctimer,"initnpctimer","*"},
+ {buildin_stopnpctimer,"stopnpctimer","*"},
+ {buildin_startnpctimer,"startnpctimer","*"},
+ {buildin_setnpctimer,"setnpctimer","*"},
+ {buildin_getnpctimer,"getnpctimer","i*"},
+ {buildin_attachnpctimer,"attachnpctimer","*"}, // attached the player id to the npc timer [Celest]
+ {buildin_detachnpctimer,"detachnpctimer","*"}, // detached the player id from the npc timer [Celest]
+ {buildin_playerattached,"playerattached",""}, // returns id of the current attached player. [Skotlex]
+ {buildin_announce,"announce","si*"},
+ {buildin_mapannounce,"mapannounce","ssi*"},
+ {buildin_areaannounce,"areaannounce","siiiisi*"},
+ {buildin_getusers,"getusers","i"},
+ {buildin_getmapusers,"getmapusers","s"},
+ {buildin_getareausers,"getareausers","siiii"},
+ {buildin_getareadropitem,"getareadropitem","siiiii"},
+ {buildin_enablenpc,"enablenpc","s"},
+ {buildin_disablenpc,"disablenpc","s"},
+ {buildin_enablearena,"enablearena",""}, // Added by RoVeRT
+ {buildin_disablearena,"disablearena",""}, // Added by RoVeRT
+ {buildin_hideoffnpc,"hideoffnpc","s"},
+ {buildin_hideonnpc,"hideonnpc","s"},
+ {buildin_sc_start,"sc_start","iii*"},
+ {buildin_sc_start2,"sc_start2","iiii*"},
+ {buildin_sc_start4,"sc_start4","iiiiii*"},
+ {buildin_sc_end,"sc_end","i"},
+ {buildin_getscrate,"getscrate","ii*"},
+ {buildin_debugmes,"debugmes","s"},
+ {buildin_catchpet,"pet","i"},
+ {buildin_birthpet,"bpet",""},
+ {buildin_resetlvl,"resetlvl","i"},
+ {buildin_resetstatus,"resetstatus",""},
+ {buildin_resetskill,"resetskill",""},
+ {buildin_skillpointcount,"skillpointcount",""},
+ {buildin_changebase,"changebase","i"},
+ {buildin_changesex,"changesex",""},
+ {buildin_waitingroom,"waitingroom","si*"},
+ {buildin_warpwaitingpc,"warpwaitingpc","sii"},
+ {buildin_delwaitingroom,"delwaitingroom","*"},
+ {buildin_enablewaitingroomevent,"enablewaitingroomevent","*"},
+ {buildin_disablewaitingroomevent,"disablewaitingroomevent","*"},
+ {buildin_getwaitingroomstate,"getwaitingroomstate","i*"},
+ {buildin_warpwaitingpc,"warpwaitingpc","sii*"},
+ {buildin_attachrid,"attachrid","i"},
+ {buildin_detachrid,"detachrid",""},
+ {buildin_isloggedin,"isloggedin","i"},
+ {buildin_setmapflagnosave,"setmapflagnosave","ssii"},
+ {buildin_setmapflag,"setmapflag","si*"},
+ {buildin_removemapflag,"removemapflag","si"},
+ {buildin_pvpon,"pvpon","s"},
+ {buildin_pvpoff,"pvpoff","s"},
+ {buildin_gvgon,"gvgon","s"},
+ {buildin_gvgoff,"gvgoff","s"},
+ {buildin_emotion,"emotion","i*"},
+ {buildin_maprespawnguildid,"maprespawnguildid","sii"},
+ {buildin_agitstart,"agitstart",""}, // <Agit>
+ {buildin_agitend,"agitend",""},
+ {buildin_agitcheck,"agitcheck","i"}, // <Agitcheck>
+ {buildin_flagemblem,"flagemblem","i"}, // Flag Emblem
+ {buildin_getcastlename,"getcastlename","s"},
+ {buildin_getcastledata,"getcastledata","si*"},
+ {buildin_setcastledata,"setcastledata","sii"},
+ {buildin_requestguildinfo,"requestguildinfo","i*"},
+ {buildin_getequipcardcnt,"getequipcardcnt","i"},
+ {buildin_successremovecards,"successremovecards","i"},
+ {buildin_failedremovecards,"failedremovecards","ii"},
+ {buildin_marriage,"marriage","s"},
+ {buildin_wedding_effect,"wedding",""},
+ {buildin_divorce,"divorce",""},
+ {buildin_ispartneron,"ispartneron",""},
+ {buildin_getpartnerid,"getpartnerid",""},
+ {buildin_getchildid,"getchildid",""},
+ {buildin_getmotherid,"getmotherid",""},
+ {buildin_getfatherid,"getfatherid",""},
+ {buildin_warppartner,"warppartner","sii"},
+ {buildin_getitemname,"getitemname","i"},
+ {buildin_getitemslots,"getitemslots","i"},
+ {buildin_makepet,"makepet","i"},
+ {buildin_getexp,"getexp","ii"},
+ {buildin_getinventorylist,"getinventorylist",""},
+ {buildin_getskilllist,"getskilllist",""},
+ {buildin_clearitem,"clearitem",""},
+ {buildin_classchange,"classchange","ii"},
+ {buildin_misceffect,"misceffect","i"},
+ {buildin_soundeffect,"soundeffect","si"},
+ {buildin_soundeffectall,"soundeffectall","si*"}, // SoundEffectAll [Codemaster]
+ {buildin_strmobinfo,"strmobinfo","ii"}, // display mob data [Valaris]
+ {buildin_guardian,"guardian","siisii*i"}, // summon guardians
+ {buildin_guardianinfo,"guardianinfo","i"}, // display guardian data [Valaris]
+ {buildin_petskillbonus,"petskillbonus","iiii"}, // [Valaris]
+ {buildin_petrecovery,"petrecovery","ii"}, // [Valaris]
+ {buildin_petloot,"petloot","i"}, // [Valaris]
+ {buildin_petheal,"petheal","iiii"}, // [Valaris]
+// {buildin_petmag,"petmag","iiii"}, // [Valaris]
+ {buildin_petskillattack,"petskillattack","iiii"}, // [Skotlex]
+ {buildin_petskillattack2,"petskillattack2","iiiii"}, // [Valaris]
+ {buildin_petskillsupport,"petskillsupport","iiiii"}, // [Skotlex]
+ {buildin_skilleffect,"skilleffect","ii"}, // skill effect [Celest]
+ {buildin_npcskilleffect,"npcskilleffect","iiii"}, // npc skill effect [Valaris]
+ {buildin_specialeffect,"specialeffect","i*"}, // npc skill effect [Valaris]
+ {buildin_specialeffect2,"specialeffect2","i*"}, // skill effect on players[Valaris]
+ {buildin_nude,"nude",""}, // nude command [Valaris]
+ {buildin_mapwarp,"mapwarp","ssii"}, // Added by RoVeRT
+ {buildin_inittimer,"inittimer",""},
+ {buildin_stoptimer,"stoptimer",""},
+ {buildin_cmdothernpc,"cmdothernpc","ss"},
+ {buildin_atcommand,"atcommand","*"}, // [MouseJstr]
+ {buildin_charcommand,"charcommand","*"}, // [MouseJstr]
+ {buildin_movenpc,"movenpc","sii"}, // [MouseJstr]
+ {buildin_message,"message","s*"}, // [MouseJstr]
+ {buildin_npctalk,"npctalk","*"}, // [Valaris]
+ {buildin_hasitems,"hasitems","*"}, // [Valaris]
+ {buildin_mobcount,"mobcount","ss"},
+ {buildin_getlook,"getlook","i"},
+ {buildin_getsavepoint,"getsavepoint","i"},
+ {buildin_npcspeed,"npcspeed","i"}, // [Valaris]
+ {buildin_npcwalkto,"npcwalkto","ii"}, // [Valaris]
+ {buildin_npcstop,"npcstop",""}, // [Valaris]
+ {buildin_getmapxy,"getmapxy","siii*"}, //by Lorky [Lupus]
+ {buildin_checkoption1,"checkoption1","i"},
+ {buildin_checkoption2,"checkoption2","i"},
+ {buildin_guildgetexp,"guildgetexp","i"},
+ {buildin_guildchangegm,"guildchangegm","is"},
+ {buildin_logmes,"logmes","s"}, //this command actls as MES but rints info into LOG file either SQL/TXT [Lupus]
+ {buildin_summon,"summon","si*"}, // summons a slave monster [Celest]
+ {buildin_isnight,"isnight",""}, // check whether it is night time [Celest]
+ {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]
+ {buildin_cardscnt,"cardscnt","i*"}, // check how many items/cards are being equipped in the same arm [Lupus]
+ {buildin_getrefine,"getrefine","*"}, // returns the refined number of the current item, or an item with index specified [celest]
+ {buildin_adopt,"adopt","sss"}, // allows 2 parents to adopt a child
+ {buildin_night,"night",""}, // sets the server to night time
+ {buildin_day,"day",""}, // sets the server to day time
+#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
+ {buildin_dispbottom,"dispbottom","s"}, //added from jA [Lupus]
+ {buildin_getusersname,"getusersname","*"},
+ {buildin_recovery,"recovery",""},
+ {buildin_getpetinfo,"getpetinfo","i"},
+ {buildin_checkequipedcard,"checkequipedcard","i"},
+ {buildin_jump_zero,"jump_zero","ii"}, //for future jA script compatibility
+ {buildin_select,"select","*"}, //for future jA script compatibility
+ {buildin_globalmes,"globalmes","s*"},
+ {buildin_getmapmobs,"getmapmobs","s"}, //end jA addition
+ {buildin_unequip,"unequip","i"}, // unequip command [Spectre]
+ {buildin_getstrlen,"getstrlen","s"}, //strlen [Valaris]
+ {buildin_charisalpha,"charisalpha","si"}, //isalpha [Valaris]
+ {buildin_fakenpcname,"fakenpcname","ssi"}, // [Lance]
+ {buildin_compare,"compare","ss"}, // Lordalfa - To bring strstr to scripting Engine.
+ {buildin_getiteminfo,"getiteminfo","ii"}, //[Lupus] returns Items Buy / sell Price, etc info
+ {buildin_getequipcardid,"getequipcardid","ii"}, //[Lupus] returns CARD ID or other info from CARD slot N of equipped item
+ // [zBuffer] List of mathematics commands --->
+ {buildin_sqrt,"sqrt","i"},
+ {buildin_pow,"pow","ii"},
+ {buildin_distance,"distance","iiii"},
+ {buildin_checkcell,"checkcell","siii"},
+ // <--- [zBuffer] List of mathematics commands
+ // [zBuffer] List of dynamic var commands --->
+ {buildin_getd,"getd","*"},
+ {buildin_setd,"setd","*"},
+ // <--- [zBuffer] List of dynamic var commands
+ {buildin_petstat,"petstat","i"},
+ {buildin_callshop,"callshop","si"}, // [Skotlex]
+ {buildin_npcshopitem,"npcshopitem","sii*"}, // [Lance]
+ {buildin_npcshopadditem,"npcshopadditem","sii*"},
+ {buildin_npcshopdelitem,"npcshopdelitem","si*"},
+ {buildin_equip,"equip","i"},
+ {buildin_autoequip,"autoequip","ii"},
+ {buildin_setbattleflag,"setbattleflag","ss"},
+ {buildin_getbattleflag,"getbattleflag","s"},
+ {buildin_setitemscript,"setitemscript","is"}, //Set NEW item bonus script. Lupus
+ {buildin_disguise,"disguise","i"}, //disguise player. Lupus
+ {buildin_undisguise,"undisguise","i"}, //undisguise player. Lupus
+ {buildin_getmonsterinfo,"getmonsterinfo","ii"}, //Lupus
+ {buildin_axtoi,"axtoi","s"},
+#ifndef TXT_ONLY
+ {buildin_query_sql, "query_sql", "s*"},
+ {buildin_escape_sql, "escape_sql", "s"},
+#endif
+ {buildin_atoi,"atoi","s"},
+ // [zBuffer] List of player cont commands --->
+ {buildin_rid2name,"rid2name","i"},
+ {buildin_pcfollow,"pcfollow","ii"},
+ {buildin_pcstopfollow,"pcstopfollow","i"},
+ {buildin_pcblockmove,"pcblockmove","ii"},
+ // <--- [zBuffer] List of player cont commands
+ // [zBuffer] List of mob control commands --->
+ {buildin_mobspawn,"mobspawn","*"},
+ {buildin_mobremove,"mobremove","i"},
+ {buildin_getmobdata,"getmobdata","i*"},
+ {buildin_setmobdata,"setmobdata","iii"},
+ {buildin_mobassist,"mobassist","i*"},
+ {buildin_mobattach,"mobattach","i*"},
+ {buildin_unitwalk,"unitwalk","i*"},
+ {buildin_unitkill,"unitkill","i"},
+ {buildin_unitwarp,"unitwarp","isii"},
+ {buildin_unitattack,"unitattack","i*"},
+ {buildin_unitstop,"unitstop","i"},
+ {buildin_unittalk,"unittalk","is"},
+ {buildin_unitemote,"unitemote","ii"},
+ {buildin_unitdeadsit,"unitdeadsit","ii"},
+ {buildin_unitskilluseid,"unitskilluseid","iii*"}, // originally by Qamera [Celest]
+ {buildin_unitskillusepos,"unitskillusepos","iiiii"}, // [Celest]
+// <--- [zBuffer] List of mob control commands
+ {buildin_sleep,"sleep","i"},
+ {buildin_sleep2,"sleep2","i"},
+ {buildin_awake,"awake","s"},
+ {buildin_getvariableofnpc,"getvariableofnpc","is"},
+ // [blackhole89] -->
+ {buildin_warpportal,"warpportal","iisii"},
+ // <--- [blackhole89]
+ {buildin_homunculus_evolution,"homevolution",""}, //[orn]
+ {NULL,NULL,NULL},
+};
+
/*==========================================
*
*------------------------------------------
@@ -2766,16 +3969,15 @@ int buildin_goto(struct script_state *st)
{
int pos;
- if (st->stack->stack_data[st->start+2].type != C_POS){
- int func = st->stack->stack_data[st->start+2].u.num;
- ShowMessage("script: goto '"CL_WHITE"%s"CL_RESET"': not label!\n", str_buf + str_data[func].str);
- st->state = END;
+ if( st->stack->stack_data[st->start+2].type!=C_POS){
+ ShowMessage("script: goto: not label!\n");
+ st->state=END;
return 1;
}
- pos = conv_num(st,& (st->stack->stack_data[st->start+2]));
- st->pos = pos;
- st->state = GOTO;
+ pos=conv_num(st,& (st->stack->stack_data[st->start+2]));
+ st->pos=pos;
+ st->state=GOTO;
return 0;
}
@@ -2788,7 +3990,7 @@ int buildin_callfunc(struct script_state *st)
struct script_code *scr, *oldscr;
char *str=conv_str(st,& (st->stack->stack_data[st->start+2]));
- if( (scr=(struct script_code *) strdb_get(userfunc_db,(unsigned char*)str)) ){
+ if( (scr=strdb_get(userfunc_db,(unsigned char*)str)) ){
int i,j;
struct linkdb_node **oldval = st->stack->var_function;
for(i=st->start+3,j=0;i<st->end;i++,j++)
@@ -2841,6 +4043,7 @@ int buildin_callsub(struct script_state *st)
return 1;
} else {
struct linkdb_node **oldval = st->stack->var_function;
+
for(i=st->start+3,j=0;i<st->end;i++,j++)
push_copy(st->stack,i);
@@ -2956,22 +4159,31 @@ int buildin_menu(struct script_state *st)
{
char *buf;
int len,i;
- struct map_session_data *sd;
+ struct map_session_data *sd = script_rid2sd(st);
- sd=script_rid2sd(st);
+ nullpo_retr(0, sd);
if(sd->state.menu_or_input==0){
st->state=RERUNLINE;
sd->state.menu_or_input=1;
- for(i=st->start+2,len=16;i<st->end;i+=2){
+ if( (st->end - st->start - 2) % 2 == 1 ) {
+ // 引数の数が奇数なのでエラー扱い
+ ShowError("buildin_menu: illigal argument count(%d).\n", st->end - st->start - 2);
+ sd->state.menu_or_input=0;
+ st->state=END;
+ return 1;
+ }
+ for(i=st->start+2,len=0;i<st->end;i+=2){
conv_str(st,& (st->stack->stack_data[i]));
len+=(int)strlen(st->stack->stack_data[i].u.str)+1;
}
buf=(char *)aMallocA((len+1)*sizeof(char));
buf[0]=0;
for(i=st->start+2,len=0;i<st->end;i+=2){
- strcat(buf,st->stack->stack_data[i].u.str);
- strcat(buf,":");
+ if( st->stack->stack_data[i].u.str[0] ) {
+ strcat(buf,st->stack->stack_data[i].u.str);
+ strcat(buf,":");
+ }
}
clif_scriptmenu(script_rid2sd(st),st->oid,buf);
aFree(buf);
@@ -2982,8 +4194,7 @@ int buildin_menu(struct script_state *st)
sd->state.menu_or_input=0;
if(sd->npc_menu>0){
//Skip empty menu entries which weren't displayed on the client (blackhole89)
- for(i=st->start+2;i<=(st->start+sd->npc_menu*2) && sd->npc_menu<(st->end-st->start)/2;i+=2)
- {
+ for(i=st->start+2;i<=(st->start+sd->npc_menu*2) && sd->npc_menu<(st->end-st->start)/2;i+=2) {
conv_str(st,& (st->stack->stack_data[i])); // we should convert variables to strings before access it [jA1983] [EoE]
if((int)strlen(st->stack->stack_data[i].u.str) < 1)
sd->npc_menu++; //Empty selection which wasn't displayed on the client.
@@ -2999,7 +4210,7 @@ int buildin_menu(struct script_state *st)
return 1;
}
pc_setreg(sd,add_str((unsigned char *) "@menu"),sd->npc_menu);
- st->pos= conv_num(st,& (st->stack->stack_data[st->start+sd->npc_menu*2+1]));
+ st->pos=conv_num(st,& (st->stack->stack_data[st->start+sd->npc_menu*2+1]));
st->state=GOTO;
}
}
@@ -3012,17 +4223,16 @@ int buildin_menu(struct script_state *st)
*/
int buildin_rand(struct script_state *st)
{
- int range;
+ int range,min,max;
if (st->end > st->start+3){
- int min, max;
min = conv_num(st,& (st->stack->stack_data[st->start+2]));
max = conv_num(st,& (st->stack->stack_data[st->start+3]));
if (max == min){ //Why would someone do this?
push_val(st->stack,C_INT,min);
return 0;
}
- if (max < min){
+ if(max<min){
int tmp = min;
min = max;
max = tmp;
@@ -3048,6 +4258,8 @@ int buildin_warp(struct script_state *st)
char *str;
struct map_session_data *sd=script_rid2sd(st);
+ nullpo_retr(0, sd);
+
str=conv_str(st,& (st->stack->stack_data[st->start+2]));
x=conv_num(st,& (st->stack->stack_data[st->start+3]));
y=conv_num(st,& (st->stack->stack_data[st->start+4]));
@@ -3411,13 +4623,13 @@ int buildin_jobchange(struct script_state *st)
*/
int buildin_input(struct script_state *st)
{
- struct map_session_data *sd=NULL;
- int num=(st->end>st->start+2)?st->stack->stack_data[st->start+2].u.num:0;
- char *name=(char *) ((st->end>st->start+2)?str_buf+str_data[num&0x00ffffff].str:"");
-// char prefix=*name;
+ struct map_session_data *sd = script_rid2sd(st);
+ int num = (st->end>st->start+2)? st->stack->stack_data[st->start+2].u.num: 0;
+ char *name = (st->end>st->start+2)? str_buf+str_data[num&0x00ffffff].str: "";
char postfix=name[strlen(name)-1];
- sd=script_rid2sd(st);
+ nullpo_retr(0, sd);
+
if(sd->state.menu_or_input){
sd->state.menu_or_input=0;
if( postfix=='$' ){
@@ -3479,7 +4691,6 @@ int buildin_set(struct script_state *st)
if(not_server_variable(prefix))
sd=script_rid2sd(st);
-
if( postfix=='$' ){
// 文字列
char *str = conv_str(st,& (st->stack->stack_data[st->start+3]));
@@ -3492,6 +4703,7 @@ int buildin_set(struct script_state *st)
return 0;
}
+
/*==========================================
* 配列変数設定
*------------------------------------------
@@ -6905,13 +8117,6 @@ int buildin_isloggedin(struct script_state *st)
*
*------------------------------------------
*/
-enum { MF_NOMEMO,MF_NOTELEPORT,MF_NOSAVE,MF_NOBRANCH,MF_NOPENALTY,MF_NOZENYPENALTY,
- MF_PVP,MF_PVP_NOPARTY,MF_PVP_NOGUILD,MF_GVG,MF_GVG_NOPARTY,MF_NOTRADE,MF_NOSKILL,
- MF_NOWARP,MF_FREE,MF_NOICEWALL,MF_SNOW,MF_FOG,MF_SAKURA,MF_LEAVES,MF_RAIN,
- MF_INDOORS,MF_NOGO,MF_CLOUDS,MF_CLOUDS2,MF_FIREWORKS,MF_GVG_CASTLE,MF_GVG_DUNGEON,MF_NIGHTENABLED,
- MF_NOBASEEXP, MF_NOJOBEXP, MF_NOMOBLOOT, MF_NOMVPLOOT, MF_NORETURN, MF_NOWARPTO, MF_NIGHTMAREDROP,
- MF_RESTRICTED, MF_NOCOMMAND, MF_NODROP, MF_JEXP, MF_BEXP, MF_NOVENDING, MF_LOADEVENT, MF_NOCHAT };
-
int buildin_setmapflagnosave(struct script_state *st)
{
int m,x,y;
@@ -10275,7 +11480,7 @@ int buildin_setitemscript(struct script_state *st)
if (i_data && script!=NULL && script[0]=='{') {
if(i_data->script!=NULL)
script_free_code(i_data->script);
- i_data->script = parse_script((unsigned char *) script, 0);
+ i_data->script = parse_script((unsigned char *) script, "script_setitemscript", 0);
push_val(st->stack,C_INT,1);
} else
push_val(st->stack,C_INT,0);
@@ -10399,6 +11604,47 @@ int buildin_getmonsterinfo(struct script_state *st)
return 0;
}
+int axtoi(char *hexStg) {
+ int n = 0; // position in string
+ int m = 0; // position in digit[] to shift
+ int count; // loop index
+ int intValue = 0; // integer value of hex string
+ int digit[11]; // hold values to convert
+ while (n < 10) {
+ if (hexStg[n]=='\0')
+ break;
+ if (hexStg[n] > 0x29 && hexStg[n] < 0x40 ) //if 0 to 9
+ digit[n] = hexStg[n] & 0x0f; //convert to int
+ else if (hexStg[n] >='a' && hexStg[n] <= 'f') //if a to f
+ digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int
+ else if (hexStg[n] >='A' && hexStg[n] <= 'F') //if A to F
+ digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int
+ else break;
+ n++;
+ }
+ count = n;
+ m = n - 1;
+ n = 0;
+ while(n < count) {
+ // digit[n] is value of hex digit at position n
+ // (m << 2) is the number of positions to shift
+ // OR the bits into return value
+ intValue = intValue | (digit[n] << (m << 2));
+ m--; // adjust the position to set
+ n++; // next digit to process
+ }
+ return (intValue);
+}
+
+// [Lance] Hex string to integer converter
+int buildin_axtoi(struct script_state *st)
+{
+ char *hex = conv_str(st,& (st->stack->stack_data[st->start+2]));
+ push_val(st->stack, C_INT, axtoi(hex));
+ return 0;
+}
+
+
// [zBuffer] List of player cont commands --->
int buildin_rid2name(struct script_state *st){
struct block_list *bl = NULL;
@@ -11078,1206 +12324,3 @@ int buildin_warpportal(struct script_state *st){
// <-- [blackhole89]
-//
-// 実行部main
-//
-/*==========================================
- * コマンドの読み取り
- *------------------------------------------
- */
-static int unget_com_data=-1;
-int get_com(unsigned char *script,int *pos)
-{
- int i,j;
- if(unget_com_data>=0){
- i=unget_com_data;
- unget_com_data=-1;
- return i;
- }
- if(script[*pos]>=0x80){
- return C_INT;
- }
- i=0; j=0;
- while(script[*pos]>=0x40){
- i=script[(*pos)++]<<j;
- j+=6;
- }
- return i+(script[(*pos)++]<<j);
-}
-
-/*==========================================
- * コマンドのプッシュバック
- *------------------------------------------
- */
-void unget_com(int c)
-{
- if(unget_com_data!=-1){
- if(battle_config.error_log)
- ShowError("unget_com can back only 1 data\n");
- }
- unget_com_data=c;
-}
-
-/*==========================================
- * 数値の所得
- *------------------------------------------
- */
-int get_num(unsigned char *script,int *pos)
-{
- int i,j;
- i=0; j=0;
- while(script[*pos]>=0xc0){
- i+=(script[(*pos)++]&0x7f)<<j;
- j+=6;
- }
- return i+((script[(*pos)++]&0x7f)<<j);
-}
-
-/*==========================================
- * スタックから値を取り出す
- *------------------------------------------
- */
-int pop_val(struct script_state* st)
-{
- if(st->stack->sp<=0)
- return 0;
- st->stack->sp--;
- get_val(st,&(st->stack->stack_data[st->stack->sp]));
- if(st->stack->stack_data[st->stack->sp].type==C_INT)
- return st->stack->stack_data[st->stack->sp].u.num;
- return 0;
-}
-
-#define isstr(c) ((c).type==C_STR || (c).type==C_CONSTSTR)
-
-/*==========================================
- * 加算演算子
- *------------------------------------------
- */
-void op_add(struct script_state* st)
-{
- st->stack->sp--;
- get_val(st,&(st->stack->stack_data[st->stack->sp]));
- get_val(st,&(st->stack->stack_data[st->stack->sp-1]));
-
- if(isstr(st->stack->stack_data[st->stack->sp]) || isstr(st->stack->stack_data[st->stack->sp-1])){
- conv_str(st,&(st->stack->stack_data[st->stack->sp]));
- conv_str(st,&(st->stack->stack_data[st->stack->sp-1]));
- }
- if(st->stack->stack_data[st->stack->sp].type==C_INT){ // ii
- st->stack->stack_data[st->stack->sp-1].u.num += st->stack->stack_data[st->stack->sp].u.num;
- } else { // ssの予定
- char *buf;
- buf=(char *)aMallocA((strlen(st->stack->stack_data[st->stack->sp-1].u.str)+
- strlen(st->stack->stack_data[st->stack->sp].u.str)+1)*sizeof(char));
- strcpy(buf,st->stack->stack_data[st->stack->sp-1].u.str);
- strcat(buf,st->stack->stack_data[st->stack->sp].u.str);
- if(st->stack->stack_data[st->stack->sp-1].type==C_STR)
- {
- aFree(st->stack->stack_data[st->stack->sp-1].u.str);
- st->stack->stack_data[st->stack->sp-1].type=C_INT;
- }
- if(st->stack->stack_data[st->stack->sp].type==C_STR)
- {
- aFree(st->stack->stack_data[st->stack->sp].u.str);
- st->stack->stack_data[st->stack->sp].type=C_INT;
- }
- st->stack->stack_data[st->stack->sp-1].type=C_STR;
- st->stack->stack_data[st->stack->sp-1].u.str=buf;
- }
-}
-
-/*==========================================
- * 二項演算子(文字列)
- *------------------------------------------
- */
-void op_2str(struct script_state *st,int op,int sp1,int sp2)
-{
- char *s1=st->stack->stack_data[sp1].u.str,
- *s2=st->stack->stack_data[sp2].u.str;
- int a=0;
-
- switch(op){
- case C_EQ:
- a= (strcmp(s1,s2)==0);
- break;
- case C_NE:
- a= (strcmp(s1,s2)!=0);
- break;
- case C_GT:
- a= (strcmp(s1,s2)> 0);
- break;
- case C_GE:
- a= (strcmp(s1,s2)>=0);
- break;
- case C_LT:
- a= (strcmp(s1,s2)< 0);
- break;
- case C_LE:
- a= (strcmp(s1,s2)<=0);
- break;
- default:
- ShowWarning("script: illegal string operator\n");
- break;
- }
-
- // Because push_val() overwrite stack_data[sp1], C_STR on stack_data[sp1] won't be freed.
- // So, call push_val() after freeing strings. [jA1783]
- // push_val(st->stack,C_INT,a);
- if(st->stack->stack_data[sp1].type==C_STR)
- {
- aFree(s1);
- st->stack->stack_data[sp1].type=C_INT;
- }
- if(st->stack->stack_data[sp2].type==C_STR)
- {
- aFree(s2);
- st->stack->stack_data[sp2].type=C_INT;
- }
- push_val(st->stack,C_INT,a);
-}
-/*==========================================
- * 二項演算子(数値)
- *------------------------------------------
- */
-void op_2num(struct script_state *st,int op,int i1,int i2)
-{
- switch(op){
- case C_SUB:
- i1-=i2;
- break;
- case C_MUL:
- {
- #ifndef _MSC_VER
- long long res = i1 * i2;
- #else
- __int64 res = i1 * i2;
- #endif
- if (res > 2147483647 )
- i1 = 2147483647;
- else
- i1*=i2;
- }
- break;
- case C_DIV:
- if (i2 != 0)
- i1/=i2;
- else
- ShowWarning("op_2num: Attempted to divide by 0 in a script (operation C_DIV)!\n");
- break;
- case C_MOD:
- if (i2 != 0)
- i1%=i2;
- else
- ShowWarning("op_2num: Attempted to divide by 0 in a script (operation C_MOD)!\n");
- break;
- case C_AND:
- i1&=i2;
- break;
- case C_OR:
- i1|=i2;
- break;
- case C_XOR:
- i1^=i2;
- break;
- case C_LAND:
- i1=i1&&i2;
- break;
- case C_LOR:
- i1=i1||i2;
- break;
- case C_EQ:
- i1=i1==i2;
- break;
- case C_NE:
- i1=i1!=i2;
- break;
- case C_GT:
- i1=i1>i2;
- break;
- case C_GE:
- i1=i1>=i2;
- break;
- case C_LT:
- i1=i1<i2;
- break;
- case C_LE:
- i1=i1<=i2;
- break;
- case C_R_SHIFT:
- i1=i1>>i2;
- break;
- case C_L_SHIFT:
- i1=i1<<i2;
- break;
- }
- push_val(st->stack,C_INT,i1);
-}
-/*==========================================
- * 二項演算子
- *------------------------------------------
- */
-void op_2(struct script_state *st,int op)
-{
- int i1,i2;
- char *s1=NULL,*s2=NULL;
-
- i2=pop_val(st);
- if( isstr(st->stack->stack_data[st->stack->sp]) )
- s2=st->stack->stack_data[st->stack->sp].u.str;
-
- i1=pop_val(st);
- if( isstr(st->stack->stack_data[st->stack->sp]) )
- s1=st->stack->stack_data[st->stack->sp].u.str;
-
- if( s1!=NULL && s2!=NULL ){
- // ss => op_2str
- op_2str(st,op,st->stack->sp,st->stack->sp+1);
- }else if( s1==NULL && s2==NULL ){
- // ii => op_2num
- op_2num(st,op,i1,i2);
- }else{
- // si,is => error
- ShowWarning("script: op_2: int&str, str&int not allow.\n");
- report_src(st);
- push_val(st->stack,C_INT,0);
- }
-}
-
-/*==========================================
- * 単項演算子
- *------------------------------------------
- */
-void op_1num(struct script_state *st,int op)
-{
- int i1;
- i1=pop_val(st);
- switch(op){
- case C_NEG:
- i1=-i1;
- break;
- case C_NOT:
- i1=~i1;
- break;
- case C_LNOT:
- i1=!i1;
- break;
- }
- push_val(st->stack,C_INT,i1);
-}
-
-
-/*==========================================
- * 関数の実行
- *------------------------------------------
- */
-int run_func(struct script_state *st)
-{
- int i,start_sp,end_sp,func;
-
- end_sp=st->stack->sp;
- for(i=end_sp-1;i>=0 && st->stack->stack_data[i].type!=C_ARG;i--);
- if(i==0){
- if(battle_config.error_log)
- ShowError("function not found\n");
-// st->stack->sp=0;
- st->state=END;
- report_src(st);
- return 1;
- }
- start_sp=i-1;
- st->start=i-1;
- st->end=end_sp;
-
- func=st->stack->stack_data[st->start].u.num;
- if( st->stack->stack_data[st->start].type!=C_NAME || str_data[func].type!=C_FUNC ){
- ShowMessage ("run_func: '"CL_WHITE"%s"CL_RESET"' (type %d) is not function and command!\n",
- str_buf + str_data[func].str, str_data[func].type);
-// st->stack->sp=0;
- st->state=END;
- report_src(st);
- return 1;
- }
-#ifdef DEBUG_RUN
- if(battle_config.etc_log) {
- ShowDebug("run_func : %s? (%d(%d)) sp=%d (%d...%d)\n",str_buf+str_data[func].str, func, str_data[func].type, st->stack->sp, st->start, st->end);
- ShowDebug("stack dump :");
- for(i=0;i<end_sp;i++){
- switch(st->stack->stack_data[i].type){
- case C_INT:
- printf(" int(%d)",st->stack->stack_data[i].u.num);
- break;
- case C_NAME:
- printf(" name(%s)",str_buf+str_data[st->stack->stack_data[i].u.num].str);
- break;
- case C_ARG:
- printf(" arg");
- break;
- case C_POS:
- printf(" pos(%d)",st->stack->stack_data[i].u.num);
- break;
- case C_STR:
- printf(" str(%s)",st->stack->stack_data[i].u.str);
- break;
- case C_CONSTSTR:
- printf(" cstr(%s)",st->stack->stack_data[i].u.str);
- break;
- default:
- printf(" %d,%d",st->stack->stack_data[i].type,st->stack->stack_data[i].u.num);
- }
- }
- printf("\n");
- }
-#endif
- if(str_data[func].func){
- if (str_data[func].func(st)) //Report error
- report_src(st);
- } else {
- if(battle_config.error_log)
- ShowError("run_func : %s? (%d(%d))\n",str_buf+str_data[func].str,func,str_data[func].type);
- push_val(st->stack,C_INT,0);
- report_src(st);
- }
-
- // Stack's datum are used when re-run functions [Eoe]
- if(st->state != RERUNLINE) {
- pop_stack(st->stack,start_sp,end_sp);
- }
-
- if(st->state==RETFUNC){
- // ユーザー定義関数からの復帰
- int olddefsp=st->stack->defsp;
- int i;
-
- pop_stack(st->stack,st->stack->defsp,start_sp); // 復帰に邪魔なスタック削除
- if(st->stack->defsp<5 || st->stack->stack_data[st->stack->defsp-1].type!=C_RETINFO){
- ShowWarning("script:run_func(return) return without callfunc or callsub!\n");
- st->state=END;
- report_src(st);
- return 1;
- }
- script_free_vars( st->stack->var_function );
- aFree(st->stack->var_function);
- i = conv_num(st,& (st->stack->stack_data[st->stack->defsp-5])); // 引数の数所得
- st->pos=conv_num(st,& (st->stack->stack_data[st->stack->defsp-1])); // スクリプト位置の復元
- st->script=(struct script_code *)conv_num(st,& (st->stack->stack_data[st->stack->defsp-3])); // スクリプトを復元
- st->stack->var_function = (struct linkdb_node**)st->stack->stack_data[st->stack->defsp-2].u.num; // 関数依存変数
- st->stack->defsp=conv_num(st,& (st->stack->stack_data[st->stack->defsp-4])); // 基準スタックポインタを復元
-
- pop_stack(st->stack,olddefsp-5-i,olddefsp); // 要らなくなったスタック(引数と復帰用データ)削除
-
- st->state=GOTO;
- }
-
- return 0;
-}
-
-/*==========================================
- * スクリプトの実行メイン部分
- *------------------------------------------
- */
-void run_script_main(struct script_state *st)
-{
- int c/*,rerun_pos*/;
- int cmdcount=script_config.check_cmdcount;
- int gotocount=script_config.check_gotocount;
- struct script_stack *stack=st->stack;
- TBL_PC *sd = map_id2sd(st->rid);
- struct script_state *bk_st = NULL;
- int bk_npcid = 0;
-
- if(sd){
- if(sd->st != st){
- bk_st = sd->st;
- bk_npcid = sd->npc_id;
- }
- sd->st = st;
- sd->npc_id = st->oid;
- }
-
- if(st->state == RERUNLINE) {
- st->state = RUN;
- run_func(st);
- if(st->state == GOTO)
- st->state = RUN;
- } else if(st->state != END)
- st->state = RUN;
-
- while( st->state == RUN) {
- c= get_com((unsigned char *) st->script->script_buf,&st->pos);
- switch(c){
- case C_EOL:
- if(stack->sp!=stack->defsp){
- if(stack->sp > stack->defsp)
- { //sp > defsp is valid in cases when you invoke functions and don't use the returned value. [Skotlex]
- //Since sp is supposed to be defsp in these cases, we could assume the extra stack elements are unneeded.
- if (battle_config.etc_log)
- ShowWarning("Clearing unused stack stack.sp(%d) -> default(%d)\n",stack->sp,stack->defsp);
- pop_stack(stack, stack->defsp, stack->sp); //Clear out the unused stack-section.
- } else if(battle_config.error_log)
- ShowError("stack.sp(%d) != default(%d)\n",stack->sp,stack->defsp);
- stack->sp=stack->defsp;
- }
- // rerun_pos=st->pos;
- break;
- case C_INT:
- push_val(stack,C_INT,get_num((unsigned char *) st->script->script_buf,&st->pos));
- break;
- case C_POS:
- case C_NAME:
- push_val(stack,c,(*(int*)(st->script->script_buf+st->pos))&0xffffff);
- st->pos+=3;
- break;
- case C_ARG:
- push_val(stack,c,0);
- break;
- case C_STR:
- push_str(stack,C_CONSTSTR,(unsigned char *) (st->script->script_buf+st->pos));
- while(st->script->script_buf[st->pos++]);
- break;
- case C_FUNC:
- run_func(st);
- if(st->state==GOTO){
- // rerun_pos=st->pos;
- st->state=RUN;
- if( gotocount>0 && (--gotocount)<=0 ){
- ShowError("run_script: infinity loop !\n");
- st->state=END;
- }
- }
- break;
-
- case C_ADD:
- op_add(st);
- break;
-
- case C_SUB:
- case C_MUL:
- case C_DIV:
- case C_MOD:
- case C_EQ:
- case C_NE:
- case C_GT:
- case C_GE:
- case C_LT:
- case C_LE:
- case C_AND:
- case C_OR:
- case C_XOR:
- case C_LAND:
- case C_LOR:
- case C_R_SHIFT:
- case C_L_SHIFT:
- op_2(st,c);
- break;
-
- case C_NEG:
- case C_NOT:
- case C_LNOT:
- op_1num(st,c);
- break;
-
- case C_NOP:
- st->state=END;
- break;
-
- default:
- if(battle_config.error_log)
- ShowError("unknown command : %d @ %d\n",c,pos);
- st->state=END;
- break;
- }
- if( cmdcount>0 && (--cmdcount)<=0 ){
- ShowError("run_script: infinity loop !\n");
- st->state=END;
- }
- }
- switch(st->state){
- case STOP:
- break;
- case END:
- {
- st->pos=-1;
- if(sd){
- if(sd->state.using_fake_npc){
- clif_clearchar_id(sd->npc_id, 0, sd->fd);
- sd->state.using_fake_npc = 0;
- }
- npc_event_dequeue(sd);
- //Restore previous script if any.
- sd->st = bk_st;
- sd->npc_id = bk_npcid;
- bk_st = NULL; //Remove tag for removal.
- if (sd->state.reg_dirty&2)
- intif_saveregistry(sd,2);
- if (sd->state.reg_dirty&1)
- intif_saveregistry(sd,1);
- }
- //Remove unneeded script.
- script_free_stack (st->stack);
- aFree(st);
- }
- break;
- case RERUNLINE:
- if(bk_st && sd->st != bk_st && st->sleep.tick <= 0)
- ShowWarning("Unable to restore stack! Double continuation!\n");
-
- if(st->sleep.tick > 0)
- { //Delay execution
- if(sd)
- st->sleep.charid = sd->char_id;
- else
- st->sleep.charid = 0;
- st->sleep.timer = add_timer(gettick()+st->sleep.tick,
- run_script_timer, st->sleep.charid, (int)st);
- linkdb_insert(&sleep_db, (void*)st->oid, st);
- //Restore previous script/
- sd->st = bk_st;
- sd->npc_id = bk_npcid;
- bk_st = NULL; //Remove tag for removal.
- }
- // Do not call function of commands two time! [ Eoe / jA 1094 ]
- // For example: select "1", "2", callsub(...);
- // If current script position is changed, callsub will be called two time.
- //
- // {
- // st->pos=rerun_pos;
- // }
- break;
- }
-
- if (bk_st)
- { //Remove previous script
- script_free_stack(bk_st->stack);
- aFree(bk_st);
- bk_st = NULL;
- }
-
- //FIXME: Is it correct to NOT free the script when the state is not END AND there's NO PLAYER running it??
- return;
-}
-
-/*==========================================
- * スクリプトの実行
- *------------------------------------------
- */
-void run_script(struct script_code *rootscript,int pos,int rid,int oid)
-{
- struct script_state *st;
- struct map_session_data *sd=NULL;
-
- //Variables for backing up the previous script and restore it if needed. [Skotlex]
- //struct script_code *bck_script = NULL;
- //struct script_code *bck_scriptroot = NULL;
- //int bck_scriptstate = 0,bck_npcid = 0;
- //struct script_stack *bck_stack = NULL;
-
- if (rootscript == NULL || pos < 0)
- return;
-
- if ((sd = map_id2sd(rid)) && sd->st && sd->st->scriptroot == rootscript && sd->st->pos == pos){
- st = sd->st;
- } else {
- st = aCalloc(sizeof(struct script_state), 1);
- // the script is different, make new script_state and stack
- st->stack = aMalloc (sizeof(struct script_stack));
- st->stack->sp = 0;
- st->stack->sp_max = 64;
- st->stack->stack_data = (struct script_data *) aCalloc (st->stack->sp_max,sizeof(st->stack->stack_data[0]));
- st->stack->defsp = st->stack->sp;
- st->stack->var_function = aCalloc(1, sizeof(struct linkdb_node*));
- st->state = RUN;
- st->script = rootscript;
-
- /*if (sd){
- if(sd->stack) {
- // if there's a sd and a stack - back it up and restore it if possible.
- bck_script = sd->npc_script;
- bck_scriptroot = sd->npc_scriptroot;
- bck_scriptstate = sd->npc_scriptstate;
- bck_stack = sd->stack;
- sd->stack = NULL;
- }
- bck_npcid = sd->npc_id;
- sd->npc_id = oid;
- }*/
- }
- st->pos = pos;
- st->rid = rid;
- st->oid = oid;
- st->sleep.timer = -1;
-
- run_script_main(st);
- /* if (st->state != END){
- pos = st->pos;
- if(!st->sleep.tick && sd) {
- // script is not finished, store data in sd.
- sd->npc_script = st->script;
- sd->npc_scriptroot = rootscript;
- sd->npc_scriptstate = st->state;
- sd->stack = st->stack;
- if (bck_stack) //Get rid of the backup as it can't be restored.
- script_free_stack (bck_stack);
- aFree(st);
- }
- return pos;
- } else {
- if(st->stack)
- script_free_stack(st->stack);
- aFree(st);
- }
- } else {
- //Script finished.
- if (sd)
- { //Clear or restore previous script.
- sd->npc_script = bck_script;
- sd->npc_scriptroot = bck_scriptroot;
- sd->npc_scriptstate = bck_scriptstate;
- sd->stack = bck_stack;
- sd->npc_id = bck_npcid;
- //Since the script is done, save any changed account variables [Skotlex]
- if (sd->state.reg_dirty&2)
- intif_saveregistry(sd,2);
- if (sd->state.reg_dirty&1)
- intif_saveregistry(sd,1);
- }
- }*/
- return;
-}
-
-/*==========================================
- * 指定ノードをsleep_dbから削除
- *------------------------------------------
- */
-struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n)
-{
- struct linkdb_node *retnode;
-
- if( n == NULL)
- return NULL;
- if( n->prev == NULL )
- sleep_db = n->next;
- else
- n->prev->next = n->next;
- if( n->next )
- n->next->prev = n->prev;
- retnode = n->next;
- aFree( n );
- return retnode; // 次のノードを返す
-}
-
-
-/*==========================================
- * sleep用タイマー関数
- *------------------------------------------
- */
-int run_script_timer(int tid, unsigned int tick, int id, int data)
-{
- struct script_state *st = (struct script_state *)data;
- struct linkdb_node *node = (struct linkdb_node *)sleep_db;
- struct map_session_data *sd = map_id2sd(st->rid);
-
- if((sd && sd->char_id != id) || (st->rid && !sd))
- { //Character mismatch. Cancel execution.
- st->rid = 0;
- st->state = END;
- }
-
- while( node && st->sleep.timer != -1 ) {
- if( (int)node->key == st->oid && ((struct script_state *)node->data)->sleep.timer == st->sleep.timer ) {
- script_erase_sleepdb(node);
- st->sleep.timer = -1;
- break;
- }
- node = node->next;
- }
-
- run_script_main(st);
- return 0;
-}
-
-
-/*==========================================
- * マップ変数の変更
- *------------------------------------------
- */
-int mapreg_setreg(int num,int val)
-{
-#if !defined(TXT_ONLY) && defined(MAPREGSQL)
- int i=num>>24;
- char *name=str_buf+str_data[num&0x00ffffff].str;
- char tmp_str[64];
-#endif
-
- if(val!=0) {
- if(idb_put(mapreg_db,num,(void*)val))
- ;
-#if !defined(TXT_ONLY) && defined(MAPREGSQL)
- else if(name[1] != '@') {
- sprintf(tmp_sql,"INSERT INTO `%s`(`%s`,`%s`,`%s`) VALUES ('%s','%d','%d')",mapregsql_db,mapregsql_db_varname,mapregsql_db_index,mapregsql_db_value,jstrescapecpy(tmp_str,name),i,val);
- if(mysql_query(&mmysql_handle,tmp_sql)){
- ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
- ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
- }
- }
-#endif
- // else
- } else { // [zBuffer]
-#if !defined(TXT_ONLY) && defined(MAPREGSQL)
- if(name[1] != '@') { // Remove from database because it is unused.
- sprintf(tmp_sql,"DELETE FROM `%s` WHERE `%s`='%s' AND `%s`='%d'",mapregsql_db,mapregsql_db_varname,name,mapregsql_db_index,i);
- if(mysql_query(&mmysql_handle,tmp_sql)){
- ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
- ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
- }
- }
-#endif
- idb_remove(mapreg_db,num);
- }
-
- mapreg_dirty=1;
- return 0;
-}
-/*==========================================
- * 文字列型マップ変数の変更
- *------------------------------------------
- */
-int mapreg_setregstr(int num,const char *str)
-{
- char *p;
-#if !defined(TXT_ONLY) && defined(MAPREGSQL)
- char tmp_str[64];
- char tmp_str2[512];
- int i=num>>24; // [zBuffer]
- char *name=str_buf+str_data[num&0x00ffffff].str;
-#endif
-
- if( str==NULL || *str==0 ){
-#if !defined(TXT_ONLY) && defined(MAPREGSQL)
- if(name[1] != '@') {
- sprintf(tmp_sql,"DELETE FROM `%s` WHERE `%s`='%s' AND `%s`='%d'",mapregsql_db,mapregsql_db_varname,name,mapregsql_db_index,i);
- if(mysql_query(&mmysql_handle,tmp_sql)){
- ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
- ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
- }
- }
-#endif
- idb_remove(mapregstr_db,num);
- mapreg_dirty=1;
- return 0;
- }
- p=(char *)aMallocA((strlen(str)+1)*sizeof(char));
- strcpy(p,str);
-
- if (idb_put(mapregstr_db,num,p))
- ;
-#if !defined(TXT_ONLY) && defined(MAPREGSQL)
- else if(name[1] != '@'){ //put returned null, so we must insert.
- // Someone is causing a database size infinite increase here without name[1] != '@' [Lance]
- sprintf(tmp_sql,"INSERT INTO `%s`(`%s`,`%s`,`%s`) VALUES ('%s','%d','%s')",mapregsql_db,mapregsql_db_varname,mapregsql_db_index,mapregsql_db_value,jstrescapecpy(tmp_str,name),i,jstrescapecpy(tmp_str2,p));
- if(mysql_query(&mmysql_handle,tmp_sql)){
- ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
- ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
- }
- }
-#endif
- mapreg_dirty=1;
- return 0;
-}
-
-/*==========================================
- * 永続的マップ変数の読み込み
- *------------------------------------------
- */
-static int script_load_mapreg(void)
-{
-#if defined(TXT_ONLY) || !defined(MAPREGSQL)
- FILE *fp;
- char line[1024];
-
- if( (fp=fopen(mapreg_txt,"rt"))==NULL )
- return -1;
-
- while(fgets(line,sizeof(line),fp)){
- char buf1[256],buf2[1024],*p;
- int n,v,s,i;
- if( sscanf(line,"%255[^,],%d\t%n",buf1,&i,&n)!=2 &&
- (i=0,sscanf(line,"%[^\t]\t%n",buf1,&n)!=1) )
- continue;
- if( buf1[strlen(buf1)-1]=='$' ){
- if( sscanf(line+n,"%[^\n\r]",buf2)!=1 ){
- ShowError("%s: %s broken data !\n",mapreg_txt,buf1);
- continue;
- }
- p=(char *)aMallocA((strlen(buf2) + 1)*sizeof(char));
- strcpy(p,buf2);
- s= add_str((unsigned char *) buf1);
- idb_put(mapregstr_db,(i<<24)|s,p);
- }else{
- if( sscanf(line+n,"%d",&v)!=1 ){
- ShowError("%s: %s broken data !\n",mapreg_txt,buf1);
- continue;
- }
- s= add_str((unsigned char *) buf1);
- idb_put(mapreg_db,(i<<24)|s,(void*)v);
- }
- }
- fclose(fp);
- mapreg_dirty=0;
- return 0;
-#else
- // SQL mapreg code start [zBuffer]
- /*
- 0 1 2
- +-------------------------+
- | varname | index | value |
- +-------------------------+
- */
- unsigned int perfomance = (unsigned int)time(NULL);
- sprintf(tmp_sql,"SELECT * FROM `%s`",mapregsql_db);
- ShowInfo("Querying script_load_mapreg ...\n");
- if(mysql_query(&mmysql_handle, tmp_sql) ) {
- ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
- ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
- return -1;
- }
- ShowInfo("Success! Returning results ...\n");
- sql_res = mysql_store_result(&mmysql_handle);
- if (sql_res) {
- while ((sql_row = mysql_fetch_row(sql_res))) {
- char buf1[33], *p = NULL;
- int i,v,s;
- strcpy(buf1,sql_row[0]);
- if( buf1[strlen(buf1)-1]=='$' ){
- i = atoi(sql_row[1]);
- p=(char *)aMallocA((strlen(sql_row[2]) + 1)*sizeof(char));
- strcpy(p,sql_row[2]);
- s= add_str((unsigned char *) buf1);
- idb_put(mapregstr_db,(i<<24)|s,p);
- }else{
- s= add_str((unsigned char *) buf1);
- v= atoi(sql_row[2]);
- i = atoi(sql_row[1]);
- idb_put(mapreg_db,(i<<24)|s,(void *)v);
- }
- }
- }
- ShowInfo("Freeing results...\n");
- mysql_free_result(sql_res);
- mapreg_dirty=0;
- perfomance = ((unsigned int)time(NULL) - perfomance);
- ShowInfo("SQL Mapreg Loading Completed Under %d Seconds.\n",perfomance);
- return 0;
-#endif /* TXT_ONLY */
-}
-/*==========================================
- * 永続的マップ変数の書き込み
- *------------------------------------------
- */
-static int script_save_mapreg_intsub(DBKey key,void *data,va_list ap)
-{
-#if defined(TXT_ONLY) || !defined(MAPREGSQL)
- FILE *fp=va_arg(ap,FILE*);
- int num=key.i&0x00ffffff, i=key.i>>24;
- char *name=str_buf+str_data[num].str;
- if( name[1]!='@' ){
- if(i==0)
- fprintf(fp,"%s\t%d\n", name, (int)data);
- else
- fprintf(fp,"%s,%d\t%d\n", name, i, (int)data);
- }
- return 0;
-#else
- int num=key.i&0x00ffffff, i=key.i>>24; // [zBuffer]
- char *name=str_buf+str_data[num].str;
- if ( name[1] != '@') {
- sprintf(tmp_sql,"UPDATE `%s` SET `%s`='%d' WHERE `%s`='%s' AND `%s`='%d'",mapregsql_db,mapregsql_db_value,(int)data,mapregsql_db_varname,name,mapregsql_db_index,i);
- if(mysql_query(&mmysql_handle, tmp_sql) ) {
- ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
- ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
- }
- }
- return 0;
-#endif
-}
-static int script_save_mapreg_strsub(DBKey key,void *data,va_list ap)
-{
-#if defined(TXT_ONLY) || !defined(MAPREGSQL)
- FILE *fp=va_arg(ap,FILE*);
- int num=key.i&0x00ffffff, i=key.i>>24;
- char *name=str_buf+str_data[num].str;
- if( name[1]!='@' ){
- if(i==0)
- fprintf(fp,"%s\t%s\n", name, (char *)data);
- else
- fprintf(fp,"%s,%d\t%s\n", name, i, (char *)data);
- }
- return 0;
-#else
- char tmp_str2[512];
- int num=key.i&0x00ffffff, i=key.i>>24;
- char *name=str_buf+str_data[num].str;
- if ( name[1] != '@') {
- sprintf(tmp_sql,"UPDATE `%s` SET `%s`='%s' WHERE `%s`='%s' AND `%s`='%d'",mapregsql_db,mapregsql_db_value,jstrescapecpy(tmp_str2,(char *)data),mapregsql_db_varname,name,mapregsql_db_index,i);
- if(mysql_query(&mmysql_handle, tmp_sql) ) {
- ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
- ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
- }
- }
- return 0;
-#endif
-}
-static int script_save_mapreg(void)
-{
-#if defined(TXT_ONLY) || !defined(MAPREGSQL)
- FILE *fp;
- int lock;
-
- if( (fp=lock_fopen(mapreg_txt,&lock))==NULL ) {
- ShowError("script_save_mapreg: Unable to lock-open file [%s]\n",mapreg_txt);
- return -1;
- }
- mapreg_db->foreach(mapreg_db,script_save_mapreg_intsub,fp);
- mapregstr_db->foreach(mapregstr_db,script_save_mapreg_strsub,fp);
- lock_fclose(fp,mapreg_txt,&lock);
-#else
- unsigned int perfomance = (unsigned int)time(NULL);
- mapreg_db->foreach(mapreg_db,script_save_mapreg_intsub); // [zBuffer]
- mapregstr_db->foreach(mapregstr_db,script_save_mapreg_strsub);
- perfomance = ((unsigned int)time(NULL) - perfomance);
- if(perfomance > 2)
- ShowWarning("Slow Query: MapregSQL Saving @ %d second(s).\n", perfomance);
-#endif
- mapreg_dirty=0;
- return 0;
-}
-static int script_autosave_mapreg(int tid,unsigned int tick,int id,int data)
-{
- if(mapreg_dirty)
- if (script_save_mapreg() == -1)
- ShowError("Failed to save the mapreg data!\n");
- return 0;
-}
-
-/*==========================================
- *
- *------------------------------------------
- */
-static int set_posword(char *p)
-{
- char* np,* str[15];
- int i=0;
- for(i=0;i<11;i++) {
- if((np=strchr(p,','))!=NULL) {
- str[i]=p;
- *np=0;
- p=np+1;
- } else {
- str[i]=p;
- p+=strlen(p);
- }
- if(str[i])
- strcpy(pos[i],str[i]);
- }
- return 0;
-}
-
-int script_config_read_sub(char *cfgName)
-{
- int i;
- char line[1024],w1[1024],w2[1024];
- FILE *fp;
-
-
- fp = fopen(cfgName, "r");
- if (fp == NULL) {
- ShowError("file not found: [%s]\n", cfgName);
- return 1;
- }
- while (fgets(line, sizeof(line) - 1, fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
- i = sscanf(line,"%[^:]: %[^\r\n]",w1,w2);
- if (i != 2)
- continue;
- if(strcmpi(w1,"refine_posword")==0) {
- set_posword(w2);
- }
- else if(strcmpi(w1,"verbose_mode")==0) {
- script_config.verbose_mode = battle_config_switch(w2);
- }
- else if(strcmpi(w1,"warn_func_no_comma")==0) {
- script_config.warn_func_no_comma = battle_config_switch(w2);
- }
- else if(strcmpi(w1,"warn_cmd_no_comma")==0) {
- script_config.warn_cmd_no_comma = battle_config_switch(w2);
- }
- else if(strcmpi(w1,"warn_func_mismatch_paramnum")==0) {
- script_config.warn_func_mismatch_paramnum = battle_config_switch(w2);
- }
- else if(strcmpi(w1,"warn_cmd_mismatch_paramnum")==0) {
- script_config.warn_cmd_mismatch_paramnum = battle_config_switch(w2);
- }
- else if(strcmpi(w1,"check_cmdcount")==0) {
- script_config.check_cmdcount = battle_config_switch(w2);
- }
- else if(strcmpi(w1,"check_gotocount")==0) {
- script_config.check_gotocount = battle_config_switch(w2);
- }
- else if(strcmpi(w1,"event_script_type")==0) {
- script_config.event_script_type = battle_config_switch(w2);
- }
- else if(strcmpi(w1,"event_requires_trigger")==0) {
- script_config.event_requires_trigger = battle_config_switch(w2);
- }
- else if(strcmpi(w1,"die_event_name")==0) {
- strncpy(script_config.die_event_name, w2, NAME_LENGTH-1);
- if (strlen(script_config.die_event_name) != strlen(w2))
- ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.die_event_name);
- }
- else if(strcmpi(w1,"kill_pc_event_name")==0) {
- strncpy(script_config.kill_pc_event_name, w2, NAME_LENGTH-1);
- if (strlen(script_config.kill_pc_event_name) != strlen(w2))
- ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.kill_pc_event_name);
- }
- else if(strcmpi(w1,"kill_mob_event_name")==0) {
- strncpy(script_config.kill_mob_event_name, w2, NAME_LENGTH-1);
- if (strlen(script_config.kill_mob_event_name) != strlen(w2))
- ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.kill_mob_event_name);
- }
- else if(strcmpi(w1,"login_event_name")==0) {
- strncpy(script_config.login_event_name, w2, NAME_LENGTH-1);
- if (strlen(script_config.login_event_name) != strlen(w2))
- ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.login_event_name);
- }
- else if(strcmpi(w1,"logout_event_name")==0) {
- strncpy(script_config.logout_event_name, w2, NAME_LENGTH-1);
- if (strlen(script_config.logout_event_name) != strlen(w2))
- ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.logout_event_name);
- }
- else if(strcmpi(w1,"loadmap_event_name")==0) {
- strncpy(script_config.loadmap_event_name, w2, NAME_LENGTH-1);
- if (strlen(script_config.loadmap_event_name) != strlen(w2))
- ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.loadmap_event_name);
- }
- else if(strcmpi(w1,"baselvup_event_name")==0) {
- strncpy(script_config.baselvup_event_name, w2, NAME_LENGTH-1);
- if (strlen(script_config.baselvup_event_name) != strlen(w2))
- ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.baselvup_event_name);
- }
- else if(strcmpi(w1,"joblvup_event_name")==0) {
- strncpy(script_config.joblvup_event_name, w2, NAME_LENGTH-1);
- if (strlen(script_config.joblvup_event_name) != strlen(w2))
- ShowWarning("script_config_read: Event label truncated (max length is 23 chars): %d\n", script_config.joblvup_event_name);
- }
- else if(strcmpi(w1,"import")==0){
- script_config_read_sub(w2);
- }
- }
- fclose(fp);
-
- return 0;
-}
-
-int script_config_read(char *cfgName)
-{ //Script related variables should be initialized once! [Skotlex]
-
- memset (&script_config, 0, sizeof(script_config));
- script_config.verbose_mode = 0;
- script_config.warn_func_no_comma = 1;
- script_config.warn_cmd_no_comma = 1;
- script_config.warn_func_mismatch_paramnum = 1;
- script_config.warn_cmd_mismatch_paramnum = 1;
- script_config.check_cmdcount = 65535;
- script_config.check_gotocount = 2048;
-
- script_config.event_script_type = 0;
- script_config.event_requires_trigger = 1;
-
- return script_config_read_sub(cfgName);
-}
-
-static int do_final_userfunc_sub (DBKey key,void *data,va_list ap){
- struct script_code *code = (struct script_code *)data;
- if(code){
- script_free_vars( &code->script_vars );
- aFree( code->script_buf );
- }
- return 0;
-}
-
-/*==========================================
- * 終了
- *------------------------------------------
- */
-int do_final_script()
-{
- if(mapreg_dirty>=0)
- script_save_mapreg();
-
- mapreg_db->destroy(mapreg_db,NULL);
- mapregstr_db->destroy(mapregstr_db,NULL);
- scriptlabel_db->destroy(scriptlabel_db,NULL);
- userfunc_db->destroy(userfunc_db,do_final_userfunc_sub);
- if(sleep_db) {
- struct linkdb_node *n = (struct linkdb_node *)sleep_db;
- while(n) {
- struct script_state *st = (struct script_state *)n->data;
- script_free_stack(st->stack);
- free(st);
- n = n->next;
- }
- linkdb_final(&sleep_db);
- }
-
- if (str_data)
- aFree(str_data);
- if (str_buf)
- aFree(str_buf);
-
- return 0;
-}
-/*==========================================
- * 初期化
- *------------------------------------------
- */
-int do_init_script()
-{
- mapreg_db= db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_BASE,sizeof(int));
- mapregstr_db=db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_RELEASE_DATA,sizeof(int));
- userfunc_db=db_alloc(__FILE__,__LINE__,DB_STRING,DB_OPT_RELEASE_BOTH,50);
- scriptlabel_db=db_alloc(__FILE__,__LINE__,DB_STRING,DB_OPT_ALLOW_NULL_DATA,50);
-
- script_load_mapreg();
-
- add_timer_func_list(script_autosave_mapreg,"script_autosave_mapreg");
- add_timer_interval(gettick()+MAPREG_AUTOSAVE_INTERVAL,
- script_autosave_mapreg,0,0,MAPREG_AUTOSAVE_INTERVAL);
-
- return 0;
-}
-
-int script_reload()
-{
- if(mapreg_dirty>=0)
- script_save_mapreg();
-
- mapreg_db->clear(mapreg_db, NULL);
- mapregstr_db->clear(mapregstr_db, NULL);
- userfunc_db->clear(userfunc_db,do_final_userfunc_sub);
- scriptlabel_db->clear(scriptlabel_db, NULL);
-
- if(sleep_db) {
- struct linkdb_node *n = (struct linkdb_node *)sleep_db;
- while(n) {
- struct script_state *st = (struct script_state *)n->data;
- script_free_stack(st->stack);
- free(st);
- n = n->next;
- }
- linkdb_final(&sleep_db);
- }
-
- script_load_mapreg();
- return 0;
-}
diff --git a/src/map/script.h b/src/map/script.h
index 85ddc2d6a..8ce446212 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -45,26 +45,24 @@ struct script_code {
unsigned char* script_buf;
struct linkdb_node* script_vars;
};
-struct script_stack {
- int sp,sp_max,defsp;
- struct script_data *stack_data;
- struct linkdb_node **var_function; // 関数依存変数
-};
+
struct script_state {
- struct script_stack *stack;
+ struct script_stack {
+ int sp,sp_max,defsp;
+ struct script_data *stack_data;
+ struct linkdb_node **var_function; // 関数依存変数
+ } *stack;
int start,end;
int pos,state;
int rid,oid;
- //unsigned char *script,*new_script;
- int new_pos,new_defsp;
struct script_code *script, *scriptroot;
struct sleep_data {
int tick,timer,charid;
} sleep;
};
-struct script_code *parse_script(unsigned char *,int);
-void run_script(struct script_code *rootscript,int pos,int rid,int oid);
+struct script_code* parse_script(unsigned char *,const char*,int);
+void run_script(struct script_code*,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);
@@ -74,13 +72,13 @@ int run_script_timer(int tid, unsigned int tick, int id, int data);
void run_script_main(struct script_state *st);
struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n);
+void script_free_stack(struct script_stack*);
void script_free_code(struct script_code* code);
struct dbt* script_get_label_db(void);
struct dbt* script_get_userfunc_db(void);
int script_config_read(char *cfgName);
-void script_free_stack(struct script_stack*);
int do_init_script(void);
int do_final_script(void);
int add_str(const unsigned char *p);