Beispiel #1
0
        private void CheckAcquire()
        {
            for (int i = AcquireTargets.Count - 1; i >= 0; i--)
            {
                var w = AcquireTargets[i];
                using (w.Comp.MyCube.Pin())
                    using (w.Comp.Ai?.MyGrid.Pin())
                    {
                        var comp = w.Comp;
                        if (w.Comp.Ai == null || comp.Ai.MyGrid.MarkedForClose || !comp.Ai.HasPower || comp.Ai.Concealed || comp.MyCube.MarkedForClose || !comp.Ai.DbReady || !w.Set.Enable || !comp.State.Value.Online || !comp.Set.Value.Overrides.Activate)
                        {
                            w.AcquiringTarget = false;
                            AcquireTargets.RemoveAtFast(i);
                            continue;
                        }

                        var gridAi         = w.Comp.Ai;
                        var sinceCheck     = Tick - w.Target.CheckTick;
                        var seekProjectile = w.ProjectilesNear || w.TrackProjectiles && gridAi.CheckProjectiles;

                        var checkTime = w.Target.TargetChanged || sinceCheck > 239 || sinceCheck > 60 && Count == w.LoadId || seekProjectile;

                        if (checkTime || gridAi.TargetResetTick == Tick && w.Target.HasTarget)
                        {
                            if (seekProjectile || comp.TrackReticle || gridAi.TargetingInfo.TargetInRange && gridAi.TargetingInfo.ValidTargetExists(w))
                            {
                                if (comp.TrackingWeapon != null && comp.TrackingWeapon.System.DesignatorWeapon && comp.TrackingWeapon != w && comp.TrackingWeapon.Target.HasTarget)
                                {
                                    var topMost = comp.TrackingWeapon.Target.Entity?.GetTopMostParent();
                                    GridAi.AcquireTarget(w, false, topMost);
                                }
                                else
                                {
                                    GridAi.AcquireTarget(w, gridAi.TargetResetTick == Tick);
                                }
                            }


                            if (w.Target.HasTarget || !gridAi.TargetingInfo.TargetInRange)
                            {
                                w.AcquiringTarget = false;
                                AcquireTargets.RemoveAtFast(i);
                                if (w.Target.HasTarget && MpActive)
                                {
                                    w.Target.SyncTarget(comp.WeaponValues.Targets[w.WeaponId], w.WeaponId);

                                    if (WeaponsSyncCheck.Add(w))
                                    {
                                        WeaponsToSync.Add(w);
                                        comp.Ai.NumSyncWeapons++;
                                        w.SendTarget = true;

                                        if (Tick - w.LastSyncTick > 20)
                                        {
                                            w.SendSync = true;
                                        }

                                        w.LastSyncTick = Tick;
                                    }
                                }
                            }
                        }
                    }
            }
        }
        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())
                {
                    gridAi.Concealed = ((uint)gridAi.MyGrid.Flags & 4) > 0;
                    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.State.Value.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;

                            InputStateData inputState;
                            if (PlayerMouseStates.TryGetValue(compCurPlayer.PlayerId, out inputState))
                            {
                                leftClick  = inputState.MouseButtonLeft;  // && currentControl;
                                rightClick = inputState.MouseButtonRight; // && currentControl;
                            }
                            else
                            {
                                inputState = PlayerMouseStates[-1];
                            }

                            ///
                            /// 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;
                                    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 || w.State.ManualShoot == ShootClick)) || 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 (!IsClient && w.IsTurret && !w.TrackTarget && !w.Target.HasTarget && gridAi.TargetingInfo.TargetInRange)
                                {
                                    if (w.Target != w.Comp.TrackingWeapon.Target)
                                    {
                                        w.Target = w.Comp.TrackingWeapon.Target;

                                        w.Target.SyncTarget(comp.WeaponValues.Targets[w.WeaponId], w.WeaponId);

                                        if (WeaponsSyncCheck.Add(w))
                                        {
                                            WeaponsToSync.Add(w);
                                            comp.Ai.NumSyncWeapons++;
                                            w.SendTarget = true;

                                            if (Tick - w.LastSyncTick > 20)
                                            {
                                                w.SendSync = true;
                                            }

                                            w.LastSyncTick = Tick;
                                        }
                                    }
                                }

                                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);
                                }

                                ///
                                /// Update Weapon Hud Info
                                ///

                                //if (HandlesInput && (w.State.Sync.Heat > 0 || w.State.Sync.Reloading) && HudUi.WeaponsToDisplayCheck.Add(w))
                                if (HandlesInput && !Session.Config.MinimalHud && ((w.State.Sync.Reloading && Tick - w.LastLoadedTick > 30) || (w.State.Sync.Heat > 0)) && ActiveControlBlock != null && gridAi.SubGrids.Contains(ActiveControlBlock.CubeGrid))
                                {
                                    HudUi.TexturesToAdd++;
                                    HudUi.WeaponsToDisplay.Add(w);
                                }

                                ///
                                /// Determine if its time to shoot
                                ///
                                ///
                                w.AiShooting = w.Target.TargetLock && !comp.UserControlled;
                                var reloading        = w.ActiveAmmoDef.AmmoDef.Const.Reloadable && (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 && !inputState.InMenu && (j % 2 == 0 && leftClick || j == 1 && rightClick);
                                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 && gridAi.Focus.HasFocus;
                                if (canShoot && (shoot || w.LockOnFireState))
                                {
                                    if (w.System.DelayCeaseFire && (validShootStates || manualShot || w.FinishBurst))
                                    {
                                        w.CeaseFireDelayTick = Tick;
                                    }

                                    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)
                                        {
                                            if (!comp.UnlimitedPower)
                                            {
                                                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)
                                {
                                    w.StopShooting();
                                }
                                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();
            }
        }