@ -124,6 +124,8 @@ char tmp_sql[65535];
// --------------------------------------------------------
# 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_mobattach ( struct script_state * st ) ;
// <--- [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 ) ;
int run_func ( struct script_state * st ) ;
@ -763,6 +769,10 @@ struct {
{ buildin_mobemote , " mobemote " , " * " } ,
{ buildin_mobattach , " mobattach " , " * " } ,
// <--- [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 } ,
} ;
@ -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 ;
int i ;
struct script_code * code ;
static int first = 1 ;
if ( first ) {
@ -2275,7 +2286,11 @@ unsigned char* parse_script(unsigned char *src,int line)
# endif
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,7 +2345,17 @@ int get_val(struct script_state*st,struct script_data* data)
if ( sd )
data - > u . str = pc_readaccountregstr ( sd , name ) ;
}
} else {
} 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 {
if ( sd )
data - > u . str = pc_readglobalreg_str ( sd , name ) ;
} // [zBuffer]
@ -2362,6 +2387,16 @@ int get_val(struct script_state*st,struct script_data* data)
if ( sd )
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 {
if ( sd )
data - > u . num = pc_readglobalreg ( sd , name ) ;
@ -2374,11 +2409,12 @@ int get_val(struct script_state*st,struct script_data* data)
* 変 数 の 読 み 取 り 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 ;
dat . type = C_NAME ;
dat . u . num = num ;
dat . ref = ref ;
get_val ( st , & dat ) ;
if ( dat . type = = C_INT ) return ( void * ) dat . u . num ;
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 postfix = name [ strlen ( name ) - 1 ] ;
@ -2404,7 +2440,24 @@ static int set_reg(struct map_session_data *sd,int num,char *name,void *v)
pc_setaccountreg2str ( sd , name , str ) ;
else
pc_setaccountregstr ( sd , name , str ) ;
} else {
} 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 {
pc_setglobalreg_str ( sd , name , str ) ;
} // [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 ) ;
else
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 {
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 )
{
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);
stack - > stack_data [ stack - > sp ] . type = type ;
stack - > stack_data [ stack - > sp ] . u . num = val ;
stack - > stack_data [ stack - > sp ] . ref = NULL ;
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);
stack - > stack_data [ stack - > sp ] . type = type ;
stack - > stack_data [ stack - > sp ] . u . str = ( char * ) str ;
stack - > stack_data [ stack - > sp ] . ref = NULL ;
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 ) ) ;
break ;
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 ;
}
}
@ -2556,6 +2638,24 @@ void pop_stack(struct script_stack* stack,int start,int end)
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 ]
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -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);
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 ) {
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 ) ;
}
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 n = 0 ; // position in string
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 )
{
char * scr;
struct script_code * scr , * old scr;
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 ;
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 ) ;
push_val ( st - > stack , C_INT , j ) ; // 引数の数をプッシュ
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 - > stack - > var_function ) ; // 現在の関数依存変数をプッシュ
push_val ( st - > stack , C_RETINFO , st - > pos ) ; // 現在のスクリプト位置をプッシュ
oldscr = st - > script ;
st - > pos = 0 ;
st - > script = scr ;
st - > stack - > defsp = st - > start + 4 + j ;
st - > stack - > defsp = st - > start + 5 + j ;
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 {
ShowWarning ( " script:callfunc: function not found! [%s] \n " , str ) ;
st - > state = END ;
@ -2694,17 +2824,32 @@ int buildin_callsub(struct script_state *st)
st - > state = END ;
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 ) ;
push_val ( st - > stack , C_INT , j ) ; // 引数の数をプッシュ
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 - > stack - > var_function ) ; // 現在の関数依存変数をプッシュ
push_val ( st - > stack , C_RETINFO , st - > pos ) ; // 現在のスクリプト位置をプッシュ
st - > pos = pos ;
st - > stack - > defsp = st - > start + 4 + j ;
st - > stack - > defsp = st - > start + 5 + j ;
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 ;
}
@ -2717,13 +2862,13 @@ int buildin_getarg(struct script_state *st)
{
int num = conv_num ( st , & ( st - > stack - > stack_data [ st - > start + 2 ] ) ) ;
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 " ) ;
st - > state = END ;
return 1 ;
}
max = conv_num ( st , & ( st - > stack - > stack_data [ st - > stack - > defsp - 4 ] ) ) ;
stsp = st - > stack - > defsp - max - 4 ;
max = conv_num ( st , & ( st - > stack - > stack_data [ st - > stack - > defsp - 5 ] ) ) ;
stsp = st - > stack - > defsp - max - 5 ;
if ( num > = max ) {
ShowWarning ( " script:getarg arg1(%d) out of range(%d) ! \n " , num , max ) ;
st - > state = END ;
@ -3248,7 +3393,7 @@ int buildin_input(struct script_state *st)
if ( postfix = = ' $ ' ) {
// 文字列
if ( st - > end > st - > start + 2 ) { // 引数1個
set_reg ( s d, num , name , ( void * ) sd - > npc_str ) ;
set_reg ( s t, s d, num , name , ( void * ) sd - > npc_str , st - > stack - > stack_data [ st - > start + 2 ] . ref ) ;
} else {
ShowError ( " buildin_input: string discarded !! \n " ) ;
return 1 ;
@ -3267,10 +3412,10 @@ int buildin_input(struct script_state *st)
// 数値
if ( st - > end > st - > start + 2 ) { // 引数1個
set_reg ( s d, num , name , ( void * ) sd - > npc_amount ) ;
set_reg ( s t, s d, num , name , ( void * ) sd - > npc_amount , st - > stack - > stack_data [ st - > start + 2 ] . ref ) ;
} else {
// 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 ;
}
@ -3301,18 +3446,18 @@ int buildin_set(struct script_state *st)
return 1 ;
}
if ( prefix ! = ' $ ' )
if ( prefix ! = ' $ ' & & prefix ! = ' \' ' )
sd = script_rid2sd ( st ) ;
if ( postfix = = ' $ ' ) {
// 文字列
char * str = conv_str ( st , & ( st - > stack - > stack_data [ st - > start + 3 ] ) ) ;
set_reg ( s d, num , name , ( void * ) str ) ;
set_reg ( s t, s d, num , name , ( void * ) str , st - > stack - > stack_data [ st - > start + 2 ] . ref ) ;
} else {
// 数値
int val = conv_num ( st , & ( st - > stack - > stack_data [ st - > start + 3 ] ) ) ;
set_reg ( s d, num , name , ( void * ) val ) ;
set_reg ( s t, s d, num , name , ( void * ) val , st - > stack - > stack_data [ st - > start + 2 ] . ref ) ;
}
return 0 ;
@ -3330,11 +3475,11 @@ int buildin_setarray(struct script_state *st)
char postfix = name [ strlen ( name ) - 1 ] ;
int i , j ;
if ( prefix ! = ' $ ' & & prefix ! = ' @ ' ) {
if ( prefix ! = ' $ ' & & prefix ! = ' @ ' & & prefix ! = ' \' ' ) {
ShowWarning ( " buildin_setarray: illegal scope ! \n " ) ;
return 1 ;
}
if ( prefix ! = ' $ ' )
if ( prefix ! = ' $ ' & & prefix ! = ' \' ' )
sd = script_rid2sd ( st ) ;
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 ] ) ) ;
else
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 ;
}
@ -3375,7 +3520,7 @@ int buildin_cleararray(struct script_state *st)
v = ( void * ) conv_num ( st , & ( st - > stack - > stack_data [ st - > start + 3 ] ) ) ;
for ( i = 0 ; i < sz ; i + + )
set_reg ( s d, num + ( i < < 24 ) , name , v ) ;
set_reg ( s t, s d, num + ( i < < 24 ) , name , v , st - > stack - > stack_data [ st - > start + 2 ] . ref ) ;
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 i ;
if ( prefix ! = ' $ ' & & prefix ! = ' @ ' & & prefix2 ! = ' $ ' & & prefix2 ! = ' @ ' ) {
ShowWarning ( " buildin_copyarray: illegal scope ! \n " ) ;
return 1 ;
if ( prefix ! = ' $ ' & & prefix ! = ' @ ' & & prefix ! = ' \' ' ) {
printf ( " buildin_copyarray: illeagal scope ! \n " ) ;
return 0 ;
}
if ( prefix2 ! = ' $ ' & & prefix2 ! = ' @ ' & & prefix2 ! = ' \' ' ) {
printf ( " buildin_copyarray: illeagal scope ! \n " ) ;
return 0 ;
}
if ( ( postfix = = ' $ ' | | postfix2 = = ' $ ' ) & & postfix ! = postfix2 ) {
ShowError ( " buildin_copyarray: type mismatch ! \n " ) ;
return 1 ;
printf ( " buildin_copyarray: type mismatch ! \n " ) ;
return 0 ;
}
if ( prefix ! = ' $ ' || prefix2 ! = ' $ ' )
if ( ( prefix ! = ' $ ' && prefix ! = ' \' ' ) || ( prefix2 ! = ' $ ' & & prefix2 ! = ' \' ' ) )
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 ) ) {
// 同じ配列で、num > num2 の場合大きい方からコピーしないといけない
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 {
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 ;
}
/*==========================================
* 配 列 変 数 の サ イ ズ 所 得
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
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]
if ( postfix = = ' $ ' ) {
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 ;
}
} else {
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 ;
}
}
return c + 1 ;
}
int buildin_getarraysize ( struct script_state * st )
{
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 postfix = name [ strlen ( name ) - 1 ] ;
if ( prefix ! = ' $ ' & & prefix ! = ' @ ' ) {
if ( prefix ! = ' $ ' & & prefix ! = ' @ ' & & prefix ! = ' \' ' ) {
ShowWarning ( " buildin_copyarray: illegal scope ! \n " ) ;
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 ;
}
/*==========================================
@ -3465,7 +3622,7 @@ int buildin_deletearray(struct script_state *st)
char prefix = * name ;
char postfix = name [ strlen ( name ) - 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 ) )
@ -3479,15 +3636,19 @@ int buildin_deletearray(struct script_state *st)
sd = script_rid2sd ( st ) ;
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 ! = ' $ ' ) {
for ( ; i < ( 128 - ( num > > 24 ) ) ; i + + )
set_reg ( s d, num + ( i < < 24 ) , name , 0 ) ;
set_reg ( s t, s d, num + ( i < < 24 ) , name , 0 , st - > stack - > stack_data [ st - > start + 2 ] . ref ) ;
} else {
for ( ; i < ( 128 - ( num > > 24 ) ) ; i + + )
set_reg ( s d, num + ( i < < 24 ) , name , ( void * ) " " ) ;
set_reg ( s t, s d, num + ( i < < 24 ) , name , ( void * ) " " , st - > stack - > stack_data [ st - > start + 2 ] . ref ) ;
}
return 0 ;
}
@ -9112,7 +9273,7 @@ int buildin_getmapxy(struct script_state *st){
else
sd = NULL ;
set_reg ( s d, num , name , ( void * ) mapname ) ;
set_reg ( s t, s d, num , name , ( void * ) mapname , NULL ) ;
//Set MapX
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 ) ;
else
sd = NULL ;
set_reg ( s d, num , name , ( void * ) x ) ;
set_reg ( s t, s d, num , name , ( void * ) x , NULL ) ;
//Set MapY
@ -9136,7 +9297,7 @@ int buildin_getmapxy(struct script_state *st){
else
sd = NULL ;
set_reg ( s d, num , name , ( void * ) y ) ;
set_reg ( s t, s d, num , name , ( void * ) y , NULL ) ;
//Return Success value
push_val ( st - > stack , C_INT , 0 ) ;
@ -9726,7 +9887,7 @@ int buildin_distance(struct script_state *st){
// [zBuffer] List of dynamic var commands --->
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 ;
}
@ -9980,7 +10141,7 @@ int buildin_setitemscript(struct script_state *st)
if ( i_data & & script ! = NULL & & script [ 0 ] = = ' { ' ) {
if ( i_data - > script ! = NULL )
aFre e( i_data - > script ) ;
script_free_cod e( i_data - > script ) ;
i_data - > script = parse_script ( ( unsigned char * ) script , 0 ) ;
push_val ( st - > stack , C_INT , 1 ) ;
} else
@ -10542,6 +10703,107 @@ int buildin_mobattach(struct script_state *st){
}
// <--- [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
//
@ -10913,18 +11175,21 @@ int run_func(struct script_state *st)
int i ;
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 " ) ;
st - > state = END ;
report_src ( st ) ;
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 - > script = ( char * ) conv_num ( st , & ( st - > stack - > stack_data [ st - > stack - > defsp - 2 ] ) ) ; // スクリプトを復元
st - > stack - > defsp = conv_num ( st , & ( st - > stack - > stack_data [ st - > stack - > defsp - 3 ] ) ) ; // 基準スタックポインタを復元
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 - 4 - i , olddefsp ) ; // 要らなくなったスタック(引数と復帰用データ)削除
pop_stack ( st - > stack , olddefsp - 5 - i , olddefsp ) ; // 要らなくなったスタック(引数と復帰用データ)削除
st - > state = GOTO ;
}
@ -10942,6 +11207,7 @@ int run_script_main(struct script_state *st)
int cmdcount = script_config . check_cmdcount ;
int gotocount = script_config . check_gotocount ;
struct script_stack * stack = st - > stack ;
TBL_PC * sd = NULL ;
if ( st - > state = = RERUNLINE ) {
st - > state = RUN ;
@ -10953,7 +11219,7 @@ int run_script_main(struct script_state *st)
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 ) {
case C_EOL :
if ( stack - > sp ! = stack - > defsp ) {
@ -10970,19 +11236,19 @@ int run_script_main(struct script_state *st)
// rerun_pos=st->pos;
break ;
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 ;
case C_POS :
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 ;
break ;
case C_ARG :
push_val ( stack , c , 0 ) ;
break ;
case C_STR :
push_str ( stack , C_CONSTSTR , ( unsigned char * ) ( st - > script +st - > pos ) ) ;
while ( st - > script [ st - > pos + + ] ) ;
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 ) ;
@ -11041,31 +11307,40 @@ int run_script_main(struct script_state *st)
st - > state = END ;
}
}
switch ( st - > state ) {
case STOP :
break ;
case END :
{
struct map_session_data * sd = map_id2sd ( st - > rid ) ;
st - > pos = - 1 ;
if ( sd & & ( sd - > npc_id = = st - > oid | | sd - > state . using_fake_npc ) ) {
if ( sd - > state . using_fake_npc ) {
clif_clearchar_id ( sd - > npc_id , 0 , sd - > fd ) ;
sd - > state . using_fake_npc = 0 ;
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 ) {
case STOP :
break ;
case END :
{
struct map_session_data * sd = map_id2sd ( st - > rid ) ;
st - > pos = - 1 ;
if ( sd & & ( sd - > npc_id = = st - > oid | | sd - > state . using_fake_npc ) ) {
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 ) ;
}
npc_event_dequeue ( sd ) ;
}
break ;
case RERUNLINE :
// 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 ;
}
break ;
case RERUNLINE :
// 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 ;
}
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 * root script, int pos , int rid , int oid )
{
struct script_state st ;
struct map_session_data * sd ;
unsigned char * rootscript = script ;
struct map_session_data * sd = NULL ;
//Variables for backing up the previous script and restore it if needed. [Skotlex]
unsigned char * bck_script = NULL ;
unsigned char * bck_scriptroot = NULL ;
struct script_code * bck_script = NULL ;
struct script_code * bck_scriptroot = NULL ;
int bck_scriptstate = 0 ;
struct script_stack * bck_stack = NULL ;
if ( script = = NULL | | pos < 0 )
if ( root script = = NULL | | pos < 0 )
return - 1 ;
memset ( & st , 0 , sizeof ( struct script_state ) ) ;
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 - > 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 ;
@ -11122,6 +11398,7 @@ int run_script(unsigned char *script,int pos,int rid,int oid)
st . pos = pos ;
st . rid = rid ;
st . oid = oid ;
st . sleep . timer = - 1 ;
// let's run that stuff
run_script_main ( & st ) ;
@ -11155,6 +11432,57 @@ int run_script(unsigned char *script,int pos,int rid,int oid)
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 ) ;
scriptlabel_db - > destroy ( scriptlabel_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 )
aFree ( str_data ) ;