Page 1 of 1

Item Specific Container

Posted: Fri Mar 27, 2015 10:58 pm
by EnochDagor
I was thinking a neat item might be a container for a specific type of item.

For example, an herb satchel.

So, I created the item from a base_item. Here's my container definition where I was trying the theory in general... basically, if I can get the item to remove itself and reattach to the mouse, I want to do that... then I can do it by type.

Code: Select all

	{
		class = "ContainerItem",
		containerType = "chest",
		onInsertItem = function(self, item, slot)
			local theObj = self:getItem(slot)
			if theObj ~= nil then
				self:removeItemFromSlot(slot) 
				setMouseItem(item)
			end
			return false
		end 
	},
This code works but the mouse item does not get set. Well, that's not entirely accurate. The Mouse Item gets set while I'm in scope of the function (if I do a getMouseItem and print the ID its the correct ID). But once the scope is left, I lose the item.

Any ideas on what I am doing wrong?

Re: Item Specific Container

Posted: Sun Mar 29, 2015 2:48 pm
by MrChoke
You need to call setMouseItem() in a delayedCall and it should work.

Replace setMouseItem with something like:

Code: Select all

delayedCall("script_entity_01", 0.1, "giveMouseItem", item.go.id)
In a script entity with id of "script_entity_01", define this function:

Code: Select all

function giveMouseItem(itemId)
    local itemGO = findEntity(itemId)
    setMouseItem(itemGO.item)
end

Re: Item Specific Container

Posted: Sun Apr 12, 2015 12:33 am
by Dunkler
Did you guys ever suceed in this script?

I tried to create a Spellbook item that can only fit "SpellScrollItem" but i failed :)

When i try to put an item into the Spellbook it just vanishes. Im probably just too bad at scripting though :)

Re: Item Specific Container

Posted: Mon Apr 20, 2015 2:35 am
by EnochDagor
Unfortunately, no. I tried to do the delay but it still did not work 100% (and actually lead to a nasty bug where items insta-charged which I saved for later use).

Instead, I simply allowed it for my current scenario and put an OOC to not mess with the item. I will go back at some point and try again when I get time.

-E

Re: Item Specific Container

Posted: Mon Apr 20, 2015 8:05 am
by Dunkler
Thanks for the reply :)

At least i know that i dont have to bother with the "spellbook" anymore. I am using another Spell scroll learn script now anyway..so no spellbook needed :)

Re: Item Specific Container

Posted: Sat May 30, 2015 12:38 am
by Zo Kath Ra
Put a script entity called "script_entity_1" in your mod, and put this code in it:

Code: Select all

function giveMouseItem(item_id, altar_id)
	local item_local = findEntity(item_id)
	local altar_local = findEntity(altar_id)
	
	if ((item_local ~= nil) and (altar_local ~= nil)) then
		setMouseItem(item_local.item)
		altar_local:destroy()
	end
end
This bag only accepts keys:

Code: Select all

