ds2.9a12/bin/
ds2.9a12/extra/
ds2.9a12/extra/crat/
ds2.9a12/extra/creremote/
ds2.9a12/extra/mingw/
ds2.9a12/extra/wolfpaw/
ds2.9a12/fluffos-2.14-ds13/
ds2.9a12/fluffos-2.14-ds13/Win32/
ds2.9a12/fluffos-2.14-ds13/compat/
ds2.9a12/fluffos-2.14-ds13/compat/simuls/
ds2.9a12/fluffos-2.14-ds13/include/
ds2.9a12/fluffos-2.14-ds13/testsuite/
ds2.9a12/fluffos-2.14-ds13/testsuite/clone/
ds2.9a12/fluffos-2.14-ds13/testsuite/command/
ds2.9a12/fluffos-2.14-ds13/testsuite/data/
ds2.9a12/fluffos-2.14-ds13/testsuite/etc/
ds2.9a12/fluffos-2.14-ds13/testsuite/include/
ds2.9a12/fluffos-2.14-ds13/testsuite/inherit/
ds2.9a12/fluffos-2.14-ds13/testsuite/inherit/master/
ds2.9a12/fluffos-2.14-ds13/testsuite/log/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/compiler/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/efuns/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/operators/
ds2.9a12/fluffos-2.14-ds13/testsuite/u/
ds2.9a12/lib/cmds/admins/
ds2.9a12/lib/cmds/common/
ds2.9a12/lib/cmds/creators/include/
ds2.9a12/lib/daemon/services/
ds2.9a12/lib/daemon/tmp/
ds2.9a12/lib/doc/
ds2.9a12/lib/doc/bguide/
ds2.9a12/lib/doc/efun/all/
ds2.9a12/lib/doc/efun/arrays/
ds2.9a12/lib/doc/efun/buffers/
ds2.9a12/lib/doc/efun/compile/
ds2.9a12/lib/doc/efun/floats/
ds2.9a12/lib/doc/efun/functions/
ds2.9a12/lib/doc/efun/general/
ds2.9a12/lib/doc/efun/mixed/
ds2.9a12/lib/doc/efun/numbers/
ds2.9a12/lib/doc/efun/parsing/
ds2.9a12/lib/doc/hbook/
ds2.9a12/lib/doc/help/classes/
ds2.9a12/lib/doc/help/races/
ds2.9a12/lib/doc/lfun/
ds2.9a12/lib/doc/lfun/all/
ds2.9a12/lib/doc/lfun/lib/abilities/
ds2.9a12/lib/doc/lfun/lib/armor/
ds2.9a12/lib/doc/lfun/lib/bank/
ds2.9a12/lib/doc/lfun/lib/bot/
ds2.9a12/lib/doc/lfun/lib/clay/
ds2.9a12/lib/doc/lfun/lib/clean/
ds2.9a12/lib/doc/lfun/lib/clerk/
ds2.9a12/lib/doc/lfun/lib/client/
ds2.9a12/lib/doc/lfun/lib/combat/
ds2.9a12/lib/doc/lfun/lib/connect/
ds2.9a12/lib/doc/lfun/lib/container/
ds2.9a12/lib/doc/lfun/lib/corpse/
ds2.9a12/lib/doc/lfun/lib/creator/
ds2.9a12/lib/doc/lfun/lib/daemon/
ds2.9a12/lib/doc/lfun/lib/damage/
ds2.9a12/lib/doc/lfun/lib/deterioration/
ds2.9a12/lib/doc/lfun/lib/donate/
ds2.9a12/lib/doc/lfun/lib/door/
ds2.9a12/lib/doc/lfun/lib/equip/
ds2.9a12/lib/doc/lfun/lib/file/
ds2.9a12/lib/doc/lfun/lib/fish/
ds2.9a12/lib/doc/lfun/lib/fishing/
ds2.9a12/lib/doc/lfun/lib/flashlight/
ds2.9a12/lib/doc/lfun/lib/follow/
ds2.9a12/lib/doc/lfun/lib/ftp_client/
ds2.9a12/lib/doc/lfun/lib/ftp_data_connection/
ds2.9a12/lib/doc/lfun/lib/fuel/
ds2.9a12/lib/doc/lfun/lib/furnace/
ds2.9a12/lib/doc/lfun/lib/genetics/
ds2.9a12/lib/doc/lfun/lib/holder/
ds2.9a12/lib/doc/lfun/lib/id/
ds2.9a12/lib/doc/lfun/lib/interactive/
ds2.9a12/lib/doc/lfun/lib/lamp/
ds2.9a12/lib/doc/lfun/lib/leader/
ds2.9a12/lib/doc/lfun/lib/light/
ds2.9a12/lib/doc/lfun/lib/limb/
ds2.9a12/lib/doc/lfun/lib/living/
ds2.9a12/lib/doc/lfun/lib/load/
ds2.9a12/lib/doc/lfun/lib/look/
ds2.9a12/lib/doc/lfun/lib/manipulate/
ds2.9a12/lib/doc/lfun/lib/meal/
ds2.9a12/lib/doc/lfun/lib/messages/
ds2.9a12/lib/doc/lfun/lib/player/
ds2.9a12/lib/doc/lfun/lib/poison/
ds2.9a12/lib/doc/lfun/lib/position/
ds2.9a12/lib/doc/lfun/lib/post_office/
ds2.9a12/lib/doc/lfun/lib/potion/
ds2.9a12/lib/doc/lfun/lib/room/
ds2.9a12/lib/doc/lfun/lib/server/
ds2.9a12/lib/doc/lfun/lib/spell/
ds2.9a12/lib/doc/lfun/lib/torch/
ds2.9a12/lib/doc/lfun/lib/vendor/
ds2.9a12/lib/doc/lfun/lib/virt_sky/
ds2.9a12/lib/doc/lfun/lib/weapon/
ds2.9a12/lib/doc/lfun/lib/worn_storage/
ds2.9a12/lib/doc/lpc/basic/
ds2.9a12/lib/doc/lpc/concepts/
ds2.9a12/lib/doc/lpc/constructs/
ds2.9a12/lib/doc/lpc/etc/
ds2.9a12/lib/doc/lpc/intermediate/
ds2.9a12/lib/doc/lpc/types/
ds2.9a12/lib/doc/misc/
ds2.9a12/lib/doc/old/
ds2.9a12/lib/domains/
ds2.9a12/lib/domains/Praxis/adm/
ds2.9a12/lib/domains/Praxis/attic/
ds2.9a12/lib/domains/Praxis/cemetery/mon/
ds2.9a12/lib/domains/Praxis/data/
ds2.9a12/lib/domains/Praxis/death/
ds2.9a12/lib/domains/Praxis/mountains/
ds2.9a12/lib/domains/Praxis/obj/armour/
ds2.9a12/lib/domains/Praxis/obj/magic/
ds2.9a12/lib/domains/Praxis/obj/weapon/
ds2.9a12/lib/domains/Praxis/orc_valley/
ds2.9a12/lib/domains/Ylsrim/
ds2.9a12/lib/domains/Ylsrim/adm/
ds2.9a12/lib/domains/Ylsrim/armor/
ds2.9a12/lib/domains/Ylsrim/broken/
ds2.9a12/lib/domains/Ylsrim/fish/
ds2.9a12/lib/domains/Ylsrim/meal/
ds2.9a12/lib/domains/Ylsrim/npc/
ds2.9a12/lib/domains/Ylsrim/obj/
ds2.9a12/lib/domains/Ylsrim/virtual/
ds2.9a12/lib/domains/Ylsrim/weapon/
ds2.9a12/lib/domains/campus/adm/
ds2.9a12/lib/domains/campus/etc/
ds2.9a12/lib/domains/campus/meals/
ds2.9a12/lib/domains/campus/save/
ds2.9a12/lib/domains/campus/txt/ai/charles/
ds2.9a12/lib/domains/campus/txt/ai/charles/bak2/
ds2.9a12/lib/domains/campus/txt/ai/charles/bak2/bak1/
ds2.9a12/lib/domains/campus/txt/ai/charly/
ds2.9a12/lib/domains/campus/txt/ai/charly/bak/
ds2.9a12/lib/domains/campus/txt/jenny/
ds2.9a12/lib/domains/cave/doors/
ds2.9a12/lib/domains/cave/etc/
ds2.9a12/lib/domains/cave/meals/
ds2.9a12/lib/domains/cave/weap/
ds2.9a12/lib/domains/default/creator/
ds2.9a12/lib/domains/default/doors/
ds2.9a12/lib/domains/default/etc/
ds2.9a12/lib/domains/default/vehicles/
ds2.9a12/lib/domains/default/virtual/
ds2.9a12/lib/domains/default/weap/
ds2.9a12/lib/domains/town/txt/shame/
ds2.9a12/lib/domains/town/virtual/
ds2.9a12/lib/domains/town/virtual/bottom/
ds2.9a12/lib/domains/town/virtual/space/
ds2.9a12/lib/estates/
ds2.9a12/lib/ftp/
ds2.9a12/lib/lib/comp/
ds2.9a12/lib/lib/daemons/
ds2.9a12/lib/lib/daemons/include/
ds2.9a12/lib/lib/lvs/
ds2.9a12/lib/lib/user/
ds2.9a12/lib/lib/virtual/
ds2.9a12/lib/log/
ds2.9a12/lib/log/adm/
ds2.9a12/lib/log/archive/
ds2.9a12/lib/log/chan/
ds2.9a12/lib/log/errors/
ds2.9a12/lib/log/law/adm/
ds2.9a12/lib/log/law/email/
ds2.9a12/lib/log/law/names/
ds2.9a12/lib/log/law/sites-misc/
ds2.9a12/lib/log/law/sites-register/
ds2.9a12/lib/log/law/sites-tempban/
ds2.9a12/lib/log/law/sites-watch/
ds2.9a12/lib/log/open/
ds2.9a12/lib/log/reports/
ds2.9a12/lib/log/router/
ds2.9a12/lib/log/secure/
ds2.9a12/lib/log/watch/
ds2.9a12/lib/obj/book_source/
ds2.9a12/lib/obj/include/
ds2.9a12/lib/powers/prayers/
ds2.9a12/lib/powers/spells/
ds2.9a12/lib/realms/template/adm/
ds2.9a12/lib/realms/template/area/armor/
ds2.9a12/lib/realms/template/area/npc/
ds2.9a12/lib/realms/template/area/obj/
ds2.9a12/lib/realms/template/area/room/
ds2.9a12/lib/realms/template/area/weap/
ds2.9a12/lib/realms/template/bak/
ds2.9a12/lib/realms/template/cmds/
ds2.9a12/lib/save/kills/o/
ds2.9a12/lib/secure/cfg/classes/
ds2.9a12/lib/secure/cmds/builders/
ds2.9a12/lib/secure/cmds/creators/include/
ds2.9a12/lib/secure/cmds/players/
ds2.9a12/lib/secure/cmds/players/include/
ds2.9a12/lib/secure/daemon/imc2server/
ds2.9a12/lib/secure/daemon/include/
ds2.9a12/lib/secure/lib/
ds2.9a12/lib/secure/lib/include/
ds2.9a12/lib/secure/lib/net/include/
ds2.9a12/lib/secure/lib/std/
ds2.9a12/lib/secure/log/adm/
ds2.9a12/lib/secure/log/bak/
ds2.9a12/lib/secure/log/intermud/
ds2.9a12/lib/secure/log/network/
ds2.9a12/lib/secure/modules/
ds2.9a12/lib/secure/npc/
ds2.9a12/lib/secure/obj/include/
ds2.9a12/lib/secure/room/
ds2.9a12/lib/secure/save/
ds2.9a12/lib/secure/save/backup/
ds2.9a12/lib/secure/save/boards/
ds2.9a12/lib/secure/tmp/
ds2.9a12/lib/secure/upgrades/files/
ds2.9a12/lib/secure/verbs/creators/
ds2.9a12/lib/std/board/
ds2.9a12/lib/std/lib/
ds2.9a12/lib/tmp/
ds2.9a12/lib/verbs/admins/include/
ds2.9a12/lib/verbs/builders/
ds2.9a12/lib/verbs/common/
ds2.9a12/lib/verbs/common/include/
ds2.9a12/lib/verbs/creators/
ds2.9a12/lib/verbs/creators/include/
ds2.9a12/lib/verbs/rooms/
ds2.9a12/lib/verbs/rooms/include/
ds2.9a12/lib/www/client/
ds2.9a12/lib/www/errors/
ds2.9a12/lib/www/images/
ds2.9a12/lib/www/lpmuds/downloads_files/
ds2.9a12/lib/www/lpmuds/intermud_files/
ds2.9a12/lib/www/lpmuds/links_files/
ds2.9a12/win32/
/*    /daemon/seasons.c
 *    from the Dead Souls LPC Library
 *    handles game-based time
 *    created by Descartes of Borg 950508
 *    Version: @(#) seasons.c 1.7@(#)
 *    Last modified: 96/10/27
 */

