Hey, we have forums!

Author Topic: Day-cycling script  (Read 9427 times)

0 Members and 1 Guest are viewing this topic.

Offline Particlese

  • Bit Bit
  • ****
  • Posts: 85
    • View Profile
Day-cycling script
« on: January 20, 2009, 08:21:18 am »
Here's a script for a node that changes the tint of the whole scene to make it look like the day is passing by.  It looks decent with gradTop="0.8 0.8 0.8" and gradBtm="0 0.4 0.6" in the map file or editor.  You can try it out here.  The little bit of coral above the starting point toggles the color cycling.  Suggestions are welcomed!  Also, because I'm lazy, that file has some more pierogi mod tests in it, so feel free to look around.  Just note that the "SJ" map is waaaaay too big right now and will be changed.  :P

Those of you who know the ins and outs of Lua and/or Aquaria scripting:  are there any changes I should make to the day-cycling script?  I tried using math.pi(), but the script wouldn't run, so I calculated it within the script.  Also, I can't for the life of me make setFlag() work.  I can getFlag() all day on custom-numbered flags, and set and get the built-in ones, but trying setFlag() on a custom one crashes Aquaria every time, probably because it points to somewhere naughty.  Is there a flag creation function hidden somewhere?  Flags would be nice for keeping track of the time (even in integer form) and many other things between level changes.
Code: [Select]
dofile("scripts/entities/entityinclude.lua")

active=true        --Choose whether to wait for activation before starting to change the time of day.
pi=2*math.asin(1)  --Make pi!
lengthofday=20     --Change the first number to the length of day (in seconds).
c=pi/lengthofday   --Provide a conversion factor from seconds to radians so we don't have to calculate it every update.
r,g,b=0,0,0        --Initialize some stuff.
t=lengthofday/2    --Set the starting point of the cycle.

function init(me)
node_setCursorActivation(me, true)
end

function activate(me)
shakeCamera(10,0.1)
active=not active --not to be confused with "active=false" :)
end

function update(me, dt)
if active then
t=(t+dt)%lengthofday --Prevent a runaway t.
--setControlHint("The time of day is " .. t/lengthofday .. ".",0,0,0,3)
thecos=math.cos(c*(t-lengthofday/2)) --Trig is expensive, so do this once instead of thrice.
r=math.min(1,0.3+8*thecos^3)
g=math.min(1,0.4+2*thecos^2)
b=math.min(1,0.5+  thecos^4)
setSceneColor(r,g,b,0)
end
end
And because I'm a dork, here's a graph of what the three colors are doing over the course of a "day":

Offline Dolphin's Cry

  • Bit Bit
  • ****
  • Posts: 61
    • View Profile
Re: Day-cycling script
« Reply #1 on: January 20, 2009, 09:53:17 pm »
math.pi contains a number, not a function, so you would use it like this:

local f = math.sin(x*math.pi)
Can you hear the dolphin's cry?

Offline Edwards

  • Bit Bit
  • ****
  • Posts: 93
    • View Profile
Re: Day-cycling script
« Reply #2 on: January 20, 2009, 11:17:09 pm »
setFlag works perectly fine for me for custom-numbered flags, at least for the handful (below 1024) I've tried using.  I have a line in one of my scripts: setFlag(390, x), where 390 is the flag I'm using, and x is a variable for a couple lines earlier.  Perhaps you're using flags above 1024, and Aquaria doesn't assign more space than that to its internal array of flags?

Anyway, I haven't tried this yet, but it sounds like a nice addition to the game.  Suggestion: Use a flag or something to record a general time of day (morning, afternoon, evening, night, etc.), so that other scripts can use the current time of day to determine things like how entities act, or possibly even what songs do.

- Edwards
You should only need one canister shell to bag your deer using your howitzer, but assemble more than one if  you have a mind to.1

Offline Particlese

  • Bit Bit
  • ****
  • Posts: 85
    • View Profile
Re: Day-cycling script
« Reply #3 on: January 21, 2009, 01:24:06 am »
I thought I had tried math.pi, too, but I guess I messed up something else at the same time. :-\

