Exemplo n.º 1
0
        public override void OnStart(StartState state)
        {
            if (HighLogic.LoadedSceneIsFlight)
            {
                part.explosionPotential        = 1.0f;
                part.OnJustAboutToBeDestroyed += DetonateIfPossible;
                part.force_activate();
                sourcevessel = vessel;
                var MF = VesselModuleRegistry.GetModule <MissileFire>(vessel, true);
                if (MF != null)
                {
                    sourcevessel = MF.vessel;             // grab the vessel the Weapon manager is on at start
                }
            }
            if (part.FindModuleImplementing <MissileLauncher>() == null)
            {
                isMissile = false;
            }
            GuiSetup();
            if (BDArmorySettings.ADVANCED_EDIT)
            {
                //Fields["tntMass"].guiActiveEditor = true;

                //((UI_FloatRange)Fields["tntMass"].uiControlEditor).minValue = 0f;
                //((UI_FloatRange)Fields["tntMass"].uiControlEditor).maxValue = 3000f;
                //((UI_FloatRange)Fields["tntMass"].uiControlEditor).stepIncrement = 5f;
            }

            CalculateBlast();
        }
Exemplo n.º 2
0
 protected void UpdateWeaponManager()
 {
     weaponManager = VesselModuleRegistry.GetModule <MissileFire>(vessel);
     if (weaponManager != null)
     {
         weaponManager.AI = this;
     }
 }
Exemplo n.º 3
0
 private void ConfigureKerbalEVA(KerbalEVA kerbalEVA)
 {
     chute = VesselModuleRegistry.GetModule <ModuleEvaChute>(kerbalEVA.vessel);
     if (chute != null)
     {
         chute.deploymentState = ModuleEvaChute.deploymentStates.STOWED;                                   // Make sure the chute is stowed.
     }
     if ((Versioning.version_major == 1 && Versioning.version_minor > 10) || Versioning.version_major > 1) // Introduced in 1.11
     {
         DisableConstructionMode(kerbalEVA);
         if (BDArmorySettings.KERBAL_SAFETY_INVENTORY == 2)
         {
             RemoveJetpack(kerbalEVA);
         }
     }
 }
Exemplo n.º 4
0
 /// <summary>
 /// If guard mode off, and UI target is of the opposing team, set it as target
 /// </summary>
 protected void GetNonGuardTarget()
 {
     if (weaponManager != null && !weaponManager.guardMode)
     {
         if (vessel.targetObject != null)
         {
             var nonGuardTargetVessel = vessel.targetObject.GetVessel();
             if (nonGuardTargetVessel != null)
             {
                 var targetWeaponManager = VesselModuleRegistry.GetModule <MissileFire>(nonGuardTargetVessel);
                 if (targetWeaponManager != null && weaponManager.Team.IsEnemy(targetWeaponManager.Team))
                 {
                     targetVessel = (Vessel)vessel.targetObject;
                 }
             }
         }
     }
 }
Exemplo n.º 5
0
 public override void OnFixedUpdate()
 {
     base.OnFixedUpdate();
     if (HighLogic.LoadedSceneIsFlight)
     {
         if (!isMissile)
         {
             if (IFF_On)
             {
                 updateTimer -= Time.fixedDeltaTime;
                 if (updateTimer < 0)
                 {
                     GetTeamID();        //have this only called once a sec
                     updateTimer = 1.0f; //next update in half a sec only
                 }
             }
             if (manualOverride) // don't call proximity code if a missile/MMG, use theirs
             {
                 if (Armed)
                 {
                     if (VesselModuleRegistry.GetModule <MissileFire>(vessel) == null)
                     {
                         if (sourcevessel != null && sourcevessel != part.vessel)
                         {
                             distanceFromStart = Vector3.Distance(part.vessel.transform.position, sourcevessel.transform.position);
                         }
                     }
                     if (Checkproximity(distanceFromStart))
                     {
                         Detonate();
                     }
                 }
             }
         }
     }
 }