#include <lib.h>
#include <cfg.h>
#include <config.h>
#include <function.h>
#include "include/seasons.h"

inherit LIB_DAEMON;

private static int CurrentDay, CurrentYear; 
private static int Dawn, Morning, Noon, Twilight, Night;
private static int ticktock;
private static string CurrentSeason, TimeOfDay;
private static mapping Moons;
private static class month CurrentMonth;
private static string *Days;
private static function *DawnCalls, *MorningCalls, *NoonCalls;
private static function *TwilightCalls, *NightCalls, *MidnightCalls;
private static class month *Months;

int eventTickTock(int tick){
    if(!tick) tick = 0;
    ticktock = tick;
    eventConfigure();
    return GetCurrentTime()/1200;
}

int GetTickTock(){ return ticktock; }

int *GetMudTime(){
    //return ({ GetHour(GetCurrentTime()), GetMinutes(GetCurrentTime()) });
    return ({ GetHour(time()), GetMinutes(time()) });
}


static void create() {
    string *lines;
    int i, maxi;

    daemon::create();
    DawnCalls = ({});
    MorningCalls = ({});
    NoonCalls = ({});
    TwilightCalls = ({});
    NightCalls = ({});
    MidnightCalls = ({});
    ticktock = 0;
    maxi = sizeof(lines = filter(explode(read_file(CFG_MONTHS), "\n"),
        (: $1 && $1 != "" && $1[0] != '#' :)));
    Months = allocate(maxi);
    for(i=0; i<maxi; i++) {
        Months[i] = new(class month);
        sscanf(lines[i], "%s:%s:%d:%d",((class month)Months[i])->Name,
          ((class month)Months[i])->Season,
          ((class month)Months[i])->Days,
          ((class month)Months[i])->DaylightHours);
    }
    Days = filter(explode(read_file(CFG_DAYS), "\n"),
      (: $1 && $1 != "" && $1[0] != '#' :));
    maxi = sizeof(lines = filter(explode(read_file(CFG_MOONS), "\n"),
        (: $1 && $1 != "" && $1[0] != '#' :)));
    Moons = allocate_mapping(maxi);
    for(i=0; i<maxi; i++) {
        string nom, id, desc, lnom;
        int phase;

        sscanf(lines[i], "%s:%d:%s:%s", nom, phase, id, desc);
        lnom = convert_name(nom);
        Moons[lnom] = new(class moon);
        ((class moon)Moons[lnom])->Name = nom;
        ((class moon)Moons[lnom])->Phase = phase;
        ((class moon)Moons[lnom])->Id = id;
        ((class moon)Moons[lnom])->Description = desc;
    }
    eventConfigure();
}

