Exemplo n.º 1
0
 static VEF_ReflectionData()
 {
     if (VEF_ModCompatibilityCheck.enabled_rooloDualWield)
     {
         MB_TryGetOffHandEquipment = AccessTools.Method(type: GenTypes.GetTypeInAnyAssemblyNew("DualWield.Ext_Pawn_EquipmentTracker", "DualWield"), name: "TryGetOffHandEquipment");
     }
 }
Exemplo n.º 2
0
        static HarmonyPatches()
        {
            //HarmonyInstance.DEBUG = true;
            RenameEverything.HarmonyInstance.PatchAll();

            // RPG Style Inventory
            if (ModCompatibilityCheck.RPGStyleInventory)
            {
                // Apply the same transpiler used on ITab_Pawn_Gear.DrawThingRow to RPG_GearTab's DrawThingRow
                var rpgGearTab = GenTypes.GetTypeInAnyAssemblyNew("Sandy_Detailed_RPG_Inventory.Sandy_Detailed_RPG_GearTab", "Sandy_Detailed_RPG_Inventory");
                if (rpgGearTab != null)
                {
                    RenameEverything.HarmonyInstance.Patch(AccessTools.Method(rpgGearTab, "DrawThingRow"), transpiler: new HarmonyMethod(typeof(Patch_ITab_Pawn_Gear.Patch_DrawThingRow), "Transpiler"));
                }
                else
                {
                    Log.Error("Could not find type Sandy_Detailed_RPG_Inventory.Sandy_Detailed_RPG_GearTab in RPG Style Inventory");
                }
            }

            // Infused
            if (ModCompatibilityCheck.Infused)
            {
                var infusedThingLabelPatch = GenTypes.GetTypeInAnyAssemblyNew("Infused.GenMapUI_DrawThingLabel_Patch", "Infused");
                if (infusedThingLabelPatch != null)
                {
                    RenameEverything.HarmonyInstance.Patch(AccessTools.Method(infusedThingLabelPatch, "Postfix"), transpiler: new HarmonyMethod(typeof(Patch_Infused_GenMapUI_DrawThingLabel_Patch.ManualPatch_Postfix), "Transpiler"));
                }
                else
                {
                    Log.Error("Could not find type Infused.GenMapUI_DrawThingLabel_Patch in Infused");
                }
            }
        }