Thanks for the <1024 suggestion for flags.  I was using 2000 and 2001 to stay away from the entityinclude flags, so I'll try a lower number and let you know how it goes.  I'll probably store the time both in predefined chunks and as a number between 0 and 1023 or something.  Then scripts can easily reference whichever one is appropriate.  I was just going to use it for entity behavior, but I like the idea of affecting songs.  My first thought was Ocarina of Time's Sun Song (which toggles day and night.) :)

Edit:  Yup, that did the trick on both accounts, and the flags persist after warping.  Something interesting I found in entityinclude.lua was a line that read "MAX_FLAGS = 1024".  I don't think there's any reason to try changing it at this point, though.  Thanks for the help!

Edit2:  Here's the new version of the script.  I uploaded the new version of the test mod over the old one, so see the link in the first post for that.
Code: [Select]
dofile("scripts/entities/entityinclude.lua")
dofile("_mods/pierogitest/scripts/includes.lua")

active=true        --Choose whether to wait for activation before starting to change the time of day.
c=math.pi/DAY_LENGTH   --Provide a conversion factor from seconds to radians so we don't have to calculate it every update.
r,g,b=0,0,0        --Initialize some stuff.

function init(me)
node_setCursorActivation(me, true)
t=getFlag(FLAG_DAYCYCLE_NUM)/1000 --Retreive the previously stored time of day.
end

function activate(me)
shakeCamera(10,0.1)
active=not active --not to be confused with "active=false" :)
if active then
setControlHint("Day cycling on.", 0, 0, 0, 4)
else
setControlHint("Day cycling off.", 0, 0, 0, 4)
end
end

function update(me, dt)
if active then
t=(t+dt)%DAY_LENGTH --Keep t between 0 and 1 to prevent an eventual runaway t.
----- Update flags -----
setFlag(FLAG_DAYCYCLE_NUM,t*1000) --This might not change every update due to rounding errors, but it's good enough.
if     t>=0.90*DAY_LENGTH or  t<0.15*DAY_LENGTH then
setFlag(FLAG_DAYCYCLE_NAME,TOD_NIGHT)
--setControlHint("It is nighttime.", 0,0,0,3)
elseif t>=0.15*DAY_LENGTH and t<0.50*DAY_LENGTH then
setFlag(FLAG_DAYCYCLE_NAME,TOD_MORNING)
--setControlHint("It is morning.",   0,0,0,3)
elseif t>=0.50*DAY_LENGTH and t<0.75*DAY_LENGTH then
setFlag(FLAG_DAYCYCLE_NAME,TOD_AFTERNOON)
--setControlHint("It is after noon.",0,0,0,3)
elseif t>=0.75*DAY_LENGTH and t<0.90*DAY_LENGTH then
setFlag(FLAG_DAYCYCLE_NAME,TOD_EVENING)
--setControlHint("It is evening.",   0,0,0,3)
end
----- Tint Scene -----
--setControlHint("The time of day is " .. t/lengthofday .. ".",0,0,0,3)
thecos=math.cos(c*(t-DAY_LENGTH/2)) --Do this once instead of thrice.
r=math.min(1,0.3+8*thecos^3)
g=math.min(1,0.4+2*thecos^2)
b=math.min(1,0.5+  thecos^4)
setSceneColor(r,g,b,0)
end
end
« Last Edit: January 21, 2009, 06:45:36 am by Particlese »

Offline Particlese

  • Bit Bit
  • ****
  • Posts: 85
    • View Profile
Re: Day-cycling script
« Reply #4 on: January 25, 2009, 06:34:53 am »
Does anyone know a way to suppress debug output when using setFlag?  Since this script currently sets two flags every update, my debug log is getting pretty big.  I'll eventually make the script set the flags less frequently in the interest of efficiency, but even then, there will be many "setting flag [ x ] to y" lines dumped into the log as the "days" go by.  Something like setFlag(FLAG,flagVal,boolDebugless) would be great, but that doesn't seem to work.