Page 1 of 1
Yet another alcove question!
Posted: Mon Sep 17, 2012 4:00 pm
by guigr
I'm having a puzzle where I want to have some items in an alcove in order to open a door. It works well using a code taken here but you can just remove the item and the door will stay open.
Code: Select all
function checkAlcoveForItems()
local itemName = "chitin_boots"
local alcoveID = dungeon_alcove_3
for i in alcoveID:containedItems() do
if i.name == itemName then
itemFound()
porte1:open()
end
end
end
So I tried to do a variation of this code activated by a pressure plate to check if the item was still is the alcove. But it doesn't work. Can someone help me here?
Code: Select all
function secondcheck()
local itemName = "chitin_boots"
local alcoveID = dungeon_alcove_3
for i in alcoveID:containedItems() do
if i.name == itemName then
porte1:open()
else
porte1:close()
end
end
end
Re: Yet another alcove question!
Posted: Mon Sep 17, 2012 4:10 pm
by antti
There's two possible pitfalls here that I can think of:
1) You need to add a connector for the alcove deactivation too (activation happens when items are added on the alcove and deactivation happens when the last item is removed from alcove, both activation and deactivation are needed in this case to cover all the possible cases)
2) The structure in the script probably does not work well for multiple items. For example if I first add the chitin boots to the alcove (the correct item), the door will open but then if I add another item after it, it would close again since the for loop would keep on running. To prevent it, I would add a break that will terminate the for-loop as soon as the correct item is found like so:
Code: Select all
function secondcheck()
local itemName = "chitin_boots"
local alcoveID = dungeon_alcove_3
for i in alcoveID:containedItems() do
if i.name == itemName then
porte1:open()
break
else
porte1:close()
end
end
end
For more information, check out this guide I just added on the modding documentation:
http://www.grimrock.net/modding/how-to- ... ve-puzzle/
Re: Yet another alcove question!
Posted: Mon Sep 17, 2012 4:35 pm
by guigr
Thanks it works now!
I understand that it was doing the check only if there was an item there (for example a torch). If there was no item it wouldn't close the door. So I've told the alcove to close the door on deactivate and it seems to work.
Re: Yet another alcove question!
Posted: Mon Sep 17, 2012 4:54 pm
by Lilltiger
Edited: Added the exclusive check option, that only opens when it's the exactly specified items and no others
Edited: Fixed the code, there where some flaws in it.
Or you could do it in a more generic and nifty way:
Code: Select all
function checkForItems()
-- You cant use the alcove and altars connections to trigger, as they do only activate for the first
-- item added, or when the last one is removed, so use a lever or a pressure plate
-- to activate the check instead
if( checkForContainedItem(dungeon_alcove_3, "chitin_boots") ) then
porte1:open()
else
porte1:close()
end
end
function checkForContainedItem(container, itemName)
for i in container:containedItems() do
if( i.name == itemName ) then
return true
end
end
return false
end
But this only checks for one item, so let's expand it to check for multiple items:
Code: Select all
function checkForItems()
-- You cant use the alcove and altars connections to trigger, as they do only activate for the first
-- item added, or when the last one is removed, so use a lever or a pressure plate
-- to activate the check instead
-- Let's make an table of the item names to check
-- Tables in LUA are a bit like array's in c, but still quite different, check the LUA docs
item_name_table = {"chitin_boots","dagger","torch"}
if( checkForContainedItem(dungeon_alcove_3, item_name_table, true ) ) then
porte1:open()
else
porte1:close()
end
end
function checkForContainedItem(container, itemNameTable, exclusive)
if( exclusive ) then
return checkForContainedItemExclusive(container, itemNameTable)
else
return checkForContainedItemUnExclusive(container, itemNameTable)
end
end
function checkForContainedItemUnExclusive(container, itemNameTable)
local items_found = 0
-- The outer loop needs to be the names,
-- else we will trigger the items_found count several times for the same name.
for id,names in ipairs(itemNameTable) do
for i in container:containedItems() do
if( i.name == names) then
-- If the item name and the item matches, add to the counter
items_found = items_found+1
-- Now we need to break out of this check to avoid triggering the same name twice
-- A break exits the current/inner loop, but the outer loop will continue
break
end
end
end
-- Now we check if we have found as many items as there are names in the table
if( items_found == table.getn( itemNameTable ) ) then
-- Return the value true, this also ends the function
return true
end
-- Return false in all other cases, no need for an else in the above "if" as the function end's as soon
-- it hit's a "return"
return false
end
function checkForContainedItemExclusive(container, itemNameTable)
items_found = 0
-- Here we use the container as outerloop as we will return false as soon we get a missmatch
for i in container:containedItems() do
name_check = false
for id,names in ipairs(itemNameTable) do
if( i.name == names) then
-- If the item name and the item matches, add to the counter, and set the name_check to true
items_found = items_found+1
name_check = true
-- Now we need to break out of this check to avoid triggering the same name twice
-- A break exits the current/inner loop, but the outer loop will continue
break
end
end
-- If name_check is false, then we found a item not named in our table, so return false
if( name_check == false ) then
return false
end
end
-- Now we check if we have found as many items as there are names in the table
-- This check wont pass if there are more of one item type then allowed.
if( items_found == table.getn( itemNameTable ) ) then
-- Return the value true, this also ends the function
return true
end
-- Return false in all other cases, no need for an else in the above "if" as the function end's as soon
-- it hit's a "return"
return false
end
And there we have it, this functions works for all container objects, so both Alcove and Altar.
The code is tested and works, after some fixes
Re: Yet another alcove question!
Posted: Mon Sep 17, 2012 7:57 pm
by guigr
Wow, did you read my mind? I wanted it to work with multiple items but was not sure if it was worth the trouble.
Thanks a lot!
Re: Yet another alcove question!
Posted: Mon Sep 17, 2012 8:06 pm
by petri
You cant use the alcove and altars connections to trigger, as they do only activate for the first item added, or when the last one is removed
Actually you can, just tick Activate Always in inspector.