/* /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 #include #include #include "include/seasons.h" inherit LIB_DAEMON; private static int CurrentDay, CurrentYear; private static int Dawn, Morning, Noon, Twilight, Night; private static int ticktock, pending; 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(!this_player() || !archp(this_player())) return 0; if(!tick) tick = 0; ticktock = tick; remove_call_out(pending); eventConfigure(); //return GetCurrentTime()/1200; return GetCurrentTime(); } int GetTickTock(){ return ticktock; } int *GetMudTime(){ //return ({ GetHour(GetCurrentTime()), GetMinutes(GetCurrentTime()) }); return ({ GetHour(time()+ticktock), GetMinutes(time()+ticktock) }); } static void create() { string *lines; int i, maxi; daemon::create(); ticktock = 0; maxi = sizeof(lines = filter(explode(read_file(CFG_MONTHS), "\n"), (: $1 && $1 != "" && $1[0] != '#' :))); Months = allocate(maxi); for(i=0; iName, ((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; iName = 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; DawnCalls = ({}); MorningCalls = ({}); NoonCalls = ({}); TwilightCalls = ({}); NightCalls = ({}); MidnightCalls = ({}); days = GetTime(time()+ticktock) / (DAY_LENGTH * HOUR_LENGTH); for(tot=0, i=0, maxi = sizeof(Months); iDays; CurrentYear = days / tot + 1; days = (days % tot) + 1; for(i=0, maxi = sizeof(Months); iDays ) { 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"; pending = call_out( (: eventDawn :), Dawn - x); } else if( x < Morning ) { TimeOfDay = "dawn"; pending = call_out( (: eventMorning :), Morning - x); } else if( x < Noon ) { TimeOfDay = "day"; pending = call_out( (: eventNoon :), Noon - x); } else if( x < Twilight ) { TimeOfDay = "day"; pending = call_out( (: eventTwilight :), Twilight - x); } else if( x < Night ) { TimeOfDay = "twilight"; pending = call_out( (: eventNight :), Night - x ); } else { TimeOfDay = "night"; pending = call_out( (: eventMidnight :), (DAY_LENGTH * HOUR_LENGTH) - x); } } static void eventDawn() { object *obs; int i; pending = call_out( (: eventMorning :), Morning - GetCurrentTime() ); TimeOfDay = "dawn"; obs = filter(users(), (: environment($1) && environment($1)->GetClimateExposed() && inherits(LIB_ROOM,environment($1)) && !(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; pending = call_out( (: eventNoon :), Noon - GetCurrentTime()); TimeOfDay = "day"; obs = filter(users(), (: environment($1) && environment($1)->GetClimateExposed() && inherits(LIB_ROOM,environment($1)) && !(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; pending = call_out( (: eventTwilight :), Twilight - GetCurrentTime()); TimeOfDay = "day"; i = sizeof(NoonCalls); while(i--) catch(evaluate(NoonCalls[i])); } static void eventTwilight() { object *obs; int i; pending = call_out( (: eventNight :), Night - GetCurrentTime() ); TimeOfDay = "twilight"; obs = filter(users(), (: environment($1) && environment($1)->GetClimateExposed() && inherits(LIB_ROOM,environment($1)) && !(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; pending = call_out( (: eventMidnight :), (DAY_LENGTH * HOUR_LENGTH) - GetCurrentTime() ); TimeOfDay = "night"; obs = filter(users(), (: environment($1) && environment($1)->GetClimateExposed() && inherits(LIB_ROOM,environment($1)) && !(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; } pending = call_out( (: eventDawn :), Dawn); TimeOfDay = "night"; i = sizeof(MidnightCalls); while(i--) catch(evaluate(MidnightCalls[i])); } int GetCurrentDay() { return CurrentDay; } string GetCurrentDayName() { return GetDayName(time()+ticktock); } string GetCurrentMonth() { return CurrentMonth->Name; } string GetCurrentSeason() { return CurrentSeason; } // get seconds from the start of the day. int GetCurrentTime() { return GetTime(time()+ticktock) % (DAY_LENGTH * HOUR_LENGTH); } int GetCurrentYear() { return CurrentYear; } varargs int GetDay(int x) { int tot, days, i, maxi; if(!x) x = time()+ticktock; days = absolute_value(GetTime(x) / (DAY_LENGTH * HOUR_LENGTH)); for(tot=0, i=0, maxi = sizeof(Months); iDays; 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); iDays ) return days; else days -= ((class month)Months[i])->Days; } return 0; } varargs string GetDayName(int x) { int days; if(!x) x = time()+ticktock; 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()+ticktock; 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()+ticktock; 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()+ticktock; 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); iDays; 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); iDays ) return i; else days -= ((class month)Months[i])->Days; } return 0; } string *GetMonths() { string *ret = ({}); int i, maxi; for(i=0, maxi = sizeof(Months); iName }); return ret; } string GetSeason(int x) { int monthIndex; monthIndex = GetMonthIndex(x); return Months[monthIndex]->Season; } varargs int GetTime(int x) { if(!x) x = time()+ticktock; 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()+ticktock; 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()+ticktock) % 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; iGetName(); } 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( !environment(who)->GetClimateExposed() ) { who->eventPrint("You can't see that from here!"); return 1; } who->eventPrint(str); environment(who)->eventPrint(who->GetName() + " gazes toward the sky.", who); return 1; }