static void eventConfigure() {
    int i, x, days, tot, maxi;

    days = GetTime(time()) / (DAY_LENGTH * HOUR_LENGTH);
    for(tot=0, i=0, maxi = sizeof(Months); i<maxi; i++)
        tot += ((class month)Months[i])->Days;
    CurrentYear = days / tot + 1;
    days = (days % tot) + 1;
    for(i=0, maxi = sizeof(Months); i<maxi; i++) {
        if( days <= ((class month)Months[i])->Days ) {
            CurrentMonth = (class month)Months[i];
            CurrentSeason = ((class month)Months[i])->Season;
            CurrentDay = days;
            break;
        }
        else days -= ((class month)Months[i])->Days;
    }
    x = CurrentMonth->DaylightHours * HOUR_LENGTH;
    Morning = ((DAY_LENGTH * HOUR_LENGTH) - x) / 2;
    Twilight = Morning + x;
    Noon = (DAY_LENGTH * HOUR_LENGTH) / 2;
    if( Morning < HOUR_LENGTH ) {
        Dawn = Morning/2;
        Night = Twilight + Morning/2;
    }
    else {
        Dawn = Morning - HOUR_LENGTH;
        Night = Twilight + HOUR_LENGTH;
    }
    x = GetCurrentTime();
    if( x < Dawn ) {
        TimeOfDay = "night";
        call_out( (: eventDawn :), Dawn - x);
    }
    else if( x < Morning ) {
        TimeOfDay = "dawn";
        call_out( (: eventMorning :), Morning - x);
    }
    else if( x < Noon ) {
        TimeOfDay = "day";
        call_out( (: eventNoon :), Noon - x);
    }
    else if( x < Twilight ) {
        TimeOfDay = "day";
        call_out( (: eventTwilight :), Twilight - x);
    }
    else if( x < Night ) {
        TimeOfDay = "twilight";
        call_out( (: eventNight :), Night - x );
    }
    else {
        TimeOfDay = "night";
        call_out( (: eventMidnight :), (DAY_LENGTH * HOUR_LENGTH) - x);
    }
}

