internal void PurgeAll() { FutureEvents.Purge((int)Tick); PurgeTerminalSystem(); foreach (var reports in Reporter.ReportData.Values) { foreach (var report in reports) { report.Clean(); Reporter.ReportPool.Return(report); } reports.Clear(); } Reporter.ReportData.Clear(); Reporter.ReportPool.Clean(); PacketsToClient.Clear(); PacketsToServer.Clear(); foreach (var suit in (PacketType[])Enum.GetValues(typeof(PacketType))) { foreach (var pool in PacketPools.Values) { pool.Clean(); } PacketPools.Clear(); } foreach (var item in _effectedCubes) { var cubeid = item.Key; var blockInfo = item.Value; var functBlock = blockInfo.FunctBlock; var cube = blockInfo.CubeBlock; if (cube == null || cube.MarkedForClose) { _effectPurge.Enqueue(cubeid); continue; } functBlock.EnabledChanged -= ForceDisable; functBlock.Enabled = blockInfo.FirstState; cube.SetDamageEffect(false); _effectPurge.Enqueue(cubeid); } while (_effectPurge.Count != 0) { _effectedCubes.Remove(_effectPurge.Dequeue()); } Av.Glows.Clear(); Av.AvShotPool.Clean(); DeferedUpBlockTypeCleanUp(true); BlockTypeCleanUp.Clear(); foreach (var map in GridToFatMap.Keys) { RemoveGridFromMap(map); } GridToFatMap.Clear(); FatMapPool.Clean(); DirtyGridsTmp.Clear(); foreach (var structure in WeaponPlatforms.Values) { foreach (var system in structure.WeaponSystems) { foreach (var ammo in system.Value.WeaponAmmoTypes) { ammo.AmmoDef.Const.PrimeEntityPool?.Clean(); } } structure.WeaponSystems.Clear(); } WeaponPlatforms.Clear(); foreach (var gridToMap in GridToBlockTypeMap) { foreach (var map in gridToMap.Value) { map.Value.ClearImmediate(); ConcurrentListPool.Return(map.Value); } gridToMap.Value.Clear(); BlockTypePool.Return(gridToMap.Value); } GridToBlockTypeMap.Clear(); foreach (var playerGrids in PlayerEntityIdInRange) { playerGrids.Value.Clear(); } PlayerEntityIdInRange.Clear(); DirtyGrids.Clear(); DsUtil.Purge(); DsUtil2.Purge(); _effectActive = false; ShootingWeapons.Clear(); AcquireTargets.Clear(); RemoveEffectsFromGrid.Clear(); WeaponAmmoPullQueue.Clear(); AmmoToPullQueue.Clear(); Hits.Clear(); AllArmorBaseDefinitions.Clear(); HeavyArmorBaseDefinitions.Clear(); AllArmorBaseDefinitions.Clear(); AcquireTargets.Clear(); ChargingWeapons.Clear(); LargeBlockSphereDb.Clear(); SmallBlockSphereDb.Clear(); AnimationsToProcess.Clear(); _subTypeIdToWeaponDefs.Clear(); WeaponDefinitions.Clear(); SlimsSortedList.Clear(); _destroyedSlims.Clear(); _destroyedSlimsClient.Clear(); _slimHealthClient.Clear(); _slimsSet.Clear(); _turretDefinitions.Clear(); foreach (var comp in CompsToStart) { PlatFormPool.Return(comp.Platform); comp.Platform = null; } foreach (var readd in CompReAdds) { PlatFormPool.Return(readd.Comp.Platform); readd.Comp.Platform = null; } foreach (var comp in CompsDelayed) { PlatFormPool.Return(comp.Platform); comp.Platform = null; } PlatFormPool.Clean(); CompsToStart.ClearImmediate(); CompsDelayed.Clear(); CompReAdds.Clear(); GridAiPool.Clean(); Av.RipMap.Clear(); foreach (var mess in Av.KeensBrokenParticles) { Av.KeenMessPool.Return(mess); } Av.KeensBrokenParticles.Clear(); foreach (var av in Av.AvShots) { av.GlowSteps.Clear(); Av.AvShotPool.Return(av); } Av.AvShotPool.Clean(); Av.AvBarrels1.Clear(); Av.AvBarrels2.Clear(); Av.AvShots.Clear(); Av.HitSounds.Clear(); foreach (var errorpkt in ClientSideErrorPktList) { errorpkt.Packet.CleanUp(); } ClientSideErrorPktList.Clear(); GridEffectPool.Clean(); GridEffectsPool.Clean(); BlockTypePool.Clean(); ConcurrentListPool.Clean(); GroupInfoPool.Clean(); TargetInfoPool.Clean(); Projectiles.Clean(); WeaponCoreBlockDefs.Clear(); VanillaIds.Clear(); VanillaCoreIds.Clear(); WeaponCoreFixedBlockDefs.Clear(); WeaponCoreTurretBlockDefs.Clear(); foreach (var p in Projectiles.ProjectilePool) { p.AmmoEffect?.Stop(); } Projectiles.ShrapnelToSpawn.Clear(); Projectiles.ShrapnelPool.Clean(); Projectiles.FragmentPool.Clean(); Projectiles.ActiveProjetiles.ApplyChanges(); Projectiles.ActiveProjetiles.Clear(); Projectiles.ProjectilePool.Clear(); Projectiles.HitEntityPool.Clean(); Projectiles.CleanUp.Clear(); Projectiles.VirtInfoPool.Clean(); DbsToUpdate.Clear(); GridTargetingAIs.Clear(); DsUtil = null; DsUtil2 = null; SlimsSortedList = null; Enforced = null; StallReporter = null; Proccessor = null; Physics = null; Camera = null; Projectiles = null; TrackingAi = null; UiInput = null; TargetUi = null; Placer = null; WheelUi = null; TargetGps = null; SApi.Unload(); SApi = null; Api = null; ApiServer = null; Reporter = null; WeaponDefinitions = null; AnimationsToProcess = null; ProjectileTree.Clear(); ProjectileTree = null; Av = null; HudUi = null; AllDefinitions = null; SoundDefinitions = null; ActiveCockPit = null; ActiveControlBlock = null; ControlledEntity = null; }
internal void PurgeAll() { PurgedAll = true; FutureEvents.Purge((int)Tick); foreach (var comp in CompsToStart) { if (comp?.Platform != null) { CloseComps(comp.MyCube); } } foreach (var readd in CompReAdds) { if (!readd.Ai.Closed) { readd.Ai.AiForceClose(); } if (readd.Comp?.Platform != null) { CloseComps(readd.Comp.MyCube); } } foreach (var comp in CompsDelayed) { if (comp?.Platform != null) { CloseComps(comp.MyCube); } } foreach (var gridAi in DelayedAiClean) { if (!gridAi.Closed) { gridAi.AiForceClose(); } } PlatFormPool.Clean(); CompsToStart.ClearImmediate(); DelayedAiClean.ClearImmediate(); CompsDelayed.Clear(); CompReAdds.Clear(); GridAiPool.Clean(); PurgeTerminalSystem(this); HudUi.Purge(); TerminalMon.Purge(); foreach (var reports in Reporter.ReportData.Values) { foreach (var report in reports) { report.Clean(); Reporter.ReportPool.Return(report); } reports.Clear(); } Reporter.ReportData.Clear(); Reporter.ReportPool.Clean(); PacketsToClient.Clear(); PacketsToServer.Clear(); AcqManager.Clean(); CleanSounds(true); foreach (var e in Emitters) { e.StopSound(true); } foreach (var e in Av.HitEmitters) { e.StopSound(true); } foreach (var e in Av.FireEmitters) { e.StopSound(true); } foreach (var e in Av.TravelEmitters) { e.StopSound(true); } Emitters.Clear(); Av.HitEmitters.Clear(); Av.FireEmitters.Clear(); Av.TravelEmitters.Clear(); foreach (var item in EffectedCubes) { var cubeid = item.Key; var blockInfo = item.Value; var functBlock = blockInfo.FunctBlock; if (functBlock == null || functBlock.MarkedForClose) { _effectPurge.Enqueue(cubeid); continue; } functBlock.EnabledChanged -= ForceDisable; functBlock.Enabled = blockInfo.FirstState; functBlock.SetDamageEffect(false); if (HandlesInput) { functBlock.AppendingCustomInfo -= blockInfo.AppendCustomInfo; } _effectPurge.Enqueue(cubeid); } while (_effectPurge.Count != 0) { EffectedCubes.Remove(_effectPurge.Dequeue()); } Av.Glows.Clear(); Av.AvShotPool.Clean(); DeferedUpBlockTypeCleanUp(true); BlockTypeCleanUp.Clear(); foreach (var map in GridToInfoMap.Keys) { RemoveGridFromMap(map); } GridToInfoMap.Clear(); GridMapPool.Clean(); DirtyGridsTmp.Clear(); foreach (var structure in WeaponPlatforms.Values) { foreach (var system in structure.WeaponSystems) { system.Value.PreFirePairs.Clear(); system.Value.FireWhenDonePairs.Clear(); system.Value.FirePerShotPairs.Clear(); system.Value.RotatePairs.Clear(); system.Value.ReloadPairs.Clear(); foreach (var ammo in system.Value.AmmoTypes) { ammo.AmmoDef.Const.PrimeEntityPool?.Clean(); ammo.AmmoDef.Const.HitDefaultSoundPairs.Clear(); ammo.AmmoDef.Const.HitVoxelSoundPairs.Clear(); ammo.AmmoDef.Const.HitShieldSoundPairs.Clear(); ammo.AmmoDef.Const.HitFloatingSoundPairs.Clear(); ammo.AmmoDef.Const.HitPlayerSoundPairs.Clear(); ammo.AmmoDef.Const.TravelSoundPairs.Clear(); ammo.AmmoDef.Const.CustomSoundPairs.Clear(); } } structure.WeaponSystems.Clear(); } WeaponPlatforms.Clear(); foreach (var gridToMap in GridToBlockTypeMap) { foreach (var map in gridToMap.Value) { ConcurrentListPool.Return(map.Value); } gridToMap.Value.Clear(); BlockTypePool.Return(gridToMap.Value); } GridToBlockTypeMap.Clear(); foreach (var playerGrids in PlayerEntityIdInRange) { playerGrids.Value.Clear(); } PlayerEntityIdInRange.Clear(); DirtyGridInfos.Clear(); DsUtil.Purge(); DsUtil2.Purge(); ShootingWeapons.Clear(); WeaponToPullAmmo.Clear(); AmmoToPullQueue.Clear(); ChargingWeaponsIndexer.Clear(); WeaponsToRemoveAmmoIndexer.Clear(); ChargingWeapons.Clear(); Hits.Clear(); HomingWeapons.Clear(); GridToMasterAi.Clear(); Players.Clear(); IdToCompMap.Clear(); AllArmorBaseDefinitions.Clear(); HeavyArmorBaseDefinitions.Clear(); AllArmorBaseDefinitions.Clear(); AcquireTargets.Clear(); LargeBlockSphereDb.Clear(); SmallBlockSphereDb.Clear(); AnimationsToProcess.Clear(); _subTypeIdToWeaponDefs.Clear(); WeaponDefinitions.Clear(); SlimsSortedList.Clear(); _destroyedSlims.Clear(); _destroyedSlimsClient.Clear(); _slimHealthClient.Clear(); _slimsSet.Clear(); _turretDefinitions.Clear(); _tmpNearByBlocks.Clear(); foreach (var av in Av.AvShots) { av.GlowSteps.Clear(); Av.AvShotPool.Return(av); } Av.AvShotPool.Clean(); Av.AvBarrels1.Clear(); Av.AvBarrels2.Clear(); Av.AvShots.Clear(); Av.HitSounds.Clear(); foreach (var errorpkt in ClientSideErrorPkt) { errorpkt.Packet.CleanUp(); } ClientSideErrorPkt.Clear(); GridEffectPool.Clean(); GridEffectsPool.Clean(); BlockTypePool.Clean(); ConcurrentListPool.Clean(); TargetInfoPool.Clean(); PacketObjPool.Clean(); InventoryMoveRequestPool.Clean(); WeaponCoreBlockDefs.Clear(); VanillaIds.Clear(); VanillaCoreIds.Clear(); WeaponCoreFixedBlockDefs.Clear(); WeaponCoreTurretBlockDefs.Clear(); VoxelCaches.Clear(); ArmorCubes.Clear(); foreach (var p in Projectiles.ProjectilePool) { p.Info?.AvShot?.AmmoEffect?.Stop(); } Projectiles.ShrapnelToSpawn.Clear(); Projectiles.ShrapnelPool.Clean(); Projectiles.FragmentPool.Clean(); Projectiles.ActiveProjetiles.Clear(); Projectiles.ProjectilePool.Clear(); Projectiles.HitEntityPool.Clean(); Projectiles.VirtInfoPool.Clean(); DbsToUpdate.Clear(); GridTargetingAIs.Clear(); DsUtil = null; DsUtil2 = null; SlimsSortedList = null; Settings = null; StallReporter = null; TerminalMon = null; Physics = null; Camera = null; Projectiles = null; TrackingAi = null; UiInput = null; TargetUi = null; Placer = null; TargetGps = null; SApi.Unload(); SApi = null; Api = null; ApiServer = null; Reporter = null; WeaponDefinitions = null; AnimationsToProcess = null; ProjectileTree.Clear(); ProjectileTree = null; Av = null; HudUi = null; AllDefinitions = null; SoundDefinitions = null; ActiveCockPit = null; ActiveControlBlock = null; ControlledEntity = null; TmpStorage = null; }
private void ShootWeapons() { for (int i = ShootingWeapons.Count - 1; i >= 0; i--) { var w = ShootingWeapons[i]; var invalidWeapon = w.Comp.MyCube.MarkedForClose || w.Comp.Ai == null || w.Comp.Ai.Concealed || w.Comp.Ai.MyGrid.MarkedForClose || w.Comp.Platform.State != CorePlatform.PlatformState.Ready; var smartTimer = !w.AiEnabled && w.ActiveAmmoDef.ConsumableDef.Trajectory.Guidance == WeaponDefinition.ConsumableDef.TrajectoryDef.GuidanceType.Smart && Tick - w.LastSmartLosCheck > 180; var quickSkip = invalidWeapon || smartTimer && !w.SmartLos() || w.PauseShoot; if (quickSkip) { continue; } if (!w.Comp.UnlimitedPower) { //TODO add logic for power priority if (!w.System.DesignatorWeapon && w.Comp.Ai.OverPowered && (w.ActiveAmmoDef.ConsumableDef.Const.EnergyAmmo || w.ActiveAmmoDef.ConsumableDef.Const.IsHybrid) && !w.ActiveAmmoDef.ConsumableDef.Const.MustCharge) { if (w.ChargeDelayTicks == 0) { var percUseable = w.RequiredPower / w.Comp.Ai.RequestedWeaponsDraw; w.OldUseablePower = w.UseablePower; w.UseablePower = (w.Comp.Ai.GridMaxPower * .98f) * percUseable; if (w.DrawingPower) { w.DrawPower(true); } else { w.DrawPower(); } w.ChargeDelayTicks = (uint)(((w.RequiredPower - w.UseablePower) / w.UseablePower) * MyEngineConstants.UPDATE_STEPS_PER_SECOND); w.ChargeUntilTick = Tick + w.ChargeDelayTicks; w.Charging = true; } else if (w.ChargeUntilTick <= Tick) { w.Charging = false; w.ChargeUntilTick = Tick + w.ChargeDelayTicks; } } else if (!w.ActiveAmmoDef.ConsumableDef.Const.MustCharge && (w.Charging || w.ChargeDelayTicks > 0 || w.ResetPower)) { w.OldUseablePower = w.UseablePower; w.UseablePower = w.RequiredPower; w.DrawPower(true); w.ChargeDelayTicks = 0; w.Charging = false; w.ResetPower = false; } if (w.Charging) { continue; } } w.Shoot(); } ShootingWeapons.Clear(); }
private void AiLoop() { //Fully Inlined due to keen's mod profiler foreach (var ai in GridTargetingAIs.Values) { /// /// GridAi update section /// ai.MyProjectiles = 0; ai.ProInMinCacheRange = 0; ai.AccelChecked = false; if (ai.MarkedForClose || !ai.GridInit || ai.MyGrid == null || ai.Construct.RootAi == null || ai.MyGrid.MarkedForClose) { continue; } ai.Concealed = ((uint)ai.MyGrid.Flags & 4) > 0; if (ai.Concealed) { continue; } if (!ai.ScanInProgress && Tick - ai.TargetsUpdatedTick > 100 && DbTask.IsComplete) { ai.RequestDbUpdate(); } if (ai.DeadProjectiles.Count > 0) { for (int i = 0; i < ai.DeadProjectiles.Count; i++) { ai.LiveProjectile.Remove(ai.DeadProjectiles[i]); } ai.DeadProjectiles.Clear(); ai.LiveProjectileTick = Tick; } var enemyProjectiles = ai.LiveProjectile.Count > 0; ai.CheckProjectiles = Tick - ai.NewProjectileTick <= 1; if (ai.UpdatePowerSources || !ai.HadPower && ai.MyGrid.IsPowered || ai.HasPower && !ai.MyGrid.IsPowered || Tick10) { ai.UpdateGridPower(); } if (!ai.HasPower || Settings.Enforcement.ServerSleepSupport && IsServer && ai.AwakeComps == 0 && ai.WeaponsTracking == 0 && ai.SleepingComps > 0 && !ai.CheckProjectiles && ai.AiSleep && !ai.DbUpdated) { continue; } if (IsServer) { if (ai.Construct.RootAi.Construct.NewInventoryDetected) { ai.Construct.RootAi.Construct.CheckForMissingAmmo(); } else if (Tick60 && ai.Construct.RootAi.Construct.RecentItems.Count > 0) { ai.Construct.RootAi.Construct.CheckEmptyWeapons(); } } /// /// Comp update section /// for (int i = 0; i < ai.Weapons.Count; i++) { var comp = ai.Weapons[i]; if (comp.Status != Started) { comp.HealthCheck(); } if (ai.DbUpdated || !comp.UpdatedState) { comp.DetectStateChanges(); } if (comp.Platform.State != CorePlatform.PlatformState.Ready || comp.IsAsleep || !comp.IsWorking || comp.MyCube.MarkedForClose || comp.IsDisabled) { continue; } if (IsServer && comp.Data.Repo.Base.State.PlayerId > 0 && !ai.Data.Repo.ControllingPlayers.ContainsKey(comp.Data.Repo.Base.State.PlayerId)) { comp.ResetPlayerControl(); } if (HandlesInput) { var wasTrack = comp.Data.Repo.Base.State.TrackingReticle; var isControllingPlayer = comp.Data.Repo.Base.State.PlayerId == PlayerId; var track = (isControllingPlayer && (comp.Data.Repo.Base.Set.Overrides.Control != GroupOverrides.ControlModes.Auto) && TargetUi.DrawReticle && !InMenu && comp.Ai.Construct.RootAi.Data.Repo.ControllingPlayers.ContainsKey(PlayerId)); if (IsServer) { comp.Data.Repo.Base.State.TrackingReticle = track; } if (MpActive && track != wasTrack) { comp.Session.SendTrackReticleUpdate(comp, track); } } var trackReticle = comp.Data.Repo.Base.State.TrackingReticle; comp.WasControlled = comp.UserControlled; comp.UserControlled = comp.Data.Repo.Base.State.Control != ControlMode.None; if (!PlayerMouseStates.TryGetValue(comp.Data.Repo.Base.State.PlayerId, out comp.InputState)) { comp.InputState = DefaultInputStateData; } var compManualMode = comp.Data.Repo.Base.State.Control == ControlMode.Camera || (comp.Data.Repo.Base.Set.Overrides.Control == GroupOverrides.ControlModes.Manual && trackReticle); var canManualShoot = !ai.SuppressMouseShoot && !comp.InputState.InMenu; /// /// Weapon update section /// for (int j = 0; j < comp.Platform.Weapons.Length; j++) { var w = comp.Platform.Weapons[j]; if (w.WeaponReadyTick > Tick) { if (w.Target.HasTarget && !IsClient) { w.Target.Reset(comp.Session.Tick, States.WeaponNotReady); } continue; } if (w.AvCapable && Tick20) { var avWasEnabled = w.PlayTurretAv; double distSqr; Vector3D.DistanceSquared(ref CameraPos, ref w.MyPivotPos, out distSqr); w.PlayTurretAv = distSqr < w.System.HardPointAvMaxDistSqr; if (avWasEnabled != w.PlayTurretAv) { w.StopBarrelAvTick = Tick; } } if (!ai.HadPower && w.ActiveAmmoDef.ConsumableDef.Const.MustCharge && w.State.Action != ShootOff) { if (IsServer) { w.State.WeaponMode(comp, ShootOff); w.Ammo.CurrentAmmo = 0; } w.Reloading = false; w.FinishBurst = false; if (w.IsShooting) { w.StopShooting(); } } /// ///Check Reload /// if (w.ActiveAmmoDef.ConsumableDef.Const.Reloadable && !w.System.DesignatorWeapon && !w.Reloading) { if (IsServer && (w.Ammo.CurrentAmmo == 0 || w.CheckInventorySystem)) { w.ComputeServerStorage(); } else if (IsClient) { if (w.ClientReloading && w.Reload.EndId > w.ClientEndId && w.Reload.StartId == w.ClientStartId) { w.Reloaded(); } else { w.ClientReload(); } } } /// /// Update Weapon Hud Info /// var isWaitingForBurstDelay = w.ShowBurstDelayAsReload && !w.Reloading && w.ShootTick > Tick && w.ShootTick >= w.LastShootTick + w.System.Values.HardPoint.Loading.DelayAfterBurst; if (HandlesInput && (w.Reloading || w.HeatPerc >= 0.01 || isWaitingForBurstDelay) && Tick - w.LastLoadedTick > 30 && !Session.Config.MinimalHud && ActiveControlBlock != null && ai.SubGrids.Contains(ActiveControlBlock.CubeGrid)) { HudUi.TexturesToAdd++; HudUi.WeaponsToDisplay.Add(w); } if (w.System.Armor != ArmorState.IsWeapon) { continue; } if (w.Target.ClientDirty) { w.Target.ClientUpdate(w, w.TargetData); } /// /// Check target for expire states /// bool targetLock = false; var noAmmo = w.NoMagsToLoad && w.Ammo.CurrentAmmo == 0 && w.ActiveAmmoDef.ConsumableDef.Const.Reloadable && !w.System.DesignatorWeapon && Tick - w.LastMagSeenTick > 600; if (w.Target.HasTarget) { if (w.PosChangedTick != Tick) { w.UpdatePivotPos(); } if (!IsClient && noAmmo) { w.Target.Reset(Tick, States.Expired); } else if (!IsClient && w.Target.Entity == null && w.Target.Projectile == null && (!trackReticle || Tick - PlayerDummyTargets[comp.Data.Repo.Base.State.PlayerId].LastUpdateTick > 120)) { w.Target.Reset(Tick, States.Expired, !trackReticle); } else if (!IsClient && w.Target.Entity != null && (comp.UserControlled && !w.System.SuppressFire || w.Target.Entity.MarkedForClose)) { w.Target.Reset(Tick, States.Expired); } else if (!IsClient && w.Target.Projectile != null && (!ai.LiveProjectile.Contains(w.Target.Projectile) || w.Target.IsProjectile && w.Target.Projectile.State != Projectile.ProjectileState.Alive)) { w.Target.Reset(Tick, States.Expired); } else if (w.AiEnabled) { if (!Weapon.TrackingTarget(w, w.Target, out targetLock) && !IsClient && w.Target.ExpiredTick != Tick) { w.Target.Reset(Tick, States.LostTracking, !trackReticle && (w.Target.CurrentState != States.RayCheckFailed && !w.Target.HasTarget)); } } else { Vector3D targetPos; if (w.IsTurret) { if (!w.TrackTarget && !IsClient) { if ((comp.TrackingWeapon.Target.Projectile != w.Target.Projectile || w.Target.IsProjectile && w.Target.Projectile.State != Projectile.ProjectileState.Alive || comp.TrackingWeapon.Target.Entity != w.Target.Entity || comp.TrackingWeapon.Target.IsFakeTarget != w.Target.IsFakeTarget)) { w.Target.Reset(Tick, States.Expired); } else { targetLock = true; } } else if (!Weapon.TargetAligned(w, w.Target, out targetPos) && !IsClient) { w.Target.Reset(Tick, States.Expired); } } else if (w.TrackTarget && !Weapon.TargetAligned(w, w.Target, out targetPos) && !IsClient) { w.Target.Reset(Tick, States.Expired); } } } w.ProjectilesNear = enemyProjectiles && w.System.TrackProjectile && w.Comp.Data.Repo.Base.Set.Overrides.Projectiles && !w.Target.HasTarget && (w.Target.TargetChanged || SCount == w.ShortLoadId); if (comp.Data.Repo.Base.State.Control == ControlMode.Camera && UiInput.MouseButtonPressed) { w.Target.TargetPos = Vector3D.Zero; } /// /// Queue for target acquire or set to tracking weapon. /// var seek = trackReticle && !w.Target.IsFakeTarget || (!noAmmo && !w.Target.HasTarget && w.TrackTarget && (comp.TargetNonThreats && ai.TargetingInfo.OtherInRange || ai.TargetingInfo.ThreatInRange) && (!comp.UserControlled || w.State.Action == ShootClick)); if (!IsClient && (seek || w.TrackTarget && ai.TargetResetTick == Tick && !comp.UserControlled) && !w.AcquiringTarget && (comp.Data.Repo.Base.State.Control == ControlMode.None || comp.Data.Repo.Base.State.Control == ControlMode.Ui)) { w.AcquiringTarget = true; AcquireTargets.Add(w); } if (w.Target.TargetChanged) // Target changed { w.TargetChanged(); } /// /// Check weapon's turret to see if its time to go home /// if (w.TurretMode && !w.IsHome && !w.ReturingHome && !w.Target.HasTarget && Tick - w.Target.ResetTick > 239 && !comp.UserControlled && w.State.Action == ShootOff) { w.ScheduleWeaponHome(); } /// /// Determine if its time to shoot /// /// w.AiShooting = targetLock && !comp.UserControlled && !w.System.SuppressFire; var reloading = w.ActiveAmmoDef.ConsumableDef.Const.Reloadable && w.ClientMakeUpShots == 0 && (w.Reloading || w.Ammo.CurrentAmmo == 0); var canShoot = !w.State.Overheated && !reloading && !w.System.DesignatorWeapon && (!w.LastEventCanDelay || w.AnimationDelayTick <= Tick || w.ClientMakeUpShots > 0); var fakeTarget = comp.Data.Repo.Base.Set.Overrides.Control == GroupOverrides.ControlModes.Painter && trackReticle && w.Target.IsFakeTarget && w.Target.IsAligned; var validShootStates = fakeTarget || w.State.Action == ShootOn || w.AiShooting && w.State.Action == ShootOff; var manualShot = (compManualMode || w.State.Action == ShootClick) && canManualShoot && comp.InputState.MouseButtonLeft; var delayedFire = w.System.DelayCeaseFire && !w.Target.IsAligned && Tick - w.CeaseFireDelayTick <= w.System.CeaseFireDelay; var shoot = (validShootStates || manualShot || w.FinishBurst || delayedFire); w.LockOnFireState = !shoot && w.System.LockOnFocus && ai.Construct.Data.Repo.FocusData.HasFocus && ai.Construct.Focus.FocusInRange(w); var shotReady = canShoot && (shoot || w.LockOnFireState); if ((shotReady || w.ShootOnce) && ai.CanShoot) { if (w.ShootOnce && IsServer && (shotReady || w.State.Action != ShootOnce)) { w.ShootOnce = false; } if (MpActive && HandlesInput && !ManualShot) { ManualShot = !validShootStates && !w.FinishBurst && !delayedFire; } if (w.System.DelayCeaseFire && (validShootStates || manualShot || w.FinishBurst)) { w.CeaseFireDelayTick = Tick; } if ((ai.AvailablePowerChanged || ai.RequestedPowerChanged || (w.RecalcPower && Tick60)) && !w.ActiveAmmoDef.ConsumableDef.Const.MustCharge) { if ((!ai.RequestIncrease || ai.PowerIncrease) && !Tick60) { w.RecalcPower = true; } else { w.RecalcPower = false; w.ChargeDelayTicks = 0; } } if (w.ChargeDelayTicks == 0 || w.ChargeUntilTick <= Tick) { if (!w.RequestedPower && !w.ActiveAmmoDef.ConsumableDef.Const.MustCharge && !w.System.DesignatorWeapon) { if (!comp.UnlimitedPower) { ai.RequestedWeaponsDraw += w.RequiredPower; } w.RequestedPower = true; } ShootingWeapons.Add(w); } else if (w.ChargeUntilTick > Tick && !w.ActiveAmmoDef.ConsumableDef.Const.MustCharge) { w.Charging = true; w.StopShooting(false); } } else if (w.IsShooting) { w.StopShooting(); } else if (w.BarrelSpinning) { w.SpinBarrel(true); } if (comp.Debug && !DedicatedServer) { WeaponDebug(w); } } } ai.OverPowered = ai.RequestedWeaponsDraw > 0 && ai.RequestedWeaponsDraw > ai.GridMaxPower; ai.DbUpdated = false; } if (DbTask.IsComplete && DbsToUpdate.Count > 0 && !DbUpdating) { UpdateDbsInQueue(); } }
private void ShootWeapons() { for (int i = ShootingWeapons.Count - 1; i >= 0; i--) { var w = ShootingWeapons[i]; using (w.Comp.MyCube.Pin()) using (w.Comp.Ai?.MyGrid.Pin()) { if (w.Comp.MyCube.MarkedForClose || w.Comp.Ai == null || w.Comp.Ai.Concealed || w.Comp.Ai.MyGrid.MarkedForClose || w.Comp.Platform.State != MyWeaponPlatform.PlatformState.Ready) { ShootingWeapons.RemoveAtFast(i); continue; } //TODO add logic for power priority if (!w.System.DesignatorWeapon && w.Comp.Ai.OverPowered && (w.ActiveAmmoDef.AmmoDef.Const.EnergyAmmo || w.ActiveAmmoDef.AmmoDef.Const.IsHybrid) && !w.ActiveAmmoDef.AmmoDef.Const.MustCharge) { if (w.Timings.ChargeDelayTicks == 0) { var percUseable = w.RequiredPower / w.Comp.Ai.RequestedWeaponsDraw; w.OldUseablePower = w.UseablePower; w.UseablePower = (w.Comp.Ai.GridMaxPower * .98f) * percUseable; if (w.DrawingPower) { w.DrawPower(true); } else { w.DrawPower(); } w.Timings.ChargeDelayTicks = (uint)(((w.RequiredPower - w.UseablePower) / w.UseablePower) * MyEngineConstants.UPDATE_STEPS_PER_SECOND); w.Timings.ChargeUntilTick = Tick + w.Timings.ChargeDelayTicks; w.State.Sync.Charging = true; } else if (w.Timings.ChargeUntilTick <= Tick) { w.State.Sync.Charging = false; w.Timings.ChargeUntilTick = Tick + w.Timings.ChargeDelayTicks; } } else if (!w.ActiveAmmoDef.AmmoDef.Const.MustCharge && (w.State.Sync.Charging || w.Timings.ChargeDelayTicks > 0 || w.ResetPower)) { w.OldUseablePower = w.UseablePower; w.UseablePower = w.RequiredPower; w.DrawPower(true); w.Timings.ChargeDelayTicks = 0; w.State.Sync.Charging = false; w.ResetPower = false; } if (w.State.Sync.Charging) { continue; } if (w.Timings.ShootDelayTick <= Tick) { w.Shoot(); } } } ShootingWeapons.Clear(); }
private void AiLoop() { //Fully Inlined due to keen's mod profiler foreach (var aiPair in GridTargetingAIs) { /// /// GridAi update section /// var gridAi = aiPair.Value; using (gridAi.MyGrid.Pin()) { if (!gridAi.GridInit || gridAi.MyGrid.MarkedForClose || gridAi.Concealed) { continue; } var readyToUpdate = Tick - gridAi.TargetsUpdatedTick > 100 && DbCallBackComplete && DbTask.IsComplete; if (readyToUpdate && gridAi.UpdateOwner()) { gridAi.RequestDbUpdate(); } if (gridAi.DeadProjectiles.Count > 0) { for (int i = 0; i < gridAi.DeadProjectiles.Count; i++) { gridAi.LiveProjectile.Remove(gridAi.DeadProjectiles[i]); } gridAi.DeadProjectiles.Clear(); gridAi.LiveProjectileTick = Tick; } gridAi.CheckProjectiles = Tick - gridAi.NewProjectileTick <= 1; if (!gridAi.HasPower && gridAi.HadPower || gridAi.UpdatePowerSources || !gridAi.WasPowered && gridAi.MyGrid.IsPowered || Tick10) { gridAi.UpdateGridPower(); } if (!gridAi.HasPower) { continue; } /// /// Comp update section /// for (int i = 0; i < gridAi.Weapons.Count; i++) { var comp = gridAi.Weapons[i]; using (comp.MyCube.Pin()) { if (comp.MyCube.MarkedForClose || comp.Platform.State != MyWeaponPlatform.PlatformState.Ready) { continue; } if (!comp.State.Value.Online || !comp.Set.Value.Overrides.Activate || comp.Status != Started) { if (comp.Status != Started) { comp.HealthCheck(); } continue; } if (InMenu && Tick20 && gridAi.LastTerminal == comp.MyCube) { comp.TerminalRefresh(); } var overRides = comp.Set.Value.Overrides; var compCurPlayer = comp.State.Value.CurrentPlayerControl; if (HandlesInput) { comp.WasTrackReticle = comp.TrackReticle; var isControllingPlayer = comp.State.Value.CurrentPlayerControl.PlayerId == PlayerId; comp.TrackReticle = comp.OtherPlayerTrackingReticle || (isControllingPlayer && (overRides.TargetPainter || overRides.ManualControl) && TargetUi.DrawReticle && !InMenu && comp.Ai.ControllingPlayers.ContainsKey(PlayerId)); if (MpActive && isControllingPlayer && comp.TrackReticle != comp.WasTrackReticle) { comp.Session.SendTrackReticleUpdate(comp); } } comp.WasControlled = comp.UserControlled; comp.UserControlled = compCurPlayer.ControlType != ControlType.None; var leftClick = false; var rightClick = false; MouseStateData mouseState; if (PlayerMouseStates.TryGetValue(compCurPlayer.PlayerId, out mouseState)) { leftClick = mouseState.MouseButtonLeft; // && currentControl; rightClick = mouseState.MouseButtonRight; // && currentControl; } /// /// Weapon update section /// for (int j = 0; j < comp.Platform.Weapons.Length; j++) { var w = comp.Platform.Weapons[j]; if (!w.Set.Enable) { if (w.Target.HasTarget && !IsClient) { w.Target.Reset(comp.Session.Tick, States.Expired); } continue; } if (w.Timings.WeaponReadyTick > Tick) { continue; } if (w.AvCapable && (!w.PlayTurretAv || Tick60)) { var avWasEnabled = w.PlayTurretAv; w.PlayTurretAv = Vector3D.DistanceSquared(CameraPos, w.MyPivotPos) < w.System.HardPointAvMaxDistSqr; if (avWasEnabled != w.PlayTurretAv) { w.StopBarrelAv = !w.PlayTurretAv; } } /// /// Check target for expire states /// if (w.Target.HasTarget && !(IsClient && w.Target.CurrentState == States.Invalid)) { if (w.PosChangedTick != Tick) { w.UpdatePivotPos(); } if (!IsClient && w.Target.Entity == null && w.Target.Projectile == null && (!comp.TrackReticle || gridAi.DummyTarget.ClearTarget)) { w.Target.Reset(Tick, States.Expired, !comp.TrackReticle); } else if (!IsClient && w.Target.Entity != null && (comp.UserControlled || w.Target.Entity.MarkedForClose)) { w.Target.Reset(Tick, States.Expired); } else if (!IsClient && w.Target.Projectile != null && (!gridAi.LiveProjectile.Contains(w.Target.Projectile) || w.Target.IsProjectile && w.Target.Projectile.State != Projectile.ProjectileState.Alive)) { w.Target.Reset(Tick, States.Expired); } else if (w.AiEnabled) { if (!Weapon.TrackingTarget(w, w.Target) && !IsClient) { w.Target.Reset(Tick, States.Expired, !comp.TrackReticle); } } else { Vector3D targetPos; if (w.IsTurret) { if (!w.TrackTarget && !IsClient) { if ((comp.TrackingWeapon.Target.Projectile != w.Target.Projectile || w.Target.IsProjectile && w.Target.Projectile.State != Projectile.ProjectileState.Alive || comp.TrackingWeapon.Target.Entity != w.Target.Entity || comp.TrackingWeapon.Target.IsFakeTarget != w.Target.IsFakeTarget)) { w.Target.Reset(Tick, States.Expired); } } else if (!Weapon.TargetAligned(w, w.Target, out targetPos) && !IsClient) { w.Target.Reset(Tick, States.Expired); } } else if (w.TrackTarget && !Weapon.TargetAligned(w, w.Target, out targetPos) && !IsClient) { w.Target.Reset(Tick, States.Expired); } } } else if (w.Target.HasTarget && MyEntities.EntityExists(comp.WeaponValues.Targets[w.WeaponId].EntityId)) { w.Target.HasTarget = false; comp.Session.ClientGridResyncRequests.Add(comp); } w.ProjectilesNear = w.TrackProjectiles && !w.Target.HasTarget && (w.Target.TargetChanged || SCount == w.ShortLoadId && gridAi.LiveProjectile.Count > 0); if (compCurPlayer.ControlType == ControlType.Camera && UiInput.MouseButtonPressed) { w.Target.TargetPos = Vector3D.Zero; } /// /// Queue for target acquire or set to tracking weapon. /// w.SeekTarget = (!IsClient && !w.Target.HasTarget && w.TrackTarget && gridAi.TargetingInfo.TargetInRange && !comp.UserControlled) || comp.TrackReticle && !w.Target.IsFakeTarget; if (!IsClient && (w.SeekTarget || w.TrackTarget && gridAi.TargetResetTick == Tick && !comp.UserControlled) && !w.AcquiringTarget && (compCurPlayer.ControlType == ControlType.None || compCurPlayer.ControlType == ControlType.Ui)) { w.AcquiringTarget = true; AcquireTargets.Add(w); } else if (w.IsTurret && !w.TrackTarget && !w.Target.HasTarget && gridAi.TargetingInfo.TargetInRange) { w.Target = w.Comp.TrackingWeapon.Target; } if (w.Target.TargetChanged) // Target changed { w.TargetChanged(); } /// /// Check weapon's turret to see if its time to go home /// if (w.TurretMode && (!w.Target.HasTarget && !w.ReturingHome && !w.IsHome && Tick - w.Target.ExpiredTick > 300) || comp.UserControlled != comp.WasControlled && !comp.UserControlled) { w.TurretHomePosition(comp.WasControlled); } /// /// Determine if its time to shoot /// /// w.AiShooting = (w.Target.TargetLock || w.System.DelayCeaseFire && !w.Target.IsAligned && Tick - w.CeaseFireDelayTick <= w.System.CeaseFireDelay) && !comp.UserControlled; var reloading = (!w.ActiveAmmoDef.AmmoDef.Const.EnergyAmmo || w.ActiveAmmoDef.AmmoDef.Const.MustCharge) && (w.State.Sync.Reloading || w.OutOfAmmo); var canShoot = !w.State.Sync.Overheated && !reloading; var fakeTarget = overRides.TargetPainter && comp.TrackReticle && w.Target.IsFakeTarget && w.Target.IsAligned; var validShootStates = fakeTarget || w.State.ManualShoot == ShootOn || w.State.ManualShoot == ShootOnce || w.AiShooting && w.State.ManualShoot == ShootOff; var manualShot = (compCurPlayer.ControlType == ControlType.Camera || (overRides.ManualControl && comp.TrackReticle) || w.State.ManualShoot == ShootClick) && !gridAi.SupressMouseShoot && (j % 2 == 0 && leftClick || j == 1 && rightClick); var shoot = (validShootStates || manualShot || w.FinishBurst); w.LockOnFireState = !shoot && w.System.LockOnFocus && gridAi.Focus.HasFocus; if (canShoot && (shoot || w.LockOnFireState)) { if ((gridAi.AvailablePowerChanged || gridAi.RequestedPowerChanged || (w.RecalcPower && Tick60)) && !w.ActiveAmmoDef.AmmoDef.Const.MustCharge) { if ((!gridAi.RequestIncrease || gridAi.PowerIncrease) && !Tick60) { w.RecalcPower = true; } else { w.RecalcPower = false; w.Timings.ChargeDelayTicks = 0; } } if (w.Timings.ChargeDelayTicks == 0 || w.Timings.ChargeUntilTick <= Tick) { if (!w.RequestedPower && !w.ActiveAmmoDef.AmmoDef.Const.MustCharge && !w.System.DesignatorWeapon) { gridAi.RequestedWeaponsDraw += w.RequiredPower; w.RequestedPower = true; } ShootingWeapons.Add(w); } else if (w.Timings.ChargeUntilTick > Tick && !w.ActiveAmmoDef.AmmoDef.Const.MustCharge) { w.State.Sync.Charging = true; w.StopShooting(false, false); } } else if (w.IsShooting) { if (!w.System.DelayCeaseFire || !w.Target.IsAligned && Tick - w.CeaseFireDelayTick > w.System.CeaseFireDelay) { w.StopShooting(); } else if (w.System.DelayCeaseFire && w.Target.IsAligned) { w.CeaseFireDelayTick = Tick; } } else if (w.BarrelSpinning) { w.SpinBarrel(true); } if (comp.Debug && !DedicatedServer) { WeaponDebug(w); } } } } gridAi.OverPowered = gridAi.RequestedWeaponsDraw > 0 && gridAi.RequestedWeaponsDraw > gridAi.GridMaxPower; } } if (DbCallBackComplete && DbsToUpdate.Count > 0 && DbTask.IsComplete) { UpdateDbsInQueue(); } }