summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/map/script.c74
-rw-r--r--src/map/script.h1
2 files changed, 67 insertions, 8 deletions
diff --git a/src/map/script.c b/src/map/script.c
index 5ed09b52a..76cb2ef89 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -2597,6 +2597,49 @@ void* get_val2(struct script_state* st, int64 uid, struct DBMap** ref) {
return (data->type == C_INT ? (void*)__64BPTRSIZE(data->u.num) : (void*)__64BPTRSIZE(data->u.str));
}
/**
+ * Because, currently, array members with key 0 are indifferenciable from normal variables, we should ensure its actually in
+ * Will be gone as soon as undefined var feature is implemented
+ **/
+void script_array_ensure_zero(struct script_state *st, struct map_session_data *sd, int64 uid, struct DBMap** ref) {
+ const char *name = script->get_str(script_getvarid(uid));
+ bool insert = false;
+
+ if( sd ) /* when sd comes, st isn't available */
+ insert = true;
+ else {
+ if( is_string_variable(name) ) {
+ char* str = (char*)script->get_val2(st, uid, ref);
+ if( str && *str )
+ insert = true;
+ script_removetop(st, -1, 0);
+ } else {
+ int32 num = (int32)__64BPTRSIZE(script->get_val2(st, uid, ref));
+ if( num )
+ insert = true;
+ script_removetop(st, -1, 0);
+ }
+ }
+
+ if( insert ) {
+ struct script_array *sa = NULL;
+ struct DBMap *src = script->array_src(st, sd ? sd : st->rid ? map->id2sd(st->rid) : NULL, name);
+
+ if( src ) {
+ if( (sa = idb_get(src, script_getvarid(uid)) ) ) {
+ unsigned int i;
+
+ ARR_FIND(0, sa->size, i, sa->members[i] == 0);
+ if( i != sa->size )
+ return;
+
+ script->array_add_member(sa,0);
+ } else {
+ script->array_update(&src,reference_uid(script_getvarid(uid), 0),false);
+ }
+ }
+ }
+}
+/**
* Returns array size by ID
**/
unsigned int script_array_size(struct script_state *st, struct map_session_data *sd, const char *name) {
@@ -2614,16 +2657,23 @@ 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 script_array *sa = NULL;
struct DBMap *src = script->array_src(st, sd, name);
+
+
+ if( src ) {
+ int key = script->add_word(name);
- if( src && ( sa = idb_get(src, script->search_str(name)) ) ) {
- unsigned int i, highest_key = 0;
+ script->array_ensure_zero(st,sd,reference_uid(key, 0),NULL);
- for(i = 0; i < sa->size; i++) {
- if( sa->members[i] > highest_key )
- highest_key = sa->members[i];
+ if( ( sa = idb_get(src, 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 highest_key + 1;
}
-
- return highest_key + 1;
}
return 0;
@@ -4025,6 +4075,9 @@ void script_cleararray_pc(struct map_session_data* sd, const char* varname, void
if( !(src = script->array_src(NULL,sd,varname) ) )
return;
+ if( value )
+ script->array_ensure_zero(NULL,sd,reference_uid(key,0),NULL);
+
if( !(sa = idb_get(src, key)) ) /* non-existent array, nothing to empty */
return;
@@ -5779,7 +5832,11 @@ BUILDIN(deletearray)
script->reportdata(data);
st->state = END;
return false;// not a variable
- } else if ( !(sa = idb_get(src, id)) ) { /* non-existent array, nothing to empty */
+ }
+
+ script->array_ensure_zero(st,NULL,data->u.num,reference_getref(data));
+
+ if ( !(sa = idb_get(src, id)) ) { /* non-existent array, nothing to empty */
return true;// not a variable
}
@@ -19217,6 +19274,7 @@ void script_defaults(void) {
script->array_size = script_array_size;
script->array_free_db = script_free_array_db;
script->array_highest_key = script_array_highest_key;
+ script->array_ensure_zero = script_array_ensure_zero;
/* */
script->reg_destroy_single = script_reg_destroy_single;
script->reg_destroy = script_reg_destroy;
diff --git a/src/map/script.h b/src/map/script.h
index 65e11d3ca..7a643fa3e 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -688,6 +688,7 @@ struct script_interface {
unsigned int (*array_size) (struct script_state *st, struct map_session_data *sd, const char *name);
unsigned int (*array_highest_key) (struct script_state *st, struct map_session_data *sd, const char *name);
int (*array_free_db) (DBKey key, DBData *data, va_list ap);
+ void (*array_ensure_zero) (struct script_state *st, struct map_session_data *sd, int64 uid, struct DBMap** ref);
/* */
void (*reg_destroy_single) (struct map_session_data *sd, int64 reg, struct script_reg_state *data);
int (*reg_destroy) (DBKey key, DBData *data, va_list ap);