コード例 #1
0
        internal override List <GameObject> Execute(BehaviorUpdateContext context)
        {
            var debrisObject = context.GameContext.GameObjects.Add("GenericDebris", context.GameObject.Owner);

            var lifeTime = context.GameContext.Random.NextDouble() * (MaxLifetime - MinLifetime) + MinLifetime;

            debrisObject.LifeTime = context.Time.TotalTime + TimeSpan.FromMilliseconds(lifeTime);

            debrisObject.UpdateTransform(context.GameObject.Translation + Offset, context.GameObject.Rotation);

            // Model
            var w3dDebrisDraw = (W3dDebrisDraw)debrisObject.DrawModules[0];
            // TODO
            //var modelName = ModelNames[context.GameContext.Random.Next(ModelNames.Length)];
            var modelName = ModelNames[0];

            w3dDebrisDraw.SetModelName(modelName);

            // Physics
            var physicsBehavior = debrisObject.FindBehavior <PhysicsBehavior>();

            physicsBehavior.Mass = Mass;

            if (Disposition.Get(ObjectDisposition.SendItFlying))
            {
                physicsBehavior.AddForce(
                    new Vector3(
                        ((float)context.GameContext.Random.NextDouble() - 0.5f) * DispositionIntensity * 200,
                        ((float)context.GameContext.Random.NextDouble() - 0.5f) * DispositionIntensity * 200,
                        DispositionIntensity * 200));
            }

            // TODO: Count, Disposition, DispositionIntensity

            return(new List <GameObject> {
                debrisObject
            });
        }
コード例 #2
0
ファイル: MaxHealthUpgrade.cs プロジェクト: MetaIdea/OpenSAGE
        internal override void OnTrigger(BehaviorUpdateContext context, bool triggered)
        {
            if (triggered)
            {
                switch (_moduleData.ChangeType)
                {
                case MaxHealthChangeType.PreserveRatio:
                    Fix64 ratio = _gameObject.Body.Health / _gameObject.Body.MaxHealth;
                    _gameObject.Body.Health += ratio * (Fix64)_moduleData.AddMaxHealth;
                    break;

                case MaxHealthChangeType.AddCurrentHealthToo:
                    _gameObject.Body.Health += (Fix64)_moduleData.AddMaxHealth;
                    break;

                case MaxHealthChangeType.SameCurrentHealth:
                    // Don't add any new health
                    break;
                }

                _gameObject.Body.MaxHealth += (Fix64)_moduleData.AddMaxHealth;
            }
        }
コード例 #3
0
        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));
                }
            }
        }
コード例 #4
0
        internal override void Update(BehaviorUpdateContext context)
        {
            if (context.Time.TotalTime < _waitUntil)
            {
                return;
            }

            _waitUntil = context.Time.TotalTime + TimeSpan.FromMilliseconds(_updateInterval);

            var collidingObjects = context.GameContext.Quadtree.FindIntersecting(GameObject);

            foreach (var collidingObject in collidingObjects)
            {
                if (collidingObject.Definition.KindOf.Get(ObjectKinds.Structure))
                {
                    GameObject.IsSelectable = false;
                    GameObject.Hidden       = true;
                    return;
                }
            }

            GameObject.IsSelectable = true;
            GameObject.Hidden       = false;
        }
コード例 #5
0
        private void Initialize(BehaviorUpdateContext context)
        {
            // not sure why the required experience for rank 1 is 1 instead of 0
            if (_gameObject.ExperienceValue == 0)
            {
                _gameObject.ExperienceValue = 1;
            }

            _experienceLevels = FindRelevantExperienceLevels(context);
            if (_experienceLevels != null && _experienceLevels.Count > 0)
            {
                _nextLevel = _experienceLevels.First();
                _gameObject.ExperienceRequiredForNextLevel = _nextLevel.RequiredExperience;
                ObjectGainsExperience = true;

                while (_gameObject.Rank >= _nextLevel.Rank)
                {
                    levelUp();
                }
            }

            _bannerCarrierUpdate = _gameObject.FindBehavior <BannerCarrierUpdate>();
            _initial             = false;
        }
コード例 #6
0
        internal override List <GameObject> Execute(BehaviorUpdateContext context)
        {
            var result = new List <GameObject>();

            // TODO

            foreach (var objectName in ObjectNames)
            {
                var newGameObject = context.GameContext.GameObjects.Add(objectName.Value, context.GameObject.Owner);
                newGameObject.Transform.Translation = context.GameObject.Transform.Translation;
                newGameObject.Transform.Rotation    = context.GameObject.Transform.Rotation;

                // TODO: Count
                // TODO: Disposition
                // TODO: DispositionIntensity
                // TODO: IgnorePrimaryObstacle
                // TODO: Offset
                newGameObject.Transform.Translation += Offset;

                result.Add(newGameObject);
            }

            return(result);
        }
