OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
SunModule.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using System.Reflection;
31 using log4net;
32 using Mono.Addins;
33 using Nini.Config;
34 using OpenMetaverse;
35 using OpenSim.Framework;
36 using OpenSim.Region.Framework.Interfaces;
37 using OpenSim.Region.Framework.Scenes;
38 
39 namespace OpenSim.Region.CoreModules
40 {
41  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SunModule")]
42  public class SunModule : ISunModule
43  {
48 
49  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 
51  //
52  // Global Constants used to determine where in the sky the sun is
53  //
54  private const double m_SeasonalTilt = 0.03 * Math.PI; // A daily shift of approximately 1.7188 degrees
55  private const double m_AverageTilt = -0.25 * Math.PI; // A 45 degree tilt
56  private const double m_SunCycle = 2.0D * Math.PI; // A perfect circle measured in radians
57  private const double m_SeasonalCycle = 2.0D * Math.PI; // Ditto
58 
59  //
60  // Per Region Values
61  //
62 
63  private bool ready = false;
64 
65  // This solves a chick before the egg problem
66  // the local SunFixedHour and SunFixed variables MUST be updated
67  // at least once with the proper Region Settings before we start
68  // updating those region settings in GenSunPos()
69  private bool receivedEstateToolsSunUpdate = false;
70 
71  // Sun's position information is updated and sent to clients every m_UpdateInterval frames
72  private int m_UpdateInterval = 0;
73 
74  // Number of real time hours per virtual day
75  private double m_DayLengthHours = 0;
76 
77  // Number of virtual days to a virtual year
78  private int m_YearLengthDays = 0;
79 
80  // Ratio of Daylight hours to Night time hours. This is accomplished by shifting the
81  // sun's orbit above the horizon
82  private double m_HorizonShift = 0;
83 
84  // Used to scale current and positional time to adjust length of an hour during day vs night.
85  private double m_DayTimeSunHourScale;
86 
87  // private double m_longitude = 0;
88  // private double m_latitude = 0;
89  // Configurable defaults Defaults close to SL
90  private int d_frame_mod = 100; // Every 10 seconds (actually less)
91  private double d_day_length = 4; // A VW day is 4 RW hours long
92  private int d_year_length = 60; // There are 60 VW days in a VW year
93  private double d_day_night = 0.5; // axis offset: Default Hoizon shift to try and closely match the sun model in LL Viewer
94  private double d_DayTimeSunHourScale = 0.5; // Day/Night hours are equal
95 
96 
97  // private double d_longitude = -73.53;
98  // private double d_latitude = 41.29;
99 
100  // Frame counter
101  private uint m_frame = 0;
102 
103  // Cached Scene reference
104  private Scene m_scene = null;
105 
106  // Calculated Once in the lifetime of a region
107  private long TicksToEpoch; // Elapsed time for 1/1/1970
108  private uint SecondsPerSunCycle; // Length of a virtual day in RW seconds
109  private uint SecondsPerYear; // Length of a virtual year in RW seconds
110  private double SunSpeed; // Rate of passage in radians/second
111  private double SeasonSpeed; // Rate of change for seasonal effects
112  // private double HoursToRadians; // Rate of change for seasonal effects
113  private long TicksUTCOffset = 0; // seconds offset from UTC
114  // Calculated every update
115  private float OrbitalPosition; // Orbital placement at a point in time
116  private double HorizonShift; // Axis offset to skew day and night
117  private double TotalDistanceTravelled; // Distance since beginning of time (in radians)
118  private double SeasonalOffset; // Seaonal variation of tilt
119  private float Magnitude; // Normal tilt
120  // private double VWTimeRatio; // VW time as a ratio of real time
121 
122  // Working values
123  private Vector3 Position = Vector3.Zero;
124  private Vector3 Velocity = Vector3.Zero;
125  private Quaternion Tilt = new Quaternion(1.0f, 0.0f, 0.0f, 0.0f);
126 
127  // Used to fix the sun in the sky so it doesn't move based on current time
128  private bool m_SunFixed = false;
129  private float m_SunFixedHour = 0f;
130 
131  private const int TICKS_PER_SECOND = 10000000;
132 
133  private ulong m_CurrentTimeOffset = 0;
134 
135  // Current time in elapsed seconds since Jan 1st 1970
136  private ulong CurrentTime
137  {
138  get
139  {
140  ulong ctime = (ulong)(((DateTime.Now.Ticks) - TicksToEpoch + TicksUTCOffset) / TICKS_PER_SECOND);
141  return ctime + m_CurrentTimeOffset;
142  }
143  }
144 
145  // Time in seconds since UTC to use to calculate sun position.
146  ulong PosTime = 0;
147 
151  private void GenSunPos()
152  {
153  // Time in seconds since UTC to use to calculate sun position.
154  PosTime = CurrentTime;
155 
156  if (m_SunFixed)
157  {
158  // SunFixedHour represents the "hour of day" we would like
159  // It's represented in 24hr time, with 0 hour being sun-rise
160  // Because our day length is probably not 24hrs {LL is 6} we need to do a bit of math
161 
162  // Determine the current "day" from current time, so we can use "today"
163  // to determine Seasonal Tilt and what'not
164 
165  // Integer math rounded is on purpose to drop fractional day, determines number
166  // of virtual days since Epoch
167  PosTime = CurrentTime / SecondsPerSunCycle;
168 
169  // Since we want number of seconds since Epoch, multiply back up
170  PosTime *= SecondsPerSunCycle;
171 
172  // Then offset by the current Fixed Sun Hour
173  // Fixed Sun Hour needs to be scaled to reflect the user configured Seconds Per Sun Cycle
174  PosTime += (ulong)((m_SunFixedHour / 24.0) * (ulong)SecondsPerSunCycle);
175  }
176  else
177  {
178  if (m_DayTimeSunHourScale != 0.5f)
179  {
180  ulong CurDaySeconds = CurrentTime % SecondsPerSunCycle;
181  double CurDayPercentage = (double)CurDaySeconds / SecondsPerSunCycle;
182 
183  ulong DayLightSeconds = (ulong)(m_DayTimeSunHourScale * SecondsPerSunCycle);
184  ulong NightSeconds = SecondsPerSunCycle - DayLightSeconds;
185 
186  PosTime = CurrentTime / SecondsPerSunCycle;
187  PosTime *= SecondsPerSunCycle;
188 
189  if (CurDayPercentage < 0.5)
190  {
191  PosTime += (ulong)((CurDayPercentage / .5) * DayLightSeconds);
192  }
193  else
194  {
195  PosTime += DayLightSeconds;
196  PosTime += (ulong)(((CurDayPercentage - 0.5) / .5) * NightSeconds);
197  }
198  }
199  }
200 
201  TotalDistanceTravelled = SunSpeed * PosTime; // distance measured in radians
202 
203  OrbitalPosition = (float)(TotalDistanceTravelled % m_SunCycle); // position measured in radians
204 
205  // TotalDistanceTravelled += HoursToRadians-(0.25*Math.PI)*Math.Cos(HoursToRadians)-OrbitalPosition;
206  // OrbitalPosition = (float) (TotalDistanceTravelled%SunCycle);
207 
208  SeasonalOffset = SeasonSpeed * PosTime; // Present season determined as total radians travelled around season cycle
209  Tilt.W = (float)(m_AverageTilt + (m_SeasonalTilt * Math.Sin(SeasonalOffset))); // Calculate seasonal orbital N/S tilt
210 
211  // m_log.Debug("[SUN] Total distance travelled = "+TotalDistanceTravelled+", present position = "+OrbitalPosition+".");
212  // m_log.Debug("[SUN] Total seasonal progress = "+SeasonalOffset+", present tilt = "+Tilt.W+".");
213 
214  // The sun rotates about the Z axis
215 
216  Position.X = (float)Math.Cos(-TotalDistanceTravelled);
217  Position.Y = (float)Math.Sin(-TotalDistanceTravelled);
218  Position.Z = 0;
219 
220  // For interest we rotate it slightly about the X access.
221  // Celestial tilt is a value that ranges .025
222 
223  Position *= Tilt;
224 
225  // Finally we shift the axis so that more of the
226  // circle is above the horizon than below. This
227  // makes the nights shorter than the days.
228 
229  Position = Vector3.Normalize(Position);
230  Position.Z = Position.Z + (float)HorizonShift;
231  Position = Vector3.Normalize(Position);
232 
233  // m_log.Debug("[SUN] Position("+Position.X+","+Position.Y+","+Position.Z+")");
234 
235  Velocity.X = 0;
236  Velocity.Y = 0;
237  Velocity.Z = (float)SunSpeed;
238 
239  // Correct angular velocity to reflect the seasonal rotation
240 
241  Magnitude = Position.Length();
242  if (m_SunFixed)
243  {
244  Velocity.X = 0;
245  Velocity.Y = 0;
246  Velocity.Z = 0;
247  }
248  else
249  {
250  Velocity = (Velocity * Tilt) * (1.0f / Magnitude);
251  }
252 
253  // TODO: Decouple this, so we can get rid of Linden Hour info
254  // Update Region with new Sun Vector
255  // set estate settings for region access to sun position
256  if (receivedEstateToolsSunUpdate)
257  {
258  m_scene.RegionInfo.RegionSettings.SunVector = Position;
259  }
260  }
261 
262  private float GetCurrentTimeAsLindenSunHour()
263  {
264  float curtime = m_SunFixed ? m_SunFixedHour : GetCurrentSunHour();
265  return (curtime + 6.0f) % 24.0f;
266  }
267 
268  #region INonSharedRegion Methods
269 
270  // Called immediately after the module is loaded for a given region
271  // i.e. Immediately after instance creation.
272  public void Initialise(IConfigSource config)
273  {
274  m_frame = 0;
275 
276  // This one puts an entry in the main help screen
277 // m_scene.AddCommand("Regions", this, "sun", "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null);
278 
279  TimeZone local = TimeZone.CurrentTimeZone;
280  TicksUTCOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks;
281  m_log.DebugFormat("[SUN]: localtime offset is {0}", TicksUTCOffset);
282 
283  // Align ticks with Second Life
284 
285  TicksToEpoch = new DateTime(1970, 1, 1).Ticks;
286 
287  // Just in case they don't have the stanzas
288  try
289  {
290  // Mode: determines how the sun is handled
291  // m_latitude = config.Configs["Sun"].GetDouble("latitude", d_latitude);
292  // Mode: determines how the sun is handled
293  // m_longitude = config.Configs["Sun"].GetDouble("longitude", d_longitude);
294  // Year length in days
295  m_YearLengthDays = config.Configs["Sun"].GetInt("year_length", d_year_length);
296  // Day length in decimal hours
297  m_DayLengthHours = config.Configs["Sun"].GetDouble("day_length", d_day_length);
298 
299  // Horizon shift, this is used to shift the sun's orbit, this affects the day / night ratio
300  // must hard code to ~.5 to match sun position in LL based viewers
301  m_HorizonShift = config.Configs["Sun"].GetDouble("day_night_offset", d_day_night);
302 
303  // Scales the sun hours 0...12 vs 12...24, essentially makes daylight hours longer/shorter vs nighttime hours
304  m_DayTimeSunHourScale = config.Configs["Sun"].GetDouble("day_time_sun_hour_scale", d_DayTimeSunHourScale);
305 
306  // Update frequency in frames
307  m_UpdateInterval = config.Configs["Sun"].GetInt("update_interval", d_frame_mod);
308  }
309  catch (Exception e)
310  {
311  m_log.Debug("[SUN]: Configuration access failed, using defaults. Reason: " + e.Message);
312  m_YearLengthDays = d_year_length;
313  m_DayLengthHours = d_day_length;
314  m_HorizonShift = d_day_night;
315  m_UpdateInterval = d_frame_mod;
316  m_DayTimeSunHourScale = d_DayTimeSunHourScale;
317 
318  // m_latitude = d_latitude;
319  // m_longitude = d_longitude;
320  }
321 
322  SecondsPerSunCycle = (uint) (m_DayLengthHours * 60 * 60);
323  SecondsPerYear = (uint) (SecondsPerSunCycle*m_YearLengthDays);
324 
325  // Ration of real-to-virtual time
326 
327  // VWTimeRatio = 24/m_day_length;
328 
329  // Speed of rotation needed to complete a cycle in the
330  // designated period (day and season)
331 
332  SunSpeed = m_SunCycle/SecondsPerSunCycle;
333  SeasonSpeed = m_SeasonalCycle/SecondsPerYear;
334 
335  // Horizon translation
336 
337  HorizonShift = m_HorizonShift; // Z axis translation
338  // HoursToRadians = (SunCycle/24)*VWTimeRatio;
339 
340  m_log.Debug("[SUN]: Initialization completed. Day is " + SecondsPerSunCycle + " seconds, and year is " + m_YearLengthDays + " days");
341  m_log.Debug("[SUN]: Axis offset is " + m_HorizonShift);
342  m_log.Debug("[SUN]: Percentage of time for daylight " + m_DayTimeSunHourScale);
343  m_log.Debug("[SUN]: Positional data updated every " + m_UpdateInterval + " frames");
344  }
345 
346  public Type ReplaceableInterface
347  {
348  get { return null; }
349  }
350 
351  public void AddRegion(Scene scene)
352  {
353  m_scene = scene;
354  // Insert our event handling hooks
355 
356  scene.EventManager.OnFrame += SunUpdate;
357  scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
358  scene.EventManager.OnEstateToolsSunUpdate += EstateToolsSunUpdate;
359  scene.EventManager.OnGetCurrentTimeAsLindenSunHour += GetCurrentTimeAsLindenSunHour;
360 
361  scene.RegisterModuleInterface<ISunModule>(this);
362 
363  // This one enables the ability to type just "sun" without any parameters
364  // m_scene.AddCommand("Regions", this, "sun", "", "", HandleSunConsoleCommand);
365  foreach (KeyValuePair<string, string> kvp in GetParamList())
366  {
367  string sunCommand = string.Format("sun {0}", kvp.Key);
368  m_scene.AddCommand("Regions", this, sunCommand, string.Format("{0} [<value>]", sunCommand), kvp.Value, "", HandleSunConsoleCommand);
369  }
370  m_scene.AddCommand("Regions", this, "sun help", "sun help", "list parameters that can be changed", "", HandleSunConsoleCommand);
371  m_scene.AddCommand("Regions", this, "sun list", "sun list", "list parameters that can be changed", "", HandleSunConsoleCommand);
372  ready = true;
373  }
374 
375  public void RemoveRegion(Scene scene)
376  {
377  ready = false;
378 
379  // Remove our hooks
380  m_scene.EventManager.OnFrame -= SunUpdate;
381  m_scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel;
382  m_scene.EventManager.OnEstateToolsSunUpdate -= EstateToolsSunUpdate;
383  m_scene.EventManager.OnGetCurrentTimeAsLindenSunHour -= GetCurrentTimeAsLindenSunHour;
384  }
385 
386  public void RegionLoaded(Scene scene)
387  {
388  }
389 
390  public void Close()
391  {
392  }
393 
394  public string Name
395  {
396  get { return "SunModule"; }
397  }
398 
399  #endregion
400 
401  #region EventManager Events
402 
403  public void SunToClient(IClientAPI client)
404  {
405  if (ready)
406  {
407  if (m_SunFixed)
408  {
409  // m_log.DebugFormat("[SUN]: Fixed SunHour {0}, Position {1}, PosTime {2}, OrbitalPosition : {3} ",
410  // m_SunFixedHour, Position.ToString(), PosTime.ToString(), OrbitalPosition.ToString());
411  client.SendSunPos(Position, Velocity, PosTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition);
412  }
413  else
414  {
415  // m_log.DebugFormat("[SUN]: SunHour {0}, Position {1}, PosTime {2}, OrbitalPosition : {3} ",
416  // m_SunFixedHour, Position.ToString(), PosTime.ToString(), OrbitalPosition.ToString());
417  client.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition);
418  }
419  }
420  }
421 
422  public void SunUpdate()
423  {
424  if (((m_frame++ % m_UpdateInterval) != 0) || !ready || m_SunFixed || !receivedEstateToolsSunUpdate)
425  return;
426 
427  GenSunPos(); // Generate shared values once
428 
429  SunUpdateToAllClients();
430  }
431 
438  private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, UUID regionID)
439  {
440  SunToClient(avatar.ControllingClient);
441  }
442 
443  public void EstateToolsSunUpdate(ulong regionHandle)
444  {
445  if (m_scene.RegionInfo.RegionHandle == regionHandle)
446  {
447  float sunFixedHour;
448  bool fixedSun;
449 
450  if (m_scene.RegionInfo.RegionSettings.UseEstateSun)
451  {
452  sunFixedHour = (float)m_scene.RegionInfo.EstateSettings.SunPosition;
453  fixedSun = m_scene.RegionInfo.EstateSettings.FixedSun;
454  }
455  else
456  {
457  sunFixedHour = (float)m_scene.RegionInfo.RegionSettings.SunPosition - 6.0f;
458  fixedSun = m_scene.RegionInfo.RegionSettings.FixedSun;
459  }
460 
461  // Must limit the Sun Hour to 0 ... 24
462  while (sunFixedHour > 24.0f)
463  sunFixedHour -= 24;
464 
465  while (sunFixedHour < 0)
466  sunFixedHour += 24;
467 
468  m_SunFixedHour = sunFixedHour;
469  m_SunFixed = fixedSun;
470 
471  // m_log.DebugFormat("[SUN]: Sun Settings Update: Fixed Sun? : {0}", m_SunFixed.ToString());
472  // m_log.DebugFormat("[SUN]: Sun Settings Update: Sun Hour : {0}", m_SunFixedHour.ToString());
473 
474  receivedEstateToolsSunUpdate = true;
475 
476  // Generate shared values
477  GenSunPos();
478 
479  // When sun settings are updated, we should update all clients with new settings.
480  SunUpdateToAllClients();
481 
482  // m_log.DebugFormat("[SUN]: PosTime : {0}", PosTime.ToString());
483  }
484  }
485 
486  #endregion
487 
488  private void SunUpdateToAllClients()
489  {
490  m_scene.ForEachRootClient(delegate(IClientAPI client)
491  {
492  SunToClient(client);
493  });
494  }
495 
496  #region ISunModule Members
497 
498  public double GetSunParameter(string param)
499  {
500  switch (param.ToLower())
501  {
502  case "year_length":
503  return m_YearLengthDays;
504 
505  case "day_length":
506  return m_DayLengthHours;
507 
508  case "day_night_offset":
509  return m_HorizonShift;
510 
511  case "day_time_sun_hour_scale":
512  return m_DayTimeSunHourScale;
513 
514  case "update_interval":
515  return m_UpdateInterval;
516 
517  case "current_time":
518  return GetCurrentTimeAsLindenSunHour();
519 
520  default:
521  throw new Exception("Unknown sun parameter.");
522  }
523  }
524 
525  public void SetSunParameter(string param, double value)
526  {
527  switch (param)
528  {
529  case "year_length":
530  m_YearLengthDays = (int)value;
531  SecondsPerYear = (uint) (SecondsPerSunCycle*m_YearLengthDays);
532  SeasonSpeed = m_SeasonalCycle/SecondsPerYear;
533  break;
534 
535  case "day_length":
536  m_DayLengthHours = value;
537  SecondsPerSunCycle = (uint) (m_DayLengthHours * 60 * 60);
538  SecondsPerYear = (uint) (SecondsPerSunCycle*m_YearLengthDays);
539  SunSpeed = m_SunCycle/SecondsPerSunCycle;
540  SeasonSpeed = m_SeasonalCycle/SecondsPerYear;
541  break;
542 
543  case "day_night_offset":
544  m_HorizonShift = value;
545  HorizonShift = m_HorizonShift;
546  break;
547 
548  case "day_time_sun_hour_scale":
549  m_DayTimeSunHourScale = value;
550  break;
551 
552  case "update_interval":
553  m_UpdateInterval = (int)value;
554  break;
555 
556  case "current_time":
557  value = (value + 18.0) % 24.0;
558  // set the current offset so that the effective sun time is the parameter
559  m_CurrentTimeOffset = 0; // clear this first so we use raw time
560  m_CurrentTimeOffset = (ulong)(SecondsPerSunCycle * value/ 24.0) - (CurrentTime % SecondsPerSunCycle);
561  break;
562 
563  default:
564  throw new Exception("Unknown sun parameter.");
565  }
566 
567  // Generate shared values
568  GenSunPos();
569 
570  // When sun settings are updated, we should update all clients with new settings.
571  SunUpdateToAllClients();
572  }
573 
574  public float GetCurrentSunHour()
575  {
576  float ticksleftover = CurrentTime % SecondsPerSunCycle;
577 
578  return (24.0f * (ticksleftover / SecondsPerSunCycle));
579  }
580 
581  #endregion
582 
583  public void HandleSunConsoleCommand(string module, string[] cmdparams)
584  {
585  if (m_scene.ConsoleScene() == null)
586  {
587  // FIXME: If console region is root then this will be printed by every module. Currently, there is no
588  // way to prevent this, short of making the entire module shared (which is complete overkill).
589  // One possibility is to return a bool to signal whether the module has completely handled the command
590  m_log.InfoFormat("[Sun]: Please change to a specific region in order to set Sun parameters.");
591  return;
592  }
593 
594  if (m_scene.ConsoleScene() != m_scene)
595  {
596  m_log.InfoFormat("[Sun]: Console Scene is not my scene.");
597  return;
598  }
599 
600  m_log.InfoFormat("[Sun]: Processing command.");
601 
602  foreach (string output in ParseCmdParams(cmdparams))
603  {
604  MainConsole.Instance.Output(output);
605  }
606  }
607 
608  private Dictionary<string, string> GetParamList()
609  {
610  Dictionary<string, string> Params = new Dictionary<string, string>();
611 
612  Params.Add("year_length", "number of days to a year");
613  Params.Add("day_length", "number of hours to a day");
614  Params.Add("day_night_offset", "induces a horizon shift");
615  Params.Add("update_interval", "how often to update the sun's position in frames");
616  Params.Add("day_time_sun_hour_scale", "scales day light vs nite hours to change day/night ratio");
617  Params.Add("current_time", "time in seconds of the simulator");
618 
619  return Params;
620  }
621 
622  private List<string> ParseCmdParams(string[] args)
623  {
624  List<string> Output = new List<string>();
625 
626  if ((args.Length == 1) || (args[1].ToLower() == "help") || (args[1].ToLower() == "list"))
627  {
628  Output.Add("The following parameters can be changed or viewed:");
629  foreach (KeyValuePair<string, string> kvp in GetParamList())
630  {
631  Output.Add(String.Format("{0} - {1}",kvp.Key, kvp.Value));
632  }
633  return Output;
634  }
635 
636  if (args.Length == 2)
637  {
638  try
639  {
640  double value = GetSunParameter(args[1]);
641  Output.Add(String.Format("Parameter {0} is {1}.", args[1], value.ToString()));
642  }
643  catch (Exception)
644  {
645  Output.Add(String.Format("Unknown parameter {0}.", args[1]));
646  }
647 
648  }
649  else if (args.Length == 3)
650  {
651  double value = 0.0;
652  if (! double.TryParse(args[2], out value))
653  {
654  Output.Add(String.Format("The parameter value {0} is not a valid number.", args[2]));
655  return Output;
656  }
657 
658  SetSunParameter(args[1].ToLower(), value);
659  Output.Add(String.Format("Parameter {0} set to {1}.", args[1], value.ToString()));
660  }
661 
662  return Output;
663  }
664  }
665 }
void Initialise(IConfigSource config)
This is called to initialize the region module. For shared modules, this is called exactly once...
Definition: SunModule.cs:272
void SetSunParameter(string param, double value)
Definition: SunModule.cs:525
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
Definition: SunModule.cs:375
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
Definition: SunModule.cs:351
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
Definition: SunModule.cs:390
void HandleSunConsoleCommand(string module, string[] cmdparams)
Definition: SunModule.cs:583
void SunToClient(IClientAPI client)
Definition: SunModule.cs:403
double GetSunParameter(string param)
Definition: SunModule.cs:498
void EstateToolsSunUpdate(ulong regionHandle)
Definition: SunModule.cs:443
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
Definition: SunModule.cs:386