diff options
Diffstat (limited to 'src/map/script.c')
-rw-r--r-- | src/map/script.c | 703 |
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 **/ |