openclonk/planet/Objects.ocd/Environment.ocd/Time.ocd/Script.c

161 lines
3.5 KiB
C

/*--
Time Controller
Author:Ringwall
Creates time based on the 24-hour time scheme.
Time is computed in minutes, which are by default
1/2 a second in real life (18 frames). This will
make each complete day/night cycle last 12 minutes
in real life.
--*/
local time;
// Sets the current time using a 24*60 minute clock scheme.
public func SetTime(int to_time)
{
// Set time.
time = to_time % (24 * 60);
// Adjust to time.
AdjustToTime();
return;
}
// Returns the time in minutes.
public func GetTime()
{
return time;
}
// Sets the number of frames per clonk-minute.
// Standard is 18 frames per minute, making a day-night cycle of 12 minutes.
// Setting minute lenght to 0 will stop day-night cycle.
public func SetCycleSpeed(int speed)
{
//GetEffect("IntTimeCycle", this).Interval = Max(0, speed);
RemoveEffect("IntTimeCycle", this);
AddEffect("IntTimeCycle", this, 100, Max(0, speed), this);
return;
}
public func GetCycleSpeed()
{
return GetEffect("IntTimeCycle", this).Interval;
}
local time_set;
protected func Initialize()
{
// Only one time control object.
if (ObjectCount(Find_ID(Environment_Time)) > 1)
return RemoveObject();
time_set = {
SunriseStart = 180,
SunriseEnd = 540,
SunsetStart = 900,
SunsetEnd = 1260,
};
// Add effect that controls time cycle.
AddEffect("IntTimeCycle", this, 100, 18, this);
// Set the time to midday (12:00).
time = 720;
// Create moon and stars.
if (FindObject(Find_ID(Environment_Celestial)))
{
CreateObject(Moon, LandscapeWidth() / 2, LandscapeHeight() / 6);
PlaceStars();
}
return;
}
public func IsDay()
{
var day_start = (time_set["SunriseStart"] + time_set["SunriseEnd"]) / 2;
var day_end = (time_set["SunsetStart"] + time_set["SunsetEnd"]) / 2;
if (Inside(time, day_start, day_end))
return true;
return false;
}
public func IsNight()
{
var night_start = (time_set["SunsetStart"] + time_set["SunsetEnd"]) / 2;
var night_end = (time_set["SunriseStart"] + time_set["SunriseEnd"]) / 2;
if (Inside(time, night_start, night_end))
return true;
return false;
}
private func PlaceStars()
{
//Star Creation
var maxamount = LandscapeWidth() * LandscapeHeight() / 40000;
var amount = 0;
while (amount != maxamount)
{
var pos;
if (pos = FindPosInMat("Sky", 0, 0, LandscapeWidth(), LandscapeHeight()))
CreateObject(Star, pos[0], pos[1]);
amount++;
}
return;
}
// Cycles through day and night.
protected func FxIntTimeCycleTimer(object target)
{
// Adjust to time.
AdjustToTime();
// Advance time.
time++;
time %= (24 * 60);
return 1;
}
// Adjusts the sky, celestial and others to the current time.
private func AdjustToTime()
{
var skyshade;
// Sunrise
if (Inside(time, time_set["SunriseStart"], time_set["SunriseEnd"]))
{
skyshade = Sin((GetTime() - 180) / 4, 255);
if (time == 540)
if (FindObject(Find_ID(Moon)))
FindObject(Find_ID(Moon))->Phase();
}
// Day
else if (Inside(time, time_set["SunriseEnd"], time_set["SunsetStart"]))
skyshade = 255;
//Sunset
else if (Inside(time, time_set["SunsetStart"], time_set["SunsetEnd"]))
skyshade = 255 - Sin((GetTime() - 900) / 4, 255);
// Night
else if (time > time_set["SunsetEnd"] || time < time_set["SunriseStart"])
skyshade = 0;
// Shade sky.
SetSkyAdjust(RGB(skyshade, skyshade, skyshade));
// Adjust celestial objects.
for (var celestial in FindObjects(Find_Func("IsCelestial")))
celestial->SetObjAlpha(255 - skyshade);
// Adjust clouds, TODO remedie this special case of white clouds on black sky.
return;
}
local Name = "Time";