Page 1 of 1

Remove Item from Sack and WoodenBox

Posted: Thu Apr 25, 2013 10:47 pm
by Damonya
All in the title. I search on the forum and I don't know if pettri finished with his todo list ^^ viewtopic.php?f=14&t=4395

This is my script for destroy 4 item from inventory.

Code: Select all

function removeItmGem()

local itmgem = false
local gemmeitem = {"itm_gem_blue_01","itm_gem_red_01","itm_gem_yellow_01","itm_gem_green_01"}
	 
for i=1,4 do
for v=1,31 do
for t = 1, #gemmeitem do
if (party:getChampion(i):getItem(v) ~= nil) and (party:getChampion(i):getItem(v).name == gemmeitem[t]) then
party:getChampion(i):removeItem(v)								
itmgem = true
end
end
end
end   
return itmgem
end
But if the item is in a sack or a wooden box ? I don't know how destroy.

sack_id:removeItem(v) don't work. (otherwise I prefer with the sack.name to sack.id)

Re: Remove Item from Sack and WoodenBox

Posted: Thu Apr 25, 2013 11:01 pm
by JohnWordsworth
I'm not 100% sure, but I've got a feeling this was fixed (I think the problem was just that the 'removeItem' method didn't exist, and now it does), but I might be mistaken. Assuming it does work, then you just need to test whether an item is a container, and if it is - iterate over that container for items.

Perhaps something like the following;
SpoilerShow

Code: Select all

function isStringInList(aString, aList) 
  for i=1, #aList do
    if ( aList[i] == aString ) then
      return true;
    end
  end

  return false;
end

function removeItmGem()
  local itmgem = false
  local gemmeitem = {"itm_gem_blue_01","itm_gem_red_01","itm_gem_yellow_01","itm_gem_green_01"}
    
  for champIdx=1,4 do
    for slotIdx=1,31 do
      local item = party:getChampion(champIdx):getItem(slotIdx);

      if ( item ~= nil ) and ( item:containedItems() ~= nil ) then
        for i=1,16 do
          local subItem = item:getItem(i);

          if ( subItem ~= nil ) and ( isStringInList(subItem.name, gemmeitem) ) then
            item:removeItem(i);
            itmgem = true;
          end
        end
      elseif ( item ~= nil ) and ( isStringInList(item.name, gemmeitem) ) then
        party:getChampion(i):removeItem(slotIdx);
        itmgem = true;
      end
    end
  end

  return itmgem;
end
You might be able to use the item:containedItems() iterator instead of blindly iterating over 1-16 possible slots on a container, but I don't know if you can extract the slot index from the containedItems iterator, so then you wouldn't be able to actually remove that item (as the remove item method requires a slot index).

This is untested and just bashed out while at work - so it might not work out of the box - but this is the sort of thing I would look at doing.

Re: Remove Item from Sack and WoodenBox

Posted: Thu Apr 25, 2013 11:10 pm
by Damonya
Ok thank you I will test it tomorrow ;)

It is in any case, in fact more complicated than I thought it would.

Re: Remove Item from Sack and WoodenBox

Posted: Fri Apr 26, 2013 9:18 am
by Damonya
Tested and approved. Your code is perfect.

Image

Just a very small mistake here:

Code: Select all

function isStringInList(aString, aList)
  for i=1, #list do
    if ( aList[i] == aString ) then
      return true;
    end
  end

  return false;
end
change #list by #aList

Re: Remove Item from Sack and WoodenBox

Posted: Fri Apr 26, 2013 6:41 pm
by JohnWordsworth
Great to hear that it works! I will edit my original post so that if anyone else finds this useful they can just copy and paste it in :).

Hope your mod is coming along well.

Re: Remove Item from Sack and WoodenBox

Posted: Sun May 05, 2013 12:07 pm
by akroma222
Hi John & Damonya,

I have a quick question, seems like this is a relevant thread ;)
I have a spell which spawns a staff weapon in front of the party (floating alcove) and then the staff is destroyed after a period of time (it is a late game power weapon). So, I have adapted (one of) the scripts designed to look through sacks, boxes, mortars etc to find the "item" so we can destroy it.

Here is a cut down version of the destroy staff function that is called when the timer runs out (activates):
SpoilerShow

Code: Select all


function destroyStave()
  	
        local n = "guardian_stave"
	for i in allEntities(party.level) do
		if i and i.name == n then
			i:destroy()
			if findEntity("guardiantimer") ~= nil then
				findEntity("guardiantimer"):destroy()
				return true
			end
		end
	end
	for i = 1, 4 do
	for j = 1, 31 do
        local item = party:getChampion(i):getItem(j)
        if item then
            if item.name == "sack" or 
            item.name == "mortar" or 
            item.name == "wooden_box" or
	    item.name == "treasure_chest" then
                  for s = 1,16 do
	          for m = 1,16 do

	          for x in item:containedItems() do
                        if x then
                               if x.name == "mortar" then
				     for y in x:containedItems() do
                                           if y then 
						if y.name == n then 
							item:getItem(s):removeItem(m) 
							if findEntity("guardiantimer") ~= nil then
								findEntity("guardiantimer"):destroy()
								return true 
							end
						  end
					   end
                                      end 
				 end
		           end
                           if x.name == n then 
				item:removeItem(s) 
				if findEntity("guardiantimer") ~= nil then
				       findEntity("guardiantimer"):destroy()
					return true 
				end
		          end
         	    end 
	       end 
            end
         end
         if item.name == n then 
		party:getChampion(i):removeItem(j)
		if findEntity("guardiantimer") ~= nil then
			findEntity("guardiantimer"):destroy()
			return true 
			end
		   end
  	     end 
       end 
    end
end
Again, this is adapted from a oldish but working script that actually used the itemFound = true/false method that you used in your script^^ John (which by the way I have copied and will experiment with soon - thank you!)

My question here is - Why am I cycling through 1,16 container slots? Where does the 16 come from? Sacks and mortars are 6 and the wooden box is 10 (the custom treasure chest is also 10)... Curious because the function will find and destroy that staff quite effectively - but NOT when the staff is in a wooden box or treasure chest :?

This has me stumped unfortunately :cry: .... any guidance here??
(p.s. if you want me to post the spell up I am happy to.. just didn't want to dump a whole heap of code and expect people to wade through it ;) )

Re: Remove Item from Sack and WoodenBox

Posted: Sun May 05, 2013 6:06 pm
by Xanathar
Hi Akroma,
I worked quite hard on that.
If you dare :) you can try this:

1) put either jkos framework or grimq in your dungeon
2) add this lines:

Code: Select all

local ex = grimq.findEx("mythingie_id")

if (ex ~= nil) then
	ex:destroy()
end
This should cover every possibile case (ground, alcoves, inventory, containers, etc.).. hopefully. or at least, I couldn't find a case where it doesn't work, but surely you will :oops:

Re: Remove Item from Sack and WoodenBox

Posted: Wed May 15, 2013 7:56 am
by akroma222
Hey Xanathar!

I actually was going to try some of the code from this thread:
viewtopic.php?f=14&t=5217

(which involved you, Grimfam, Marble Mouth and Diarmuid)

I have not yet had the chance to try it though (will the code Marble Mouth created do the job?)
Otherwise I will add Jkos Framework / Grimq and give your code a shot :D

Thanks v much :D
Akroma