static void eventDawn() {
    object *obs;
    int i;

    call_out( (: eventMorning :), Morning - GetCurrentTime() );
    TimeOfDay = "dawn";
    obs = filter(users(), (: environment($1) &&
        environment($1)->GetClimateExposed() &&
        inherits(LIB_ROOM,environment($1)) &&
        !((int)environment($1)->GetProperty("no time")) :));
    message("environment",
      "%^YELLOW%^The sun appears just over the horizon.%^RESET%^",
      obs );
    i = sizeof(DawnCalls);
    while(i--) catch(evaluate(DawnCalls[i]));
}

static void eventMorning() {
    object *obs;
    int i;

    call_out( (: eventNoon :), Noon - GetCurrentTime());
    TimeOfDay = "day";
    obs = filter(users(), (: environment($1) &&
        (string)environment($1)->GetClimateExposed() &&
        inherits(LIB_ROOM,environment($1)) &&
        !((int)environment($1)->GetProperty("no time")) :));
    message("environment", "%^BOLD%^YELLOW%^The sun now shines completely "
      "on a new day.%^RESET%^", obs);
    i = sizeof(MorningCalls);
    while(i--) catch(evaluate(MorningCalls[i]));
}

static void eventNoon() {
    int i;
    call_out( (: eventTwilight :), Twilight - GetCurrentTime());
    TimeOfDay = "day";
    /* debug("Noon Time!"); */
    i = sizeof(NoonCalls);
    while(i--) catch(evaluate(NoonCalls[i]));
}

