//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:
 
 menschenfresser@rcn.com

 */



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

/*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++;
	}
}
;

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

