Пример #1
0
        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);
        }
Пример #2
0
        public DeletionUpdate(GameObject gameObject, DeletionUpdateModuleData moduleData)
        {
            _gameObject = gameObject;
            _moduleData = moduleData;

            _frameToDelete = gameObject.GameContext.GameLogic.CurrentFrame + gameObject.GameContext.GetRandomLogicFrameSpan(_moduleData.MinLifetime, _moduleData.MaxLifetime);
        }
Пример #3
0
        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);
        }
Пример #4
0
        internal void ExtendRods()
        {
            _rodsExtended = true;

            _gameObject.Drawable.ModelConditionFlags.Set(ModelConditionFlag.PowerPlantUpgrading, true);

            _rodsExtendedEndFrame = _gameObject.GameContext.GameLogic.CurrentFrame + _moduleData.RodsExtendTime;
        }
Пример #5
0
        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;
            }
        }
Пример #6
0
        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);
        }
Пример #7
0
        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));
                }
            }
        }
Пример #9
0
        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);
            }
        }
Пример #10
0
        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;
            }
        }
Пример #11
0
        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));
            }
        }
Пример #12
0
        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;
            }
        }
Пример #13
0
        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;
            }
        }
Пример #14
0
 protected override void OnEnterStateImpl()
 {
     // TODO: Randomly pick value between Duration.Min and Duration.Max
     _exitTime = Context.GameContext.GameLogic.CurrentFrame + Duration.Min;
 }
Пример #15
0
        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;
        }