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 }); }
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; } }
internal override void Update(BehaviorUpdateContext context) { if (context.LogicFrame < _nextPing) { return; } _nextPing = context.LogicFrame + _moduleData.PingDelay; var nearbyObjects = context.GameContext.Game.PartitionCellManager.QueryObjects( _gameObject, _gameObject.Translation, _moduleData.EffectRadius, new PartitionQueries.ObjectFilterQuery(_moduleData.AllowFilter)); foreach (var nearbyObject in nearbyObjects) { // TODO: HealPercentPerSecond, UpgradeRequired, NonStackable, HealFX, AntiCategories foreach (var modifier in _moduleData.Modifiers) { nearbyObject.AddAttributeModifier(modifier.Value.Name, new AttributeModifier(modifier.Value)); } } }
internal override void Update(BehaviorUpdateContext context) { if (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; }
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; }
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); }
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; }
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; } }
internal abstract List <GameObject> Execute(BehaviorUpdateContext context);
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)); } }
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()); }
internal virtual bool SupplySourceHasBoxes(BehaviorUpdateContext context, SupplyWarehouseDockUpdate dockUpdate, GameObject supplySource) { return(dockUpdate?.HasBoxes() ?? false); }
internal override void Update(BehaviorUpdateContext context) { }
internal override void OnDie(BehaviorUpdateContext context, DeathType deathType) { _gameObject.Destroy(); }
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; } }
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; } }
private static GameObject FindClosestSupplyCenter(BehaviorUpdateContext context) { return(context.GameObject.Owner.SupplyManager.FindClosestSupplyCenter(context.GameObject)); }
internal virtual GameObject FindClosestSupplyWarehouse(BehaviorUpdateContext context) { return(context.GameObject.Owner.SupplyManager.FindClosestSupplyWarehouse(context.GameObject)); }
internal virtual void GetBox(BehaviorUpdateContext context) { _currentSourceDockUpdate?.GetBox(); }
internal override void Update(BehaviorUpdateContext context) { base.Update(context); }
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); } }
private void KillObject(BehaviorUpdateContext context) { context.GameObject.Kill(DeathType.Toppled, context.Time); }
internal abstract List <GameObject> Execute(BehaviorUpdateContext context, Vector3?position = null);
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) { 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 } }
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); } }
internal virtual void OnTrigger(BehaviorUpdateContext context, bool triggered) { }
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; } }
internal override List <GameObject> Execute(BehaviorUpdateContext context, Vector3?position) { // TODO return(new List <GameObject>()); }
private static TimeSpan GetDelayWithVariance(BehaviorUpdateContext context, TimeSpan delay, TimeSpan variance) { var randomMultiplier = (context.GameContext.Random.NextDouble() * 2.0) - 1.0; return(delay + variance * randomMultiplier); }