コード例 #7
0
        internal static void CheckForStructure(BehaviorUpdateContext context, GameObject obj, ref TimeSpan waitUntil, int interval)
        {
            if (context.Time.TotalTime < waitUntil)
            {
                return;
            }

            waitUntil = context.Time.TotalTime + TimeSpan.FromMilliseconds(interval);

            var collidingObjects = context.GameContext.Quadtree.FindNearby(obj, obj.Transform, obj.RoughCollider.WorldBounds.Radius);

            foreach (var collidingObject in collidingObjects)
            {
                if (collidingObject.Definition.KindOf.Get(ObjectKinds.Structure))
                {
                    obj.IsSelectable = false;
                    obj.Hidden       = true;
                    return;
                }
            }

            obj.IsSelectable = true;
            obj.Hidden       = false;
        }
コード例 #8
0
ファイル: TurretAIUpdate.cs プロジェクト: lanyizi/OpenSAGE
        internal void Update(BehaviorUpdateContext context, BitArray <AutoAcquireEnemiesType> autoAcquireEnemiesWhenIdle)
        {
            var deltaTime = (float)context.Time.DeltaTime.TotalSeconds;

            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.Time.TotalTime > _waitUntil && (autoAcquireEnemiesWhenIdle?.Get(AutoAcquireEnemiesType.Yes) ?? true))
                {
                    _turretAIstate = TurretAIStates.ScanningForTargets;
                }
                break;

            case TurretAIStates.ScanningForTargets:
                if (target == null)
                {
                    if (!FoundTargetWhileScanning(context, autoAcquireEnemiesWhenIdle))
                    {
                        var scanInterval =
                            context.GameContext.Random.NextDouble() *
                            (_moduleData.MaxIdleScanInterval - _moduleData.MinIdleScanInterval) +
                            _moduleData.MinIdleScanInterval;
                        _waitUntil     = context.Time.TotalTime + TimeSpan.FromMilliseconds(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.Time.TotalTime + TimeSpan.FromMilliseconds(_moduleData.RecenterTime);
                    _turretAIstate = TurretAIStates.Recentering;
                    break;
                }

                var directionToTarget = (target.TargetPosition - _gameObject.Translation).Vector2XY();
                targetYaw = MathUtility.GetYawFromDirection(directionToTarget) - _gameObject.Yaw;

                if (Rotate(targetYaw, deltaTime))
                {
                    break;
                }

                if (!_moduleData.FiresWhileTurning)
                {
                    _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Attacking, true);
                }

                _turretAIstate = TurretAIStates.Attacking;
                break;

            case TurretAIStates.Attacking:
                if (target == null)
                {
                    _waitUntil     = context.Time.TotalTime + TimeSpan.FromMilliseconds(_moduleData.RecenterTime);
                    _turretAIstate = TurretAIStates.Recentering;
                }
                else if (target != _currentTarget)
                {
                    _turretAIstate = TurretAIStates.Turning;
                    _currentTarget = target;
                }
                break;

            case TurretAIStates.Recentering:
                if (context.Time.TotalTime > _waitUntil)
                {
                    targetYaw = MathUtility.ToRadians(_moduleData.NaturalTurretAngle);
                    if (!Rotate(targetYaw, deltaTime))
                    {
                        _turretAIstate = TurretAIStates.Idle;
                    }
                }
                break;
            }
        }
コード例 #9
0
 internal abstract List <GameObject> Execute(BehaviorUpdateContext context);
コード例 #10
0
ファイル: JetAIUpdate.cs プロジェクト: Avatarchik/OpenSAGE
        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 transform = GameObject.Transform;
            var trans     = transform.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.Time.TotalTime + TimeSpan.FromMilliseconds(_moduleData.TakeoffPause);
                break;

            case JetAIState.PreparingStart:
                if (context.Time.TotalTime < _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.Time.TotalTime + TimeSpan.FromMilliseconds(_moduleData.ReturnToBaseIdleTime);
                break;

            case JetAIState.ReachedTargetPoint:
                if (context.Time.TotalTime < _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;
                transform.Translation = trans;
            }

            if (GameObject.ModelConditionFlags.Get(ModelConditionFlag.Dying))
            {
                parkingPlaceBehavior.ClearObjectFromSlot(GameObject);
                Base.ProductionUpdate?.CloseDoor(context.Time, parkingPlaceBehavior.GetCorrespondingSlot(GameObject));
            }
        }
