Clocks With Chimes

From The DarkMod Wiki
Jump to: navigation, search

Written by grayman, who started with a set of instructions for a non-chiming clock, written by Fidcal.


Introduction

SUMMARY: A TDM 2.07+ script and clock setup that lets the clock chime on the quarter-hour and hour.

This assumes that the clock's hand movement is managed by the materials for the big and little hands.

The Clock

A prefab grandfather clock with chime support is provided in prefabs/furniture/misc/grandfather_clock.pfb. Place one in your map and look how it's set up. By default, this clock is set to 2:00, which is where the hands will point at mission start. If you want to change the starting time, set these spawnargs:

shaderparm7 H

shaderparm8 M

H = The hour

M = The minute

If you set M to anything but 0, you'll need to set H accordingly. For example, here are settings for starting at 2:15 ...

shaderparm7 2.25

shaderparm8 15

The Clock Scripts

This is the script that keeps time and rotates the clock hands. See next section for how to set it up...

 // ------------------------------- HOUSE TIME - CLOCK CHIMES --------------------------------------
 
 #define START_HR	       2
 #define START_MIN	       0
 #define TIME_INTERVAL        15
 #define CHIME_PAUSE         1.9
 
 // Each clock targets speakers that handle the chimes.
 //
 // target0 is one of the speakers that handles the hour chime.
 // target1 is one of the speakers that handles the hour chime.
 // target2 is one of the speakers that handles the hour chime.
 // target3 is the speaker that handles the 15-min chime.
 // target4 is the speaker that handles the 30-min chime.
 // target5 is the speaker that handles the 45-min chime.
 // target6 is the speaker that handles the 60-min chime.
 
 void ChimeMinutes( entity clock, float minutes )
 {
 	entity speaker;
 	if ( minutes == TIME_INTERVAL )
 	{
 		speaker = clock.getTarget(3);
 	}
 	else if ( minutes == 2*TIME_INTERVAL )
 	{
 		speaker = clock.getTarget(4);
 	}
 	else // 3*TIME_INTERVAL
 	{
 		speaker = clock.getTarget(5);
 	}
 	speaker.activate($player1);
 }
 
 // Each clock targets three speakers that handle the individual
 // hour chimes. Having three rather than one allows us to
 // overlap the chimes. Three is the minimum number needed to
 // achieve a nice sequence of overlapped chimes.
 //
 // target6 is the speaker that handles the pre-chime sound.
 // target{0,1,2} are the speakers that handle the hour chimes.
 
 void ChimeHour( entity clock, float hour)
 {
 	clock.getTarget(6).activate($player1);
 	sys.wait(14.5); // let this chime nearly complete. there's a little blend in the last second or so.
 
 	entity speaker1 = clock.getTarget(0);
 
 	speaker1.activate($player1);
 	if ( hour > 1 )
 	{
 		sys.wait(CHIME_PAUSE);
 		entity speaker2 = clock.getTarget(1);
 		speaker2.activate($player1);
 		if ( hour > 2 )
 		{
 			sys.wait(CHIME_PAUSE);
 			entity speaker3 = clock.getTarget(2);
 			speaker3.activate($player1);
 			if ( hour > 3 )
 			{
 				sys.wait(CHIME_PAUSE);
 				speaker1.activate($player1);
 				if ( hour > 4 )
 				{
 					sys.wait(CHIME_PAUSE);
 					speaker2.activate($player1);
 					if ( hour > 5 )
 					{
 						sys.wait(CHIME_PAUSE);
 						speaker3.activate($player1);
 						if ( hour > 6 )
 						{
 							sys.wait(CHIME_PAUSE);
 							speaker1.activate($player1);
 							if ( hour > 7 )
 							{
 								sys.wait(CHIME_PAUSE);
 								speaker2.activate($player1);
 								if ( hour > 8 )
 								{
 									sys.wait(CHIME_PAUSE);
 									speaker3.activate($player1);
 									if ( hour > 9 )
 									{
 										sys.wait(CHIME_PAUSE);
 										speaker1.activate($player1);
 										if ( hour > 10 )
 										{
 											sys.wait(CHIME_PAUSE);
 											speaker2.activate($player1);
 											if ( hour > 11 )
 											{
 												sys.wait(CHIME_PAUSE);
 												speaker3.activate($player1);
 											}
 										}
 									}
 								}
 							}
 						}
 					}
 				}
 			}
 		}
 	}
 }
 
 // HouseTime()
 //
 // - chimes the clocks every TIME_INTERVAL minutes
 // - chimes the clocks at the top of each hour, one chime for each hour
 
 void HouseTime()
 {
 	float timeHr  = START_HR;
 	float timeMin = START_MIN;
 
 	while ( 1 )
 	{
 		if ( timeMin != 4*TIME_INTERVAL )
 		{
 			// play minutes chime at each clock
 
 			thread ChimeMinutes( $Clock1, timeMin );
 			//thread ChimeMinutes( $Clock2, timeMin );
 		}
 		else
 		{
 			timeMin = 0; // top of the hour
 			timeHr = timeHr + 1;
 			if ( timeHr == 13 )
 			{
 				timeHr = 1;
 			}
 
 			// play hour chime at each clock
 
 			thread ChimeHour( $Clock1, timeHr );
 			//thread ChimeHour( $Clock2, timeHr );
 		}
 
 		sys.wait(TIME_INTERVAL*60); // sleep for TIME_INTERVAL minutes
 		timeMin = timeMin + TIME_INTERVAL;
 	}
 }  


How to Set Up the Scripts & Clock

The clock scripts are listed in the previous section. This is how you set them up...

  • Copy the ChimeMinutes(), ChimeHour() and HouseTime() scripts from above.
  • If you already have a script file for your map then paste these scripts into it (above the main() routine), or....
  • If you haven't already got a script file then paste the clock scripts into your plain text editor and save them in the same folder as your map with the same name but suffix .script. Example :
    mymapname.map
    mymapname.script. Add a main() routine.
  • Edit the lines START_HR and START_MIN for the time you want the clock to show at the start.
  • Resave the file.
  • Import one of the clock prefabs.
  • Make sure the clock entity is named "Clock1".
  • Position and turn the entire clock prefab to face the way you want it in-game.
  • The clock is now ready to keep and show time in your Dark Mod mission.
  • If you want another clock, import another prefab clock and place it where you want. DR should name it "Clock2". Look for the lines in the scripts that reference "Clock2" and uncomment them (Delete the // at the start of the line). If you add a third clock, add lines for "Clock3" beneath the lines that reference "Clock2". Further clocks can be added the same way.

Starting the Clock at Mission Start

  • To start the clock running at the start of the mission you must also have in your script file this main() routine (add it if not there) and insert a line between its curly brackets as shown. The main() routine must be placed BELOW the HouseTime() script routine:
 void main ()
 {
 	thread HouseTime();
 }
  • The main() routine will run automatically at mission start and the clock will begin working.