//SunTracker.t

#include <adv3.h>
#include <en_us.h>
#include <timesys.h>

/*For use with Kevin L. Forchione's excellent Timesys module.
*
*By Zachary Hutchinson
*
*This module addition contains two separate functions: the sun tracker
*and code which will correct the time when travelling between
*locations.
*
*Sun Tracker:
*The sun tracker is to be used with a daemon. I've tried to use Kevin's
*Timesys specific daemons, but for reasons of my own stupidity, no doubt,
*I couldn't get them to repeat themselves, so if you can get them to
*work, great...and if not you can use a regular daemon. Here's my
*suggestion:
*
*new Daemon(sun_tracker,&timeAction,1);
*
*This daemon will check the movement of the sun every minute of the day.
*You can of course change the regularity at which the daemon runs...if
*you see a purpose in doing so. I see two basic uses for this module
*addition. First off, it is simply to add environment, allowing the
*player to "examine sky" and get a changing response. Second, and more
*importantly, are the four global references which could be used for a
*great many things (see suggestions below).
*
*You'll also need to initially set the time of day in which the story
*opens; otherwise the player can x sky on the first turn and get a wrong
*response. It is presently set to daytime.
*
*From there it is all a matter of simply making outdoor rooms inherit
*from OutdoorRoom, like you normally would.
*
*Possible modification ideas:
*-You can add more times of the day (i.e. afternoon, morning, etc)
*-Customize the time of day descriptions, even including a changing list.
*-With Mike's new actor agendas, or the numerous other ways to affect
*NPCs, one could use the global references to say, have an NPC, show up
*for work, or go home, or go to sleep. You could even add in some random variables so
*that all NPCs don't always show up for work at the strike of 7am. I
*can think of a thousand uses for them. This is precisely where I think
*Kevin's module shines.
*-One could abstract the original sky object and turn it into a class.
*This would then allow for multiple Outdoor regions to have different
*sky descriptions.
*-I suppose a clever person could add in some randomness to the
*changing of the times of day...so that the sun doesn't always go down
*at the same time...etc.
*
*Strange Quirks in SunTracker:
*-Whenever the player types 'x sky' for the first time, 5 extra minutes
*are added to the clock on top of the regular one minute increase. I'll
*be damned if I know why. While it is annoying, I don't think it is
*game breaking. Perhaps a better programmer than myself can uncover why
*this happens. It doesn't seem to happen in any other case, even if the
*PC is moved to a different location.
*-Also if a player types "x sky" when the clock is showing 9:00, he
*will still get "It is dusk." as a response. But if you then repeat the
*command at 9:01, you'll get "It is night." So the transition is a
*little sketchy. I'm not such a T3 expert to understand why this is
*happening. It probably has something to do with the order in which
*things are processed.

*TravelTime Code:
*For reasons unknown to me, if you use Kevin's two new functions
*(addToTime & subtractFromTime) inside a room's directions,
*the time will be tripled or quadrupled...I forget which. To use the
*function you would do something like this:

startroom: Room
       //regular room code

       north
       {
               TravelTime(0,0,4,0);
               return(secondroom);
       }
;

secondroom: Room
       //regular room code

       south = startroom
;

*What this code will do is make TOTAL travel time between two rooms 5
*minutes (you must always figure the standard rate at which time passes
*for any given action, which by Timesys default is 1). Even though the
*code is only in one room, it will take five minutes to travel in either
*direction. You can duplicate startroom's code in the second room and it
*will still take 5 minutes to travel either way. You can do that if it
*helps you to remember what's going on, or if you want different travel
*times between these two rooms (i.e. if the character is walking up a
*steep hill it might take 30 minutes, whereas going down takes
*20...whatever).
*
*There may be an easier way to keep the travel time from duplicating
*when using addToTime and subtractFromTime in room travel, and if so,
*let me know.
*
*Also, SunTacket.t is open for anyone to use in any way--to change,
*modify, call their own, etc. I take no responsibility, if using this
*module addition results in you making a crappy game, I am not liable.
*The only thing I ask, is that if you make some kickass improvement to
*it, you drop me a line...as I might want to use your improvements. :)
*
*If you have any questions, drop me a line at:

[email protected]

*/



/*-------------------------------------------------------------*/

/*Add global references for the various times of day.
*/

modify libGlobal
{
       isNight = nil
       isDay = true
       isDawn = nil
       isDusk = nil
}

/*-------------------------------------------------------*/

/*The sky object. Feel free to add more vocabulary or desc here.
*/

thesky: Distant, RoomPart 'sky' 'sky'
       desc
       {
               if(libGlobal.isDay==true)
                       "It is daytime. ";
               if(libGlobal.isNight==true)
                       "It is night. ";
               if(libGlobal.isDawn==true)
                       "It is dawn. ";
               if(libGlobal.isDusk==true)
                       "It is dusk. ";
       }
;

/*------------------------------------------------------------------*/

/*modify OutdoorRoom so that all outdoor rooms use the sky object by
*default.
*/

modify OutdoorRoom
       roomParts = [defaultGround, thesky]
;

/*--------------------------------------------------------------------*/

sun_tracker: object
       timeAction()
       {
               local dtlist, hour_;

               /*Gets a list of [hour, minute, second], but we only need the
                *hour.
                */
               dtlist = gWallClock.getTimeVals(gWallClock.getCurrClockRatio());

               hour_ = dtlist[1];

               /*Change the global variables to determine whether or not it is
                *presently night or day, dusk or dawn.
                */

               if(hour_ == 6)
               {
                       libGlobal.isNight=nil;
                       libGlobal.isDawn=true;
                       libGlobal.isDay=nil;
                       libGlobal.isDusk=nil;
               }
               if(hour_ >= 7 && hour_ < 20)
               {
                       libGlobal.isDawn=nil;
                       libGlobal.isDay=true;
                       libGlobal.isNight=nil;
                       libGlobal.isDusk=nil;
               }
               if(hour_ == 20)
               {
                       libGlobal.isDay=nil;
                       libGlobal.isDusk=true;
                       libGlobal.isNight=nil;
                       libGlobal.isDawn=nil;
               }
               if((hour_ >= 21) || (hour_ >= 0 && hour_ < 6))
               {
                       libGlobal.isDusk=nil;
                       libGlobal.isDay=nil;
                       libGlobal.isDawn=nil;
                       libGlobal.isNight=true;
               }
       }
;


/*-------------------------------------------------------------------*/

/*I had to do this so that each room's timeCounter is reset when the
*player leaves the room. Otherwise, the extra travel time would only be
*called with the PC leaves in a given direction for the first time.
*/

modify BasicLocation
       travelerLeaving(traveler, dest, connector)
       {
               gPlayerChar.location.timeCounter=0;

               /* describe the departure */
               if (dest != traveler.location)
               traveler.describeDeparture(dest, connector);
       }
;
/*-------------------------------------------------------------*/

//adds a timeCounter to all rooms.

modify Room
       timeCounter = 0
;

/*----------------------------------------------------------*/

/*Tests to see if timeCounter has not been used, if not, it adds the
*travel time and prevents further incrementation until the PC vacates the
*room.
*/

TravelTime(day, hour, minute, second)
{
       local a, b, c, d;
       a=day;
       b=hour;
       c=minute;
       d=second;
       if(gPlayerChar.location.timeCounter==0)
       {
               gWallClock.addToTime(a,b,c,d);
               gPlayerChar.location.timeCounter++;
       }
}
;

/*-----------------------------------------------------------*/