Open stairs in a level to move between elevations?

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!
User avatar
Mysterious
Posts: 226
Joined: Wed Nov 06, 2013 8:31 am

Re: Open stairs in a level to move between elevations?

Post by Mysterious »

errrrr imam no coder but +1 to gambit37. I thought the same thing, click the ladder to go down and......nothing??, then I thought why cant the stairs be like ladder, you know move you up like the ladders do.
nichg
Posts: 48
Joined: Thu Oct 11, 2012 12:38 pm

Re: Open stairs in a level to move between elevations?

Post by nichg »

You can actually do this already, but it's a bit of a hack. Petri's point about the ambiguity of the state ends up actually being the thing that lets you do it.

Lets say we have a 1x1 tile which is supposed to be a platform halfway between H=0 and H=1 (very simple kind of stairs). The logic for this platform should be that you can enter that tile at H=0, but you can leave that tile at H=1 if moving towards a square with a walkable area at H=1, or you can leave the tile at H=0 if moving towards a square which is passable at H=0 but not at H=1. Of course you should try to build things to limit the number of ambiguous directions of motion, so the player understands how they will be leaving the tile when they queue a move.

It turns out that you can in fact make that happen via quirks in the engine. I'm not 100% sure of the logic here, but I've managed to get this to work in the editor:

Lets say you place two bridge objects in the level in the same square, one at H=0 and one at H=1. In this case, you can continue to move at H=1 if you start at H=1, and you can continue to move at H=0 if you start at H=0. The trick then is to enable moving from H=0 to H=1 automatically. It turns out that the way the engine handles gravity combined with platforms can let you pull this off. The reason is that the engine detects uses a different encoding of positions to detect when an object lands on a platform than it does to detect whether an object can move between platforms.

So now imagine that you use setWorldPositionY to shift the H=1 tile so that it lies below the nominal Y position associated with H=0. If the player walks onto that tile from another H=0 tile, they will drop a bit and then land on an H=1 object. The engine then decides that their new (integer) map coordinates correspond to H=1, even though their physical coordinates within the world are actually lower.

Now, you can combine this with another trick. If you have a platform at H=0 but at a world position Y value inconsistent with that, the engine will automatically lift the party up to that world position when it enters the tile from an adjacent H=0 tile. This means that you can use this effect to automatically 'drop' the party onto the H=1 tile.

In practice, all you need to do is make an H=0 and H=1 tile in the same map square, and use setWorldPositionY to place them at the same physical height. When the party walks onto that square from an adjacent H=0 square, the game engine lifts them up to the H=0 platform height, but then (for whatever reason) 'drops' them onto the H=1 tile. When the party leaves the square, they can leave to an H=1 landing if one is available, or can 'drop' down to H=0 if moving in a direction that has no supporting surface at H=1.

I don't yet know how to do proper directional stairs using this trick, but you can certainly do effects that look like continuous stairs. The main problem is that it looks ugly when the party steps upwards - basically instead of smoothly rising up in the Y axis like they do on stairs which exit the level, they 'jump' up vertically. If there were a way to fix that in the engine, it'd be near-perfect (you can probably do it with scripts triggered by entry into that square which control the party's motion, I guess?)
User avatar
Mysterious
Posts: 226
Joined: Wed Nov 06, 2013 8:31 am

Re: Open stairs in a level to move between elevations?

Post by Mysterious »

Hi this is very interesting and was wondering could you make a demo dungeon so we (I) can see how it works thxs :)
nichg
Posts: 48
Joined: Thu Oct 11, 2012 12:38 pm

Re: Open stairs in a level to move between elevations?

Post by nichg »

Alright, I made a bit of a demo map with some stairs (and a model-less secret door to constrain movement) along with an elevator using a similar trick.
User avatar
Mysterious
Posts: 226
Joined: Wed Nov 06, 2013 8:31 am

Re: Open stairs in a level to move between elevations?

Post by Mysterious »

nichg wrote:Alright, I made a bit of a demo map with some stairs (and a model-less secret door to constrain movement) along with an elevator using a similar trick.
Ok I downloaded the file thinking it was going to be a Editor version, but it's a Dat file. It's good to see you can create stairs and a lift, but would have liked the Editor version rather than the Dat version :) (sigh)
User avatar
Mysterious
Posts: 226
Joined: Wed Nov 06, 2013 8:31 am

Re: Open stairs in a level to move between elevations?

Post by Mysterious »

bump... sorry
Jackard
Posts: 59
Joined: Thu Oct 30, 2014 7:32 pm

Re: Open stairs in a level to move between elevations?

Post by Jackard »

You can sort of make stairs using heightmap and bridges. It's finicky though, and remains on the same elevation.
ninjanerdbgm
Posts: 28
Joined: Tue Nov 04, 2014 6:53 pm

Re: Open stairs in a level to move between elevations?

Post by ninjanerdbgm »

Mysterious wrote:
nichg wrote:Alright, I made a bit of a demo map with some stairs (and a model-less secret door to constrain movement) along with an elevator using a similar trick.
Ok I downloaded the file thinking it was going to be a Editor version, but it's a Dat file. It's good to see you can create stairs and a lift, but would have liked the Editor version rather than the Dat version :) (sigh)
If you'd like, you can use my elevator script. I'm not sure it's the most optimal method, but it works well.

You will need a sound entity called 'sound_1' somewhere in the elevator shaft. Make sure the sound it's set to play is 'pushable_block_hover'.

Code: Select all