defineObject{
    name = "key_bag",
    baseObject = "base_item",
    components = {
        {
            class = "Model",
            model = "assets/models/items/sack_empty.fbx",
        },
        
        {
            class = "Item",
            uiName = "Key Bag",
            gfxIndex = 82,
            gfxIndexContainer = 482,
            weight = 0.4,
            fitContainer = false,
        },
        
        {
            class = "ContainerItem",
            containerType = "sack",
            openSound = "container_sack_open",
            closeSound = "container_sack_close",
            
            onInit = function(self)
                if self:getItemCount() > 0 then
                    self.go.model:setModel("assets/models/items/sack_full.fbx")
                    self.go.item:setGfxIndex(81)
                    self.go.item:updateBoundingBox()
                end
            end,
            
            onInsertItem = function(self, item, slot)
                if (item:hasTrait("key")) then
                    self.go.data:set("item_id", nil)
                    self.go.data:set("altar_id", nil)
                    
                    -- convert to full sack
                    if self.go.item:getGfxIndex() == 82 then
                    self.go.model:setModel("assets/models/items/sack_full.fbx")
                    self.go.item:setGfxIndex(81)
                        self.go.item:updateBoundingBox()
                    end
                else
                    hudPrint("This bag only accepts keys!")
                    
                    self.go.data:set("item_id", item.go.id)
                    
                    local altar_local = spawn("altar", party.level, party.x, party.y, party.facing, party.elevation)
                    self.go.data:set("altar_id", altar_local.id)
                    altar_local.surface:addItem(item)
                    
                    self:removeItemFromSlot(slot)
                    
                    if (getMouseItem() ~= nil) then
                        if (getMouseItem().go.id ~= item.go.id) then
                            self:insertItem(slot, getMouseItem())
                        end
                    end
                end
            end,
            
            onRemoveItem = function(self, item)
                if ((self.go.data:get("item_id") ~= nil) and (self.go.data:get("altar_id") ~= nil)) then
                    delayedCall("script_entity_1", 0, "giveMouseItem", self.go.data:get("item_id"), self.go.data:get("altar_id"))
                    self.go.data:set("item_id", nil)
                    self.go.data:set("altar_id", nil)
                end
                
                -- convert to empty sack when last item is removed
                if self:getItemCount() == 0 and self.go.item:getGfxIndex() == 81 then
                    self.go.model:setModel("assets/models/items/sack_empty.fbx")
                    self.go.item:setGfxIndex(82)
                    self.go.item:updateBoundingBox()
                end
            end,
        },
        
        {
            class = "Script",
            name = "data",
            source = [[
                data = { ["item_id"] = nil, ["altar_id"] = nil }
                
                get = function(self, name)
                return self.data[name]
                end
                
                set = function(self, name, value)
                self.data[name] = value
                end
            ]],
        }
    },
}
Based on viewtopic.php?f=22&t=8464&p=93490#p93489

Re: Item Specific Container

Posted: Sun May 31, 2015 8:43 am
by Zo Kath Ra
Simpler version of the bag code:

Code: Select all

defineObject{
    name = "key_bag",
    baseObject = "base_item",
    components = {
        {
            class = "Model",
            model = "assets/models/items/sack_empty.fbx",
        },
        
        {
            class = "Item",
            uiName = "Key Bag",
            gfxIndex = 82,
            gfxIndexContainer = 482,
            weight = 0.4,
            fitContainer = false,
        },
        
        {
            class = "ContainerItem",
            containerType = "sack",
            openSound = "container_sack_open",
            closeSound = "container_sack_close",
            
            onInit = function(self)
                if self:getItemCount() > 0 then
                    self.go.model:setModel("assets/models/items/sack_full.fbx")
                    self.go.item:setGfxIndex(81)
                    self.go.item:updateBoundingBox()
                end
            end,
            
            onInsertItem = function(self, item, slot)
                if (item:hasTrait("key")) then
                    -- convert to full sack
                    if self.go.item:getGfxIndex() == 82 then
                    self.go.model:setModel("assets/models/items/sack_full.fbx")
                    self.go.item:setGfxIndex(81)
                        self.go.item:updateBoundingBox()
                    end
                else
                    hudPrint("This bag only accepts keys!")
                    
                    local altar_local = spawn("altar", party.level, party.x, party.y, party.facing, party.elevation)
                    altar_local.surface:addItem(item)
                    
                    self:removeItemFromSlot(slot)
                    
                    delayedCall("script_entity_1", 0, "giveMouseItem", item.go.id, altar_local.id)
                    
                    if (getMouseItem() ~= nil) then
                        if (getMouseItem().go.id ~= item.go.id) then
                            self:insertItem(slot, getMouseItem())
                        end
                    end
                end
            end,
            
            onRemoveItem = function(self, item)
                -- convert to empty sack when last item is removed
                if self:getItemCount() == 0 and self.go.item:getGfxIndex() == 81 then
                    self.go.model:setModel("assets/models/items/sack_empty.fbx")
                    self.go.item:setGfxIndex(82)
                    self.go.item:updateBoundingBox()
                end
            end,
        },
    },
}

Re: Item Specific Container

Posted: Mon Jun 01, 2015 1:26 am
by Eleven Warrior
Zo would you be able to create a new (Mortar) eg: The dm_tool_box from Germmany. When you put items in the Tool Box you can make things like a Torch, hammer etc... It will need to have a recipe function like the mortar though. Ok if you can give me a pm please. This would be super awesome for everyone thxs :)