NebulaGames

Advanced Earth Time

May 23rd, 2019
2,242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 33.80 KB | None | 0 0
  1. // Fill out your copyright notice in the Description page of Project Settings.
  2.  
  3. #pragma once
  4.  
  5. #include "CoreMinimal.h"
  6. #include "Runtime/Engine/Classes/GameFramework/Actor.h"
  7. #include "Runtime/CoreUObject/Public/UObject/Class.h"
  8. #include "Components/ActorComponent.h"
  9. #include "Runtime/Engine/Public/TimerManager.h"
  10. #include "Kismet/KismetStringLibrary.h"
  11. #include "Runtime/Core/Public/Containers/UnrealString.h"
  12. #include "EarthTime.generated.h"
  13.  
  14. // Enum of Months
  15. UENUM(BlueprintType)                                   
  16. enum class ECalendarMonths : uint8
  17. {
  18.     January, February, March, April, May, June, July,
  19.     August, September, October, November, December
  20. };
  21.  
  22. // Input struct containing necessary values to determine "Sun position" during day/night cycle
  23. USTRUCT(BlueprintType)
  24. struct FDay_Night_Cycle
  25. {
  26.     GENERATED_USTRUCT_BODY()
  27.  
  28. public:
  29.  
  30.     // The sun will start at this value in the sky on an invisible 360 path (0 degrees would be flat on the ground, 90 degrees directly above)
  31.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Sun Position", meta = (ClampMin = "0", UIMin = "0"))
  32.         float Min_Degrees;
  33.     // The total amount of degrees the sun will travel through on an imaginary 360 degree path (180 would be a traditional "path" that started at 0)
  34.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Sun Position", meta = (ClampMax = "359", UIMax = "359"))
  35.         float Max_Degrees;
  36.     // Determines the time of day the sun will begin to travel along its path
  37.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Sun Position", meta = (ClampMin = "0", UIMin = "0"))
  38.         int32 Sunrise;
  39.     // Determines how long it will take the sun to reach the final position of its path before being reset
  40.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Sun Position", meta = (ClampMin = "0", UIMin = "0"))
  41.         int32 Hours_Of_Daylight;
  42.  
  43.     // Hidden value we will pass along with this struct to keep track of the sun's position during save/load cycles
  44.         float Sun_Start_Degrees;
  45. };
  46.  
  47. // Input struct for holding time stamp data
  48. USTRUCT(BlueprintType)
  49. struct FTimeStamp
  50. {
  51.     GENERATED_USTRUCT_BODY()
  52.  
  53. public:
  54.  
  55.     // The current time stamp in MM/DD/YYYY + 00:00:00 format
  56.     UPROPERTY(BlueprintReadOnly, Category = "Time Stamp")
  57.         FString Time_Stamp;
  58.     // Current second at the time this function was called
  59.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Time Stamp", meta = (ClampMin = "0", ClampMax = "59", UIMin = "0", UIMax = "59"))
  60.         int32 Seconds;
  61.     // Current minute at the time this function was called
  62.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Time Stamp", meta = (ClampMin = "0", ClampMax = "59", UIMin = "0", UIMax = "59"))
  63.         int32 Minutes;
  64.     // Current hour at the time this function was called
  65.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Time Stamp", meta = (ClampMin = "0", ClampMax = "23", UIMin = "0", UIMax = "23"))
  66.         int32 Hours;
  67.     // Current day at the time this function was called
  68.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Time Stamp", meta = (ClampMin = "1", ClampMax = "31", UIMin = "1", UIMax = "31"))
  69.         int32 Day;
  70.     // Current month at the time this function was called
  71.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Time Stamp", meta = (ClampMin = "1", ClampMax = "12", UIMin = "1", UIMax = "12"))
  72.         int32 Month;
  73.     // Current year at the time this function was called
  74.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Time Stamp", meta = (ClampMin = "0", UIMin = "0"))
  75.         int32 Year;
  76.  
  77.     /* Hidden value we will pass along with this struct to keep track of the total seconds passed in this year
  78.         (may not be necessary as this can easily be calculated) */
  79.         int32 YTD_Seconds;
  80. };
  81.  
  82. // Input struct containing all necessary values to determine where to begin counting time
  83. USTRUCT(BlueprintType)                                 
  84. struct FStandard_Calendar
  85. {
  86.     GENERATED_USTRUCT_BODY()           
  87.  
  88. public:                                                                                                            
  89.  
  90.     // Where to start counting seconds on a standard calendar cycle
  91.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Standard", meta = (ClampMin = "0", ClampMax = "59", UIMin = "0", UIMax = "59"))
  92.         int32 Seconds;
  93.     // Where to start counting minutes on a standard calendar cycle
  94.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Standard", meta = (ClampMin = "0", ClampMax = "59", UIMin = "0", UIMax = "59"))
  95.         int32 Minutes;
  96.     // Where to start counting hours on a standard calendar cycle
  97.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Standard", meta = (ClampMin = "0", ClampMax = "23", UIMin = "0", UIMax = "23"))
  98.         int32 Hours;
  99.     // Where to start counting days on a standard calendar cycle
  100.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Standard", meta = (ClampMin = "1", ClampMax = "31", UIMin = "1", UIMax = "31"))
  101.         int32 Day;
  102.     // Where to start counting months on a standard calendar cycle
  103.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Standard", meta = (ClampMin = "1", ClampMax = "12", UIMin = "1", UIMax = "12"))
  104.         ECalendarMonths Month;
  105.     // Where to start counting years on a standard calendar cycle
  106.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Standard", meta = (ClampMin = "0", UIMin = "0"))
  107.         int32 Year;
  108.     // Detemines the day/night cycle for a standard calendar cycle
  109.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Standard")
  110.         FDay_Night_Cycle Daylight_Settings;
  111.  
  112.     /* Hidden value we will pass along with this struct to keep track of the total seconds passed in this year
  113.         (may not be necessary as this can easily be calculated) */
  114.     int32 YearToDateSeconds;
  115. };
  116.  
  117. // Struct to define custom calendar types with non-standard day/month/year & second/minute/hour cycles
  118. USTRUCT(BlueprintType)
  119. struct FChaos_Calendar_Defaults
  120. {
  121.     GENERATED_USTRUCT_BODY()
  122.  
  123. public:
  124.  
  125.     // Detemines the seconds per minute on a custom calendar cycle
  126.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Chaos", meta = (DisplayName = "Seconds Per Minute", ClampMin = "0", UIMin = "0"))
  127.         int32 Seconds;
  128.     // Detemines the minutes per hour on a custom calendar cycle
  129.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Chaos", meta = (DisplayName = "Minutes Per Hour", ClampMin = "0", UIMin = "0"))
  130.         int32 Minutes;
  131.     // Detemines the hours per day on a custom calendar cycle
  132.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Chaos", meta = (DisplayName = "Hours Per Day", ClampMin = "0", UIMin = "0"))
  133.         int32 Hours;
  134.     // Detemines the days per month on a custom calendar cycle
  135.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Chaos", meta = (DisplayName = "Days Per Month", ClampMin = "1", UIMin = "1"))
  136.         int32 Day;
  137.     // The names of the months for a custom calendar
  138.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Chaos", meta = (DisplayName = "Month Names"))
  139.         TArray<FString> Chaos_Months;
  140.     // Detemines the day/night cycle for a custom calendar
  141.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Chaos")
  142.         FDay_Night_Cycle Daylight_Settings;
  143.  
  144.     // Where to start counting seconds on a custom calendar cycle
  145.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Chaos", meta = (DisplayName = "Start Second", ClampMin = "0", UIMin = "0"))
  146.         int32 Start_Seconds;
  147.     // Where to start counting minutes on a custom calendar cycle
  148.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Chaos", meta = (DisplayName = "Start Minute", ClampMin = "0", UIMin = "0"))
  149.         int32 Start_Minutes;
  150.     // Where to start counting hours on a custom calendar cycle
  151.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Chaos", meta = (DisplayName = "Start Hour", ClampMin = "0", UIMin = "0"))
  152.         int32 Start_Hours;
  153.     // Where to start counting days on a custom calendar cycle
  154.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Chaos", meta = (DisplayName = "Start Day", ClampMin = "1", UIMin = "1"))
  155.         int32 Start_Day;
  156.     // Where to start counting months on a custom calendar cycle
  157.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Chaos", meta = (DisplayName = "Start Month Index", ClampMin = "0", UIMin = "0"))
  158.         int32 Start_Month;
  159.     // Where to start counting years on a custom calendar cycle
  160.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Calendar|Chaos", meta = (DisplayName = "Start Year", ClampMin = "0", UIMin = "0"))
  161.         int32 Start_Year;
  162.    
  163.     // Hidden data on the total year to date seconds we will pass along with this struct
  164.     int32 YearToDateSeconds;
  165. };
  166.  
  167.  
  168. UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
  169. class CODE_TEST_API UEarthTime : public UActorComponent
  170. {
  171.     GENERATED_BODY()
  172.  
  173. public:
  174.  
  175.     // Sets default values for this component's properties
  176.     UEarthTime();
  177.  
  178.     // Called every frame
  179.     virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
  180.  
  181.     // Variable that returns the current world clock output as 00:00:00
  182.     UPROPERTY(BlueprintReadOnly, Category = "Earth Time")                      
  183.         FString World_Clock;
  184.     // Variable that returns the current world date
  185.     UPROPERTY(BlueprintReadOnly, Category = "Earth Time")                      
  186.         FString World_Date;
  187.     // The current world seconds
  188.     UPROPERTY(BlueprintReadOnly, Category = "Earth Time")                      
  189.         int32 Current_Seconds;
  190.     // The current world minutes
  191.     UPROPERTY(BlueprintReadOnly, Category = "Earth Time")                      
  192.         int32 Current_Minutes;
  193.     // The current world hours
  194.     UPROPERTY(BlueprintReadOnly, Category = "Earth Time")                      
  195.         int32 Current_Hours;
  196.     // The current world days
  197.     UPROPERTY(BlueprintReadOnly, Category = "Earth Time")                      
  198.         int32 Current_Day;
  199.     // The current world months
  200.     UPROPERTY(BlueprintReadOnly, Category = "Earth Time")                      
  201.         int32 Current_Month;
  202.     // The current world years
  203.     UPROPERTY(BlueprintReadOnly, Category = "Earth Time")                      
  204.         int32 Current_Year;
  205.     // The position of the sun in degrees
  206.     UPROPERTY(BlueprintReadOnly, Category = "Earth Time")
  207.         float Sun_Degrees;
  208.  
  209.     // Function to start a world date and clock
  210.     UFUNCTION(BlueprintCallable)                                                                   
  211.         void Earth_Genesis(UPARAM()FStandard_Calendar Standard_Calendar, float Rate, UPARAM(DisplayName = "Military Time") bool TwentyFour, UPARAM()FChaos_Calendar_Defaults Chaos_Calendar, bool Custom_Calendar);
  212.     // Function to change the rate of time passage
  213.     UFUNCTION(BlueprintCallable)                                                                   
  214.         void AlterTime(float New_Rate, UPARAM(DisplayName = "Military Time") bool NewClock);
  215.     // Function to pause the world clock
  216.     UFUNCTION(BlueprintCallable)                                                                   
  217.         void Pause();
  218.     // Function to unpause the world clock
  219.     UFUNCTION(BlueprintCallable)                                                                   
  220.         void Unpause();
  221.     // Function to clear the timer associated with the world clock
  222.     UFUNCTION(BlueprintCallable)                                                                   
  223.         void ClearTimer();
  224.     // Function to reset the world clock to 00:00:00 (does not affect world date)
  225.     UFUNCTION(BlueprintCallable)
  226.         void ResetClock();
  227.     // Function to save a world date and time running a standard calendar cycle
  228.     UFUNCTION(BlueprintCallable)
  229.         void SaveStandardDate(FStandard_Calendar &End_Date, bool Pause_Timer, bool Clear_Timer);
  230.     // Function to save a world date and time running a custom calendar cycle
  231.     UFUNCTION(BlueprintCallable)
  232.         void SaveChaosDate(FChaos_Calendar_Defaults &End_Date, bool Pause_Timer, bool Clear_Timer);
  233.     /* Function to generate a time stamp (used to calculate elapsed times, output not user friendly)
  234.         for user friendly world date/time grab the "World Date" and "World Time" string variables*/
  235.     UFUNCTION(BlueprintCallable)
  236.         FTimeStamp Generate_Time_Stamp();
  237.     // Function to calculate the time elapsed from the given input value (gathered from a call to "Generate Time Stamp") to the current moment
  238.     UFUNCTION(BlueprintCallable)
  239.         void Elapsed_Time(FTimeStamp Time, FTimeStamp &Elapsed);
  240.     // Function to calculate the elapsed time between 2 user input dates (both must be acquired using the "Generate Time Stamp" function)
  241.     UFUNCTION(BlueprintCallable)
  242.     FTimeStamp Delta_Time(FTimeStamp Start_Time, FTimeStamp End_Time);
  243.    
  244.  
  245.     // Internal Functions
  246.     void AgeOfEarth();
  247.     FString GenerateWorld_Clock(int32 Hour, int32 Minute, int32 Second);
  248.     FString GenerateWorld_Date(int32 Month, int32 Day, int32 Year);
  249.     void GenerateDaysReset(int32 ActiveMonth);
  250.     void Sun_Dial();
  251.     FString MonthAsString(int32 ConvertMonth); 
  252.     int32 GetYTD_Seconds();
  253.  
  254.     // Global variables necessary for Earth Time functionality
  255.     bool Time_Altered;                                                         
  256.     bool Military_Time;
  257.     bool Chaos;
  258.     float Delta_Degrees;
  259.     float Range;
  260.     int32 SecondsReset;
  261.     int32 SecondsResetValue;
  262.     int32 MinutesReset;
  263.     int32 MinutesResetValue;
  264.     int32 HoursReset;
  265.     int32 HoursResetValue;
  266.     int32 DaysReset;
  267.     int32 MonthsReset;
  268.     int32 YearToDateSeconds;
  269.     int32 TotalSecondsPerYear;
  270.     ECalendarMonths Calendar_Months;
  271.     FChaos_Calendar_Defaults Initial_Chaos_Calendar;
  272.     FDay_Night_Cycle Daylight;
  273.     TArray<FString> Chaos_Months;
  274.     FTimerHandle Universal_Age;
  275.     AActor* Parent_Actor;
  276.  
  277. protected:
  278.  
  279.     // Called when the game starts
  280.     virtual void BeginPlay() override;
  281. };
  282.  
  283. --------------------------------------------------------------------------------------------------------
  284.  
  285. #include "EarthTime.h"
  286.  
  287.  
  288. // Sets default values for this component's properties
  289. UEarthTime::UEarthTime()
  290. {
  291.     // Disable tick for this component
  292.     PrimaryComponentTick.bCanEverTick = false;
  293.  
  294.     // Retrieve actor component's Parent Actor
  295.     Parent_Actor = GetOwner(); 
  296.  
  297.     // Assume no alterations to the rate and AM/PM output desired initially
  298.     Time_Altered = false;
  299.     Military_Time = false;                     
  300.    
  301.     // Set our variable values to standard values
  302.     SecondsReset = 60;
  303.     SecondsResetValue = 0;
  304.     MinutesReset = 60;
  305.     MinutesResetValue = 0;
  306.     HoursReset = 24;
  307.     HoursResetValue = 0;
  308.     DaysReset = 32;
  309.     MonthsReset = 12;
  310.     Sun_Degrees = 0.0f;
  311.     Delta_Degrees = 0.1f;
  312.     Range = 180.0f;
  313.     YearToDateSeconds = 0;
  314.     TotalSecondsPerYear = 31536000;
  315. }
  316.  
  317. // Called when the game starts
  318. void UEarthTime::BeginPlay()
  319. {
  320.     Super::BeginPlay();
  321. }
  322.  
  323. // Called every frame
  324. void UEarthTime::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
  325. {
  326.     Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
  327. }
  328.  
  329. // Set date and time values for timer function
  330. void UEarthTime::Earth_Genesis(UPARAM()FStandard_Calendar Standard_Calendar, float Rate, UPARAM(DisplayName = "Military Time") bool TwentyFour, UPARAM()FChaos_Calendar_Defaults Chaos_Calendar, bool Custom_Calendar)
  331. {          
  332.     // Should we start counting from initial input values or do we already have values
  333.     if (Time_Altered == false)                             
  334.     {
  335.         // Determine if we are using a standard or non-standard calendar, if non-standard initialize user defined settings
  336.         if (Custom_Calendar == true)
  337.         {
  338.             // We won't use AM/PM for non-standard calendars
  339.             Military_Time = true;
  340.  
  341.             // Let the other functions know we are using a custom calendar
  342.             Chaos = true;
  343.  
  344.             // Set the custom calendar cycle
  345.             Initial_Chaos_Calendar = Chaos_Calendar;
  346.             SecondsReset = Chaos_Calendar.Seconds;
  347.             MinutesReset = Chaos_Calendar.Minutes;
  348.             HoursReset = Chaos_Calendar.Hours;
  349.             DaysReset = (Chaos_Calendar.Day + 1);
  350.             MonthsReset = Chaos_Calendar.Chaos_Months.Num();
  351.             Daylight = Chaos_Calendar.Daylight_Settings;
  352.  
  353.             // If no months named, populate array with error message & set start month to "0" index (prevents crash & identifies improper input)
  354.             if (Chaos_Calendar.Chaos_Months.Num() < 1)
  355.             {
  356.                 Chaos_Months = { "No Months Named In Custom Calendar" };
  357.                 Current_Month = 0;
  358.             }
  359.             else
  360.             {
  361.                 Chaos_Months = Chaos_Calendar.Chaos_Months;
  362.                 Current_Month = Chaos_Calendar.Start_Month;
  363.             }
  364.            
  365.             // Set initial start date and time for custom calendar
  366.             Current_Seconds = Chaos_Calendar.Start_Seconds;
  367.             Current_Minutes = Chaos_Calendar.Start_Minutes;
  368.             Current_Hours = Chaos_Calendar.Start_Hours;
  369.             Current_Day = Chaos_Calendar.Start_Day;
  370.             Current_Year = Chaos_Calendar.Start_Year;
  371.             YearToDateSeconds = GetYTD_Seconds();
  372.  
  373.             // Ensure we don't start a month on Day "0"
  374.             if (Current_Day == 0)
  375.             {
  376.                 Current_Day = 1;
  377.             }
  378.         }
  379.         else
  380.         {
  381.             // Determine if we are using a 12 or 24 hour clock
  382.             Military_Time = TwentyFour;
  383.  
  384.             // Set start time and date to user defined input on a standard calendar
  385.             Current_Seconds = Standard_Calendar.Seconds;
  386.             Current_Minutes = Standard_Calendar.Minutes;
  387.             Current_Hours = Standard_Calendar.Hours;
  388.             Current_Day = Standard_Calendar.Day;
  389.             Current_Month = static_cast<int>(Standard_Calendar.Month);
  390.             Current_Year = Standard_Calendar.Year;
  391.             Daylight = Standard_Calendar.Daylight_Settings;
  392.             YearToDateSeconds = GetYTD_Seconds();
  393.  
  394.             // Ensure we don't start a month on Day "0"
  395.             if (Current_Day == 0)
  396.             {
  397.                 Current_Day = 1;
  398.             }
  399.         }
  400.  
  401.         // Call function to ensure we don't start a month on a non-valid day
  402.         GenerateDaysReset(Current_Month);
  403.  
  404.         // Set Sun starting position
  405.         Sun_Degrees = Daylight.Sun_Start_Degrees;
  406.     }
  407.    
  408.     // If we have altered time ensure the Sun is appropriately positioned to the point it was just before alteration
  409.     if (Time_Altered == true && Chaos == true)
  410.     {
  411.         Sun_Degrees = Chaos_Calendar.Daylight_Settings.Sun_Start_Degrees;
  412.         Military_Time = true;
  413.     }
  414.     else if (Time_Altered == true && Chaos == false)
  415.     {
  416.         Sun_Degrees = Standard_Calendar.Daylight_Settings.Sun_Start_Degrees;
  417.         Military_Time = TwentyFour;
  418.     }
  419.  
  420.     // Prevent division by "0" from improper user input
  421.     if (Rate == 0)
  422.     {
  423.         Rate = 1;
  424.     }
  425.  
  426.     // Calculate the number of degrees to move the Sun's position based on total daylight hours, total degrees and rate of time passage
  427.     Range = (Daylight.Max_Degrees - Daylight.Min_Degrees);
  428.     Delta_Degrees = (Range / Daylight.Hours_Of_Daylight / MinutesReset / SecondsReset);
  429.  
  430.     // Create a timer
  431.     Parent_Actor->GetWorldTimerManager().SetTimer(Universal_Age, this, &UEarthTime::AgeOfEarth, 1 / Rate, true);
  432. }
  433.  
  434. // Function that actually tracks date and time
  435. void UEarthTime::AgeOfEarth()                                
  436. {
  437.     Current_Seconds++;
  438.     YearToDateSeconds++;
  439.    
  440.     if (YearToDateSeconds >= TotalSecondsPerYear)
  441.     {
  442.         YearToDateSeconds = 0;
  443.     }
  444.  
  445.     if (Current_Seconds == SecondsReset)                   
  446.     {
  447.         Current_Seconds = SecondsResetValue;
  448.         Current_Minutes ++;
  449.  
  450.         if (Current_Minutes == MinutesReset)               
  451.         {
  452.             Current_Minutes = MinutesResetValue;
  453.             Current_Hours ++;
  454.         }
  455.  
  456.         if (Current_Hours == HoursReset)
  457.         {
  458.             Current_Hours = HoursResetValue;
  459.             Current_Day ++;
  460.         }
  461.         if (Current_Day == DaysReset)              
  462.         {
  463.             Current_Day = 1;
  464.             Current_Month ++;
  465.             GenerateDaysReset(Current_Month);
  466.         }
  467.         if (Current_Month == MonthsReset)
  468.         {
  469.             Current_Month = 0;
  470.             Current_Year ++;
  471.         }
  472.  
  473.     }
  474.  
  475.     // Function calls to create World Date and Clock string values and output the Sun position in degrees
  476.     World_Clock = GenerateWorld_Clock(Current_Hours, Current_Minutes, Current_Seconds);                                    
  477.     World_Date = GenerateWorld_Date(Current_Month, Current_Day, Current_Year);
  478.     Sun_Dial();
  479. }
  480.  
  481. // Function to convert time values into "00:00:00" format (AM/PM if necessary)
  482. FString UEarthTime::GenerateWorld_Clock(int32 Hour, int32 Minute, int32 Second)
  483. {
  484.     FString HoursOutput;
  485.     FString MinutesOutput;
  486.     FString SecondsOutput;
  487.     FString TimeOfDay = "AM";
  488.     FString ClockOutput;
  489.     int32 StandardHours = Hour;
  490.     bool PM = false;
  491.    
  492.     if (Military_Time == false && StandardHours == 0)
  493.     {
  494.         StandardHours = 12;
  495.         TimeOfDay = "AM";
  496.     }
  497.     else if (Military_Time == false && StandardHours > 12)
  498.     {
  499.         StandardHours -= 12;
  500.         PM = true;
  501.         TimeOfDay = "PM";
  502.     }
  503.     else if (Military_Time == false && StandardHours == 12)
  504.     {
  505.         PM = true;
  506.         TimeOfDay = "PM";
  507.     }
  508.  
  509.     HoursOutput = FString::FromInt(StandardHours);             
  510.     if (HoursOutput.Len() < 2)                                 
  511.     {
  512.         HoursOutput = "0" + HoursOutput;
  513.     }
  514.     MinutesOutput = FString::FromInt(Minute);
  515.     if (MinutesOutput.Len() < 2)                                   
  516.     {
  517.         MinutesOutput = "0" + MinutesOutput;
  518.     }
  519.     SecondsOutput = FString::FromInt(Second);
  520.     if (SecondsOutput.Len() < 2)
  521.     {
  522.         SecondsOutput = "0" + SecondsOutput;
  523.     }
  524.    
  525.     // If not on military time output string will include "AM/PM" designation
  526.     if (Military_Time == false)
  527.     {
  528.         ClockOutput = (HoursOutput + " : " + MinutesOutput + " : " + SecondsOutput + " " + TimeOfDay);
  529.     }
  530.     else
  531.     {
  532.         ClockOutput = (HoursOutput + " : " + MinutesOutput + " : " + SecondsOutput);
  533.     }
  534.  
  535.     return ClockOutput;
  536. }
  537.  
  538. // Function to convert month, day, year values into "MM/DD/YYYY" format
  539. FString UEarthTime::GenerateWorld_Date(int32 Month, int32 Day, int32 Year)
  540. {
  541.     FString MonthOutput;
  542.     FString DayOutput;
  543.     FString YearOutput;
  544.     FString DateOutput;
  545.  
  546.     MonthOutput = MonthAsString(Month);
  547.  
  548.     DayOutput = FString::FromInt(Day);
  549.     if (DayOutput.Len() < 2)
  550.     {
  551.         DayOutput = "0" + DayOutput;
  552.     }
  553.  
  554.     YearOutput = FString::FromInt(Year);
  555.     DateOutput = (MonthOutput + " " + DayOutput + ", " + YearOutput);
  556.     return DateOutput;
  557. }
  558.  
  559. // Function to "Pause" World Time
  560. void UEarthTime::Pause()                                                   
  561. {
  562.     Parent_Actor->GetWorldTimerManager().PauseTimer(Universal_Age);
  563. }
  564.  
  565. // Function to "Unpause" World Time
  566. void UEarthTime::Unpause()                                                 
  567. {
  568.     Parent_Actor->GetWorldTimerManager().UnPauseTimer(Universal_Age);
  569. }
  570.  
  571. // Function to "Clear" World Time
  572. void UEarthTime::ClearTimer()                                              
  573. {
  574.     Parent_Actor->GetWorldTimerManager().ClearTimer(Universal_Age);
  575. }
  576.  
  577. // Function to "Reset" World Time to 00:00:00
  578. void UEarthTime::ResetClock()
  579. {
  580.     Current_Seconds = 0;
  581.     Current_Minutes = 0;
  582.     Current_Hours = 0;
  583.     YearToDateSeconds = GetYTD_Seconds();
  584. }
  585.  
  586. // Function to "Save" current World Time and Date
  587. void UEarthTime::SaveStandardDate(FStandard_Calendar &End_Date, bool Pause_Timer, bool Clear_Timer)
  588. {
  589.     // Should we pause our timer during a save cycle or continue counting
  590.     if (Pause_Timer == true)
  591.     {
  592.         Pause();
  593.     }
  594.  
  595.     End_Date.Month = static_cast<ECalendarMonths>(Current_Month);
  596.     End_Date.Day = Current_Day;
  597.     End_Date.Year = Current_Year;
  598.     End_Date.Hours = Current_Hours;
  599.     End_Date.Minutes = Current_Minutes;
  600.     End_Date.Seconds = Current_Seconds;
  601.     End_Date.Daylight_Settings = Daylight;
  602.     End_Date.YearToDateSeconds = YearToDateSeconds;
  603.  
  604.     // Overwrite the default Sun position during a save cycle
  605.     End_Date.Daylight_Settings.Sun_Start_Degrees = Sun_Degrees;
  606.  
  607.     // Should we stop our timer after saving or continue counting
  608.     if (Clear_Timer == true)
  609.     {
  610.         ClearTimer();
  611.     }
  612. }
  613.  
  614. // Function to "Save" current World Time and Date for custom calendar types
  615. void UEarthTime::SaveChaosDate(FChaos_Calendar_Defaults &End_Date, bool Pause_Timer, bool Clear_Timer)
  616. {
  617.     // Should we pause our timer during a save cycle or continue counting
  618.     if (Pause_Timer == true)
  619.     {
  620.         Pause();
  621.     }
  622.    
  623.     // When saving a custom calendar cycle, save the input defaults back out
  624.     End_Date.Seconds = Initial_Chaos_Calendar.Seconds;
  625.     End_Date.Minutes = Initial_Chaos_Calendar.Minutes;
  626.     End_Date.Hours = Initial_Chaos_Calendar.Hours;
  627.     End_Date.Day = Initial_Chaos_Calendar.Day;
  628.     End_Date.Chaos_Months = Initial_Chaos_Calendar.Chaos_Months;
  629.     End_Date.Daylight_Settings = Daylight;
  630.     End_Date.YearToDateSeconds = YearToDateSeconds;
  631.  
  632.     /* The new start time and date will be set to the last registered values, this way the struct can be directly fed back into the "Earth Genesis"
  633.        function with no additional modifications and the cycle will continue at the exact spot of the last save with the same default cycle values*/
  634.     End_Date.Start_Seconds = Current_Seconds;
  635.     End_Date.Start_Minutes = Current_Minutes;
  636.     End_Date.Start_Hours = Current_Hours;
  637.     End_Date.Start_Day = Current_Day;
  638.     End_Date.Start_Month = Current_Month;
  639.     End_Date.Start_Year = Current_Year;
  640.     End_Date.YearToDateSeconds = YearToDateSeconds;
  641.  
  642.     // Overwrite the default Sun position during a save cycle
  643.     End_Date.Daylight_Settings.Sun_Start_Degrees = Sun_Degrees;
  644.  
  645.     // Should we stop our timer after saving or continue counting
  646.     if (Clear_Timer == true)
  647.     {
  648.         ClearTimer();
  649.     }
  650. }
  651.  
  652. // Function to change rate of World Time passage
  653. void UEarthTime::AlterTime(float New_Rate, UPARAM(DisplayName = "Military Time") bool NewClock)
  654. {
  655.     // Declare both possible input types for a new Earth Genesis call **only one will be valid and used**
  656.     FStandard_Calendar New_Start_Date;
  657.     FChaos_Calendar_Defaults New_Chaos_Date;
  658.  
  659.     if (Chaos == true)
  660.     {
  661.         New_Chaos_Date.Seconds = Current_Seconds;
  662.         New_Chaos_Date.Minutes = Current_Minutes;
  663.         New_Chaos_Date.Hours = Current_Hours;
  664.         New_Chaos_Date.Day = Current_Day;
  665.         New_Chaos_Date.Start_Month = Current_Month;
  666.         New_Chaos_Date.Start_Year = Current_Year;
  667.         New_Chaos_Date.Daylight_Settings = Daylight;
  668.         New_Chaos_Date.Daylight_Settings.Sun_Start_Degrees = Sun_Degrees;
  669.         YearToDateSeconds = GetYTD_Seconds();
  670.     }
  671.     else
  672.     {
  673.         New_Start_Date.Seconds = Current_Seconds;
  674.         New_Start_Date.Minutes = Current_Minutes;
  675.         New_Start_Date.Hours = Current_Hours;
  676.         New_Start_Date.Day = Current_Day;
  677.         New_Start_Date.Month = static_cast<ECalendarMonths>(Current_Month);
  678.         New_Start_Date.Year = Current_Year;
  679.         New_Start_Date.Daylight_Settings = Daylight;
  680.         New_Start_Date.Daylight_Settings.Sun_Start_Degrees = Sun_Degrees;
  681.         YearToDateSeconds = GetYTD_Seconds();
  682.     }
  683.  
  684.     // Let other functions know we have altered time
  685.     Time_Altered = true;
  686.  
  687.     // Clear our current timer
  688.     Parent_Actor->GetWorldTimerManager().ClearTimer(Universal_Age);
  689.  
  690.     // Reset our Earth Timer to the new rate and/or clock output type
  691.     Earth_Genesis(New_Start_Date, New_Rate, NewClock, New_Chaos_Date, Chaos);
  692. }
  693.  
  694. // Function to convert Month Enum to string for output to blueprints
  695. FString UEarthTime::MonthAsString(int32 ConvertMonth)
  696. {
  697.     FString EnumMonth;
  698.  
  699.     if (Chaos == true)
  700.     {
  701.         EnumMonth = Chaos_Months[ConvertMonth];
  702.     }
  703.     else
  704.     {
  705.         switch (ConvertMonth)
  706.         {
  707.         case 0:
  708.             EnumMonth = "January";
  709.             break;
  710.         case 1:
  711.             EnumMonth = "February";
  712. break;
  713.         case 2:
  714.             EnumMonth = "March";
  715.             break;
  716.         case 3:
  717.             EnumMonth = "April";
  718.             break;
  719.         case 4:
  720.             EnumMonth = "May";
  721.             break;
  722.         case 5:
  723.             EnumMonth = "June";
  724.             break;
  725.         case 6:
  726.             EnumMonth = "July";
  727.             break;
  728.         case 7:
  729.             EnumMonth = "August";
  730.             break;
  731.         case 8:
  732.             EnumMonth = "September";
  733.             break;
  734.         case 9:
  735.             EnumMonth = "October";
  736.             break;
  737.         case 10:
  738.             EnumMonth = "November";
  739.             break;
  740.         case 11:
  741.             EnumMonth = "December";
  742.             break;
  743.         default:
  744.             EnumMonth = "Bad Month";
  745.             break;
  746.         }
  747.     }
  748.     return EnumMonth;
  749. }
  750.  
  751. // Function to determine when to "reset" day count (adjusts for Leap year)
  752. void UEarthTime::GenerateDaysReset(int32 ActiveMonth)
  753. {
  754.     /* If using a non-standard calendar skip determining how many days/month, all months will have the same # of days
  755.         Only modify the Total Seconds Per Year Variable */
  756.     if (Chaos == true)
  757.     {
  758.         TotalSecondsPerYear = (SecondsReset * MinutesReset * HoursReset * (DaysReset - 1) * MonthsReset);
  759.     }
  760.     else
  761.     {
  762.         switch (ActiveMonth)
  763.         {
  764.         case 0: case 2: case 4: case 6: case 7: case 9: case 11:
  765.             DaysReset = 32;
  766.             break;
  767.         case 1:
  768.             if (Current_Year % 4 == 0)
  769.             {
  770.                 DaysReset = 30;
  771.             }
  772.             else
  773.             {
  774.                 DaysReset = 29;
  775.             }
  776.             break;
  777.         case 3: case 5: case 8: case 10:
  778.             DaysReset = 31;
  779.             break;
  780.         default:
  781.             DaysReset = 31;
  782.             break;
  783.         }
  784.  
  785.         if (Current_Year % 4 == 0)
  786.         {
  787.             TotalSecondsPerYear = 31622400;
  788.         }
  789.         else
  790.         {
  791.             TotalSecondsPerYear = 31536000;
  792.         }
  793.     }
  794.     // Now that we know how many days are in the current month ensure we are on a valid day
  795.     if (Current_Day >= DaysReset)
  796.     {
  797.         Current_Day = (DaysReset - 1);
  798.     }
  799. }
  800.  
  801. // Function to determine the Sun's position in degrees
  802. void UEarthTime::Sun_Dial()
  803. {
  804.     /* Ensure we are only moving the Sun through the specified "Min" and "Max" degrees and make sure we only
  805.        change the Sun's position during the specified "Daylight" hours, otherwise Sun position will be at "0" degrees*/
  806.     if (Current_Hours < Daylight.Sunrise || Sun_Degrees >= Daylight.Max_Degrees || (Current_Hours - Daylight.Sunrise) >= Daylight.Hours_Of_Daylight)
  807.     {
  808.         Sun_Degrees = 0;
  809.     }
  810.     else
  811.     {
  812.         Sun_Degrees += Delta_Degrees;
  813.     }
  814. }
  815.  
  816. // Function that calculates the total seconds passed to date of the current year
  817. int32 UEarthTime::GetYTD_Seconds()
  818. {
  819.     int32 SummedDays = 0;
  820.     bool LeapYear;
  821.  
  822.     if (Current_Year % 4 == 0)
  823.     {
  824.         LeapYear = true;
  825.     }
  826.     else
  827.     {
  828.         LeapYear = false;
  829.     }
  830.  
  831.     if (Chaos == false)
  832.     {
  833.         switch (Current_Month)
  834.         {
  835.         case 0:
  836.             SummedDays = (Current_Day - 1);
  837.             break;
  838.         case 1:
  839.             SummedDays = (Current_Month * 30) + Current_Day;
  840.             break;
  841.         case 2:
  842.             if (LeapYear == true)
  843.             {
  844.                 SummedDays = (Current_Month * 30) + (Current_Day - 1);
  845.             }
  846.             else
  847.             {
  848.                 SummedDays = (Current_Month * 30) + (Current_Day - 2);
  849.             }
  850.             break;
  851.         case 3:
  852.             if (LeapYear == true)
  853.             {
  854.                 SummedDays = (Current_Month * 30) + (Current_Day);
  855.             }
  856.             else
  857.             {
  858.                 SummedDays = (Current_Month * 30) + (Current_Day - 1);
  859.             }
  860.             break;
  861.         case 4:
  862.             if (LeapYear == true)
  863.             {
  864.                 SummedDays = (Current_Month * 30) + Current_Day;
  865.             }
  866.             else
  867.             {
  868.                 SummedDays = (Current_Month * 30) + (Current_Day - 1);
  869.             }
  870.             break;
  871.         case 5:
  872.             if (LeapYear == true)
  873.             {
  874.                 SummedDays = (Current_Month * 30) + (Current_Day + 1);
  875.             }
  876.             else
  877.             {
  878.                 SummedDays = (Current_Month * 30) + Current_Day;
  879.             }
  880.             break;
  881.         case 6:
  882.             if (LeapYear == true)
  883.             {
  884.                 SummedDays = (Current_Month * 30) + (Current_Day + 1);
  885.             }
  886.             else
  887.             {
  888.                 SummedDays = (Current_Month * 30) + Current_Day;
  889.             }
  890.             break;
  891.         case 7:
  892.             if (LeapYear == true)
  893.             {
  894.                 SummedDays = (Current_Month * 30) + (Current_Day + 2);
  895.             }
  896.             else
  897.             {
  898.                 SummedDays = (Current_Month * 30) + (Current_Day + 1);
  899.             }
  900.             break;
  901.         case 8:
  902.             if (LeapYear == true)
  903.             {
  904.                 SummedDays = (Current_Month * 30) + (Current_Day + 3);
  905.             }
  906.             else
  907.             {
  908.                 SummedDays = (Current_Month * 30) + (Current_Day + 2);
  909.             }
  910.             break;
  911.         case 9:
  912.             if (LeapYear == true)
  913.             {
  914.                 SummedDays = (Current_Month * 30) + (Current_Day + 3);
  915.             }
  916.             else
  917.             {
  918.                 SummedDays = (Current_Month * 30) + (Current_Day + 2);
  919.             }
  920.             break;
  921.         case 10:
  922.             if (LeapYear == true)
  923.             {
  924.                 SummedDays = (Current_Month * 30) + (Current_Day + 4);
  925.             }
  926.             else
  927.             {
  928.                 SummedDays = (Current_Month * 30) + (Current_Day + 3);
  929.             }
  930.             break;
  931.         case 11:
  932.             if (LeapYear == true)
  933.             {
  934.                 SummedDays = (Current_Month * 30) + (Current_Day + 4);
  935.             }
  936.             else
  937.             {
  938.                 SummedDays = (Current_Month * 30) + (Current_Day + 3);
  939.             }
  940.             break;
  941.         }
  942.     }
  943.     else
  944.     {
  945.     SummedDays = (Current_Month * (DaysReset - 1)) + (Current_Day - 1);    
  946.     }
  947.  
  948.     int32 YTD_Seconds = ((SummedDays * HoursReset * MinutesReset * SecondsReset) + (Current_Hours * MinutesReset * SecondsReset) + (Current_Minutes * SecondsReset) + Current_Seconds);
  949.     return YTD_Seconds;
  950. }
  951.  
  952. // Function to generate a time stamp used for calculating time elapsed between two given time stamps
  953. FTimeStamp UEarthTime::Generate_Time_Stamp()
  954. {
  955.     FTimeStamp Time_Stamp;
  956.  
  957.     Time_Stamp.Time_Stamp.Append(World_Date + " " + World_Clock);
  958.     Time_Stamp.YTD_Seconds = GetYTD_Seconds();
  959.     Time_Stamp.Seconds = Current_Seconds;
  960.     Time_Stamp.Minutes = Current_Minutes;
  961.     Time_Stamp.Hours = Current_Hours;
  962.     Time_Stamp.Day = Current_Day;
  963.     Time_Stamp.Month = Current_Month;
  964.     Time_Stamp.Year = Current_Year;
  965.  
  966.     return Time_Stamp;
  967. }
  968.  
  969. // Function that takes 2 time stamps and calculates the elapsed time between them
  970. FTimeStamp UEarthTime::Delta_Time(FTimeStamp Start_Time, FTimeStamp End_Time)
  971. {
  972.     int32 TempInt1 = (End_Time.Year - Start_Time.Year);
  973.     int32 TempInt2 = 0;
  974.     FTimeStamp FinalTimeStamp;
  975.  
  976.     // If we only have a difference in the year-to-date totals we can ignore the years category
  977.     if ((TempInt1 >= 0 && (End_Time.YTD_Seconds - Start_Time.YTD_Seconds) >= 0))
  978.     {
  979.         TempInt2 = (End_Time.YTD_Seconds - Start_Time.YTD_Seconds);
  980.         FinalTimeStamp.Year = TempInt1;
  981.         FinalTimeStamp.Month = (TempInt2 / (SecondsReset * MinutesReset * HoursReset * (DaysReset - 1)));
  982.         TempInt2 = (TempInt2 % (SecondsReset * MinutesReset * HoursReset * (DaysReset - 1)));
  983.         FinalTimeStamp.Day = (TempInt2 / (SecondsReset * MinutesReset * HoursReset));
  984.         TempInt2 = (TempInt2 % (SecondsReset * MinutesReset * HoursReset));
  985.         FinalTimeStamp.Hours = (TempInt2 / (SecondsReset * MinutesReset));
  986.         TempInt2 = (TempInt2 % (SecondsReset * MinutesReset));
  987.         FinalTimeStamp.Minutes = (TempInt2 / SecondsReset);
  988.         FinalTimeStamp.Seconds = (TempInt2 % SecondsReset);
  989.     }
  990.     // If there is a difference in the years we will take this into account when determining the total elapsed time
  991.     else if (TempInt1 > 0 && (End_Time.YTD_Seconds - Start_Time.YTD_Seconds) <= 0)
  992.     {
  993.         TempInt2 = (TotalSecondsPerYear - Start_Time.YTD_Seconds) + (End_Time.YTD_Seconds);
  994.         FinalTimeStamp.Year = (TempInt1 - 1);
  995.         FinalTimeStamp.Month = (TempInt2 / (SecondsReset * MinutesReset * HoursReset * (DaysReset - 1)));
  996.         TempInt2 = (TempInt2 % (SecondsReset * MinutesReset * HoursReset * (DaysReset - 1)));
  997.         FinalTimeStamp.Day = (TempInt2 / (SecondsReset * MinutesReset * HoursReset));
  998.         TempInt2 = (TempInt2 % (SecondsReset * MinutesReset * HoursReset));
  999.         FinalTimeStamp.Hours = (TempInt2 / (SecondsReset * MinutesReset));
  1000.         TempInt2 = (TempInt2 % (SecondsReset * MinutesReset));
  1001.         FinalTimeStamp.Minutes = (TempInt2 / SecondsReset);
  1002.         FinalTimeStamp.Seconds = (TempInt2 % SecondsReset);
  1003.     }
  1004.  
  1005.     // Display the elapsed time as a string in "year:month:day + 00:00:00" format
  1006.     if (FinalTimeStamp.Year > 0)
  1007.     {
  1008.         FinalTimeStamp.Time_Stamp.Append(FString::FromInt(FinalTimeStamp.Year) + " years : ");
  1009.     }
  1010.     if (FinalTimeStamp.Month > 0)
  1011.     {
  1012.         FinalTimeStamp.Time_Stamp.Append(FString::FromInt(FinalTimeStamp.Month) + " months : ");
  1013.     }
  1014.     if (FinalTimeStamp.Day > 0)
  1015.     {
  1016.         FinalTimeStamp.Time_Stamp.Append(FString::FromInt(FinalTimeStamp.Day) + " days and ");
  1017.     }
  1018.  
  1019.     FinalTimeStamp.Time_Stamp.Append(GenerateWorld_Clock(FinalTimeStamp.Hours, FinalTimeStamp.Minutes, FinalTimeStamp.Seconds));
  1020.  
  1021.     return FinalTimeStamp;
  1022. }
  1023.  
  1024. // Function that auto-calculates the elapsed time between the input reference time stamp and the current world time
  1025. void UEarthTime::Elapsed_Time(FTimeStamp Time, FTimeStamp &Elapsed)
  1026. {
  1027.     FTimeStamp PresentTime = Generate_Time_Stamp();
  1028.     Elapsed = Delta_Time(Time, PresentTime);
  1029. }
Advertisement
Add Comment
Please, Sign In to add comment