static void Prefix(CombatHUDAttackModeSelector __instance, CombatHUDFireButton.FireMode mode, ref string additionalDetails, bool showHeatWarnings) { Mod.UILog.Trace?.Write($"ShowFireButton called with mode: {mode}"); // Intentionally regen the meleeStates everytime the button changes, to make sure different positions calculate properly if (mode == CombatHUDFireButton.FireMode.Engage || mode == CombatHUDFireButton.FireMode.DFA) { if (SharedState.CombatHUD?.SelectionHandler?.ActiveState?.PreviewPos != ModState.MeleePreviewPos) { ModState.MeleePreviewPos = SharedState.CombatHUD.SelectionHandler.ActiveState.PreviewPos; // Update melee states ModState.AddorUpdateMeleeState( SharedState.CombatHUD.SelectionHandler.ActiveState.SelectedActor, SharedState.CombatHUD.SelectionHandler.ActiveState.PreviewPos, SharedState.CombatHUD.SelectionHandler.ActiveState.TargetedCombatant); Mod.UILog.Debug?.Write($"Updated melee state for position: {ModState.MeleePreviewPos}"); // Re-enable any buttons if they were disabled. __instance.FireButton.SetState(ButtonState.Enabled); __instance.DescriptionContainer.SetActive(true); } } else { ModState.InvalidateState(SharedState.CombatHUD?.SelectionHandler?.ActiveState?.SelectedActor); } }
public static void Postfix(CombatHUDAttackModeSelector __instance, CombatHUDFireButton.FireMode mode, string additionalDetails, bool showHeatWarnings) { Log.TWL(0, "CombatHUDAttackModeSelector.ShowFireButton mode:" + mode); Log.WL(0, Environment.StackTrace); if (string.IsNullOrEmpty(RenameFireButton) == false) { RenameFireButton = string.Empty; __instance.FireButton.FireText.SetText(RenameFireButton); } }
public static void Prefix(CombatHUDAttackModeSelector __instance) { try { __instance.DescriptionText.SetAllDirty(); } catch (Exception e) { Logger.Error(e); } }
public static void Postfix(CombatHUDAttackModeSelector __instance) { Mod.UILog.Trace?.Write("CHUDAMS:U - entered."); Traverse HUDT = Traverse.Create(__instance).Property("HUD"); CombatHUD HUD = HUDT.GetValue <CombatHUD>(); if (HUD != null && HUD.SelectedActor != null && HUD.SelectedActor is Mech) { Traverse showHeatWarningsT = Traverse.Create(__instance).Field("showHeatWarnings"); bool showHeatWarnings = showHeatWarningsT.GetValue <bool>(); if (showHeatWarnings) { CalculatedHeat calculatedHeat = HeatHelper.CalculateHeat(HUD.SelectedActor as Mech, HUD.SelectionHandler.ProjectedHeatForState); //Mod.UILog.Debug?.Write($" In CombatHUDAttackModeSelector, projectedHeat: {calculatedHeat.ThresholdHeat} vs {Mod.Config.Heat.WarnAtHeat}"); bool isOverheated = calculatedHeat.ThresholdHeat >= Mod.Config.Heat.WarnAtHeat; bool isShutdown = calculatedHeat.ThresholdHeat >= Mod.Config.Heat.MaxHeat; Traverse updateOverheatWarningsT = Traverse.Create(__instance).Method("UpdateOverheatWarnings", new object[] { isOverheated, isShutdown }); updateOverheatWarningsT.GetValue(); } } }
public static void Postfix(CombatHUDAttackModeSelector __instance, ArmorLocation ___displayedLocation) { try { //Logger.Debug("[CombatHUDAttackModeSelector_DisplayedLocation_POSTFIX] Called."); CombatHUD ___HUD = (CombatHUD)AccessTools.Property(typeof(CombatHUDAttackModeSelector), "HUD").GetValue(__instance, null); // Prepping Called Shot if (___displayedLocation == ArmorLocation.None) { // Safeguarding even more... if ( ___HUD.SelectionHandler.ActiveState.SelectionType != SelectionType.FireMorale || ___HUD.SelectedTarget.UnitType != UnitType.Mech ) { return; } if (___HUD.SelectedTarget.IsShutDown || ___HUD.SelectedTarget.IsProne) { Color c = LazySingletonBehavior <UIManager> .Instance.UIColorRefs.whiteHalf; __instance.DescriptionText.SetText("{0}{1}IMMOBILIZED{2}", new object[] { "^^^ SELECT A LOCATION FOR CALLED SHOT ^^^ \n", "<color=#" + ColorUtility.ToHtmlStringRGBA(c) + "><size=80%>", "</size></color>" }); return; } if (___HUD.CalledShotPopUp.ShownAttackDirection == AttackDirection.FromBack) { Color c = LazySingletonBehavior <UIManager> .Instance.UIColorRefs.whiteHalf; __instance.DescriptionText.SetText("{0}{1}REAR ARC{2}", new object[] { "^^^ SELECT A LOCATION FOR CALLED SHOT ^^^ \n", "<color=#" + ColorUtility.ToHtmlStringRGBA(c) + "><size=80%>", "</size></color>" }); return; } // Regular Precision Strike from front or sides Pilot selectedPilot = ___HUD.SelectedActor.GetPilot(); int enabledWeaponCount = Utilities.GetReadiedWeaponCount(___HUD.SelectedActor.Weapons, ___HUD.SelectedTarget); int maxAllowedWeapons = Utilities.GetMaxAllowedWeaponCountForHeadshots(selectedPilot); int weaponsToDisable = Math.Max(0, enabledWeaponCount - maxAllowedWeapons); //string pluralizeSuffix = maxAllowedWeapons > 1 ? "S" : ""; string pluralizeSuffix = weaponsToDisable > 1 ? "S" : ""; //Logger.Debug("[CombatHUDAttackModeSelector_DisplayedLocation_POSTFIX] Appending headshot note..."); if (weaponsToDisable >= 1) { Color c = LazySingletonBehavior <UIManager> .Instance.UIColorRefs.whiteHalf; __instance.DescriptionText.SetText("{0}{1}DISABLE {2} MORE WEAPON{3} FOR A HEADSHOT{4}", new object[] { "^^^ SELECT A LOCATION FOR CALLED SHOT ^^^ \n", "<color=#" + ColorUtility.ToHtmlStringRGBA(c) + "><size=80%>", weaponsToDisable, pluralizeSuffix, "</size></color>" }); } else { Color c = LazySingletonBehavior <UIManager> .Instance.UIColorRefs.gold; __instance.DescriptionText.SetText("{0}{1}HEADSHOT ENABLED{2}", new object[] { "^^^ SELECT A LOCATION FOR CALLED SHOT ^^^ \n", "<color=#" + ColorUtility.ToHtmlStringRGBA(c) + "><size=80%>", "</size></color>" }); } } // Called Shot set at location else { //string targetName = ___HUD.SelectedActor.DisplayName; //string readiedWeaponList = Utilities.GetReadiedWeaponsString(___HUD.SelectedActor.Weapons, ___HUD.SelectedTarget); string locationHealth = Utilities.GetLocationHealthString(___HUD.SelectedTarget, ___displayedLocation); __instance.DescriptionText.SetText("CALLED SHOT: {0}\n{1}{2}{3}", new object[] { Mech.GetLongArmorLocation(___displayedLocation), "<size=80%>", locationHealth, "</size>" }); } } catch (Exception e) { Logger.Error(e); } }
static void Postfix(CombatHUDAttackModeSelector __instance, CombatGameState Combat, CombatHUD HUD) { try { Mod.UILog.Trace?.Write($"CREATING TEST COMPONENTS: instance is null? {__instance == null} instanceGO is null? {__instance?.gameObject == null}"); // Find icPanel_Layout as the parent Transform icPanelLayoutTransform = __instance.FireButton.gameObject.transform.parent; GameObject icPanelLayoutGO = icPanelLayoutTransform.gameObject; if (icPanelLayoutGO == null) { Mod.UILog.Warn?.Write("FAILED TO FIND IC_PANEL_LAYOUT!"); } VerticalLayoutGroup vlg = icPanelLayoutGO.GetComponent <VerticalLayoutGroup>(); vlg.childAlignment = TextAnchor.MiddleCenter; vlg.childControlWidth = true; vlg.spacing = 8f; ModState.MeleeAttackContainer = new GameObject(); ModState.MeleeAttackContainer.transform.parent = icPanelLayoutTransform; ModState.MeleeAttackContainer.transform.SetSiblingIndex(1); // Move us above the description container ModState.MeleeAttackContainer.layer = 5; // everyting else is at this level ModState.MeleeAttackContainer.name = ModConsts.Container_GO_ID; if (ModState.MeleeAttackContainer == null) { Mod.UILog.Warn?.Write("FAILED TO ADD CONTAINER!"); } RectTransform containerRectTransform = ModState.MeleeAttackContainer.AddComponent <RectTransform>(); containerRectTransform.localScale = Vector3.one; HorizontalLayoutGroup hlg = ModState.MeleeAttackContainer.AddComponent <HorizontalLayoutGroup>(); if (hlg == null) { Mod.UILog.Warn?.Write("FAILED TO CREATE HORIZONTAL GROUP"); } hlg.childForceExpandHeight = false; hlg.childForceExpandWidth = false; hlg.childControlHeight = false; hlg.childControlWidth = false; hlg.childAlignment = TextAnchor.LowerLeft; hlg.spacing = 16f; hlg.gameObject.SetActive(true); LayoutElement le = ModState.MeleeAttackContainer.AddComponent <LayoutElement>(); if (le == null) { Mod.UILog.Warn?.Write("FAILED TO ADD LAYOUT ELEMENT"); } le.preferredHeight = 75f; le.preferredWidth = 500f; // Reverse order, as the first one created is the right-most Mod.UILog.Trace?.Write($"CREATING BUTTONS"); ModState.ChargeFB = CloneCHUDFireButton(hlg.gameObject, __instance.FireButton, ModConsts.ChargeFB_GO_ID, Combat, HUD); ModState.PhysicalWeaponFB = CloneCHUDFireButton(hlg.gameObject, __instance.FireButton, ModConsts.PhysicalWeaponFB_GO_ID, Combat, HUD); ModState.PunchFB = CloneCHUDFireButton(hlg.gameObject, __instance.FireButton, ModConsts.PunchFB_GO_ID, Combat, HUD); ModState.KickFB = CloneCHUDFireButton(hlg.gameObject, __instance.FireButton, ModConsts.KickFB_GO_ID, Combat, HUD); } catch (Exception e) { Mod.UILog.Error?.Write(e, $"Failed to create melee buttons!"); } }
static bool Prefix(CombatHUDFireButton __instance) { if (__instance == null || __instance.gameObject == null) { return(true); } Mod.UILog.Info?.Write($"CHUDFB - OnClick FIRED for FireMode: {__instance.CurrentFireMode}"); bool shouldReturn = true; CombatHUDAttackModeSelector selector = SharedState.CombatHUD.AttackModeSelector; if (__instance.gameObject.name == ModConsts.ChargeFB_GO_ID) { MeleeState meleeState = ModState.GetMeleeState( SharedState.CombatHUD.SelectionHandler.ActiveState.SelectedActor, SharedState.CombatHUD.SelectionHandler.ActiveState.PreviewPos); ModState.AddOrUpdateSelectedAttack( SharedState.CombatHUD.SelectionHandler.ActiveState.SelectedActor, meleeState.Charge ); Mod.UILog.Info?.Write("User selected Charge button"); shouldReturn = false; } else if (__instance.gameObject.name == ModConsts.KickFB_GO_ID) { MeleeState meleeState = ModState.GetMeleeState( SharedState.CombatHUD.SelectionHandler.ActiveState.SelectedActor, SharedState.CombatHUD.SelectionHandler.ActiveState.PreviewPos); ModState.AddOrUpdateSelectedAttack( SharedState.CombatHUD.SelectionHandler.ActiveState.SelectedActor, meleeState.Kick ); Mod.UILog.Info?.Write("User selected Kick button"); shouldReturn = false; } else if (__instance.gameObject.name == ModConsts.PhysicalWeaponFB_GO_ID) { MeleeState meleeState = ModState.GetMeleeState( SharedState.CombatHUD.SelectionHandler.ActiveState.SelectedActor, SharedState.CombatHUD.SelectionHandler.ActiveState.PreviewPos); ModState.AddOrUpdateSelectedAttack( SharedState.CombatHUD.SelectionHandler.ActiveState.SelectedActor, meleeState.PhysicalWeapon ); Mod.UILog.Info?.Write("User selected PhysWeap button"); shouldReturn = false; } else if (__instance.gameObject.name == ModConsts.PunchFB_GO_ID) { MeleeState meleeState = ModState.GetMeleeState( SharedState.CombatHUD.SelectionHandler.ActiveState.SelectedActor, SharedState.CombatHUD.SelectionHandler.ActiveState.PreviewPos); ModState.AddOrUpdateSelectedAttack( SharedState.CombatHUD.SelectionHandler.ActiveState.SelectedActor, meleeState.Punch ); Mod.UILog.Info?.Write("User selected Punch button"); shouldReturn = false; } else { MeleeAttack selectedAttack2 = ModState.GetSelectedAttack(SharedState.CombatHUD?.SelectionHandler?.ActiveState?.SelectedActor); if (selectedAttack2 != null) { Mod.UILog.Info?.Write("OnClick from generic CHUDFB with selected type, short-cutting to action."); // Disable the buttons to prevent accidental clicks? if (selectedAttack2 is ChargeAttack) { ModState.ChargeFB.CurrentFireMode = CombatHUDFireButton.FireMode.None; } if (selectedAttack2 is KickAttack) { ModState.KickFB.CurrentFireMode = CombatHUDFireButton.FireMode.None; } if (selectedAttack2 is WeaponAttack) { ModState.PhysicalWeaponFB.CurrentFireMode = CombatHUDFireButton.FireMode.None; } if (selectedAttack2 is PunchAttack) { ModState.PunchFB.CurrentFireMode = CombatHUDFireButton.FireMode.None; } return(true); } } MeleeAttack selectedAttack = ModState.GetSelectedAttack(SharedState.CombatHUD?.SelectionHandler?.ActiveState?.SelectedActor); if (selectedAttack != null) { Mod.UILog.Debug?.Write("Enabling description container for melee attack"); selector.DescriptionContainer.SetActive(true); selector.DescriptionContainer.gameObject.SetActive(true); HashSet <string> descriptonNotes = selectedAttack.DescriptionNotes; string description = String.Join(", ", descriptonNotes); Mod.UILog.Debug?.Write($"Aggregate description is: {description}"); selector.DescriptionText.SetText(description); selector.DescriptionText.ForceMeshUpdate(true); // TODO: Update weapon damage instead? // Update the weapon strings SharedState.CombatHUD.WeaponPanel.RefreshDisplayedWeapons(); } return(shouldReturn); }
static void Postfix(CombatHUDAttackModeSelector __instance, CombatHUDFireButton.FireMode mode, ref string additionalDetails, bool showHeatWarnings) { try { // Disable the melee container if there's no active state if (SharedState.CombatHUD?.SelectionHandler?.ActiveState == null || SharedState.CombatHUD?.SelectionHandler?.ActiveState?.SelectedActor == null || SharedState.CombatHUD?.SelectionHandler?.ActiveState?.PreviewPos == null) { Mod.UILog.Trace?.Write($"Disabling all CHUD_Fire_Buttons"); ModState.MeleeAttackContainer.SetActive(false); return; } Mod.UILog.Trace?.Write($"ShowFireButton called with mode: {mode}"); if (mode == CombatHUDFireButton.FireMode.Engage) { Mod.UILog.Trace?.Write($"Enabling all CHUD_Fire_Buttons"); ModState.MeleeAttackContainer.SetActive(true); MeleeState meleeState = ModState.GetMeleeState( SharedState.CombatHUD.SelectionHandler.ActiveState.SelectedActor, SharedState.CombatHUD.SelectionHandler.ActiveState.PreviewPos); // Toggle each button by available state ToggleStateButtons(meleeState); // Autoselect best option MeleeAttack autoselectedAttack = meleeState.GetHighestDamageAttackForUI(); if (autoselectedAttack != null) { Mod.UILog.Info?.Write($"Autoselecting state of type: '{autoselectedAttack.Label}' as most damaging."); } else { Mod.UILog.Info?.Write("No highest damaging state - no melee options!"); } // Final check - if everything is disabled, disable the button bool hasValidAttack = meleeState.Charge.IsValid || meleeState.Kick.IsValid || meleeState.PhysicalWeapon.IsValid || meleeState.Punch.IsValid; if (!hasValidAttack) { Mod.UILog.Info?.Write("NO VALID MELEE ATTACKS, DISABLING!"); __instance.FireButton.SetState(ButtonState.Disabled); __instance.FireButton.CurrentFireMode = CombatHUDFireButton.FireMode.None; __instance.DescriptionContainer.SetActive(false); SharedState.CombatHUD.SelectionHandler.ActiveState.BackOut(); __instance.ForceRefreshImmediate(); } else { Mod.UILog.Info?.Write($" CHECKING FOR VALID ATTACKS: hasValidAttack=>{hasValidAttack}" + $" charge=>{meleeState.Charge.IsValid}" + $" kick=>{meleeState.Kick.IsValid}" + $" punch=>{meleeState.Punch.IsValid}" + $" weapon=>{meleeState.PhysicalWeapon.IsValid}" + $""); } } else { Mod.UILog.Trace?.Write($"Disabling all CHUD_Fire_Buttons"); ModState.MeleeAttackContainer.SetActive(false); if (ModState.ChargeFB != null) { ModState.ChargeFB.CurrentFireMode = CombatHUDFireButton.FireMode.None; } if (ModState.KickFB != null) { ModState.KickFB.CurrentFireMode = CombatHUDFireButton.FireMode.None; } if (ModState.PhysicalWeaponFB != null) { ModState.PhysicalWeaponFB.CurrentFireMode = CombatHUDFireButton.FireMode.None; } if (ModState.PunchFB != null) { ModState.PunchFB.CurrentFireMode = CombatHUDFireButton.FireMode.None; } ModState.InvalidateState(SharedState.CombatHUD.SelectionHandler.ActiveState.SelectedActor); } // Handle the DFA button here if (mode == CombatHUDFireButton.FireMode.DFA) { MeleeState meleeState = ModState.GetMeleeState( SharedState.CombatHUD.SelectionHandler.ActiveState.SelectedActor, SharedState.CombatHUD.SelectionHandler.ActiveState.PreviewPos); // Check for valid attack if (!meleeState.DFA.IsValid) { Mod.UILog.Info?.Write($"DFA attack failed validation, disabling button."); __instance.FireButton.SetState(ButtonState.Disabled); __instance.FireButton.CurrentFireMode = CombatHUDFireButton.FireMode.None; __instance.DescriptionContainer.SetActive(false); SharedState.CombatHUD.SelectionHandler.ActiveState.BackOut(); __instance.ForceRefreshImmediate(); } HashSet <string> descriptonNotes = meleeState.DFA.DescriptionNotes; additionalDetails = String.Join(", ", descriptonNotes); Mod.UILog.Info?.Write($"Aggregate description is: {additionalDetails}"); // Select state here as a click will validate ModState.AddOrUpdateSelectedAttack( SharedState.CombatHUD.SelectionHandler.ActiveState.SelectedActor, meleeState.DFA ); } } catch (Exception e) { Mod.Log.Warn?.Write(e, "Failed to update the CombatButton states - warn Frost!"); } }