/// <summary> /// Calculates and returns the latest GameDate by which this rotation should complete. /// <remarks>Typically used to calculate how long to allow a rotation coroutine to run before throwing a warning or error. /// Use of a date in this manner handles GameSpeed changes and Pauses during the rotation. /// </remarks> /// <remarks>This version is meant for rotation coroutines that use fixed update.</remarks> /// </summary> /// <param name="rotationRateInDegreesPerHour">The rotation rate in degrees per hour.</param> /// <param name="maxRotationReqdInDegrees">The maximum rotation reqd in degrees.</param> /// <returns></returns> public static GameDate CalcWarningDateForRotation(float rotationRateInDegreesPerHour, float maxRotationReqdInDegrees = 180F) { float maxHoursReqdToCompleteRotation = maxRotationReqdInDegrees / rotationRateInDegreesPerHour; maxHoursReqdToCompleteRotation = Mathf.Clamp(maxHoursReqdToCompleteRotation, MinimumRotationErrorDateHours, GameTime.HoursPerDay); //D.Log("MaxHoursReqdToCompleteRotation of 180 degrees at {0:0.} per hour = {1:0.##}.", rotationRateInDegreesPerHour, maxHoursReqdToCompleteRotation); var maxDurationFromCurrentDate = new GameTimeDuration(maxHoursReqdToCompleteRotation); return new GameDate(maxDurationFromCurrentDate); }
protected override void Awake() { base.Awake(); _gameTime = GameTime.Instance; _gameMgr = References.GameManager; _rotationPeriod = GameTimeDuration.OneDay; _rotationRate = _relativeRotationRate * Constants.DegreesPerRotation / (float)_rotationPeriod.TotalInHours; Subscribe(); enabled = false; }
/// <summary> /// Initializes a new instance of the <see cref="AOrbitSlot" /> struct. /// </summary> /// <param name="innerRadius">The closest distance to the body orbited.</param> /// <param name="outerRadius">The furthest distance from the body orbited.</param> /// <param name="isOrbitedObjectMobile">if set to <c>true</c> [is orbited object mobile].</param> /// <param name="orbitPeriod">The orbit period.</param> /// <param name="toOrbit">if set to <c>true</c> the orbitSimulator will rotate if activated.</param> public AOrbitSlot(float innerRadius, float outerRadius, bool isOrbitedObjectMobile, GameTimeDuration orbitPeriod, bool toOrbit) { Utility.Validate(innerRadius != outerRadius); Utility.ValidateForRange(innerRadius, Constants.ZeroF, outerRadius); Utility.ValidateForRange(outerRadius, innerRadius, Mathf.Infinity); Utility.Validate(orbitPeriod != default(GameTimeDuration)); InnerRadius = innerRadius; OuterRadius = outerRadius; MeanRadius = innerRadius + (outerRadius - innerRadius) / 2F; Depth = outerRadius - innerRadius; IsOrbitedObjectMobile = isOrbitedObjectMobile; OrbitPeriod = orbitPeriod; ToOrbit = toOrbit; }
/// <summary> /// Initializes a new instance of the <see cref="OrbitData" /> class without a /// designated OrbitedItem. /// </summary> /// <param name="slotIndex">Index of the slot.</param> /// <param name="innerRadius">The closest distance to the body orbited.</param> /// <param name="outerRadius">The furthest distance from the body orbited.</param> /// <param name="orbitPeriod">The orbit period.</param> /// <param name="toOrbit">if set to <c>true</c> the orbitSimulator will rotate if activated.</param> public OrbitData(int slotIndex, float innerRadius, float outerRadius, GameTimeDuration orbitPeriod, bool toOrbit) { Utility.Validate(innerRadius != outerRadius); Utility.ValidateForRange(innerRadius, Constants.ZeroF, outerRadius); Utility.ValidateForRange(outerRadius, innerRadius, Mathf.Infinity); Utility.Validate(orbitPeriod != default(GameTimeDuration)); SlotIndex = slotIndex; InnerRadius = innerRadius; OuterRadius = outerRadius; MeanRadius = innerRadius + (outerRadius - innerRadius) / 2F; Depth = outerRadius - innerRadius; OrbitPeriod = orbitPeriod; ToOrbit = toOrbit; }
/// <summary> /// Initializes a new instance of the <see cref="CelestialOrbitSlot" /> class. /// WARNING: The orbiter and all its children (the actual orbiting object) will assume the layer of the orbitedObject. /// </summary> /// <param name="innerRadius">The inner radius.</param> /// <param name="outerRadius">The outer radius.</param> /// <param name="orbitedObject">The GameObject being orbited.</param> /// <param name="isOrbitedObjectMobile">if set to <c>true</c> [is orbited object mobile].</param> /// <param name="orbitPeriod">The orbit period.</param> /// <param name="toOrbit">if set to <c>true</c> the orbit simulator will rotate if activated.</param> public CelestialOrbitSlot(float innerRadius, float outerRadius, GameObject orbitedObject, bool isOrbitedObjectMobile, GameTimeDuration orbitPeriod, bool toOrbit = true) : base(innerRadius, outerRadius, isOrbitedObjectMobile, orbitPeriod, toOrbit) { OrbitedObject = orbitedObject; }
/// <summary> /// Generates a random settlement creator, places it in orbit around <c>system</c> and deploys it on a random date. /// </summary> /// <param name="owner">The owner.</param> /// <param name="system">The system.</param> /// <returns></returns> public SettlementCreator GenerateRandomAutoSettlementCreator(Player owner, SystemItem system) { GameTimeDuration deployDateDelay = new GameTimeDuration(UnityEngine.Random.Range(Constants.ZeroF, 3F)); //GameTimeDuration deployDateDelay = new GameTimeDuration(5F); GameDate deployDate = GameTime.Instance.GenerateRandomFutureDate(deployDateDelay); return GenerateRandomAutoSettlementCreator(owner, system, deployDate); }
/// <summary> /// Generates a random starbase creator, places it at location and deploys it on a random date. /// </summary> /// <param name="owner">The owner.</param> /// <param name="location">The location.</param> /// <returns></returns> public StarbaseCreator GenerateRandomAutoStarbaseCreator(Player owner, Vector3 location) { GameTimeDuration deployDateDelay = new GameTimeDuration(UnityEngine.Random.Range(Constants.ZeroF, 3F)); //GameTimeDuration deployDateDelay = new GameTimeDuration(0.1F); GameDate deployDate = GameTime.Instance.GenerateRandomFutureDate(deployDateDelay); return GenerateRandomAutoStarbaseCreator(owner, location, deployDate); }
private void HandleAnyDurationChange() { if (_durationRef == null) { return; } if (_durationRef.Value != _duration) { // duration has changed //D.Log("{0}.ReferenceValue is changing from {1} to {2}.", DebugName, _duration, _durationRef.Value); _duration = _durationRef.Value; _targetDate = new GameDate(_startDate, _duration); } }
/// <summary> /// Initializes a new instance of the <see cref="ShipOrbitSlot" /> class. /// </summary> /// <param name="lowOrbitRadius">The radius at this slot's lowest orbit.</param> /// <param name="highOrbitRadius">The radius at this slot's highest orbit.</param> /// <param name="orbitedObject">The object being orbited.</param> /// <param name="orbitPeriod">The orbit period.</param> public ShipOrbitSlot(float lowOrbitRadius, float highOrbitRadius, IShipCloseOrbitable orbitedObject, GameTimeDuration orbitPeriod) : base(lowOrbitRadius, highOrbitRadius, orbitedObject.IsMobile, orbitPeriod, toOrbit: true) { OrbitedObject = orbitedObject; //_orbitingShips = new List<IShipItem>(); }
/// <summary> /// Initializes a new instance of the <see cref="OrbitData" /> class without a /// designated OrbitedItem that moves in orbit. /// </summary> /// <param name="slotIndex">Index of the slot.</param> /// <param name="innerRadius">The radius at this slot's lowest orbit.</param> /// <param name="outerRadius">The radius at this slot's highest orbit.</param> /// <param name="orbitPeriod">The orbit period.</param> public OrbitData(int slotIndex, float innerRadius, float outerRadius, GameTimeDuration orbitPeriod) : this(slotIndex, innerRadius, outerRadius, orbitPeriod, toOrbit: true) { }
/// <summary> /// Checks for a progress check period correction, a speed correction and then a progress check period correction again in that order. /// Returns <c>true</c> if a correction is provided, <c>false</c> otherwise. Only one correction at a time will be provided and /// it must be tested against its default value to know which one it is. /// </summary> /// <param name="distanceToArrival">The distance to arrival.</param> /// <param name="isIncreaseAboveApSpeedAllowed">if set to <c>true</c> [is increase above automatic pilot speed allowed].</param> /// <param name="halfArrivalCaptureDepth">The half arrival capture depth.</param> /// <param name="currentPeriod">The current period.</param> /// <param name="correctedPeriod">The corrected period.</param> /// <param name="correctedSpeed">The corrected speed.</param> /// <returns></returns> private bool TryCheckForPeriodOrSpeedCorrection(float distanceToArrival, bool isIncreaseAboveApSpeedAllowed, float halfArrivalCaptureDepth, GameTimeDuration currentPeriod, out GameTimeDuration correctedPeriod, out Speed correctedSpeed) { //D.Log(ShowDebugLog, "{0} called TryCheckForPeriodOrSpeedCorrection().", DebugName); correctedSpeed = default(Speed); correctedPeriod = default(GameTimeDuration); if (_doesApProgressCheckPeriodNeedRefresh) { Profiler.BeginSample("__RefreshProgressCheckPeriod", _ship); correctedPeriod = __RefreshProgressCheckPeriod(currentPeriod); Profiler.EndSample(); //D.Log(ShowDebugLog, "{0} is refreshing progress check period from {1} to {2}.", DebugName, currentPeriod, correctedPeriod); _doesApProgressCheckPeriodNeedRefresh = false; return true; } float maxDistanceCoveredDuringNextProgressCheck = currentPeriod.TotalInHours * _engineRoom.IntendedCurrentSpeedValue; float checksRemainingBeforeArrival = distanceToArrival / maxDistanceCoveredDuringNextProgressCheck; float checksRemainingThreshold = MaxNumberOfProgressChecksBeforeSpeedAndCheckPeriodReductionsBegin; if (checksRemainingBeforeArrival < checksRemainingThreshold) { // limit how far down progress check period reductions can go float minDesiredHoursPerCheckPeriod = MinHoursPerProgressCheckPeriodAllowed * 2F; bool isMinDesiredCheckPeriod = currentPeriod.TotalInHours.IsLessThanOrEqualTo(minDesiredHoursPerCheckPeriod, .01F); bool isDistanceCoveredPerCheckTooHigh = maxDistanceCoveredDuringNextProgressCheck > halfArrivalCaptureDepth; if (!isMinDesiredCheckPeriod && isDistanceCoveredPerCheckTooHigh) { // reduce progress check period to the desired minimum before considering speed reductions float correctedPeriodHours = currentPeriod.TotalInHours / 2F; if (correctedPeriodHours < minDesiredHoursPerCheckPeriod) { correctedPeriodHours = minDesiredHoursPerCheckPeriod; //D.Log(ShowDebugLog, "{0} has set progress check period hours to desired min {1:0.00}.", DebugName, minDesiredHoursPerCheckPeriod); } correctedPeriod = new GameTimeDuration(correctedPeriodHours); //D.Log(ShowDebugLog, "{0} is reducing progress check period to {1} to find halfArrivalCaptureDepth {2:0.00}.", DebugName, correctedPeriod, halfArrivalCaptureDepth); return true; } //D.Log(ShowDebugLog, "{0} distanceCovered during next progress check = {1:0.00}, halfArrivalCaptureDepth = {2:0.00}.", DebugName, maxDistanceCoveredDuringNextProgressCheck, halfArrivalCaptureDepth); if (isDistanceCoveredPerCheckTooHigh) { // at this speed I could miss the arrival window //D.Log(ShowDebugLog, "{0} will arrive in as little as {1:0.0} checks and will miss front half depth {2:0.00} of arrival window.", //Name, checksRemainingBeforeArrival, halfArrivalCaptureDepth); if (CurrentSpeedSetting.TryDecreaseSpeed(out correctedSpeed)) { //D.Log(ShowDebugLog, "{0} is reducing speed to {1}.", DebugName, correctedSpeed.GetValueName()); return true; } // Can't reduce speed further yet still covering too much ground per check so reduce check period to minimum correctedPeriod = new GameTimeDuration(MinHoursPerProgressCheckPeriodAllowed); maxDistanceCoveredDuringNextProgressCheck = correctedPeriod.TotalInHours * _engineRoom.IntendedCurrentSpeedValue; isDistanceCoveredPerCheckTooHigh = maxDistanceCoveredDuringNextProgressCheck > halfArrivalCaptureDepth; if (isDistanceCoveredPerCheckTooHigh) { D.Warn("{0} cannot cover less distance per check so could miss arrival window. DistanceCoveredBetweenChecks {1:0.00} > HalfArrivalCaptureDepth {2:0.00}.", DebugName, maxDistanceCoveredDuringNextProgressCheck, halfArrivalCaptureDepth); } return true; } } else { //D.Log(ShowDebugLog, "{0} ChecksRemainingBeforeArrival {1:0.0} > Threshold {2:0.0}.", DebugName, checksRemainingBeforeArrival, checksRemainingThreshold); if (checksRemainingBeforeArrival > MinNumberOfProgressChecksBeforeSpeedIncreasesCanBegin) { if (isIncreaseAboveApSpeedAllowed || CurrentSpeedSetting < ApSpeed) { if (CurrentSpeedSetting.TryIncreaseSpeed(out correctedSpeed)) { //D.Log(ShowDebugLog, "{0} is increasing speed to {1}.", DebugName, correctedSpeed.GetValueName()); return true; } } } } return false; }
/// <summary> /// Sets static values that cannot be set via a static initializer. /// /// WARNING: Static initializers use the Loading Thread which runs AT EDITOR TIME. /// GameTimeDuration needs to load values from XML (GeneralSettings) which won't /// run until the Editor.Play button is pressed. Unity avoids this condition by requiring /// that calls to Application.dataPath (via UnityConstants.DataLibraryDir, AValuesHelper /// and GeneralSettings) come from the MainThread, not the LoadingThread. /// If from the LoadingThread, an ArgumentException is raised. /// </summary> private void SetStaticValues() { if (_minSystemOrbitPeriod == default(GameTimeDuration)) { _minSystemOrbitPeriod = GameTimeDuration.OneYear; } if (_systemOrbitPeriodIncrement == default(GameTimeDuration)) { _systemOrbitPeriodIncrement = new GameTimeDuration(hours: 0, days: GameTime.DaysPerYear / 2, years: 0); } if (_minMoonOrbitPeriod == default(GameTimeDuration)) { _minMoonOrbitPeriod = new GameTimeDuration(hours: 0, days: 30, years: 0); } if (_moonOrbitPeriodIncrement == default(GameTimeDuration)) { _moonOrbitPeriodIncrement = new GameTimeDuration(hours: 0, days: 10, years: 0); } }
/// <summary> /// Initializes a new instance of the <see cref="WaitForHours"/> class. /// </summary> /// <param name="duration">The duration.</param> public RecurringWaitForHours(GameTimeDuration duration) : base(duration) { }
protected override void OnDespawned() { base.OnDespawned(); _cumDistanceTraveled = Constants.ZeroF; _positionLastRangeCheck = Vector3.zero; _courseUpdateJob = null; _chgHeadingJob = null; _impactEffectCompletionJob = null; _muzzleEffectCompletionJob = null; _courseUpdatePeriod = default(GameTimeDuration); _hasPushedOver = false; }
private string ConstructIntelText(AIntel intel) { string intelMsg = intel.CurrentCoverage.GetValueName(); string addendum = ". Intel is current."; var intelWithDatedCoverage = intel as Intel; if (intelWithDatedCoverage != null && intelWithDatedCoverage.IsDatedCoverageValid) { //D.Log("DateStamp = {0}, CurrentDate = {1}.", intelWithDatedCoverage.DateStamp, GameTime.Instance.CurrentDate); GameTimeDuration intelAge = new GameTimeDuration(intelWithDatedCoverage.DateStamp, GameTime.Instance.CurrentDate); addendum = String.Format(". Intel age {0}.", intelAge.ToString()); } intelMsg = intelMsg + addendum; D.Log(intelMsg); return intelMsg; }
/// <summary> /// Initializes a new instance of the <see cref="OrbitData" /> class that moves in orbit. /// <remarks>Used to create a single ShipCloseOrbitSlot during runtime around <c>orbitedItem</c>. /// The slotIndex is by definition 0.</remarks> /// </summary> /// <param name="orbitedItem">The orbited item.</param> /// <param name="innerRadius">The radius at this slot's lowest orbit.</param> /// <param name="outerRadius">The radius at this slot's highest orbit.</param> /// <param name="isOrbitedItemMobile">if set to <c>true</c> [is orbited item mobile].</param> /// <param name="orbitPeriod">The orbit period.</param> public OrbitData(GameObject orbitedItem, float innerRadius, float outerRadius, bool isOrbitedItemMobile, GameTimeDuration orbitPeriod) : this(orbitedItem, innerRadius, outerRadius, isOrbitedItemMobile, orbitPeriod, toOrbit: true) { }
/// <summary> /// Initializes a new instance of the <see cref="OrbitData" /> class. /// <remarks>Used to create a single ShipCloseOrbitSlot during runtime around <c>orbitedItem</c>. /// The slotIndex is by definition 0.</remarks> /// </summary> /// <param name="orbitedItem">The orbited item.</param> /// <param name="innerRadius">The closest distance to the body orbited.</param> /// <param name="outerRadius">The furthest distance from the body orbited.</param> /// <param name="isOrbitedItemMobile">if set to <c>true</c> [is orbited object mobile].</param> /// <param name="orbitPeriod">The orbit period.</param> /// <param name="toOrbit">if set to <c>true</c> the orbitSimulator will rotate if activated.</param> public OrbitData(GameObject orbitedItem, float innerRadius, float outerRadius, bool isOrbitedItemMobile, GameTimeDuration orbitPeriod, bool toOrbit) { Utility.ValidateNotNull(orbitedItem); Utility.Validate(innerRadius != outerRadius); Utility.ValidateForRange(innerRadius, Constants.ZeroF, outerRadius); Utility.ValidateForRange(outerRadius, innerRadius, Mathf.Infinity); Utility.Validate(orbitPeriod != default(GameTimeDuration)); OrbitedItem = orbitedItem; SlotIndex = Constants.Zero; InnerRadius = innerRadius; OuterRadius = outerRadius; MeanRadius = innerRadius + (outerRadius - innerRadius) / 2F; Depth = outerRadius - innerRadius; IsOrbitedItemMobile = isOrbitedItemMobile; OrbitPeriod = orbitPeriod; ToOrbit = toOrbit; }
/// <summary> /// Refreshes the progress check period. /// <remarks>Current algorithm is a HACK.</remarks> /// </summary> /// <param name="currentPeriod">The current progress check period.</param> /// <returns></returns> private GameTimeDuration __RefreshProgressCheckPeriod(GameTimeDuration currentPeriod) { float currentProgressCheckPeriodHours = currentPeriod.TotalInHours; float intendedSpeedValueChangeRatio = _engineRoom.IntendedCurrentSpeedValue / _engineRoom.__PreviousIntendedCurrentSpeedValue; // increase in speed reduces progress check period float refreshedProgressCheckPeriodHours = currentProgressCheckPeriodHours / intendedSpeedValueChangeRatio; if (refreshedProgressCheckPeriodHours < MinHoursPerProgressCheckPeriodAllowed) { // 5.9.16 eliminated warning as this can occur when currentPeriod is at or close to minimum. This is a HACK after all D.Log(ShowDebugLog, "{0}.__RefreshProgressCheckPeriod() generated period hours {1:0.0000} < MinAllowed {2:0.00}. Correcting.", DebugName, refreshedProgressCheckPeriodHours, MinHoursPerProgressCheckPeriodAllowed); refreshedProgressCheckPeriodHours = MinHoursPerProgressCheckPeriodAllowed; } refreshedProgressCheckPeriodHours = VaryCheckPeriod(refreshedProgressCheckPeriodHours); return new GameTimeDuration(refreshedProgressCheckPeriodHours); }
public override void Launch(IElementAttackable target, AWeapon weapon, Topography topography) { base.Launch(target, weapon, topography); _positionLastRangeCheck = Position; _rigidbody.velocity = ElementVelocityAtLaunch; _courseUpdatePeriod = new GameTimeDuration(1F / CourseUpdateFrequency); SteeringInaccuracy = CalcSteeringInaccuracy(); target.deathOneShot += TargetDeathEventHandler; _driftCorrector = new DriftCorrector(FullName, transform, _rigidbody); enabled = true; }
private void InitiateObstacleCheckingEnrouteTo(AutoPilotDestinationProxy destProxy, CourseRefreshMode courseRefreshMode) { D.AssertNotNull(destProxy, DebugName); // 12.15.16 Got null ref in TryCheckForObstacleEnrouteTo() D.AssertNull(_apObstacleCheckJob, DebugName); _apObstacleCheckPeriod = __GenerateObstacleCheckPeriod(); AutoPilotDestinationProxy detourProxy; string jobName = "{0}.ApObstacleCheckJob".Inject(DebugName); _apObstacleCheckJob = _jobMgr.RecurringWaitForHours(new Reference<GameTimeDuration>(() => _apObstacleCheckPeriod), jobName, waitMilestone: () => { Profiler.BeginSample("Ship ApObstacleCheckJob Execution", _ship); if (TryCheckForObstacleEnrouteTo(destProxy, out detourProxy)) { KillApObstacleCheckJob(); RefreshCourse(courseRefreshMode, detourProxy); Profiler.EndSample(); ContinueCourseToTargetVia(detourProxy); return; } if (_doesApObstacleCheckPeriodNeedRefresh) { _apObstacleCheckPeriod = __GenerateObstacleCheckPeriod(); _doesApObstacleCheckPeriodNeedRefresh = false; } Profiler.EndSample(); }); }
/// <summary> /// Disengages the pilot but does not change its heading or residual speed. /// <remarks>Externally calling ChangeSpeed() or ChangeHeading() will also disengage the pilot /// if needed and make a one time change to the ship's speed and/or heading.</remarks> /// </summary> internal void DisengagePilot() { if (IsPilotEngaged) { //D.Log(ShowDebugLog, "{0} Pilot disengaging.", DebugName); IsPilotEngaged = false; CleanupAnyRemainingJobs(); RefreshCourse(CourseRefreshMode.ClearCourse); ApSpeed = Speed.None; ApTargetProxy = null; _isApFleetwideMove = false; _isApCurrentSpeedFleetwide = false; _doesApObstacleCheckPeriodNeedRefresh = false; _doesApProgressCheckPeriodNeedRefresh = false; _apObstacleCheckPeriod = default(GameTimeDuration); _isApInPursuit = false; } }
/// <summary> /// Initializes a new instance of the <see cref="WaitForHours"/> class. /// </summary> /// <param name="duration">The duration.</param> public WaitForHours(GameTimeDuration duration) { _gameTime = GameTime.Instance; _targetDate = new GameDate(duration); _duration = duration; }