Exemplo n.º 6
0
        void PilotLogic()
        {
            // check for collisions, but not every frame
            if (collisionDetectionTicker == 0)
            {
                collisionDetectionTicker = 20;
                float predictMult = Mathf.Clamp(10 / MaxDrift, 1, 10);

                dodgeVector = null;

                using (var vs = BDATargetManager.LoadedVessels.GetEnumerator())
                    while (vs.MoveNext())
                    {
                        if (vs.Current == null || vs.Current == vessel || vs.Current.GetTotalMass() < AvoidMass)
                        {
                            continue;
                        }
                        if (!VesselModuleRegistry.ignoredVesselTypes.Contains(vs.Current.vesselType))
                        {
                            var ibdaiControl = VesselModuleRegistry.GetModule <IBDAIControl>(vs.Current);
                            if (!vs.Current.LandedOrSplashed || (ibdaiControl != null && ibdaiControl.commandLeader != null && ibdaiControl.commandLeader.vessel == vessel))
                            {
                                continue;
                            }
                        }
                        dodgeVector = PredictCollisionWithVessel(vs.Current, 5f * predictMult, 0.5f);
                        if (dodgeVector != null)
                        {
                            break;
                        }
                    }
            }
            else
            {
                collisionDetectionTicker--;
            }

            // avoid collisions if any are found
            if (dodgeVector != null)
            {
                targetVelocity  = PoweredSteering ? MaxSpeed : CruiseSpeed;
                targetDirection = (Vector3)dodgeVector;
                SetStatus($"Avoiding Collision");
                leftPath = true;
                return;
            }

            // if bypass target is no longer relevant, remove it
            if (bypassTarget != null && ((bypassTarget != targetVessel && bypassTarget != (commandLeader != null ? commandLeader.vessel : null)) ||
                                         (VectorUtils.GetWorldSurfacePostion(bypassTargetPos, vessel.mainBody) - bypassTarget.CoM).sqrMagnitude > 500000))
            {
                bypassTarget = null;
            }

            if (bypassTarget == null)
            {
                // check for enemy targets and engage
                // not checking for guard mode, because if guard mode is off now you can select a target manually and if it is of opposing team, the AI will try to engage while you can man the turrets
                if (weaponManager && targetVessel != null && !BDArmorySettings.PEACE_MODE)
                {
                    leftPath = true;
                    if (collisionDetectionTicker == 5)
                    {
                        checkBypass(targetVessel);
                    }

                    Vector3 vecToTarget = targetVessel.CoM - vessel.CoM;
                    float   distance    = vecToTarget.magnitude;
                    // lead the target a bit, where 1km/s is a ballpark estimate of the average bullet velocity
                    float shotSpeed = 1000f;
                    if ((weaponManager != null ? weaponManager.selectedWeapon : null) is ModuleWeapon wep)
                    {
                        shotSpeed = wep.bulletVelocity;
                    }
                    vecToTarget = targetVessel.PredictPosition(distance / shotSpeed) - vessel.CoM;

                    if (BroadsideAttack)
                    {
                        Vector3 sideVector = Vector3.Cross(vecToTarget, upDir); //find a vector perpendicular to direction to target
                        if (collisionDetectionTicker == 10 &&
                            !pathingMatrix.TraversableStraightLine(
                                VectorUtils.WorldPositionToGeoCoords(vessel.CoM, vessel.mainBody),
                                VectorUtils.WorldPositionToGeoCoords(vessel.PredictPosition(10), vessel.mainBody),
                                vessel.mainBody, SurfaceType, MaxSlopeAngle, AvoidMass))
                        {
                            sideSlipDirection = -Math.Sign(Vector3.Dot(vesselTransform.up, sideVector)); // switch sides if we're running ashore
                        }
                        sideVector *= sideSlipDirection;

                        float sidestep = distance >= MaxEngagementRange?Mathf.Clamp01((MaxEngagementRange - distance) / (CruiseSpeed *Mathf.Clamp(90 / MaxDrift, 0, 10)) + 1) * AttackAngleAtMaxRange / 90 : // direct to target to attackAngle degrees if over maxrange
                                         (distance <= MinEngagementRange ? 1.5f - distance / (MinEngagementRange * 2) :                                                                                      // 90 to 135 degrees if closer than minrange
                                          (MaxEngagementRange - distance) / (MaxEngagementRange - MinEngagementRange) * (1 - AttackAngleAtMaxRange / 90) + AttackAngleAtMaxRange / 90);                      // attackAngle to 90 degrees from maxrange to minrange

                        targetDirection = Vector3.LerpUnclamped(vecToTarget.normalized, sideVector.normalized, sidestep);                                                                                    // interpolate between the side vector and target direction vector based on sidestep
                        targetVelocity  = MaxSpeed;
                        DebugLine($"Broadside attack angle {sidestep}");
                    }
                    else // just point at target and go
                    {
                        if ((targetVessel.horizontalSrfSpeed < 10 || Vector3.Dot(Vector3.ProjectOnPlane(targetVessel.srf_vel_direction, upDir), vessel.up) < 0) && //if target is stationary or we're facing in opposite directions
                            (distance < MinEngagementRange || (distance < (MinEngagementRange * 3 + MaxEngagementRange) / 4 && //and too close together
                                                               extendingTarget != null && targetVessel != null && extendingTarget == targetVessel)))
                        {
                            extendingTarget = targetVessel;
                            // not sure if this part is very smart, potential for improvement
                            targetDirection = -vecToTarget; //extend
                            targetVelocity  = MaxSpeed;
                            SetStatus($"Extending");
                            return;
                        }
                        else
                        {
                            extendingTarget = null;
                            targetDirection = Vector3.ProjectOnPlane(vecToTarget, upDir);
                            if (Vector3.Dot(targetDirection, vesselTransform.up) < 0)
                            {
                                targetVelocity = PoweredSteering ? MaxSpeed : 0; // if facing away from target
                            }
                            else if (distance >= MaxEngagementRange || distance <= MinEngagementRange)
                            {
                                targetVelocity = MaxSpeed;
                            }
                            else
                            {
                                targetVelocity = CruiseSpeed / 10 + (MaxSpeed - CruiseSpeed / 10) * (distance - MinEngagementRange) / (MaxEngagementRange - MinEngagementRange); //slow down if inside engagement range to extend shooting opportunities
                                if (weaponManager != null && weaponManager.selectedWeapon != null)
                                {
                                    switch (weaponManager.selectedWeapon.GetWeaponClass())
                                    {
                                    case WeaponClasses.Gun:
                                    case WeaponClasses.Rocket:
                                    case WeaponClasses.DefenseLaser:
                                        var gun = (ModuleWeapon)weaponManager.selectedWeapon;
                                        if ((gun.yawRange == 0 || gun.maxPitch == gun.minPitch) && gun.FiringSolutionVector != null)
                                        {
                                            aimingMode = true;
                                            if (Vector3.Angle((Vector3)gun.FiringSolutionVector, vessel.transform.up) < 20)
                                            {
                                                targetDirection = (Vector3)gun.FiringSolutionVector;
                                            }
                                        }
                                        break;
                                    }
                                }
                            }
                            targetVelocity = Mathf.Clamp(targetVelocity, PoweredSteering ? CruiseSpeed / 5 : 0, MaxSpeed); // maintain a bit of speed if using powered steering
                        }
                    }
                    SetStatus($"Engaging target");
                    return;
                }

                // follow
                if (command == PilotCommands.Follow)
                {
                    leftPath = true;
                    if (collisionDetectionTicker == 5)
                    {
                        checkBypass(commandLeader.vessel);
                    }

                    Vector3 targetPosition = GetFormationPosition();
                    Vector3 targetDistance = targetPosition - vesselTransform.position;
                    if (Vector3.Dot(targetDistance, vesselTransform.up) < 0 &&
                        Vector3.ProjectOnPlane(targetDistance, upDir).sqrMagnitude < 250f * 250f &&
                        Vector3.Angle(vesselTransform.up, commandLeader.vessel.srf_velocity) < 0.8f)
                    {
                        targetDirection = Vector3.RotateTowards(Vector3.ProjectOnPlane(commandLeader.vessel.srf_vel_direction, upDir), targetDistance, 0.2f, 0);
                    }
                    else
                    {
                        targetDirection = Vector3.ProjectOnPlane(targetDistance, upDir);
                    }
                    targetVelocity = (float)(commandLeader.vessel.horizontalSrfSpeed + (vesselTransform.position - targetPosition).magnitude / 15);
                    if (Vector3.Dot(targetDirection, vesselTransform.up) < 0 && !PoweredSteering)
                    {
                        targetVelocity = 0;
                    }
                    SetStatus($"Following");
                    return;
                }
            }

            // goto
            if (leftPath && bypassTarget == null)
            {
                Pathfind(finalPositionGeo);
                leftPath = false;
            }

            const float targetRadius = 250f;

            targetDirection = Vector3.ProjectOnPlane(assignedPositionWorld - vesselTransform.position, upDir);

            if (targetDirection.sqrMagnitude > targetRadius * targetRadius)
            {
                if (bypassTarget != null)
                {
                    targetVelocity = MaxSpeed;
                }
                else if (waypoints.Count > 1)
                {
                    targetVelocity = command == PilotCommands.Attack ? MaxSpeed : CruiseSpeed;
                }
                else
                {
                    targetVelocity = Mathf.Clamp((targetDirection.magnitude - targetRadius / 2) / 5f,
                                                 0, command == PilotCommands.Attack ? MaxSpeed : CruiseSpeed);
                }

                if (Vector3.Dot(targetDirection, vesselTransform.up) < 0 && !PoweredSteering)
                {
                    targetVelocity = 0;
                }
                SetStatus(bypassTarget ? "Repositioning" : "Moving");
                return;
            }

            cycleWaypoint();

            SetStatus($"Not doing anything in particular");
            targetDirection = vesselTransform.up;
        }