static void eventTwilight() {
    object *obs;
    int i;

    call_out( (: eventNight :), Night - GetCurrentTime() );
    TimeOfDay = "twilight";
    obs = filter(users(), (: environment($1) &&
        (string)environment($1)->GetClimateExposed() &&
        inherits(LIB_ROOM,environment($1)) &&
        !((int)environment($1)->GetProperty("no time")) :));
    message("environment", "%^CYAN%^The sun begins to fall away into "
      "twilight.%^RESET%^", obs);
    i = sizeof(TwilightCalls);
    while(i--) catch(evaluate(TwilightCalls[i]));
}

static void eventNight() {
    object *obs;
    int i,x;

    call_out( (: eventMidnight :),
      (DAY_LENGTH * HOUR_LENGTH) - GetCurrentTime() );
    TimeOfDay = "night";
    obs = filter(users(), (: environment($1) &&
        (string)environment($1)->GetClimateExposed() &&
        inherits(LIB_ROOM,environment($1)) &&
        !((int)environment($1)->GetProperty("no time")) :));
    message("environment",
      "%^BOLD%^BLUE%^Night darkens all that is real.%^RESET%^", obs);
    i = sizeof(NightCalls);
    while(i--){
        mixed f = NightCalls[i];
        if((x = functionp(f)) && !(x & FP_OWNER_DESTED)){
            catch(evaluate(f));
        }
    }
}