コード例 #11
0
        internal virtual List <GameObject> GetNearbySupplyCenters(BehaviorUpdateContext context)
        {
            var nearbyObjects = context.GameContext.Scene3D.Quadtree.FindNearby(GameObject, GameObject.Transform, _moduleData.SupplyWarehouseScanDistance);

            return(nearbyObjects.Where(x => x.Definition.KindOf.Get(ObjectKinds.CashGenerator)).ToList());
        }
コード例 #12
0
 internal virtual bool SupplySourceHasBoxes(BehaviorUpdateContext context, SupplyWarehouseDockUpdate dockUpdate, GameObject supplySource)
 {
     return(dockUpdate?.HasBoxes() ?? false);
 }
コード例 #13
0
 internal override void Update(BehaviorUpdateContext context)
 {
 }
コード例 #14
0
ファイル: DestroyDie.cs プロジェクト: wazazhang/OpenSAGE
 internal override void OnDie(BehaviorUpdateContext context, DeathType deathType)
 {
     _gameObject.Destroy();
 }
コード例 #15
0
ファイル: ProductionUpdate.cs プロジェクト: MetaIdea/OpenSAGE
        internal override void Update(BehaviorUpdateContext context)
        {
            var time = context.Time;

            // If door is opening, halt production until it's finished opening.
            if (_currentDoorState == DoorState.Opening)
            {
                if (time.TotalTime >= _currentStepEnd)
                {
                    _productionQueue.RemoveAt(0);
                    Logger.Info($"Door waiting open for {_moduleData.DoorWaitOpenTime}");
                    _currentStepEnd   = time.TotalTime + _moduleData.DoorWaitOpenTime;
                    _currentDoorState = DoorState.Open;
                    _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Door1Opening, false);
                    _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Door1WaitingOpen, true);
                    MoveProducedObjectOut();
                }

                return;
            }

            if (_productionQueue.Count > 0)
            {
                var front  = _productionQueue[0];
                var result = front.Produce((float)time.DeltaTime.TotalMilliseconds);
                if (result == ProductionJobResult.Finished)
                {
                    if (front.Type == ProductionJobType.Unit)
                    {
                        if (_moduleData.NumDoorAnimations > 0)
                        {
                            Logger.Info($"Door opening for {_moduleData.DoorOpeningTime}");
                            _currentStepEnd   = time.TotalTime + _moduleData.DoorOpeningTime;
                            _currentDoorState = DoorState.Opening;
                            _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Door1Opening, true);

                            ProduceObject(front);
                        }
                        else
                        {
                            ProduceObject(front);
                            MoveProducedObjectOut();
                            _productionQueue.RemoveAt(0);
                        }
                    }
                    else if (front.Type == ProductionJobType.Upgrade)
                    {
                        GrantUpgrade(front);
                        _productionQueue.RemoveAt(0);
                    }
                }
            }

            switch (_currentDoorState)
            {
            case DoorState.Open:
                if (time.TotalTime >= _currentStepEnd)
                {
                    Logger.Info($"Door closing for {_moduleData.DoorCloseTime}");
                    _currentStepEnd   = time.TotalTime + _moduleData.DoorCloseTime;
                    _currentDoorState = DoorState.Closing;
                    _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Door1WaitingOpen, false);
                    _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Door1Closing, true);
                    // TODO: What is ModelConditionFlag.Door1WaitingToClose?
                }
                break;

            case DoorState.Closing:
                if (time.TotalTime >= _currentStepEnd)
                {
                    Logger.Info($"Door closed");
                    _currentDoorState = DoorState.Closed;
                    _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Door1Closing, false);
                }
                break;
            }
        }
