示例#1
0
            public static void Postfix(FiringPreviewManager __instance, ref FiringPreviewManager.PreviewInfo __result, ICombatant target)
            {
                try
                {
                    if (__result.availability != FiringPreviewManager.TargetAvailability.PossibleDirect)
                    {
                        return;
                    }

                    AbstractActor  selectedActor = HUD?.SelectedActor;
                    SelectionState activeState   = HUD?.SelectionHandler?.ActiveState;
                    float          dist          = Vector3.Distance(activeState.PreviewPos, target.CurrentPosition);

                    if (selectedActor.Weapons.Any(w => !w.IndirectFireCapable && w.IsEnabled && w.CanFire && w.MaxRange > dist))
                    {
                        Logger.Info($"[FiringPreviewManager_GetPreviewInfo_POSTFIX] Smart indirect lof preview blocked by some direct fire only weapon");
                        return;
                    }

                    if (!CanSmartIndirect(selectedActor, activeState.PreviewPos, activeState.PreviewRot, target))
                    {
                        return;
                    }



                    __result.availability = FiringPreviewManager.TargetAvailability.PossibleIndirect;
                }
                catch (Exception e)
                {
                    Logger.Error(e);
                }
            }
        public static void Postfix(FiringPreviewManager __instance, ref bool __result, CombatGameState ___combat,
                                   AbstractActor attacker, ICombatant target, Vector3 position, List <AbstractActor> allies)
        {
            //LowVisibility.Logger.Debug("FiringPreviewManager:HasLOS:post - entered.");
            for (int i = 0; i < allies.Count; i++)
            {
                //if (allies[i].VisibilityCache.VisibilityToTarget(target).VisibilityLevel == VisibilityLevel.LOSFull) {
                if (allies[i].VisibilityCache.VisibilityToTarget(target).VisibilityLevel >= VisibilityLevel.Blip0Minimum)
                {
                    __result = true;
                    Mod.Log.Trace?.Write($"Allied actor{CombatantUtils.Label(allies[i])} has LOS " +
                                         $"to target:{CombatantUtils.Label(target as AbstractActor)}, returning true.");
                    return;
                }
            }

            VisibilityLevel visibilityToTargetWithPositionsAndRotations =
                ___combat.LOS.GetVisibilityToTargetWithPositionsAndRotations(attacker, position, target);

            //__result = visibilityToTargetWithPositionsAndRotations == VisibilityLevel.LOSFull;
            __result = visibilityToTargetWithPositionsAndRotations >= VisibilityLevel.Blip0Minimum;
            Mod.Log.Trace?.Write($"Actor{CombatantUtils.Label(attacker)} has LOS? {__result} " +
                                 $"to target:{CombatantUtils.Label(target as AbstractActor)}");
        }
        // ============ Smart Indirect Fire ============

        public static void SmartIndirectFireLoF(FiringPreviewManager __instance, ref FiringPreviewManager.PreviewInfo __result, ICombatant target)
        {
            try {
                if (__result.availability != PossibleDirect)
                {
                    return;
                }
                AbstractActor actor = HUD?.SelectedActor;
                float         dist  = Vector3.Distance(ActiveState.PreviewPos, target.CurrentPosition);
                foreach (Weapon w in actor.Weapons) // Don't change LoF if any direct weapon is enabled and can shot
                {
                    if (!w.IndirectFireCapable && w.IsEnabled && w.MaxRange > dist && w.CanFire)
                    {
                        return;
                    }
                }
                //Verbo( "Smart indirect blocked by {0}: {1}, {2}, {3}, {4}, {5}", w, dist, w.MaxRange, w.IsDisabled, w.IsEnabled, w.IndirectFireCapable );
                if (!CanSmartIndirect(actor, ActiveState.PreviewPos, ActiveState.PreviewRot, target))
                {
                    return;
                }
                __result.availability = PossibleIndirect;
            }                 catch (Exception ex) { Error(ex); }
        }