[Solved!] Want to make a chest openable with a key

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
MrChoke
Posts: 324
Joined: Sat Oct 25, 2014 7:20 pm

Re: Want to make a chest openable with a key

Post by MrChoke »

JKos, you found the key (pun intended)! It is in "setMouseItem(nil)". You make the hard-coded clickable action not have anything to open! Its brilliant.

I modified it a bit and made use of delayedCall(). So now instead of dropping the lock picks on the ground, delayedCall will give them back to you in 0.2 seconds.
I also added a line to get your key back if you want to have it given back.

It works perfect. I am marking this solved.

One last comment is how the normal chest comes with a component called "lock". This is named very poorly. This is not a LockComponet. It's the lock model, "treasure_chest_lock.model". We should have never been touching this to solve the problem. Oh well, we know now.

Thanks everyone for your help. Final (UPDATED 12/21) code:

In objects.lua:

Code: Select all

defineObject{
   name = "chest_keylocked",
   baseObject = "chest",
   components = {   		
   		{
    		class = "Lock",
           	name = "keyLock"        
      	},
      	{
      		class = "Clickable",
      		offset = vec(0,0.5,0),
			size = vec(1.5, 1.0, 1.0),
			maxDistance = 1,			
			onClick = function(self)			
				if not self.go.chest:getLocked() then
					if self.go:getComponent("keyLock") then				
						self.go:removeComponent("keyLock")
					end
					return true
				else
					local used_item = getMouseItem()
					if not self.go.chest:getLocked() then 
						return false
					end
					if used_item == nil then 
						return false
					end

					local stackSize = used_item:getStackSize()
					if used_item.go.name == 'lock_pick' then          			         
						setMouseItem(nil)
						playSound("lock_incorrect")		
						hudPrint("This chest requires a key and cannot be picked.")
						delayedCall("chest_scr", 0.2, "delayedGiveLockPick", used_item.go.name, stackSize)
						return false
					elseif not used_item.go.item:hasTrait("key") then
						hudPrint("You must open the chest with a key.")
						return false
					elseif self.go.keyLock:getOpenedBy() == used_item.go.name then
						self.go.chest:setLocked(false)
						setMouseItem(nil)
						self.go.lock:disable()
						playSound("key_lock")
						self.go:removeComponent("keyLock")

						-- If you don't want the key back, remove the line below
						delayedCall("chest_scr", 0.2, "delayedGiveLockPick", used_item.go.name)        		   			
						return true
					else
						hudPrint("Not the right key.")
						playSound("key_lock_faint")
						return false
					end   
				end
      		end
      		
      	},       
   },
}
Then in a script of your choice. I called mine "chest_scr", add this function:

Code: Select all

function delayedGiveLockPick(itemName, stackSize)
	local lockpick = spawn(itemName,party.level,party.x,party.y,party.elevation)
	if stackSize then
		lockpick.item:setStackSize(stackSize)	
	end
	setMouseItem(lockpick.item)
end
Last edited by MrChoke on Sun Dec 21, 2014 4:10 pm, edited 1 time in total.
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: [Solved!] Want to make a chest openable with a key

Post by akroma222 »

Geez! Just spent 3 hours messing around with all^^ the same problems!
That will teach me not to do forum searches first :roll:
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: Want to make a chest openable with a key

Post by Drakkan »

MrChoke wrote:JKos, you found the key (pun intended)! It is in "setMouseItem(nil)". You make the hard-coded clickable action not have anything to open! Its brilliant.

I modified it a bit and made use of delayedCall(). So now instead of dropping the lock picks on the ground, delayedCall will give them back to you in 0.2 seconds.
I also added a line to get your key back if you want to have it given back.

It works perfect. I am marking this solved.

One last comment is how the normal chest comes with a component called "lock". This is named very poorly. This is not a LockComponet. It's the lock model, "treasure_chest_lock.model". We should have never been touching this to solve the problem. Oh well, we know now.

Thanks everyone for your help. Final code:

In objects.lua:

Code: Select all

defineObject{
   name = "chest_keylocked",
   baseObject = "chest",
   components = {    
   		{
    		class = "Lock",
           	name = "keyLock"        
      	},      
      	{
      		class = "Clickable",
      		maxDistance = 1,      
      		size = vec(1.5, 1.0, 1.0, 0),
      		offset = vec(0, 0.5, 0, 0),
			onClick = function(self)
        		local used_item = getMouseItem()
		        if not self.go.chest:getLocked() then 
		        	return false
		        end
      			if used_item == nil then 
      				return false
      			end
      			
      			local stackSize = used_item:getStackSize()
      			if used_item.go.name == 'lock_pick' then          			         
					setMouseItem(nil)
         			playSound("lock_incorrect")		
         			hudPrint("This chest requires a key and cannot be picked.")
         			delayedCall("chest_scr", 0.2, "delayedGiveLockPick", used_item.go.name, stackSize)
         			return false
      			elseif not used_item.go.item:hasTrait("key") then
         			hudPrint("You must open the chest with a key.")
			      	return false
      			elseif self.go.keyLock:getOpenedBy() == used_item.go.name then
        			self.go.chest:setLocked(false)
			        setMouseItem(nil)
        			self.go.lock:disable()
        			playSound("key_lock")
        			
        			-- If you don't want the key back, remove the line below
        			delayedCall("chest_scr", 0.2, "delayedGiveLockPick", used_item.go.name)        		   			
			        return true
			 	else
			        hudPrint("Not the right key.")
			        playSound("key_lock_faint")
			        return false
      			end      
      		end
      	},      	
   },
}
Then in a script of your choice. I called mine "chest_scr", add this function:

