10 alcoves with 5 different items unlocking a set of doors

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
Post Reply
Treybor
Posts: 93
Joined: Wed Jun 06, 2012 3:13 am

10 alcoves with 5 different items unlocking a set of doors

Post by Treybor »

I ran into an issue with one of my scripts. Ten alcoves must be fillled with items to open a set of doors.
The alcoves are paired so they must have identical items before their matched door opens.
The first combination of two filled alcoves works correctly, but each following alcove pair opens the next door with only one alcove filled.
Any ideas? I know there has to be an easier way to do this.

Code: Select all

-- run this script _once for each item_ with a matching name
function check1()
   -- change these variables to match your alcove's ID and the item you want to test for
   local itemName = "XXXXXX"
   local alcoveID01 = alcove_1
   local alcoveID02 = alcove_2

   -- iterate through all the contained items on alcove, checking for a matching name
   for i in alcoveID01:containedItems() and alcoveID02:containedItems() do
      if i.name == itemName then
         itemFound1()
      else
         itemNotFound1()
      end
   end
end

-- run this script _once for each item_ with a matching name
function itemFound1()
   door1:open()
end

-- run this script _once for each item_ without a matching name
function itemNotFound1()
   door1:close()
   spawn("poison_cloud", party.level, party.x, party.y, 0)
end


-- run this script _once for each item_ with a matching name
function check2()
   -- change these variables to match your alcove's ID and the item you want to test for
   local itemName = "XXXXXX"
   local alcoveID03 = alcove_3
   local alcoveID04 = alcove_4

   -- iterate through all the contained items on alcove, checking for a matching name
   for i in alcoveID03:containedItems() and alcoveID04:containedItems() do
      if i.name == itemName then
         itemFound2()
      else
         itemNotFound2()
      end
   end
end

-- run this script _once for each item_ with a matching name
function itemFound2()
   door2:open()
end

-- run this script _once for each item_ without a matching name
function itemNotFound2()
   door2:close()
   spawn("poison_cloud", party.level, party.x, party.y, 0)
end


-- run this script _once for each item_ with a matching name
function check3()
   -- change these variables to match your alcove's ID and the item you want to test for
   local itemName = "XXXXXX"
   local alcoveID05 = alcove_5
   local alcoveID06 = alcove_6

   -- iterate through all the contained items on alcove, checking for a matching name
   for i in alcoveID05:containedItems() and alcoveID06:containedItems() do
      if i.name == itemName then
         itemFound3()
      else
         itemNotFound3()
      end
   end
end

-- run this script _once for each item_ with a matching name
function itemFound3()
   door3:open()
end

-- run this script _once for each item_ without a matching name
function itemNotFound3()
   door3:close()
   spawn("poison_cloud", party.level, party.x, party.y, 0)
end



-- run this script _once for each item_ with a matching name
function check4()
   -- change these variables to match your alcove's ID and the item you want to test for
   local itemName = "XXXXXX"
   local alcoveID07 = alcove_7
   local alcoveID08 = alcove_8

   -- iterate through all the contained items on alcove, checking for a matching name
   for i in alcoveID07:containedItems() and alcoveID08:containedItems() do
      if i.name == itemName then
         itemFound4()
      else
         itemNotFound4()
      end
   end
end

-- run this script _once for each item_ with a matching name
function itemFound4()
   door4:open()
end

-- run this script _once for each item_ without a matching name
function itemNotFound4()
   door4:close()
   spawn("poison_cloud", party.level, party.x, party.y, 0)
end



-- run this script _once for each item_ with a matching name
function check5()
   -- change these variables to match your alcove's ID and the item you want to test for
   local itemName = "XXXXXX"
   local alcoveID09 = alcove_9
   local alcoveID10 = alcove_10

   -- iterate through all the contained items on alcove, checking for a matching name
   for i in alcoveID09:containedItems() and alcoveID10:containedItems() do
      if i.name == itemName then
         itemFound5()
      else
         itemNotFound5()
      end
   end
