using HarmonyLib; using KFCommonUtilityLib.Scripts.Attributes; using KFCommonUtilityLib.Scripts.StaticManagers; using KFCommonUtilityLib.Scripts.Utilities; [TypeTarget(typeof(ItemActionAttack)), ActionDataTarget(typeof(MultiActionData))] public class ActionModuleMultiActionFix { private int actionIndex; public string GetDisplayType(ItemValue itemValue) { string displayType = itemValue.GetPropertyOverrideForAction("DisplayType", null, actionIndex); if (string.IsNullOrEmpty(displayType)) { displayType = itemValue.ItemClass.DisplayType; } return displayType; } [HarmonyPatch(nameof(ItemAction.ReadFrom)), MethodTargetPostfix] public void Postfix_ReadFrom(ItemActionAttack __instance) { actionIndex = __instance.ActionIndex; } [HarmonyPatch(nameof(ItemAction.StartHolding)), MethodTargetPrefix] public bool Prefix_StartHolding(ItemActionData _data, out ItemActionData __state) { SetAndSaveItemActionData(_data, out __state); return true; } [HarmonyPatch(nameof(ItemAction.StartHolding)), MethodTargetPostfix] public void Postfix_StartHolding(ItemActionData _data, ItemActionData __state) { RestoreItemActionData(_data, __state); } [HarmonyPatch(typeof(ItemActionRanged), nameof(ItemAction.OnModificationsChanged)), MethodTargetPostfix] public void Postfix_OnModificationChanged_ItemActionRanged(ItemActionData _data, ItemActionAttack __instance) { var rangedData = _data as ItemActionRanged.ItemActionDataRanged; if (rangedData != null) { string muzzleName; string indexExtension = (_data.indexInEntityOfAction > 0 ? _data.indexInEntityOfAction.ToString() : ""); if (rangedData.IsDoubleBarrel) { muzzleName = _data.invData.itemValue.GetPropertyOverrideForAction($"Muzzle_L_Name", $"Muzzle_L{indexExtension}", _data.indexInEntityOfAction); rangedData.muzzle = AnimationRiggingManager.GetTransformOverrideByName(rangedData.invData.model, muzzleName) ?? rangedData.muzzle; muzzleName = _data.invData.itemValue.GetPropertyOverrideForAction($"Muzzle_R_Name", $"Muzzle_R{indexExtension}", _data.indexInEntityOfAction); rangedData.muzzle2 = AnimationRiggingManager.GetTransformOverrideByName(rangedData.invData.model, muzzleName) ?? rangedData.muzzle2; } else { muzzleName = _data.invData.itemValue.GetPropertyOverrideForAction($"Muzzle_Name", $"Muzzle{indexExtension}", _data.indexInEntityOfAction); rangedData.muzzle = AnimationRiggingManager.GetTransformOverrideByName(rangedData.invData.model, muzzleName) ?? rangedData.muzzle; } } } [HarmonyPatch(typeof(ItemActionLauncher), nameof(ItemAction.OnModificationsChanged)), MethodTargetPostfix] public void Postfix_OnModificationChanged_ItemActionLauncher(ItemActionData _data, ItemActionAttack __instance) { Postfix_OnModificationChanged_ItemActionRanged(_data, __instance); if (_data is ItemActionLauncher.ItemActionDataLauncher launcherData) { string indexExtension = (_data.indexInEntityOfAction > 0 ? _data.indexInEntityOfAction.ToString() : ""); string jointName = _data.invData.itemValue.GetPropertyOverrideForAction($"ProjectileJoint_Name", $"ProjectileJoint{indexExtension}", _data.indexInEntityOfAction); launcherData.projectileJoint = AnimationRiggingManager.GetTransformOverrideByName(launcherData.invData.model, jointName) ?? launcherData.projectileJoint; } } [HarmonyPatch(nameof(ItemAction.StopHolding)), MethodTargetPrefix] public bool Prefix_StopHolding(ItemActionData _data, out ItemActionData __state) { SetAndSaveItemActionData(_data, out __state); return true; } [HarmonyPatch(nameof(ItemAction.StopHolding)), MethodTargetPostfix] public void Postfix_StopHolding(ItemActionData _data, ItemActionData __state) { RestoreItemActionData(_data, __state); } [HarmonyPatch(typeof(ItemActionLauncher), nameof(ItemAction.ItemActionEffects)), MethodTargetPrefix] public bool Prefix_ItemActionEffects(ItemActionData _actionData, out ItemActionData __state) { SetAndSaveItemActionData(_actionData, out __state); return true; } [HarmonyPatch(typeof(ItemActionLauncher), nameof(ItemAction.ItemActionEffects)), MethodTargetPostfix] public void Postfix_ItemActionEffects(ItemActionData _actionData, ItemActionData __state) { RestoreItemActionData(_actionData, __state); } [HarmonyPatch(nameof(ItemAction.CancelAction)), MethodTargetPrefix] public bool Prefix_CancelAction(ItemActionData _actionData, out ItemActionData __state) { SetAndSaveItemActionData(_actionData, out __state); return true; } [HarmonyPatch(nameof(ItemAction.CancelAction)), MethodTargetPostfix] public void Postfix_CancelAction(ItemActionData _actionData, ItemActionData __state) { RestoreItemActionData(_actionData, __state); } [HarmonyPatch(nameof(ItemActionAttack.CancelReload)), MethodTargetPrefix] public bool Prefix_CancelReload(ItemActionData _actionData, out ItemActionData __state) { SetAndSaveItemActionData(_actionData, out __state); return true; } [HarmonyPatch(nameof(ItemActionAttack.CancelReload)), MethodTargetPostfix] public void Postfix_CancelReload(ItemActionData _actionData, ItemActionData __state) { RestoreItemActionData(_actionData, __state); } [HarmonyPatch(nameof(ItemActionAttack.ReloadGun)), MethodTargetPrefix] public bool Prefix_ReloadGun(ItemActionData _actionData) { //int reloadAnimationIndex = MultiActionManager.GetMetaIndexForActionIndex(_actionData.invData.holdingEntity.entityId, _actionData.indexInEntityOfAction); _actionData.invData.holdingEntity.emodel?.avatarController?.UpdateInt(MultiActionUtils.ExecutingActionIndexHash, _actionData.indexInEntityOfAction, false); _actionData.invData.holdingEntity.MinEventContext.ItemActionData = _actionData; //MultiActionManager.GetMappingForEntity(_actionData.invData.holdingEntity.entityId)?.SaveMeta(); return true; } [HarmonyPatch(nameof(ItemAction.OnHUD)), MethodTargetPrefix] public bool Prefix_OnHUD(ItemActionData _actionData) { if (_actionData.invData?.holdingEntity?.MinEventContext?.ItemActionData == null || _actionData.indexInEntityOfAction != _actionData.invData.holdingEntity.MinEventContext.ItemActionData.indexInEntityOfAction) return false; return true; } //[MethodTargetPrefix(nameof(ItemActionAttack.ExecuteAction), typeof(ItemActionRanged))] //public bool Prefix_ExecuteAction(ItemActionData _actionData, MultiActionData __customData) //{ // //when executing action, set last action index so that correct accuracy is used for drawing crosshair // if (_actionData.invData.holdingEntity is EntityPlayerLocal player) // { // ((ItemActionRanged.ItemActionDataRanged)_actionData).lastAccuracy = __customData.lastAccuracy; // } // return true; //} //[MethodTargetPrefix("updateAccuracy", typeof(ItemActionRanged))] //public bool Prefix_updateAccuracy(ItemActionData _actionData, MultiActionData __customData) //{ // if (_actionData.invData.holdingEntity is EntityPlayerLocal player && MultiActionManager.GetActionIndexForEntityID(player.entityId) == _actionData.indexInEntityOfAction) // return true; // //always update custom accuracy // ItemActionRanged.ItemActionDataRanged rangedData = _actionData as ItemActionRanged.ItemActionDataRanged; // (rangedData.lastAccuracy, __customData.lastAccuracy) = (__customData.lastAccuracy, rangedData.lastAccuracy); // return true; //} //[MethodTargetPostfix("updateAccuracy", typeof(ItemActionRanged))] //public void Postfix_updateAccuracy(ItemActionData _actionData, MultiActionData __customData) //{ // //retain rangedData accuracy if it's the last executed action // ItemActionRanged.ItemActionDataRanged rangedData = _actionData as ItemActionRanged.ItemActionDataRanged; // if (_actionData.invData.holdingEntity is EntityPlayerLocal player && MultiActionManager.GetActionIndexForEntityID(player.entityId) == _actionData.indexInEntityOfAction) // { // __customData.lastAccuracy = rangedData.lastAccuracy; // } // else // { // (rangedData.lastAccuracy, __customData.lastAccuracy) = (__customData.lastAccuracy, rangedData.lastAccuracy); // } //} [HarmonyPatch(typeof(ItemActionRanged), nameof(ItemActionRanged.onHoldingEntityFired)), MethodTargetPrefix] public bool Prefix_onHoldingEntityFired(ItemActionData _actionData) { if (!_actionData.invData.holdingEntity.isEntityRemote) { _actionData.invData.holdingEntity?.emodel?.avatarController.UpdateInt(MultiActionUtils.ExecutingActionIndexHash, _actionData.indexInEntityOfAction); //_actionData.invData.holdingEntity?.emodel?.avatarController.CancelEvent("WeaponFire"); } return true; } //[MethodTargetPostfix("onHoldingEntityFired", typeof(ItemActionRanged))] //public void Postfix_onHoldingEntityFired(ItemActionData _actionData, MultiActionData __customData) //{ // //after firing, if it's the last executed action then update custom accuracy // if (_actionData.invData.holdingEntity is EntityPlayerLocal player && MultiActionManager.GetActionIndexForEntityID(player.entityId) == _actionData.indexInEntityOfAction) // { // __customData.lastAccuracy = ((ItemActionRanged.ItemActionDataRanged)_actionData).lastAccuracy; // } //} public static void SetAndSaveItemActionData(ItemActionData _actionData, out ItemActionData lastActionData) { lastActionData = _actionData.invData.holdingEntity.MinEventContext.ItemActionData; _actionData.invData.holdingEntity.MinEventContext.ItemActionData = _actionData; } public static void RestoreItemActionData(ItemActionData _actionData, ItemActionData lastActionData) { if (lastActionData != null) _actionData.invData.holdingEntity.MinEventContext.ItemActionData = lastActionData; } public class MultiActionData { public float lastAccuracy; public MultiActionData(ItemInventoryData _invData, int _indexInEntityOfAction, ActionModuleMultiActionFix _module) { } } }