Exemplo n.º 7
0
        private bool Checkproximity(float distanceFromStart)
        {
            bool detonate = false;

            if (distanceFromStart < blastRadius)
            {
                return(detonate = false);
            }

            using (var hitsEnu = Physics.OverlapSphere(transform.position, detonationRange, 557057).AsEnumerable().GetEnumerator())
            {
                while (hitsEnu.MoveNext())
                {
                    if (hitsEnu.Current == null)
                    {
                        continue;
                    }

                    Part partHit = hitsEnu.Current.GetComponentInParent <Part>();
                    if (partHit == null || partHit.vessel == null)
                    {
                        continue;
                    }
                    if (ProjectileUtils.IsIgnoredPart(partHit))
                    {
                        continue;                                         // Ignore ignored parts.
                    }
                    if (partHit.vessel == vessel || partHit.vessel == sourcevessel)
                    {
                        continue;
                    }
                    if (partHit.vessel.vesselType == VesselType.Debris)
                    {
                        continue;
                    }
                    if (sourcevessel != null && partHit.vessel.vesselName.Contains(sourcevessel.vesselName))
                    {
                        continue;
                    }
                    var weaponManager = VesselModuleRegistry.GetModule <MissileFire>(partHit.vessel);
                    if (IFF_On && (weaponManager == null || weaponManager.teamString == IFFID))
                    {
                        continue;
                    }
                    if (detonateAtMinimumDistance)
                    {
                        var distance          = Vector3.Distance(partHit.transform.position + partHit.CoMOffset, transform.position);
                        var predictedDistance = Vector3.Distance(AIUtils.PredictPosition(partHit.transform.position + partHit.CoMOffset, partHit.vessel.Velocity(), partHit.vessel.acceleration, Time.fixedDeltaTime), AIUtils.PredictPosition(transform.position, vessel.Velocity(), vessel.acceleration, Time.fixedDeltaTime));
                        if (distance > predictedDistance && distance > Time.fixedDeltaTime * (float)vessel.srfSpeed) // If we're closing and not going to hit within the next update, then wait.
                        {
                            return(detonate = false);
                        }
                    }
                    if (BDArmorySettings.DRAW_DEBUG_LABELS)
                    {
                        Debug.Log("[BDArmory.BDExplosivePart]: Proxifuze triggered by " + partHit.partName + " from " + partHit.vessel.vesselName);
                    }
                    return(detonate = true);
                }
            }
            return(detonate);
        }