コード例 #16
0
        internal override void Update(BehaviorUpdateContext context)
        {
            // TODO: get proper values for these
            var night   = false;
            var fire    = false;
            var glowing = false;

            if (night != _isNight || _initial)
            {
                var nightWindow = _moduleData.NightWindowName;
                if (night)
                {
                    _gameObject.ShowSubObject(nightWindow);
                }
                else
                {
                    _gameObject.HideSubObject(nightWindow);
                }

                _isNight = night;
            }

            if (fire != _fire || _initial)
            {
                var fireWindow = _moduleData.FireWindowName;
                if (fire)
                {
                    _gameObject.ShowSubObject(fireWindow);
                    foreach (var fireName in _moduleData.FireNames)
                    {
                        _gameObject.ShowSubObject(fireName);
                    }
                }
                else
                {
                    _gameObject.HideSubObject(fireWindow);

                    foreach (var fireName in _moduleData.FireNames)
                    {
                        _gameObject.HideSubObject(fireName);
                    }
                }

                _fire = fire;
            }

            if (glowing != _isGlowing || _initial)
            {
                var glowWindow = _moduleData.GlowWindowName;
                if (glowing)
                {
                    _gameObject.ShowSubObject(glowWindow);
                }
                else
                {
                    _gameObject.HideSubObject(glowWindow);
                }

                _isGlowing = glowing;
            }

            if (_initial)
            {
                _initial = false;
            }
        }
コード例 #17
0
 private static GameObject FindClosestSupplyCenter(BehaviorUpdateContext context)
 {
     return(context.GameObject.Owner.SupplyManager.FindClosestSupplyCenter(context.GameObject));
 }
コード例 #18
0
 internal virtual GameObject FindClosestSupplyWarehouse(BehaviorUpdateContext context)
 {
     return(context.GameObject.Owner.SupplyManager.FindClosestSupplyWarehouse(context.GameObject));
 }
コード例 #19
0
 internal virtual void GetBox(BehaviorUpdateContext context)
 {
     _currentSourceDockUpdate?.GetBox();
 }
コード例 #20
0
 internal override void Update(BehaviorUpdateContext context)
 {
     base.Update(context);
 }
コード例 #21
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);
            }
        }
コード例 #22
0
 private void KillObject(BehaviorUpdateContext context)
 {
     context.GameObject.Kill(DeathType.Toppled, context.Time);
 }
コード例 #23
0
 internal abstract List <GameObject> Execute(BehaviorUpdateContext context, Vector3?position = null);
コード例 #24
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;
            }
        }
コード例 #25
0
ファイル: ProductionUpdate.cs プロジェクト: tecno14/OpenSAGE
        internal override void Update(BehaviorUpdateContext context)
        {
            var time = context.Time;

            // If door is opening, halt production until it's finished opening.
            if (_currentDoorState == DoorState.Opening)
            {
                if (time.TotalTime >= _currentStepEnd)
                {
                    _productionQueue.RemoveAt(0);
                    Logger.Info($"Door waiting open for {_moduleData.DoorWaitOpenTime}");
                    _currentStepEnd   = time.TotalTime + _moduleData.DoorWaitOpenTime;
                    _currentDoorState = DoorState.Open;

                    GetDoorConditionFlags(out var doorOpening, out var doorWaitingOpen, out var _);

                    _gameObject.ModelConditionFlags.Set(doorOpening, false);
                    _gameObject.ModelConditionFlags.Set(doorWaitingOpen, true);
                    MoveProducedObjectOut();
                }

                return;
            }

            if (_productionQueue.Count > 0)
            {
                var front  = _productionQueue[0];
                var result = front.Produce((float)time.DeltaTime.TotalMilliseconds);
                if (result == ProductionJobResult.Finished)
                {
                    if (front.Type == ProductionJobType.Unit)
                    {
                        if (_moduleData.NumDoorAnimations > 0 &&
                            ExitsThroughDoor(front.ObjectDefinition) &&
                            (_currentDoorState != DoorState.OpenForHordePayload))
                        {
                            Logger.Info($"Door opening for {_moduleData.DoorOpeningTime}");
                            _currentStepEnd   = time.TotalTime + _moduleData.DoorOpeningTime;
                            _currentDoorState = DoorState.Opening;

                            SetDoorIndex();

                            GetDoorConditionFlags(out var doorOpening, out var _, out var _);
                            _gameObject.ModelConditionFlags.Set(doorOpening, true);

                            ProduceObject(front);
                        }
                        else
                        {
                            ProduceObject(front);
                            MoveProducedObjectOut();
                            _productionQueue.RemoveAt(0);
                        }
                    }
                    else if (front.Type == ProductionJobType.Upgrade)
                    {
                        GrantUpgrade(front);
                        _productionQueue.RemoveAt(0);
                    }
                }
            }

            switch (_currentDoorState)
            {
            case DoorState.Open:
                if (time.TotalTime >= _currentStepEnd)
                {
                    _productionExit ??= _gameObject.FindBehavior <IProductionExit>();
                    if (_productionExit is ParkingPlaceBehaviour)
                    {
                        break;     // Door is closed on aircraft death from JetAIUpdate
                    }
                    CloseDoor(time, _doorIndex);
                }
                break;

            case DoorState.Closing:
                if (time.TotalTime >= _currentStepEnd)
                {
                    Logger.Info($"Door closed");
                    _currentDoorState = DoorState.Closed;
                    GetDoorConditionFlags(out var _, out var _, out var doorClosing);
                    _gameObject.ModelConditionFlags.Set(doorClosing, false);
                }
                break;

            case DoorState.OpenForHordePayload:
                break;     //door is closed again by HordeContain
            }
        }
