Page 1 of 1
Pressure Plate Question
Posted: Thu Jan 24, 2013 6:46 am
by Ryeath_Greystalk
I figured out how to add connectors to pressure plates in a script entity, but wat I am hhoping for is a way to remove connectors in a script entity. Ideally a remove all connectors would be awesome. Anyone know if this is possible. What I am trying to do is use one pressure plate to control different doors depending on the posistion of some wall levers.
So far
Code: Select all
function SetPressurePlateTarget()
if NorthLever:getLeverState()=="deactivated" and
SouthLever:getLeverState()=="deactivated" then
VariablePlate1:addConnector("activate","NorthwestDoor","toggle")
else
if NorthLever:getLeverState()=="activated" and
SouthLever:getLeverState()=="activated" then
VariablePlate1:addConnector("activate","SoutheastDoor","toggle")
else
if NorthLever:getLeverState()=="deactivated" and
SouthLever:getLeverState()=="activated" then
VariablePlate1:addConnector("activate","NortheastDoor","toggle")
else
if NorthLever:getLeverState()=="activated" and
SouthLever:getLeverState()=="deactivated" then
VariablePlate1:addConnector("activate","SouthwestDoor","toggle")
end
end
end
end
end
But the problem is the connectors just stack instead of replacing the previous one.
Any suggestions?
Thanks in advance.
Re: Pressure Plate Question
Posted: Thu Jan 24, 2013 7:11 am
by dasarby
As best I can tell, there is no good way to remove a connector once its been added (I kinda suspect the addConnector function is meant to be used by the editor, not directly from scripts, but it is convenient for some things).
The work around I use is to use a script level variable to flag which things have been connected to what, and then don't run addConnector if it as already been connected, and then using some other flag to indicate if the script should run.
I suspect, though, that for your case you can accomplish this without using addConnector. It seems to me you have two levers, NorthLever and SouthLever, and a pressure plate which when activated opens a different grate based on which combo of levers is down, ya? If so, you probably want the following instead.
Instead of wiring the pressure plate to the appropriate door, just open the door directly from the script.
Code: Select all
function OpenSelectedDoor()
if NorthLever:getLeverState()=="deactivated" and SouthLever:getLeverState()=="deactivated" then
NorthwestDoor:open()
elseif NorthLever:getLeverState()=="activated" and SouthLever:getLeverState()=="activated" then
SoutheastDoor:open()
elseif NorthLever:getLeverState()=="deactivated" and SouthLever:getLeverState()=="activated" then
NortheastDoor:open()
elseif NorthLever:getLeverState()=="activated" and SouthLever:getLeverState()=="deactivated" then
NortheastDoor:close()
end
end
Then add a connector from your pressure place to that function. Add a deactivate connector from your place to each door to close them all. That should have the same effect as what your trying to do.
Re: Pressure Plate Question
Posted: Thu Jan 24, 2013 8:12 am
by Ryeath_Greystalk
Thanks dasarby.
You understand perfectly what I was trying to accomplish. I will give your method a try.
Re: Pressure Plate Question
Posted: Thu Jan 24, 2013 8:31 am
by Ryeath_Greystalk
It worked perfectly.
My final code ended up being
Code: Select all
function SetPressurePlateTarget()
if NorthLever:getLeverState()=="deactivated" and
SouthLever:getLeverState()=="deactivated" then
NorthwestDoor:open()
SouthwestDoor:close()
SoutheastDoor:close()
NortheastDoor:close()
else
if NorthLever:getLeverState()=="activated" and
SouthLever:getLeverState()=="activated" then
SoutheastDoor:open()
NortheastDoor:close()
NorthwestDoor:close()
SouthwestDoor:close()
else
if NorthLever:getLeverState()=="deactivated" and
SouthLever:getLeverState()=="activated" then
NortheastDoor:open()
NorthwestDoor:close()
SoutheastDoor:close()
SouthwestDoor:close()
else
if NorthLever:getLeverState()=="activated" and
SouthLever:getLeverState()=="deactivated" then
SouthwestDoor:open()
SoutheastDoor:close()
NorthwestDoor:close()
NortheastDoor:close()
end
end
end
end
end
Much appreciate the help.
Re: Pressure Plate Question
Posted: Thu Jan 24, 2013 12:03 pm
by Komag
Let's clean that up a little:
Code: Select all
function SetPressurePlateTarget()
local N = false
local S = false
if NorthLever:getLeverState()=="activated" then N = true end
if SouthLever:getLeverState()=="activated" then S = true end
if not N and not S then _doors("Northwe")
elseif N and S then _doors("Southea")
elseif not N and S then _doors("Northea")
elseif N and not S then _doors("Southwe")
end
end
function _doors(dir)
for i in allEntities(party.level) do
if i.id:sub(8,13) == "stDoor" then i:close() end
end
local i = findEntity(dir.."stDoor")
if i then i:open() end
end
Re: Pressure Plate Question
Posted: Thu Jan 24, 2013 3:52 pm
by Ryeath_Greystalk
Thanks for taking the time to clean up the code Komag.
I pretty sure I understand the first function. The "if" statement needs to return "true" to operate _doors("Northwe") function.
So if both levers are up then N=false and S=false, so then they get inverted by the "not" function, which would make two "trues" and thus call the open door function. And so forth.
The second part is way over my head for now, but I will look up those commands later today and see if I can figure it out.
Re: Pressure Plate Question
Posted: Thu Jan 24, 2013 6:43 pm
by dasarby
I see a potental problem with Komag's, namely closing the doors by finding all and substring matching. It is possible (albeit probably unlikely

) that it will close another door that is not part of the puzzle. For example, if you had a door named "HallFirstDoor", it would also get closed, because it is 13 letters long and ends in "stDoor".
More nitpickingly, it seems unnecessary to use allEntities here; we know the ids of the doors, so why loop across everything on the level? True, the loop is probably pretty fast, but for levels with large amounts of entities you might notice a slowdown. It seems clearer and faster to just loop across the doors we want, close them all, and then open the door directly:
Code: Select all
function SetPressurePlateTarget()
local N = NorthLever:getLeverState() == "activated"
local S = SouthLever:getLeverState() == "activated"
if N and S then _doors(SoutheastDoor)
elseif N then _doors(SouthwestDoor)
elseif S then _doors(NortheastDoor)
else _doors(NorthwestDoor)
end
end
function _doors(openDoor)
local allDoors = {SoutheastDoor, SouthwestDoor, NorthwestDoor, NortheastDoor}
for _, door in ipairs(allDoors) do
door:close()
end
openDoor:open()
end
Re: Pressure Plate Question
Posted: Thu Jan 24, 2013 7:00 pm
by Ryeath_Greystalk
Ok, I think I'm getting close here.
The first function is using boolean logic to figure out what door should be opened. It then passes the first 7 letters of the door name to the _doors(dir) function. Here I am guessing that dir is another local variable?
The first section of the _doors function searches all the entities on the level that the player is on looking for any name that ends with stDoor and performs the door:close() function. The sub(8,13) I'm unsure of. The 13 makes sense as each door name has 13 letters, but the 8 is confusing me a bit. At any rate, this should perform the duty of closing all 4 doors.
The next line I believe joins together the 7 letters passed from the first function, for example Northwe, with stDoor, to complete the door name, in this case NorthwestDoor. (I base this from reading Komags post about tables and it looks like two dots (..) joins strings together.) If it finds the entity named NorthwestDoor ir performs the door:open() function.
That is some really slick programming there. Well beyond my pitiful knowledge, but still awesome you would take time to help out.
edit-- looks like dasarby and I were typing replies at the same time

Re: Pressure Plate Question
Posted: Thu Jan 24, 2013 7:20 pm
by Komag
I like dasarby's better, more direct like he says, good
I would write the table a little different:
Code: Select all
function _doors(openDoor)
local allDoors = {SoutheastDoor, SouthwestDoor, NorthwestDoor, NortheastDoor}
for i=1,4 do allDoors[i]:close() end
openDoor:open()
end
Re: Pressure Plate Question
Posted: Thu Jan 24, 2013 7:33 pm
by dasarby
that's probably waaay more idiomatic LoG lua than my table loop

. (assigning to _, the unused variable,
is idiomatic in another language in which I do most of my work, so I do it without thinking. using an indexed for loop is probably better and clearer here!)