static void eventMidnight() {
    int i;

    CurrentDay++;
    i = CurrentMonth->Days;
    if( CurrentDay > i ) {
        int y;

        y = CurrentYear;
        eventConfigure();
        if( y != CurrentYear )
            message("shout", "Happy New Year!!!\nIt is now the year " +
              GetYearString(CurrentYear) + "!!!!!", users());
        return;
    }
    call_out( (: eventDawn :), Dawn);
    TimeOfDay = "night";
    /* debug("midnight!"); */
    i = sizeof(MidnightCalls);
    while(i--) catch(evaluate(MidnightCalls[i]));
}

int GetCurrentDay() { return CurrentDay; }

string GetCurrentDayName() { return GetDayName(time()); }

string GetCurrentMonth() { return CurrentMonth->Name; }

string GetCurrentSeason() { return CurrentSeason; }

// get seconds from the start of the day.
int GetCurrentTime() { return GetTime(time()) % (DAY_LENGTH * HOUR_LENGTH) + ticktock; }

int GetCurrentYear() { return CurrentYear; }

varargs int GetDay(int x) {
    int tot, days, i, maxi;

    if(!x) x = time();
    days = absolute_value(GetTime(x) / (DAY_LENGTH * HOUR_LENGTH));
    for(tot=0, i=0, maxi = sizeof(Months); i<maxi; i++)
        tot += ((class month)Months[i])->Days;
    days = (days % tot) + ( (x < DAY_ONE) ? 0 : 1 );
    if( x < DAY_ONE ) {
        i = sizeof(Months);
        while(i--) {
            if( days < ((class month)Months[i])->Days )
                return ((class month)Months[i])->Days - days;
            else days -= ((class month)Months[i])->Days;
        }
        return 0;
    }
    for(i=0, maxi = sizeof(Months); i<maxi; i++) {
        if( days <= ((class month)Months[i])->Days ) return days;
        else days -= ((class month)Months[i])->Days;
    }
    return 0;
}

varargs string GetDayName(int x) {
    int days;

    if(!x) x = time();
    days = absolute_value(GetTime(x) / (DAY_LENGTH * HOUR_LENGTH));
    return Days[days % sizeof(Days)];
}

string *GetDays() { return Days + ({}); }

int GetDaylightHours(string mon) {
    int i;

    i = sizeof(Months);
    while(i--) {
        if( ((class month)Months[i])->Name == mon )
            return ((class month)Months[i])->DaylightHours;
    }
    return 0;
}

varargs int GetHour(int x) {
    int y;

    if(!x)
        x = time();
    y = absolute_value(GetTime(x));
    y = y % (DAY_LENGTH * HOUR_LENGTH);
    if( x < DAY_ONE ) y = (DAY_LENGTH * HOUR_LENGTH) - y;
    return (y / HOUR_LENGTH);
}