Exemplo n.º 3
0
        static HarmonyPatches()
        {
            HarmonyInstance h = HarmonyInstance.Create("XeoNovaDan.SurvivalTools");

            //HarmonyInstance.DEBUG = true;

            // Automatic patches
            h.PatchAll(Assembly.GetExecutingAssembly());

            // Manual patches
            // Plants that obstruct construction zones
            var postfixHandleBlockingThingJob = new HarmonyMethod(patchType, nameof(Postfix_HandleBlockingThingJob));

            h.Patch(AccessTools.Method(typeof(GenConstruct), nameof(GenConstruct.HandleBlockingThingJob)), postfix: postfixHandleBlockingThingJob);
            h.Patch(AccessTools.Method(typeof(RoofUtility), nameof(RoofUtility.HandleBlockingThingJob)), postfix: postfixHandleBlockingThingJob);

            // Mining JobDriver - ResetTicksToPickHit
            var transpileResetTicksToPickHit = new HarmonyMethod(patchType, nameof(Transpile_JobDriver_Mine_ResetTicksToPickHit));

            h.Patch(AccessTools.Method(typeof(JobDriver_Mine), "ResetTicksToPickHit"), transpiler: transpileResetTicksToPickHit);

            // Thanks Mehni!
            if (!ModCompatibilityCheck.OtherInventoryModsActive)
            {
                h.Patch(AccessTools.Method(typeof(FloatMenuMakerMap), "AddHumanlikeOrders"), transpiler: new HarmonyMethod(patchType, nameof(Transpile_FloatMenuMakerMad_AddHumanlikeOrders)));
            }

            // erdelf never fails to impress :)
            #region JobDriver Boilerplate
            h.Patch(typeof(RimWorld.JobDriver_PlantWork).GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Instance).First().
                    GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Instance).First().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).
                    MaxBy(mi => mi.GetMethodBody()?.GetILAsByteArray().Length ?? -1),
                    transpiler: new HarmonyMethod(patchType, nameof(Transpile_JobDriver_PlantWork_MakeNewToils)));

            var transpileMineMakeNewToils = new HarmonyMethod(patchType, nameof(Transpile_JobDriver_Mine_MakeNewToils));
            h.Patch(typeof(JobDriver_Mine).GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Instance).First().
                    GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Instance).First().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).
                    MaxBy(mi => mi.GetMethodBody()?.GetILAsByteArray().Length ?? -1),
                    transpiler: transpileMineMakeNewToils);

            h.Patch(typeof(JobDriver_ConstructFinishFrame).GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Instance).First().
                    GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Instance).First().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).
                    MaxBy(mi => mi.GetMethodBody()?.GetILAsByteArray().Length ?? -1),
                    transpiler: new HarmonyMethod(patchType, nameof(Transpile_JobDriver_ConstructFinishFrame_MakeNewToils)));

            h.Patch(typeof(JobDriver_Repair).GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Instance).First().
                    GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Instance).First().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).
                    MaxBy(mi => mi.GetMethodBody()?.GetILAsByteArray().Length ?? -1),
                    transpiler: new HarmonyMethod(patchType, nameof(Transpile_JobDriver_Repair_MakeNewToils)));

            h.Patch(AccessTools.Method(typeof(JobDriver_Deconstruct), "TickAction"),
                    new HarmonyMethod(patchType, nameof(Prefix_JobDriver_Deconstruct_TickAction)));

            h.Patch(typeof(JobDriver_AffectRoof).GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Instance).First().
                    GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Instance).First().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).
                    MaxBy(mi => mi.GetMethodBody()?.GetILAsByteArray().Length ?? -1),
                    transpiler: new HarmonyMethod(patchType, nameof(Transpile_JobDriver_AffectRoof_MakeNewToils)));
            #endregion

            // Fluffy Breakdowns
            if (ModCompatibilityCheck.FluffyBreakdowns)
            {
                var maintenanceDriver = GenTypes.GetTypeInAnyAssemblyNew("Fluffy_Breakdowns.JobDriver_Maintenance", null);
                if (maintenanceDriver != null && typeof(JobDriver).IsAssignableFrom(maintenanceDriver))
                {
                    h.Patch(maintenanceDriver.GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Instance).MinBy(x => x.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).Count())
                            .GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).MaxBy(mi => mi.GetMethodBody()?.GetILAsByteArray().Length ?? -1),
                            transpiler: new HarmonyMethod(patchType, nameof(Transpile_JobDriver_Maintenance_MakeNewToils)));
                }
                else
                {
                    Log.Error("Survival Tools - Could not find Fluffy_Breakdowns.JobDriver_Maintenance type to patch");
                }
            }

            // Quarry
            if (ModCompatibilityCheck.Quarry)
            {
                var quarryDriver = GenTypes.GetTypeInAnyAssemblyNew("Quarry.JobDriver_MineQuarry", null);
                if (quarryDriver != null && typeof(JobDriver).IsAssignableFrom(quarryDriver))
                {
                    h.Patch(AccessTools.Method(quarryDriver, "Mine"), postfix: new HarmonyMethod(patchType, nameof(Postfix_JobDriver_MineQuarry_Mine)));
                    h.Patch(AccessTools.Method(quarryDriver, "ResetTicksToPickHit"), transpiler: new HarmonyMethod(patchType, nameof(Transpile_JobDriver_MineQuarry_ResetTicksToPickHit)));
                }
                else
                {
                    Log.Error("Survival Tools - Could not find Quarry.JobDriver_MineQuarry type to patch");
                }
            }

            // Turret Extensions
            if (ModCompatibilityCheck.TurretExtensions)
            {
                var turretExtensionsDriver = GenTypes.GetTypeInAnyAssemblyNew("TurretExtensions.JobDriver_UpgradeTurret", null);
                if (turretExtensionsDriver != null && typeof(JobDriver).IsAssignableFrom(turretExtensionsDriver))
                {
                    h.Patch(AccessTools.Method(turretExtensionsDriver, "Upgrade"), postfix: new HarmonyMethod(patchType, nameof(Postfix_JobDriver_UpgradeTurret_Upgrade)));
                }
                else
                {
                    Log.Error("Survival Tools - Could not find TurretExtensions.JobDriver_UpgradeTurret type to patch");
                }
            }

            // Combat Extended
            if (ModCompatibilityCheck.CombatExtended)
            {
                // Prevent tools from incorrectly being removed based on loadout
                var combatExtendedHoldTrackerExcessThingClass = GenTypes.GetTypeInAnyAssemblyNew("CombatExtended.Utility_HoldTracker", null);
                if (combatExtendedHoldTrackerExcessThingClass != null)
                {
                    h.Patch(AccessTools.Method(combatExtendedHoldTrackerExcessThingClass, "GetExcessThing"), postfix: new HarmonyMethod(patchType, nameof(Postfix_CombatExtended_Utility_HoldTracker_GetExcessThing)));
                }
                else
                {
                    Log.Error("Survival Tools - Could not find CombatExtended.Utility_HoldTracker type to patch");
                }

                // Prevent pawns from picking up excess tools with Combat Extended's CompInventory
                var combatExtendedCompInventory = GenTypes.GetTypeInAnyAssemblyNew("CombatExtended.CompInventory", null);
                if (combatExtendedCompInventory != null)
                {
                    h.Patch(AccessTools.Method(combatExtendedCompInventory, "CanFitInInventory"), postfix: new HarmonyMethod(patchType, nameof(Postfix_CombatExtended_CompInventory_CanFitInInventory)));
                }
                else
                {
                    Log.Error("Survival Tools - Could not find CombatExtended.CompInventory type to patch");
                }
            }

            // Prison Labor
            if (ModCompatibilityCheck.PrisonLabor)
            {
                // Fix pickaxe degradation and use correct mining speed stat
                var prisonLabourMineJobDriver = GenTypes.GetTypeInAnyAssemblyNew("PrisonLabor.JobDriver_Mine_Tweak", null);
                if (prisonLabourMineJobDriver != null)
                {
                    h.Patch(AccessTools.Method(prisonLabourMineJobDriver, "ResetTicksToPickHit"), transpiler: transpileResetTicksToPickHit);
                    h.Patch(prisonLabourMineJobDriver.GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Instance).Last()
                            .GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).MaxBy(mi => mi.GetMethodBody()?.GetILAsByteArray().Length ?? -1),
                            transpiler: transpileMineMakeNewToils);
                }
            }
        }
        static HarmonyPatches()
        {
            // Harmony Setup and Debug
            Log.Message("VEF :: Performing Hamrony Patches");
            HarmonyInstance.DEBUG = false;
            HarmonyInstance harmony = HarmonyInstance.Create(id: "com.framework.expansion.verb");

            // Harmony Patches required for Core operation.
            harmony.Patch(original: AccessTools.Method(type: typeof(Alert_BrawlerHasRangedWeapon), name: nameof(Alert_BrawlerHasRangedWeapon.GetReport)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(Alert_BrawlerHasRangedWeapon_GetReportPostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(AttackTargetsCache), name: nameof(AttackTargetsCache.GetPotentialTargetsFor)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(AttackTargetsCache_GetPotentialTargetsForPostfix)));
            harmony.Patch(original: AccessTools.Constructor(type: typeof(BattleLogEntry_RangedFire), parameters: new Type[] { typeof(Thing), typeof(Thing), typeof(ThingDef), typeof(ThingDef), typeof(bool) }), prefix: new HarmonyMethod(type: patchType, name: nameof(BattleLogEntry_WeaponDefGrammarPrefix)), postfix: null);
            harmony.Patch(original: AccessTools.Constructor(type: typeof(BattleLogEntry_RangedImpact), parameters: new Type[] { typeof(Thing), typeof(Thing), typeof(Thing), typeof(ThingDef), typeof(ThingDef), typeof(ThingDef) }), prefix: new HarmonyMethod(type: patchType, name: nameof(BattleLogEntry_WeaponDefGrammarPrefix)), postfix: null);
            harmony.Patch(original: AccessTools.Method(type: typeof(Command_VerbTarget), name: nameof(Command_VerbTarget.ProcessInput)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(Command_VerbTarget_ProcessInputPostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(Command_VerbTarget), name: nameof(Command_VerbTarget.GizmoUpdateOnMouseover)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(Command_VerbTarget_GizmoUpdateOnMousoverPostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(Explosion), name: "AffectCell"), prefix: new HarmonyMethod(type: patchType, name: nameof(Explsoion_AffectCellPrefix)), postfix: null);
            harmony.Patch(original: AccessTools.Method(type: typeof(FloatMenuUtility), name: nameof(FloatMenuUtility.GetAttackAction)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(FloatMenuUtility_GetAttackActionPostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(HealthCardUtility), name: "GenerateSurgeryOption"), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(HealthCardUtility_GenerateSurgeryOptionPostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(HediffSet), name: "CalculateBleedRate"), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(HediffSet_CalculateBleedRatePostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(JobDriver_Wait), name: "CheckForAutoAttack"), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(JobDriver_Wait_CheckForAutoAttackPostfix)));
            harmony.Patch(original: AccessTools.Property(type: typeof(Pawn), name: nameof(Pawn.HealthScale)).GetGetMethod(true), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(Pawn_GetHealthScalePostfix)));
            if (!VEF_ModCompatibilityCheck.enabled_CombatExtended)
            {
                harmony.Patch(original: AccessTools.Method(type: typeof(Pawn), name: nameof(Pawn.TryGetAttackVerb)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(Pawn_TryGetAttackVerbPostfix)));
                harmony.Patch(original: AccessTools.Method(type: typeof(PawnAttackGizmoUtility), name: "GetSquadAttackGizmo"), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(PawnAttackGizmoUtility_GetSquadAttackGizmoPostfix)));
            }
            harmony.Patch(original: VEF_ReflectionData.MB_Pawn_DraftController_GetGizmo(), prefix: null, postfix: null, transpiler: new HarmonyMethod(type: patchType, name: nameof(Pawn_DraftController_GetGizmosTranspiler)));
            harmony.Patch(original: AccessTools.Method(type: typeof(Pawn_HealthTracker), name: nameof(Pawn_HealthTracker.PreApplyDamage)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(Pawn_HealthTracker_PreApplyDamagePostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(SmokepopBelt), name: nameof(SmokepopBelt.CheckPreAbsorbDamage)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(SmokepopBelt_CheckPreAbsorbDamagePostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(Targeter), name: "GetTargetingVerb"), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(Targeter_GetTargetingVerbPostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(Targeter), name: nameof(Targeter.TargeterUpdate)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(Targeter_TargeterUpdatePostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(ThoughtWorker_IsCarryingRangedWeapon), name: "CurrentStateInternal"), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(ThoughtWorker_IsCarryingRangedWeapon_CurrentStateInternalPostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(Verb_ShootOneUse), name: "SelfConsume"), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(Verb_ShootOneUse_SelfConsumePostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(Verb_Spawn), name: "TryCastShot"), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(Verb_Spawn_TryCastShotPostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(VerbProperties), name: nameof(VerbProperties.GetDamageFactorFor), parameters: new Type[] { typeof(Tool), typeof(Pawn), typeof(HediffComp_VerbGiver) }), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(VerbProperties_GetDamageFactorForPostfix)), transpiler: new HarmonyMethod(type: patchType, name: nameof(VerbProperties_GetDamageFactorForTranspiler)));
            harmony.Patch(original: AccessTools.Method(type: typeof(VerbUtility), name: nameof(VerbUtility.AllowAdjacentShot)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(VerbUtility_AllowAdjacentShotPostfix)));

            //  UpdateHediffSetPostfix (instrcucts HediffSets on pawn to update when a hediff changed)
            harmony.Patch(original: AccessTools.Method(type: typeof(HediffSet), name: nameof(HediffSet.DirtyCache)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(UpdateHediffSetPostfix)));

            // UpdateRangedVerbPostfix (forces update to ranged verbs when a change to a possible verb source is detected)
            harmony.Patch(original: AccessTools.Method(type: typeof(HediffSet), name: nameof(HediffSet.DirtyCache)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(UpdateRangedVerbsPostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(Pawn_EquipmentTracker), name: nameof(Pawn_EquipmentTracker.Notify_EquipmentAdded)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(UpdateRangedVerbsPostfix)));
            harmony.Patch(original: AccessTools.Method(type: typeof(Pawn_EquipmentTracker), name: nameof(Pawn_EquipmentTracker.Notify_EquipmentRemoved)), prefix: null, postfix: new HarmonyMethod(type: patchType, name: nameof(UpdateRangedVerbsPostfix)));

            // Harmony Patches for Mod Compatibility
            // Dual Wield
            if (VEF_ModCompatibilityCheck.enabled_rooloDualWield)
            {
                try
                {
                    ((Action)(() =>
                    {
                        harmony.Patch(original: AccessTools.Method(type: typeof(DualWield.Ext_Verb), name: nameof(DualWield.Ext_Verb.OffhandTryStartCastOn)), prefix: new HarmonyMethod(type: patchType, name: nameof(DualWield_Ext_Verb_OffhandTryStartCastOn)), postfix: null);
                    }))();
                }
                catch (TypeLoadException ex)
                {
                }
            }

            // Range Animal Framework
            if (VEF_ModCompatibilityCheck.enabled_RangeAnimalFramework)
            {
                try
                {
                    ((Action)(() =>
                    {
                        harmony.Patch(original: AccessTools.Method(type: GenTypes.GetTypeInAnyAssemblyNew("AnimalRangeAttack.ARA_FightAI_Patch", "AnimalRangeAttack"), name: "Prefix"), prefix: null, postfix: null, transpiler: new HarmonyMethod(type: patchType, name: nameof(PrefixSlayerTranspiler)));
                        harmony.Patch(original: AccessTools.Method(type: GenTypes.GetTypeInAnyAssemblyNew("AnimalRangeAttack.ARA__ManHunter_Patch", "AnimalRangeAttack"), name: "Prefix"), prefix: null, postfix: null, transpiler: new HarmonyMethod(type: patchType, name: nameof(PrefixSlayerTranspiler)));
                        harmony.Patch(original: AccessTools.Method(type: GenTypes.GetTypeInAnyAssemblyNew("AnimalRangeAttack.ARA__VerbCheck_Patch", "AnimalRangeAttack"), name: "Prefix"), prefix: null, postfix: null, transpiler: new HarmonyMethod(type: patchType, name: nameof(PrefixSlayerTranspiler)));
                    }))();
                }
                catch (TypeLoadException ex)
                {
                }
            }
        }
        static VEF_ModCompatibilityCheck()
        {
            if (ModsConfig.ActiveModsInLoadOrder.Any(m => m.Name == "Range Animal Framework") || GenTypes.GetTypeInAnyAssemblyNew("AnimalRangeAttack.AnimalRangeAttack_Init", "AnimalRangeAttack") != null)
            {
                enabled_RangeAnimalFramework = true;
            }

            if (ModsConfig.ActiveModsInLoadOrder.Any(m => m.Name == "Smokepop Defense Framework") || GenTypes.GetTypeInAnyAssemblyNew("SmokepopCompFramework.SCF_Harmony", "SmokepopCompFramework") != null)
            {
                enabled_SmokepopDefenseFramework = true;
            }

            if (ModsConfig.ActiveModsInLoadOrder.Any(m => m.Name == "Variable Health Framework") || GenTypes.GetTypeInAnyAssemblyNew("VariableHealthFramework.VHF_Harmony", "VariableHealthFramework") != null)
            {
                enabled_VariableHealthFramework = true;
            }
        }
 static ReflectedMethods()
 {
     // Convert DualWield.Ext_Pawn_EquipmentTracker.TryGetOffHandEquipment to a delegate
     if (ModCompatibilityCheck.DualWield)
     {
         TryGetOffHandEquipment = (FuncOut <Pawn_EquipmentTracker, ThingWithComps, bool>)Delegate.CreateDelegate(typeof(FuncOut <Pawn_EquipmentTracker, ThingWithComps, bool>),
                                                                                                                 AccessTools.Method(GenTypes.GetTypeInAnyAssemblyNew("DualWield.Ext_Pawn_EquipmentTracker", "DualWield"), "TryGetOffHandEquipment"));
     }
 }