Well, ~20 to a little less than 30 attributes don't really work for me. Especially if it requires dedicating certain ganis to each slot (and memorizing/documenting them..). SO I've developed a system that, when told, will actively search for a free slot within a range of slot numbers (in this case, 10-29. assuming there is no [30] as I hear it's 30 slots, and 0-29 is 30 slots.), and if it finds one, will place a gani into a client.attr slot (Then will use that list to place ganis into player.attr). And when told, will search for any ganis within that range and remove them. As well as storing an internal queue if slots 10-29 are full, and as soon as a slot opens up, places the next gani in line into the queue.
edit for clarification (and cuz I dont feel like editing the entire paragraph above

): it actually searches between client.attr 0-19, then offsets the difference by +10 when applying it to player.attr.
I excecute the add gani command with AttrSys.addAttr(<ganiname>) and oddly enough, this was somewhat working (displaying the ganis) when I accidentally had it set up as player.attr[11] = AttrSys.addAttr(ganiname). But as of fixing that, the ganis stopped displaying when I try setting them. So I'm not sure what's up with that.
So here's my script. Can anyone figure out what I'm doing wrong this time?
PHP Code:
//#CLIENTSIDE
function onCreated(){
AttrSys = this;
client.attr = {
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
};
this.queue = null;
setTimer(0.05);
}
function onTimeout(){
doApplyAttributes();
setTimer(0.05);
}
public function addAttr(ganiname){
if(ganiname in client.attr){//Return if the gani is already there.
return;
}
for(i=0;i<19;i++){
if(client.attr[i] == ""){//If the slot is empty, set it.
client.attr[i] = ganiname;
player.chat = ganiname SPC "added to attr[" @ i @ "]!";
return;
}
if(i == 19 && client.attr[i] != ""){//If all slots are full, store the gani in a queue.
this.queue.add(ganiname);
player.chat = "All attributes are currently taken!";
return;
}
}
}
public function delAttr(ganiname){
for(i=0;i<19;i++){
if(client.attr[i] == ganiname){//If the slot is empty, set it.
client.attr[i] = "";
player.attr[i+10] = "";
player.chat = "Removed" SPC ganiname SPC "from " @ i @ " !";
return;
}
}
}
function doApplyAttributes(){
if(this.queue == null){
for(i=0;i<19;i++){//If no attributes are stored, apply them.
if(player.attr[i+10] != client.attr[i]){
player.attr[i+10] = client.attr[i];
}
}
}
else{
//If we have stored attributes, attempt to apply the first one in the queue.
addAttribute(this.queue[0]);//Attempt to add the first one into the attributes.
temp.placeholder = null;
for(i=1;i<this.queue.size();i++){//Shift all of the queued params down one place by copying the queue with everything one position down then..
temp.placeholder[i-1] = this.queue[i];
}
this.queue = null;
for(i=0;i<temp.placeholder.size();i++){//..Pasting the copied queue back into this.queue.
this.queue[i] = temp.placeholder[i];
}
temp.placeholder = null;//Clear the placeholder.
doApplyattributes();//Try again.
}
}
function onPlayerchats(){
//In case part of client.attr is cut off due to setting player attributes with RC, resulting in an undeletable client.attr slot.
if(player.chat == "/resetattrs"){
onCreated();//Run onCreated to clear client.attr
}
}