Sleep and Ladders
Posted: Sat Oct 04, 2014 4:24 am
Hey everyone,
Just got into modding Grimrock, and two of the features I was looking for (sleep & ladders - hence the title) I found hints at, but nothing "complete."
So I thought I would share a few of the things I made in a "complete" format so someone else can just copy & paste.
SLEEP
Create a script_entity with the ID "sleep" following source/body
The parameters are the following:
then, when you want to call sleep in another script, you can simply do this
The sleep:start(...) function also returns the timer in case you want to stop or restart it. If you manually stop it (outside of letting it activate) remember to destroy it before calling sleep:start(...) again. Note that "self.id" and "_callback" could be something different like "wooden_door_1" and "open" - they don't have to refer to the calling script_entity
LADDERS
Hoookay, so this one is a bit of a cop-out, since I'm not supplying models. You can get some awesome ladders from EOB (DJ, JKos, Tom, Bifrost, Thomson, Wallasaurus, montagneyaya) and other places. I'll just show how to wire it up without making someone fall screaming down a hole (and w/o excessive scripts, timers, and teleports copied all over)
Add the following to your objects.lua (in addition to your ladder definitions)
Then, create a script_entity in a "global" area (like the top or bottom floor - you only need one of these) with the ID "ladder" and the following body:
Note that when suppling level, you can omit, set a floor number, or relative "up" or "down" like a regular Teleport object. Then, when you want to use it, just connect a new script_entity to the "dungeon_fake_pit"s activate() with the following body: (or on the ladder_up's activate)
and that's it! Just make sure to always set the destination before activating it (hence why you need to call it from a script, not a connector)
What the script does is start fading the screen to black, freezes the party, waits until the screen is black, teleports the party, fades the screen to normal, and unfreezes the party. It's a much smoother transition that mimics the stairs transition (sound, black screen) and isn't as jarring as a plain invisible teleport. It's also pretty clean wherever you want to use it. Just keep in mind not to let the player activate this more than once per transition or it gets all screwy.
When I first started doing the ladder transition, I had a timer, script_entity, and teleporter for EACH ladder. now it's just a global script_entity, and one for each ladder. Much easier to maintain.
CAVEAT
I can't figure out how to get the "screen_wipe" particle to continue to generate after teleportation. It doesn't smooth out like I want it to.
Just got into modding Grimrock, and two of the features I was looking for (sleep & ladders - hence the title) I found hints at, but nothing "complete."
So I thought I would share a few of the things I made in a "complete" format so someone else can just copy & paste.
SLEEP
Create a script_entity with the ID "sleep" following source/body
Code: Select all
function start(self, receiverID, callback, delay, name)
if not name then name = "timer_spawn_"..receiverID end
local t = spawn("timer", self.level, self.x, self.y, 0, name)
t:setTimerInterval(delay)
t:addConnector("activate", receiverID, callback)
t:addConnector("activate", t.id, "deactivate")
t:addConnector("activate", t.id, "destroy")
t:activate()
return t
end
Code: Select all
self (don't pass this in, it just shows up, is this a Lua thing?)
receiverID - the ID of the script entity (or other object) to call when the timer finishes
callback - the name of the function to call on the receiver when the timer finishes
delay - how long (in seconds) to delay for
name [optional] - the unique ID of the timer. You should supply this (see example below)
Code: Select all
function doSomething()
print("starting timer")
timer = sleep:start(self.id, "_callback", 10, "a_unique_id_for_the_timer_you_make")
end
function _callback()
print("timer finished")
end
LADDERS
Hoookay, so this one is a bit of a cop-out, since I'm not supplying models. You can get some awesome ladders from EOB (DJ, JKos, Tom, Bifrost, Thomson, Wallasaurus, montagneyaya) and other places. I'll just show how to wire it up without making someone fall screaming down a hole (and w/o excessive scripts, timers, and teleports copied all over)
Add the following to your objects.lua (in addition to your ladder definitions)
Code: Select all
cloneObject{
name = "dungeon_fake_pit",
baseObject = "pressure_plate_hidden" -- using this as the base object has the nice benefit of tilting the camera down slightly
model = "assets/models/env/dungeon_pit.fbx", -- you can use another pit model for temple or prison
hidden = false,
editorIcon = 40, -- pit icon
}
defineParticleSystem{
name = "screen_wipe",
emitters = {
-- glow
{
spawnBurst = true,
emissionRate = 20,
emissionTime = 0,
maxParticles = 20,
boxMin = {0,0,0},
boxMax = {0,0,0.2},
sprayAngle = {0,360},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {2, 2},
colorAnimation = false,
color0 = {0.0, 0.0, 0.0},
opacity = 1,
fadeIn = 1,
fadeOut = 1,
size = {5, 5},
gravity = {0,0,0},
airResistance = 0.3,
rotationSpeed = 1,
blendMode = "Translucent",
objectSpace = true,
}
}
}
Code: Select all
-- Ladder Change Function.
dlevel = self.level
dx = self.x
dy = self.y
df = self.facing
function setDestination(ignore,x,y,f,level)
dx = x
dy = y
df = f
dlevel = level
end
function activate()
playSound("party_enter_stairs")
party:playScreenEffect("screen_wipe")
stopParty:freezeParty() -- search for cMove for this explanation
sleep:start(self.id, "_teleport", 0.8, "ladder_timer_1")
end
function _teleport()
t = spawn("teleporter", party.level, party.x, party.y, df, _teleportID(self.id))
t:setTriggeredByParty(true)
t:setChangeFacing(true)
t:setInvisible(true)
t:setSilent(true)
t:setHideLight(true)
t:setScreenFlash(false)
t:setTeleportTarget(dx,dy,df,dlevel)
t:activate()
sleep:start(self.id, "_finish", 0.1, "ladder_timer_2") -- note the need for a unique timer ID here. The first timer still exists during this callback.
end
function _finish()
t = findEntity(_teleportID(self.id))
t:deactivate()
t:destroy()
stopParty:thawParty() -- search for cMove for this explanation
end
function _teleportID(objectID) -- shortcut for a unique ID for the teleporter
return "teleporter_"..objectID
end
Code: Select all
function onStep()
ladder:setDestination(party.x+1,party.y,party.facing,party.level) -- set the destination like you would for a teleport
ladder:activate()
end
What the script does is start fading the screen to black, freezes the party, waits until the screen is black, teleports the party, fades the screen to normal, and unfreezes the party. It's a much smoother transition that mimics the stairs transition (sound, black screen) and isn't as jarring as a plain invisible teleport. It's also pretty clean wherever you want to use it. Just keep in mind not to let the player activate this more than once per transition or it gets all screwy.
When I first started doing the ladder transition, I had a timer, script_entity, and teleporter for EACH ladder. now it's just a global script_entity, and one for each ladder. Much easier to maintain.
CAVEAT
I can't figure out how to get the "screen_wipe" particle to continue to generate after teleportation. It doesn't smooth out like I want it to.