varargs int GetMinutes(int x) {
    int y;

    if(!x)
        x = time();
    y = absolute_value(GetTime(x));
    y = y % (DAY_LENGTH * HOUR_LENGTH);
    if( x < DAY_ONE ) y = (DAY_LENGTH * HOUR_LENGTH) - y;
    return (y % HOUR_LENGTH) / (HOUR_LENGTH/60);
}

string GetMonth(int x) {
    int monthIndex;

    monthIndex = GetMonthIndex(x);
    return Months[monthIndex]->Name;
}

private varargs int GetMonthIndex(int x) {
    int tot, days, i, maxi;

    if(!x) x = time();
    if( x < DAY_ONE ) days = (DAY_ONE - x) / (DAY_LENGTH * HOUR_LENGTH);
    else days = GetTime(x) / (DAY_LENGTH * HOUR_LENGTH);
    for(tot=0, i=0, maxi = sizeof(Months); i<maxi; i++)
        tot += ((class month)Months[i])->Days;
    days = (days % tot) + ((x >= DAY_ONE) ? 1 : 0);
    if( x < DAY_ONE ) {
        i = sizeof(Months);
        while(i--) {
            if( days < ((class month)Months[i])->Days )
                return i;
            else days -= ((class month)Months[i])->Days;
        }
        return 0;
    }
    for(i=0, maxi = sizeof(Months); i<maxi; i++) {
        if( days <= ((class month)Months[i])->Days )
            return i;
        else days -= ((class month)Months[i])->Days;
    }
    return 0;
}

string *GetMonths() {
    string *ret = ({});
    int i, maxi;

    for(i=0, maxi = sizeof(Months); i<maxi; i++)
        ret += ({ ((class month)Months[i])->Name });
    return ret;
}

string GetSeason(int x) {
    int monthIndex;

    monthIndex = GetMonthIndex(x);
    return Months[monthIndex]->Season;
}

varargs int GetTime(int x) { if(!x) x = time(); return (x - DAY_ONE); }

string GetTimeOfDay() { return TimeOfDay; }

function AddTimeEvent(string tod, function f) {
    switch(tod) {
    case "dawn": DawnCalls += ({ f }); break;
    case "morning": MorningCalls += ({ f }); break;
    case "noon": NoonCalls += ({ f }); break;
    case "twilight": TwilightCalls += ({ f }); break;
    case "night": NightCalls += ({ f }); break;
    case "midnight": MidnightCalls += ({ f }); break;
    default: return 0;
    }
    return f;
}

mapping GetTimeEvents() {
    return ([ "dawn" : DawnCalls + ({}), "morning" : MorningCalls + ({}),
      "noon" : NoonCalls + ({}), "twilight" : TwilightCalls + ({}),
      "night" : NightCalls + ({}), "midnight" : MidnightCalls + ({}) ]);
}

varargs int GetYear(int x) {
    int i, tot;

    if(!x) x = time();
    i = sizeof(Months);
    while(i--) tot += ((class month)Months[i])->Days;
    i = (GetTime(x) / (DAY_LENGTH * HOUR_LENGTH)) / tot;
    if( x < DAY_ONE ) return i;
    else return i + 1;
}

string GetYearString(int x) {
    if( x < 0 ) return (x * (-1)) + " BN";
    else return x + " NM";
}


/*
 * Moon functions
 */
string array GetMoons() {
    return map(keys(Moons), (: ((class moon)Moons[$1])->Name :));
}

string GetPhaseName(mixed val) {
    if( stringp(val) ) {
        val = GetPhase(val);
    }
    switch(val) {
    case 0: return "new";
    case 1: return "waxing";
    case 2: return "waning";
    case 3: return "full";
    default: return "error";
    }
}

int GetPhase(string m) {
    int x, y, z;

    m = convert_name(m);
    x = ((class moon)Moons[m])->Phase;
    y = GetTime(time()) % x;
    z = x / 4;
    return y / z;
}