end

-- run this script _once for each item_ with a matching name
function itemFound5()
   door5:open()
end

-- run this script _once for each item_ without a matching name
function itemNotFound5()
   door5:close()
   spawn("poison_cloud", party.level, party.x, party.y, 0)
end
Marble Mouth
Posts: 52
Joined: Sun Feb 10, 2013 12:46 am
Location: Dorchester, MA, USA

Re: 10 alcoves with 5 different items unlocking a set of doo

Post by Marble Mouth »

Hi Treybor. I see a couple issues here. First, this is not a good way to use iterators:

Code: Select all

for i in alcoveID01:containedItems() and alcoveID02:containedItems() do
Without getting into all of the lua nitty-gritty, this won't do what you want. You're going to have to write two different for loops, one for each iterator:

Code: Select all

for i in alcoveID01:containedItems() do
--stuff
end
for i in alcoveID02:containedItems() do
--stuff
end
Second, the way you have your script setup, it will close the door and spawn a poison cloud once for each item that doesn't match itemName. Maybe you wanted multiple poison clouds, I don't know, but you definitely don't need to close the door repeatedly. I'll assume that you want the door to open only when each alcove has the correct item and nothing else, and you want to spawn a poison cloud and to close the door in any other case. So if either alcove is missing its proper item, or has any extra item then the door is shut and poison spawns. Note that this would spawn a poison cloud when the player put the first item into the first alcove, assuming all alcoves start empty. I'm making a lot of assumptions here, please correct me if any of these details are incorrect.

Third, you can reuse a lot of code, since you are doing five very similar things. Code reuse is your friend.

Try this:

Code: Select all

function check1()
	-- change these arguments to match your alcove's ID
	-- and the item you want to test for
	check( "shuriken" , alcove_1 , alcove_2 , door_1 )
end

function check2()
	-- change these arguments to match your alcove's ID
	-- and the item you want to test for
	check( "torch" , alcove_3 , alcove_4 , door_2 )
end

function check3()
	-- change these arguments to match your alcove's ID
	-- and the item you want to test for
	check( "arrow" , alcove_5 , alcove_6 , door_3 )
end

function check4()
	-- change these arguments to match your alcove's ID
	-- and the item you want to test for
	check( "blue_gem" , alcove_7 , alcove_8 , door_4 )
end

function check5()
	-- change these arguments to match your alcove's ID
	-- and the item you want to test for
	check( "brass_key" , alcove_9 , alcove_10 , door_5 )
end

function check( itemName , alcoveID1 , alcoveID2 , door )
	local foundAlcove1 , foundAlcove2
	
	-- iterate through all the contained items on first alcove,
	-- checking for a matching name
	for i in alcoveID1:containedItems() do
      if i.name == itemName then
         foundAlcove1 = true
      else
         fail( door )
         return
      end
   end

	-- iterate through all the contained items on second alcove,
	-- checking for a matching name
	for i in alcoveID2:containedItems() do
      if i.name == itemName then
         foundAlcove2 = true
      else
         fail( door )
         return
      end
   end

	if foundAlcove1 and foundAlcove2 then
		door:open()
	else
		fail( door )
	end
end

function fail( door )
	door:close()
	spawn("poison_cloud", party.level, party.x, party.y, 0)
end
I setup my alcoves with Activate Always checked and a single connector: Event = any , Target = script_entity_1 , Action depends on which pair this alcove belongs to. This will rerun the check any time an item is placed into or removed from the alcove. Please let me know if this works for you or not. Also, if this isn't quite what you wanted, please clarify. Hope this helps :)
Treybor
Posts: 93
Joined: Wed Jun 06, 2012 3:13 am

Re: 10 alcoves with 5 different items unlocking a set of doo

Post by Treybor »

Thanks. That makes more sense. I'll give it a try.
Post Reply