I bashed my had against this for the past four days.
These are my notes, maybe something is interesting.
[transfer_pid_between_objs]
[transfer_all_pid_between_objs]
[remove_pid_qty]
-can detect all items (inventory, handslot, worn).
-but only move what they can find in inventory and ignore the rest (handslot & worn) (bug).
-if nothing is in inventory it will remove a single item instead. The order to select this item is: handslot item1, handslot item2, worn.
And last: (oddity: picked up items*). If this happens it (may) remove the item incorrectly (bug). That means it may not clean up animation (weapon & armour; minor bug) and may not reset DT/DR (armour; bug).
*ODDITY: an item (or items) dropped to the ground and picked up again, are not part of the inventory until opening/closing inventory. So in the case of the bug the engine will check handslots and worn first, and the picked up items last. [note: only if the picked up items do not already exist in inventory. If they do, the picked up items get added to that stack and removed with it. But if it's a new stack, the whole stack of items is in “limbo”. Until opening/closing inventory.]
**ODDITY II: This is more vague, but it's possible that an item moved from handslot to inventory via [inven_unwield] will enter the same limbo state as the picked up item.
I did run [inven_unwield] before [remove_pid_qty
] and it would put the item in limbo, but when I used [rm_obj_from_inven plus add_obj_to_inven] instead [inven_unwield], it didn't. May have been bad scripting on my part. Used this:
if (critter_inven_obj(dude_obj, 2) or critter_inven_obj(dude_obj, 1)) then begin
metarule(43, dude_obj);
end
which does unwield but may not do it correctly... not sure. Anyway, [inven_unwield] may be another potential case.
Btw, I also tested this w/ [
rm_mult_objs_from_inven] only, see AcMorlis.int (node007). She wants three Healing Powder and you can hide two on your handslots.
[You can also test the pick up limbo with her: Put one powder on handslot and drop the other two. Then pick the two up again. And deliver. And it will only remove the one from handslot.]
Tests done w/ sfall 4.3.7. And confirmed w/o it. This should all be vanilla behaviour.
Fixes:
-The first [incorrect removal] can be fixed by adding a "proper" [remove_armor] and [
inven_unwield] check into the code.
[Notes: The transfer command misses it entirely. The check in [remove_pid_qty] uses
self_obj for [
critter_inven_obj] (instead of who_obj) so it does not adjust to dude_obj. This creates a bug w/ [remove_armor], i.e. it removes the armour but does not reset DT/DR or clean up animation.]
Note: may also use [rm_obj_from_inven] or [move_obj_inven_to_obj] which do this [i.e. unequip] correctly, and w/o any addition to the code.
-The second [ignoring items on handslot and armour]... I only managed to fix with this:
#define
remove_pid_qty_proper(who_obj, the_pid, pid_qty)
counter := 0; \
while (counter < pid_qty) do begin \
restock_obj := obj_carrying_pid_obj(who_obj, the_pid); \
rm_obj_from_inven(dude_obj, restock_obj); \
destroy_object(restock_obj); \
counter := (counter + 1); \
end
And
remove_pid_qty_proper(dude_obj, PID_COMBAT_ARMOR, 5)
scr_return(1);
Which seems to work so far.
-The limbo thing is beyond my scope.
[Notes on behaviour: when using the loop it only results in unnecessary stripping (i.e. it removes handslot & worn first and “limbo” item last). With [
rm_mult_objs_from_inven] it results in removing only a single item again (i.e. it can't find an item in inventory). Example, I can have 5 combat armour, put one on handslot, drop the other 4, pick them up again, deliver and only lose the one on handslot. However, using the loop can fix this.]
Should this be fixed yes/no?
I'm not really sure... [
rm_mult_objs_from_inven] allows to transfer items from one NPC to another w/o wiping their equipped gear. Which could be useful. [Of course if wanting to move all it would need a workaround then...]
However, regarding the dude I can't think of a case where the equipment should be untouched. In most cases that results in buggy behaviour (like the old "dropping items from barter" trick).
A technical issue is that hiding items on handslot & worn has a range of X + 3. Example; I need to deliver 5 Combat Armours. I can put 2 in inventory, one on each handslot and wear the 5th.
That said, maybe [
rm_mult_objs_from_inven] could get an extension of:
if dude then, if items on dude => qty and < qty +3 then, loop to remove items one by one... not sure if this makes sense (or just loop always?), but in theory that would not create wrong behaviour i.e. strip the player unnecessarily [unless there is a limbo item].
Idk, may be a starting point.
Personally, I'm not sure yet, I don't think LH (for example) should replace any check with the loop, I'd rather have sfall fix that. But for WM2 I may consider to use it, as I like that the mod works w/o sfall and I'd like to maintain that (if possible), but it would mean to rebuild every single request script.
Anyway, [summary]
-[
rm_mult_objs_from_inven] not removing armor & weapons correctly, script error. [i.e. use correct unwield and/or the correct [
rm_obj_from_inven].]
-[
rm_mult_objs_from_inven] not touching equipped gear, engine error. (esp. for the dude) [loop can fix it]
-Unable to find items in limbo (Object Pointer?), engine error, probably. (allows to reduce any "hand in" quest to a single item if it runs [
rm_mult_objs_from_inven] w/o loop fix.)
The easiest to confirm this is w/ AcMorlis, should work in 1.02d and RP 2.3.3.
Using 1.02d has the benefit of toggling sfall. Almost anything else nowadays stops working the moment you disable sfall.
That's all. The tests on the last day had become very consistent and predictable. So, I think I'm done with this... then again... idk, there is always something.