protected override MethodInfo?ResolveMethodInfo() => AccessTools.DeclaredMethod(Type, Name, Parameters, Generics);
public static void Init(string directory, string settingsJSON) { Log = HBS.Logging.Logger.GetLogger("BTX_CAC_Compatibility"); try { Sett = JsonConvert.DeserializeObject <Settings>(settingsJSON); } catch (Exception e) { Sett = new Settings(); Log.LogException(e); } if (Sett.LogLevelLog) { HBS.Logging.Logger.SetLoggerLevel("BTX_CAC_Compatibility", LogLevel.Log); } HarmonyInstance harmony = HarmonyInstance.Create("com.github.mcb5637.BTX_CAC_Compatibility"); harmony.PatchAll(Assembly.GetExecutingAssembly()); AccessExtensionPatcher.PatchAll(harmony, Assembly.GetExecutingAssembly()); AbstractActor_InitStats.Patch(harmony); AbstractActor_IndirectImmune.Patch(harmony); //harmony.Patch( // AccessTools.Method(typeof(EffectManager), "CreateEffect", new Type[] { typeof(EffectData), typeof(string), typeof(int), typeof(ICombatant), typeof(ICombatant), typeof(WeaponHitInfo), typeof(int), typeof(bool) }), // null, new HarmonyMethod(AccessTools.Method(typeof(MarkEffects_Patch), "Postfix")), null); //harmony.Patch(AccessTools.DeclaredMethod(typeof(Mech), "DamageLocation"), new HarmonyMethod(AccessTools.Method(typeof(Main), "LogDamageLoc")), null, null); if (Sett.MECompat) { return; } InfernoExplode.Patch(harmony); try { // artemis //Unpatch(harmony, AccessTools.DeclaredMethod(typeof(AttackDirector.AttackSequence), "GetClusteredHits"), "BEX.BattleTech.Extended_CE"); //Type[] ptypes = new Type[] { typeof(Vector3), typeof(Mech), typeof(float), typeof(ArmorLocation), typeof(float), typeof(float), typeof(ArmorLocation), typeof(float) }; //Unpatch(harmony, AccessTools.DeclaredMethod(typeof(HitLocation), "GetAdjacentHitLocation", ptypes), "BEX.BattleTech.Extended_CE"); //ptypes = new Type[] { typeof(Vector3), typeof(Vehicle), typeof(float), typeof(VehicleChassisLocations), typeof(float), typeof(float), typeof(VehicleChassisLocations), typeof(float) }; //Unpatch(harmony, AccessTools.DeclaredMethod(typeof(HitLocation), "GetAdjacentHitLocation", ptypes), "BEX.BattleTech.Extended_CE"); // streak Unpatch(harmony, AccessTools.DeclaredMethod(typeof(MissileLauncherEffect), "AllMissilesComplete"), "BEX.BattleTech.Extended_CE"); Unpatch(harmony, AccessTools.DeclaredMethod(typeof(MissileLauncherEffect), "LaunchMissile"), "BEX.BattleTech.Extended_CE"); Unpatch(harmony, AccessTools.DeclaredMethod(typeof(AttackDirector.AttackSequence), "GetIndividualHits"), "BEX.BattleTech.Extended_CE"); // stepped hit chance Unpatch(harmony, AccessTools.DeclaredMethod(typeof(ToHit), "GetUMChance"), "BEX.BattleTech.Extended_CE"); // called shot nerf //Unpatch(harmony, AccessTools.DeclaredMethod(typeof(Pilot), "InitAbilities"), "BEX.BattleTech.Extended_CE", false, true, false); // TSM Unpatch(harmony, AccessTools.DeclaredMethod(typeof(Mech), "OnActivationEnd"), "BEX.BattleTech.Extended_CE", false, true, false); // prefix is heat shutdown // lbx/uac Unpatch(harmony, AccessTools.DeclaredMethod(typeof(Contract), "CompleteContract"), "BEX.BattleTech.Extended_CE", true, true, true, "System.Void Extended_CE.WeaponModes+Contract_CompleteContract.Prefix(BattleTech.Contract __instance)"); Unpatch(harmony, AccessTools.DeclaredMethod(typeof(AttackEvaluator), "MakeAttackOrder"), "BEX.BattleTech.Extended_CE"); Unpatch(harmony, AccessTools.DeclaredMethod(typeof(AITeam), "TurnActorProcessActivation"), "BEX.BattleTech.Extended_CE"); Unpatch(harmony, AccessTools.DeclaredMethod(typeof(CombatHUDWeaponSlot), "OnPointerUp"), "BEX.BattleTech.Extended_CE"); Unpatch(harmony, AccessTools.DeclaredMethod(typeof(Weapon), "get_AmmoCategoryValue"), "BEX.BattleTech.Extended_CE"); Unpatch(harmony, AccessTools.DeclaredMethod(typeof(CombatHUDWeaponSlot), "RefreshDisplayedWeapon"), "BEX.BattleTech.Extended_CE", true, false, false); // transpiler is coil fix Unpatch(harmony, AccessTools.DeclaredMethod(typeof(MechValidationRules), "ValidateMechHasAppropriateAmmo"), "BEX.BattleTech.Extended_CE"); } catch (Exception e) { FileLog.Log(e.ToString()); } try { foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) { if (a.GetName().Name.Equals("MechQuirks")) { Type t = a.GetType("Quirks.Tooltips.QuirkToolTips"); harmony.Patch(t.GetMethod("DetailMechQuirks", BindingFlags.Static | BindingFlags.NonPublic), null, new HarmonyMethod(typeof(QuirkToolTips_DetailMechQuirks), "Postfix"), null); } } } catch (Exception e) { FileLog.Log(e.ToString()); } ToHitModifiersHelper.registerModifier("BTX_CAC_Compatibility_CounterNarc", "Counter NARC", true, true, CounterNarc, null); }
// Based on HarmonyLib test "Test_Patch_Returning_Structs", adjusted to be run ingame public static void Test_Patch_Returning_Structs(int n, string type) { var name = $"{type}M{n:D2}"; var patchClass = typeof(ReturningStructs_Patch); var prefix = SymbolExtensions.GetMethodInfo(() => ReturningStructs_Patch.Prefix(null)); var instance = new Harmony("returning-structs"); var cls = typeof(ReturningStructs); var method = AccessTools.DeclaredMethod(cls, name); if (method == null) { throw new Exception("method == null"); } UnityEngine.Debug.Log($"Test_Returning_Structs: patching {name} start"); try { var replacement = instance.Patch(method, new HarmonyMethod(prefix)); if (replacement == null) { throw new Exception("replacement == null"); } } catch (Exception ex) { UnityEngine.Debug.Log($"Test_Returning_Structs: patching {name} exception: {ex}"); } UnityEngine.Debug.Log($"Test_Returning_Structs: patching {name} done"); var clsInstance = new ReturningStructs(); try { UnityEngine.Debug.Log($"Test_Returning_Structs: running patched {name}"); var original = AccessTools.DeclaredMethod(cls, name); if (original == null) { throw new Exception("original == null"); } var result = original.Invoke(type == "S" ? null : clsInstance, new object[] { "test" }); if (result == null) { throw new Exception("result == null"); } if ($"St{n:D2}" != result.GetType().Name) { throw new Exception($"invalid result type name: {result.GetType().Name}"); } var field = result.GetType().GetField("b1"); var fieldValue = (byte)field.GetValue(result); UnityEngine.Debug.Log(fieldValue); if (fieldValue != 42) { throw new Exception($"result scrambled!"); } UnityEngine.Debug.Log($"Test_Returning_Structs: running patched {name} done"); } catch (Exception ex) { UnityEngine.Debug.Log($"Test_Returning_Structs: running {name} exception: {ex}"); } }
public static bool LateUpdateBullet_Prefix(Bullet __instance, Transform ___bulletSpriteTr) { // Bullet Range mods // TODO: Transpiler method int logcounter = 0; logger.LogDebug("Bullet_LateUpdateBullet"); logger.LogDebug("\tLog: " + logcounter++); if (Time.timeScale != 0f) { bool flag = true; Vector2 vector = __instance.tr.position; float maxBulletDistance; if (__instance.bulletType != bulletStatus.Fire && __instance.bulletType != bulletStatus.Water && __instance.bulletType != bulletStatus.Water2 && __instance.bulletType != bulletStatus.LeafBlower && __instance.bulletType != bulletStatus.ResearchGun && __instance.bulletType != bulletStatus.FireExtinguisher) { maxBulletDistance = C_Combat.BulletRange(__instance.agent); } else { maxBulletDistance = 13f; } logger.LogDebug("\tLog: " + logcounter++); MethodInfo destroyMe_Base = AccessTools.DeclaredMethod(typeof(PlayfieldObject), "DestroyMe", new Type[0] { }); if (__instance.agent != null && Vector2.Distance(__instance.agent.curPosition, vector) > maxBulletDistance) { flag = false; } logger.LogDebug("\tLog: " + logcounter++); if (!GC.splitScreen) { logger.LogDebug("\tLog A: " + logcounter++); if (!flag && Vector2.Distance(GC.cameraScript.containerTr.position, vector) > maxBulletDistance) { if (GC.activePooling) { __instance.bulletSprite.SetSprite(__instance.bulletSprite.GetSpriteIdByName("Clear")); } destroyMe_Base.GetMethodWithoutOverrides <Action>(__instance).Invoke(); return(false); } } else if (!flag) { logger.LogDebug("\tLog B: " + logcounter++); if (GC.coopMode) { if (Vector2.Distance(GC.cameraScriptS1.containerTr.position, vector) > maxBulletDistance && Vector2.Distance(GC.cameraScriptS2.containerTr.position, vector) > maxBulletDistance) { if (GC.activePooling) { __instance.bulletSprite.SetSprite(__instance.bulletSprite.GetSpriteIdByName("Clear")); } destroyMe_Base.GetMethodWithoutOverrides <Action>(__instance).Invoke(); return(false); } } else if (GC.fourPlayerMode && Vector2.Distance(GC.cameraScriptS1.containerTr.position, vector) > maxBulletDistance && Vector2.Distance(GC.cameraScriptS2.containerTr.position, vector) > maxBulletDistance && Vector2.Distance(GC.cameraScriptS3.containerTr.position, vector) > maxBulletDistance && Vector2.Distance(GC.cameraScriptS4.containerTr.position, vector) > maxBulletDistance) { if (GC.activePooling) { __instance.bulletSprite.SetSprite(__instance.bulletSprite.GetSpriteIdByName("Clear")); } destroyMe_Base.GetMethodWithoutOverrides <Action>(__instance).Invoke(); return(false); } } logger.LogDebug("\tLog: " + logcounter++); Vector3 position = new Vector3(vector.x, vector.y, -2f + (vector.y - 1.28f) * 100f / 100000f); ___bulletSpriteTr.position = position; __instance.timeSinceLaunch += Time.deltaTime; logger.LogDebug("\tLog: " + logcounter++); if (__instance.bulletType == bulletStatus.Fire || __instance.bulletType == bulletStatus.Water || __instance.bulletType == bulletStatus.Water2 || __instance.bulletType == bulletStatus.LeafBlower || __instance.bulletType == bulletStatus.ResearchGun || __instance.bulletType == bulletStatus.FireExtinguisher) { logger.LogDebug("\tLog C: " + logcounter++); float num = 0.4f; float num2 = 0.35f; if (__instance.bulletType == bulletStatus.ResearchGun) { num = 0.2f; num2 = 0.15f; } else if (__instance.bulletType == bulletStatus.Water2) { num = 0.6f; num2 = 0.55f; } logger.LogDebug("\tLog: " + logcounter++); if (__instance.timeSinceLaunch >= num2 && !__instance.bulletFireStopped) { logger.LogDebug("\tLog D: " + logcounter++); __instance.bulletFireStopped = true; if (__instance.particles != null) { __instance.particles.GetComponent <ParticleSystem>().Stop(); float num3 = __instance.myParticleScale; __instance.particles.transform.SetParent(GC.particleEffectsNest.transform); __instance.particles.transform.localScale = new Vector3(num3, num3, num3); return(false); } } else if (__instance.timeSinceLaunch >= num) { logger.LogDebug("\tLogE: " + logcounter++); __instance.DestroyMe(); return(false); } } else if (__instance.bulletType == bulletStatus.GhostBlaster) { try { __instance.tr.position = __instance.agent.tr.position; __instance.agent.gun.visibleTime = 4f; if ((!__instance.agent.localPlayer || __instance.agent.outOfControl) && !__instance.agent.objectAgent) { if (__instance.agent.isPlayer != 0 && __instance.agent.outOfControl) { __instance.movement.RotateToPositionOffsetTr(__instance.agent.opponent.tr.position); } else if (__instance.agent.isPlayer != 0) { Vector3 vector2 = __instance.agent.gun.holdAttackAimPoint - __instance.tr.position; vector2.Normalize(); float num4 = Mathf.Atan2(vector2.y, vector2.x) * 57.29578f; Quaternion b = Quaternion.Euler(0f, 0f, num4 - 90f); __instance.tr.rotation = Quaternion.Slerp(__instance.tr.rotation, b, Time.deltaTime * 15f); } else if (__instance.agent.oma.mindControlled) { __instance.movement.RotateToAngleTransform(__instance.agent.tr.eulerAngles.z - 90f); } else if (GC.serverPlayer) { __instance.movement.RotateToPositionOffsetTr(__instance.agent.opponent.tr.position); } else { __instance.movement.RotateToPositionOffsetTr(__instance.agent.melee.attackObject.tr.position); } } else if (__instance.agent.controllerType == "Keyboard") { if (GC.sessionDataBig.trackpadMode) { __instance.movement.RotateToAngleTransform(__instance.agent.tr.eulerAngles.z - 90f); } else { __instance.movement.RotateToMouseTr(__instance.agent.agentCamera.actualCamera); } } else if (__instance.agent.target.AttackTowardTarget()) { __instance.tr.rotation = Quaternion.Euler(0f, 0f, __instance.agent.target.transform.eulerAngles.z); } else { __instance.tr.rotation = Quaternion.Euler(0f, 0f, __instance.agent.gun.FindWeaponAngleGamepad() - 90f); } if (__instance.FindStoppingPoint() != Vector2.zero) { __instance.movement.MoveForwardTransform(__instance.stoppingPointDistance / 2f); __instance.tr.localScale = new Vector3(__instance.tr.localScale.x, __instance.stoppingPointDistance / 2f, __instance.tr.localScale.z); __instance.particles.GetComponent <ParticleSystem>().emissionRate = __instance.stoppingPointDistance * 150f; ParticleSystem.ShapeModule a = __instance.particles.GetComponent <ParticleSystem>().shape; a.length = __instance.stoppingPointDistance - 0.32f; } else { if ((!__instance.agent.localPlayer || __instance.agent.outOfControl) && !__instance.agent.objectAgent) { if (__instance.agent.isPlayer != 0 && __instance.agent.outOfControl) { __instance.movement.RotateToPositionOffsetTr(__instance.agent.opponent.tr.position); } else if (__instance.agent.isPlayer != 0) { Vector3 vector3 = __instance.agent.gun.holdAttackAimPoint - __instance.tr.position; vector3.Normalize(); float num5 = Mathf.Atan2(vector3.y, vector3.x) * 57.29578f; Quaternion b2 = Quaternion.Euler(0f, 0f, num5 - 90f); __instance.tr.rotation = Quaternion.Slerp(__instance.tr.rotation, b2, Time.deltaTime * 15f); } else if (__instance.agent.oma.mindControlled) { __instance.movement.RotateToAngleTransform(__instance.agent.tr.eulerAngles.z - 90f); } else if (GC.serverPlayer) { __instance.movement.RotateToPositionOffsetTr(__instance.agent.opponent.tr.position); } else { __instance.movement.RotateToPositionOffsetTr(__instance.agent.melee.attackObject.tr.position); } } else if (__instance.agent.controllerType == "Keyboard") { if (GC.sessionDataBig.trackpadMode) { __instance.movement.RotateToAngleTransform(__instance.agent.tr.eulerAngles.z - 90f); } else { __instance.movement.RotateToMouseTr(__instance.agent.agentCamera.actualCamera); } } else if (__instance.agent.target.AttackTowardTarget()) { __instance.tr.rotation = Quaternion.Euler(0f, 0f, __instance.agent.target.transform.eulerAngles.z); } else { __instance.tr.rotation = Quaternion.Euler(0f, 0f, __instance.agent.gun.FindWeaponAngleGamepad() - 90f); } __instance.movement.MoveForwardTransform(6.72f); __instance.tr.localScale = new Vector3(__instance.tr.localScale.x, 6.72f, __instance.tr.localScale.z); __instance.particles.GetComponent <ParticleSystem>().emissionRate = 2015.9999f; ParticleSystem.ShapeModule a = __instance.particles.GetComponent <ParticleSystem>().shape; a.length = 13.12f; } __instance.particles.transform.position = __instance.agent.tr.position; __instance.particles.transform.Translate(Vector3.forward * 0.32f, Space.Self); bool flag2 = false; __instance.timeToDamage += Time.deltaTime; if (__instance.timeToDamage >= 0.05f) { flag2 = true; __instance.timeToDamage = 0f; } if (GC.multiplayerMode && __instance.agent.isPlayer != 0) { __instance.timeToSendAimPoint += Time.deltaTime; if (__instance.timeToSendAimPoint >= 0.1f && (__instance.agent.isPlayer == 0 || __instance.agent.localPlayer) && (GC.serverPlayer || __instance.agent.isPlayer != 0)) { Vector3 v = Vector3.zero; if (__instance.agent.controllerType == "Keyboard") { if (GC.sessionDataBig.trackpadMode) { __instance.movement.RotateToAngleTransform(__instance.agent.tr.eulerAngles.z - 90f); __instance.dirHelper.localPosition = new Vector3(0f, 0.32f, 0f); v = __instance.dirHelper.position; } else { v = __instance.agent.agentCamera.actualCamera.ScreenCamera.ScreenToWorldPoint(Input.mousePosition); } } else if (__instance.agent.target.AttackTowardTarget()) { v = __instance.agent.target.tr.position; } else { __instance.tr.rotation = Quaternion.Euler(0f, 0f, __instance.agent.gun.FindWeaponAngleGamepad() - 90f); __instance.dirHelper.localPosition = new Vector3(0f, 0.32f, 0f); v = __instance.dirHelper.position; } __instance.agent.objectMult.SendHoldAttackAimPoint(v); __instance.timeToSendAimPoint = 0f; } } if (__instance.stoppingPointObject != null && flag2) { __instance.RayHit(__instance.stoppingPointObject); } if (__instance.timeSinceLaunch >= 0.1f && (__instance.agent.isPlayer == 0 || __instance.agent.localPlayer) && (GC.serverPlayer || __instance.agent.isPlayer != 0)) { __instance.bulletFireStopped = true; __instance.agent.objectMult.StopHoldAttack(); __instance.DestroyMe(); } if (__instance.agent.gun.stopHoldAttack) { GC.audioHandler.Fade(__instance.agent, "GhostGibberFire"); GC.audioHandler.Fade(__instance.agent, "GhostGibberLoop"); __instance.agent.gun.stopHoldAttack = false; __instance.bulletFireStopped = true; __instance.timeSinceLaunch = 0f; __instance.timeToSendAimPoint = 0f; __instance.DestroyMe(); } } catch { Debug.LogError("Ghost Gibber Error"); __instance.DestroyMe(); } } } return(false); }
private DynamicMethodDefinition CreateIl2CppShim(MethodInfo patch) { string patchName = patch.Name + "_il2cpp"; ParameterInfo[] patchParams = patch.GetParameters(); Type[] patchParamTypes = patchParams.Types().ToArray(); Type[] il2cppParamTypes = patchParamTypes.Select(Il2CppTypeForPatchType).ToArray(); Type patchReturnType = AccessTools.GetReturnedType(patch); Type il2cppReturnType = Il2CppTypeForPatchType(patchReturnType); var method = new DynamicMethodDefinition(patchName, il2cppReturnType, il2cppParamTypes); var il = method.GetILGenerator(); LocalBuilder returnLocal = null; if (patchReturnType != typeof(void)) { returnLocal = il.DeclareLocal(patchReturnType); LogLocalVariable(il, returnLocal); } Type exceptionType = typeof(Exception); LocalBuilder exceptionLocal = il.DeclareLocal(exceptionType); LogLocalVariable(il, exceptionLocal); // Start a try-block for the call to the original patch il.BeginExceptionBlock(); // Load arguments, invoking the IntPrt -> Il2CppObject constructor for IL2CPP types LocalBuilder[] byRefValues = new LocalBuilder[patchParams.Length]; for (int i = 0; i < patchParamTypes.Length; ++i) { il.Emit(OpCodes.Ldarg, i); ConvertArgument(il, patchParamTypes[i], ref byRefValues[i]); if (byRefValues[i] != null) { LogLocalVariable(il, byRefValues[i]); } } // Call the original patch with the now-correct types il.Emit(OpCodes.Call, patch); // Store the result, if any if (returnLocal != null) { il.Emit(OpCodes.Stloc, returnLocal); } // Catch any exceptions that may have been thrown il.BeginCatchBlock(exceptionType); // MelonLogger.LogError("Exception in ...\n" + exception.ToString()); il.Emit(OpCodes.Stloc, exceptionLocal); il.Emit(OpCodes.Ldstr, $"Exception in Harmony patch of method {Original.FullDescription()}:\n"); il.Emit(OpCodes.Ldloc, exceptionLocal); il.Emit(OpCodes.Call, AccessTools.DeclaredMethod(typeof(Exception), "ToString", new Type[0])); il.Emit(OpCodes.Call, AccessTools.DeclaredMethod(typeof(string), "Concat", new Type[] { typeof(string), typeof(string) })); il.Emit(OpCodes.Call, AccessTools.DeclaredMethod(typeof(MelonLogger), "Error", new Type[] { typeof(string) })); // Close the exception block il.EndExceptionBlock(); // Write back the pointers of ref arguments for (var i = 0; i < patchParamTypes.Length; ++i) { if (byRefValues[i] == null) { continue; } il.Emit(OpCodes.Ldarg_S, i); il.Emit(OpCodes.Ldloc, byRefValues[i]); ConvertTypeToIl2Cpp(il, patchParamTypes[i].GetElementType()); il.Emit(OpCodes.Stind_I); } // Load the return value, if any, and unwrap it if required if (returnLocal != null) { il.Emit(OpCodes.Ldloc, returnLocal); ConvertTypeToIl2Cpp(il, patchReturnType); } il.Emit(OpCodes.Ret); return(method); }
public static void Patch(Harmony harmony) { harmony.Patch( AccessTools.DeclaredMethod(typeof(WidgetPrefab), nameof(WidgetPrefab.LoadFrom)), transpiler: new HarmonyMethod(AccessTools.DeclaredMethod(typeof(WidgetPrefabPatch), nameof(WidgetPrefab_LoadFrom_Transpiler)))); }
internal static void InitializePatch(IPlatoHelper helper) { Plato = helper; if (_patched) { return; } _patched = true; var questionRaised = AccessTools.DeclaredConstructor(typeof(DialogueBox), new Type[] { typeof(string), typeof(List <Response>), typeof(int) }); List <Type> questionLocationTypes = new List <Type>() { typeof(GameLocation), typeof(BusStop), typeof(Desert), typeof(JojaMart) }; var channelSelected = AccessTools.DeclaredMethod(typeof(TV), "selectChannel"); var tvAction = AccessTools.DeclaredMethod(typeof(TV), "checkForAction"); List <MethodInfo> questionAsked = new List <MethodInfo>(questionLocationTypes.Select(t => AccessTools.Method(t, "answerDialogue"))); var performTouchAction = new[] { AccessTools.DeclaredMethod(typeof(GameLocation), "performTouchAction"), AccessTools.DeclaredMethod(typeof(MovieTheater), "performTouchAction"), AccessTools.DeclaredMethod(typeof(Desert), "performTouchAction") }; var performAction = new[] { AccessTools.DeclaredMethod(typeof(GameLocation), "performAction"), AccessTools.DeclaredMethod(typeof(MovieTheater), "performAction"), AccessTools.DeclaredMethod(typeof(CommunityCenter), "performAction"), AccessTools.DeclaredMethod(typeof(FarmHouse), "performAction"), AccessTools.DeclaredMethod(typeof(ManorHouse), "performAction"), AccessTools.DeclaredMethod(typeof(LibraryMuseum), "performAction"), AccessTools.DeclaredMethod(typeof(Town), "performAction"), }; var harmony = new Harmony($"Plato.QuestionPatches"); harmony.Patch(questionRaised, prefix: new HarmonyMethod(AccessTools.Method(typeof(EventPatches), nameof(DialogueBox)))); foreach (var method in questionAsked) { harmony.Patch(method, prefix: new HarmonyMethod( AccessTools.DeclaredMethod(typeof(EventPatches), nameof(QuestionAsked), null, new Type[] { method.DeclaringType }))); } harmony.Patch(channelSelected, prefix: new HarmonyMethod(AccessTools.Method(typeof(EventPatches), nameof(SelectChannel)))); harmony.Patch(tvAction, prefix: new HarmonyMethod(AccessTools.Method(typeof(EventPatches), nameof(SetIsTv)))); harmony.Patch(tvAction, postfix: new HarmonyMethod(AccessTools.Method(typeof(EventPatches), nameof(UnsetIsTV)))); harmony.Patch(AccessTools.Method(typeof(Event), nameof(Event.tryEventCommand)), new HarmonyMethod(typeof(EventPatches), nameof(TryEventCommandPre))); harmony.Patch(AccessTools.Method(typeof(Event), nameof(Event.tryEventCommand)), null, new HarmonyMethod(typeof(EventPatches), nameof(TryEventCommandPost))); foreach (var ta in performTouchAction) { harmony.Patch(ta, prefix: new HarmonyMethod(AccessTools.Method(typeof(EventPatches), nameof(PerformTouchAction)))); } foreach (var a in performAction) { harmony.Patch(a, prefix: new HarmonyMethod(AccessTools.Method(typeof(EventPatches), nameof(PerformAction)))); } var checkEventPreconditions = AccessTools.Method(typeof(GameLocation), "checkEventPrecondition"); harmony.Patch(checkEventPreconditions, prefix: new HarmonyMethod(typeof(EventPatches), nameof(CheckEventConditions))); }
static MethodBase TargetMethod() => AccessTools.DeclaredMethod(PuahCompHauledToInventoryType, "RegisterHauledItem");
static MethodBase TargetMethod() => AccessTools.DeclaredMethod(PuahWorkGiver_HaulToInventoryType, "TryFindBestBetterStoreCellFor");
static MethodBase TargetMethod() => AccessTools.DeclaredMethod(PuahJobDriver_UnloadYourHauledInventoryType, "MakeNewToils");
// always use DeclaredMethod (explicit) static MethodBase TargetMethod() => AccessTools.DeclaredMethod(typeof(JobDriver), nameof(JobDriver.GetReport));
static MethodBase TargetMethod() => AccessTools.DeclaredMethod(PuahJobDriver_UnloadYourHauledInventoryType, "FirstUnloadableThing");
static IEnumerable <CodeInstruction> _UseTryFindBestBetterStoreCellFor_ClosestToDestCell(IEnumerable <CodeInstruction> instructions) { return(instructions.MethodReplacer( AccessTools.DeclaredMethod(typeof(StoreUtility), nameof(StoreUtility.TryFindBestBetterStoreCellFor)), AccessTools.DeclaredMethod(typeof(WorkGiver_HaulToInventory_JobOnThing_Patch), nameof(UseTryFindBestBetterStoreCellFor_ClosestToDestCell)))); }
public static RectTransform Checkbox(RectTransform parent) { GameObject obj = new GameObject("ToyBox.Checkbox"); RectTransform transform = obj.AddComponent <RectTransform>(); transform.SetParent(parent, false); transform.anchorMin = new Vector2(0.0f, 0.0f); transform.anchorMax = new Vector2(1.0f, 1.0f); transform.pivot = new Vector2(0.5f, 0.5f); transform.offsetMin = new Vector2(0.0f, 0.0f); transform.offsetMax = new Vector2(0.0f, 0.0f); HorizontalLayoutGroupWorkaround group = obj.AddComponent <HorizontalLayoutGroupWorkaround>(); group.SetLayoutHorizontal(); group.childControlWidth = true; group.childControlHeight = true; group.childForceExpandWidth = false; group.childForceExpandHeight = false; group.childScaleWidth = false; group.childScaleHeight = false; group.childAlignment = TextAnchor.UpperLeft; group.spacing = DefaultSpacing; group.padding = DefaultPadding; LayoutElement layout = obj.AddComponent <LayoutElement>(); layout.minWidth = 32.0f; layout.minHeight = 32.0f; layout.preferredWidth = -1.0f; layout.preferredHeight = -1.0f; layout.flexibleWidth = 0.0f; layout.flexibleHeight = 0.0f; OwlcatMultiButton button = obj.AddComponent <OwlcatMultiButton>(); button.ClickSoundType = -1; //button.HoverSoundType = 1; // background GameObject background_obj = new GameObject("ToyBox.Checkbox.Background"); RectTransform background_transform = background_obj.AddComponent <RectTransform>(); background_transform.SetParent(transform, false); background_transform.anchorMin = new Vector2(0.0f, 0.0f); background_transform.anchorMax = new Vector2(1.0f, 1.0f); background_transform.pivot = new Vector2(0.5f, 0.5f); background_transform.offsetMin = new Vector2(0.0f, 0.0f); background_transform.offsetMax = new Vector2(0.0f, 0.0f); HorizontalLayoutGroupWorkaround background_group = background_obj.AddComponent <HorizontalLayoutGroupWorkaround>(); background_group.SetLayoutHorizontal(); background_group.childControlWidth = true; background_group.childControlHeight = true; background_group.childForceExpandWidth = false; background_group.childForceExpandHeight = false; background_group.childScaleWidth = false; background_group.childScaleHeight = false; background_group.childAlignment = TextAnchor.UpperLeft; background_group.spacing = DefaultSpacing; background_group.padding = new RectOffset( (int)(layout.minWidth * 0.2f), (int)(layout.minHeight * 0.2f), (int)(layout.minWidth * 0.2f), (int)(layout.minHeight * 0.2f) ); LayoutElement background_layout = background_obj.AddComponent <LayoutElement>(); background_layout.minWidth = -1.0f; background_layout.minHeight = -1.0f; background_layout.preferredWidth = -1.0f; background_layout.preferredHeight = -1.0f; background_layout.flexibleWidth = 0.0f; background_layout.flexibleHeight = 0.0f; CanvasRenderer background_renderer = background_obj.AddComponent <CanvasRenderer>(); Image background_image = background_obj.AddComponent <Image>(); background_image.sprite = crUI.CheckboxBackgroundImage?.sprite; // checkmark GameObject checkmark_obj = new GameObject("ToyBox.Checkbox.Checkmark"); RectTransform checkmark_transform = checkmark_obj.AddComponent <RectTransform>(); checkmark_transform.SetParent(background_transform, false); checkmark_transform.anchorMin = new Vector2(0.0f, 0.0f); checkmark_transform.anchorMax = new Vector2(1.0f, 1.0f); checkmark_transform.pivot = new Vector2(0.5f, 0.5f); checkmark_transform.offsetMin = new Vector2(0.0f, 0.0f); checkmark_transform.offsetMax = new Vector2(0.0f, 0.0f); LayoutElement checkmark_layout = checkmark_obj.AddComponent <LayoutElement>(); checkmark_layout.minWidth = -1.0f; checkmark_layout.minHeight = -1.0f; checkmark_layout.preferredWidth = -1.0f; checkmark_layout.preferredHeight = -1.0f; checkmark_layout.flexibleWidth = 1.0f; checkmark_layout.flexibleHeight = 1.0f; CanvasRenderer checkmark_renderer = checkmark_obj.AddComponent <CanvasRenderer>(); Image checkmark_image = checkmark_obj.AddComponent <Image>(); checkmark_image.sprite = crUI.CheckboxCheckmarkImage?.sprite; SpriteState sprite_state = crUI.CheckboxLayerParts[0].SpriteState; OwlcatSelectableLayerPart layer0 = new OwlcatSelectableLayerPart(); layer0.Image = background_image; layer0.Transition = OwlcatTransition.SpriteSwap; layer0.SpriteState = sprite_state; button.AddLayerToMainPart(layer0); button.AddMultiLayer(); button.AddMultiLayer(); List <OwlcatMultiLayer> layers = AccessTools.DeclaredField(typeof(OwlcatMultiSelectable), "m_MultiLayers") .GetValue(button) as List <OwlcatMultiLayer>; layers[0].LayerName = "Unchecked"; OwlcatMultiLayer layer1 = layers[1]; layer1.LayerName = "Checked"; layer1.AddPart(); layer1.Parts[0].Transition = OwlcatTransition.Activate; AccessTools.DeclaredField(typeof(OwlcatSelectableLayerPart), "m_TargetGameObject") .SetValue(layer1.Parts[0], checkmark_obj); AccessTools.DeclaredMethod(typeof(OwlcatMultiSelectable), "DoSetLayers").Invoke(button, new object[] {}); Button.ButtonClickedEvent evt = AccessTools .DeclaredField(typeof(OwlcatMultiButton), "m_OnLeftClick").GetValue(button) as Button.ButtonClickedEvent; evt.AddListener(() => { List <OwlcatMultiLayer> layers = AccessTools.DeclaredField(typeof(OwlcatMultiSelectable), "m_MultiLayers") .GetValue(button) as List <OwlcatMultiLayer>; button.SetActiveLayer((button.ActiveLayerIndex + 1) % layers.Count); }); return(transform); }
public static IEnumerable <CodeInstruction> BuildingDecorationLoadPathsTranspiler <TypeExtension>(IEnumerable <CodeInstruction> instructions) where TypeExtension : IBaseNetAssetDataExtension { var segmentBufferField = AccessTools.DeclaredField(typeof(NetManager), nameof(NetManager.m_tempSegmentBuffer)); var nodeBufferField = AccessTools.DeclaredField(typeof(NetManager), nameof(NetManager.m_tempNodeBuffer)); var clearMethod = AccessTools.DeclaredMethod(nodeBufferField.FieldType, nameof(FastList <ushort> .Clear)); var matchCount = 0; var inserted = false; var enumerator = instructions.GetEnumerator(); var prevPrevInstruction = (CodeInstruction)null; var prevInstruction = (CodeInstruction)null; while (enumerator.MoveNext()) { var instruction = enumerator.Current; if (prevInstruction != null && prevInstruction.opcode == OpCodes.Ldfld && prevInstruction.operand == nodeBufferField && instruction.opcode == OpCodes.Callvirt && instruction.operand == clearMethod) { matchCount += 1; } if (!inserted && matchCount == 2) { yield return(new CodeInstruction(OpCodes.Call, AccessTools.PropertyGetter(typeof(SingletonItem <TypeExtension>), nameof(SingletonItem <TypeExtension> .Instance)))); yield return(new CodeInstruction(OpCodes.Box, typeof(TypeExtension))); yield return(new CodeInstruction(OpCodes.Ldarg_0)); yield return(new CodeInstruction(OpCodes.Ldloc_0)); yield return(new CodeInstruction(OpCodes.Ldfld, segmentBufferField)); yield return(new CodeInstruction(OpCodes.Ldloc_0)); yield return(new CodeInstruction(OpCodes.Ldfld, nodeBufferField)); yield return(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(TypeExtension), nameof(IBaseNetAssetDataExtension.OnPlaceAsset)))); inserted = true; } if (prevPrevInstruction != null) { yield return(prevPrevInstruction); } prevPrevInstruction = prevInstruction; prevInstruction = instruction; } if (prevPrevInstruction != null) { yield return(prevPrevInstruction); } if (prevInstruction != null) { yield return(prevInstruction); } }
static IEnumerable <CodeInstruction> UsePuahHasJobOnThing_HasStore(IEnumerable <CodeInstruction> instructions) { return(instructions.MethodReplacer( AccessTools.DeclaredMethod(typeof(StoreUtility), nameof(StoreUtility.TryFindBestBetterStoreCellFor)), AccessTools.DeclaredMethod(typeof(JooStoreUtility), nameof(JooStoreUtility.PuahHasJobOnThing_HasStore)))); }
private static void DoPatch() { HarmonyInstance harmony = HarmonyInstance.Create("zaneyork.CustomLocalization"); harmony.Patch( original: AccessTools.DeclaredMethod(typeof(TitleContainer), "OpenStream"), prefix: new HarmonyMethod(typeof(TitleContainerRewrites.OpenStreamRewrite), nameof(TitleContainerRewrites.OpenStreamRewrite.Prefix)) ); harmony.Patch( original: AccessTools.DeclaredMethod(typeof(StartupPreferences), "readSettings"), postfix: new HarmonyMethod(typeof(StartupPreferencesRewrites.ReadSettingsRewrite), nameof(StartupPreferencesRewrites.ReadSettingsRewrite.Postfix)) ); harmony.Patch( original: AccessTools.DeclaredMethod(typeof(StartupPreferences), "writeSettings"), prefix: new HarmonyMethod(typeof(StartupPreferencesRewrites.WriteSettingsRewrite), nameof(StartupPreferencesRewrites.WriteSettingsRewrite.Prefix)), postfix: new HarmonyMethod(typeof(StartupPreferencesRewrites.WriteSettingsRewrite), nameof(StartupPreferencesRewrites.WriteSettingsRewrite.Postfix)) ); harmony.Patch( original: AccessTools.DeclaredMethod(typeof(StartupPreferences), "writeSettings"), prefix: new HarmonyMethod(typeof(StartupPreferencesRewrites.WriteSettingsRewrite), nameof(StartupPreferencesRewrites.WriteSettingsRewrite.Prefix)), postfix: new HarmonyMethod(typeof(StartupPreferencesRewrites.WriteSettingsRewrite), nameof(StartupPreferencesRewrites.WriteSettingsRewrite.Postfix)) ); harmony.Patch( original: AccessTools.DeclaredMethod(typeof(SpriteText), "OnLanguageChange"), prefix: new HarmonyMethod(typeof(SpriteTextRewrites.OnLanguageChangeRewrite), nameof(SpriteTextRewrites.OnLanguageChangeRewrite.Prefix)) ); harmony.Patch( original: AccessTools.DeclaredMethod(typeof(SpriteText), "setUpCharacterMap"), prefix: new HarmonyMethod(typeof(SpriteTextRewrites.SetUpCharacterMapRewrite), nameof(SpriteTextRewrites.SetUpCharacterMapRewrite.Prefix)) ); harmony.Patch( original: AccessTools.DeclaredMethod(typeof(LocalizedContentManager), "LanguageCodeString"), prefix: new HarmonyMethod(typeof(LocalizedContentManagerRewrites.LanguageCodeStringRewrite), nameof(LocalizedContentManagerRewrites.LanguageCodeStringRewrite.Prefix)) ); harmony.Patch( original: AccessTools.DeclaredProperty(typeof(LocalizedContentManager), "CurrentLanguageLatin").GetMethod, prefix: new HarmonyMethod(typeof(LocalizedContentManagerRewrites.GetCurrentLanguageLatinRewrite), nameof(LocalizedContentManagerRewrites.GetCurrentLanguageLatinRewrite.Prefix)) ); Type mobileMenuType = AccessTools.TypeByName("StardewValley.Menus.LanguageSelectionMobile"); if (mobileMenuType != null) { harmony.Patch( original: AccessTools.DeclaredMethod(mobileMenuType, "draw", new Type[] { typeof(SpriteBatch) }), prefix: new HarmonyMethod(typeof(LanguageSelectionMobileRewrites.DrawRewrite), nameof(LanguageSelectionMobileRewrites.DrawRewrite.Prefix)) ); harmony.Patch( original: AccessTools.DeclaredMethod(mobileMenuType, "releaseLeftClick"), prefix: new HarmonyMethod(typeof(LanguageSelectionMobileRewrites.ReleaseLeftClickRewrite), nameof(LanguageSelectionMobileRewrites.ReleaseLeftClickRewrite.Prefix)) ); harmony.Patch( original: AccessTools.DeclaredMethod(mobileMenuType, "setCurrentItemIndex"), prefix: new HarmonyMethod(typeof(LanguageSelectionMobileRewrites.SetCurrentItemIndexRewrite), nameof(LanguageSelectionMobileRewrites.SetCurrentItemIndexRewrite.Prefix)) ); harmony.Patch( original: AccessTools.DeclaredMethod(mobileMenuType, "SetupButtons"), transpiler: new HarmonyMethod(typeof(LanguageSelectionMobileRewrites.SetupButtonsRewrite), nameof(LanguageSelectionMobileRewrites.SetupButtonsRewrite.Transpiler)) ); } }
static MethodBase TargetMethod() => AccessTools.DeclaredMethod(PuahWorkGiver_HaulToInventoryType, "JobOnThing");
static bool Prepare() { if (ModsConfig.ActiveModsInLoadOrder.Any(m => m.Name == "Quick Stockpile Creation")) { BufferStockpileGizmo.Smartstockpilegizmotype = AccessTools.TypeByName("SmartStockpileCreation.RimObjs.SmartStockpile.SmartStockpileGizmo"); BufferStockpileDesignator.SmartStockpileDesignatortype = AccessTools.TypeByName("SmartStockpileCreation.RimObjs.SmartStockpile.SmartStockpileDesignator"); BufferStockpileDesignator.makeNewZone = AccessTools.MethodDelegate <Func <Designator_ZoneAddStockpile, Zone> >(AccessTools.DeclaredMethod(BufferStockpileDesignator.SmartStockpileDesignatortype, "MakeNewZone")); BufferStockpileDesignator.finalizeDesignationSucceeded = AccessTools.MethodDelegate <Action <Designator_ZoneAddStockpile> >(AccessTools.DeclaredMethod(BufferStockpileDesignator.SmartStockpileDesignatortype, "FinalizeDesignationSucceeded")); return(true); } else { return(false); } }
// Non-Patch private static IEnumerator AddPointsLate_Enumerator(string pointsType, int extraNum, SkillPoints __instance, Agent ___agent) { logger.LogDebug("SkillPoints_AddPointsLate_IEnumerator:"); logger.LogDebug("\tpointsType = " + pointsType); logger.LogDebug("\textraNum = " + extraNum); if (pointsType == "DestructionPoints" || pointsType == "DestructionPoints2" || pointsType == "FireExtinguishPoints") { yield return(null); } else { yield return(new WaitForSeconds(0.3f)); } if (Time.timeScale == 0f && !GC.multiplayerMode) { while (Time.timeScale == 0f) { yield return(null); } yield return(new WaitForSeconds(0.2f)); } int xpReward = 0; bool suppressAnimation = false; string text = pointsType; switch (text) { case "ArrestedPoints": xpReward = 100; break; case "ArrestedPointsInnocent": if (___agent.statusEffects.hasTrait(vTrait.TheLaw) && !___agent.oma.superSpecialAbility || ___agent.HasTrait <VeryHardOnYourself>()) // TODO is new { if (___agent.statusEffects.hasTrait(vTrait.Crooked)) { xpReward = 0; } else if (___agent.statusEffects.hasTrait(vTrait.Crooked2)) { xpReward = -40; } else { xpReward = -80; } } else { xpReward = 10; } break; case "BigQuestBonusDowntown": xpReward = 500; break; case "BigQuestBonusFloor": xpReward = 300; break; case "BigQuestBonusGame": xpReward = 1000; break; case "BigQuestBonusIndustrial": xpReward = 500; break; case "BigQuestBonusPark": xpReward = 500; break; case "BigQuestBonusSlums": xpReward = 500; break; case "BigQuestBonusUptown": xpReward = 500; break; case cSkillPoints.BQMalusDowntown: // TODO is new xpReward = -500; break; case cSkillPoints.BQMalusFloor: // TODO is new xpReward = 300; break; case cSkillPoints.BQMalusGame: // TODO is new xpReward = -1000; break; case cSkillPoints.BQMalusIndustrial: // TODO is new xpReward = -500; break; case cSkillPoints.BQMalusPark: // TODO is new xpReward = -500; break; case cSkillPoints.BQMalusSlums: // TODO is new xpReward = -500; break; case cSkillPoints.BQMalusUptown: // TODO is new xpReward = -500; break; case "CompleteMission": xpReward = 300; if (GC.challenges.Contains(cChallenge.UnpaidInternship)) // TODO is new { xpReward *= 2; } break; case "CompleteMissionFindBombs": xpReward = 700; break; case "CompleteMissionReduced": xpReward = 150; if (GC.challenges.Contains(cChallenge.UnpaidInternship)) // TODO is new { xpReward *= 2; } break; case "Destruction": xpReward = 200; break; case "DestructionPoints": xpReward = 1; suppressAnimation = true; break; case "DestructionPoints2": xpReward = 2; suppressAnimation = true; break; case "DisarmDetonatorPoints": xpReward = 20; break; case "ElectabilityBonus": xpReward = 100; break; case cSkillPoints.ElectabilityMalus: // TODO is new xpReward = -100; break; case "Enslaved": xpReward = 30; break; case "FindTreasure": xpReward = 100; GC.stats.AddToStat(___agent, "TreasuresFound", 1); break; case "FireExtinguishPoints": xpReward = 5; suppressAnimation = true; break; case "FreedPrisoner": xpReward = 20 * extraNum; if (extraNum > 1) { pointsType = "FreedPrisoners"; } break; case "FreedSlave": xpReward = 50 * extraNum; if (extraNum > 1) { pointsType = "FreedSlaves"; } break; case cSkillPoints.FreePrisonerFailure: // TODO is new xpReward = -50 * extraNum; break; case "HackPoints": xpReward = 20; break; case "IndirectlyKill": xpReward = 30; break; case "IndirectlyKillInnocent": if ((___agent.statusEffects.hasTrait(vTrait.TheLaw) && !___agent.oma.superSpecialAbility) || ___agent.HasTrait <VeryHardOnYourself>()) // TODO is new { if (___agent.statusEffects.hasTrait(vTrait.Crooked)) { xpReward = 0; } else if (___agent.statusEffects.hasTrait(vTrait.Crooked2)) { xpReward = -15; } else { xpReward = -30; } } else { xpReward = 10; } break; case "IndirectlyKillRival": xpReward = 90; break; case "Joke": xpReward = 30 * extraNum; break; case "KilledRobot": xpReward = 1000; break; case "KillPoints": xpReward = 50; break; case "KillPointsInnocent": if ((___agent.statusEffects.hasTrait(vTrait.TheLaw) && !___agent.oma.superSpecialAbility) || ___agent.HasTrait <VeryHardOnYourself>()) // TODO is new { if (___agent.statusEffects.hasTrait(vTrait.Crooked2)) { xpReward = 0; } else if (___agent.statusEffects.hasTrait(vTrait.Crooked)) { xpReward = -20; } else if (!___agent.oma.superSpecialAbility) { xpReward = -40; } } else { xpReward = 10; } break; case "KillPointsRival": xpReward = 150; break; case "KnockOutPoints": xpReward = 75; break; case "KnockOutPointsInnocent": if ((___agent.statusEffects.hasTrait(vTrait.TheLaw) && !___agent.oma.superSpecialAbility) || ___agent.HasTrait <VeryHardOnYourself>()) // TODO is new { if (___agent.statusEffects.hasTrait(vTrait.Crooked)) { xpReward = 0; } else if (___agent.statusEffects.hasTrait(vTrait.Crooked2)) { xpReward = -20; } else { xpReward = -40; } } else { xpReward = 10; } break; case "KnockOutPointsRival": xpReward = 150; break; case "LockpickPoints": xpReward = 20; break; case "ManySleeping": xpReward = 100; break; case "Massacre": xpReward = 100; break; case "NoAngerLevel": xpReward = 100; break; case cSkillPoints.AngeredMany: // TODO is new xpReward *= -100; // TODO '*' by mistake? break; case "NoDamageTaken": xpReward = 100; break; case cSkillPoints.TookLotsOfDamage: // TODO is new xpReward = 100; break; case "NoDestruction": xpReward = 200; break; case "NoGuns": xpReward = 200; break; case "NoKillBonus": xpReward = 100; break; case "NoKillLevel": xpReward = 100; break; case "NotAlertedBonus": xpReward = 100; break; case "OnlyFists": xpReward = 200; break; case "PickpocketPoints": if ((___agent.statusEffects.hasTrait(vTrait.TheLaw) && !___agent.oma.superSpecialAbility && !___agent.statusEffects.hasTrait(vTrait.PromiseIllReturnIt)) || ___agent.HasTrait <VeryHardOnYourself>()) // TODO is new { if (___agent.statusEffects.hasTrait(vTrait.Crooked)) { xpReward = 0; } else if (___agent.statusEffects.hasTrait(vTrait.Crooked2)) { xpReward = -10; } else { xpReward = -15; } } else { xpReward = 15; } break; case "PoisonAirPoints": xpReward = 20; break; case "RemoveSlaveHelmetPoints": xpReward = 20; break; case "RemoveWindowPoints": xpReward = 20; break; case "ShakedownFailPoints": xpReward = -100; break; case "ShakedownPoints": xpReward = 100; break; case "StealPoints": xpReward = extraNum * 10; break; case "StealPointsNegative": xpReward = extraNum * 10; if ((___agent.statusEffects.hasTrait(vTrait.TheLaw) && !___agent.oma.superSpecialAbility && !___agent.statusEffects.hasTrait(vTrait.PromiseIllReturnIt)) || ___agent.HasTrait <VeryHardOnYourself>()) // TODO is new { xpReward *= -1; if (___agent.statusEffects.hasTrait(vTrait.Crooked)) { xpReward /= 2; } else if (___agent.statusEffects.hasTrait(vTrait.Crooked2)) { xpReward = 0; } } break; case "StoleLots": xpReward = 200; break; case "TamperGeneratorPoints": xpReward = 20; break; case "TamperLaserEmitterPoints": xpReward = 20; break; case "TamperPoliceBoxPoints": xpReward = 20; break; case "TamperSatelliteDishPoints": xpReward = 20; break; case "TimeBonus": xpReward = 100; break; case "TwoPlayerWinner1": xpReward = 200; break; case "TwoPlayerWinner2": xpReward = 200; break; case "UnlockSafePoints": xpReward = 20; break; case "WonElectionPoints": xpReward = 100; // TODO missing a '0' here? break; } if (xpReward != 0) { float xpModifier = 1.00f; if (___agent.HasTrait <SmoothBrained>()) // TODO is new { xpModifier = 0.00f; } else if (xpReward > 0) { if (___agent.statusEffects.hasTrait(vTrait.Studious)) { xpModifier = 1.30f; } else if (___agent.statusEffects.hasTrait(vTrait.SuperStudious)) { xpModifier = 1.50f; } else if (___agent.HasTrait <DimBulb>()) // TODO is new { xpModifier = 0.75f; } else if (___agent.HasTrait <MoronTheMerrier>()) // TODO is new { xpModifier = 0.50f; } else if (___agent.HasTrait <Brainiac>()) // TODO is new { xpModifier = 4.00f; } } else if (___agent.HasTrait <VeryHardOnYourself>()) // TODO is new { xpModifier = 2.00f; } xpReward = (int)(xpReward * xpModifier); float floorXpAcceleration = 0.075f; int cityFloor = Mathf.Clamp(GC.sessionDataBig.curLevelEndless, 1, 16); if (GC.sessionDataBig.challenges.Contains("QuickGame")) { floorXpAcceleration = 0.1125f; cityFloor = Mathf.Clamp(GC.sessionDataBig.curLevelEndless, 1, 11); } xpReward = (int)(xpReward * (1f + (cityFloor - 1) * floorXpAcceleration)); GC.sessionData.skillPoints[___agent.isPlayer] += xpReward; Color32 myColor; if (xpReward < 0) { myColor = new Color32(byte.MaxValue, 0, 0, byte.MaxValue); if (GC.sessionData.skillPoints[___agent.isPlayer] < __instance.findLevelThreshold(GC.sessionData.skillLevel[___agent.isPlayer] - 1)) { GC.sessionData.skillPoints[___agent.isPlayer] = __instance.findLevelThreshold(GC.sessionData.skillLevel[___agent.isPlayer] - 1); } } else { myColor = new Color32(byte.MaxValue, 216, 0, byte.MaxValue); } if (GC.sessionData.skillPoints[___agent.isPlayer] >= __instance.findLevelThreshold(GC.sessionData.skillLevel[___agent.isPlayer])) { GC.audioHandler.Play(___agent, "LevelUp"); if (___agent.isPlayer == 1) { GC.alienFX.GainLevel(); } GC.sessionData.skillLevel[___agent.isPlayer]++; __instance.levelsGained++; GC.sessionData.levelsGained[___agent.isPlayer]++; __instance.justGainedLevel = true; //__instance.StartCoroutine(__instance.CancelJustGainedLevel()); // Original Private Method Inaccessible // TODO this is a Coroutine, you'll have to StartCoroutine it. - although that doesn't really matter since this will be replaced with a transpiler MethodInfo CancelJustGainedLevel = AccessTools.DeclaredMethod(typeof(SkillPoints), "CancelJustGainedLevel"); CancelJustGainedLevel.GetMethodWithoutOverrides <Action>(__instance).Invoke(); if (GC.unlocks.CanDoUnlocks()) { if (___agent.statusEffects.hasTrait(vTrait.SuperStudious)) { GC.unlocks.AddNuggets(2); GC.spawnerMain.SpawnStatusText(___agent, "ItemPickupSlower", "Nuggets", "Item", "Add2Nuggets", ""); } else { GC.unlocks.AddNuggets(3); GC.spawnerMain.SpawnStatusText(___agent, "ItemPickupSlower", "Nuggets", "Item", "Add3Nuggets", ""); } } ___agent.objectMult.SendChatAnnouncement("LevelUp", GC.sessionData.skillLevel[___agent.isPlayer].ToString(), ""); if (___agent.localPlayer) { ___agent.skillBar.dTr.localScale = new Vector3(0f, ___agent.skillBar.dTr.localScale.y, ___agent.skillBar.dTr.localScale.z); } if (!___agent.finishedLevel) { GC.spawnerMain.SpawnStatusText(___agent, "LevelUp", "LevelUp", "Interface"); } if (___agent.statusEffects.hasTrait(vTrait.PotentialtoNotSuck)) { Agent agent = ___agent; if (___agent.possessing || ___agent.transforming) { if (!GC.multiplayerMode) { if (___agent.isPlayer == 1) { agent = GC.backupAgent1; } if (___agent.isPlayer == 2) { agent = GC.backupAgent2; } if (___agent.isPlayer == 3) { agent = GC.backupAgent3; } if (___agent.isPlayer == 4) { agent = GC.backupAgent4; } } else { if (___agent.playerColor == 1) { agent = GC.backupAgent1; } if (___agent.playerColor == 2) { agent = GC.backupAgent2; } if (___agent.playerColor == 3) { agent = GC.backupAgent3; } if (___agent.playerColor == 4) { agent = GC.backupAgent4; } } } if (GC.sessionData.skillLevel[___agent.isPlayer] % 2 == 0 && (agent.strengthStatMod != 3 || agent.enduranceStatMod != 3 || agent.accuracyStatMod != 3 || agent.speedStatMod != 3)) { string randStatMod; bool bonusStat; do { randStatMod = GC.Choose("Strength", "Endurance", "Accuracy", "Speed"); bonusStat = true; if (randStatMod == "Strength" && agent.strengthStatMod == 3) { bonusStat = false; } else if (randStatMod == "Endurance" && agent.enduranceStatMod == 3) { bonusStat = false; } else if (randStatMod == "Accuracy" && agent.accuracyStatMod == 3) { bonusStat = false; } else if (randStatMod == "Speed" && agent.speedStatMod == 3) { bonusStat = false; } } while (!bonusStat); switch (randStatMod) { case "Accuracy": agent.SetAccuracy(agent.accuracyStatMod + 1, true); GC.spawnerMain.SpawnStatusText(___agent, "BuffSpecial", "Accuracy", "BuffSpecial", ""); break; case "Endurance": agent.SetEndurance(agent.enduranceStatMod + 1, true); GC.spawnerMain.SpawnStatusText(___agent, "BuffSpecial", "Endurance", "BuffSpecial", ""); break; case "Speed": agent.SetSpeed(agent.speedStatMod + 1, true); GC.spawnerMain.SpawnStatusText(___agent, "BuffSpecial", "Speed", "BuffSpecial", ""); break; case "Strength": agent.SetStrength(agent.strengthStatMod + 1, true); GC.spawnerMain.SpawnStatusText(___agent, "BuffSpecial", "Strength", "BuffSpecial", ""); break; } } } if (___agent.health > 0f && !GC.menuGUI.demoOver) { if (___agent.possessing) { if (!GC.multiplayerMode) { if (___agent.isPlayer == 1) { GC.backupAgent1.health = GC.backupAgent1.healthMax; } if (___agent.isPlayer == 2) { GC.backupAgent2.health = GC.backupAgent2.healthMax; } if (___agent.isPlayer == 3) { GC.backupAgent3.health = GC.backupAgent3.healthMax; } if (___agent.isPlayer == 4) { GC.backupAgent4.health = GC.backupAgent4.healthMax; } } else { if (___agent.playerColor == 1) { GC.backupAgent1.health = GC.backupAgent1.healthMax; } if (___agent.playerColor == 2) { GC.backupAgent2.health = GC.backupAgent2.healthMax; } if (___agent.playerColor == 3) { GC.backupAgent3.health = GC.backupAgent3.healthMax; } if (___agent.playerColor == 4) { GC.backupAgent4.health = GC.backupAgent4.healthMax; } } GC.spawnerMain.SpawnStatusText(___agent, "HealthUpSlower", "FullHealth", "StatusEffect"); } else { ___agent.statusEffects.ChangeHealth(___agent.healthMax); } } else { ___agent.fullHealthAfterResurrect = true; } if (___agent.localPlayer && !suppressAnimation) { if (GC.fourPlayerMode) { __instance.SpawnSkillPointsStatusText(pointsType, xpReward); } else { ___agent.skillBar.StartChange(true); ___agent.skillBar.StartAnim(xpReward, pointsType, myColor); } } if (___agent.completingBigQuestLevel) { GC.quests.SpawnBigQuestCompletedText2(___agent, true); } else if (___agent.failingBigQuestLevel) { GC.quests.SpawnBigQuestFailedText2(___agent, true); } } else if (___agent.localPlayer && !suppressAnimation) { if (GC.fourPlayerMode) { __instance.SpawnSkillPointsStatusText(pointsType, xpReward); if (___agent.completingBigQuestLevel) { GC.quests.SpawnBigQuestCompletedText2(___agent, false); } else if (___agent.failingBigQuestLevel) { GC.quests.SpawnBigQuestFailedText2(___agent, false); } } else { ___agent.skillBar.StartChange(false); ___agent.skillBar.StartAnim(xpReward, pointsType, myColor); } } if (___agent.localPlayer) { ___agent.skillBar.UpdateSkillText(); } } logger.LogDebug("\txpReward = " + xpReward); }
public static void Patch(Harmony harmony) { harmony.Patch( AccessTools.DeclaredMethod(typeof(ViewModel), nameof(ViewModel.ExecuteCommand)), transpiler: new HarmonyMethod(SymbolExtensions.GetMethodInfo(() => ViewModel_ExecuteCommand_Transpiler(null !, null !)))); }
private static void ConvertArgument(ILGenerator il, Type paramType, ref LocalBuilder byRefLocal) { if (paramType.IsValueType) { return; } Type currentType = paramType; bool byRef = paramType.IsByRef; if (byRef) { currentType = paramType.GetElementType(); } if (currentType == typeof(string)) { // return Il2CppStringToManaged(ptr); // byRefLocal = Il2CppStringToManaged(*ptr); // return ref byRefLocal; if (byRef) { byRefLocal = il.DeclareLocal(currentType); il.Emit(OpCodes.Ldind_I); } il.Emit(OpCodes.Call, AccessTools.DeclaredMethod(typeof(IL2CPP), "Il2CppStringToManaged", new Type[] { typeof(IntPtr) })); if (byRef) { il.Emit(OpCodes.Stloc, byRefLocal); il.Emit(OpCodes.Ldloca, byRefLocal); } } else if (Main.unhollower.IsInheritedFromIl2CppObjectBase(currentType)) { // return ptr == 0 ? null : new SomeType(ptr); // byRefLocal = *ptr == 0 ? null : new SomeType(*ptr); // return ref byRefLocal; Label ptrNonZero = il.DefineLabel(); Label done = il.DefineLabel(); if (byRef) { byRefLocal = il.DeclareLocal(currentType); il.Emit(OpCodes.Ldind_I); } il.Emit(OpCodes.Dup); il.Emit(OpCodes.Brtrue_S, ptrNonZero); il.Emit(OpCodes.Pop); if (!byRef) { il.Emit(OpCodes.Ldnull); } il.Emit(OpCodes.Br_S, done); il.MarkLabel(ptrNonZero); il.Emit(OpCodes.Newobj, Il2CppConstuctor(currentType)); if (byRef) { il.Emit(OpCodes.Stloc, byRefLocal); } il.MarkLabel(done); if (byRef) { il.Emit(OpCodes.Ldloca, byRefLocal); } } }