Jump to content


Photo

FillSlot()


  • Please log in to reply
11 replies to this topic

#1 temnix

temnix
  • Member
  • 983 posts

Posted 18 August 2017 - 04:37 AM

This action is broken. Here is how the G3 guide advertises it:

 

"This action will attempt to fill a slot in the active creature's inventory with the appropriate item type. Using FillSlot(SLOT_WEAPON) will look for any weapon in the inventory, and move the first such item into the weapon slot. Any item already in the slot is destroyed."

 

Actually, the action will search for weapons, move the first in the slot, then move the next one in the slot, destroying the first, and keep looking and thrusting weapons in that slot until the very last one. It will consume a whole backpack's worth of weapons, and it's the same way with other slots. What's worse, SLOT_SHIELD also accepts one-handed weapons, so the action will shove weaponry in there, too, as it pages forward to the last suitable item. Basically FillSlot() is only good when there is only one item of the corresponding type in the inventory - one weapon, one shield (in that order), one helmet...


Edited by temnix, 18 August 2017 - 04:46 AM.


#2 The Imp

The Imp

    Not good, see EVIL is better. You'll LIVE.

  • Member
  • 5150 posts

Posted 18 August 2017 - 05:00 AM

Are you sure you didn't over commit to a stupidity, like for example, like having the trigger that launches multiple times ?


Yep, Jarno Mikkola. my Mega Mod FAQ. Use of the BWS, and how to use it(scroll down that post a bit). 
OK, desert dweller, welcome to the sanity, you are free to search for the limit, it's out there, we drew it in the sand. Ouh, actually it was still snow then.. but anyways.


#3 Argent77

Argent77
  • Administrator
  • 1397 posts

Posted 18 August 2017 - 05:17 AM

I can confirm that FillSlot() does some weird things. Aside from wasting inventory items it can also place invisible/unremovable items (e.g. Fist) into the inventory. That's why I would never use it on (potential) party members.



#4 jastey

jastey
  • Administrator
  • 3218 posts

Posted 18 August 2017 - 09:42 AM

Thanks for the heads up. Do you have a suggestion what I would use instead?



#5 Roxanne

Roxanne

    Modder

  • Member
  • 3564 posts

Posted 18 August 2017 - 10:00 AM

I can confirm that FillSlot() does some weird things. Aside from wasting inventory items it can also place invisible/unremovable items (e.g. Fist) into the inventory. That's why I would never use it on (potential) party members.

This may be misunderstood. FillSlot() can do what you describe if used by itself.

However a widely used feature is the use of FillSlot() with a preceding CreateItem() or TakePartyItem() in the same action block. In those cases the already selected item will be the one used to fill the designated slot (if it matches, no idea what happens when you try to put the wrong item into the wrong slot...). See the famous "create item for 1HP protection and fill amulet slot with it".

A side effect is that the item formerly in the slot will vanish, unless it is flagged as a plot item.


Edited by Roxanne, 18 August 2017 - 10:00 AM.

The Sandrah Saga

another piece of *buggy, cheesy, unbalanced junk*

 


#6 Argent77

Argent77
  • Administrator
  • 1397 posts

Posted 18 August 2017 - 10:11 AM

Correct. What I meant was that this script action has its use. But shouldn't be used on active party members since you have no control over their current inventory (unless you use DropInventory() beforehand). In the worst case you can destroy several valuable items in the process and/or replace them with unremovable items.
 



#7 jastey

jastey
  • Administrator
  • 3218 posts

Posted 18 August 2017 - 11:39 AM

I see. Thank you both very much.

#8 Argent77

Argent77
  • Administrator
  • 1397 posts

Posted 18 August 2017 - 01:25 PM

Btw, it looks like XEquipItem() could be used as a viable replacement for FillSlot() in many situations. It can be used to equip/unequip items without destroying anything.

Example 1: Equip Quarterstaff +3 (item must exist in inventory)

XEquipItem("STAF08", Myself, SLOT_WEAPON, EQUIP)

An already equipped weapon will be placed into the inventory.

Example 2: Unequip current weapon

XEquipItem("", Myself, SLOT_WEAPON, EQUIP)

For some reason UNEQUIP doesn't work, but using empty ITM resref does. Does nothing if there is no free inventory slot available.



#9 Roxanne

Roxanne

    Modder

  • Member
  • 3564 posts

Posted 18 August 2017 - 10:37 PM

Btw, it looks like XEquipItem() could be used as a viable replacement for FillSlot() in many situations. It can be used to equip/unequip items without destroying anything.

Example 1: Equip Quarterstaff +3 (item must exist in inventory)
XEquipItem("STAF08", Myself, SLOT_WEAPON, EQUIP)