コード例 #26
0
        internal override void Update(BehaviorUpdateContext context)
        {
            bool triggered = false;

            if (_moduleData.TriggeredBy != null)
            {
                foreach (var trigger in _moduleData.TriggeredBy)
                {
                    var upgrade = context.GameObject.Upgrades.FirstOrDefault(template => template.Name == trigger);

                    if (upgrade != null)
                    {
                        triggered = true;
                        if (_moduleData.RequiresAllTriggers == false)
                        {
                            break;
                        }
                        else
                        {
                            //TODO:
                        }
                    }
                    else if (_moduleData.RequiresAllTriggers == true)
                    {
                        break;
                    }
                }
            }

            if (_moduleData.ConflictsWith != null)
            {
                foreach (var conflict in _moduleData.ConflictsWith)
                {
                    var upgrade = context.GameObject.Upgrades.FirstOrDefault(template => template.Name == conflict);

                    if (upgrade != null)
                    {
                        if (_moduleData.RequiresAllConflictingTriggers == false)
                        {
                            triggered = false;
                            break;
                        }
                        else
                        {
                            //TODO:
                        }
                    }
                    else if (_moduleData.RequiresAllConflictingTriggers == true)
                    {
                        break;
                    }
                }
            }

            if (triggered != _triggered || _initial)
            {
                _initial   = false;
                _triggered = triggered;
                OnTrigger(context, _triggered);
            }
        }
コード例 #27
0
 internal virtual void OnTrigger(BehaviorUpdateContext context, bool triggered)
 {
 }
コード例 #28
0
        internal override void Update(BehaviorUpdateContext context)
        {
            if (_initial && _experienceLevels == null)
            {
                Initialize(context);
            }

            if (_experienceLevels == null ||
                _experienceLevels.Count == 0 ||
                _gameObject.ExperienceValue < _nextLevel.RequiredExperience)
            {
                return;
            }

            _gameObject.ExperienceValue -= _nextLevel.RequiredExperience;
            _gameObject.Rank             = _nextLevel.Rank;

            if (_nextLevel.Upgrades != null)
            {
                foreach (var upgradeReference in _nextLevel.Upgrades)
                {
                    _gameObject.Upgrades.Add(context.GameContext.AssetLoadContext.AssetStore.Upgrades.GetByName(upgradeReference));
                }
            }

            if (_nextLevel.LevelUpFX != null)
            {
                var levelUpFx = context.GameContext.AssetLoadContext.AssetStore.FXLists.GetByName(_nextLevel.LevelUpFX);

                levelUpFx?.Execute(new FXListExecutionContext(
                                       context.GameObject.Rotation,
                                       context.GameObject.Translation,
                                       context.GameContext));
            }

            if (_nextLevel.InformUpdateModule)
            {
                _bannerCarrierUpdate?.NotifyLevelChanged();
            }

            if (_nextLevel.SelectionDecal != null)
            {
                _gameObject.SelectionDecal = _nextLevel.SelectionDecal;
            }

            // TODO:
            // ExperienceAwardOwnGuysDie -> what is this?
            // AttributeModifiers
            // EmotionType

            _experienceLevels.RemoveAt(0);
            if (_experienceLevels.Count > 0)
            {
                _nextLevel = _experienceLevels.First();
                _gameObject.ExperienceRequiredForNextLevel = _nextLevel.RequiredExperience;
            }
            else
            {
                _gameObject.ExperienceRequiredForNextLevel = int.MaxValue;
            }
        }
コード例 #29
0
 internal override List <GameObject> Execute(BehaviorUpdateContext context, Vector3?position)
 {
     // TODO
     return(new List <GameObject>());
 }
コード例 #30
0
        private static TimeSpan GetDelayWithVariance(BehaviorUpdateContext context, TimeSpan delay, TimeSpan variance)
        {
            var randomMultiplier = (context.GameContext.Random.NextDouble() * 2.0) - 1.0;

            return(delay + variance * randomMultiplier);
        }