static CIEnumerable Transpiler(CIEnumerable cins) { int ld = 0; return(ciInsert(cins, ci => (ci.isOp(OpCodes.Ldarg_2) && ++ld == 2) || ci.isLDC(0.1f), +1, 2, _codeForCfgVar(nameof(ModConfig.dayNightSpeed)), OpCodes.Mul)); }
static CIEnumerable Transpiler(CIEnumerable cins, ILGenerator ilg) { int ldc25 = 0; return(cins.ciReplace(ci => ci.isLDC(25f) && ++ldc25 == 2, _codeForCfgVar <float, GrapplingArmUpgraded>(25f, nameof(Main.config.hookSpeed), ilg))); }
static CIEnumerable Transpiler(CIEnumerable cins) { int ld = 0; return(cins.ciInsert(ci => (ci.isOp(OpCodes.Ldarg_2) && ++ld == 2) || ci.isLDC(0.1f), +1, 2, CIUtils.speed, OpCodes.Mul)); }
static CIEnumerable transpiler(CIEnumerable cins) { FieldInfo growingPeriod = typeof(WaterParkCreatureParameters).field("growingPeriod"); return(ciInsert(cins, ci => ci.isOp(OpCodes.Ldfld, growingPeriod), +1, 0, _codeForCfgVar(nameof(ModConfig.speedCreaturesGrow)), OpCodes.Div)); }
static CIEnumerable Transpiler(CIEnumerable cins) { var list = cins.ToList(); ciInsert(list, ci => ci.isLDC <double>(0.03f), _dnsClamped01.ci, OpCodes.Mul); // do not change to 0.03d ! ciInsert(list, ci => ci.isLDC(500f), _dnsClamped01.ci, OpCodes.Div); // changing only first '500f' return(list); }
static CIEnumerable Transpiler(CIEnumerable cins) { var list = cins.ToList(); list.ciInsert(ci => ci.isLDC <double>(0.03f), CIUtils.speedClamped01, OpCodes.Mul); // do not change to 0.03d ! list.ciInsert(ci => ci.isLDC(500f), CIUtils.speedClamped01, OpCodes.Div); // changing only first '500f' return(list); }
// transpiler for correcting time if daynightspeed < 1 (with additional multiplier) static CIEnumerable transpiler_dnsClamped01(CIEnumerable cins, string multCfgVarName) { MethodInfo deltaTime = typeof(DayNightCycle).method("get_deltaTime"); MethodInfo dayNightSpeed = typeof(DayNightCycle).method("get_dayNightSpeed"); return(ciInsert(cins, ci => ci.isOp(OpCodes.Callvirt, deltaTime) || ci.isOp(OpCodes.Callvirt, dayNightSpeed), +1, 0, _dnsClamped01.ci, OpCodes.Div, _codeForCfgVar(multCfgVarName), OpCodes.Mul)); }
static CIEnumerable F1_F3_disabler(CIEnumerable cins) { var list = cins.ToList(); CIHelper.MemberMatch match = new (OpCodes.Call, Mod.Consts.isGameSN? "get_isShippingRelease": "get_isConsolePlatform"); int[] i = list.ciFindIndexes(match, match, ci => ci.isOp(Mod.Consts.isGameSN? OpCodes.Blt: OpCodes.Ret)); return(i == null? cins: list.ciRemoveRange(i[0], i[2])); }
static CIEnumerable Transpiler(CIEnumerable cins, ILGenerator ilg) { var list = cins.ToList(); var field_lastBindedIndex = typeof(BindingPatches).field(nameof(lastBindedIndex)); #if GAME_SN && BRANCH_STABLE var cinsCompare = CIHelper.toCIList(OpCodes.Ldloc_S, 4, OpCodes.Ldsfld, field_lastBindedIndex); #else var cinsCompare = CIHelper.toCIList(OpCodes.Ldarg_1, CIHelper.emitCall <Func <KeyCode> >(_lastBindedKeyCode));
static CIEnumerable Transpiler(CIEnumerable cins, ILGenerator ilg) { var list = cins.ToList(); void _changeVal(float val, string cfgVar) => constToCfgVar <float, GrapplingArmUpgraded>(list, val, cfgVar, ilg); _changeVal(35f, nameof(Main.config.hookMaxDistance)); _changeVal(15f, nameof(Main.config.acceleration)); _changeVal(400f, nameof(Main.config.force)); return(list); }
static void saveLastBind() => lastBindedIndex = GameInput.lastInputPressed[0]; // for keyboard static CIEnumerable Transpiler(CIEnumerable cins) { var list = cins.ToList(); // saving binded keycode to check later in GameInput.UpdateKeyInputs patch list.ciInsert(new CIHelper.MemberMatch(nameof(GameInput.ClearInput)), CIHelper.emitCall <Action>(saveLastBind)); #if GAME_SN if (Main.config.easyBindRemove) { int index = list.FindIndex(new CIHelper.MemberMatch($"get_{nameof(EventSystem.current)}")); Common.Debug.assert(index != -1); var get_hoveredObject = typeof(BindCheckPointer).property(nameof(BindCheckPointer.hoveredObject)).GetGetMethod(); list.RemoveRange(index, 2); list.Insert(index, new CodeInstruction(OpCodes.Call, get_hoveredObject)); } #endif return(list); }
static CIEnumerable Transpiler(CIEnumerable cins) => cins.ciInsert(ci => ci.isLDC(500f), CIUtils.speedClamped01, OpCodes.Div);
static CIEnumerable Transpiler(CIEnumerable cins) => ciInsert(cins, ci => ci.isOp(OpCodes.Call), _dnsClamped01.ci, OpCodes.Mul);
static CIEnumerable Transpiler(CIEnumerable cins) => cins.ciInsert(ci => ci.isOp(OpCodes.Ldarg_S, (byte)5), CIUtils.speedClamped01, OpCodes.Mul);
static CIEnumerable Transpiler(CIEnumerable cins) => ciInsert(cins, ci => ci.isLDC(100f), +1, 2, _codeForCfgVar(nameof(ModConfig.dayNightSpeed)), OpCodes.Mul, _codeForCfgVar(nameof(ModConfig.auxSpeedHungerThrist)), OpCodes.Mul);
// simple transpiler for changing 1.0 to current value of dayNightSpeed static CIEnumerable transpiler_dayNightSpeed(CIEnumerable cins) => constToCfgVar(cins, 1.0f, nameof(Main.config.dayNightSpeed));
// indexDelta - change actual index from matched for removing // countToRemove - instructions count to be removed public static CIList ciRemove(CIEnumerable cins, CIPredicate predicate, int indexDelta, int countToRemove) => ciRemove(cins.ToList(), predicate, indexDelta, countToRemove);
static CIEnumerable IngameMenu_Start_Transpiler(CIEnumerable cins) => CIHelper.ciRemove(cins, 0, 3);
static CIEnumerable Transpiler(CIEnumerable cins) => ciInsert(cins, ci => ci.isOp(OpCodes.Ldarg_S, (byte)5), _dnsClamped01.ci, OpCodes.Mul);
public static CIList ciRemove(CIEnumerable cins, int index, int countToRemove) => ciRemove(cins.ToList(), index, countToRemove);
// changing constant to config field if gameobject have component C public static CIList constToCfgVar <T, C>(CIEnumerable cins, T val, string cfgVarName, ILGenerator ilg) where C : Component => constToCfgVar <T, C>(cins.ToList(), val, cfgVarName, ilg);
// replaces first matched CodeInstruction with cinsForReplace CodeInstructions public static CIList ciReplace(CIEnumerable cins, CIPredicate predicate, params object[] cinsForReplace) => ciReplace(cins.ToList(), predicate, cinsForReplace);
static CIEnumerable transpiler_dnsClamped01_consume(CIEnumerable cins) => transpiler_dnsClamped01(cins, nameof(ModConfig.auxSpeedPowerConsume));
// maxMatchCount = 0 for all predicate matches // indexDelta - change actual index from matched for insertion // if indexDelta is 0 than cinsToInsert will be inserted right before finded instruction // throws assert exception if there were no matches at all or if maxMatchCount > 0 and there were less predicate matches public static CIList ciInsert(CIEnumerable cins, CIPredicate predicate, int indexDelta, int maxMatchCount, params object[] cinsToInsert) => ciInsert(cins.ToList(), predicate, indexDelta, maxMatchCount, cinsToInsert);
static CIEnumerable Transpiler(CIEnumerable cins) => ciInsert(cins, ci => ci.isOp(OpCodes.Sub), _codeForCfgVar(nameof(ModConfig.dayNightSpeed)), OpCodes.Div);
static CIEnumerable Transpiler(CIEnumerable cins, ILGenerator ilg) => constToCfgVar <float, GrapplingArmUpgraded>(cins, 2.0f, nameof(Main.config.armCooldown), ilg);
static CIEnumerable Transpiler(CIEnumerable cins) => ciInsert(cins, ci => ci.isLDC(500f), _dnsClamped01.ci, OpCodes.Div);
static CIEnumerable Transpiler(CIEnumerable cins) => cins.ciReplace(ci => ci.isLDC(90f), OpCodes.Ldarg_0, emitCall <Func <GrapplingHook, float> >(getAngle));
// warning: nested classes are not supported for cfgVarName! // changing constant to config field public static CIList constToCfgVar <T>(CIEnumerable cins, T val, string cfgVarName) => constToCfgVar(cins.ToList(), val, cfgVarName);
// for just first predicate match (insert right after finded instruction) public static CIList ciInsert(CIEnumerable cins, CIPredicate predicate, params object[] cinsToInsert) => ciInsert(cins.ToList(), predicate, cinsToInsert);