int GetRadiantLight() {
    switch( TimeOfDay ) {
    case "night": return (GetMoonLight() * 2);
    case "day": return 60;
    default: return 30;
    }
}

int GetMoonLight() {
    string *moons;
    int i, y = 0;

    i = sizeof(moons = keys(Moons));
    while(i--) {
        int z;

        z = GetPhase(moons[i]);
        if( z == 4) z = 2;
        y += z;
    }
    return y;
}

string GetLong(string arg) {
    string array arr, mn;
    object env;
    string tmp;
    int i;

    if( !(env = environment(this_player())) )
        return "You are in serious trouble.";
    switch(arg) {
    case "sun":
        switch(GetTimeOfDay()) {
        case "dawn":
            return "The sun is hanging low in the eastern sky.";
        case "day":
            return "The sun is shining brightly in the daytime sky.";
        case "twilight":
            return "The sun is sinking into the western sky.";
        case "night":
            return "There is no sun to be seen.";
        }
    case "moon": case "moons":
        if( GetTimeOfDay() != "night" ) return "During the day?";
        else {
            string *moons;
            int x = 0;

            i = sizeof(moons = keys(Moons));
            while(i--) {
                int y;

                if( (y = GetPhase(moons[i])) == 0 ) continue;
                else if( tmp )
                    tmp += (((class moon)Moons[moons[i]])->Name) +
                    " is " + GetPhaseName(y) + ".\n";
                else tmp = "\n" +
                    "You gaze up at the sky, and see the moons...\n"+
                    (((class moon)Moons[moons[i]])->Name) +
                    " is " +
                    GetPhaseName(y) + ".\n";
                x = 1;
            }
            if( !x ) return 0;
            else return tmp;
        }
    case "sky":
        if( GetTimeOfDay() == "night" ) {
            tmp =  GetLong("moon");
            if( !tmp ) {
                return "The sky is filled only with the glitter of stars.";
            }
            else {
                return tmp;
            }
        }
        else {
            string sky;

            tmp = GetLong("sun");
            if( this_player() ) {
                env = environment(this_player());
            }
            if( sky = env->GetSky() ) {
                env = find_object(sky);
                if( env ) {
                    object array obs = filter(all_inventory(env),
                      (: living($1) &&
                        !$1->GetInvis(this_player()) :));
                    /* function(object ob) { */
                    /* if( ob->GetInvis(this_player()) ) { */
                    /*     return 0; */
                    /* } */
                    /* if( living(ob) ) { */
                    /*     return 1; */
                    /* } */
                    /*     return 0; */
                    /* }); */

                    if( sizeof(obs) ) {
                        int maxi = sizeof(obs);

                        sky = obs[i]->GetName();
                        if( maxi == 1 ) {
                            sky += " is flying in the sky.";
                        }
                        else {
                            for(i=1; i<maxi; i++) {
                                if( i == maxi-1 ) {
                                    if( maxi == 2 ) {
                                        sky += " and ";
                                    }
                                    else {
                                        sky += ", and ";
                                    }
                                }
                                else {
                                    sky += ", ";
                                }
                                sky += obs[i]->GetName();
                            }
                            sky += " are flying in the sky.";
                        }
                        tmp = sky + "\n" + tmp;
                    }
                }
            }
            return tmp;
        }
    default:
        if( Moons[arg] ) return ((class moon)Moons[arg])->Description;
        arr = map(mn = keys(Moons), (: ((class moon)Moons[$1])->Id :));
        if( (i = member_array(arg, arr)) != -1 )
            return ((class moon)Moons[mn[i]])->Description;
        else return 0;
    }
}

int eventShow(object who, string args) {
    string str;
    if( !who || !sizeof(args) ) return 0;
    if( !str = GetLong(args) ) return 0;
    if( !(string)environment(who)->GetClimateExposed() ) {
        who->eventPrint("You can't see that from here!");
        return 1;
    }
    who->eventPrint(str);
    environment(who)->eventPrint((string)who->GetName() + " gazes toward the sky.", who);
    return 1;
}