I'm making a collectible trading card game, where the player gets cards as inventory items. I want to have these cards able to be sorted by various aspects of those cards (attack, defense, type of card, etc). So far I've used a Bubble Sort, but the variables that I use (InvWindow.ItemCount, InvWindow.ItemAtIndex, etc) are read-only, and i can't update them. So then I tried to modify the contents of the Character.InventoryQuantity[] array, but then I have to call UpdateInventory() in order for it to be shown on screen, and that totally defeats the purpose of sorting it to begin with, since UpdateInventory resets all items back to their index based on the order they were created in the editor.
Does anyone have any idea how to sort inventory items well? Thanks in advance! ;D
Since trading card games tend to have rules for "types of cards", why not make these PROPERTIES (Like Black, Blue, White / Summon, Land, Instant etc) and give them to the cards, accordingly? Properties can be Boolean, Integer and Char, and they are read-and-changeable, so this should work nicely. Property handling is covered in the manual, but should you need a few tips, just say so.
Of course, there's bound to be a less time-consuming, more programmer-oriented way too...
I'm actually using properties as the focus points of the sort. However, that's not really the problem. I can't seem to get the script right, because the indexes of the items are read-only. I guess the best way to put the question is, is there any way to get around the read-only-ness of the variables?
And by the way, I don't think properties are changable. At least, that's the message I got when I read about them in th manual.
Hm. In that case case I suggest you wait for KrisMUC and/or SSH. Both have extensive knowledge of advanced scripting and may be able to help you out. PMing them should be okay, too.
Yes, Custom Properties (http://www.adventuregamestudio.co.uk/manual/Custom%20Properties.htm) (if that's what you were talking about, Ghost) are read-only, says so right in the manual. And there's no need to start PMing people, until everyone's had a chance to make suggestions.
It might be a bit clunky, but what if you clear the player's inventory (copy it to another character), then refill it using the addAtIndex parameter of Character.AddInventory? That SHOULD allow you to sort the items as you wish - the downside being needing to clear all items to rearrange them.
I know there's code floating around to duplicate the player's Inventory into another character (pretty simple) and depending on how exactly you want to sort them, it shouldn't be too hard to figure a way to move them back in the right order.
As I was typing, I realised it might make more sense to copy them to the other character in order, and display that inventory... So basically, a 'Dummy' character could be the way to go.
Probably the easiest approach would be to store all the item IDs in an array, sort them there, then lose all inventory and add it back in the order of the array. I use a similar device to alphabetize lists, and I see no reason why it shouldn't work for inventory items too.
Something like this should do the trick, I think:
function SortInventory(InvWindow* invwin, String property, bool highestfirst) {
int maxitems = invwin.ItemCount;
int invitem[AGS_MAX_INV_ITEMS]; //initialize an array, unfortunately we can't use maxitems because it's not a constant. Should be possible using Dynamic arrays in AGS 2.8
int itemcount;
Character* invchar = invwin.CharacterToUse;
if (invchar == null) invchar = player;
while (itemcount < maxitems) { //read inventory to array, emptying the inventory at the same time
invitem[itemcount] = invwin.ItemAtIndex[0].ID;
invchar.LoseInventory(invwin.ItemAtIndex[0]);
itemcount++;
}
int countentries;
int countsubentries;
while (countentries < maxitems) { //Now we bubble sort the items according to custom properties
while (countsubentries < maxitems - (1 + countentries)) {
if (inventory[invitem[countsubentries]].GetProperty(property) > inventory[invitem[countsubentries+1]].GetProperty(property)) {
int tempid = invitem[countsubentries];
invitem[countsubentries] = invitem[countsubentries+1];
invitem[countsubentries+1] = tempid;
}
countsubentries++;
}
countsubentries = 0;
countentries++;
}
//write back items into inventory, with either highest or lowest value first.
if (highestfirst == true) {
while (itemcount > 0) {
itemcount--;
invchar.AddInventory(inventory[invitem[itemcount]]);
}
}
else {
itemcount = 0;
while (itemcount < maxitems) {
invchar.AddInventory(inventory[invitem[itemcount]]);
itemcount++;
}
}
}
I don't get any compile errors, and my small test game works fine now. But I don't have a game around with a lot of inventory items to test it out with. Could someone please give it a try and see if it works?
Rewriting this to sort alphabetically by text property instead of numerical properties should be trivial. Just replace:
if (inventory[invitem[countsubentries]].GetProperty(property) > inventory[invitem[countsubentries+1]].GetProperty(property)) {
with
String tempstring = inventory[invitem[countsubentries]].GetTextProperty(property);
if (tempstring.CompareTo(inventory[invitem[countsubentries+1]].GetTextProperty(property)) > 0) {
Wow, that code really did the trick! I still need to tweak it in parts so that it sorts the way I need it to in my particular game, but the actual sorting part worked excellently. Thanks so much!
NiksterG ;D