Skip to content

Sorting inventory after destroying items

When destroying items in object's inventory, they're positions are still locked. Let's say I destroy an item in someone's inventory and then add another item to them. This item will not be at the start of this object's inventory but more adjusted to the right because the first item had already used that starting space. Is there a solution to this?

Comments

  • MelkiorMelkior Member Posts: 240
    The DestroyObject command always runs after the script finishes (just in case the destroyed object is what the script was running on, since scripts can't run on a nonexistent object).
    I found a solution, but it's a round-about way, and requires a bit of script trickery.

    If you use the command queue of a creature, then you can force the object to be moved BEFORE you create the replacement object. That will leave an empty space which, presuming it's the first space of that size in the inventory, will be filled by the replacement.

    You need to use the command queue of a creature to first transfer the original item to another container (which can be in a completely different area) and then create a new item on the source. You can issue the DestroyObject command on the transferred item at any point (before transfer, after transfer, or even after creating the replacement) since it won't vanish until after the script ends. Just for my sanity, I usually issue the command right after the transfer.

    The key is that all of these have to be run as creature commands.
    AssignCommand(oPC,ActionGiveItem(oItem,oGiveTo));
    AssignCommand(oPC,DestroyObject(oItem));
    AssignCommand(oPC,ActionDoCommand(CreateItemOnObject("newobject",oPC,1)));

    I'm not sure of the format for the last one, but it has to set up CreateitemOnObject so that it works like a command rather than like a function, otherwise the AssignCommand will complain that what you've given it isn't a command.

    There are ways of getting around the problem if you need to save the object variable of the new item when you create it. Possibly the simplest is to just use GetItemPossessedBy on the PC after, to find the newly created item.

    Strictly speaking, the DestroyObject command doesn't need to be part of the command queue because, repeating myself again, it doesn't get done until after the script ends.
  • DestherSurvivedDestherSurvived Member Posts: 5
    Unfortunately, this part of the code gave me trouble.

    AssignCommand(oPC,ActionDoCommand(CreateItemOnObject("newobject",oPC,1)));

    It would always throw an error with a different (create item) approach. Fortunately I've managed to find another solution. That DestroyObject executing at the end of the script made me think -what if I create an item after the script has ended with a delay

    DelayCommand(0.0, CopyItem());

    And it worked! At least for containers. With creatures it was a little different. When a creature is NOT lootable (doesn't leave corpse), this method works as well, but when a creature leaves a lootable corpse, after removing all the items, the body isn't selectable anymore. For me it's not a huge issue; I just make every npc leave a treasure model, and that's it. There could be empty inventory pages if the npc had too many items, but this is manageable.
  • MelkiorMelkior Member Posts: 240
    IIRC, there's a script in one of the standard include modules which acts as a "wrapper" for the CreateObject script, turning it into a command rather than a function so that it can be used in something like AssignCommand.
    The way to do it yourself is to make a void type function which takes all of the same parameters as CreateObject and which then calls the CreateObject command with those parameters. That void function can then be used in AssignCommand since it does not return anything. I've done it before and I just call my custom function CreateObjectVoid to make it easy to remember.
    But it's good that you found a work-around.
Sign In or Register to comment.