private bool ProcessWaypointPath(BehaviorUpdateContext context, ParkingPlaceBehaviour parkingPlaceBehavior, Queue <string> path) { if (_currentTaxiingTarget != null) { parkingPlaceBehavior.SetTaxiingPointBlocked(_currentTaxiingTarget, false); } if (path.Count > 0) { var nextPoint = path.Peek(); if (parkingPlaceBehavior.IsTaxiingPointBlocked(nextPoint)) { _waitUntil = context.LogicFrame + _moduleData.TakeoffPause; return(true); } if (context.LogicFrame < _waitUntil) { return(true); } _currentTaxiingTarget = nextPoint; parkingPlaceBehavior.SetTaxiingPointBlocked(nextPoint, true); base.SetTargetPoint(Base.ToWorldspace(parkingPlaceBehavior.GetBoneTranslation(path.Dequeue()))); return(true); } return(false); }
public DeletionUpdate(GameObject gameObject, DeletionUpdateModuleData moduleData) { _gameObject = gameObject; _moduleData = moduleData; _frameToDelete = gameObject.GameContext.GameLogic.CurrentFrame + gameObject.GameContext.GetRandomLogicFrameSpan(_moduleData.MinLifetime, _moduleData.MaxLifetime); }
internal override void OnDie(BehaviorUpdateContext context, DeathType deathType) { if (!IsApplicable(deathType)) { return; } _isDying = true; context.GameObject.ModelConditionFlags.Set(ModelConditionFlag.Dying, true); // TODO: ProbabilityModifier var destructionDelay = GetDelayWithVariance(context, _moduleData.DestructionDelay, _moduleData.DestructionDelayVariance); _midpointTime = context.LogicFrame + (destructionDelay / 2.0f); _destructionTime = context.LogicFrame + destructionDelay; _sinkStartTime = context.LogicFrame + GetDelayWithVariance(context, _moduleData.SinkDelay, _moduleData.SinkDelayVariance); // TODO: Decay // TODO: Fling ExecutePhaseActions(context, SlowDeathPhase.Initial); }
internal void ExtendRods() { _rodsExtended = true; _gameObject.Drawable.ModelConditionFlags.Set(ModelConditionFlag.PowerPlantUpgrading, true); _rodsExtendedEndFrame = _gameObject.GameContext.GameLogic.CurrentFrame + _moduleData.RodsExtendTime; }
internal override void Update(BehaviorUpdateContext context) { base.Update(context); if (_rodsExtended && _rodsExtendedEndFrame < context.LogicFrame) { _gameObject.Drawable.ModelConditionFlags.Set(ModelConditionFlag.PowerPlantUpgrading, false); _gameObject.Drawable.ModelConditionFlags.Set(ModelConditionFlag.PowerPlantUpgraded, true); _rodsExtendedEndFrame = LogicFrame.MaxValue; } }
internal override void Update(BehaviorUpdateContext context) { switch (_state) { case MissileState.Inactive: _nextStateChangeTime = context.LogicFrame + _moduleData.IgnitionDelay; _state = MissileState.WaitingForIgnition; goto case MissileState.WaitingForIgnition; case MissileState.WaitingForIgnition: if (context.LogicFrame >= _nextStateChangeTime) { _moduleData.IgnitionFX?.Value?.Execute( new FXListExecutionContext( GameObject.Rotation, GameObject.Translation, context.GameContext)); if (_moduleData.DistanceToTravelBeforeTurning > 0) { var pointToReachBeforeTurning = context.GameObject.Translation + Vector3.TransformNormal(Vector3.UnitX, context.GameObject.TransformMatrix) * _moduleData.DistanceToTravelBeforeTurning; AddTargetPoint(pointToReachBeforeTurning); } // TODO: What to do if target doesn't exist anymore? if (context.GameObject.CurrentWeapon.CurrentTarget != null) { AddTargetPoint(context.GameObject.CurrentWeapon.CurrentTarget.TargetPosition); } context.GameObject.Speed = _moduleData.InitialVelocity; _state = MissileState.Moving; } break; case MissileState.Moving: // TODO: TryToFollowTarget BezierProjectileBehavior.CheckForHit(context, _moduleData.DetonateCallsKill, DetonationFX); break; default: throw new InvalidOperationException(); } base.Update(context); }
internal override void Update(BehaviorUpdateContext context) { if (_gameObject.IsBeingConstructed() || (context.LogicFrame < _waitUntil)) { return; } _waitUntil = context.LogicFrame + _moduleData.DepositTiming; var amount = (uint)(_moduleData.DepositAmount * _gameObject.ProductionModifier); _gameObject.Owner.BankAccount.Deposit(amount); if (!_moduleData.GiveNoXP) { _gameObject.GainExperience((int)amount); } }
internal override void Update(BehaviorUpdateContext context) { if (context.LogicFrame < _nextPing) { return; } _nextPing = context.LogicFrame + _moduleData.PingDelay; var nearbyObjects = context.GameContext.Game.PartitionCellManager.QueryObjects( _gameObject, _gameObject.Translation, _moduleData.EffectRadius, new PartitionQueries.ObjectFilterQuery(_moduleData.AllowFilter)); foreach (var nearbyObject in nearbyObjects) { // TODO: HealPercentPerSecond, UpgradeRequired, NonStackable, HealFX, AntiCategories foreach (var modifier in _moduleData.Modifiers) { nearbyObject.AddAttributeModifier(modifier.Value.Name, new AttributeModifier(modifier.Value)); } } }
internal override void Update(BehaviorUpdateContext context) { if (Master == null) { // TODO: Should this ever be null? return; } var masterIsMoving = Master.ModelConditionFlags.Get(ModelConditionFlag.Moving); var masterHealthPercent = Master.HealthPercentage; var offsetToMaster = Master.Translation - _gameObject.Translation; var distanceToMaster = offsetToMaster.Vector2XY().Length(); if (!masterIsMoving && (masterHealthPercent < (Fix64)(_moduleData.RepairWhenBelowHealthPercent / 100.0) || _repairStatus != RepairStatus.INITIAL)) { // repair master var isMoving = _gameObject.ModelConditionFlags.Get(ModelConditionFlag.Moving); switch (_repairStatus) { case RepairStatus.INITIAL: // go to master if (distanceToMaster > 1.0) { _gameObject.AIUpdate.SetTargetPoint(Master.Translation); _repairStatus = RepairStatus.GOING_TO_MASTER; } _gameObject.AIUpdate.SetLocomotor(LocomotorSetType.Panic); break; case RepairStatus.GOING_TO_MASTER: if (!isMoving) { _repairStatus = RepairStatus.READY; var readyDuration = context.GameContext.GetRandomLogicFrameSpan(_moduleData.RepairMinReadyTime, _moduleData.RepairMaxReadyTime); _waitUntil = context.LogicFrame + readyDuration; } break; case RepairStatus.READY: if (context.LogicFrame >= _waitUntil) { var range = (float)(context.GameContext.Random.NextDouble() * _moduleData.RepairRange); var height = (float)(context.GameContext.Random.NextDouble() * (_moduleData.RepairMaxAltitude - _moduleData.RepairMinAltitude) + _moduleData.RepairMinAltitude); var angle = (float)(context.GameContext.Random.NextDouble() * (Math.PI * 2)); var offset = Vector3.Transform(new Vector3(range, 0.0f, height), Quaternion.CreateFromAxisAngle(Vector3.UnitZ, angle)); _gameObject.AIUpdate.SetTargetPoint(Master.Translation + offset); _repairStatus = RepairStatus.IN_TRANSITION; } break; case RepairStatus.IN_TRANSITION: if (!isMoving) { var(modelInstance, bone) = _gameObject.Drawable.FindBone(_moduleData.RepairWeldingFXBone); var transform = modelInstance.AbsoluteBoneTransforms[bone.Index]; _particleTemplate ??= context.GameContext.AssetLoadContext.AssetStore.FXParticleSystemTemplates.GetByName(_moduleData.RepairWeldingSys); var particleSystem = context.GameContext.ParticleSystems.Create( _particleTemplate, transform); particleSystem.Activate(); var weldDuration = context.GameContext.GetRandomLogicFrameSpan(_moduleData.RepairMinWeldTime, _moduleData.RepairMaxWeldTime); _waitUntil = context.LogicFrame + weldDuration; _repairStatus = RepairStatus.WELDING; } break; case RepairStatus.WELDING: if (context.LogicFrame >= _waitUntil) { _repairStatus = RepairStatus.READY; } break; } switch (_repairStatus) { case RepairStatus.ZIP_AROUND: case RepairStatus.IN_TRANSITION: case RepairStatus.WELDING: Master.Health += (Fix64)(_moduleData.RepairRatePerSecond / Game.LogicFramesPerSecond); if (Master.Health > Master.MaxHealth) { Master.Health = Master.MaxHealth; _repairStatus = RepairStatus.INITIAL; _gameObject.AIUpdate.SetLocomotor(LocomotorSetType.Normal); } break; } } else if (_gameObject.ModelConditionFlags.Get(ModelConditionFlag.Attacking)) { // stay near target var target = _gameObject.CurrentWeapon.CurrentTarget.GetTargetObject(); if (target != null) { var offsetToTarget = target.Translation - _gameObject.Translation; var distanceToTarget = offsetToTarget.Length(); if (_gameObject.AIUpdate.TargetPoints.Count == 0 && distanceToTarget > _moduleData.AttackWanderRange) { _gameObject.AIUpdate.SetTargetPoint(Master.Translation); } } } else { // stay near master var maxRange = _moduleData.GuardMaxRange; if (masterIsMoving) { maxRange = _moduleData.ScoutRange; } else if (Master.ModelConditionFlags.Get(ModelConditionFlag.Guarding)) { maxRange = _moduleData.GuardWanderRange; } else if (Master.ModelConditionFlags.Get(ModelConditionFlag.Attacking)) { maxRange = _moduleData.AttackRange; } if (_gameObject.AIUpdate.TargetPoints.Count == 0 && distanceToMaster > maxRange) { _gameObject.AIUpdate.SetTargetPoint(Master.Translation); } } if (_moduleData.DieOnMastersDeath && Master.ModelConditionFlags.Get(ModelConditionFlag.Dying)) { _gameObject.Die(DeathType.Exploded); } }
internal override void Update(BehaviorUpdateContext context) { base.Update(context); var isMoving = GameObject.ModelConditionFlags.Get(ModelConditionFlag.Moving); switch (SupplyGatherState) { case SupplyGatherStates.SearchingForSupplySource: if (isMoving) { break; } if (_currentSupplySource == null || (_currentSourceDockUpdate != null && !_currentSourceDockUpdate.HasBoxes())) { _currentSupplySource = FindClosestSupplyWarehouse(context); } if (_currentSupplySource == null) { break; } _currentSourceDockUpdate = _currentSupplySource.FindBehavior <SupplyWarehouseDockUpdate>(); var direction = Vector3.Normalize(_currentSupplySource.Translation - GameObject.Translation); SetTargetPoint(_currentSupplySource.Translation - direction * GetHarvestActivationRange()); SupplyGatherState = SupplyGatherStates.ApproachingSupplySource; break; case SupplyGatherStates.ApproachingSupplySource: if (!isMoving) { SupplyGatherState = SupplyGatherStates.RequestingSupplies; GameObject.ModelConditionFlags.Set(ModelConditionFlag.Docking, true); } break; case SupplyGatherStates.RequestingSupplies: var boxesAvailable = SupplySourceHasBoxes(context, _currentSourceDockUpdate, _currentSupplySource); if (!boxesAvailable) { _currentSupplySource = null; if (_numBoxes == 0) { GameObject.ModelConditionFlags.Set(ModelConditionFlag.Docking, false); SupplyGatherState = SupplyGatherStates.SearchingForSupplySource; break; } } else if (_numBoxes < _moduleData.MaxBoxes) { GetBox(context); var waitTime = _moduleData.SupplyWarehouseActionDelay + GetPreparationTime(); _waitUntil = context.LogicFrame + waitTime; SupplyGatherState = SupplyGatherStates.GatheringSupplies; SetGatheringConditionFlags(); break; } GameObject.ModelConditionFlags.Set(ModelConditionFlag.Docking, false); GameObject.ModelConditionFlags.Set(ModelConditionFlag.Carrying, true); SetActionConditionFlags(); _waitUntil = context.LogicFrame + GetPickingUpTime(); SupplyGatherState = SupplyGatherStates.PickingUpSupplies; break; case SupplyGatherStates.GatheringSupplies: if (context.LogicFrame >= _waitUntil) { _numBoxes++; SupplyGatherState = SupplyGatherStates.RequestingSupplies; } break; case SupplyGatherStates.PickingUpSupplies: if (context.LogicFrame >= _waitUntil) { SupplyGatherState = SupplyGatherStates.SearchingForSupplyTarget; ClearActionConditionFlags(); } break; case SupplyGatherStates.SearchingForSupplyTarget: if (CurrentSupplyTarget == null) { CurrentSupplyTarget = FindClosestSupplyCenter(context); } if (CurrentSupplyTarget == null) { break; } _currentTargetDockUpdate = CurrentSupplyTarget.FindBehavior <SupplyCenterDockUpdate>(); if (!_currentTargetDockUpdate.CanApproach()) { break; } SetTargetPoint(_currentTargetDockUpdate.GetApproachTargetPosition(this)); SupplyGatherState = SupplyGatherStates.ApproachingSupplyTarget; break; case SupplyGatherStates.ApproachingSupplyTarget: if (!isMoving) { SupplyGatherState = SupplyGatherStates.EnqueuedAtSupplyTarget; } break; case SupplyGatherStates.EnqueuedAtSupplyTarget: // wait until the DockUpdate moves us forward break; case SupplyGatherStates.StartDumpingSupplies: GameObject.ModelConditionFlags.Set(ModelConditionFlag.Docking, true); SupplyGatherState = SupplyGatherStates.DumpingSupplies; _waitUntil = context.LogicFrame + _moduleData.SupplyCenterActionDelay; break; case SupplyGatherStates.DumpingSupplies: if (context.LogicFrame >= _waitUntil) { SupplyGatherState = SupplyGatherStates.FinishedDumpingSupplies; var assetStore = context.GameContext.AssetLoadContext.AssetStore; var bonusAmountPerBox = GetAdditionalValuePerSupplyBox(assetStore.Upgrades); _currentTargetDockUpdate.DumpBoxes(assetStore, ref _numBoxes, bonusAmountPerBox); GameObject.ModelConditionFlags.Set(ModelConditionFlag.Docking, false); GameObject.ModelConditionFlags.Set(ModelConditionFlag.Carrying, false); } break; case SupplyGatherStates.FinishedDumpingSupplies: break; } }
internal override void Update(BehaviorUpdateContext context) { base.Update(context); if (!_moduleData.KeepsParkingSpaceWhenAirborne) { return; // helicopters are way more simple (at least for now) } if (Base == null) { // fix for mapObject aircrafts etc (e.g. ZH shellmap) // TODO: handle scenario of a destroyed airfield return; } var parkingPlaceBehavior = Base.FindBehavior <ParkingPlaceBehaviour>(); var isMoving = GameObject.ModelConditionFlags.Get(ModelConditionFlag.Moving); var trans = GameObject.Translation; var terrainHeight = context.GameContext.Terrain.HeightMap.GetHeight(trans.X, trans.Y); switch (CurrentJetAIState) { case JetAIState.JustCreated: var parkingTransform = parkingPlaceBehavior.GetParkingTransform(GameObject); var parkingOffset = Vector4.Transform(new Vector4(_moduleData.ParkingOffset, 0, 0, 1), parkingTransform.Rotation).ToVector3(); base.SetTargetPoint(Base.ToWorldspace(parkingTransform.Translation + parkingOffset)); CurrentJetAIState = JetAIState.MovingToParkingPlace; break; case JetAIState.MovingToParkingPlace: if (isMoving) { break; } CurrentJetAIState = JetAIState.ReachedParkingPlace; break; case JetAIState.ReachedParkingPlace: var createTransform = Base.ToWorldspace(parkingPlaceBehavior.GetUnitCreateTransform(GameObject)); SetTargetDirection(createTransform.LookDirection); CurrentJetAIState = JetAIState.Rotating; break; case JetAIState.Rotating: if (isMoving) { break; } //base.SetTargetPoint(GameObject.Transform.Translation + GameObject.Transform.LookDirection * _moduleData.ParkingOffset); CurrentJetAIState = JetAIState.Parked; break; case JetAIState.Parked: if (_unparkingRequested) { _pathToStart = parkingPlaceBehavior.GetPathToStart(GameObject); CurrentJetAIState = JetAIState.MovingTowardsStart; _unparkingRequested = false; } break; case JetAIState.MovingTowardsStart: if (isMoving || ProcessWaypointPath(context, parkingPlaceBehavior, _pathToStart)) { break; } CurrentJetAIState = JetAIState.PreparingStart; _waitUntil = context.LogicFrame + _moduleData.TakeoffPause; break; case JetAIState.PreparingStart: if (context.LogicFrame < _waitUntil) { break; } SetLocomotor(LocomotorSetType.Normal); GameObject.ModelConditionFlags.Set(ModelConditionFlag.JetExhaust, true); GameObject.ModelConditionFlags.Set(ModelConditionFlag.JetAfterburner, true); _afterburnerEnabled = true; var endPointPosition = Base.ToWorldspace(parkingPlaceBehavior.GetRunwayEndPoint(GameObject)); base.SetTargetPoint(endPointPosition); AddTargetPoint(_currentTargetPoint); CurrentJetAIState = JetAIState.Starting; CurrentLocomotor.LiftFactor = 0; break; case JetAIState.Starting: var speedPercentage = GameObject.Speed / CurrentLocomotor.GetSpeed(); CurrentLocomotor.LiftFactor = speedPercentage; if (speedPercentage < _moduleData.TakeoffSpeedForMaxLift) { break; } CurrentJetAIState = JetAIState.MovingTowardsTarget; break; case JetAIState.MovingTowardsTarget: if (isMoving) { if (_afterburnerEnabled && trans.Z - terrainHeight >= CurrentLocomotor.GetLocomotorValue(_ => _.PreferredHeight)) { GameObject.ModelConditionFlags.Set(ModelConditionFlag.JetAfterburner, false); _afterburnerEnabled = false; } break; } CurrentJetAIState = JetAIState.ReachedTargetPoint; _waitUntil = context.LogicFrame + _moduleData.ReturnToBaseIdleTime; break; case JetAIState.ReachedTargetPoint: if (context.LogicFrame < _waitUntil) { break; } var endPosition = Base.ToWorldspace(parkingPlaceBehavior.GetRunwayEndPoint(GameObject)); base.SetTargetPoint(endPosition); CurrentJetAIState = JetAIState.ReturningToBase; break; case JetAIState.ReturningToBase: if (isMoving) { break; } GameObject.ModelConditionFlags.Set(ModelConditionFlag.JetExhaust, false); CurrentJetAIState = JetAIState.MovingBackToHangar; SetLocomotor(LocomotorSetType.Taxiing); _pathToParking = parkingPlaceBehavior.GetPathToHangar(GameObject); break; case JetAIState.MovingBackToHangar: if (isMoving || ProcessWaypointPath(context, parkingPlaceBehavior, _pathToParking)) { break; } CurrentJetAIState = JetAIState.JustCreated; break; } if (trans.Z - terrainHeight < _moduleData.MinHeight) { trans.Z = terrainHeight + _moduleData.MinHeight; GameObject.SetTranslation(trans); } if (GameObject.ModelConditionFlags.Get(ModelConditionFlag.Dying)) { parkingPlaceBehavior.ClearObjectFromSlot(GameObject); Base.ProductionUpdate?.CloseDoor(parkingPlaceBehavior.GetCorrespondingSlot(GameObject)); } }
internal override void Update(BehaviorUpdateContext context) { var audioSystem = context.GameContext.AudioSystem; switch (_state) { case DoorState.Idle: return; case DoorState.StartOpening: audioSystem.DisposeSource(_closingSoundLoop); _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Door1Closing, false); _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Door1Opening, true); _toggleFinishedTime = context.LogicFrame + _moduleData.ResetTime; _pathingToggleTime = context.LogicFrame + (_moduleData.ResetTime * _moduleData.PercentOpenForPathing); _openingSoundLoop = audioSystem.PlayAudioEvent(_gameObject, _moduleData.SoundOpeningGateLoop?.Value, true); _finishedSoundTime = context.LogicFrame + _moduleData.TimeBeforePlayingOpenSound; _state = DoorState.Opening; _toggledColliders = false; _playedFinishedSound = false; break; case DoorState.Opening: if (!_toggledColliders && context.LogicFrame >= _pathingToggleTime) { _gameObject.HideCollider(_closedGeometry); foreach (var openCollider in _openGeometries) { _gameObject.ShowCollider(openCollider); } _toggledColliders = true; } if (!_playedFinishedSound && context.LogicFrame >= _finishedSoundTime) { audioSystem.DisposeSource(_openingSoundLoop); audioSystem.PlayAudioEvent(_gameObject, _moduleData.SoundFinishedOpeningGate?.Value); _playedFinishedSound = true; } if (context.LogicFrame >= _toggleFinishedTime) { _open = true; _state = DoorState.Idle; } break; case DoorState.StartClosing: audioSystem.DisposeSource(_openingSoundLoop); _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Door1Opening, false); _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Door1Closing, true); _toggleFinishedTime = context.LogicFrame + _moduleData.ResetTime; _pathingToggleTime = context.LogicFrame + (_moduleData.ResetTime * _moduleData.PercentOpenForPathing); _closingSoundLoop = audioSystem.PlayAudioEvent(_gameObject, _moduleData.SoundClosingGateLoop?.Value, true); _finishedSoundTime = context.LogicFrame + _moduleData.TimeBeforePlayingClosedSound; _state = DoorState.Closing; _toggledColliders = false; _playedFinishedSound = false; break; case DoorState.Closing: if (!_toggledColliders && context.LogicFrame >= _pathingToggleTime) { _gameObject.ShowCollider(_closedGeometry); foreach (var openCollider in _openGeometries) { _gameObject.HideCollider(openCollider); } _toggledColliders = true; } if (!_playedFinishedSound && context.LogicFrame >= _finishedSoundTime) { audioSystem.DisposeSource(_closingSoundLoop); audioSystem.PlayAudioEvent(_gameObject, _moduleData.SoundFinishedClosingGate?.Value); _playedFinishedSound = true; } if (context.LogicFrame >= _toggleFinishedTime) { _open = false; _state = DoorState.Idle; } break; } }
internal void Update(BehaviorUpdateContext context, BitArray <AutoAcquireEnemiesType> autoAcquireEnemiesWhenIdle) { var target = _gameObject.CurrentWeapon?.CurrentTarget; float targetYaw; if (_gameObject.ModelConditionFlags.Get(ModelConditionFlag.Moving)) { _turretAIstate = TurretAIStates.Recentering; _gameObject.CurrentWeapon?.SetTarget(null); } switch (_turretAIstate) { case TurretAIStates.Disabled: break; // TODO: how does it get enabled? case TurretAIStates.Idle: if (target != null) { _turretAIstate = TurretAIStates.Turning; _currentTarget = target; } else if (context.LogicFrame >= _waitUntil && (autoAcquireEnemiesWhenIdle?.Get(AutoAcquireEnemiesType.Yes) ?? true)) { _turretAIstate = TurretAIStates.ScanningForTargets; } break; case TurretAIStates.ScanningForTargets: if (target == null) { if (!FoundTargetWhileScanning(context, autoAcquireEnemiesWhenIdle)) { var scanInterval = context.GameContext.GetRandomLogicFrameSpan( _moduleData.MinIdleScanInterval, _moduleData.MaxIdleScanInterval); _waitUntil = context.LogicFrame + scanInterval; _turretAIstate = TurretAIStates.Idle; break; } } if (!_moduleData.FiresWhileTurning) { _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Attacking, false); } _turretAIstate = TurretAIStates.Turning; break; case TurretAIStates.Turning: if (target == null) { _waitUntil = context.LogicFrame + _moduleData.RecenterTime; _turretAIstate = TurretAIStates.Recentering; break; } var directionToTarget = (target.TargetPosition - _gameObject.Translation).Vector2XY(); targetYaw = MathUtility.GetYawFromDirection(directionToTarget) - _gameObject.Yaw; if (Rotate(targetYaw)) { break; } if (!_moduleData.FiresWhileTurning) { _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Attacking, true); } _turretAIstate = TurretAIStates.Attacking; break; case TurretAIStates.Attacking: if (target == null) { _waitUntil = context.LogicFrame + _moduleData.RecenterTime; _turretAIstate = TurretAIStates.Recentering; } else if (target != _currentTarget) { _turretAIstate = TurretAIStates.Turning; _currentTarget = target; } break; case TurretAIStates.Recentering: if (context.LogicFrame >= _waitUntil) { targetYaw = MathUtility.ToRadians(_moduleData.NaturalTurretAngle); if (!Rotate(targetYaw)) { _turretAIstate = TurretAIStates.Idle; } } break; } }
protected override void OnEnterStateImpl() { // TODO: Randomly pick value between Duration.Min and Duration.Max _exitTime = Context.GameContext.GameLogic.CurrentFrame + Duration.Min; }
internal static void CheckForStructure(BehaviorUpdateContext context, GameObject obj, ref LogicFrame waitUntil, LogicFrameSpan interval) { if (context.LogicFrame < waitUntil) { return; } waitUntil = context.LogicFrame + interval; var collidingObjects = context.GameContext.Game.PartitionCellManager.QueryObjects( obj, obj.Translation, obj.Geometry.BoundingCircleRadius, new PartitionQueries.KindOfQuery(ObjectKinds.Structure)); if (collidingObjects.Any()) { obj.IsSelectable = false; obj.Hidden = true; return; } obj.IsSelectable = true; obj.Hidden = false; }