Page 1 of 1

[Script] Moving platforms

Posted: Mon May 04, 2015 11:16 pm
by alois
I've made a new asset (using the old ones...) which allows for platforms (like forest_bridge) to be moved up and down and sideways (without anything on them, however).

Do the following: in "items.lua", add the following lines (feel free to remove comments!)

Code: Select all

defineObject{
	name = "forest_bridge_moving",
	baseObject = "base_floor_decoration",
	components = {
		{
			class = "Model",
			model = "assets/models/env/forest_bridge.fbx", -- the forest bridge model (change here as needed)
			staticShadow = true,
		},
		{
			class = "Platform", -- or otherwise you are going to fall through the model :)
		},
		{
			class = "Timer",
			DisableSelf = false, -- never stop (until you say so!)
			TimerInterval = 0.05, -- time interval (change as needed, but modify also below)
			onActivate = function(self)
				if (self.go.data:get("tmax") == 0) then -- to avoid the "start when run" problem
					self:stop() -- if tmax = 0, then nothing has to move, stop timer
					return
				end
				local points = self.go.data:get("points") -- the path to follow (see instructions)
				local interval = 0 -- the i-th interval of points
				for idx = 1,#points-1 do
					local time = self.go.data:get("time")
					if ((points[idx].t <= time) and (time < points[idx+1].t)) then -- if the time is in between two points
						interval = idx -- register the interval
					end
				end
				if (interval ~= 0) and (interval ~= self.go.data:get("interval")) then -- has the interval changed?
					self.go.data:set("interval",interval) -- save it
					local ps = points[interval] -- starting point of the i-th interval
					local pf = points[interval+1] -- ending point of the i-th interval
					local dt = points[interval+1].t - points[interval].t -- length, in seconds, of the interval
					local dx = 3 * (pf.x - ps.x) / dt / 20 -- space to move in the x direction (east-west)
					local dy = 3 * (pf.y - ps.y) / dt / 20 -- space to move in the y direction (up-down)
					local dz = 3 * (ps.z - pf.z) / dt / 20 -- space to move in the z direction (north-south)
					self.go.data:set("d",{dx = dx, dy = dy, dz = dz}) -- save the datum
				end
				self.go.data:set("time",self.go.data:get("time") + 0.05) -- increase time (of TimerInterval)
				if (not(self.go.data:get("sound"))) then -- is there a sound? if not
					self.go.sound:play("wall_sliding_loop") -- moving platform sound (see sound.lua for the definition)
					self.go.data:set("sound",true) -- register the fact that a sound is playing
				end
				if (self.go.data:get("time") < self.go.data:get("tmax")) then -- are we before the end of the movement?
					local offset = self.go:getWorldPosition() -- yes: where is the platform?
					local d = self.go.data:get("d") -- take the increase in space
					self.go:setWorldPosition(vec(offset.x+d.dx,offset.y+d.dy,offset.z+d.dz)) -- and move it!
				elseif (self.go.data:get("time") < self.go.data:get("tmax")+0.05) then -- the movement has just ended? (0.04 = TimerInterval - 0.01)
					self.go.sound:play("wall_sliding_lock") -- change sound
					local point = points[#points] -- take the last point
					self.go:setPosition(point.x,point.z,self.go.facing,point.y,self.go.level) -- and set the bridge to it (with integers!)
				elseif (self.go.data:get("time") > self.go.data:get("tmax") + 2) then -- two seconds more (the "lock" sound still has to play)
					self.go.data:set("time",0) -- reset values
					self.go.data:set("tmax",0) -- reset values
					self.go.data:set("sound",false) -- reset values
					self.go.data:set("interval",0) -- reset values
					self.go.sound:stop() -- stop sound
					self.go.timer:stop() -- stop timer
				end
			end,
		},
		{
			class = "Script",
			name = "data",
			source = [[
data = {time = 0, interval = 0, tmax = 0, sound = false}
function set(self,name,value)
	self.data[name] = value
end
function get(self,name)
	return self.data[name]
end
]],
		},
		{
			class = "Sound",
			volume = 100,
		},
	},
	editorIcon = 184,
	automapIcon = 136,
}
and in "sounds.lua", add the following:

Code: Select all

defineSound{
	name = "wall_sliding_loop",
	filename = "assets/samples/env/wall_sliding_01.wav",
	loop = true,
	volume = 0.5,
	minDistance = 2,
	maxDistance = 10,
}
Then, in a script_entity in your dungeon, you have to specify two things: a sequence of points through which you want the platform to move, and the total time of movements. For example,

Code: Select all

local points = {
   {x = 14, y = 2, z = 14, t = 0},
   {x = 15, y = 1, z = 13, t = 2},
   {x = 12, y = 1, z = 13, t = 5},
}
local tmax = 5
Then, place a "forest_bridge_moving" platform at x = 14, z = 14, and elevation 2; say that its id is "forest_bridge_moving_1"; then add the following lines to the script (maybe connect them to a floor trigger, or a lever, etc):

Code: Select all

forest_bridge_moving_1.data:set("points",points)
forest_bridge_moving_1.data:set("tmax",tmax)
forest_bridge_moving_1.timer:start()
and watch the platform moving from (14,14,2) to (15,13,1) in 2 seconds, and then to (12,13,1) in another 3 seconds. Do not try to "jump" on moving platforms, because you will fall through (as of now).

Alois :)

PS: Thanks to JKos for the "data" trick!

Re: [Script] Moving platforms

Posted: Mon May 11, 2015 8:19 am
by Eleven Warrior
Awesome man :) Good job. Will the party be able to stand on them eventualy mate?

Re: [Script] Moving platforms

Posted: Mon May 11, 2015 8:52 am
by alois
Eleven Warrior wrote:Awesome man :) Good job. Will the party be able to stand on them eventualy mate?
Uhm... I do not know... maybe I can do some trick with cameras; keep in mind that - as of now - even if you put an object on the platform, it falls through as soon as the platform starts moving.

Alois :)

PS: Actually, moving items with platforms is quite easy (you just have to check for items on the platform as it starts moving, and move them accordingly). And you can move party too; but - for the party - camera stutters during the movement... (keep you posted!)