* WARNING: New scripting system contains memory leak
TODO: Free all scripts using script_free_code() instead of old methods. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@6690 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
afdee66062
commit
a7e5993400
@ -4,6 +4,8 @@ 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.
|
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||||
|
|
||||||
2006/05/22
|
2006/05/22
|
||||||
|
* WARNING: New scripting system contains memory leak
|
||||||
|
TODO: Free all scripts using script_free_code() instead of old methods. [Lance]
|
||||||
* Excluded idle and auto-trade party members from TK_POWER list. [Lance]
|
* Excluded idle and auto-trade party members from TK_POWER list. [Lance]
|
||||||
* Fixed compilation errors.
|
* Fixed compilation errors.
|
||||||
Tidy up jobmaster for easy debugging. [Lance]
|
Tidy up jobmaster for easy debugging. [Lance]
|
||||||
|
104
src/common/db.c
104
src/common/db.c
@ -2342,3 +2342,107 @@ void db_final(void)
|
|||||||
#endif /* DB_ENABLE_STATS */
|
#endif /* DB_ENABLE_STATS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Link DB System - jAthena
|
||||||
|
void linkdb_insert( struct linkdb_node** head, void *key, void* data) {
|
||||||
|
struct linkdb_node *node;
|
||||||
|
if( head == NULL ) return ;
|
||||||
|
node = aMalloc( sizeof(struct linkdb_node) );
|
||||||
|
if( *head == NULL ) {
|
||||||
|
// first node
|
||||||
|
*head = node;
|
||||||
|
node->prev = NULL;
|
||||||
|
node->next = NULL;
|
||||||
|
} else {
|
||||||
|
// link nodes
|
||||||
|
node->next = *head;
|
||||||
|
node->prev = (*head)->prev;
|
||||||
|
(*head)->prev = node;
|
||||||
|
(*head) = node;
|
||||||
|
}
|
||||||
|
node->key = key;
|
||||||
|
node->data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* linkdb_search( struct linkdb_node** head, void *key) {
|
||||||
|
int n = 0;
|
||||||
|
struct linkdb_node *node;
|
||||||
|
if( head == NULL ) return NULL;
|
||||||
|
node = *head;
|
||||||
|
while( node ) {
|
||||||
|
if( node->key == key ) {
|
||||||
|
if( node->prev && n > 5 ) {
|
||||||
|
// 処理効率改善の為にheadに移動させる
|
||||||
|
if(node->prev) node->prev->next = node->next;
|
||||||
|
if(node->next) node->next->prev = node->prev;
|
||||||
|
node->next = *head;
|
||||||
|
node->prev = (*head)->prev;
|
||||||
|
(*head)->prev = node;
|
||||||
|
(*head) = node;
|
||||||
|
}
|
||||||
|
return node->data;
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* linkdb_erase( struct linkdb_node** head, void *key) {
|
||||||
|
struct linkdb_node *node;
|
||||||
|
if( head == NULL ) return NULL;
|
||||||
|
node = *head;
|
||||||
|
while( node ) {
|
||||||
|
if( node->key == key ) {
|
||||||
|
void *data = node->data;
|
||||||
|
if( node->prev == NULL )
|
||||||
|
*head = node->next;
|
||||||
|
else
|
||||||
|
node->prev->next = node->next;
|
||||||
|
if( node->next )
|
||||||
|
node->next->prev = node->prev;
|
||||||
|
aFree( node );
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void linkdb_replace( struct linkdb_node** head, void *key, void *data ) {
|
||||||
|
int n = 0;
|
||||||
|
struct linkdb_node *node;
|
||||||
|
if( head == NULL ) return ;
|
||||||
|
node = *head;
|
||||||
|
while( node ) {
|
||||||
|
if( node->key == key ) {
|
||||||
|
if( node->prev && n > 5 ) {
|
||||||
|
// 処理効率改善の為にheadに移動させる
|
||||||
|
if(node->prev) node->prev->next = node->next;
|
||||||
|
if(node->next) node->next->prev = node->prev;
|
||||||
|
node->next = *head;
|
||||||
|
node->prev = (*head)->prev;
|
||||||
|
(*head)->prev = node;
|
||||||
|
(*head) = node;
|
||||||
|
}
|
||||||
|
node->data = data;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
// 見つからないので挿入
|
||||||
|
linkdb_insert( head, key, data );
|
||||||
|
}
|
||||||
|
|
||||||
|
void linkdb_final( struct linkdb_node** head ) {
|
||||||
|
struct linkdb_node *node, *node2;
|
||||||
|
if( head == NULL ) return ;
|
||||||
|
node = *head;
|
||||||
|
while( node ) {
|
||||||
|
node2 = node->next;
|
||||||
|
aFree( node );
|
||||||
|
node = node2;
|
||||||
|
}
|
||||||
|
*head = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -731,4 +731,18 @@ void db_init(void);
|
|||||||
*/
|
*/
|
||||||
void db_final(void);
|
void db_final(void);
|
||||||
|
|
||||||
|
// Link DB System - From jAthena
|
||||||
|
struct linkdb_node {
|
||||||
|
struct linkdb_node *next;
|
||||||
|
struct linkdb_node *prev;
|
||||||
|
void *key;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
void linkdb_insert ( struct linkdb_node** head, void *key, void* data); // 重複を考慮しない
|
||||||
|
void linkdb_replace( struct linkdb_node** head, void *key, void* data); // 重複を考慮する
|
||||||
|
void* linkdb_search ( struct linkdb_node** head, void *key);
|
||||||
|
void* linkdb_erase ( struct linkdb_node** head, void *key);
|
||||||
|
void linkdb_final ( struct linkdb_node** head );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -862,7 +862,7 @@ static int itemdb_read_sqldb(void)
|
|||||||
// ----------
|
// ----------
|
||||||
|
|
||||||
if (id->script)
|
if (id->script)
|
||||||
aFree(id->script);
|
script_free_code(id->script);
|
||||||
if (sql_row[19] != NULL) {
|
if (sql_row[19] != NULL) {
|
||||||
if (sql_row[19][0] == '{')
|
if (sql_row[19][0] == '{')
|
||||||
id->script = parse_script((unsigned char *) sql_row[19], 0);
|
id->script = parse_script((unsigned char *) sql_row[19], 0);
|
||||||
@ -873,7 +873,7 @@ static int itemdb_read_sqldb(void)
|
|||||||
} else id->script = NULL;
|
} else id->script = NULL;
|
||||||
|
|
||||||
if (id->equip_script)
|
if (id->equip_script)
|
||||||
aFree(id->equip_script);
|
script_free_code(id->equip_script);
|
||||||
if (sql_row[20] != NULL) {
|
if (sql_row[20] != NULL) {
|
||||||
if (sql_row[20][0] == '{')
|
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], 0);
|
||||||
@ -884,7 +884,7 @@ static int itemdb_read_sqldb(void)
|
|||||||
} else id->equip_script = NULL;
|
} else id->equip_script = NULL;
|
||||||
|
|
||||||
if (id->unequip_script)
|
if (id->unequip_script)
|
||||||
aFree(id->unequip_script);
|
script_free_code(id->unequip_script);
|
||||||
if (sql_row[21] != NULL) {
|
if (sql_row[21] != NULL) {
|
||||||
if (sql_row[21][0] == '{')
|
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], 0);
|
||||||
@ -1030,7 +1030,7 @@ static int itemdb_readdb(void)
|
|||||||
id->sex = itemdb_gendercheck(id); //Apply gender filtering.
|
id->sex = itemdb_gendercheck(id); //Apply gender filtering.
|
||||||
|
|
||||||
if (id->script) {
|
if (id->script) {
|
||||||
aFree(id->script);
|
script_free_code(id->script);
|
||||||
id->script=NULL;
|
id->script=NULL;
|
||||||
}
|
}
|
||||||
if (id->equip_script) {
|
if (id->equip_script) {
|
||||||
@ -1130,17 +1130,17 @@ static int itemdb_final_sub (DBKey key,void *data,va_list ap)
|
|||||||
flag = va_arg(ap, int);
|
flag = va_arg(ap, int);
|
||||||
if (id->script)
|
if (id->script)
|
||||||
{
|
{
|
||||||
aFree(id->script);
|
script_free_code(id->script);
|
||||||
id->script = NULL;
|
id->script = NULL;
|
||||||
}
|
}
|
||||||
if (id->equip_script)
|
if (id->equip_script)
|
||||||
{
|
{
|
||||||
aFree(id->equip_script);
|
script_free_code(id->equip_script);
|
||||||
id->equip_script = NULL;
|
id->equip_script = NULL;
|
||||||
}
|
}
|
||||||
if (id->unequip_script)
|
if (id->unequip_script)
|
||||||
{
|
{
|
||||||
aFree(id->unequip_script);
|
script_free_code(id->unequip_script);
|
||||||
id->unequip_script = NULL;
|
id->unequip_script = NULL;
|
||||||
}
|
}
|
||||||
// Whether to clear the item data (exception: do not clear the dummy item data
|
// Whether to clear the item data (exception: do not clear the dummy item data
|
||||||
@ -1162,11 +1162,11 @@ void do_final_itemdb(void)
|
|||||||
item_db->destroy(item_db, itemdb_final_sub, 1);
|
item_db->destroy(item_db, itemdb_final_sub, 1);
|
||||||
if (dummy_item) {
|
if (dummy_item) {
|
||||||
if (dummy_item->script)
|
if (dummy_item->script)
|
||||||
aFree(dummy_item->script);
|
script_free_code(dummy_item->script);
|
||||||
if (dummy_item->equip_script)
|
if (dummy_item->equip_script)
|
||||||
aFree(dummy_item->equip_script);
|
script_free_code(dummy_item->equip_script);
|
||||||
if (dummy_item->unequip_script)
|
if (dummy_item->unequip_script)
|
||||||
aFree(dummy_item->unequip_script);
|
script_free_code(dummy_item->unequip_script);
|
||||||
aFree(dummy_item);
|
aFree(dummy_item);
|
||||||
dummy_item = NULL;
|
dummy_item = NULL;
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,9 @@ struct item_data {
|
|||||||
unsigned short chance;
|
unsigned short chance;
|
||||||
int id;
|
int id;
|
||||||
} mob[MAX_SEARCH]; //Holds the mobs that have the highest drop rate for this item. [Skotlex]
|
} mob[MAX_SEARCH]; //Holds the mobs that have the highest drop rate for this item. [Skotlex]
|
||||||
unsigned char *script; //Default script for everything.
|
struct script_code *script; //Default script for everything.
|
||||||
unsigned char *equip_script; //Script executed once when equipping.
|
struct script_code *equip_script; //Script executed once when equipping.
|
||||||
unsigned char *unequip_script;//Script executed once when unequipping.
|
struct script_code *unequip_script;//Script executed once when unequipping.
|
||||||
struct {
|
struct {
|
||||||
unsigned available : 1;
|
unsigned available : 1;
|
||||||
unsigned value_notdc : 1;
|
unsigned value_notdc : 1;
|
||||||
|
@ -538,7 +538,7 @@ struct map_session_data {
|
|||||||
int npc_menu;
|
int npc_menu;
|
||||||
int npc_amount;
|
int npc_amount;
|
||||||
struct script_stack *stack;
|
struct script_stack *stack;
|
||||||
unsigned char *npc_script,*npc_scriptroot;
|
struct script_code *npc_script,*npc_scriptroot;
|
||||||
int npc_scriptstate;
|
int npc_scriptstate;
|
||||||
char npc_str[256];
|
char npc_str[256];
|
||||||
int npc_timer_id; //For player attached npc timers. [Skotlex]
|
int npc_timer_id; //For player attached npc timers. [Skotlex]
|
||||||
@ -805,7 +805,7 @@ struct npc_data {
|
|||||||
|
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
unsigned char *script;
|
struct script_code *script;
|
||||||
short xs,ys;
|
short xs,ys;
|
||||||
int guild_id;
|
int guild_id;
|
||||||
int timer,timerid,timeramount,rid;
|
int timer,timerid,timeramount,rid;
|
||||||
|
@ -1780,7 +1780,8 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
|
|||||||
{
|
{
|
||||||
int x, y, dir = 0, m, xs = 0, ys = 0, class_ = 0; // [Valaris] thanks to fov
|
int x, y, dir = 0, m, xs = 0, ys = 0, class_ = 0; // [Valaris] thanks to fov
|
||||||
char mapname[MAP_NAME_LENGTH];
|
char mapname[MAP_NAME_LENGTH];
|
||||||
unsigned char *srcbuf = NULL, *script;
|
unsigned char *srcbuf = NULL;
|
||||||
|
struct script_code *script;
|
||||||
int srcsize = 65536;
|
int srcsize = 65536;
|
||||||
int startline = 0;
|
int startline = 0;
|
||||||
unsigned char line[1024];
|
unsigned char line[1024];
|
||||||
@ -1838,7 +1839,7 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
|
|||||||
script = NULL;
|
script = NULL;
|
||||||
} else {
|
} else {
|
||||||
// printf("Ok line %d\n",*lines);
|
// printf("Ok line %d\n",*lines);
|
||||||
script = (unsigned char *) parse_script((unsigned char *) srcbuf, startline);
|
script = parse_script((unsigned char *) srcbuf, startline);
|
||||||
}
|
}
|
||||||
if (script == NULL) {
|
if (script == NULL) {
|
||||||
// script parse error?
|
// script parse error?
|
||||||
@ -1857,7 +1858,7 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
|
|||||||
ShowError("bad duplicate name (in %s)! (not exist) : %s\n", current_file, srcname);
|
ShowError("bad duplicate name (in %s)! (not exist) : %s\n", current_file, srcname);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
script = (unsigned char *)nd2->u.scr.script;
|
script = nd2->u.scr.script;
|
||||||
label_dup = nd2->u.scr.label_list;
|
label_dup = nd2->u.scr.label_list;
|
||||||
label_dupnum = nd2->u.scr.label_list_num;
|
label_dupnum = nd2->u.scr.label_list_num;
|
||||||
src_id = nd2->bl.id;
|
src_id = nd2->bl.id;
|
||||||
@ -2027,7 +2028,8 @@ static int npc_parse_script (char *w1,char *w2,char *w3,char *w4,char *first_lin
|
|||||||
*/
|
*/
|
||||||
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)
|
||||||
{
|
{
|
||||||
unsigned char *srcbuf, *script, *p;
|
unsigned char *srcbuf, *p;
|
||||||
|
struct script_code *script;
|
||||||
int srcsize = 65536;
|
int srcsize = 65536;
|
||||||
int startline = 0;
|
int startline = 0;
|
||||||
char line[1024];
|
char line[1024];
|
||||||
|
@ -2661,7 +2661,7 @@ int pc_useitem(struct map_session_data *sd,int n)
|
|||||||
{
|
{
|
||||||
unsigned int tick = gettick();
|
unsigned int tick = gettick();
|
||||||
int amount;
|
int amount;
|
||||||
unsigned char *script;
|
struct script_code *script;
|
||||||
|
|
||||||
nullpo_retr(0, sd);
|
nullpo_retr(0, sd);
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ struct pet_db {
|
|||||||
int attack_rate;
|
int attack_rate;
|
||||||
int defence_attack_rate;
|
int defence_attack_rate;
|
||||||
int change_target_rate;
|
int change_target_rate;
|
||||||
unsigned char *script;
|
struct script_code *script;
|
||||||
};
|
};
|
||||||
extern struct pet_db pet_db[MAX_PET_DB];
|
extern struct pet_db pet_db[MAX_PET_DB];
|
||||||
|
|
||||||
|
464
src/map/script.c
464
src/map/script.c
@ -124,6 +124,8 @@ char tmp_sql[65535];
|
|||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static struct linkdb_node *sleep_db;
|
||||||
|
|
||||||
/*==========================================
|
/*==========================================
|
||||||
* ローカルプロトタイプ宣言 (必要な物のみ)
|
* ローカルプロトタイプ宣言 (必要な物のみ)
|
||||||
*------------------------------------------
|
*------------------------------------------
|
||||||
@ -428,6 +430,10 @@ int buildin_mobtalk(struct script_state *st);
|
|||||||
int buildin_mobemote(struct script_state *st);
|
int buildin_mobemote(struct script_state *st);
|
||||||
int buildin_mobattach(struct script_state *st);
|
int buildin_mobattach(struct script_state *st);
|
||||||
// <--- [zBuffer] List of mob control commands
|
// <--- [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);
|
||||||
void push_val(struct script_stack *stack,int type,int val);
|
void push_val(struct script_stack *stack,int type,int val);
|
||||||
int run_func(struct script_state *st);
|
int run_func(struct script_state *st);
|
||||||
|
|
||||||
@ -763,6 +769,10 @@ struct {
|
|||||||
{buildin_mobemote,"mobemote","*"},
|
{buildin_mobemote,"mobemote","*"},
|
||||||
{buildin_mobattach,"mobattach","*"},
|
{buildin_mobattach,"mobattach","*"},
|
||||||
// <--- [zBuffer] List of mob control commands
|
// <--- [zBuffer] List of mob control commands
|
||||||
|
{buildin_sleep,"sleep","i"},
|
||||||
|
{buildin_sleep2,"sleep2","i"},
|
||||||
|
{buildin_awake,"awake","s"},
|
||||||
|
{buildin_getvariableofnpc,"getvariableofnpc","is"},
|
||||||
{NULL,NULL,NULL},
|
{NULL,NULL,NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2162,10 +2172,11 @@ static void read_constdb(void)
|
|||||||
* スクリプトの解析
|
* スクリプトの解析
|
||||||
*------------------------------------------
|
*------------------------------------------
|
||||||
*/
|
*/
|
||||||
unsigned char* parse_script(unsigned char *src,int line)
|
struct script_code* parse_script(unsigned char *src,int line)
|
||||||
{
|
{
|
||||||
unsigned char *p, *tmpp;
|
unsigned char *p, *tmpp;
|
||||||
int i;
|
int i;
|
||||||
|
struct script_code *code;
|
||||||
static int first = 1;
|
static int first = 1;
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
@ -2275,7 +2286,11 @@ unsigned char* parse_script(unsigned char *src,int line)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
startptr = NULL; //Clear pointer to prevent future references to a src that may be free'd. [Skotlex]
|
startptr = NULL; //Clear pointer to prevent future references to a src that may be free'd. [Skotlex]
|
||||||
return (unsigned char *) script_buf;
|
code = aCalloc(1, sizeof(struct script_code));
|
||||||
|
code->script_buf = script_buf;
|
||||||
|
code->script_size = script_size;
|
||||||
|
code->script_vars = NULL;
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -2330,6 +2345,16 @@ int get_val(struct script_state*st,struct script_data* data)
|
|||||||
if(sd)
|
if(sd)
|
||||||
data->u.str = pc_readaccountregstr(sd,name);
|
data->u.str = pc_readaccountregstr(sd,name);
|
||||||
}
|
}
|
||||||
|
}else if(prefix=='\'') {
|
||||||
|
struct linkdb_node **n;
|
||||||
|
if( data->ref ) {
|
||||||
|
n = data->ref;
|
||||||
|
} else if( name[1] == '@' ) {
|
||||||
|
n = st->stack->var_function;
|
||||||
|
} else {
|
||||||
|
n = &st->script->script_vars;
|
||||||
|
}
|
||||||
|
data->u.str = linkdb_search(n, (void*)data->u.num );
|
||||||
}else{
|
}else{
|
||||||
if(sd)
|
if(sd)
|
||||||
data->u.str = pc_readglobalreg_str(sd,name);
|
data->u.str = pc_readglobalreg_str(sd,name);
|
||||||
@ -2362,6 +2387,16 @@ int get_val(struct script_state*st,struct script_data* data)
|
|||||||
if(sd)
|
if(sd)
|
||||||
data->u.num = pc_readaccountreg(sd,name);
|
data->u.num = pc_readaccountreg(sd,name);
|
||||||
}
|
}
|
||||||
|
}else if(prefix=='\''){
|
||||||
|
struct linkdb_node **n;
|
||||||
|
if( data->ref ) {
|
||||||
|
n = data->ref;
|
||||||
|
} else if( name[1] == '@' ) {
|
||||||
|
n = st->stack->var_function;
|
||||||
|
} else {
|
||||||
|
n = &st->script->script_vars;
|
||||||
|
}
|
||||||
|
data->u.num = (int)linkdb_search(n, (void*)data->u.num);
|
||||||
}else{
|
}else{
|
||||||
if(sd)
|
if(sd)
|
||||||
data->u.num = pc_readglobalreg(sd,name);
|
data->u.num = pc_readglobalreg(sd,name);
|
||||||
@ -2374,11 +2409,12 @@ int get_val(struct script_state*st,struct script_data* data)
|
|||||||
* 変数の読み取り2
|
* 変数の読み取り2
|
||||||
*------------------------------------------
|
*------------------------------------------
|
||||||
*/
|
*/
|
||||||
void* get_val2(struct script_state*st,int num)
|
void* get_val2(struct script_state*st,int num,struct linkdb_node **ref)
|
||||||
{
|
{
|
||||||
struct script_data dat;
|
struct script_data dat;
|
||||||
dat.type=C_NAME;
|
dat.type=C_NAME;
|
||||||
dat.u.num=num;
|
dat.u.num=num;
|
||||||
|
dat.ref = ref;
|
||||||
get_val(st,&dat);
|
get_val(st,&dat);
|
||||||
if( dat.type==C_INT ) return (void*)dat.u.num;
|
if( dat.type==C_INT ) return (void*)dat.u.num;
|
||||||
else return (void*)dat.u.str;
|
else return (void*)dat.u.str;
|
||||||
@ -2388,7 +2424,7 @@ void* get_val2(struct script_state*st,int num)
|
|||||||
* 変数設定用
|
* 変数設定用
|
||||||
*------------------------------------------
|
*------------------------------------------
|
||||||
*/
|
*/
|
||||||
static int set_reg(struct map_session_data *sd,int num,char *name,void *v)
|
static int set_reg(struct script_state*st,struct map_session_data *sd,int num,char *name,void *v,struct linkdb_node** ref)
|
||||||
{
|
{
|
||||||
char prefix=*name;
|
char prefix=*name;
|
||||||
char postfix=name[strlen(name)-1];
|
char postfix=name[strlen(name)-1];
|
||||||
@ -2404,6 +2440,23 @@ static int set_reg(struct map_session_data *sd,int num,char *name,void *v)
|
|||||||
pc_setaccountreg2str(sd,name,str);
|
pc_setaccountreg2str(sd,name,str);
|
||||||
else
|
else
|
||||||
pc_setaccountregstr(sd,name,str);
|
pc_setaccountregstr(sd,name,str);
|
||||||
|
}else if(prefix=='\'') {
|
||||||
|
char *p;
|
||||||
|
struct linkdb_node **n;
|
||||||
|
if( ref ) {
|
||||||
|
n = ref;
|
||||||
|
} else if( name[1] == '@' ) {
|
||||||
|
n = st->stack->var_function;
|
||||||
|
} else {
|
||||||
|
n = &st->script->script_vars;
|
||||||
|
}
|
||||||
|
p = linkdb_search(n, (void*)num);
|
||||||
|
if(p) {
|
||||||
|
linkdb_erase(n, (void*)num);
|
||||||
|
aFree(p);
|
||||||
|
}
|
||||||
|
if( ((char*)v)[0] )
|
||||||
|
linkdb_insert(n, (void*)num, aStrdup(v));
|
||||||
}else{
|
}else{
|
||||||
pc_setglobalreg_str(sd,name,str);
|
pc_setglobalreg_str(sd,name,str);
|
||||||
} // [zBuffer]
|
} // [zBuffer]
|
||||||
@ -2425,6 +2478,20 @@ static int set_reg(struct map_session_data *sd,int num,char *name,void *v)
|
|||||||
pc_setaccountreg2(sd,name,val);
|
pc_setaccountreg2(sd,name,val);
|
||||||
else
|
else
|
||||||
pc_setaccountreg(sd,name,val);
|
pc_setaccountreg(sd,name,val);
|
||||||
|
}else if(prefix == '\'') {
|
||||||
|
struct linkdb_node **n;
|
||||||
|
if( ref ) {
|
||||||
|
n = ref;
|
||||||
|
} else if( name[1] == '@' ) {
|
||||||
|
n = st->stack->var_function;
|
||||||
|
} else {
|
||||||
|
n = &st->script->script_vars;
|
||||||
|
}
|
||||||
|
if( val == 0 ) {
|
||||||
|
linkdb_erase(n, (void*)num);
|
||||||
|
} else {
|
||||||
|
linkdb_replace(n, (void*)num, (void*)val);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
pc_setglobalreg(sd,name,val);
|
pc_setglobalreg(sd,name,val);
|
||||||
}
|
}
|
||||||
@ -2434,7 +2501,7 @@ static int set_reg(struct map_session_data *sd,int num,char *name,void *v)
|
|||||||
|
|
||||||
int set_var(struct map_session_data *sd, char *name, void *val)
|
int set_var(struct map_session_data *sd, char *name, void *val)
|
||||||
{
|
{
|
||||||
return set_reg(sd, add_str((unsigned char *) name), name, val);
|
return set_reg(NULL, sd, add_str((unsigned char *) name), name, val, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*==========================================
|
/*==========================================
|
||||||
@ -2495,9 +2562,20 @@ void push_val(struct script_stack *stack,int type,int val)
|
|||||||
// printf("push (%d,%d)-> %d\n",type,val,stack->sp);
|
// printf("push (%d,%d)-> %d\n",type,val,stack->sp);
|
||||||
stack->stack_data[stack->sp].type=type;
|
stack->stack_data[stack->sp].type=type;
|
||||||
stack->stack_data[stack->sp].u.num=val;
|
stack->stack_data[stack->sp].u.num=val;
|
||||||
|
stack->stack_data[stack->sp].ref = NULL;
|
||||||
stack->sp++;
|
stack->sp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*==========================================
|
||||||
|
* スタックへ数値+リファレンスをプッシュ
|
||||||
|
*------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void push_val2(struct script_stack *stack,int type,int val,struct linkdb_node** ref) {
|
||||||
|
push_val(stack,type,val);
|
||||||
|
stack->stack_data[stack->sp-1].ref = ref;
|
||||||
|
}
|
||||||
|
|
||||||
/*==========================================
|
/*==========================================
|
||||||
* スタックへ文字列をプッシュ
|
* スタックへ文字列をプッシュ
|
||||||
*------------------------------------------
|
*------------------------------------------
|
||||||
@ -2515,6 +2593,7 @@ void push_str(struct script_stack *stack,int type,unsigned char *str)
|
|||||||
// printf("push (%d,%x)-> %d\n",type,str,stack->sp);
|
// printf("push (%d,%x)-> %d\n",type,str,stack->sp);
|
||||||
stack->stack_data[stack->sp].type=type;
|
stack->stack_data[stack->sp].type=type;
|
||||||
stack->stack_data[stack->sp].u.str=(char *) str;
|
stack->stack_data[stack->sp].u.str=(char *) str;
|
||||||
|
stack->stack_data[stack->sp].ref = NULL;
|
||||||
stack->sp++;
|
stack->sp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2532,7 +2611,10 @@ void push_copy(struct script_stack *stack,int pos)
|
|||||||
push_str(stack,C_STR,(unsigned char *) aStrdup(stack->stack_data[pos].u.str));
|
push_str(stack,C_STR,(unsigned char *) aStrdup(stack->stack_data[pos].u.str));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
push_val(stack,stack->stack_data[pos].type,stack->stack_data[pos].u.num);
|
push_val2(
|
||||||
|
stack,stack->stack_data[pos].type,stack->stack_data[pos].u.num,
|
||||||
|
stack->stack_data[pos].ref
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2556,6 +2638,24 @@ void pop_stack(struct script_stack* stack,int start,int end)
|
|||||||
stack->sp-=end-start;
|
stack->sp-=end-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*==========================================
|
||||||
|
* スクリプト依存変数、関数依存変数の解放
|
||||||
|
*------------------------------------------
|
||||||
|
*/
|
||||||
|
void script_free_vars(struct linkdb_node **node) {
|
||||||
|
struct linkdb_node *n = *node;
|
||||||
|
while(n) {
|
||||||
|
char *name = str_buf + str_data[(int)(n->key)&0x00ffffff].str;
|
||||||
|
char postfix = name[strlen(name)-1];
|
||||||
|
if( postfix == '$' ) {
|
||||||
|
// 文字型変数なので、データ削除
|
||||||
|
aFree(n->data);
|
||||||
|
}
|
||||||
|
n = n->next;
|
||||||
|
}
|
||||||
|
linkdb_final( node );
|
||||||
|
}
|
||||||
|
|
||||||
/*==========================================
|
/*==========================================
|
||||||
* Free's the whole stack. Invoked when clearing a character. [Skotlex]
|
* Free's the whole stack. Invoked when clearing a character. [Skotlex]
|
||||||
*------------------------------------------
|
*------------------------------------------
|
||||||
@ -2570,12 +2670,24 @@ void script_free_stack(struct script_stack* stack)
|
|||||||
//ShowDebug ("script_free_stack: freeing %p at sp=%d.\n", stack->stack_data[i].u.str, i);
|
//ShowDebug ("script_free_stack: freeing %p at sp=%d.\n", stack->stack_data[i].u.str, i);
|
||||||
aFree(stack->stack_data[i].u.str);
|
aFree(stack->stack_data[i].u.str);
|
||||||
stack->stack_data[i].type = C_INT;
|
stack->stack_data[i].type = C_INT;
|
||||||
|
}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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
script_free_vars( stack->var_function );
|
||||||
|
aFree(stack->var_function);
|
||||||
aFree (stack->stack_data);
|
aFree (stack->stack_data);
|
||||||
aFree (stack);
|
aFree (stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void script_free_code(struct script_code* code) {
|
||||||
|
script_free_vars( &code->script_vars );
|
||||||
|
aFree( code->script_buf );
|
||||||
|
aFree( code );
|
||||||
|
}
|
||||||
|
|
||||||
int axtoi(char *hexStg) {
|
int axtoi(char *hexStg) {
|
||||||
int n = 0; // position in string
|
int n = 0; // position in string
|
||||||
int m = 0; // position in digit[] to shift
|
int m = 0; // position in digit[] to shift
|
||||||
@ -2657,23 +2769,41 @@ int buildin_goto(struct script_state *st)
|
|||||||
*/
|
*/
|
||||||
int buildin_callfunc(struct script_state *st)
|
int buildin_callfunc(struct script_state *st)
|
||||||
{
|
{
|
||||||
char *scr;
|
struct script_code *scr, *oldscr;
|
||||||
char *str=conv_str(st,& (st->stack->stack_data[st->start+2]));
|
char *str=conv_str(st,& (st->stack->stack_data[st->start+2]));
|
||||||
|
|
||||||
if( (scr=(char *) strdb_get(userfunc_db,(unsigned char*)str)) ){
|
if( (scr=(struct script_code *) strdb_get(userfunc_db,(unsigned char*)str)) ){
|
||||||
int i,j;
|
int i,j;
|
||||||
|
struct linkdb_node **oldval = st->stack->var_function;
|
||||||
for(i=st->start+3,j=0;i<st->end;i++,j++)
|
for(i=st->start+3,j=0;i<st->end;i++,j++)
|
||||||
push_copy(st->stack,i);
|
push_copy(st->stack,i);
|
||||||
|
|
||||||
push_val(st->stack,C_INT,j); // 引数の数をプッシュ
|
push_val(st->stack,C_INT,j); // 引数の数をプッシュ
|
||||||
push_val(st->stack,C_INT,st->stack->defsp); // 現在の基準スタックポインタをプッシュ
|
push_val(st->stack,C_INT,st->stack->defsp); // 現在の基準スタックポインタをプッシュ
|
||||||
push_val(st->stack,C_INT,(int)st->script); // 現在のスクリプトをプッシュ
|
push_val(st->stack,C_INT,(int)st->script); // 現在のスクリプトをプッシュ
|
||||||
|
push_val(st->stack,C_INT,(int)st->stack->var_function); // 現在の関数依存変数をプッシュ
|
||||||
push_val(st->stack,C_RETINFO,st->pos); // 現在のスクリプト位置をプッシュ
|
push_val(st->stack,C_RETINFO,st->pos); // 現在のスクリプト位置をプッシュ
|
||||||
|
|
||||||
|
oldscr = st->script;
|
||||||
st->pos=0;
|
st->pos=0;
|
||||||
st->script=scr;
|
st->script=scr;
|
||||||
st->stack->defsp=st->start+4+j;
|
st->stack->defsp=st->start+5+j;
|
||||||
st->state=GOTO;
|
st->state=GOTO;
|
||||||
|
st->stack->var_function = (struct linkdb_node**)aCalloc(1, sizeof(struct linkdb_node*));
|
||||||
|
|
||||||
|
// ' 変数の引き継ぎ
|
||||||
|
for(i = 0; i < j; i++) {
|
||||||
|
struct script_data *s = &st->stack->stack_data[st->stack->sp-6-i];
|
||||||
|
if( s->type == C_NAME && !s->ref ) {
|
||||||
|
char *name = str_buf+str_data[s->u.num&0x00ffffff].str;
|
||||||
|
// '@ 変数の引き継ぎ
|
||||||
|
if( name[0] == '\'' && name[1] == '@' ) {
|
||||||
|
s->ref = oldval;
|
||||||
|
} else if( name[0] == '\'' ) {
|
||||||
|
s->ref = &oldscr->script_vars;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
ShowWarning("script:callfunc: function not found! [%s]\n",str);
|
ShowWarning("script:callfunc: function not found! [%s]\n",str);
|
||||||
st->state=END;
|
st->state=END;
|
||||||
@ -2694,17 +2824,32 @@ int buildin_callsub(struct script_state *st)
|
|||||||
st->state=END;
|
st->state=END;
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
|
struct linkdb_node **oldval = st->stack->var_function;
|
||||||
for(i=st->start+3,j=0;i<st->end;i++,j++)
|
for(i=st->start+3,j=0;i<st->end;i++,j++)
|
||||||
push_copy(st->stack,i);
|
push_copy(st->stack,i);
|
||||||
|
|
||||||
push_val(st->stack,C_INT,j); // 引数の数をプッシュ
|
push_val(st->stack,C_INT,j); // 引数の数をプッシュ
|
||||||
push_val(st->stack,C_INT,st->stack->defsp); // 現在の基準スタックポインタをプッシュ
|
push_val(st->stack,C_INT,st->stack->defsp); // 現在の基準スタックポインタをプッシュ
|
||||||
push_val(st->stack,C_INT,(int)st->script); // 現在のスクリプトをプッシュ
|
push_val(st->stack,C_INT,(int)st->script); // 現在のスクリプトをプッシュ
|
||||||
|
push_val(st->stack,C_INT,(int)st->stack->var_function); // 現在の関数依存変数をプッシュ
|
||||||
push_val(st->stack,C_RETINFO,st->pos); // 現在のスクリプト位置をプッシュ
|
push_val(st->stack,C_RETINFO,st->pos); // 現在のスクリプト位置をプッシュ
|
||||||
|
|
||||||
st->pos=pos;
|
st->pos=pos;
|
||||||
st->stack->defsp=st->start+4+j;
|
st->stack->defsp=st->start+5+j;
|
||||||
st->state=GOTO;
|
st->state=GOTO;
|
||||||
|
st->stack->var_function = (struct linkdb_node**)aCalloc(1, sizeof(struct linkdb_node*));
|
||||||
|
|
||||||
|
// ' 変数の引き継ぎ
|
||||||
|
for(i = 0; i < j; i++) {
|
||||||
|
struct script_data *s = &st->stack->stack_data[st->stack->sp-6-i];
|
||||||
|
if( s->type == C_NAME && !s->ref ) {
|
||||||
|
char *name = str_buf+str_data[s->u.num&0x00ffffff].str;
|
||||||
|
// '@ 変数の引き継ぎ
|
||||||
|
if( name[0] == '\'' && name[1] == '@' ) {
|
||||||
|
s->ref = oldval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2717,13 +2862,13 @@ int buildin_getarg(struct script_state *st)
|
|||||||
{
|
{
|
||||||
int num=conv_num(st,& (st->stack->stack_data[st->start+2]));
|
int num=conv_num(st,& (st->stack->stack_data[st->start+2]));
|
||||||
int max,stsp;
|
int max,stsp;
|
||||||
if( st->stack->defsp<4 || st->stack->stack_data[st->stack->defsp-1].type!=C_RETINFO ){
|
if( st->stack->defsp<5 || st->stack->stack_data[st->stack->defsp-1].type!=C_RETINFO ){
|
||||||
ShowWarning("script:getarg without callfunc or callsub!\n");
|
ShowWarning("script:getarg without callfunc or callsub!\n");
|
||||||
st->state=END;
|
st->state=END;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
max=conv_num(st,& (st->stack->stack_data[st->stack->defsp-4]));
|
max=conv_num(st,& (st->stack->stack_data[st->stack->defsp-5]));
|
||||||
stsp=st->stack->defsp - max -4;
|
stsp=st->stack->defsp - max -5;
|
||||||
if( num >= max ){
|
if( num >= max ){
|
||||||
ShowWarning("script:getarg arg1(%d) out of range(%d) !\n",num,max);
|
ShowWarning("script:getarg arg1(%d) out of range(%d) !\n",num,max);
|
||||||
st->state=END;
|
st->state=END;
|
||||||
@ -3248,7 +3393,7 @@ int buildin_input(struct script_state *st)
|
|||||||
if( postfix=='$' ){
|
if( postfix=='$' ){
|
||||||
// 文字列
|
// 文字列
|
||||||
if(st->end>st->start+2){ // 引数1個
|
if(st->end>st->start+2){ // 引数1個
|
||||||
set_reg(sd,num,name,(void*)sd->npc_str);
|
set_reg(st,sd,num,name,(void*)sd->npc_str,st->stack->stack_data[st->start+2].ref);
|
||||||
}else{
|
}else{
|
||||||
ShowError("buildin_input: string discarded !!\n");
|
ShowError("buildin_input: string discarded !!\n");
|
||||||
return 1;
|
return 1;
|
||||||
@ -3267,10 +3412,10 @@ int buildin_input(struct script_state *st)
|
|||||||
|
|
||||||
// 数値
|
// 数値
|
||||||
if(st->end>st->start+2){ // 引数1個
|
if(st->end>st->start+2){ // 引数1個
|
||||||
set_reg(sd,num,name,(void*)sd->npc_amount);
|
set_reg(st,sd,num,name,(void*)sd->npc_amount,st->stack->stack_data[st->start+2].ref);
|
||||||
} else {
|
} else {
|
||||||
// ragemu互換のため
|
// ragemu互換のため
|
||||||
pc_setreg(sd,add_str((unsigned char *) "l14"),sd->npc_amount);
|
//pc_setreg(sd,add_str((unsigned char *) "l14"),sd->npc_amount);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3301,18 +3446,18 @@ int buildin_set(struct script_state *st)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( prefix!='$' )
|
if( prefix!='$' && prefix!='\'' )
|
||||||
sd=script_rid2sd(st);
|
sd=script_rid2sd(st);
|
||||||
|
|
||||||
|
|
||||||
if( postfix=='$' ){
|
if( postfix=='$' ){
|
||||||
// 文字列
|
// 文字列
|
||||||
char *str = conv_str(st,& (st->stack->stack_data[st->start+3]));
|
char *str = conv_str(st,& (st->stack->stack_data[st->start+3]));
|
||||||
set_reg(sd,num,name,(void*)str);
|
set_reg(st,sd,num,name,(void*)str,st->stack->stack_data[st->start+2].ref);
|
||||||
}else{
|
}else{
|
||||||
// 数値
|
// 数値
|
||||||
int val = conv_num(st,& (st->stack->stack_data[st->start+3]));
|
int val = conv_num(st,& (st->stack->stack_data[st->start+3]));
|
||||||
set_reg(sd,num,name,(void*)val);
|
set_reg(st,sd,num,name,(void*)val,st->stack->stack_data[st->start+2].ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -3330,11 +3475,11 @@ int buildin_setarray(struct script_state *st)
|
|||||||
char postfix=name[strlen(name)-1];
|
char postfix=name[strlen(name)-1];
|
||||||
int i,j;
|
int i,j;
|
||||||
|
|
||||||
if( prefix!='$' && prefix!='@' ){
|
if( prefix!='$' && prefix!='@' && prefix!='\''){
|
||||||
ShowWarning("buildin_setarray: illegal scope !\n");
|
ShowWarning("buildin_setarray: illegal scope !\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if( prefix!='$' )
|
if( prefix!='$' && prefix!='\'' )
|
||||||
sd=script_rid2sd(st);
|
sd=script_rid2sd(st);
|
||||||
|
|
||||||
for(j=0,i=st->start+3; i<st->end && j<128;i++,j++){
|
for(j=0,i=st->start+3; i<st->end && j<128;i++,j++){
|
||||||
@ -3343,7 +3488,7 @@ int buildin_setarray(struct script_state *st)
|
|||||||
v=(void*)conv_str(st,& (st->stack->stack_data[i]));
|
v=(void*)conv_str(st,& (st->stack->stack_data[i]));
|
||||||
else
|
else
|
||||||
v=(void*)conv_num(st,& (st->stack->stack_data[i]));
|
v=(void*)conv_num(st,& (st->stack->stack_data[i]));
|
||||||
set_reg( sd, num+(j<<24), name, v);
|
set_reg(st, sd, num+(j<<24), name, v, st->stack->stack_data[st->start+2].ref);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3375,7 +3520,7 @@ int buildin_cleararray(struct script_state *st)
|
|||||||
v=(void*)conv_num(st,& (st->stack->stack_data[st->start+3]));
|
v=(void*)conv_num(st,& (st->stack->stack_data[st->start+3]));
|
||||||
|
|
||||||
for(i=0;i<sz;i++)
|
for(i=0;i<sz;i++)
|
||||||
set_reg(sd,num+(i<<24),name,v);
|
set_reg(st,sd,num+(i<<24),name,v,st->stack->stack_data[st->start+2].ref);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*==========================================
|
/*==========================================
|
||||||
@ -3396,48 +3541,60 @@ int buildin_copyarray(struct script_state *st)
|
|||||||
int sz=conv_num(st,& (st->stack->stack_data[st->start+4]));
|
int sz=conv_num(st,& (st->stack->stack_data[st->start+4]));
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( prefix!='$' && prefix!='@' && prefix2!='$' && prefix2!='@' ){
|
if( prefix!='$' && prefix!='@' && prefix!='\'' ){
|
||||||
ShowWarning("buildin_copyarray: illegal scope !\n");
|
printf("buildin_copyarray: illeagal scope !\n");
|
||||||
return 1;
|
return 0;
|
||||||
|
}
|
||||||
|
if( prefix2!='$' && prefix2!='@' && prefix2!='\'' ) {
|
||||||
|
printf("buildin_copyarray: illeagal scope !\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
if( (postfix=='$' || postfix2=='$') && postfix!=postfix2 ){
|
if( (postfix=='$' || postfix2=='$') && postfix!=postfix2 ){
|
||||||
ShowError("buildin_copyarray: type mismatch !\n");
|
printf("buildin_copyarray: type mismatch !\n");
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
if( prefix!='$' || prefix2!='$' )
|
if( (prefix!='$' && prefix != '\'') || (prefix2!='$' && prefix2 != '\'') )
|
||||||
sd=script_rid2sd(st);
|
sd=script_rid2sd(st);
|
||||||
|
|
||||||
// if two array is the same and (num > num2), bottom-up copy is required [Eoe / jA 1116]
|
|
||||||
if((num & 0x00FFFFFF) == (num2 & 0x00FFFFFF) && (num & 0xFF000000) > (num2 & 0xFF000000)) {
|
if((num & 0x00FFFFFF) == (num2 & 0x00FFFFFF) && (num & 0xFF000000) > (num2 & 0xFF000000)) {
|
||||||
|
// 同じ配列で、num > num2 の場合大きい方からコピーしないといけない
|
||||||
for(i=sz-1;i>=0;i--)
|
for(i=sz-1;i>=0;i--)
|
||||||
set_reg(sd,num+(i<<24),name, get_val2(st,num2+(i<<24)) );
|
set_reg(
|
||||||
|
st,sd,num+(i<<24),name,
|
||||||
|
get_val2(st,num2+(i<<24),st->stack->stack_data[st->start+3].ref),
|
||||||
|
st->stack->stack_data[st->start+2].ref
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
for(i=0;i<sz;i++)
|
for(i=0;i<sz;i++)
|
||||||
set_reg(sd,num+(i<<24),name, get_val2(st,num2+(i<<24)) );
|
set_reg(
|
||||||
|
st,sd,num+(i<<24),name,
|
||||||
|
get_val2(st,num2+(i<<24),st->stack->stack_data[st->start+3].ref),
|
||||||
|
st->stack->stack_data[st->start+2].ref
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*==========================================
|
/*==========================================
|
||||||
* 配列変数のサイズ所得
|
* 配列変数のサイズ所得
|
||||||
*------------------------------------------
|
*------------------------------------------
|
||||||
*/
|
*/
|
||||||
static int getarraysize(struct script_state *st,int num,int postfix)
|
static int getarraysize(struct script_state *st,int num,int postfix,struct linkdb_node** ref)
|
||||||
{
|
{
|
||||||
int i=(num>>24),c=(i==0? -1:i); // Moded to -1 because even if the first element is 0, it will still report as 1 [Lance]
|
int i=(num>>24),c=(i==0? -1:i); // Moded to -1 because even if the first element is 0, it will still report as 1 [Lance]
|
||||||
if(postfix == '$'){
|
if(postfix == '$'){
|
||||||
for(;i<128;i++){
|
for(;i<128;i++){
|
||||||
void *v=get_val2(st,(num & 0x00FFFFFF)+(i<<24));
|
void *v=get_val2(st,(num & 0x00FFFFFF)+(i<<24),ref);
|
||||||
if(*((char*)v)) c=i;
|
if(*((char*)v)) c=i;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
for(;i<128;i++){
|
for(;i<128;i++){
|
||||||
void *v=get_val2(st,(num & 0x00FFFFFF)+(i<<24));
|
void *v=get_val2(st,(num & 0x00FFFFFF)+(i<<24),ref);
|
||||||
if((int)v) c=i;
|
if((int)v) c=i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c+1;
|
return c+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int buildin_getarraysize(struct script_state *st)
|
int buildin_getarraysize(struct script_state *st)
|
||||||
{
|
{
|
||||||
int num=st->stack->stack_data[st->start+2].u.num;
|
int num=st->stack->stack_data[st->start+2].u.num;
|
||||||
@ -3445,12 +3602,12 @@ int buildin_getarraysize(struct script_state *st)
|
|||||||
char prefix=*name;
|
char prefix=*name;
|
||||||
char postfix=name[strlen(name)-1];
|
char postfix=name[strlen(name)-1];
|
||||||
|
|
||||||
if( prefix!='$' && prefix!='@' ){
|
if( prefix!='$' && prefix!='@' && prefix!='\'' ){
|
||||||
ShowWarning("buildin_copyarray: illegal scope !\n");
|
ShowWarning("buildin_copyarray: illegal scope !\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
push_val(st->stack,C_INT,getarraysize(st,num,postfix) );
|
push_val(st->stack,C_INT,getarraysize(st,num,postfix,st->stack->stack_data[st->start+2].ref));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*==========================================
|
/*==========================================
|
||||||
@ -3465,7 +3622,7 @@ int buildin_deletearray(struct script_state *st)
|
|||||||
char prefix=*name;
|
char prefix=*name;
|
||||||
char postfix=name[strlen(name)-1];
|
char postfix=name[strlen(name)-1];
|
||||||
int count=1;
|
int count=1;
|
||||||
int i,sz=getarraysize(st,num,postfix)-(num>>24)-count+1;
|
int i,sz=getarraysize(st,num,postfix,st->stack->stack_data[st->start+2].ref)-(num>>24)-count+1;
|
||||||
|
|
||||||
|
|
||||||
if( (st->end > st->start+3) )
|
if( (st->end > st->start+3) )
|
||||||
@ -3479,15 +3636,19 @@ int buildin_deletearray(struct script_state *st)
|
|||||||
sd=script_rid2sd(st);
|
sd=script_rid2sd(st);
|
||||||
|
|
||||||
for(i=0;i<sz;i++){
|
for(i=0;i<sz;i++){
|
||||||
set_reg(sd,num+(i<<24),name, get_val2(st,num+((i+count)<<24) ) );
|
set_reg(
|
||||||
|
st,sd,num+(i<<24),name,
|
||||||
|
get_val2(st,num+((i+count)<<24),st->stack->stack_data[st->start+2].ref),
|
||||||
|
st->stack->stack_data[st->start+2].ref
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(postfix != '$'){
|
if(postfix != '$'){
|
||||||
for(;i<(128-(num>>24));i++)
|
for(;i<(128-(num>>24));i++)
|
||||||
set_reg(sd,num+(i<<24),name, 0);
|
set_reg(st,sd,num+(i<<24),name, 0,st->stack->stack_data[st->start+2].ref);
|
||||||
} else {
|
} else {
|
||||||
for(;i<(128-(num>>24));i++)
|
for(;i<(128-(num>>24));i++)
|
||||||
set_reg(sd,num+(i<<24),name, (void *) "");
|
set_reg(st,sd,num+(i<<24),name, (void *) "",st->stack->stack_data[st->start+2].ref);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -9112,7 +9273,7 @@ int buildin_getmapxy(struct script_state *st){
|
|||||||
else
|
else
|
||||||
sd=NULL;
|
sd=NULL;
|
||||||
|
|
||||||
set_reg(sd,num,name,(void*)mapname);
|
set_reg(st,sd,num,name,(void*)mapname,NULL);
|
||||||
|
|
||||||
//Set MapX
|
//Set MapX
|
||||||
num=st->stack->stack_data[st->start+3].u.num;
|
num=st->stack->stack_data[st->start+3].u.num;
|
||||||
@ -9123,7 +9284,7 @@ int buildin_getmapxy(struct script_state *st){
|
|||||||
sd=script_rid2sd(st);
|
sd=script_rid2sd(st);
|
||||||
else
|
else
|
||||||
sd=NULL;
|
sd=NULL;
|
||||||
set_reg(sd,num,name,(void*)x);
|
set_reg(st,sd,num,name,(void*)x,NULL);
|
||||||
|
|
||||||
|
|
||||||
//Set MapY
|
//Set MapY
|
||||||
@ -9136,7 +9297,7 @@ int buildin_getmapxy(struct script_state *st){
|
|||||||
else
|
else
|
||||||
sd=NULL;
|
sd=NULL;
|
||||||
|
|
||||||
set_reg(sd,num,name,(void*)y);
|
set_reg(st,sd,num,name,(void*)y,NULL);
|
||||||
|
|
||||||
//Return Success value
|
//Return Success value
|
||||||
push_val(st->stack,C_INT,0);
|
push_val(st->stack,C_INT,0);
|
||||||
@ -9726,7 +9887,7 @@ int buildin_distance(struct script_state *st){
|
|||||||
// [zBuffer] List of dynamic var commands --->
|
// [zBuffer] List of dynamic var commands --->
|
||||||
void setd_sub(struct map_session_data *sd, char *varname, int elem, void *value)
|
void setd_sub(struct map_session_data *sd, char *varname, int elem, void *value)
|
||||||
{
|
{
|
||||||
set_reg(sd, add_str((unsigned char *) varname)+(elem<<24), varname, value);
|
set_reg(NULL, sd, add_str((unsigned char *) varname)+(elem<<24), varname, value, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9980,7 +10141,7 @@ int buildin_setitemscript(struct script_state *st)
|
|||||||
|
|
||||||
if (i_data && script!=NULL && script[0]=='{') {
|
if (i_data && script!=NULL && script[0]=='{') {
|
||||||
if(i_data->script!=NULL)
|
if(i_data->script!=NULL)
|
||||||
aFree(i_data->script);
|
script_free_code(i_data->script);
|
||||||
i_data->script = parse_script((unsigned char *) script, 0);
|
i_data->script = parse_script((unsigned char *) script, 0);
|
||||||
push_val(st->stack,C_INT,1);
|
push_val(st->stack,C_INT,1);
|
||||||
} else
|
} else
|
||||||
@ -10542,6 +10703,107 @@ int buildin_mobattach(struct script_state *st){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// <--- [zBuffer] List of mob control commands
|
// <--- [zBuffer] List of mob control commands
|
||||||
|
|
||||||
|
// sleep <mili sec>
|
||||||
|
int buildin_sleep(struct script_state *st) {
|
||||||
|
int tick = conv_num(st,& (st->stack->stack_data[st->start+2]));
|
||||||
|
struct map_session_data *sd = map_id2sd(st->rid);
|
||||||
|
if(sd && sd->npc_id == st->oid) {
|
||||||
|
sd->npc_id = 0;
|
||||||
|
}
|
||||||
|
st->rid = 0;
|
||||||
|
if(tick <= 0) {
|
||||||
|
// 何もしない
|
||||||
|
} else if( !st->sleep.tick ) {
|
||||||
|
// 初回実行
|
||||||
|
st->state = RERUNLINE;
|
||||||
|
st->sleep.tick = tick;
|
||||||
|
} else {
|
||||||
|
// 続行
|
||||||
|
st->sleep.tick = 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sleep2 <mili sec>
|
||||||
|
int buildin_sleep2(struct script_state *st) {
|
||||||
|
int tick = conv_num(st,& (st->stack->stack_data[st->start+2]));
|
||||||
|
if( tick <= 0 ) {
|
||||||
|
// 0ms の待機時間を指定された
|
||||||
|
push_val(st->stack,C_INT,map_id2sd(st->rid) != NULL);
|
||||||
|
} else if( !st->sleep.tick ) {
|
||||||
|
// 初回実行時
|
||||||
|
st->state = RERUNLINE;
|
||||||
|
st->sleep.tick = tick;
|
||||||
|
} else {
|
||||||
|
push_val(st->stack,C_INT,map_id2sd(st->rid) != NULL);
|
||||||
|
st->sleep.tick = 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==========================================
|
||||||
|
* 指定NPCの全てのsleepを再開する
|
||||||
|
*------------------------------------------
|
||||||
|
*/
|
||||||
|
int buildin_awake(struct script_state *st)
|
||||||
|
{
|
||||||
|
struct npc_data *nd;
|
||||||
|
struct linkdb_node *node = (struct linkdb_node *)sleep_db;
|
||||||
|
|
||||||
|
nd = npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2])));
|
||||||
|
if(nd == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while( node ) {
|
||||||
|
if( (int)node->key == nd->bl.id) {
|
||||||
|
struct script_state *tst = node->data;
|
||||||
|
struct map_session_data *sd = map_id2sd(tst->rid);
|
||||||
|
|
||||||
|
if( tst->sleep.timer == -1 ) {
|
||||||
|
node = node->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( sd && sd->char_id != tst->sleep.charid )
|
||||||
|
tst->rid = 0;
|
||||||
|
|
||||||
|
delete_timer(tst->sleep.timer, run_script_timer);
|
||||||
|
node = script_erase_sleepdb(node);
|
||||||
|
tst->sleep.timer = -1;
|
||||||
|
run_script_main(tst);
|
||||||
|
} else {
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// getvariableofnpc(<param>, <npc name>);
|
||||||
|
int buildin_getvariableofnpc(struct script_state *st)
|
||||||
|
{
|
||||||
|
if( st->stack->stack_data[st->start+2].type != C_NAME ) {
|
||||||
|
// 第一引数が変数名じゃない
|
||||||
|
printf("getvariableofnpc: param not name\n");
|
||||||
|
push_val(st->stack,C_INT,0);
|
||||||
|
} else {
|
||||||
|
int num = st->stack->stack_data[st->start+2].u.num;
|
||||||
|
char *var_name = str_buf+str_data[num&0x00ffffff].str;
|
||||||
|
char *npc_name = conv_str(st,& (st->stack->stack_data[st->start+3]));
|
||||||
|
struct npc_data *nd = npc_name2id(npc_name);
|
||||||
|
if( var_name[0] != '\'' || var_name[1] == '@' ) {
|
||||||
|
// ' 変数以外はダメ
|
||||||
|
printf("getvariableofnpc: invalid scope %s\n", var_name);
|
||||||
|
push_val(st->stack,C_INT,0);
|
||||||
|
} else if( nd == NULL || nd->bl.subtype != SCRIPT || !nd->u.scr.script) {
|
||||||
|
// NPC が見つからない or SCRIPT以外のNPC
|
||||||
|
printf("getvariableofnpc: can't find npc %s\n", npc_name);
|
||||||
|
push_val(st->stack,C_INT,0);
|
||||||
|
} else {
|
||||||
|
push_val2(st->stack,C_NAME,num, &nd->u.scr.script->script_vars );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// 実行部main
|
// 実行部main
|
||||||
//
|
//
|
||||||
@ -10913,18 +11175,21 @@ int run_func(struct script_state *st)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
pop_stack(st->stack,st->stack->defsp,start_sp); // 復帰に邪魔なスタック削除
|
pop_stack(st->stack,st->stack->defsp,start_sp); // 復帰に邪魔なスタック削除
|
||||||
if(st->stack->defsp<4 || st->stack->stack_data[st->stack->defsp-1].type!=C_RETINFO){
|
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");
|
ShowWarning("script:run_func(return) return without callfunc or callsub!\n");
|
||||||
st->state=END;
|
st->state=END;
|
||||||
report_src(st);
|
report_src(st);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
i = conv_num(st,& (st->stack->stack_data[st->stack->defsp-4])); // 引数の数所得
|
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->pos=conv_num(st,& (st->stack->stack_data[st->stack->defsp-1])); // スクリプト位置の復元
|
||||||
st->script=(char*)conv_num(st,& (st->stack->stack_data[st->stack->defsp-2])); // スクリプトを復元
|
st->script=(struct script_code *)conv_num(st,& (st->stack->stack_data[st->stack->defsp-3])); // スクリプトを復元
|
||||||
st->stack->defsp=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-4-i,olddefsp); // 要らなくなったスタック(引数と復帰用データ)削除
|
pop_stack(st->stack,olddefsp-5-i,olddefsp); // 要らなくなったスタック(引数と復帰用データ)削除
|
||||||
|
|
||||||
st->state=GOTO;
|
st->state=GOTO;
|
||||||
}
|
}
|
||||||
@ -10942,6 +11207,7 @@ int run_script_main(struct script_state *st)
|
|||||||
int cmdcount=script_config.check_cmdcount;
|
int cmdcount=script_config.check_cmdcount;
|
||||||
int gotocount=script_config.check_gotocount;
|
int gotocount=script_config.check_gotocount;
|
||||||
struct script_stack *stack=st->stack;
|
struct script_stack *stack=st->stack;
|
||||||
|
TBL_PC *sd=NULL;
|
||||||
|
|
||||||
if(st->state == RERUNLINE) {
|
if(st->state == RERUNLINE) {
|
||||||
st->state = RUN;
|
st->state = RUN;
|
||||||
@ -10953,7 +11219,7 @@ int run_script_main(struct script_state *st)
|
|||||||
st->state = RUN;
|
st->state = RUN;
|
||||||
}
|
}
|
||||||
while( st->state == RUN) {
|
while( st->state == RUN) {
|
||||||
c= get_com((unsigned char *) st->script,&st->pos);
|
c= get_com((unsigned char *) st->script->script_buf,&st->pos);
|
||||||
switch(c){
|
switch(c){
|
||||||
case C_EOL:
|
case C_EOL:
|
||||||
if(stack->sp!=stack->defsp){
|
if(stack->sp!=stack->defsp){
|
||||||
@ -10970,19 +11236,19 @@ int run_script_main(struct script_state *st)
|
|||||||
// rerun_pos=st->pos;
|
// rerun_pos=st->pos;
|
||||||
break;
|
break;
|
||||||
case C_INT:
|
case C_INT:
|
||||||
push_val(stack,C_INT,get_num((unsigned char *) st->script,&st->pos));
|
push_val(stack,C_INT,get_num((unsigned char *) st->script->script_buf,&st->pos));
|
||||||
break;
|
break;
|
||||||
case C_POS:
|
case C_POS:
|
||||||
case C_NAME:
|
case C_NAME:
|
||||||
push_val(stack,c,(*(int*)(st->script+st->pos))&0xffffff);
|
push_val(stack,c,(*(int*)(st->script->script_buf+st->pos))&0xffffff);
|
||||||
st->pos+=3;
|
st->pos+=3;
|
||||||
break;
|
break;
|
||||||
case C_ARG:
|
case C_ARG:
|
||||||
push_val(stack,c,0);
|
push_val(stack,c,0);
|
||||||
break;
|
break;
|
||||||
case C_STR:
|
case C_STR:
|
||||||
push_str(stack,C_CONSTSTR,(unsigned char *) (st->script+st->pos));
|
push_str(stack,C_CONSTSTR,(unsigned char *) (st->script->script_buf+st->pos));
|
||||||
while(st->script[st->pos++]);
|
while(st->script->script_buf[st->pos++]);
|
||||||
break;
|
break;
|
||||||
case C_FUNC:
|
case C_FUNC:
|
||||||
run_func(st);
|
run_func(st);
|
||||||
@ -11041,6 +11307,14 @@ int run_script_main(struct script_state *st)
|
|||||||
st->state=END;
|
st->state=END;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sd = map_id2sd(st->rid);
|
||||||
|
if(st->sleep.tick > 0) {
|
||||||
|
// スタック情報をsleep_dbに保存
|
||||||
|
unsigned int tick = gettick()+st->sleep.tick;
|
||||||
|
st->sleep.charid = sd ? sd->char_id : 0;
|
||||||
|
st->sleep.timer = add_timer(tick, run_script_timer, st->sleep.charid, (int)st);
|
||||||
|
linkdb_insert(&sleep_db, (void*)st->oid, st);
|
||||||
|
} else {
|
||||||
switch(st->state){
|
switch(st->state){
|
||||||
case STOP:
|
case STOP:
|
||||||
break;
|
break;
|
||||||
@ -11067,6 +11341,7 @@ int run_script_main(struct script_state *st)
|
|||||||
// }
|
// }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -11075,20 +11350,20 @@ int run_script_main(struct script_state *st)
|
|||||||
* スクリプトの実行
|
* スクリプトの実行
|
||||||
*------------------------------------------
|
*------------------------------------------
|
||||||
*/
|
*/
|
||||||
int run_script(unsigned char *script,int pos,int rid,int oid)
|
int run_script(struct script_code *rootscript,int pos,int rid,int oid)
|
||||||
{
|
{
|
||||||
struct script_state st;
|
struct script_state st;
|
||||||
struct map_session_data *sd;
|
struct map_session_data *sd=NULL;
|
||||||
unsigned char *rootscript = script;
|
|
||||||
|
|
||||||
//Variables for backing up the previous script and restore it if needed. [Skotlex]
|
//Variables for backing up the previous script and restore it if needed. [Skotlex]
|
||||||
unsigned char *bck_script = NULL;
|
struct script_code *bck_script = NULL;
|
||||||
unsigned char *bck_scriptroot = NULL;
|
struct script_code *bck_scriptroot = NULL;
|
||||||
int bck_scriptstate = 0;
|
int bck_scriptstate = 0;
|
||||||
struct script_stack *bck_stack = NULL;
|
struct script_stack *bck_stack = NULL;
|
||||||
|
|
||||||
if (script == NULL || pos < 0)
|
if (rootscript == NULL || pos < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memset(&st, 0, sizeof(struct script_state));
|
memset(&st, 0, sizeof(struct script_state));
|
||||||
|
|
||||||
if ((sd = map_id2sd(rid)) && sd->stack && sd->npc_scriptroot == rootscript){
|
if ((sd = map_id2sd(rid)) && sd->stack && sd->npc_scriptroot == rootscript){
|
||||||
@ -11108,6 +11383,7 @@ int run_script(unsigned char *script,int pos,int rid,int oid)
|
|||||||
st.stack->sp_max = 64;
|
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->stack_data = (struct script_data *) aCalloc (st.stack->sp_max,sizeof(st.stack->stack_data[0]));
|
||||||
st.stack->defsp = st.stack->sp;
|
st.stack->defsp = st.stack->sp;
|
||||||
|
st.stack->var_function = aCalloc(1, sizeof(struct linkdb_node*));
|
||||||
st.state = RUN;
|
st.state = RUN;
|
||||||
st.script = rootscript;
|
st.script = rootscript;
|
||||||
|
|
||||||
@ -11122,6 +11398,7 @@ int run_script(unsigned char *script,int pos,int rid,int oid)
|
|||||||
st.pos = pos;
|
st.pos = pos;
|
||||||
st.rid = rid;
|
st.rid = rid;
|
||||||
st.oid = oid;
|
st.oid = oid;
|
||||||
|
st.sleep.timer = -1;
|
||||||
// let's run that stuff
|
// let's run that stuff
|
||||||
run_script_main(&st);
|
run_script_main(&st);
|
||||||
|
|
||||||
@ -11155,6 +11432,57 @@ int run_script(unsigned char *script,int pos,int rid,int oid)
|
|||||||
return st.pos;
|
return st.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*==========================================
|
||||||
|
* 指定ノードをsleep_dbから削除
|
||||||
|
*------------------------------------------
|
||||||
|
*/
|
||||||
|
/*==========================================
|
||||||
|
* 指定ノードを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 = 0;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*==========================================
|
/*==========================================
|
||||||
* マップ変数の変更
|
* マップ変数の変更
|
||||||
@ -11567,6 +11895,16 @@ int do_final_script()
|
|||||||
mapregstr_db->destroy(mapregstr_db,NULL);
|
mapregstr_db->destroy(mapregstr_db,NULL);
|
||||||
scriptlabel_db->destroy(scriptlabel_db,NULL);
|
scriptlabel_db->destroy(scriptlabel_db,NULL);
|
||||||
userfunc_db->destroy(userfunc_db,NULL);
|
userfunc_db->destroy(userfunc_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);
|
||||||
|
}
|
||||||
|
|
||||||
if (str_data)
|
if (str_data)
|
||||||
aFree(str_data);
|
aFree(str_data);
|
||||||
|
@ -35,30 +35,45 @@ struct script_data {
|
|||||||
int num;
|
int num;
|
||||||
char *str;
|
char *str;
|
||||||
} u;
|
} u;
|
||||||
|
struct linkdb_node** ref; // リファレンス
|
||||||
};
|
};
|
||||||
|
|
||||||
// Moved defsp from script_state to script_stack since
|
// Moved defsp from script_state to script_stack since
|
||||||
// it must be saved when script state is RERUNLINE. [Eoe / jA 1094]
|
// it must be saved when script state is RERUNLINE. [Eoe / jA 1094]
|
||||||
|
struct script_code {
|
||||||
|
int script_size;
|
||||||
|
unsigned char* script_buf;
|
||||||
|
struct linkdb_node* script_vars;
|
||||||
|
};
|
||||||
struct script_stack {
|
struct script_stack {
|
||||||
int sp,sp_max,defsp;
|
int sp,sp_max,defsp;
|
||||||
struct script_data *stack_data;
|
struct script_data *stack_data;
|
||||||
|
struct linkdb_node **var_function; // 関数依存変数
|
||||||
};
|
};
|
||||||
struct script_state {
|
struct script_state {
|
||||||
struct script_stack *stack;
|
struct script_stack *stack;
|
||||||
int start,end;
|
int start,end;
|
||||||
int pos,state;
|
int pos,state;
|
||||||
int rid,oid;
|
int rid,oid;
|
||||||
unsigned char *script,*new_script;
|
//unsigned char *script,*new_script;
|
||||||
int new_pos,new_defsp;
|
int new_pos,new_defsp;
|
||||||
|
struct script_code *script, *scriptroot;
|
||||||
|
struct sleep_data {
|
||||||
|
int tick,timer,charid;
|
||||||
|
} sleep;
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned char * parse_script(unsigned char *,int);
|
struct script_code *parse_script(unsigned char *,int);
|
||||||
int run_script(unsigned char *,int,int,int);
|
int run_script(struct script_code *rootscript,int pos,int rid,int oid);
|
||||||
|
|
||||||
int set_var(struct map_session_data *sd, char *name, void *val);
|
int set_var(struct map_session_data *sd, char *name, void *val);
|
||||||
int conv_num(struct script_state *st,struct script_data *data);
|
int conv_num(struct script_state *st,struct script_data *data);
|
||||||
char* conv_str(struct script_state *st,struct script_data *data);
|
char* conv_str(struct script_state *st,struct script_data *data);
|
||||||
void setd_sub(struct map_session_data *sd, char *varname, int elem, void *value);
|
void setd_sub(struct map_session_data *sd, char *varname, int elem, void *value);
|
||||||
|
int run_script_timer(int tid, unsigned int tick, int id, int data);
|
||||||
|
int run_script_main(struct script_state *st);
|
||||||
|
struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n);
|
||||||
|
void script_free_code(struct script_code* code);
|
||||||
|
|
||||||
struct dbt* script_get_label_db(void);
|
struct dbt* script_get_label_db(void);
|
||||||
struct dbt* script_get_userfunc_db(void);
|
struct dbt* script_get_userfunc_db(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user