How do I copy an array using `setd`?

ahoy

New member
Messages
3
Points
0
I'm creating a storage system which allows users to join a group and share a storage between them. 

When a group is created, it is assigned an ID. When a player joins the group, they are associated with the group with a permanent account variable.

If Alice is in group 0 and she deposits some items 50 items with ID 10 and 7 items with ID 21, the array `$global_storage_keys:0` should be set to `[10, 21]` and the variable `$global_storage:0:10` and `$global_storage:0:21` should be set to 50 and 7 respectively. However, when I try to update the keys variable with `setd`, only the first value of the array is preserved. How do I manipulate an array which I need to `setd` to access? Thanks.

function script add_id_to_global_store {
// Adds the ID an an item to the key store.
// arg0: the integer ID of an item
// arg1: the integer ID of the guild
.@id = getarg(0);
.@guild_id = getarg(1);

freeloop(1);
.@keys = getd("$global_storage_keys" + ":" + .@guild_id);

.@found = callfunc("array_exists", .@keys, .@id);

if (.@found) {
freeloop(0);
return;
}

// The new ID was not in the global store, so add it.
callfunc("array_pad", .@keys, getarraysize(.@keys) + 1, .@id);
setd("$global_storage_keys" + ":" + .@guild_id, .@keys);

freeloop(0);
return;
}


From this snippet, after I call `setd` with value `.@keys`, the length of `$global_storage_keys:<guild_id>` is always zero. 

 
I use the following:

function script funCopyInstanceMaps {
// Given instance name, and a reference to an Array,
// copy the array of maps to this new array.

.@instance_name$ = getarg(0);

.@which_maps$ = "$@maps_this_run_" + .@instance_name$ + "$";
.@map_count = getarraysize(getd(.@which_maps$));
copyarray(getarg(1), getd(.@which_maps$), .@map_count);

return;
}


Should be similar to your case. Usage of copyarray is documented in the script_commands.txt and there are examples on samples folder. Should work in your case with some tweaking for your situation, I suppose? Can have guard clauses on the amount of data to copy if desired.

I have getarg(1) as argument on copyarray because this is the variable I want to store the copy of the array by using getd on variable I'm obtaining dynamically on the string written in .@which_maps$.

 
Last edited by a moderator:
Hi, thanks for your reply.

I think this case is a little different as `copyarray` requires a reference to an array. Unless I am misunderstanding something, in your example, you are getting a reference to your global array and are then copying it to an array that you are passing as your first argument. But in my case, I need to update a global array. I use `getd` to get a reference to my global array, but the destination array in `copyarray` cannot accept a string reference. When I follow your pattern, I am copying the contents of an array into itself without updating the global array. 

 
Hi, thanks for your reply.

I think this case is a little different as `copyarray` requires a reference to an array. Unless I am misunderstanding something, in your example, you are getting a reference to your global array and are then copying it to an array that you are passing as your first argument. But in my case, I need to update a global array. I use `getd` to get a reference to my global array, but the destination array in `copyarray` cannot accept a string reference. When I follow your pattern, I am copying the contents of an array into itself without updating the global array. 
// Set each element of the array individually
for (.@i = 0; .@i < getarraysize(.@keys); .@i++) {
setd("$global_storage_keys" + ":" + .@guild_id + "[" + .@i + "]", .@keys[.@i]);
}


Sadly seems that the script engine is clunky when you need to work with setd and arrays, this should be done by the engine itself, but since seems like setd isn't doing the job behind the scene, maybe you could try my code.

 
Last edited by a moderator:
Back
Top