Code: Select all

function delayedGiveLockPick(itemName, stackSize)
	local lockpick = spawn(itemName,party.level,party.x,party.y,party.elevation)
	if stackSize then
		lockpick.item:setStackSize(stackSize)	
	end
	setMouseItem(lockpick.item)
end
thanks for this. not sure if it is my fault or any other bug, but I cannot take any item from such a locked chest - I could place items inside, but cannot just "click" on any inside. any ideas what is wrong ?
Breath from the unpromising waters.
Eye of the Atlantis
MrChoke
Posts: 324
Joined: Sat Oct 25, 2014 7:20 pm

Re: Want to make a chest openable with a key

Post by MrChoke »

Drakkan wrote:
thanks for this. not sure if it is my fault or any other bug, but I cannot take any item from such a locked chest - I could place items inside, but cannot just "click" on any inside. any ideas what is wrong ?
Good catch Drakkan. Yes it was bugged. TBH, I have not used this yet in my real dungeon (only my test one) so I never put an object in it. The code is now fixed and below. I am also updating the first post. Apparently the lock component must be removed for the surface component to work.

Code: Select all

defineObject{
   name = "chest_keylocked",
   baseObject = "chest",
   components = {   		
   		{
    		class = "Lock",
           	name = "keyLock"        
      	},
      	{
      		class = "Clickable",
      		offset = vec(0,0.5,0),
			size = vec(1.5, 1.0, 1.0),
			maxDistance = 1,			
			onClick = function(self)			
				if not self.go.chest:getLocked() then
					if self.go:getComponent("keyLock") then				
						self.go:removeComponent("keyLock")
					end
					return true
				else
					local used_item = getMouseItem()
					if not self.go.chest:getLocked() then 
						return false
					end
					if used_item == nil then 
						return false
					end

					local stackSize = used_item:getStackSize()
					if used_item.go.name == 'lock_pick' then          			         
						setMouseItem(nil)
						playSound("lock_incorrect")		
						hudPrint("This chest requires a key and cannot be picked.")
						delayedCall("chest_scr", 0.2, "delayedGiveLockPick", used_item.go.name, stackSize)
						return false
					elseif not used_item.go.item:hasTrait("key") then
						hudPrint("You must open the chest with a key.")
						return false
					elseif self.go.keyLock:getOpenedBy() == used_item.go.name then
						self.go.chest:setLocked(false)
						setMouseItem(nil)
						self.go.lock:disable()
						playSound("key_lock")
						self.go:removeComponent("keyLock")

						-- If you don't want the key back, remove the line below
						delayedCall("chest_scr", 0.2, "delayedGiveLockPick", used_item.go.name)        		   			
						return true
					else
						hudPrint("Not the right key.")
						playSound("key_lock_faint")
						return false
					end   
				end
      		end
      		
      	},       
   },
}

User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: Want to make a chest openable with a key

Post by Drakkan »

cool working now ! thanks
just minor request- I´d like if chest is opened with correct key, that key to be used (destroyed). I see you can set this for lockpick but I am not sure which part of script to change for this. thanks for answer
Breath from the unpromising waters.
Eye of the Atlantis
MrChoke
Posts: 324
Joined: Sat Oct 25, 2014 7:20 pm

Re: Want to make a chest openable with a key

Post by MrChoke »

Drakkan wrote:cool working now ! thanks
just minor request- I´d like if chest is opened with correct key, that key to be used (destroyed). I see you can set this for lockpick but I am not sure which part of script to change for this. thanks for answer
I have these lines of code in there. Just comment out or remove the "delayedCall" to keep the key destroyed. By default the game destroys the key. I had do a delayed call to bring it back.

Code: Select all

-- If you don't want the key back, remove the line below
delayedCall("chest_scr", 0.2, "delayedGiveLockPick", used_item.go.name)    
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: Want to make a chest openable with a key

Post by Drakkan »

MrChoke wrote:
Drakkan wrote:cool working now ! thanks
just minor request- I´d like if chest is opened with correct key, that key to be used (destroyed). I see you can set this for lockpick but I am not sure which part of script to change for this. thanks for answer
I have these lines of code in there. Just comment out or remove the "delayedCall" to keep the key destroyed. By default the game destroys the key. I had do a delayed call to bring it back.

Code: Select all

-- If you don't want the key back, remove the line below
delayedCall("chest_scr", 0.2, "delayedGiveLockPick", used_item.go.name)    
ah my stupidity I thought this is the part for lockpick. thanks
Breath from the unpromising waters.
Eye of the Atlantis
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: [Solved!] Want to make a chest openable with a key

Post by akroma222 »

Hey folks
Just posted a separate thread for a system using a locks and traps skill, (your) keylocked chests, picklock chests and chest traps
Without your help here I would never have come up with it, thanks!!!! :D
viewtopic.php?f=22&t=9046&p=88551#p88551
Post Reply