-------------
-- INIT
-------------
e_i = 0
e_j = 0
elevator:setWorldPositionY(0) --// make sure elevator is in place.
force_field_1:setWorldPositionY(-0.5) --// for the glowing floor effect.
force_field_1.controller:deactivate()
sound_1.sound:stop()

--//

function goUp()
--// The following makes it so you can't click the buttons once the ride has started
	wall_button_3.clickable:setSize(vec(0,0,0))
	wall_button_4.clickable:setSize(vec(0,0,0))
--
	if dungeon_door_wooden_double_1.door:isOpen() then
		dungeon_door_wooden_double_1.door:close()
		delayedCall(self.go.id,2,"goUp")
		return
	end

	if e_i < 9.0 then      --//  9.0 is the WorldPositionY for elevation 3.  Change this as needed.
		force_field_1.controller:activate() --// Turn on glowing floor.
		if not moving then
			sound_1.sound:play("pushable_block_hover")
			sound_1.sound:fadeIn(1)
			sound_1.sound:setVolume(2.5)
			sound_1.sound:setPitch(0.8) --// Makes it sound better, imo.
			moving = true
		end
		elevator:setWorldPositionY(e_i)
		party:setWorldPositionY(e_i)
		force_field_1:setWorldPositionY(e_i-0.5)
		party.party:shakeCamera(0.02,0.05)
		e_i = e_i + 0.02
		delayedCall(self.go.id,0.05,"goUp")
		return
	else
		if moving then
			playSound("wall_sliding_lock")	
		end
		e_j = e_i
		movinggate:setWorldPositionY(e_j)
		elevator:setWorldPositionY(9) --// Make sure it's at the right spot.
		party:setWorldPositionY(9) --// Ditto.
		force_field_1:setWorldPositionY(8.5)
		playSound("gate_open")
		wall_button_3.clickable:setSize(vec(.25,.25,.25,0)) --// Allow pressing the buttons
		wall_button_4.clickable:setSize(vec(.25,.25,.25,0)) --// again.
		force_field_1.controller:deactivate() --// Turn off glowing floor.
		moving = false
		sound_1.sound:fadeOut(1)
		gratingOpen()
	end
end

--// The following function lowers the gate on the top level.  This is optional, depending on your setup.

function gratingOpen()
	if movinggate then
		if e_j >= 5.5 then
			movinggate:setWorldPositionY(e_j)
			movinggate:setWorldPosition(28.5,e_j,33,0)
			e_j = e_j - 0.05
			delayedCall(self.go.id,0.05,"gratingOpen")
			return
		end
		movinggate:destroy()
		playSound("gate_lock")
	end
end

--// ---------

--// The following function is very similar to goUp(), except this one goes down.

function goDown()
	wall_button_3.clickable:setSize(vec(0,0,0))
	wall_button_4.clickable:setSize(vec(0,0,0))
	if not gateclosing then
		playSound("gate_close")
		gateclosing = true
	end
	if not movinggate then
		spawn("dungeon_wall_grating",7,9,21,0,2,"movinggate")
	end
	e_j = movinggate:getWorldPositionY()
	if e_j < 9 then
		e_j = e_j + 0.1
		movinggate:setWorldPositionY(e_j)
		movinggate:setWorldPosition(28.5,e_j,33,0)
		delayedCall(self.go.id,0.05,"goDown")
		return
	end
	if not gateclosed then
		playSound("gate_lock")
		gateclosed = true
	end
	if e_i > 0 then
		force_field_1.controller:activate()
		if not moving then
			sound_1.sound:play("pushable_block_hover")
			sound_1.sound:fadeIn(1)
			sound_1.sound:setVolume(2.5)
			sound_1.sound:setPitch(0.8)
			moving = true
		end
		elevator:setWorldPositionY(e_i)
		party:setWorldPositionY(e_i)
		force_field_1:setWorldPositionY(e_i-0.5)
		party.party:shakeCamera(0.02,0.05)
		e_i = e_i - 0.02
		delayedCall(self.go.id,0.05,"goDown")
		return
	else
		if moving then
			playSound("wall_sliding_lock")	
		end
		e_j = 9
		movinggate:setWorldPositionY(e_j)
		elevator:setWorldPositionY(0)
		force_field_1:setWorldPositionY(-0.5)		
		party:setWorldPositionY(0)
		wall_button_3.clickable:setSize(vec(.25,.25,.25,0))
		wall_button_4.clickable:setSize(vec(.25,.25,.25,0))
		gateclosed = false
		gateclosing = false
		moving = false
		force_field_1.controller:deactivate()
		sound_1.sound:fadeOut(1)
		dungeon_door_wooden_double_1.door:open()
	end
end
Here's a video of my elevator in action.

EDIT: I should mention what the entities are in my script.

force_field_1 is the name I gave to a pushable_block_floor entity. It sits in the same space as the elevator entity.
wall_button_3 is the button at the bottom of the shaft. This calls goUp() when clicked.
wall_button_4 is the button at the top of the shaft. This calls goDown() when clicked.
elevator is a castle_bridge_grating entity.
nichg
Posts: 48
Joined: Thu Oct 11, 2012 12:38 pm

Re: Open stairs in a level to move between elevations?

Post by nichg »

Whoops, my mistake. I thought for some reason that you could open .dat files in the editor. I've now updated the page to include the editor files in a separate rar.
NutJob
Posts: 426
Joined: Sun Oct 19, 2014 6:35 pm

Re: Open stairs in a level to move between elevations?

Post by NutJob »

Thanks for sharing the elevator script ninjanerdbgm, learned a few things.
Post Reply