An already equipped weapon will be placed into the inventory.

Example 2: Unequip current weapon

XEquipItem("", Myself, SLOT_WEAPON, EQUIP)

For some reason UNEQUIP doesn't work, but using empty ITM resref does. Does nothing if there is no free inventory slot available.

Did you ever see it working with anything else bur SLOT_WEAPON.?

I can confirm that with weapons it works like you describe, but I could never get it to work with shield or ring etc.


The Sandrah Saga

another piece of *buggy, cheesy, unbalanced junk*

 


#10 Argent77

Argent77
  • Administrator
  • 1397 posts

Posted 19 August 2017 - 12:37 AM

It works for every slot type, even quick slots and ammo slots.



#11 Roxanne

Roxanne

    Modder

  • Member
  • 3564 posts

Posted 19 August 2017 - 12:58 AM

It works for every slot type, even quick slots and ammo slots.

Thanks.

My issue must be elsewhere. Possibly in how the action checks for the item to be present in the inventory?

Like this scenario - An NPC has a personal item. If another party member *grabs* the item, the NPC is supposed to take it back and equip it. Part one of it works, part two not, i.e. the item is taken back but stays in the inventory unequipped (most of the time, randomly it works, even if conditions are not changed). I will try to break that into two script blocks and see if it works, currently I just use Wait(2) between the two actions.


Edited by Roxanne, 19 August 2017 - 12:59 AM.

The Sandrah Saga

another piece of *buggy, cheesy, unbalanced junk*

 


#12 temnix

temnix
  • Member
  • 983 posts

Posted 19 August 2017 - 04:56 AM

The problem with XEquipItem() and alternatives (there is one or two) is that they all require a definite item name. A strref. They are good for a scripted specific instance only. FillSlot() is the only action that is context-sensitive, it says "put whatever is appropriate in there." So, as I said, it's fine if there is only one suit of armor on a creature, one weapon and so on. I've used it successfully to get monsters to pick up equipment, from the ground, and put it on. It takes a combination of PickUpItem() and FillSlot(). Unfortunately, the former of these requires a strref, I dearly wish there was an action to pick up the nearest pile or an object of a type. But my purpose was to equip the monsters with items that are likely to be dropped, so I wrote in standard weapons, standard armors and so on.

 

You can script monsters directly, if they are custom-made, but I always like solutions that work on anyone. To get any monster to arm itself, create a spell that uses opcode 82, for give the monster a custom script, and insert it at the AREA script level (my old trick). Then either finish that script with ChangeAIScript("",AREA) or include another 82 opcode in the spell, delayed, setting the AREA script to a blank file. Either way the behavior will phase itself out. A delayed script change with 82, by the way, is a reliable way to pre-program a creature. It is true, you can give scripts to a creature with ChangeAIScript() and probably in other ways, but these commands get invoked either from within another script, as I just now suggested, or from ActionOverride(). If the launching script fails or the minion doing the overriding screws up, then the chain will be broken. A delayed 82 works if you leave the area and return, save and reload, and it is also unconditional - you do not have to look for a place to attach your script change to some other actions. In fact, it may be impossible in some cases. Let's say you have scripted a creature to go around healing people, but you want it to stop within six hours. What to do? Local timers don't work, and a global timer is no good if there are several such healers. But fix them with an 82 change to occur six hours later, and whenever each one starts making the rounds, he will change his mind and stop on time. If you return to the area a long time afterwards, then time will catch up with you on all delayed effects as you enter. So if one healer was just starting and another already coming to the end of his shift, and you left to come back a day later, both 82s will happen at once (or rather "will have happened" equally, by that point, strictly speaking). But this sort of thing, concurrence, is not a problem in practice.

 

I digress. Just wanted to lay that out. However you get the script onto a monster, you then write:

 

IF

True() /// There are no triggers for seeing stuff on the ground at all

PickUpItem("leat01") /// Basic leather

FillSlot(SLOT_ARMOR)

ChangeAIScript("",AREA)

 

END

 

This gets more difficult as you try to include more items that may be nearby, and there is no way to measure distance to the closest suit of leather, so the monster may cross the map in search of one, but I don't think impossible actions, when no one has dropped leathers, will break the rest of the sequence. More likely the monster will make do with what he can get his mitts on; but if you include a command to pick up a leather armor and, say, a chain mail, and both can be gotten, then the monster will pick up both, but only one will end up worn with FillSlot() - all other armors the monster grabs are going to get destroyed by that flawed action. Still, it is something to work with.


Edited by temnix, 19 August 2017 - 05:14 AM.