Beispiel #1
0
 protected override MethodInfo?ResolveMethodInfo() => AccessTools.DeclaredMethod(Type, Name, Parameters, Generics);
Beispiel #2
0
        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);
        }
Beispiel #3
0
        // 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}");
            }
        }
Beispiel #4
0
        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);
        }
Beispiel #6
0
 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))));
 }
Beispiel #7
0
        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)));
        }
Beispiel #8
0
 static MethodBase TargetMethod() => AccessTools.DeclaredMethod(PuahCompHauledToInventoryType, "RegisterHauledItem");
Beispiel #9
0
 static MethodBase TargetMethod() => AccessTools.DeclaredMethod(PuahWorkGiver_HaulToInventoryType, "TryFindBestBetterStoreCellFor");
Beispiel #10
0
 static MethodBase TargetMethod() => AccessTools.DeclaredMethod(PuahJobDriver_UnloadYourHauledInventoryType, "MakeNewToils");
Beispiel #11
0
 // always use DeclaredMethod (explicit)
 static MethodBase TargetMethod() => AccessTools.DeclaredMethod(typeof(JobDriver), nameof(JobDriver.GetReport));
Beispiel #12
0
 static MethodBase TargetMethod() => AccessTools.DeclaredMethod(PuahJobDriver_UnloadYourHauledInventoryType, "FirstUnloadableThing");
Beispiel #13
0
 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))));
 }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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);
            }
        }
Beispiel #16
0
 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))));
 }
Beispiel #17
0
        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))
                    );
            }
        }
Beispiel #18
0
 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);
            }
        }
Beispiel #20
0
        // 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 !))));
 }
Beispiel #22
0
        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);
                }
            }
        }