My take: with diagnostics and formatting for clarity:
C-like:
integer _boundary = 500;
float _interval = 10;
vector _cur_pos;
vector _pre_pos;
integer in_space() {
return(above(_cur_pos.z));
}
integer below(float h) {
return(h < _boundary);
}
integer above(float h) {
return(h >= _boundary);
}
string eval2(integer b1, integer b2) {
string s;
if (b1) s = "Y"; else s = "N";
if (b2) s += "Y"; else s += "N";
return s;
}
default
{
state_entry() {
llSetTimerEvent(_interval);
_cur_pos = llGetPos();
}
timer()
{
_pre_pos = _cur_pos;
_cur_pos = llGetPos();
if (below(_cur_pos.z)) llOwnerSay("now below");
if (above(_cur_pos.z)) llOwnerSay("now above");
string eval = eval2(
above(_pre_pos.z),
above(_cur_pos.z)
);
llOwnerSay(eval);
if (eval == "YN") llOwnerSay("@setenv_preset:midday=Force");
if (eval == "NY") llOwnerSay("@setenv_preset:midnight=Force");
if (in_space()) llOwnerSay("you are now in space");
else llOwnerSay("you are now below space");
}
}
without diagnostics, the timer code is:
C-like:
timer()
{
_pre_pos = _cur_pos;
_cur_pos = llGetPos();
string eval = eval2(above(_pre_pos.z),above(_cur_pos.z));
if (eval == "YN") llOwnerSay("@setenv_preset:midday=Force");
if (eval == "NY") llOwnerSay("@setenv_preset:midnight=Force");
}
}
(saves 8 lines)
Every time you save a value state you introduce a risk of logic errors whenever the values that state is based on changes, which is why I changed "space" from a value to a function - to make sure I was working with correct assumptions.
My use of eval2() is a trick I developed to collapse complex conditional logic, to make the code easier to read and less error prone. It REALLY simplifies things when you're working with multiple conditions and can be extended to eval3, eval4, ... etc.
pre & cur values make it more obvious when comparing a "before" value with a "current" value
prefixing a _ is just a convention I use to denote globals. The "g" prefix just looks clumsy to me for some strange reason, and it's easier to notice the underline when scanning code.
EDIT: found a bug. Code presupposes an avatar is initially ground level, and if they start above the space boundary the environmental preset is never changed. state_entry should add a condition to check for the avatar starting above or below the space boundary height and set the environment accordingly for each.
EDIT: you can get rid of the eval2 functionality and just use the in_space() function on each timer call to set the environment. Still, it's a neat trick, especially when conditional logic gets all tangled.
EDIT: adding a 2nd boundary value would let you graduate the effect to midday -> evening (or morning) -> midnight