summaryrefslogtreecommitdiff
path: root/src/map/script.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/script.c')
-rw-r--r--src/map/script.c703
1 files changed, 359 insertions, 344 deletions
diff --git a/src/map/script.c b/src/map/script.c
index efce0b986..5dbe62df3 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -87,7 +87,6 @@ static inline void script_string_buf_addb(struct script_string_buf *buf,uint8 b)
buf->size += 512;
RECREATE(buf->ptr, char, buf->size);
}
-
buf->ptr[buf->pos++] = b;
}
@@ -267,7 +266,6 @@ void script_reportdata(struct script_data* data)
}
}
-
/// Reports on the console information about the current built-in function.
void script_reportfunc(struct script_state* st)
{
@@ -301,7 +299,6 @@ void script_reportfunc(struct script_state* st)
}
}
-
/*==========================================
* Output error message
*------------------------------------------*/
@@ -398,7 +395,6 @@ unsigned int calc_hash_ci(const char* p) {
return h % SCRIPT_HASH_SIZE;
}
-
/*==========================================
* script->str_data manipulation functions
*------------------------------------------*/
@@ -590,7 +586,6 @@ int script_add_str(const char* p)
return script->str_num++;
}
-
/// Appends 1 byte to the script buffer.
void add_scriptb(int a)
{
@@ -807,19 +802,19 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom)
else { //Nested function call
script->syntax.nested_call++;
nested_call = true;
-
+
if( script->str_data[func].val == script->buildin_lang_macro_offset ) {
script->syntax.lang_macro_active = true;
macro = true;
}
}
-
+
if( !macro ) {
// buildin function
script->addl(func);
script->addc(C_ARG);
}
-
+
arg = script->buildin[script->str_data[func].val];
if (script->str_data[func].deprecated)
DeprecationWarning(p);
@@ -903,17 +898,17 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom)
if( *p != ')' )
disp_error_message("parse_callfunc: expected ')' to close argument list",p);
++p;
-
+
if( script->str_data[func].val == script->buildin_lang_macro_offset )
script->syntax.lang_macro_active = false;
}
-
+
if( nested_call )
script->syntax.nested_call--;
-
+
if( !script->syntax.nested_call )
script->syntax.last_func = -1;
-
+
if( !macro )
script->addc(C_FUNC);
return p;
@@ -978,8 +973,8 @@ const char* parse_variable(const char* p)
const char *p2 = NULL;
const char *var = p;
- if( ( p[0] == '+' && p[1] == '+' && (type = C_ADD_PRE) ) // pre ++
- || ( p[0] == '-' && p[1] == '-' && (type = C_SUB_PRE) ) // pre --
+ if( ( p[0] == '+' && p[1] == '+' && (type = C_ADD_PRE, true) ) // pre ++
+ || ( p[0] == '-' && p[1] == '-' && (type = C_SUB_PRE, true) ) // pre --
) {
var = p = script->skip_space(&p[2]);
}
@@ -1008,19 +1003,19 @@ const char* parse_variable(const char* p)
}
if( type == C_NOP &&
- !( ( p[0] == '=' && p[1] != '=' && (type = C_EQ) ) // =
- || ( p[0] == '+' && p[1] == '=' && (type = C_ADD) ) // +=
- || ( p[0] == '-' && p[1] == '=' && (type = C_SUB) ) // -=
- || ( p[0] == '^' && p[1] == '=' && (type = C_XOR) ) // ^=
- || ( p[0] == '|' && p[1] == '=' && (type = C_OR ) ) // |=
- || ( p[0] == '&' && p[1] == '=' && (type = C_AND) ) // &=
- || ( p[0] == '*' && p[1] == '=' && (type = C_MUL) ) // *=
- || ( p[0] == '/' && p[1] == '=' && (type = C_DIV) ) // /=
- || ( p[0] == '%' && p[1] == '=' && (type = C_MOD) ) // %=
- || ( p[0] == '+' && p[1] == '+' && (type = C_ADD_POST) ) // post ++
- || ( p[0] == '-' && p[1] == '-' && (type = C_SUB_POST) ) // post --
- || ( p[0] == '<' && p[1] == '<' && p[2] == '=' && (type = C_L_SHIFT) ) // <<=
- || ( p[0] == '>' && p[1] == '>' && p[2] == '=' && (type = C_R_SHIFT) ) // >>=
+ !( ( p[0] == '=' && p[1] != '=' && (type = C_EQ, true) ) // =
+ || ( p[0] == '+' && p[1] == '=' && (type = C_ADD, true) ) // +=
+ || ( p[0] == '-' && p[1] == '=' && (type = C_SUB, true) ) // -=
+ || ( p[0] == '^' && p[1] == '=' && (type = C_XOR, true) ) // ^=
+ || ( p[0] == '|' && p[1] == '=' && (type = C_OR, true) ) // |=
+ || ( p[0] == '&' && p[1] == '=' && (type = C_AND, true) ) // &=
+ || ( p[0] == '*' && p[1] == '=' && (type = C_MUL, true) ) // *=
+ || ( p[0] == '/' && p[1] == '=' && (type = C_DIV, true) ) // /=
+ || ( p[0] == '%' && p[1] == '=' && (type = C_MOD, true) ) // %=
+ || ( p[0] == '+' && p[1] == '+' && (type = C_ADD_POST, true) ) // post ++
+ || ( p[0] == '-' && p[1] == '-' && (type = C_SUB_POST, true) ) // post --
+ || ( p[0] == '<' && p[1] == '<' && p[2] == '=' && (type = C_L_SHIFT, true) ) // <<=
+ || ( p[0] == '>' && p[1] == '>' && p[2] == '=' && (type = C_R_SHIFT, true) ) // >>=
) )
{// failed to find a matching operator combination so invalid
return NULL;
@@ -1149,15 +1144,15 @@ bool is_number(const char *p) {
int script_string_dup(char *str) {
size_t len = strlen(str);
int pos = script->string_list_pos;
-
+
while( pos+len+1 >= script->string_list_size ) {
script->string_list_size += (1024*1024)/2;
RECREATE(script->string_list,char,script->string_list_size);
}
-
+
safestrncpy(script->string_list+pos, str, len+1);
script->string_list_pos += len+1;
-
+
return pos;
}
@@ -1208,7 +1203,7 @@ const char* parse_simpleexpr(const char *p)
const char *start_point = p;
bool duplicate = true;
struct script_string_buf *sbuf = &script->parse_simpleexpr_str;
-
+
do {
p++;
while( *p && *p != '"' ) {
@@ -1231,19 +1226,19 @@ const char* parse_simpleexpr(const char *p)
p++; //'"'
p = script->skip_space(p);
} while( *p && *p == '"' );
-
+
script_string_buf_addb(sbuf, 0);
-
- if( !(script->syntax.translation_db && (st = strdb_get(script->syntax.translation_db, sbuf->ptr))) ) {
+
+ if (!(script->syntax.translation_db && (st = strdb_get(script->syntax.translation_db, sbuf->ptr)) != NULL)) {
script->addc(C_STR);
-
+
if( script->pos+sbuf->pos >= script->size ) {
do {
script->size += SCRIPT_BLOCK_SIZE;
} while( script->pos+sbuf->pos >= script->size );
RECREATE(script->buf,unsigned char,script->size);
}
-
+
memcpy(script->buf+script->pos, sbuf->ptr, sbuf->pos);
script->pos += sbuf->pos;
@@ -1253,19 +1248,19 @@ const char* parse_simpleexpr(const char *p)
unsigned int st_cursor = 0;
script->addc(C_LSTR);
-
+
expand += (sizeof(char*) + sizeof(uint8)) * st->translations;
-
+
while( script->pos+expand >= script->size ) {
script->size += SCRIPT_BLOCK_SIZE;
RECREATE(script->buf,unsigned char,script->size);
}
-
+
*((int *)(&script->buf[script->pos])) = st->string_id;
*((uint8 *)(&script->buf[script->pos + sizeof(int)])) = st->translations;
script->pos += sizeof(int) + sizeof(uint8);
-
+
for(j = 0; j < st->translations; j++) {
*((uint8 *)(&script->buf[script->pos])) = RBUFB(st->buf, st_cursor);
*((char **)(&script->buf[script->pos+sizeof(uint8)])) = &st->buf[st_cursor + sizeof(uint8)];
@@ -1275,19 +1270,19 @@ const char* parse_simpleexpr(const char *p)
st_cursor += sizeof(uint8);
}
}
-
+
/* When exporting we don't know what is a translation and what isn't */
if( script->lang_export_fp && sbuf->pos > 1 ) {//sbuf->pos will always be at least 1 because of the '\0'
if( !script->syntax.strings ) {
script->syntax.strings = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_ALLOW_NULL_DATA, 0);
}
-
+
if( !strdb_exists(script->syntax.strings,sbuf->ptr) ) {
strdb_put(script->syntax.strings, sbuf->ptr, NULL);
duplicate = false;
}
}
-
+
if( script->lang_export_fp && !duplicate &&
( ( ( script->syntax.last_func == script->buildin_mes_offset ||
script->syntax.last_func == script->buildin_select_offset ) && !script->syntax.nested_call
@@ -1304,44 +1299,41 @@ const char* parse_simpleexpr(const char *p)
else
break;
}
-
+
while( *line_end != '\n' && *line_end != '\0' )
line_end++;
-
+
line_length = (size_t)(line_end - line_start);
-
if( line_length > 0 ) {
script_string_buf_ensure(lbuf,line_length + 1);
-
+
memcpy(lbuf->ptr, line_start, line_length);
lbuf->pos = line_length;
script_string_buf_addb(lbuf, 0);
-
+
normalize_name(lbuf->ptr, "\r\n\t ");
}
-
+
for(cursor = 0; cursor < sbuf->pos; cursor++) {
if( sbuf->ptr[cursor] == '"' )
script_string_buf_addb(ubuf, '\\');
script_string_buf_addb(ubuf, sbuf->ptr[cursor]);
}
script_string_buf_addb(ubuf, 0);
-
+
fprintf(script->lang_export_fp, "#: %s\n"
- "# %s\n"
- "msgctxt \"%s\"\n"
- "msgid \"%s\"\n"
- "msgstr \"\"\n",
+ "# %s\n"
+ "msgctxt \"%s\"\n"
+ "msgid \"%s\"\n"
+ "msgstr \"\"\n",
script->parser_current_file ? script->parser_current_file : "Unknown File",
lbuf->ptr,
script->parser_current_npc_name ? script->parser_current_npc_name : "Unknown NPC",
ubuf->ptr
);
-
lbuf->pos = 0;
ubuf->pos = 0;
}
-
sbuf->pos = 0;
} else {
int l;
@@ -2423,10 +2415,10 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
if( script->parse_cleanup_timer_id == INVALID_TIMER ) {
script->parse_cleanup_timer_id = timer->add(timer->gettick() + 10, script->parse_cleanup_timer, 0, 0);
}
-
+
if( script->syntax.strings ) /* used only when generating translation file */
db_destroy(script->syntax.strings);
-
+
memset(&script->syntax,0,sizeof(script->syntax));
script->syntax.last_func = -1;/* as valid values are >= 0 */
if( script->parser_current_npc_name ) {
@@ -2636,6 +2628,38 @@ TBL_PC *script_rid2sd(struct script_state *st) {
return sd;
}
+char *get_val_npcscope_str(struct script_state* st, struct reg_db *n, struct script_data* data) {
+ if (n)
+ return (char*)i64db_get(n->vars, reference_getuid(data));
+ else
+ return NULL;
+}
+
+char *get_val_instance_str(struct script_state* st, const char* name, struct script_data* data) {
+ if (st->instance_id >= 0) {
+ return (char*)i64db_get(instance->list[st->instance_id].regs.vars, reference_getuid(data));
+ } else {
+ ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to \"\"\n", name);
+ return NULL;
+ }
+}
+
+int get_val_npcscope_num(struct script_state* st, struct reg_db *n, struct script_data* data) {
+ if (n)
+ return (int)i64db_iget(n->vars, reference_getuid(data));
+ else
+ return 0;
+}
+
+int get_val_instance_num(struct script_state* st, const char* name, struct script_data* data) {
+ if (st->instance_id >= 0)
+ return (int)i64db_iget(instance->list[st->instance_id].regs.vars, reference_getuid(data));
+ else {
+ ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to 0\n", name);
+ return 0;
+ }
+}
+
/**
* Dereferences a variable/constant, replacing it with a copy of the value.
*
@@ -2689,24 +2713,15 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
data->u.str = pc_readaccountregstr(sd, data->u.num);// local
break;
case '.':
- {
- struct DBMap* n = data->ref ?
- data->ref->vars : name[1] == '@' ?
- st->stack->scope.vars : // instance/scope variable
- st->script->local.vars; // npc variable
- if( n )
- data->u.str = (char*)i64db_get(n,reference_getuid(data));
- else
- data->u.str = NULL;
- }
+ if (data->ref)
+ data->u.str = script->get_val_ref_str(st, data->ref, data);
+ else if (name[1] == '@')
+ data->u.str = script->get_val_scope_str(st, &st->stack->scope, data);
+ else
+ data->u.str = script->get_val_npc_str(st, &st->script->local, data);
break;
case '\'':
- if ( st->instance_id >= 0 ) {
- data->u.str = (char*)i64db_get(instance->list[st->instance_id].regs.vars, reference_getuid(data));
- } else {
- ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to \"\"\n", name);
- data->u.str = NULL;
- }
+ data->u.str = script->get_val_instance_str(st, name, data);
break;
default:
data->u.str = pc_readglobalreg_str(sd, data->u.num);
@@ -2744,24 +2759,15 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
data->u.num = pc_readaccountreg(sd, data->u.num);// local
break;
case '.':
- {
- struct DBMap* n = data->ref ?
- data->ref->vars : name[1] == '@' ?
- st->stack->scope.vars : // instance/scope variable
- st->script->local.vars; // npc variable
- if( n )
- data->u.num = (int)i64db_iget(n,reference_getuid(data));
- else
- data->u.num = 0;
- }
+ if (data->ref)
+ data->u.num = script->get_val_ref_num(st, data->ref, data);
+ else if (name[1] == '@')
+ data->u.num = script->get_val_scope_num(st, &st->stack->scope, data);
+ else
+ data->u.num = script->get_val_npc_num(st, &st->script->local, data);
break;
case '\'':
- if( st->instance_id >= 0 )
- data->u.num = (int)i64db_iget(instance->list[st->instance_id].regs.vars, reference_getuid(data));
- else {
- ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to 0\n", name);
- data->u.num = 0;
- }
+ data->u.num = script->get_val_instance_num(st, name, data);
break;
default:
data->u.num = pc_readglobalreg(sd, data->u.num);
@@ -2822,14 +2828,13 @@ void script_array_ensure_zero(struct script_state *st, struct map_session_data *
struct script_array *sa = idb_get(src->arrays, script_getvarid(uid));
if (sa) {
unsigned int i;
-
+
ARR_FIND(0, sa->size, i, sa->members[i] == 0);
if( i != sa->size ) {
if( !insert )
script->array_remove_member(src,sa,i);
return;
}
-
script->array_add_member(sa,0);
} else if (insert) {
script->array_update(src,reference_uid(script_getvarid(uid), 0),false);
@@ -2842,10 +2847,10 @@ void script_array_ensure_zero(struct script_state *st, struct map_session_data *
unsigned int script_array_size(struct script_state *st, struct map_session_data *sd, const char *name, struct reg_db *ref) {
struct script_array *sa = NULL;
struct reg_db *src = script->array_src(st, sd, name, ref);
-
+
if( src && src->arrays )
sa = idb_get(src->arrays, script->search_str(name));
-
+
return sa ? sa->size : 0;
}
/**
@@ -2854,25 +2859,22 @@ unsigned int script_array_size(struct script_state *st, struct map_session_data
unsigned int script_array_highest_key(struct script_state *st, struct map_session_data *sd, const char *name, struct reg_db *ref) {
struct script_array *sa = NULL;
struct reg_db *src = script->array_src(st, sd, name, ref);
-
-
+
if( src && src->arrays ) {
int key = script->add_word(name);
-
+
script->array_ensure_zero(st,sd,reference_uid(key, 0),ref);
-
+
if( ( sa = idb_get(src->arrays, key) ) ) {
unsigned int i, highest_key = 0;
-
+
for(i = 0; i < sa->size; i++) {
if( sa->members[i] > highest_key )
highest_key = sa->members[i];
}
-
return sa->size ? highest_key + 1 : 0;
}
}
-
return 0;
}
int script_free_array_db(DBKey key, DBData *data, va_list ap) {
@@ -2896,15 +2898,15 @@ void script_array_delete(struct reg_db *src, struct script_array *sa) {
**/
void script_array_remove_member(struct reg_db *src, struct script_array *sa, unsigned int idx) {
unsigned int i, cursor;
-
+
/* its the only member left, no need to do anything other than delete the array data */
if( sa->size == 1 ) {
script->array_delete(src,sa);
return;
}
-
+
sa->members[idx] = UINT_MAX;
-
+
for(i = 0, cursor = 0; i < sa->size; i++) {
if( sa->members[i] == UINT_MAX )
continue;
@@ -2912,7 +2914,7 @@ void script_array_remove_member(struct reg_db *src, struct script_array *sa, uns
sa->members[cursor] = sa->members[i];
cursor++;
}
-
+
sa->size = cursor;
}
/**
@@ -2921,11 +2923,9 @@ void script_array_remove_member(struct reg_db *src, struct script_array *sa, uns
* @param idx the index of the array member being inserted
**/
void script_array_add_member(struct script_array *sa, unsigned int idx) {
-
RECREATE(sa->members, unsigned int, ++sa->size);
-
- sa->members[sa->size - 1] = idx;
+ sa->members[sa->size - 1] = idx;
}
/**
* Obtains the source of the array database for this type and scenario
@@ -2933,7 +2933,7 @@ void script_array_add_member(struct script_array *sa, unsigned int idx) {
**/
struct reg_db *script_array_src(struct script_state *st, struct map_session_data *sd, const char *name, struct reg_db *ref) {
struct reg_db *src = NULL;
-
+
switch( name[0] ) {
/* from player */
default: /* char reg */
@@ -2956,13 +2956,12 @@ struct reg_db *script_array_src(struct script_state *st, struct map_session_data
}
break;
}
-
+
if( src ) {
if( !src->arrays )
src->arrays = idb_alloc(DB_OPT_BASE);
return src;
}
-
return NULL;
}
@@ -2977,7 +2976,7 @@ void script_array_update(struct reg_db *src, int64 num, bool empty) {
struct script_array *sa = NULL;
int id = script_getvarid(num);
unsigned int index = script_getvaridx(num);
-
+
if (!src->arrays) {
src->arrays = idb_alloc(DB_OPT_BASE);
} else {
@@ -2986,13 +2985,13 @@ void script_array_update(struct reg_db *src, int64 num, bool empty) {
if( sa ) {
unsigned int i;
-
+
/* search */
for(i = 0; i < sa->size; i++) {
if( sa->members[i] == index )
break;
}
-
+
/* if existent */
if( i != sa->size ) {
/* if empty, we gotta remove it */
@@ -3013,6 +3012,73 @@ void script_array_update(struct reg_db *src, int64 num, bool empty) {
}
}
+void set_reg_npcscope_str(struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str)
+{
+ if (n)
+ {
+ if (str[0]) {
+ i64db_put(n->vars, num, aStrdup(str));
+ if (script_getvaridx(num))
+ script->array_update(n, num, false);
+ } else {
+ i64db_remove(n->vars, num);
+ if (script_getvaridx(num))
+ script->array_update(n, num, true);
+ }
+ }
+}
+
+void set_reg_npcscope_num(struct script_state* st, struct reg_db *n, int64 num, const char* name, int val)
+{
+ if (n) {
+ if (val != 0) {
+ i64db_iput(n->vars, num, val);
+ if (script_getvaridx(num))
+ script->array_update(n, num, false);
+ } else {
+ i64db_remove(n->vars, num);
+ if (script_getvaridx(num))
+ script->array_update(n, num, true);
+ }
+ }
+}
+
+void set_reg_instance_str(struct script_state* st, int64 num, const char* name, const char *str)
+{
+ if (st->instance_id >= 0) {
+ if (str[0]) {
+ i64db_put(instance->list[st->instance_id].regs.vars, num, aStrdup(str));
+ if (script_getvaridx(num))
+ script->array_update(&instance->list[st->instance_id].regs, num, false);
+ } else {
+ i64db_remove(instance->list[st->instance_id].regs.vars, num);
+ if (script_getvaridx(num))
+ script->array_update(&instance->list[st->instance_id].regs, num, true);
+ }
+ } else {
+ ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name);
+ script->reportsrc(st);
+ }
+}
+
+void set_reg_instance_num(struct script_state* st, int64 num, const char* name, int val)
+{
+ if (st->instance_id >= 0) {
+ if (val != 0) {
+ i64db_iput(instance->list[st->instance_id].regs.vars, num, val);
+ if (script_getvaridx(num))
+ script->array_update(&instance->list[st->instance_id].regs, num, false);
+ } else {
+ i64db_remove(instance->list[st->instance_id].regs.vars, num);
+ if (script_getvaridx(num))
+ script->array_update(&instance->list[st->instance_id].regs, num, true);
+ }
+ } else {
+ ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name);
+ script->reportsrc(st);
+ }
+}
+
/**
* Stores the value of a script variable
*
@@ -3029,7 +3095,7 @@ void script_array_update(struct reg_db *src, int64 num, bool empty) {
*------------------------------------------*/
int set_reg(struct script_state* st, TBL_PC* sd, int64 num, const char* name, const void* value, struct reg_db *ref) {
char prefix = name[0];
-
+
if( is_string_variable(name) ) {// string variable
const char *str = (const char*)value;
@@ -3044,36 +3110,15 @@ int set_reg(struct script_state* st, TBL_PC* sd, int64 num, const char* name, co
pc_setaccountreg2str(sd, num, str) :
pc_setaccountregstr(sd, num, str);
case '.':
- {
- struct reg_db *n = (ref) ? ref : (name[1] == '@') ? &st->stack->scope : &st->script->local;
- if( n ) {
- if (str[0]) {
- i64db_put(n->vars, num, aStrdup(str));
- if( script_getvaridx(num) )
- script->array_update(n, num, false);
- } else {
- i64db_remove(n->vars, num);
- if( script_getvaridx(num) )
- script->array_update(n, num, true);
- }
- }
- }
+ if (ref)
+ script->set_reg_ref_str(st, ref, num, name, str);
+ else if (name[1] == '@')
+ script->set_reg_scope_str(st, &st->stack->scope, num, name, str);
+ else
+ script->set_reg_npc_str(st, &st->script->local, num, name, str);
return 1;
case '\'':
- if( st->instance_id >= 0 ) {
- if( str[0] ) {
- i64db_put(instance->list[st->instance_id].regs.vars, num, aStrdup(str));
- if( script_getvaridx(num) )
- script->array_update(&instance->list[st->instance_id].regs, num, false);
- } else {
- i64db_remove(instance->list[st->instance_id].regs.vars, num);
- if( script_getvaridx(num) )
- script->array_update(&instance->list[st->instance_id].regs, num, true);
- }
- } else {
- ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name);
- script->reportsrc(st);
- }
+ set_reg_instance_str(st, num, name, str);
return 1;
default:
return pc_setglobalreg_str(sd, num, str);
@@ -3110,36 +3155,15 @@ int set_reg(struct script_state* st, TBL_PC* sd, int64 num, const char* name, co
pc_setaccountreg2(sd, num, val) :
pc_setaccountreg(sd, num, val);
case '.':
- {
- struct reg_db *n = (ref) ? ref : (name[1] == '@') ? &st->stack->scope : &st->script->local;
- if( n ) {
- if( val != 0 ) {
- i64db_iput(n->vars, num, val);
- if( script_getvaridx(num) )
- script->array_update(n, num, false);
- } else {
- i64db_remove(n->vars, num);
- if( script_getvaridx(num) )
- script->array_update(n, num, true);
- }
- }
- }
+ if (ref)
+ script->set_reg_ref_num(st, ref, num, name, val);
+ else if (name[1] == '@')
+ script->set_reg_scope_num(st, &st->stack->scope, num, name, val);
+ else
+ script->set_reg_npc_num(st, &st->script->local, num, name, val);
return 1;
case '\'':
- if( st->instance_id >= 0 ) {
- if( val != 0 ) {
- i64db_iput(instance->list[st->instance_id].regs.vars, num, val);
- if( script_getvaridx(num) )
- script->array_update(&instance->list[st->instance_id].regs, num, false);
- } else {
- i64db_remove(instance->list[st->instance_id].regs.vars, num);
- if( script_getvaridx(num) )
- script->array_update(&instance->list[st->instance_id].regs, num, true);
- }
- } else {
- ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name);
- script->reportsrc(st);
- }
+ set_reg_instance_num(st, num, name, val);
return 1;
default:
return pc_setglobalreg(sd, num, val);
@@ -3432,7 +3456,7 @@ struct script_state* script_alloc_state(struct script_code* rootscript, int pos,
st->oid = oid;
st->sleep.timer = INVALID_TIMER;
st->npc_item_flag = battle_config.item_enabled_npc;
-
+
if( st->script->instances != USHRT_MAX )
st->script->instances++;
else {
@@ -3457,11 +3481,11 @@ struct script_state* script_alloc_state(struct script_code* rootscript, int pos,
void script_free_state(struct script_state* st) {
if( idb_exists(script->st_db,st->id) ) {
struct map_session_data *sd = st->rid ? map->id2sd(st->rid) : NULL;
-
+
if(st->bk_st) {// backup was not restored
ShowDebug("script_free_state: Previous script state lost (rid=%d, oid=%d, state=%d, bk_npcid=%d).\n", st->bk_st->rid, st->bk_st->oid, st->bk_st->state, st->bk_npcid);
}
-
+
if(sd && sd->st == st) { //Current script is aborted.
if(sd->state.using_fake_npc){
clif->clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
@@ -3864,7 +3888,6 @@ void op_1(struct script_state* st, int op)
script_pushint(st, i1);
}
-
/// Checks the type of all arguments passed to a built-in function.
///
/// @param st Script state whose stack arguments should be inspected.
@@ -3945,7 +3968,6 @@ void script_check_buildin_argtype(struct script_state* st, int func)
}
}
-
/// Executes a buildin command.
/// Stack: C_NAME(<command>) C_ARG <arg0> <arg1> ... <argN>
int run_func(struct script_state *st)
@@ -4207,15 +4229,15 @@ void run_script_main(struct script_state *st) {
int string_id = *((int *)(&st->script->script_buf[st->pos]));
uint8 translations = *((uint8 *)(&st->script->script_buf[st->pos+sizeof(int)]));
struct map_session_data *lsd = NULL;
-
+
st->pos += sizeof(int) + sizeof(uint8);
-
+
if( (!st->rid || !(lsd = map->id2sd(st->rid)) || !lsd->lang_id) && !map->default_lang_id )
script->push_str(stack,C_CONSTSTR,script->string_list+string_id);
else {
uint8 k, wlang_id = lsd ? lsd->lang_id : map->default_lang_id;
int offset = st->pos;
-
+
for(k = 0; k < translations; k++) {
uint8 lang_id = *(uint8 *)(&st->script->script_buf[offset]);
offset += sizeof(uint8);
@@ -4223,12 +4245,9 @@ void run_script_main(struct script_state *st) {
break;
offset += sizeof(char*);
}
-
script->push_str(stack,C_CONSTSTR,
- ( k == translations ) ? script->string_list+string_id : *(char**)(&st->script->script_buf[offset]) );
-
+ ( k == translations ) ? script->string_list+string_id : *(char**)(&st->script->script_buf[offset]) );
}
-
st->pos += ( ( sizeof(char*) + sizeof(uint8) ) * translations );
}
break;
@@ -4342,7 +4361,6 @@ int script_config_read(char *cfgName) {
char line[1024],w1[1024],w2[1024];
FILE *fp;
-
if( !( fp = fopen(cfgName,"r") ) ) {
ShowError("File not found: %s\n", cfgName);
return 1;
@@ -4417,7 +4435,6 @@ void script_add_autobonus(const char *autobonus)
}
}
-
/// resets a temporary character array variable to given value
void script_cleararray_pc(struct map_session_data* sd, const char* varname, void* value) {
struct script_array *sa = NULL;
@@ -4426,39 +4443,38 @@ void script_cleararray_pc(struct map_session_data* sd, const char* varname, void
int key;
key = script->add_str(varname);
-
+
if( !(src = script->array_src(NULL,sd,varname,NULL) ) )
return;
-
+
if( value )
script->array_ensure_zero(NULL,sd,reference_uid(key,0),NULL);
-
+
if( !(sa = idb_get(src->arrays, key)) ) /* non-existent array, nothing to empty */
return;
-
+
size = sa->size;
list = script->array_cpy_list(sa);
-
+
for(i = 0; i < size; i++) {
script->set_reg(NULL,sd,reference_uid(key, list[i]),varname,value,NULL);
}
}
-
/// sets a temporary character array variable element idx to given value
/// @param refcache Pointer to an int variable, which keeps a copy of the reference to varname and must be initialized to 0. Can be NULL if only one element is set.
void script_setarray_pc(struct map_session_data* sd, const char* varname, uint32 idx, void* value, int* refcache) {
int key;
-
+
if( idx >= SCRIPT_MAX_ARRAYSIZE ) {
ShowError("script_setarray_pc: Variable '%s' has invalid index '%u' (char_id=%d).\n", varname, idx, sd->status.char_id);
return;
}
key = ( refcache && refcache[0] ) ? refcache[0] : script->add_str(varname);
-
+
script->set_reg(NULL,sd,reference_uid(key, idx),varname,value,NULL);
-
+
if( refcache )
{// save to avoid repeated script->add_str calls
refcache[0] = key;
@@ -4469,23 +4485,22 @@ void script_setarray_pc(struct map_session_data* sd, const char* varname, uint32
**/
int script_reg_destroy(DBKey key, DBData *data, va_list ap) {
struct script_reg_state *src;
-
+
if( data->type != DB_DATA_PTR )/* got no need for those! */
return 0;
-
+
src = DB->data2ptr(data);
-
+
if( src->type ) {
struct script_reg_str *p = (struct script_reg_str *)src;
-
+
if( p->value )
aFree(p->value);
-
+
ers_free(pc->str_reg_ers,p);
} else {
ers_free(pc->num_reg_ers,(struct script_reg_num*)src);
}
-
return 0;
}
/**
@@ -4496,10 +4511,10 @@ void script_reg_destroy_single(struct map_session_data *sd, int64 reg, struct sc
if( data->type ) {
struct script_reg_str *p = (struct script_reg_str*)data;
-
+
if( p->value )
aFree(p->value);
-
+
ers_free(pc->str_reg_ers,p);
} else {
ers_free(pc->num_reg_ers,(struct script_reg_num*)data);
@@ -4643,16 +4658,15 @@ void do_final_script(void) {
if( script->labels != NULL )
aFree(script->labels);
-
+
ers_destroy(script->array_ers);
-
+
if( script->generic_ui_array )
aFree(script->generic_ui_array);
-
+
script->clear_translations(false);
-
script->parser_clean_leftovers();
-
+
if( script->lang_export_file )
aFree(script->lang_export_file);
}
@@ -4662,11 +4676,10 @@ void do_final_script(void) {
**/
uint8 script_add_language(const char *name) {
uint8 lang_id = script->max_lang_id;
-
+
RECREATE(script->languages, char *, ++script->max_lang_id);
-
script->languages[lang_id] = aStrdup(name);
-
+
return lang_id;
}
/**
@@ -4682,9 +4695,9 @@ void script_load_translations(void) {
if (map->minimal) // No translations in minimal mode
return;
-
+
script->translation_db = strdb_alloc(DB_OPT_DUP_KEY, NAME_LENGTH*2+1);
-
+
if( script->languages ) {
for(i = 0; i < script->max_lang_id; i++)
aFree(script->languages[i]);
@@ -4692,33 +4705,33 @@ void script_load_translations(void) {
}
script->languages = NULL;
script->max_lang_id = 0;
-
+
script->add_language("English");/* 0 is default, which is whatever is in the npc files hardcoded (in our case, English) */
-
+
if (libconfig->read_file(&translations_conf, config_filename)) {
ShowError("load_translations: can't read '%s'\n", config_filename);
return;
}
-
+
if( !(translations = libconfig->lookup(&translations_conf, "translations")) ) {
ShowError("load_translations: invalid format on '%s'\n",config_filename);
return;
}
-
+
if( script->string_list )
aFree(script->string_list);
-
+
script->string_list = NULL;
script->string_list_pos = 0;
script->string_list_size = 0;
-
+
size = libconfig->setting_length(translations);
-
+
for(i = 0; i < size; i++) {
const char *translation_file = libconfig->setting_get_string_elem(translations, i);
-
script->load_translation(translation_file, ++lang_id, &total);
}
+ libconfig->destroy(&translations_conf);
if( total ) {
DBIterator *main_iter;
@@ -4726,32 +4739,27 @@ void script_load_translations(void) {
DBMap *string_db;
struct string_translation *st = NULL;
uint32 j = 0;
-
-
+
CREATE(script->translation_buf, char *, total);
script->translation_buf_size = total;
-
+
main_iter = db_iterator(script->translation_db);
-
for( string_db = dbi_first(main_iter); dbi_exists(main_iter); string_db = dbi_next(main_iter) ) {
sub_iter = db_iterator(string_db);
-
for( st = dbi_first(sub_iter); dbi_exists(sub_iter); st = dbi_next(sub_iter) ) {
script->translation_buf[j++] = st->buf;
}
-
dbi_destroy(sub_iter);
}
-
dbi_destroy(main_iter);
}
-
+
for(k = 0; k < script->max_lang_id; k++) {
if( !strcmpi(script->languages[k],map->default_lang_str) ) {
break;
}
}
-
+
if( k == script->max_lang_id ) {
ShowError("load_translations: map server default_language setting '%s' is not a loaded language\n",map->default_lang_str);
map->default_lang_id = 0;
@@ -4766,21 +4774,21 @@ void script_load_translations(void) {
const char * script_get_translation_file_name(const char *file) {
static char file_name[200];
int i, len = (int)strlen(file), last_bar = -1, last_dot = -1;
-
+
for(i = 0; i < len; i++) {
if( file[i] == '/' || file[i] == '\\' )
last_bar = i;
else if ( file[i] == '.' )
last_dot = i;
}
-
+
if( last_bar != -1 || last_dot != -1 ) {
if( last_bar != -1 && last_dot < last_bar )
last_dot = -1;
safestrncpy(file_name, file+(last_bar >= 0 ? last_bar+1 : 0), ( last_dot >= 0 ? ( last_bar >= 0 ? last_dot - last_bar : last_dot ) : sizeof(file_name) ));
return file_name;
}
-
+
return file;
}
@@ -4795,25 +4803,25 @@ void script_load_translation(const char *file, uint8 lang_id, uint32 *total) {
size_t i;
FILE *fp;
struct script_string_buf msgid = { 0 }, msgstr = { 0 };
-
+
if( !(fp = fopen(file,"rb")) ) {
ShowError("load_translation: failed to open '%s' for reading\n",file);
return;
}
-
+
script->add_language(script->get_translation_file_name(file));
if( lang_id >= atcommand->max_message_table )
atcommand->expand_message_table();
-
+
while(fgets(line, sizeof(line), fp)) {
size_t len = strlen(line), cursor = 0;
-
+
if( len <= 1 )
continue;
-
+
if( line[0] == '#' )
continue;
-
+
if( strncasecmp(line,"msgctxt \"", 9) == 0 ) {
msgctxt[0] = '\0';
for(i = 9; i < len - 2; i++) {
@@ -4847,14 +4855,14 @@ void script_load_translation(const char *file, uint8 lang_id, uint32 *total) {
}
script_string_buf_addb(&msgstr,0);
}
-
+
if( msgctxt[0] && msgid.pos > 1 && msgstr.pos > 1 ) {
size_t msgstr_len = msgstr.pos;
unsigned int inner_len = 1 + (uint32)msgstr_len + 1; //uint8 lang_id + msgstr_len + '\0'
-
+
if( strcasecmp(msgctxt, "messages.conf") == 0 ) {
int k;
-
+
for(k = 0; k < MAX_MSG; k++) {
if( atcommand->msg_table[0][k] && strcmpi(atcommand->msg_table[0][k],msgid.ptr) == 0 ) {
if( atcommand->msg_table[lang_id][k] )
@@ -4863,29 +4871,24 @@ void script_load_translation(const char *file, uint8 lang_id, uint32 *total) {
break;
}
}
-
} else {
struct string_translation *st = NULL;
if( !( string_db = strdb_get(script->translation_db, msgctxt) ) ) {
string_db = strdb_alloc(DB_OPT_DUP_KEY, 0);
-
strdb_put(script->translation_db, msgctxt, string_db);
}
-
+
if( !(st = strdb_get(string_db, msgid.ptr) ) ) {
CREATE(st, struct string_translation, 1);
-
st->string_id = script->string_dup(msgid.ptr);
-
strdb_put(string_db, msgid.ptr, st);
}
-
RECREATE(st->buf, char, st->len + inner_len);
-
+
WBUFB(st->buf, st->len) = lang_id;
safestrncpy((char*)WBUFP(st->buf, st->len + 1), msgstr.ptr, msgstr_len + 1);
-
+
st->translations++;
st->len += inner_len;
}
@@ -4894,11 +4897,11 @@ void script_load_translation(const char *file, uint8 lang_id, uint32 *total) {
translations++;
}
}
-
+
*total += translations;
-
+
fclose(fp);
-
+
script_string_buf_destroy(&msgid);
script_string_buf_destroy(&msgstr);
@@ -4913,21 +4916,21 @@ void script_clear_translations(bool reload) {
if( script->string_list )
aFree(script->string_list);
-
+
script->string_list = NULL;
script->string_list_pos = 0;
script->string_list_size = 0;
-
+
if( script->translation_buf ) {
for(i = 0; i < script->translation_buf_size; i++) {
aFree(script->translation_buf[i]);
}
aFree(script->translation_buf);
}
-
+
script->translation_buf = NULL;
script->translation_buf_size = 0;
-
+
if( script->languages ) {
for(i = 0; i < script->max_lang_id; i++)
aFree(script->languages[i]);
@@ -4935,11 +4938,11 @@ void script_clear_translations(bool reload) {
}
script->languages = NULL;
script->max_lang_id = 0;
-
+
if( script->translation_db ) {
script->translation_db->clear(script->translation_db,script->translation_db_destroyer);
}
-
+
if( reload )
script->load_translations();
}
@@ -4949,18 +4952,17 @@ void script_clear_translations(bool reload) {
**/
int script_translation_db_destroyer(DBKey key, DBData *data, va_list ap) {
DBMap *string_db = DB->data2ptr(data);
-
+
if( db_size(string_db) ) {
- DBIterator *iter = db_iterator(string_db);
struct string_translation *st = NULL;
-
+ DBIterator *iter = db_iterator(string_db);
+
for( st = dbi_first(iter); dbi_exists(iter); st = dbi_next(iter) ) {
aFree(st);
}
-
dbi_destroy(iter);
}
-
+
db_destroy(string_db);
return 0;
}
@@ -4969,10 +4971,9 @@ int script_translation_db_destroyer(DBKey key, DBData *data, va_list ap) {
*
**/
void script_parser_clean_leftovers(void) {
-
if( script->buf )
aFree(script->buf);
-
+
script->buf = NULL;
script->size = 0;
@@ -4980,7 +4981,7 @@ void script_parser_clean_leftovers(void) {
script->translation_db->destroy(script->translation_db,script->translation_db_destroyer);
script->translation_db = NULL;
}
-
+
if( script->syntax.strings ) { /* used only when generating translation file */
db_destroy(script->syntax.strings);
script->syntax.strings = NULL;
@@ -4995,21 +4996,19 @@ void script_parser_clean_leftovers(void) {
* Performs cleanup after all parsing is processed
**/
int script_parse_cleanup_timer(int tid, int64 tick, int id, intptr_t data) {
-
script->parser_clean_leftovers();
script->parse_cleanup_timer_id = INVALID_TIMER;
-
+
return 0;
}
-
/*==========================================
* Initialization
*------------------------------------------*/
void do_init_script(bool minimal) {
script->parse_cleanup_timer_id = INVALID_TIMER;
-
+
script->st_db = idb_alloc(DB_OPT_BASE);
script->userfunc_db = strdb_alloc(DB_OPT_DUP_KEY,0);
script->autobonus_db = strdb_alloc(DB_OPT_DUP_KEY,0);
@@ -5029,7 +5028,6 @@ void do_init_script(bool minimal) {
return;
mapreg->init();
-
script->load_translations();
}
@@ -5063,9 +5061,9 @@ int script_reload(void) {
atcommand->binding_count = 0;
db_clear(script->st_db);
-
+
script->clear_translations(true);
-
+
if( script->parse_cleanup_timer_id != INVALID_TIMER ) {
timer->delete(script->parse_cleanup_timer_id,script->parse_cleanup_timer);
script->parse_cleanup_timer_id = INVALID_TIMER;
@@ -5823,7 +5821,7 @@ int buildin_areawarp_sub(struct block_list *bl,va_list ap)
tx = rnd()%(x3-x2+1)+x2;
ty = rnd()%(y3-y2+1)+y2;
j++;
- } while( map->getcell(index,tx,ty,CELL_CHKNOPASS) && j < max );
+ } while (map->getcell(index, bl, tx, ty, CELL_CHKNOPASS) && j < max);
pc->setpos((TBL_PC *)bl,index,tx,ty,CLR_OUTSIGHT);
}
@@ -6290,7 +6288,7 @@ BUILDIN(__setr) {
if (!not_array_variable(*namevalue)) {
// array variable being copied into another array variable
- if (sd == NULL && not_server_variable(*namevalue) && !(sd = script->rid2sd(st))) {
+ if (sd == NULL && not_server_variable(*namevalue) && (sd = script->rid2sd(st)) == NULL) {
// player must be attached in order to copy a player variable
ShowError("script:set: no player attached for player variable '%s'\n", namevalue);
return true;
@@ -6584,15 +6582,15 @@ BUILDIN(deletearray)
st->state = END;
return false;// not a variable
}
-
+
script->array_ensure_zero(st,NULL,data->u.num,reference_getref(data));
-
+
if ( !(sa = idb_get(src->arrays, id)) ) { /* non-existent array, nothing to empty */
return true;// not a variable
}
end = script->array_highest_key(st,sd,name,reference_getref(data));
-
+
if( start >= end )
return true;// nothing to free
@@ -6600,7 +6598,7 @@ BUILDIN(deletearray)
value = (void *)"";
else
value = (void *)0;
-
+
if( script_hasdata(st,3) ) {
unsigned int count = script_getnum(st, 3);
if( count > end - start )
@@ -6626,14 +6624,14 @@ BUILDIN(deletearray)
list = script->array_cpy_list(sa);
size = sa->size;
qsort(list, size, sizeof(unsigned int), script_array_index_cmp);
-
+
ARR_FIND(0, size, i, list[i] >= start);
-
+
for( ; i < size && list[i] < start + count; i++ ) {
// Clear any entries between start and start+count, if they exist
script->set_reg(st, sd, reference_uid(id, list[i]), name, value, reference_getref(data));
}
-
+
for( ; i < size && list[i] < end; i++ ) {
// Move back count positions any entries between start+count to fill the gaps
void* v = script->get_val2(st, reference_uid(id, list[i]), reference_getref(data));
@@ -6647,7 +6645,7 @@ BUILDIN(deletearray)
unsigned int *list = NULL, size = 0;
list = script->array_cpy_list(sa);
size = sa->size;
-
+
for(i = 0; i < size; i++) {
if( list[i] >= start ) // Less expensive than sorting it, most likely
script->set_reg(st, sd, reference_uid(id, list[i]), name, value, reference_getref(data));
@@ -7126,7 +7124,7 @@ BUILDIN(getitem) {
if ((flag = pc->additem(sd, &it, get_count, LOG_TYPE_SCRIPT))) {
clif->additem(sd, 0, 0, flag);
if( pc->candrop(sd,&it) )
- map->addflooritem(&it,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ map->addflooritem(&sd->bl, &it, get_count, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
}
}
}
@@ -7234,7 +7232,7 @@ BUILDIN(getitem2)
if ((flag = pc->additem(sd, &item_tmp, get_count, LOG_TYPE_SCRIPT))) {
clif->additem(sd, 0, 0, flag);
if( pc->candrop(sd,&item_tmp) )
- map->addflooritem(&item_tmp,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ map->addflooritem(&sd->bl, &item_tmp, get_count, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
}
}
}
@@ -7423,17 +7421,15 @@ BUILDIN(makeitem)
return false;
}
-
memset(&item_tmp,0,sizeof(item_tmp));
item_tmp.nameid = nameid;
item_tmp.identify=1;
-
- map->addflooritem(&item_tmp,amount,m,x,y,0,0,0,0);
+
+ map->addflooritem(NULL, &item_tmp, amount, m, x, y, 0, 0, 0, 0);
return true;
}
-
/// Counts / deletes the current item given by idx.
/// Used by buildin_delitem_search
/// Relies on all input data being already fully valid.
@@ -7456,7 +7452,6 @@ void buildin_delitem_delete(struct map_session_data* sd, int idx, int* amount, b
amount[0]-= delamount;
}
-
/// Searches for item(s) and checks, if there is enough of them.
/// Used by delitem and delitem2
/// Relies on all input data being already fully valid.
@@ -7564,7 +7559,6 @@ bool buildin_delitem_search(struct map_session_data* sd, struct item* it, bool e
}
}
-
/// Deletes items from the target/attached player.
/// Prioritizes ordinary items.
///
@@ -8484,7 +8478,7 @@ BUILDIN(successrefitem)
if (script_hasdata(st, 3))
up = script_getnum(st, 3);
-
+
if (num > 0 && num <= ARRAYLENGTH(script->equip))
i=pc->checkequip(sd,script->equip[num-1]);
if (i >= 0) {
@@ -8619,7 +8613,7 @@ BUILDIN(delequip)
pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT);
return true;
}
-
+
ShowError("script:delequip: no item found in position '%d' for player '%s' (AID:%d/CID:%d).\n", num, sd->status.name,sd->status.account_id, sd->status.char_id);
st->state = END;
clif->scriptclose(sd, st->oid);
@@ -9039,7 +9033,7 @@ BUILDIN(getgroupid)
/// end
BUILDIN(end) {
st->state = END;
-
+
/* are we stopping inside a function? */
if( st->stack->defsp >= 1 && st->stack->stack_data[st->stack->defsp-1].type == C_RETINFO ) {
int i;
@@ -11095,7 +11089,6 @@ BUILDIN(homunculus_checkcall) {
return true;
}
-
// [Zephyrus]
BUILDIN(homunculus_shuffle) {
TBL_PC *sd;
@@ -11135,7 +11128,7 @@ BUILDIN(roclass)
sex = script_getnum(st,3);
else {
TBL_PC *sd;
- if (st->rid && (sd=script->rid2sd(st)))
+ if (st->rid && (sd=script->rid2sd(st)) != NULL)
sex = sd->status.sex;
else
sex = 1; //Just use male when not found.
@@ -11420,6 +11413,10 @@ BUILDIN(disablewaitingroomevent) {
/// <type>=16 : the name of the waiting room event
/// <type>=32 : if the waiting room is full
/// <type>=33 : if there are enough users to trigger the event
+/// -- Custom Added
+/// <type>=34 : minimum player of waiting room
+/// <type>=35 : maximum player of waiting room
+/// <type>=36 : minimum zeny required
///
/// getwaitingroomstate(<type>,"<npc_name>") -> <info>
/// getwaitingroomstate(<type>) -> <info>
@@ -11427,6 +11424,7 @@ BUILDIN(getwaitingroomstate) {
struct npc_data *nd;
struct chat_data *cd;
int type;
+ int i;
type = script_getnum(st,2);
if( script_hasdata(st,3) )
@@ -11440,7 +11438,13 @@ BUILDIN(getwaitingroomstate) {
}
switch(type) {
- case 0: script_pushint(st, cd->users); break;
+ case 0:
+ for (i = 0; i < cd->users; i++) {
+ struct map_session_data *sd = cd->usersd[i];
+ mapreg->setreg(reference_uid(script->add_str("$@chatmembers"), i), sd->bl.id);
+ }
+ script_pushint(st, cd->users);
+ break;
case 1: script_pushint(st, cd->limit); break;
case 2: script_pushint(st, cd->trigger&0x7f); break;
case 3: script_pushint(st, ((cd->trigger&0x80)!=0)); break;
@@ -11449,6 +11453,10 @@ BUILDIN(getwaitingroomstate) {
case 16: script_pushstrcopy(st, cd->npc_event);break;
case 32: script_pushint(st, (cd->users >= cd->limit)); break;
case 33: script_pushint(st, (cd->users >= cd->trigger)); break;
+
+ case 34: script_pushint(st, cd->minLvl); break;
+ case 35: script_pushint(st, cd->maxLvl); break;
+ case 36: script_pushint(st, cd->zeny); break;
default: script_pushint(st, -1); break;
}
return true;
@@ -11565,7 +11573,6 @@ BUILDIN(isloggedin) {
return true;
}
-
/*==========================================
*
*------------------------------------------*/
@@ -11885,7 +11892,6 @@ BUILDIN(pvpon) {
bl.m = m;
clif->maptypeproperty2(&bl,ALL_SAMEMAP);
-
if(battle_config.pk_mode) // disable ranking functions if pk_mode is on [Valaris]
return true;
@@ -12294,7 +12300,7 @@ BUILDIN(successremovecards)
if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) {
// get back the cart in inventory
clif->additem(sd,0,0,flag);
- map->addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ map->addflooritem(&sd->bl, &item_tmp, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
}
}
}
@@ -12319,7 +12325,7 @@ BUILDIN(successremovecards)
if ((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) {
//chk if can be spawn in inventory otherwise put on floor
clif->additem(sd,0,0,flag);
- map->addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ map->addflooritem(&sd->bl, &item_tmp, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
}
clif->misceffect(&sd->bl,3);
@@ -12368,7 +12374,7 @@ BUILDIN(failedremovecards)
if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) {
clif->additem(sd,0,0,flag);
- map->addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ map->addflooritem(&sd->bl, &item_tmp, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
}
}
}
@@ -12399,7 +12405,7 @@ BUILDIN(failedremovecards)
if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) {
clif->additem(sd,0,0,flag);
- map->addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ map->addflooritem(&sd->bl, &item_tmp, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
}
}
clif->misceffect(&sd->bl,2);
@@ -13806,12 +13812,20 @@ BUILDIN(message) {
/*==========================================
* npctalk (sends message to surrounding area)
+ * usage: npctalk "<message>"{,"<npc name>"};
*------------------------------------------*/
BUILDIN(npctalk)
{
- struct npc_data* nd = (struct npc_data *)map->id2bl(st->oid);
+ struct npc_data* nd;
const char *str = script_getstr(st,2);
+ if (script_hasdata(st, 3)) {
+ nd = npc->name2id(script_getstr(st, 3));
+ }
+ else {
+ nd = (struct npc_data *)map->id2bl(st->oid);
+ }
+
if (nd) {
char name[NAME_LENGTH], message[256];
safestrncpy(name, nd->name, sizeof(name));
@@ -13977,7 +13991,6 @@ BUILDIN(getnpcclass)
return true;
}
-
/*==========================================
* getlook char info. getlook(arg)
*------------------------------------------*/
@@ -14082,13 +14095,13 @@ BUILDIN(getmapxy)
script_pushint(st,-1);
return false;
}
-
+
if( !is_string_variable(reference_getname(script_getdata(st, 2))) ) {
ShowWarning("script: buildin_getmapxy: %s is not a string variable\n",reference_getname(script_getdata(st, 2)));
script_pushint(st,-1);
return false;
}
-
+
if( is_string_variable(reference_getname(script_getdata(st, 3))) ) {
ShowWarning("script: buildin_getmapxy: %s is a string variable, should be int\n",reference_getname(script_getdata(st, 3)));
script_pushint(st,-1);
@@ -14180,7 +14193,7 @@ BUILDIN(getmapxy)
num=st->stack->stack_data[st->start+2].u.num;
name=script->get_str(script_getvarid(num));
prefix=*name;
-
+
if(not_server_variable(prefix))
sd=script->rid2sd(st);
else
@@ -14557,7 +14570,7 @@ BUILDIN(equip2)
script_pushint(st,0);
return true;
}
-
+
nameid = script_getnum(st,2);
if( (item_data = itemdb->exists(nameid)) == NULL )
{
@@ -14831,8 +14844,6 @@ BUILDIN(explode)
size_t len = strlen(str);
int i = 0, j = 0;
int start;
-
-
char *temp;
const char* name;
@@ -15403,7 +15414,6 @@ BUILDIN(countstr)
return true;
}
-
/// Changes the display name and/or display class of the npc.
/// Returns 0 is successful, 1 if the npc does not exist.
///
@@ -16153,7 +16163,6 @@ BUILDIN(checkvending) // check vending [Nab4]
return true;
}
-
// check chatting [Marka]
BUILDIN(checkchatting) {
TBL_PC *sd = NULL;
@@ -16295,7 +16304,6 @@ BUILDIN(pcfollow) {
int id, targetid;
TBL_PC *sd = NULL;
-
id = script_getnum(st,2);
targetid = script_getnum(st,3);
@@ -16315,7 +16323,6 @@ BUILDIN(pcstopfollow)
int id;
TBL_PC *sd = NULL;
-
id = script_getnum(st,2);
if(id)
@@ -16733,7 +16740,7 @@ BUILDIN(getvariableofnpc)
if( !nd->u.scr.script->local.vars )
nd->u.scr.script->local.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
-
+
script->push_val(st->stack, C_NAME, reference_getuid(data), &nd->u.scr.script->local);
return true;
}
@@ -16770,7 +16777,7 @@ BUILDIN(warpportal) {
if( bl->type == BL_NPC )
unit->bl2ud2(bl); // ensure nd->ud is safe to edit
-
+
group = skill->unitsetting(bl, AL_WARP, 4, spx, spy, 0);
if( group == NULL )
return true;// failed
@@ -16823,7 +16830,7 @@ BUILDIN(checkcell) {
return true;
}
- script_pushint(st, map->getcell(m, x, y, type));
+ script_pushint(st, map->getcell(m, NULL, x, y, type));
return true;
}
@@ -17726,7 +17733,7 @@ BUILDIN(has_instance) {
int16 m;
int instance_id = -1;
bool type = strcmp(script->getfuncname(st),"has_instance2") == 0 ? true : false;
-
+
str = script_getstr(st, 2);
if( (m = map->mapname2mapid(str)) < 0 ) {
@@ -17755,7 +17762,7 @@ BUILDIN(has_instance) {
if( i != sd->instances )
instance_id = sd->instance[i];
}
- if( instance_id == -1 && sd->status.party_id && (p = party->search(sd->status.party_id)) && p->instances ) {
+ if (instance_id == -1 && sd->status.party_id && (p = party->search(sd->status.party_id)) != NULL && p->instances) {
for( i = 0; i < p->instances; i++ ) {
if( p->instance[i] >= 0 ) {
ARR_FIND(0, instance->list[p->instance[i]].num_map, j, map->list[instance->list[p->instance[i]].map[j]].instance_src_map == m);
@@ -17940,7 +17947,7 @@ BUILDIN(instance_check_guild)
c++;
}
}
-
+
if( c < amount )
script_pushint(st,0);
else
@@ -18039,7 +18046,6 @@ BUILDIN(areamobuseskill) {
return true;
}
-
BUILDIN(progressbar)
{
struct map_session_data * sd = script->rid2sd(st);
@@ -18101,7 +18107,6 @@ BUILDIN(pushpc)
return true;
}
-
/// Invokes buying store preparation window
/// buyingstore <slots>;
BUILDIN(buyingstore)
@@ -18116,7 +18121,6 @@ BUILDIN(buyingstore)
return true;
}
-
/// Invokes search store info window
/// searchstores <uses>,<effect>;
BUILDIN(searchstores)
@@ -18393,7 +18397,6 @@ BUILDIN(bindatcmd) {
if( script_hasdata(st,5) ) group_lv_char = script_getnum(st,5);
if( script_hasdata(st,6) ) log = script_getnum(st,6) ? true : false;
-
if( atcommand->binding_count == 0 ) {
CREATE(atcommand->binding,struct atcmd_binding_data*,1);
@@ -18608,7 +18611,7 @@ BUILDIN(getrandgroupitem) {
if ((flag = pc->additem(sd, &it, get_count, LOG_TYPE_SCRIPT))) {
clif->additem(sd, 0, 0, flag);
if( pc->candrop(sd,&it) )
- map->addflooritem(&it,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ map->addflooritem(&sd->bl, &it, get_count, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
}
}
}
@@ -18668,11 +18671,11 @@ BUILDIN(npcskill) {
skill_level = script_getnum(st, 3);
stat_point = script_getnum(st, 4);
npc_level = script_getnum(st, 5);
-
+
if( !(sd = script->rid2sd(st)) )
return false;
-
- nd = (struct npc_data *)map->id2bl(sd->npc_id);
+
+ nd = (struct npc_data *)map->id2bl(sd->npc_id);
if (stat_point > battle_config.max_third_parameter) {
ShowError("npcskill: stat point exceeded maximum of %d.\n",battle_config.max_third_parameter );
@@ -18778,7 +18781,7 @@ BUILDIN(montransform) {
clif->ShowScript(&sd->bl, msg);
status_change_end(bl, SC_MONSTER_TRANSFORM, INVALID_TIMER); // Clear previous
sc_start2(NULL, bl, SC_MONSTER_TRANSFORM, 100, mob_id, type, tick);
-
+
if (script_hasdata(st, 4))
sc_start4(NULL, bl, type, 100, val1, val2, val3, val4, tick);
}
@@ -18862,7 +18865,7 @@ bool script_hqueue_add(int idx, int var)
script->hq[idx].item[i] = var;
script->hq[idx].items++;
- if (var >= START_ACCOUNT_NUM && (sd = map->id2sd(var))) {
+ if (var >= START_ACCOUNT_NUM && (sd = map->id2sd(var)) != NULL) {
for (i = 0; i < sd->queues_count; i++) {
if (sd->queues[i] == -1) {
break;
@@ -18908,7 +18911,7 @@ bool script_hqueue_remove(int idx, int var) {
script->hq[idx].item[i] = -1;
script->hq[idx].items--;
- if( var >= START_ACCOUNT_NUM && (sd = map->id2sd(var)) ) {
+ if (var >= START_ACCOUNT_NUM && (sd = map->id2sd(var)) != NULL) {
for(i = 0; i < sd->queues_count; i++) {
if( sd->queues[i] == idx ) {
break;
@@ -18986,7 +18989,7 @@ bool script_hqueue_del(int idx)
int i;
for (i = 0; i < script->hq[idx].size; i++) {
struct map_session_data *sd;
- if( script->hq[idx].item[i] >= START_ACCOUNT_NUM && (sd = map->id2sd(script->hq[idx].item[i])) ) {
+ if (script->hq[idx].item[i] >= START_ACCOUNT_NUM && (sd = map->id2sd(script->hq[idx].item[i])) != NULL) {
int j;
for(j = 0; j < sd->queues_count; j++) {
if( sd->queues[j] == script->hq[idx].item[i] ) {
@@ -19025,7 +19028,7 @@ void script_hqueue_clear(int idx) {
for(i = 0; i < script->hq[idx].size; i++) {
if( script->hq[idx].item[i] > 0 ) {
- if( script->hq[idx].item[i] >= START_ACCOUNT_NUM && (sd = map->id2sd(script->hq[idx].item[i])) ) {
+ if (script->hq[idx].item[i] >= START_ACCOUNT_NUM && (sd = map->id2sd(script->hq[idx].item[i])) != NULL) {
for(j = 0; j < sd->queues_count; j++) {
if( sd->queues[j] == idx ) {
break;
@@ -19292,7 +19295,7 @@ BUILDIN(checkbound)
return true;
} else
script_pushint(st,0);
-
+
return true;
}
@@ -19373,8 +19376,6 @@ BUILDIN(instance_set_respawn) {
script_pushint(st, 0);
}
}
-
-
return true;
}
/**
@@ -19676,7 +19677,6 @@ BUILDIN(channelmes)
return true;
}
-
/** By Cydh
Display script message
showscript "<message>"{,<GID>};
@@ -20128,7 +20128,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF2(atcommand,"charcommand","s"), // [MouseJstr]
BUILDIN_DEF(movenpc,"sii?"), // [MouseJstr]
BUILDIN_DEF(message,"ss"), // [MouseJstr]
- BUILDIN_DEF(npctalk,"s"), // [Valaris]
+ BUILDIN_DEF(npctalk,"s?"), // [Valaris]
BUILDIN_DEF(mobcount,"ss"),
BUILDIN_DEF(getlook,"i"),
BUILDIN_DEF(getsavepoint,"i"),
@@ -20433,7 +20433,6 @@ void script_label_add(int key, int pos) {
* Sets source-end constants for scripts to play with
**/
void script_hardcoded_constants(void) {
-
/* server defines */
script->set_constant("PACKETVER",PACKETVER,false);
script->set_constant("MAX_LEVEL",MAX_LEVEL,false);
@@ -20553,7 +20552,7 @@ void script_hardcoded_constants(void) {
**/
unsigned short script_mapindexname2id (struct script_state *st, const char* name) {
unsigned short index;
-
+
if( !(index=mapindex->name2id(name)) ) {
script->reportsrc(st);
return 0;
@@ -20561,7 +20560,6 @@ unsigned short script_mapindexname2id (struct script_state *st, const char* name
return index;
}
-
void script_defaults(void) {
// aegis->athena slot position conversion table
unsigned int equip[SCRIPT_EQUIP_TABLE_SIZE] = {EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_GARMENT,EQP_SHOES,EQP_ACC_L,EQP_ACC_R,EQP_HEAD_MID,EQP_HEAD_LOW,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_GARMENT,EQP_SHADOW_ARMOR, EQP_SHADOW_WEAPON, EQP_SHADOW_SHIELD, EQP_SHADOW_SHOES, EQP_SHADOW_ACC_R, EQP_SHADOW_ACC_L};
@@ -20574,7 +20572,7 @@ void script_defaults(void) {
script->st_ers = NULL;
script->stack_ers = NULL;
script->array_ers = NULL;
-
+
script->hq = NULL;
script->hqi = NULL;
script->hqs = script->hqis = 0;
@@ -20654,6 +20652,14 @@ void script_defaults(void) {
script->push_val = push_val;
script->get_val = get_val;
script->get_val2 = get_val2;
+ script->get_val_ref_str = get_val_npcscope_str;
+ script->get_val_scope_str = get_val_npcscope_str;
+ script->get_val_npc_str = get_val_npcscope_str;
+ script->get_val_instance_str = get_val_instance_str;
+ script->get_val_ref_num = get_val_npcscope_num;
+ script->get_val_scope_num = get_val_npcscope_num;
+ script->get_val_npc_num = get_val_npcscope_num;
+ script->get_val_instance_num = get_val_instance_num;
script->push_str = push_str;
script->push_copy = push_copy;
script->pop_stack = pop_stack;
@@ -20720,6 +20726,15 @@ void script_defaults(void) {
script->print_line = script_print_line;
script->errorwarning_sub = script_errorwarning_sub;
script->set_reg = set_reg;
+ script->set_reg_ref_str = set_reg_npcscope_str;
+ script->set_reg_scope_str = set_reg_npcscope_str;
+ script->set_reg_npc_str = set_reg_npcscope_str;
+ script->set_reg_instance_str = set_reg_instance_str;
+ script->set_reg_ref_num = set_reg_npcscope_num;
+ script->set_reg_scope_num = set_reg_npcscope_num;
+ script->set_reg_npc_num = set_reg_npcscope_num;
+ script->set_reg_instance_num = set_reg_instance_num;
+
script->stack_expand = stack_expand;
script->push_retinfo = push_retinfo;
script->op_3 = op_3;
@@ -20798,7 +20813,7 @@ void script_defaults(void) {
script->global_casecheck.str_pos = 0;
memset(script->global_casecheck.str_hash, 0, sizeof(script->global_casecheck.str_hash));
// end ENABLE_CASE_CHECK
-
+
/**
* Array Handling
**/