internal virtual void FindNearbySupplySource(BehaviorUpdateContext context) { var supplySources = GetNearbySupplySources(context); var distanceToCurrentSupplySource = float.PositiveInfinity; foreach (var supplySource in supplySources) { var offsetToSource = supplySource.Translation - GameObject.Translation; var distanceToSource = offsetToSource.Vector2XY().Length(); if (distanceToSource > distanceToCurrentSupplySource) { continue; } var dockUpdate = supplySource.FindBehavior <SupplyWarehouseDockUpdate>() ?? null; if (!SupplySourceHasBoxes(context, dockUpdate, supplySource)) { continue; } _currentSupplySource = supplySource; _currentSourceDockUpdate = dockUpdate; distanceToCurrentSupplySource = distanceToSource; } }
internal override bool SupplySourceHasBoxes(BehaviorUpdateContext context, SupplyWarehouseDockUpdate dockUpdate, GameObject supplySource) { if (_moduleData.HarvestTrees && supplySource.Definition.KindOf.Get(ObjectKinds.Tree)) { if (supplySource.Supply > 0) { return(true); } supplySource.Die(DeathType.Normal, context.Time); return(false); } return(base.SupplySourceHasBoxes(context, dockUpdate, supplySource)); }
internal virtual bool SupplySourceHasBoxes(BehaviorUpdateContext context, SupplyWarehouseDockUpdate dockUpdate, GameObject supplySource) { return(dockUpdate?.HasBoxes() ?? false); }
internal override void Update(BehaviorUpdateContext context) { base.Update(context); var isMoving = GameObject.ModelConditionFlags.Get(ModelConditionFlag.Moving); switch (SupplyGatherState) { case SupplyGatherStates.SearchingForSupplySource: if (isMoving) { break; } if (_currentSupplySource == null || (_currentSourceDockUpdate != null && !_currentSourceDockUpdate.HasBoxes())) { _currentSupplySource = FindClosestSupplyWarehouse(context); } if (_currentSupplySource == null) { break; } _currentSourceDockUpdate = _currentSupplySource.FindBehavior <SupplyWarehouseDockUpdate>(); var direction = Vector3.Normalize(_currentSupplySource.Translation - GameObject.Translation); SetTargetPoint(_currentSupplySource.Translation - direction * GetHarvestActivationRange()); SupplyGatherState = SupplyGatherStates.ApproachingSupplySource; break; case SupplyGatherStates.ApproachingSupplySource: if (!isMoving) { SupplyGatherState = SupplyGatherStates.RequestingSupplies; GameObject.ModelConditionFlags.Set(ModelConditionFlag.Docking, true); } break; case SupplyGatherStates.RequestingSupplies: var boxesAvailable = SupplySourceHasBoxes(context, _currentSourceDockUpdate, _currentSupplySource); if (!boxesAvailable) { _currentSupplySource = null; if (_numBoxes == 0) { GameObject.ModelConditionFlags.Set(ModelConditionFlag.Docking, false); SupplyGatherState = SupplyGatherStates.SearchingForSupplySource; break; } } else if (_numBoxes < _moduleData.MaxBoxes) { GetBox(context); var waitTime = _moduleData.SupplyWarehouseActionDelay + GetPreparationTime(); _waitUntil = context.LogicFrame + waitTime; SupplyGatherState = SupplyGatherStates.GatheringSupplies; SetGatheringConditionFlags(); break; } GameObject.ModelConditionFlags.Set(ModelConditionFlag.Docking, false); GameObject.ModelConditionFlags.Set(ModelConditionFlag.Carrying, true); SetActionConditionFlags(); _waitUntil = context.LogicFrame + GetPickingUpTime(); SupplyGatherState = SupplyGatherStates.PickingUpSupplies; break; case SupplyGatherStates.GatheringSupplies: if (context.LogicFrame >= _waitUntil) { _numBoxes++; SupplyGatherState = SupplyGatherStates.RequestingSupplies; } break; case SupplyGatherStates.PickingUpSupplies: if (context.LogicFrame >= _waitUntil) { SupplyGatherState = SupplyGatherStates.SearchingForSupplyTarget; ClearActionConditionFlags(); } break; case SupplyGatherStates.SearchingForSupplyTarget: if (CurrentSupplyTarget == null) { CurrentSupplyTarget = FindClosestSupplyCenter(context); } if (CurrentSupplyTarget == null) { break; } _currentTargetDockUpdate = CurrentSupplyTarget.FindBehavior <SupplyCenterDockUpdate>(); if (!_currentTargetDockUpdate.CanApproach()) { break; } SetTargetPoint(_currentTargetDockUpdate.GetApproachTargetPosition(this)); SupplyGatherState = SupplyGatherStates.ApproachingSupplyTarget; break; case SupplyGatherStates.ApproachingSupplyTarget: if (!isMoving) { SupplyGatherState = SupplyGatherStates.EnqueuedAtSupplyTarget; } break; case SupplyGatherStates.EnqueuedAtSupplyTarget: // wait until the DockUpdate moves us forward break; case SupplyGatherStates.StartDumpingSupplies: GameObject.ModelConditionFlags.Set(ModelConditionFlag.Docking, true); SupplyGatherState = SupplyGatherStates.DumpingSupplies; _waitUntil = context.LogicFrame + _moduleData.SupplyCenterActionDelay; break; case SupplyGatherStates.DumpingSupplies: if (context.LogicFrame >= _waitUntil) { SupplyGatherState = SupplyGatherStates.FinishedDumpingSupplies; var assetStore = context.GameContext.AssetLoadContext.AssetStore; var bonusAmountPerBox = GetAdditionalValuePerSupplyBox(assetStore.Upgrades); _currentTargetDockUpdate.DumpBoxes(assetStore, ref _numBoxes, bonusAmountPerBox); GameObject.ModelConditionFlags.Set(ModelConditionFlag.Docking, false); GameObject.ModelConditionFlags.Set(ModelConditionFlag.Carrying, false); } break; case SupplyGatherStates.FinishedDumpingSupplies: break; } }
internal override void Update(BehaviorUpdateContext context) { base.Update(context); 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; } }