Altar and counter
Altar and counter
Hi, please need help. 3x Ogre hammer stay on altar = open door. Remove hammer = door close.
Thanks
function OgreAltar()
for i in altar_3:containedItems() or altar_4:containedItems() or altar_5:containedItems() do
if i.name == "ogre_hammer" then
dungeon_door_portcullis_17:open()
dungeon_door_portcullis_18:open()
end
end
end
Thanks
function OgreAltar()
for i in altar_3:containedItems() or altar_4:containedItems() or altar_5:containedItems() do
if i.name == "ogre_hammer" then
dungeon_door_portcullis_17:open()
dungeon_door_portcullis_18:open()
end
end
end
Nightfall: First Contact – http://dedy.euweb.cz/nightfall.html
Re: Altar and counter
I am actually working on a similar case -- three gems on an altar (actually 3 altars on each other). But it is incomplete -- putting them on the altar opens the door, but so does putting one of them three times. Also, taking one out and putting it again will close it (because the counter is still active, should remove it as well).
It is also more than a bit rough, but maybe it will be of some help. It can probably be done more elegantly:
I'll report in again if I find a solution.
EDIT: viewtopic.php?f=14&t=3083 may also be of use, that is where I learned this much.
It is also more than a bit rough, but maybe it will be of some help. It can probably be done more elegantly:
Code: Select all
--WARNING, this code is incomplete! It works, but not completely as intended
--you will need three alcoves (here: waltars 1, 2 and 3), a counter (here: gemcounter), a secret door (here: gemdoor) and this script in a script entity.
function gemcheckfunc()
for i in waltar1:containedItems() do
if i.name == "green_gem" then
gemcounter:increment()
if i.name == "blue_gem" then
gemcounter:increment()
if i.name == "red_gem" then
gemcounter:increment()
end
end
end
end
for o in waltar2:containedItems() do
if o.name == "green_gem" then
gemcounter:increment()
if o.name == "blue_gem" then
gemcounter:increment()
if o.name == "red_gem" then
gemcounter:increment()
end
end
end
end
for p in waltar3:containedItems() do
if p.name == "green_gem" then
gemcounter:increment()
if p.name == "blue_gem" then
gemcounter:increment()
if p.name == "red_gem" then
gemcounter:increment()
end
end
end
end
if gemcounter:getValue() == 3 then
gemdoor:open()
else
gemdoor:close()
end
endEDIT: viewtopic.php?f=14&t=3083 may also be of use, that is where I learned this much.
BASILEUS
Re: Altar and counter
Try somethingl like this (not tested)
Code: Select all
function gemcheckfunc()
checkAltar(waltar1)
checkAltar(waltar2)
checkAltar(waltar3)
if gemcounter:getValue() == 3 then
gemdoor:open()
else
gemdoor:close()
end
end
function checkAltar(altar)
for i in altar:containedItems() do
if i.name == "green_gem" then
gemcounter:increment()
elseif i.name == "blue_gem" then
gemcounter:increment()
elseif i.name == "red_gem" then
gemcounter:increment()
else
gemcounter:decrement()
end
end
end
Re: Altar and counter
I haven't tested it, but Filipsan's script looks like it's on the right lines.. the important thing when using a counter is to increment and decrement it when objects are removed/added to the alter
Since counters automatically activate when they reach 0 it's best to have them count down instead of up... so set the initial value to 3... then when the right item is added to the alter decrement the counter. If the item is removed then increment the counter to avoid the situation of using 1 item 3 times!
You'll also need to make the altar trigger on ANY event, otherwise it will only trigger when the first object is added or the last one is removed.
Since counters automatically activate when they reach 0 it's best to have them count down instead of up... so set the initial value to 3... then when the right item is added to the alter decrement the counter. If the item is removed then increment the counter to avoid the situation of using 1 item 3 times!
You'll also need to make the altar trigger on ANY event, otherwise it will only trigger when the first object is added or the last one is removed.
Puzzle Frameworks - http://www.grimrock.net/forum/viewtopic.php?f=14&t=4564
Magic Pack - https://www.nexusmods.com/grimrock/mods/70
Area of Effect Spell System - http://www.grimrock.net/forum/viewtopic ... 150#p44382
Magic Pack - https://www.nexusmods.com/grimrock/mods/70
Area of Effect Spell System - http://www.grimrock.net/forum/viewtopic ... 150#p44382
Re: Altar and counter
Good tips! My altars are actually alcoves at the moment, but it seems to work all the same. I never knew I could write the script that way, looks very logical to me.
I figure I could just add a hook to the objects so one can't remove gems from these altars/alcoves, I doubt I'll use them again in this dungeon. ( just need to remember this if there are gems around if I use them again)
EDIT: ARGH! There is no RemoveItem hook? Damn!
I figure I could just add a hook to the objects so one can't remove gems from these altars/alcoves, I doubt I'll use them again in this dungeon. ( just need to remember this if there are gems around if I use them again)
EDIT: ARGH! There is no RemoveItem hook? Damn!
BASILEUS
Re: Altar and counter
Look at this post
viewtopic.php?f=14&t=3551&p=36341&hilit ... ove#p36358
Re: Altar and counter
Thanks! I actually finally found a way to do it like I originally intended, but I am sure this will be handy in the future.Filipsan wrote:Look at this postviewtopic.php?f=14&t=3551&p=36341&hilit ... ove#p36358
BASILEUS
Re: Altar and counter
Hmmm, not work
Im not programmer, only artist.
Please help.
Counter Initial Value = 3
Event = any
Please help.
Counter Initial Value = 3
Event = any
Code: Select all
function OgreAltar()
for i in altar_ogre1:containedItems() do
if i.name == "ogre_hammer" then
counter_orge_altar:decrement()
end
end
for o in altar_ogre2:containedItems() do
if o.name == "ogre_hammer" then
counter_orge_altar:decrement()
end
end
for p in altar_ogre3:containedItems() do
if p.name == "ogre_hammer" then
counter_orge_altar:decrement()
end
end
if counter_orge_altar:getValue() == 0 then
dungeon_door_portcullis_17:open()
dungeon_door_portcullis_18:open()
else
dungeon_door_portcullis_17:close()
dungeon_door_portcullis_18:close()
end
endNightfall: First Contact – http://dedy.euweb.cz/nightfall.html
Re: Altar and counter
They should be separate functions I think: (and watch the spelling on ogre)
But that is actually problematic because a player could place a hammer on one altar three times and the doors would open. If you build in an "else increment counter" for each script, anytime they place another object on the altar the counter would go up, causing problems. Might work better just to do single altar scripts like you can find all over the forums, then just link all of them to a counter properly set up, and that to the doors.
Code: Select all
function OgreAltar1()
for i in altar_ogre1:containedItems() do
if i.name == "ogre_hammer" then
counter_ogre_altar:decrement()
end
end
checkOgreAltar()
end
function OgreAltar2()
for i in altar_ogre2:containedItems() do
if i.name == "ogre_hammer" then
counter_ogre_altar:decrement()
end
end
checkOgreAltar()
end
function OgreAltar3()
for i in altar_ogre3:containedItems() do
if i.name == "ogre_hammer" then
counter_ogre_altar:decrement()
end
end
checkOgreAltar()
end
function checkOgreAltar()
if counter_ogre_altar:getValue() == 0 then
dungeon_door_portcullis_17:open()
dungeon_door_portcullis_18:open()
else
dungeon_door_portcullis_17:close()
dungeon_door_portcullis_18:close()
end
endFinished Dungeons - complete mods to play
Re: Altar and counter
I feel bad for almost hijacking your topic, so here is a working code (courtesy of Grimwold -- I'd still be swearing with my door were it not for him and all the other helpful people here, so this code basically isn't mine -- credit to the one who deserves it, I am just a messenger here ; D)
Basically, you'll want the game to check the altars every time the party takes something from them or places something on them. There are a few ways to do this, but the simplest is to connect the altars to a script entity which can then check what the item on the altar is (if any). You won't need a counter, because all the altars are checked every time an item is placed on one of them or taken from one of them.
You'll need three altars for this (I named them hammeraltar1 hammeraltar2 and hammeraltar3, you can call them whatever you want, just be sure to change the names from the script as well), a script entity (name doesn't matter, because you can activate the functions by connecting the altars straight to the script entity -- it might be wise to name it something logical, though.)
JUST MAKE SURE YOU HAVE "activate always" TICKED FROM THE ALTARS' PROPERTIES, AND THE EVENT PART SET TO "any", AND ACTION PART SET TO THE FUNCTION I CALLED "contentcheck". (again, you can name it what you want, just be sure to alter the name in the script as well)
Sorry for yelling, but this was the reason I was stuck for a long time. With activate always the altar will trigger the function also when an item is removed from it -- necessary because we want the door to close if a hammer is removed.
You'll also need the secret door you want to open, I named it hammerdoor. Same applies -- name it what you want, but make sure the script has the same name.
Here is the complete code, I will go through it line by line afterwards:
function hammercheck(altar) -- this function will be used to determine what items are on the altar and if our desired item is there, as follows
for i in altar:containedItems() do -- this just means that the game will go through all the items on the altar
if i.name == "ogre_hammer" then -- this means that if one of the items is called ogre_hammer, the next will happen
return true -- this will stop the loop and give true, "positive" result if the ogre_hammer is on the altar - the contentcheck function will use this information
end
end
return false -- if an ogre_hammer was not on the altar, this will end the function and return a false "negative" result. Again the other function will use this to decide if it opens the door or closes it
end
function contentcheck() -- this function will "use" the previous function on the altars you have in your map, and if all the altars give a positive result (the hammer is there), it will open the door
if hammercheck(hammeraltar1) and hammercheck(hammeraltar2) and hammercheck(hammeraltar3) then -- this checks the altars one at a time, if all the altars give the "true" result the next will happen
hammerdoor:open() -- this happens, the door opens; if it is already open, it will stay open.
else -- If not, (all the altars didn't have a hammer)
hammerdoor:close() -- this happens. This way if the party removes a hammer, the door will close immediately; if it is already closed, it will stay closed.
end
end
I hope I explained it clear enough, I tried to do so because I personally had much trouble understanding this script, not because it was unclear, but because certain scripting principles were unclear to me.
Basically, you'll want the game to check the altars every time the party takes something from them or places something on them. There are a few ways to do this, but the simplest is to connect the altars to a script entity which can then check what the item on the altar is (if any). You won't need a counter, because all the altars are checked every time an item is placed on one of them or taken from one of them.
You'll need three altars for this (I named them hammeraltar1 hammeraltar2 and hammeraltar3, you can call them whatever you want, just be sure to change the names from the script as well), a script entity (name doesn't matter, because you can activate the functions by connecting the altars straight to the script entity -- it might be wise to name it something logical, though.)
JUST MAKE SURE YOU HAVE "activate always" TICKED FROM THE ALTARS' PROPERTIES, AND THE EVENT PART SET TO "any", AND ACTION PART SET TO THE FUNCTION I CALLED "contentcheck". (again, you can name it what you want, just be sure to alter the name in the script as well)
Sorry for yelling, but this was the reason I was stuck for a long time. With activate always the altar will trigger the function also when an item is removed from it -- necessary because we want the door to close if a hammer is removed.
You'll also need the secret door you want to open, I named it hammerdoor. Same applies -- name it what you want, but make sure the script has the same name.
Here is the complete code, I will go through it line by line afterwards:
SpoilerShow
Code: Select all
function hammercheck(altar)
for i in altar:containedItems() do
if i.name == "ogre_hammer" then
return true
end
end
return false
end
function contentcheck()
if hammercheck(hammeraltar1) and hammercheck(hammeraltar2) and hammercheck(hammeraltar3) then
hammerdoor:open()
else
hammerdoor:close()
end
endfunction hammercheck(altar) -- this function will be used to determine what items are on the altar and if our desired item is there, as follows
for i in altar:containedItems() do -- this just means that the game will go through all the items on the altar
if i.name == "ogre_hammer" then -- this means that if one of the items is called ogre_hammer, the next will happen
return true -- this will stop the loop and give true, "positive" result if the ogre_hammer is on the altar - the contentcheck function will use this information
end
end
return false -- if an ogre_hammer was not on the altar, this will end the function and return a false "negative" result. Again the other function will use this to decide if it opens the door or closes it
end
function contentcheck() -- this function will "use" the previous function on the altars you have in your map, and if all the altars give a positive result (the hammer is there), it will open the door
if hammercheck(hammeraltar1) and hammercheck(hammeraltar2) and hammercheck(hammeraltar3) then -- this checks the altars one at a time, if all the altars give the "true" result the next will happen
hammerdoor:open() -- this happens, the door opens; if it is already open, it will stay open.
else -- If not, (all the altars didn't have a hammer)
hammerdoor:close() -- this happens. This way if the party removes a hammer, the door will close immediately; if it is already closed, it will stay closed.
end
end
I hope I explained it clear enough, I tried to do so because I personally had much trouble understanding this script, not because it was unclear, but because certain scripting principles were unclear to me.
BASILEUS