Exemplo n.º 8
0
        private void GetTeamID()
        {
            var weaponManager = VesselModuleRegistry.GetModule <MissileFire>(sourcevessel);

            IFFID = weaponManager != null ? weaponManager.teamString : null;
        }
Exemplo n.º 9
0
        public IEnumerator PerformanceTest()
        {
            var wait = new WaitForSeconds(0.1f);

            {
                // Note: this test has significant GC allocations due to the allocation of an intermediate list.
                int count     = 0;
                int iters     = 100000;
                var startTime = Time.realtimeSinceStartup;
                for (int i = 0; i < iters; ++i)
                {
                    foreach (var mf in FlightGlobals.ActiveVessel.FindPartModulesImplementing <MissileFire>())
                    {
                        ++count;
                    }
                }
                Debug.Log($"DEBUG {FlightGlobals.ActiveVessel} has {count / iters} weapon managers, checked at {iters / (Time.realtimeSinceStartup - startTime)}/s via vessel.FindPartModulesImplementing<MissileFire>()");
            }
            yield return(wait);

            {
                int count     = 0;
                int iters     = 100000;
                var startTime = Time.realtimeSinceStartup;
                for (int i = 0; i < iters; ++i)
                {
                    if (FlightGlobals.ActiveVessel.FindPartModuleImplementing <MissileFire>() != null)
                    {
                        ++count;
                    }
                }
                Debug.Log($"DEBUG {FlightGlobals.ActiveVessel} has {count / iters} weapon managers, checked at {iters / (Time.realtimeSinceStartup - startTime)}/s via vessel.FindPartModuleImplementing<MissileFire>()");
            }
            yield return(wait);

            {
                int count     = 0;
                int iters     = 10000000;
                var startTime = Time.realtimeSinceStartup;
                for (int i = 0; i < iters; ++i)
                {
                    foreach (var mf in VesselModuleRegistry.GetModules <MissileFire>(FlightGlobals.ActiveVessel))
                    {
                        ++count;
                    }
                }
                Debug.Log($"DEBUG {FlightGlobals.ActiveVessel} has {count / iters} weapon managers, checked at {iters / (Time.realtimeSinceStartup - startTime)}/s via VesselModuleRegistry.GetModules<MissileFire>(vessel)");
            }
            yield return(wait);

            {
                int count     = 0;
                int iters     = 10000000;
                var startTime = Time.realtimeSinceStartup;
                for (int i = 0; i < iters; ++i)
                {
                    foreach (var mf in VesselModuleRegistry.GetMissileFires(FlightGlobals.ActiveVessel))
                    {
                        ++count;
                    }
                }
                Debug.Log($"DEBUG {FlightGlobals.ActiveVessel} has {count / iters} weapon managers, checked at {iters / (Time.realtimeSinceStartup - startTime)}/s via VesselModuleRegistry.GetMissileFires(vessel)");
            }
            yield return(wait);

            {
                int count     = 0;
                int iters     = 10000000;
                var startTime = Time.realtimeSinceStartup;
                for (int i = 0; i < iters; ++i)
                {
                    if (VesselModuleRegistry.GetModule <MissileFire>(FlightGlobals.ActiveVessel) != null)
                    {
                        ++count;
                    }
                }
                Debug.Log($"DEBUG {FlightGlobals.ActiveVessel} has {count / iters} weapon managers, checked at {iters / (Time.realtimeSinceStartup - startTime)}/s via VesselModuleRegistry.GetModule<MissileFire>(vessel)");
            }
            yield return(wait);

            {
                int count     = 0;
                int iters     = 10000000;
                var startTime = Time.realtimeSinceStartup;
                for (int i = 0; i < iters; ++i)
                {
                    if (VesselModuleRegistry.GetModule <MissileFire>(FlightGlobals.ActiveVessel, true) != null)
                    {
                        ++count;
                    }
                }
                Debug.Log($"DEBUG {FlightGlobals.ActiveVessel} has {count / iters} weapon managers, checked at {iters / (Time.realtimeSinceStartup - startTime)}/s via VesselModuleRegistry.GetModule<MissileFire>(vessel, true)");
            }
            yield return(wait);

            {
                int count     = 0;
                int iters     = 10000000;
                var startTime = Time.realtimeSinceStartup;
                for (int i = 0; i < iters; ++i)
                {
                    if (VesselModuleRegistry.GetMissileFire(FlightGlobals.ActiveVessel) != null)
                    {
                        ++count;
                    }
                }
                Debug.Log($"DEBUG {FlightGlobals.ActiveVessel} has {count / iters} weapon managers, checked at {iters / (Time.realtimeSinceStartup - startTime)}/s via VesselModuleRegistry.GetMissileFire(vessel)");
            }
            yield return(wait);

            {
                int count     = 0;
                int iters     = 10000000;
                var startTime = Time.realtimeSinceStartup;
                for (int i = 0; i < iters; ++i)
                {
                    if (VesselModuleRegistry.GetMissileFire(FlightGlobals.ActiveVessel, true) != null)
                    {
                        ++count;
                    }
                }
                Debug.Log($"DEBUG {FlightGlobals.ActiveVessel} has {count / iters} weapon managers, checked at {iters / (Time.realtimeSinceStartup - startTime)}/s via VesselModuleRegistry.GetMissileFire(vessel, true)");
            }
            BDACompetitionMode.Instance.competitionStatus.Add("VesselModuleRegistry performance test complete.");
        }