Ejemplo n.º 1
0
        internal virtual void FindNearbySupplyTarget(BehaviorUpdateContext context)
        {
            var supplyTargets = GetNearbySupplyCenters(context);

            var distanceToCurrentSupplyTarget = float.PositiveInfinity;

            foreach (var supplyTarget in supplyTargets)
            {
                if (supplyTarget.Owner != GameObject.Owner)
                {
                    continue;
                }

                var offsetToTarget   = supplyTarget.Translation - GameObject.Translation;
                var distanceToTarget = offsetToTarget.Vector2XY().Length();

                if (distanceToTarget > distanceToCurrentSupplyTarget)
                {
                    continue;
                }

                var dockUpdate = supplyTarget.FindBehavior <SupplyCenterDockUpdate>() ?? null;
                if (!dockUpdate?.CanApproach() ?? false)
                {
                    continue;
                }

                CurrentSupplyTarget           = supplyTarget;
                _currentTargetDockUpdate      = dockUpdate;
                distanceToCurrentSupplyTarget = distanceToTarget;
            }
        }
Ejemplo n.º 2
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;
            }
        }
Ejemplo n.º 3
0
        internal override void Update(BehaviorUpdateContext context)
        {
            base.Update(context);

            var isMoving = GameObject.ModelConditionFlags.Get(ModelConditionFlag.Moving);

            switch (SupplyGatherState)
            {
            case SupplyGatherStates.SearchForSupplySource:
                if (isMoving)
                {
                    break;
                }

                if (_currentSupplySource == null || !_currentSourceDockUpdate.HasBoxes())
                {
                    // TODO: also use KindOf SUPPLY_SOURCE_ON_PREVIEW ?
                    var supplySources = context.GameContext.GameObjects.GetObjectsByKindOf(ObjectKinds.SupplySource);

                    var distanceToCurrentSupplySource = float.PositiveInfinity;
                    foreach (var supplySource in supplySources)
                    {
                        var offsetToSource   = supplySource.Transform.Translation - GameObject.Transform.Translation;
                        var distanceToSource = offsetToSource.Vector2XY().Length();

                        if (distanceToSource > _moduleData.SupplyWarehouseScanDistance || distanceToSource > distanceToCurrentSupplySource)
                        {
                            continue;
                        }

                        var dockUpdate = supplySource.FindBehavior <SupplyWarehouseDockUpdate>() ?? null;

                        if (!dockUpdate?.HasBoxes() ?? false)
                        {
                            continue;
                        }

                        _currentSupplySource          = supplySource;
                        _currentSourceDockUpdate      = dockUpdate;
                        distanceToCurrentSupplySource = distanceToSource;
                    }
                }

                if (_currentSupplySource == null)
                {
                    break;
                }

                SetTargetPoint(_currentSupplySource.Transform.Translation);
                SupplyGatherState = SupplyGatherStates.ApproachSupplySource;
                break;

            case SupplyGatherStates.ApproachSupplySource:
                if (!isMoving)
                {
                    SupplyGatherState = SupplyGatherStates.RequestSupplies;
                    GameObject.ModelConditionFlags.Set(ModelConditionFlag.Docking, true);
                }
                break;

            case SupplyGatherStates.RequestSupplies:
                var boxesAvailable = _currentSourceDockUpdate?.HasBoxes() ?? false;

                if (!boxesAvailable)
                {
                    if (_numBoxes == 0)
                    {
                        GameObject.ModelConditionFlags.Set(ModelConditionFlag.Docking, false);
                        SupplyGatherState = SupplyGatherStates.SearchForSupplySource;
                        break;
                    }
                }
                else if (_numBoxes < _moduleData.MaxBoxes)
                {
                    _currentSourceDockUpdate.GetBox();
                    _waitUntil        = context.Time.TotalTime + TimeSpan.FromMilliseconds(_moduleData.SupplyWarehouseActionDelay);
                    SupplyGatherState = SupplyGatherStates.GatheringSupplies;
                    break;
                }

                GameObject.ModelConditionFlags.Set(ModelConditionFlag.Docking, false);
                GameObject.ModelConditionFlags.Set(ModelConditionFlag.Carrying, true);
                SupplyGatherState = SupplyGatherStates.SearchForSupplyTarget;
                break;

            case SupplyGatherStates.GatheringSupplies:
                if (context.Time.TotalTime > _waitUntil)
                {
                    _numBoxes++;
                    SupplyGatherState = SupplyGatherStates.RequestSupplies;
                }
                break;

            case SupplyGatherStates.SearchForSupplyTarget:
                if (CurrentSupplyTarget == null)
                {
                    var supplyTargets = context.GameContext.GameObjects.GetObjectsByKindOf(ObjectKinds.CashGenerator);

                    var distanceToCurrentSupplyTarget = float.PositiveInfinity;
                    foreach (var supplyTarget in supplyTargets)
                    {
                        if (supplyTarget.Owner != GameObject.Owner)
                        {
                            continue;
                        }

                        var offsetToTarget   = supplyTarget.Transform.Translation - GameObject.Transform.Translation;
                        var distanceToTarget = offsetToTarget.Vector2XY().Length();

                        if (distanceToTarget > _moduleData.SupplyWarehouseScanDistance || distanceToTarget > distanceToCurrentSupplyTarget)
                        {
                            continue;
                        }

                        var dockUpdate = supplyTarget.FindBehavior <SupplyCenterDockUpdate>() ?? null;
                        if (dockUpdate?.CanApproach() ?? false)
                        {
                            continue;
                        }

                        CurrentSupplyTarget           = supplyTarget;
                        _currentTargetDockUpdate      = dockUpdate;
                        distanceToCurrentSupplyTarget = distanceToTarget;
                    }
                }

                if (CurrentSupplyTarget == null)
                {
                    break;
                }

                if (_currentTargetDockUpdate == null)
                {
                    _currentTargetDockUpdate = CurrentSupplyTarget.FindBehavior <SupplyCenterDockUpdate>();
                }

                if (!_currentTargetDockUpdate.CanApproach())
                {
                    break;
                }

                SetTargetPoint(_currentTargetDockUpdate.GetApproachTargetPosition(this));
                SupplyGatherState = SupplyGatherStates.ApproachSupplyTarget;
                break;

            case SupplyGatherStates.ApproachSupplyTarget:
                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.Time.TotalTime + TimeSpan.FromMilliseconds(_moduleData.SupplyCenterActionDelay);
                break;

            case SupplyGatherStates.DumpingSupplies:
                if (context.Time.TotalTime > _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;
            }
        }