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