/// <summary> /// Builds the CharacterData represented by this builder's parameters recursively; /// all Builders represented in this class's various fields will also be built. /// </summary> /// <returns>The newly created CharacterData</returns> public CharacterData Build() { CharacterData characterData = ScriptableObject.CreateInstance <CharacterData>(); characterData.name = this.CharacterID; foreach (var builder in this.TriggerBuilders) { this.Triggers.Add(builder.Build()); } foreach (var builder in this.RoomModifierBuilders) { this.RoomModifiers.Add(builder.Build()); } var guid = GUIDGenerator.GenerateDeterministicGUID(this.CharacterID); AccessTools.Field(typeof(CharacterData), "id").SetValue(characterData, guid); AccessTools.Field(typeof(CharacterData), "animationController").SetValue(characterData, this.AnimationController); AccessTools.Field(typeof(CharacterData), "ascendsTrainAutomatically").SetValue(characterData, this.AscendsTrainAutomatically); AccessTools.Field(typeof(CharacterData), "attackDamage").SetValue(characterData, this.AttackDamage); AccessTools.Field(typeof(CharacterData), "attackTeleportsToDefender").SetValue(characterData, this.AttackTeleportsToDefender); AccessTools.Field(typeof(CharacterData), "bossActionGroups").SetValue(characterData, this.BossActionGroups); AccessTools.Field(typeof(CharacterData), "bossRoomSpellCastVFX").SetValue(characterData, this.BossRoomSpellCastVFX); AccessTools.Field(typeof(CharacterData), "bossSpellCastVFX").SetValue(characterData, this.BossSpellCastVFX); AccessTools.Field(typeof(CharacterData), "canAttack").SetValue(characterData, this.CanAttack); AccessTools.Field(typeof(CharacterData), "canBeHealed").SetValue(characterData, this.CanBeHealed); AccessTools.Field(typeof(CharacterData), "characterChatterData").SetValue(characterData, this.CharacterChatterData); AccessTools.Field(typeof(CharacterData), "characterLoreTooltipKeys").SetValue(characterData, this.CharacterLoreTooltipKeys); if (this.CharacterPrefabVariantRef == null) { if (this.CharacterPrefabVariantRefBuilder == null) { if (this.BundleLoadingInfo != null) { this.BundleLoadingInfo.PluginPath = this.BaseAssetPath; this.CharacterPrefabVariantRefBuilder = new AssetRefBuilder { AssetLoadingInfo = this.BundleLoadingInfo }; } else { var assetLoadingInfo = new AssetLoadingInfo() { FilePath = this.AssetPath, PluginPath = this.BaseAssetPath, AssetType = AssetRefBuilder.AssetTypeEnum.Character }; this.CharacterPrefabVariantRefBuilder = new AssetRefBuilder { AssetLoadingInfo = assetLoadingInfo }; } } this.CharacterPrefabVariantRef = this.CharacterPrefabVariantRefBuilder.BuildAndRegister(); } AccessTools.Field(typeof(CharacterData), "characterPrefabVariantRef").SetValue(characterData, this.CharacterPrefabVariantRef); AccessTools.Field(typeof(CharacterData), "characterSoundData").SetValue(characterData, this.CharacterSoundData); AccessTools.Field(typeof(CharacterData), "characterSpriteCache").SetValue(characterData, this.CharacterSpriteCache); AccessTools.Field(typeof(CharacterData), "deathSlidesBackwards").SetValue(characterData, this.DeathSlidesBackwards); AccessTools.Field(typeof(CharacterData), "deathType").SetValue(characterData, this.DeathType); AccessTools.Field(typeof(CharacterData), "deathVFX").SetValue(characterData, this.DeathVFX); AccessTools.Field(typeof(CharacterData), "fallbackData").SetValue(characterData, this.FallBackData); AccessTools.Field(typeof(CharacterData), "health").SetValue(characterData, this.Health); AccessTools.Field(typeof(CharacterData), "impactVFX").SetValue(characterData, this.ImpactVFX); AccessTools.Field(typeof(CharacterData), "isMiniboss").SetValue(characterData, this.IsMiniboss); AccessTools.Field(typeof(CharacterData), "isOuterTrainBoss").SetValue(characterData, this.IsOuterTrainBoss); BuilderUtils.ImportStandardLocalization(this.NameKey, this.Name); AccessTools.Field(typeof(CharacterData), "nameKey").SetValue(characterData, this.NameKey); AccessTools.Field(typeof(CharacterData), "projectilePrefab").SetValue(characterData, this.ProjectilePrefab); AccessTools.Field(typeof(CharacterData), "roomModifiers").SetValue(characterData, this.RoomModifiers); AccessTools.Field(typeof(CharacterData), "size").SetValue(characterData, this.Size); AccessTools.Field(typeof(CharacterData), "startingStatusEffects").SetValue(characterData, this.StartingStatusEffects); AccessTools.Field(typeof(CharacterData), "statusEffectImmunities").SetValue(characterData, this.StatusEffectImmunities); //AccessTools.Field(typeof(CardData), "stringBuilder").SetValue(cardData, this.); if (this.PriorityDraw) { this.SubtypeKeys.Add("SubtypesData_Chosen"); } AccessTools.Field(typeof(CharacterData), "subtypeKeys").SetValue(characterData, this.SubtypeKeys); AccessTools.Field(typeof(CharacterData), "triggers").SetValue(characterData, this.Triggers); return(characterData); }
public static T GetField <T>(this object instance, string fieldname) => (T)AccessTools.Field(instance.GetType(), fieldname).GetValue(instance);
public static T GetPrivateFieldValue <T>(this object parentObject, string field) { return((T)AccessTools.Field(parentObject.GetType(), field)?.GetValue(parentObject)); }
static void Load(UnityModManager.ModEntry modEntry) { modEntry.Logger.Log("Loaded DvMilk"); if (AccessTools.Field(typeof(CargoTypes), "cargoTypeToSupportedCarContainer")?.GetValue(null) is Dictionary <CargoType, List <CargoContainerType> > ct2ct) { ct2ct[MILK] = new List <CargoContainerType>() { CargoContainerType.TankerChem, CargoContainerType.TankerGas }; } else { modEntry.Logger.Warning("Failed to add milk container types"); } if (AccessTools.Field(typeof(CargoTypes), "cargoTypeToCargoMassPerUnit")?.GetValue(null) is Dictionary <CargoType, float> ct2cmpu) { ct2cmpu[MILK] = 30_500f; } else { modEntry.Logger.Warning("Failed to add milk cargo mass"); } if (AccessTools.Field(typeof(CargoTypes), "cargoSpecificDisplayName")?.GetValue(null) is Dictionary <CargoType, string> cspdn) { cspdn.Add(MILK, "Milk"); } else { modEntry.Logger.Warning("Failed to add milk long name"); } if (AccessTools.Field(typeof(CargoTypes), "cargoShortDisplayName")?.GetValue(null) is Dictionary <CargoType, string> cshdn) { cshdn[MILK] = "Milk"; } else { modEntry.Logger.Warning("Failed to add milk short name"); } if (AccessTools.Field(typeof(ResourceTypes), "cargoToFullCargoDamagePrice")?.GetValue(null) is Dictionary <CargoType, float> c2fcdp) { c2fcdp[MILK] = 0f; } else { modEntry.Logger.Warning("Failed to add milk full cargo damage price"); } if (AccessTools.Field(typeof(ResourceTypes), "cargoToFullEnvironmentDamagePrice")?.GetValue(null) is Dictionary <CargoType, float> c2fedp) { c2fedp[MILK] = 16000f; } else { modEntry.Logger.Warning("Failed to add milk full cargo enviromental damage price"); } var harmony = new Harmony(modEntry.Info.Id); harmony.PatchAll(Assembly.GetExecutingAssembly()); modEntry.Logger.Log("Patched methods"); }
/// <summary>Patch to nerf Ecologist spring onion quality and increment forage counter + always allow iridium-quality crops for Agriculturist + Harvester bonus crop yield.</summary> private static IEnumerable <CodeInstruction> CropHarvestTranspiler(IEnumerable <CodeInstruction> instructions, ILGenerator iLGenerator, MethodBase original) { Helper.Attach(instructions).Trace($"Patching method {typeof(Crop)}::{nameof(Crop.harvest)}."); var mb = original.GetMethodBody(); if (mb == null) { throw new ArgumentNullException($"{original.Name} method body returned null."); } /// From: @object.Quality = 4 /// To: @object.Quality = GetEcologistForageQuality() try { Helper .FindProfessionCheck(Farmer.botanist) // find index of botanist check .AdvanceUntil( new CodeInstruction(OpCodes.Ldc_I4_4) // start of @object.Quality = 4 ) .ReplaceWith( // replace with custom quality new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Utility), nameof(Utility.GetEcologistForageQuality))) ); } catch (Exception ex) { Helper.Error($"Failed while patching modded Ecologist spring onion quality.\nHelper returned {ex}").Restore(); } Helper.Backup(); /// Injected: if (Game1.player.professions.Contains(<ecologist_id>)) /// AwesomeProfessions.Data.IncrementField($"{AwesomeProfessions.UniqueID}/ItemsForaged", amount: @object.Stack) var dontIncreaseEcologistCounter = iLGenerator.DefineLabel(); try { Helper .FindNext( new CodeInstruction(OpCodes.Callvirt, AccessTools.Property(typeof(Stats), nameof(Stats.ItemsForaged)).GetSetMethod()) ) .Advance() .InsertProfessionCheckForLocalPlayer(Utility.ProfessionMap.Forward["Ecologist"], dontIncreaseEcologistCounter) .Insert( new CodeInstruction(OpCodes.Call, AccessTools.Property(typeof(AwesomeProfessions), nameof(AwesomeProfessions.Data)) .GetGetMethod()), new CodeInstruction(OpCodes.Call, AccessTools.Property(typeof(AwesomeProfessions), nameof(AwesomeProfessions.UniqueID)) .GetGetMethod()), new CodeInstruction(OpCodes.Ldstr, operand: "/ItemsForaged"), new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(string), nameof(string.Concat), new[] { typeof(string), typeof(string) })), new CodeInstruction(OpCodes.Ldloc_1), // loc 1 = @object new CodeInstruction(OpCodes.Callvirt, AccessTools.Property(typeof(SObject), nameof(SObject.Stack)).GetGetMethod()), new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(ModDataDictionaryExtensions), name: "IncrementField", new[] { typeof(ModDataDictionary), typeof(string), typeof(int) })), new CodeInstruction(OpCodes.Pop) ) .AddLabels(dontIncreaseEcologistCounter); } catch (Exception ex) { Helper.Error($"Failed while adding Ecologist counter increment.\nHelper returned {ex}").Restore(); } Helper.Backup(); /// From: if (fertilizerQualityLevel >= 3 && random2.NextDouble() < chanceForGoldQuality / 2.0) /// To: if (Game1.player.professions.Contains(< agriculturist_id >) || fertilizerQualityLevel >= 3) && random2.NextDouble() < chanceForGoldQuality / 2.0) var fertilizerQualityLevel = mb.LocalVariables[8]; var random2 = mb.LocalVariables[9]; var isAgriculturist = iLGenerator.DefineLabel(); try { Helper.AdvanceUntil( // find index of Crop.fertilizerQualityLevel >= 3 new CodeInstruction(OpCodes.Ldloc_S, operand: fertilizerQualityLevel), new CodeInstruction(OpCodes.Ldc_I4_3), new CodeInstruction(OpCodes.Blt) ) .InsertProfessionCheckForLocalPlayer(Utility.ProfessionMap.Forward["Agriculturist"], branchDestination: isAgriculturist, useBrtrue: true) .AdvanceUntil( // find start of dice roll new CodeInstruction(OpCodes.Ldloc_S, operand: random2) ) .AddLabels(isAgriculturist); // branch here if player is agriculturist } catch (Exception ex) { Helper.Error($"Failed while adding modded Agriculturist crop harvest quality.\nHelper returned {ex}").Restore(); } Helper.Backup(); /// Injected: if (junimoHarvester == null && Game1.player.professions.Contains(<harvester_id>) && r.NextDouble() < 0.1) numToHarvest++ var numToHarvest = mb.LocalVariables[6]; var dontIncreaseNumToHarvest = iLGenerator.DefineLabel(); try { Helper .FindNext( new CodeInstruction(OpCodes.Ldloc_S, operand: numToHarvest) // find index of numToHarvest++ ) .ToBufferUntil( // copy this segment stripLabels: true, advance: false, new CodeInstruction(OpCodes.Stloc_S, operand: numToHarvest) ) .FindNext( new CodeInstruction(OpCodes.Ldloc_S, operand: random2) // find an instance of accessing the rng ) .GetOperand(out var r2) // copy operand object .FindLast( // find end of chanceForExtraCrops while loop new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(Crop), nameof(Crop.chanceForExtraCrops))) ) .AdvanceUntil( new CodeInstruction(OpCodes.Ldarg_0) // beginning of the next segment ) .GetLabels(out var labels) // copy existing labels .SetLabels(dontIncreaseNumToHarvest) // branch here if shouldn't apply Harvester bonus .Insert( // insert check if junimoHarvester == null new CodeInstruction(OpCodes.Ldarg_S, operand: (byte)4), new CodeInstruction(OpCodes.Brtrue_S, operand: dontIncreaseNumToHarvest) ) .InsertProfessionCheckForLocalPlayer(Utility.ProfessionMap.Forward["Harvester"], dontIncreaseNumToHarvest) .Insert( // insert dice roll new CodeInstruction(OpCodes.Ldloc_S, operand: (LocalBuilder)r2), new CodeInstruction(OpCodes.Callvirt, AccessTools.Method(typeof(Random), nameof(Random.NextDouble))), new CodeInstruction(OpCodes.Ldc_R8, operand: 0.1), new CodeInstruction(OpCodes.Bge_Un_S, operand: dontIncreaseNumToHarvest) ) .InsertBuffer() // insert numToHarvest++ .Return(3) // return to first inserted instruction .SetLabels(labels); // restore original labels to this segment } catch (Exception ex) { Helper.Error($"Failed while adding modded Harvester extra crop yield.\nHelper returned {ex}").Restore(); } return(Helper.Flush()); }
private static void SetField(object _instance, string name, object value) { FieldInfo fi = AccessTools.Field(_instance.GetType(), name); fi.SetValue(_instance, value); }
private static bool Prefix(SGNavigationScreen __instance) { try { Flareup flareup = Utilities.currentFlareup(); WIIC.modLog.Warn?.Write($"OnTravelCourseAccepted. Flareup: {flareup}, ActiveTravelContract: {WIIC.sim.ActiveTravelContract}"); if (flareup == null) { return(true); } if (!WIIC.flareups.ContainsKey(WIIC.sim.CurSystem.ID)) { WIIC.modLog.Warn?.Write($"Found company tag indicating flareup participation, but no matching flareup for {WIIC.sim.CurSystem.ID}"); WIIC.sim.CompanyTags.Remove("WIIC_helping_attacker"); WIIC.sim.CompanyTags.Remove("WIIC_helping_defender"); return(true); } UIManager uiManager = (UIManager)AccessTools.Field(typeof(SGNavigationScreen), "uiManager").GetValue(__instance); void cleanup() { uiManager.ResetFader(UIManagerRootType.PopupRoot); WIIC.sim.Starmap.Screen.AllowInput(true); } string title = Strings.T("Navigation Change"); string primaryButtonText = Strings.T("Break Deployment"); string cancel = Strings.T("Cancel"); string message = Strings.T("Leaving {0} will break our current deployment. Our reputation with {1} and the MRB will suffer, Commander.", flareup.location.Name, flareup.employer.FactionDef.ShortName); WIIC.modLog.Info?.Write(message); PauseNotification.Show(title, message, WIIC.sim.GetCrewPortrait(SimGameCrew.Crew_Sumire), string.Empty, true, delegate { try { WIIC.modLog.Info?.Write("Breaking deployment contract"); Flareup flareup2 = Utilities.currentFlareup(); WIIC.modLog.Info?.Write("Flareup: {flareup2}"); if (flareup2 != null && flareup2.employer.DoesGainReputation) { WIIC.modLog.Info?.Write("Employer: {flareup2.employer}"); float employerRepBadFaithMod = WIIC.sim.Constants.Story.EmployerRepBadFaithMod; WIIC.modLog.Info?.Write("employerRepBadFaithMod: {employerRepBadFaithMod}"); WIIC.modLog.Info?.Write("CAREER: {SimGameState.SimGameType.CAREER}"); WIIC.modLog.Info?.Write("difficulty: {flareup2.location.Def.GetDifficulty(SimGameState.SimGameType.CAREER)}"); int num = (int)Math.Round(flareup2.location.Def.GetDifficulty(SimGameState.SimGameType.CAREER) * employerRepBadFaithMod); WIIC.sim.SetReputation(flareup2.employer, num); WIIC.sim.SetReputation(FactionEnumeration.GetMercenaryReviewBoardFactionValue(), num); } WIIC.sim.CompanyTags.Remove("WIIC_helping_attacker"); WIIC.sim.CompanyTags.Remove("WIIC_helping_defender"); WIIC.sim.RoomManager.RefreshTimeline(false); WIIC.sim.Starmap.SetActivePath(); WIIC.sim.SetSimRoomState(DropshipLocation.SHIP); cleanup(); } catch (Exception e) { WIIC.modLog.Error?.Write(e); } }, primaryButtonText, cleanup, cancel); WIIC.sim.Starmap.Screen.AllowInput(false); uiManager.SetFaderColor(uiManager.UILookAndColorConstants.PopupBackfill, UIManagerFader.FadePosition.FadeInBack, UIManagerRootType.PopupRoot); return(false); } catch (Exception e) { WIIC.modLog.Error?.Write(e); return(true); } }
///// <summary> ///// Prevents the user from having damage with the verb. ///// </summary> ///// <param name="__instance"></param> ///// <param name="__result"></param> ///// <param name="pawn"></param> //public static void GetDamageFactorForPostFix(Verb __instance, ref float __result, Pawn pawn) //{ // Pawn_EquipmentTracker pawn_EquipmentTracker = pawn.equipment; // if (pawn_EquipmentTracker != null) // { // //Log.Message("2"); // ThingWithComps thingWithComps = (ThingWithComps)AccessTools.Field(typeof(Pawn_EquipmentTracker), "primaryInt").GetValue(pawn_EquipmentTracker); // if (thingWithComps != null) // { // //Log.Message("3"); // CompActivatableEffect compActivatableEffect = thingWithComps.GetComp<CompActivatableEffect>(); // if (compActivatableEffect != null) // { // if (compActivatableEffect.CurrentState != CompActivatableEffect.State.Activated) // { // //Messages.Message("DeactivatedWarning".Translate(), MessageSound.RejectInput); // __result = 0f; // } // } // } // } //} /// <summary> /// Adds another "layer" to the equipment aiming if they have a /// weapon with a CompActivatableEffect. /// </summary> /// <param name="__instance"></param> /// <param name="eq"></param> /// <param name="drawLoc"></param> /// <param name="aimAngle"></param> public static void DrawEquipmentAimingPostFix(PawnRenderer __instance, Thing eq, Vector3 drawLoc, float aimAngle) { var pawn = (Pawn)AccessTools.Field(typeof(PawnRenderer), "pawn").GetValue(__instance); var pawn_EquipmentTracker = pawn.equipment; var thingWithComps = pawn_EquipmentTracker?.Primary; //(ThingWithComps)AccessTools.Field(typeof(Pawn_EquipmentTracker), "primaryInt").GetValue(pawn_EquipmentTracker); var compActivatableEffect = thingWithComps?.GetComp <CompActivatableEffect>(); if (compActivatableEffect?.Graphic == null) { return; } if (compActivatableEffect.CurrentState != CompActivatableEffect.State.Activated) { return; } var num = aimAngle - 90f; var flip = false; if (aimAngle > 20f && aimAngle < 160f) { //mesh = MeshPool.GridPlaneFlip(thingWithComps.def.graphicData.drawSize); num += eq.def.equippedAngleOffset; } else if (aimAngle > 200f && aimAngle < 340f) { //mesh = MeshPool.GridPlane(thingWithComps.def.graphicData.drawSize); flip = true; num -= 180f; num -= eq.def.equippedAngleOffset; } else { //mesh = MeshPool.GridPlaneFlip(thingWithComps.def.graphicData.drawSize); num += eq.def.equippedAngleOffset; } Vector3 offset = Vector3.zero; if (eq is ThingWithComps eqComps) { if (eqComps.AllComps.FirstOrDefault(z => z is CompOversizedWeapon.CompOversizedWeapon) is CompOversizedWeapon.CompOversizedWeapon weaponComp) { if (pawn.Rotation == Rot4.East) { offset = weaponComp.Props.eastOffset; } else if (pawn.Rotation == Rot4.West) { offset = weaponComp.Props.westOffset; } else if (pawn.Rotation == Rot4.North) { offset = weaponComp.Props.northOffset; } else if (pawn.Rotation == Rot4.South) { offset = weaponComp.Props.southOffset; } offset += weaponComp.Props.offset; } var deflector = eqComps.AllComps.FirstOrDefault(y => y.GetType().ToString().Contains("Deflect")); if (deflector != null) { var isActive = (bool)AccessTools .Property(deflector.GetType(), "IsAnimatingNow").GetValue(deflector, null); if (isActive) { float numMod = (int)AccessTools .Property(deflector.GetType(), "AnimationDeflectionTicks") .GetValue(deflector, null); //float numMod2 = new float(); //numMod2 = numMod; if (numMod > 0) { if (!flip) { num += (numMod + 1) / 2; } else { num -= (numMod + 1) / 2; } } } } } num %= 360f; //ThingWithComps eqComps = eq as ThingWithComps; //if (eqComps != null) //{ // ThingComp deflector = eqComps.AllComps.FirstOrDefault<ThingComp>((ThingComp y) => y.GetType().ToString() == "CompDeflector.CompDeflector"); // if (deflector != null) // { // float numMod = (float)((int)AccessTools.Property(deflector.GetType(), "AnimationDeflectionTicks").GetValue(deflector, null)); // //Log.ErrorOnce("NumMod " + numMod.ToString(), 1239); //numMod = (numMod + 1) / 2; //if (subtract) num -= numMod; //else num += numMod; // } //} var matSingle = compActivatableEffect.Graphic.MatSingle; //if (mesh == null) mesh = MeshPool.GridPlane(thingWithComps.def.graphicData.drawSize); var s = new Vector3(eq.def.graphicData.drawSize.x, 1f, eq.def.graphicData.drawSize.y); var matrix = default(Matrix4x4); matrix.SetTRS(drawLoc + offset, Quaternion.AngleAxis(num, Vector3.up), s); if (!flip) { Graphics.DrawMesh(MeshPool.plane10, matrix, matSingle, 0); } else { Graphics.DrawMesh(MeshPool.plane10Flip, matrix, matSingle, 0); } //Graphics.DrawMesh(mesh, drawLoc, Quaternion.AngleAxis(num, Vector3.up), matSingle, 0); }
static bool CheckRestarted() => AccessTools.Field(typeof(Game), PrepatcherMarkerField) != null;
public static void ShowInfo(ThingDef tDef) { if (!CanShowInfo(tDef)) { Messages.Message("Can't show info for this.", MessageTypeDefOf.RejectInput); return; } if (tDef.thingClass == typeof(MinifiedThing)) { //TODO: check inner thing for sculptures and furniture List <ThingDef> list = (from def in DefDatabase <ThingDef> .AllDefs where def.minifiedDef == tDef select def).ToList(); if (list.Count == 1) { tDef = list[0]; } else { Messages.Message("Can't show info for this.", MessageTypeDefOf.RejectInput); return; } } if (tDef.MadeFromStuff) { List <FloatMenuOption> list = new List <FloatMenuOption>(); var map = Find.CurrentMap; var allThings = map?.listerThings?.ThingsOfDef(tDef); foreach (var sDef in GenStuff.AllowedStuffsFor(tDef)) { int?countWithThisStuff = null; int?stuffCount = null; if (map != null) { stuffCount = Count(sDef, map); countWithThisStuff = allThings.Where(x => x.Stuff == sDef).Count(); } string labelCap = $"[{countWithThisStuff.ToString() ?? "?"}] | {sDef.LabelCap} ({stuffCount?.ToString() ?? "?"})"; list.Add(new FloatMenuOption(labelCap, delegate { Vector2 scrollPosition = new Vector2(); bool restoreScrollPos = false; if (Find.WindowStack.IsOpen <Dialog_InfoCard>()) { scrollPosition = (Vector2)AccessTools.Field(typeof(StatsReportUtility), "scrollPosition").GetValue(null); restoreScrollPos = true; } Find.WindowStack.Add(new Dialog_InfoCard(FakeThingForInfo(tDef, sDef))); if (restoreScrollPos) { AccessTools.Field(typeof(StatsReportUtility), "scrollPosition").SetValue(null, scrollPosition); } }, MenuOptionPriority.Default, null, null, 0f, null, null)); } FloatMenu floatMenu = new FloatMenu(list); floatMenu.vanishIfMouseDistant = true; Find.WindowStack.Add(floatMenu); } else { Find.WindowStack.Add(new Dialog_InfoCard(FakeThingForInfo(tDef, null))); } }
public static MyTranspiler GenerateReplacementCallTranspiler(List <CodeInstruction> condition, MethodBase method = null, MethodInfo replacement = null) { return((ILGenerator generator, IEnumerable <CodeInstruction> instr) => { var labels = new List <Label>(); foreach (var cond in condition) { if (cond.operand is Label) { labels.Add((Label)cond.operand); } } var instructions = new List <CodeInstruction>(); instructions.AddRange(condition); if (method != null && replacement != null) { var parameterNames = method.GetParameters().Select(info => info.Name).ToList(); replacement.GetParameters().Do(info => { var name = info.Name; var ptype = info.ParameterType; if (name == "__instance") { instructions.Add(new CodeInstruction(OpCodes.Ldarg_0)); // instance } else { var index = parameterNames.IndexOf(name); if (index >= 0) { instructions.Add(new CodeInstruction(OpCodes.Ldarg, index + 1)); // parameters } else { var fInfo = AccessTools.Field(method.DeclaringType, name); instructions.Add(new CodeInstruction(OpCodes.Ldarg_0)); instructions.Add(new CodeInstruction(OpCodes.Ldflda, fInfo)); // extra fields } } }); } if (replacement != null) { instructions.Add(new CodeInstruction(OpCodes.Call, replacement)); } instructions.Add(new CodeInstruction(OpCodes.Ret)); var idx = instructions.Count; instructions.AddRange(instr); instructions[idx].labels = instructions[idx].labels ?? new List <Label>(); instructions[idx].labels.AddRange(labels); return instructions.AsEnumerable(); }); /* * (A) * L_0000: ldarg.0 * L_0001: ldfld class ZombieLand.FOO ZombieLand.AAA::pawn * L_0006: isinst ZombieLand.ZZZ * L_000b: brfalse.s L_001a * (B) * L_000d: ldarg.0 * L_000e: ldarg.0 * L_000f: ldflda class ZombieLand.FOO ZombieLand.AAA::pawn * L_0014: call void ZombieLand.AAAPatch::TestPatched(class ZombieLand.AAA, class ZombieLand.FOO&) * L_0019: ret * (C) * L_001f: nop * (D) * ....... */ }
public static bool Prefix(CharacterInspectionScreen __instance, InputCommands.Id command) { switch (command) { // Handle 'E' for 'Export' case InputCommands.Id.RotateCCW: SaveCharacter(); break; } return(true); void SaveCharacter() { var rulesetEntityService = ServiceRepository.GetService <IRulesetEntityService>(); using (var logger = new MethodLogger("CharacterInspectionScreen_HandleInput")) { var heroCharacter = __instance.InspectedCharacter.RulesetCharacterHero; // record current name, etc.. var name = heroCharacter.Name; var builtin = heroCharacter.BuiltIn; var guid = heroCharacter.Guid; // record current conditions, powers, spells and attunements var conditions = heroCharacter.ConditionsByCategory.ToList(); var powers = heroCharacter.PowersUsedByMe.ToList(); var spells = heroCharacter.SpellsCastByMe.ToList(); var inventoryItems = new List <RulesetItem>(); heroCharacter.CharacterInventory.EnumerateAllItems(inventoryItems); var attunedItems = inventoryItems.Select(i => new { Item = i, Name = i.AttunedToCharacter }).ToList(); // record item guids var heroItemGuids = heroCharacter.Items.Select(i => new { Item = i, i.Guid }).ToList(); var inventoryItemGuids = inventoryItems.Select(i => new { Item = i, i.Guid }).ToList(); try { // TODO: update to use convention = name-nnn.sav // TODO: then need UI to allow user to change name on export // For now just add EX- heroCharacter.Name = "EX-" + name; heroCharacter.BuiltIn = false; // remove active conditions (or filter out during serialization) heroCharacter.ConditionsByCategory.Clear(); // remove spells and effects (or filter out during serialization) heroCharacter.PowersUsedByMe.Clear(); heroCharacter.SpellsCastByMe.Clear(); // remove attunement, attuned items don't work well in the character inspection screen out of game foreach (var item in attunedItems) { item.Item.AttunedToCharacter = string.Empty; } // clear guids AccessTools.Field(heroCharacter.GetType(), "guid").SetValue(heroCharacter, 0UL); foreach (var item in heroItemGuids) { AccessTools.Field(item.Item.GetType(), "guid").SetValue(item.Item, 0UL); } foreach (var item in inventoryItemGuids) { AccessTools.Field(item.Item.GetType(), "guid").SetValue(item.Item, 0UL); } ServiceRepository .GetService <ICharacterPoolService>() .SaveCharacter(heroCharacter, true); } finally { // TODO: check these things are really restored // restore original values heroCharacter.Name = name; heroCharacter.BuiltIn = builtin; // restore conditions foreach (var kvp in conditions) { heroCharacter.ConditionsByCategory.Add(kvp.Key, kvp.Value); } // restore active spells and effects heroCharacter.PowersUsedByMe.AddRange(powers); heroCharacter.SpellsCastByMe.AddRange(spells); // restore attunement foreach (var item in attunedItems) { item.Item.AttunedToCharacter = item.Name; } // restore guids AccessTools.Field(heroCharacter.GetType(), "guid").SetValue(heroCharacter, guid); foreach (var item in heroItemGuids) { AccessTools.Field(item.Item.GetType(), "guid").SetValue(item.Item, item.Guid); } foreach (var item in inventoryItemGuids) { AccessTools.Field(item.Item.GetType(), "guid").SetValue(item.Item, item.Guid); } } } } }
static void Postfix(StarmapRenderer __instance) { try { var davionLogo = GameObject.Find("davionLogo"); var marikLogo = GameObject.Find("marikLogo"); var directorateLogo = GameObject.Find("directorateLogo"); directorateLogo?.SetActive(false); davionLogo?.SetActive(false); marikLogo?.SetActive(false); var liaoLogo = GameObject.Find("liaoLogo"); liaoLogo?.SetActive(false); var taurianLogo = GameObject.Find("taurianLogo"); taurianLogo?.SetActive(false); var magistracyLogo = GameObject.Find("magistracyLogo"); magistracyLogo?.SetActive(false); var restorationLogo = GameObject.Find("restorationLogo"); restorationLogo?.SetActive(false); GameObject go; if (Fields.originalTransform == null) { Fields.originalTransform = UnityEngine.Object.Instantiate(__instance.restorationLogo).transform; } Texture2D texture2D2; byte[] data; foreach (LogoItem logoItem in InnerSphereMap.SETTINGS.logos) { FactionValue factionValue = FactionEnumeration.GetFactionByName(logoItem.factionName); if (factionValue.IsClan && InnerSphereMap.SETTINGS.reducedClanLogos) { continue; } string mapGoObject = logoItem.factionName + "Map"; if (GameObject.Find(mapGoObject) == null) { texture2D2 = new Texture2D(2, 2); data = File.ReadAllBytes($"{InnerSphereMap.ModDirectory}/Logos/{logoItem.logoImage}.png"); texture2D2.LoadImage(data); go = UnityEngine.Object.Instantiate(__instance.restorationLogo); go.GetComponent <Renderer>().material.mainTexture = texture2D2; go.name = mapGoObject; } else { go = GameObject.Find(mapGoObject); } ReflectionHelper.InvokePrivateMethode(__instance, "PlaceLogo", new object[] { FactionEnumeration.GetFactionByName(logoItem.factionName), go }); } if (InnerSphereMap.SETTINGS.reducedClanLogos) { SimGameState sim = (SimGameState)AccessTools.Field(typeof(Starmap), "sim").GetValue(__instance.starmap); List <FactionValue> contestingFactions = new List <FactionValue>(); foreach (FactionValue faction in FactionEnumeration.FactionList) { if (faction.IsClan && faction.CanAlly) { contestingFactions.Add(faction); } } Dictionary <FactionValue, int> ranking = new Dictionary <FactionValue, int>(); foreach (StarSystem system in sim.StarSystems) { if (contestingFactions.Contains(system.OwnerValue)) { if (!ranking.ContainsKey(system.OwnerValue)) { ranking.Add(system.OwnerValue, 0); } ranking[system.OwnerValue]++; } } FactionValue invaderclan = FactionEnumeration.GetInvalidUnsetFactionValue(); if (ranking.Count > 0) { invaderclan = ranking.OrderByDescending(x => x.Value).First().Key; } if (invaderclan != FactionEnumeration.GetInvalidUnsetFactionValue()) { if (GameObject.Find("ClansInvaderLogoMap") == null) { texture2D2 = new Texture2D(2, 2); data = File.ReadAllBytes($"{InnerSphereMap.ModDirectory}/Logos/" + invaderclan.Name + "Logo.png"); texture2D2.LoadImage(data); go = UnityEngine.Object.Instantiate(__instance.restorationLogo); go.GetComponent <Renderer>().material.mainTexture = texture2D2; go.name = "ClansInvaderLogoMap"; } else { go = GameObject.Find("ClansInvaderLogoMap"); data = File.ReadAllBytes($"{InnerSphereMap.ModDirectory}/Logos/" + invaderclan.Name + "Logo.png"); texture2D2 = new Texture2D(2, 2); texture2D2.LoadImage(data); go.GetComponent <Renderer>().material.mainTexture = texture2D2; } ReflectionHelper.InvokePrivateMethode(__instance, "PlaceLogo", new object[] { invaderclan, go }); } } } catch (Exception e) { Logger.LogError(e); } }
public static void DrawEquipmentAimingPostFix(PawnRenderer __instance, Thing eq, Vector3 drawLoc, float aimAngle) { var pawn = (Pawn)AccessTools.Field(typeof(PawnRenderer), "pawn").GetValue(__instance); if (pawn != null) { ////Log.Message("1"); var pawn_EquipmentTracker = pawn.equipment; if (pawn_EquipmentTracker != null) { foreach (var thingWithComps in pawn_EquipmentTracker.AllEquipmentListForReading) { ////Log.Message("3"); if (thingWithComps != null) { ////Log.Message("4"); ////Log.Message("3"); var compDeflector = thingWithComps.GetComp <CompDeflector>(); if (compDeflector != null) { if (compDeflector.IsAnimatingNow) { var flip = false; if (!Find.TickManager.Paused && compDeflector.IsAnimatingNow) { compDeflector.AnimationDeflectionTicks -= 20; } var offset = eq.def.equippedAngleOffset; var num = aimAngle - 90f; if (aimAngle > 20f && aimAngle < 160f) { //mesh = MeshPool.plane10; num += offset; if (compDeflector.IsAnimatingNow) { num += (compDeflector.AnimationDeflectionTicks + 1) / 2; } } else if (aimAngle > 200f && aimAngle < 340f) { //mesh = MeshPool.plane10Flip; flip = true; num -= 180f; num -= offset; if (compDeflector.IsAnimatingNow) { num -= (compDeflector.AnimationDeflectionTicks + 1) / 2; } } else { //mesh = MeshPool.plane10; num += offset; if (compDeflector.IsAnimatingNow) { num += (compDeflector.AnimationDeflectionTicks + 1) / 2; } } num %= 360f; var graphic_StackCount = eq.Graphic as Graphic_StackCount; Material matSingle; if (graphic_StackCount != null) { matSingle = graphic_StackCount.SubGraphicForStackCount(1, eq.def).MatSingle; } else { matSingle = eq.Graphic.MatSingle; } //mesh = MeshPool.GridPlane(thingWithComps.def.graphicData.drawSize); //Graphics.DrawMesh(mesh, drawLoc, Quaternion.AngleAxis(num, Vector3.up), matSingle, 0); var s = new Vector3(eq.def.graphicData.drawSize.x, 1f, eq.def.graphicData.drawSize.y); var matrix = default(Matrix4x4); matrix.SetTRS(drawLoc, Quaternion.AngleAxis(num, Vector3.up), s); if (!flip) { Graphics.DrawMesh(MeshPool.plane10, matrix, matSingle, 0); } else { Graphics.DrawMesh(MeshPool.plane10Flip, matrix, matSingle, 0); } ////Log.Message("DeflectDraw"); } } } } } } }
public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { SMonitor.Log($"Transpiling DayTimeMoneyBox.draw"); var codes = new List <CodeInstruction>(instructions); for (int i = 0; i < codes.Count; i++) { if (i < codes.Count - 3 && codes[i].opcode == OpCodes.Ldc_I4_S && codes[i].operand is sbyte && (sbyte)codes[i].operand == 100 && codes[i + 1].opcode == OpCodes.Rem && codes[i + 2].opcode == OpCodes.Call && codes[i + 2].operand.Equals(AccessTools.Method(typeof(StringBuilderFormatEx), nameof(StringBuilderFormatEx.AppendEx), new Type[] { typeof(StringBuilder), typeof(int) })) && codes[i + 7].opcode == OpCodes.Ldfld && (FieldInfo)codes[i + 7].operand == AccessTools.Field(typeof(DayTimeMoneyBox), "_padZeros")) { SMonitor.Log("Overriding minute display"); codes[i + 9].opcode = OpCodes.Nop; codes[i + 8].opcode = OpCodes.Nop; codes[i + 7].opcode = OpCodes.Nop; codes[i + 6].opcode = OpCodes.Nop; codes[i + 5].opcode = OpCodes.Nop; codes[i + 4].opcode = OpCodes.Nop; codes[i + 2].opcode = OpCodes.Callvirt; codes[i + 2].operand = AccessTools.Method(typeof(StringBuilder), nameof(StringBuilder.Append), new Type[] { typeof(string) }); codes.Insert(i + 2, new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(ModEntry), nameof(ModEntry.GetActualMinutes)))); break; } } return(codes.AsEnumerable()); }
public static void RegisterBanner() { CardPool cardPool = UnityEngine.ScriptableObject.CreateInstance <CardPool>(); var cardDataList = (Malee.ReorderableArray <CardData>)AccessTools.Field(typeof(CardPool), "cardDataList").GetValue(cardPool); SubtypeData wardSub; CustomCharacterManager.CustomSubtypeData.TryGetValue("SubtypesData_Chosen", out wardSub); // This shit needs to be automated in a loop foreach (var card in CustomCardManager.CustomCardData) { if (card.Value.GetLinkedClassID() == DiscipleClan.getClan().GetID() && card.Value.GetSpawnCharacterData() != null && !card.Value.GetSpawnCharacterData().IsChampion()) { foreach (var subtype in card.Value.GetSpawnCharacterData().GetSubtypes()) { if (subtype.Key == "SubtypesData_Chosen") { cardDataList.Add(card.Value); Trainworks.Trainworks.Log(BepInEx.Logging.LogLevel.All, "Unit added to Banner: " + card.Value.GetName()); } } } } new RewardNodeDataBuilder() { RewardNodeID = "Disciple_UnitBanner", MapNodePoolIDs = new List <string> { "RandomChosenMainClassUnit", "RandomChosenSubClassUnit" }, Name = "RewardNodeData_Disciple_UnitBanner_TooltipBodyKey", Description = "RewardNodeData_Disciple_UnitBanner_TooltipTitleKey", RequiredClass = DiscipleClan.getClan(), ControllerSelectedOutline = "Clan Assets/selection_outlines.png", FrozenSpritePath = "Clan Assets/POI_Map_Clan_CDisciple_Frozen.png", EnabledSpritePath = "Clan Assets/POI_Map_Clan_CDisciple_Enabled.png", EnabledVisitedSpritePath = "Clan Assets/POI_Map_Clan_CDisciple_Enabled.png", DisabledSpritePath = "Clan Assets/POI_Map_Clan_CDisciple_Disabled.png", DisabledVisitedSpritePath = "Clan Assets/POI_Map_Clan_CDisciple_VisitedDisabled.png", GlowSpritePath = "Clan Assets/MSK_Map_Clan_CDisciple_01.png", MapIconPath = "Clan Assets/POI_Map_Clan_CDisciple_Enabled.png", MinimapIconPath = "Clan Assets/Icon_MiniMap_ClanBanner.png", SkipCheckInBattleMode = true, OverrideTooltipTitleBody = false, NodeSelectedSfxCue = "Node_Banner", RewardBuilders = new List <IRewardDataBuilder> { new DraftRewardDataBuilder() { DraftRewardID = "Disciple_UnitsDraft", _RewardSpritePath = "Clan Assets/POI_Map_Clan_CDisciple_Enabled.png", _RewardTitleKey = "ArcadianReward_Title", _RewardDescriptionKey = "ArcadianReward_Desc", Costs = new int[] { 100 }, _IsServiceMerchantReward = false, DraftPool = cardPool, ClassType = (RunState.ClassType) 7, DraftOptionsCount = 2, RarityFloorOverride = CollectableRarity.Uncommon } } }.BuildAndRegister(); }
private static object GetField(object _instance, string name) { FieldInfo fi = AccessTools.Field(_instance.GetType(), name); return(fi.GetValue(_instance)); }
/// Here we make a comparison and we trigger a field when the new values are different. /// Example: /// public void MyFunction() /// { /// ----- Fields declared before ---- /// /// ----- Function Code------ /// /// if (TrackedField1 != backupField1) /// PartModuleEvent.onPartModuleStringFieldChanged.Fire(); /// if (TrackedField2 != backupField2) /// PartModuleEvent.onPartModuleIntFieldChanged.Fire(); /// if (TrackedField3 != backupField3) /// PartModuleEvent.onPartModuleBoolFieldChanged.Fire(); /// } private void TranspileEvaluations() { var startComparisonInstructions = new List <CodeInstruction>(); var jmpInstructions = new List <CodeInstruction>(); var fields = _definition.Fields.DistinctBy(f => f.FieldName).ToList(); for (var i = 0; i < fields.Count; i++) { var field = AccessTools.Field(_originalMethod.DeclaringType, fields[i].FieldName); if (field == null) { continue; } var evaluationVar = _generator.DeclareLocal(typeof(bool)); //We write the comparision and the triggering of the event at the bottom switch (_fieldIndexToLocalVarDictionary[i]) { case 0: _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldloc_0)); break; case 1: _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldloc_1)); break; case 2: _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldloc_2)); break; case 3: _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldloc_3)); break; default: _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldloc_S, _fieldIndexToLocalVarDictionary[i])); break; } //If we are inserting the first field, redirect all the "returns" towards this instruction so we always do the comparison checks if (i == 0) { RedirectExistingReturns(_codes); } else { startComparisonInstructions.Add(_codes[_codes.Count - 2]); } //Here we generate the comparison between the fields. if (field.FieldType == typeof(Quaternion)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldarg_0)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldfld, field)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Quaternion), "op_Inequality"))); } else if (field.FieldType == typeof(Vector2)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldarg_0)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldfld, field)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Vector2), "op_Inequality"))); } else if (field.FieldType == typeof(Vector3)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldarg_0)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldfld, field)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Vector3), "op_Inequality"))); } else { //Bear in mind that we use the "ceq" opcode so the comparison that IL do is // a "==" instead of a "!=" _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldarg_0)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldfld, field)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ceq)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldc_I4_0)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ceq)); } //Here we store the result of the comparison between the fields. switch (evaluationVar.LocalIndex) { case 0: _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Stloc_0)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldloc_0)); break; case 1: _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Stloc_1)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldloc_1)); break; case 2: _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Stloc_2)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldloc_2)); break; case 3: _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Stloc_3)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldloc_3)); break; default: _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Stloc_S, evaluationVar.LocalIndex)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldloc_S, evaluationVar.LocalIndex)); break; } //If we are in the last field then return to the last "ret" of the function so we return //and exit the function in case the comparison gives us a false result (remember that we are using a == comparison) if (i == fields.Count - 1) { if (!_codes[LastIndex].labels.Any()) { _codes[LastIndex].labels.Add(_generator.DefineLabel()); } _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Brfalse_S, _codes[LastIndex].labels[0])); } else { //In case the result is false and we're not in the last field, jump to the next instruction //We will add the label that it must jump later on in the FixFallbackInstructions method var jmpInstruction = new CodeInstruction(OpCodes.Brfalse_S); _codes.Insert(LastIndex, jmpInstruction); jmpInstructions.Add(jmpInstruction); } LoadFunctionByFieldType(field.FieldType); //Here we store the field.Name value for the PartModuleEvent.onPartModuleXXXFieldChanged.Fire() parameter _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldarg_0)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldstr, field.Name)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldarg_0)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldfld, field)); if (field.FieldType.IsEnum) { //For enums we must do the call of the "ToString()" _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldarg_0)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldflda, field)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Constrained, field.FieldType)); _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Callvirt, AccessTools.Method(typeof(object), "ToString"))); } CallFunctionByFieldType(field.FieldType); } FixFallbackInstructions(startComparisonInstructions, jmpInstructions); }
static PostDefFixer() { //Add recipes to valid Genome Sequencing targets. foreach (ThingDef def in DefDatabase <ThingDef> .AllDefs.Where(def => def.category == ThingCategory.Pawn)) { if (def.GetModExtension <RaceExclusionProperties>() is RaceExclusionProperties props) { if (props.excludeThisRace) { GeneralCompatibility.excludedRaces.Add(def); } if (props.excludeTheseHediffs.Count > 0) { GeneralCompatibility.excludedHediffs.AddRange(props.excludeTheseHediffs); } } if (def.IsValidGenomeSequencingTargetDef()) { if (def.recipes == null) { def.recipes = new List <RecipeDef>(); } if (def.recipes.Count > 0) { def.recipes.Insert(0, QERecipeDefOf.QE_GenomeSequencing); } else { def.recipes.Add(QERecipeDefOf.QE_GenomeSequencing); } } if (def.IsValidBrainScanningDef()) { if (def.recipes == null) { def.recipes = new List <RecipeDef>(); } if (def.recipes.Count > 0) { def.recipes.Insert(0, QERecipeDefOf.QE_BrainScanning); } else { def.recipes.Add(QERecipeDefOf.QE_BrainScanning); } } } //Inject our own backstories. foreach (BackstoryDef def in DefDatabase <BackstoryDef> .AllDefs) { Backstory backstory = new Backstory(); backstory.slot = def.slot; backstory.title = def.title; backstory.titleShort = def.titleShort; backstory.titleFemale = def.titleFemale; backstory.titleShortFemale = def.titleShortFemale; backstory.baseDesc = def.baseDesc; AccessTools.Field(typeof(Backstory), "bodyTypeFemale").SetValue(backstory, def.bodyTypeFemale); AccessTools.Field(typeof(Backstory), "bodyTypeMale").SetValue(backstory, def.bodyTypeMale); AccessTools.Field(typeof(Backstory), "bodyTypeGlobal").SetValue(backstory, def.bodyTypeGlobal); backstory.spawnCategories.AddRange(def.spawnCategories); backstory.PostLoad(); backstory.ResolveReferences(); BackstoryDatabase.AddBackstory(backstory); def.identifier = backstory.identifier; //Log.Message("'" + def.defName + "' identifier is '" + backstory.identifier + "'"); } foreach (HediffDef def in DefDatabase <HediffDef> .AllDefs) { if (def.GetModExtension <HediffTemplateProperties>() is HediffTemplateProperties props) { if (props.includeInBrainTemplate) { QEEMod.TryLog(def.defName + " added to list of Hediffs applied to brain templates"); GeneralCompatibility.includedBrainTemplateHediffs.Add(def); } if (props.includeInGenomeTemplate) { QEEMod.TryLog(def.defName + " added to list of Hediffs applied to genome templates"); GeneralCompatibility.includedGenomeTemplateHediffs.Add(def); } } } }
/// <summary> /// Calls the correct onPartModuleXXXFieldChanged based on type /// </summary> private void LoadFunctionByFieldType(Type fieldType) { if (fieldType == typeof(bool)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleBoolFieldChanged"))); } else if (fieldType == typeof(short)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleShortFieldChanged"))); } else if (fieldType == typeof(ushort)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleUShortFieldChanged"))); } else if (fieldType == typeof(int)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleIntFieldChanged"))); } else if (fieldType == typeof(uint)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleUIntFieldChanged"))); } else if (fieldType == typeof(float)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleFloatFieldChanged"))); } else if (fieldType == typeof(long)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleLongFieldChanged"))); } else if (fieldType == typeof(ulong)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleULongFieldChanged"))); } else if (fieldType == typeof(double)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleDoubleFieldChanged"))); } else if (fieldType == typeof(string)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleStringFieldChanged"))); } else if (fieldType == typeof(Quaternion)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleQuaternionFieldChanged"))); } else if (fieldType == typeof(Vector2)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleVector2FieldChanged"))); } else if (fieldType == typeof(Vector3)) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleVector3FieldChanged"))); } else if (fieldType.IsEnum) { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleEnumFieldChanged"))); } else { _codes.Insert(LastIndex, new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PartModuleEvent), "onPartModuleObjectFieldChanged"))); } }
static IEnumerable <CodeInstruction> UnloadYourHauledInventory_MakeNewToils_Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator ilGen) { var setTarget = AccessTools.Method(typeof(Job), nameof(Job.SetTarget)); var code = instructions.ToList(); int idx = -1; int setTargetIdx = 0; for (int i = 0; i < code.Count; i++) { if (code[i].opcode == OpCodes.Callvirt && code[i].operand == setTarget) { setTargetIdx++; } if (setTargetIdx == 2) { idx = i + 1; break; } } if (idx == -1) { Log.Error($"[KanbanStockpile] Can't find insertion place"); return(code); } var checkKanbanSettings = AccessTools.Method(typeof(PickUpAndHaul_Patch), nameof(CheckKanbanSettings)); var thingMap = AccessTools.PropertyGetter(typeof(Thing), nameof(Thing.Map)); var jobDriverPawn = AccessTools.Field(typeof(JobDriver), nameof(JobDriver.pawn)); var countToDrop = AccessTools.Field(typeof(PickUpAndHaul.JobDriver_UnloadYourHauledInventory), nameof(PickUpAndHaul.JobDriver_UnloadYourHauledInventory.countToDrop)); var nestedThis = AccessTools.TypeByName("PickUpAndHaul.JobDriver_UnloadYourHauledInventory")? .GetNestedTypes(BindingFlags.Instance | BindingFlags.NonPublic) .First(t => t.FullName.Contains("c__DisplayClass4_0"))? .GetFields(BindingFlags.Instance | BindingFlags.Public) .First(x => x.Name.EndsWith("4__this")); var continueLabel = ilGen.DefineLabel(); code[idx].labels.Add(continueLabel); /* * this.job.SetTarget(TargetIndex.A, thingCount.Thing); * this.job.SetTarget(TargetIndex.B, c); * * >>> if (CheckKanbanSettings(pawn.Map, c, thingCount, ref countToDrop)) return; * * this.countToDrop = thingCount.Thing.stackCount; */ code.InsertRange(idx, new[] { new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldfld, nestedThis), new CodeInstruction(OpCodes.Ldfld, jobDriverPawn), new CodeInstruction(OpCodes.Callvirt, thingMap), new CodeInstruction(OpCodes.Ldloc_1), new CodeInstruction(OpCodes.Ldloc_0), new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldfld, nestedThis), new CodeInstruction(OpCodes.Ldflda, countToDrop), new CodeInstruction(OpCodes.Call, checkKanbanSettings), new CodeInstruction(OpCodes.Brfalse_S, continueLabel), new CodeInstruction(OpCodes.Ret) }); return(code); }
public static TickerType GetTickType(TickList tick) { FieldInfo tt = AccessTools.Field(typeof(TickList), "tickType"); return((TickerType)tt.GetValue(tick)); }
static IEnumerable <CodeInstruction> UpdateDrones_Transpiler(IEnumerable <CodeInstruction> instructions) { var found = false; var codes = new List <CodeInstruction>(instructions); for (int i = 0; i < codes.Count; i++) { if (codes[i].opcode == OpCodes.Brfalse && codes[i - 1].opcode == OpCodes.Call && codes[i + 2].opcode == OpCodes.Ldloc_S && codes[i + 1].opcode == OpCodes.Ldloc_0 && codes[i - 2].opcode == OpCodes.Ldloca_S) { found = true; codes.InsertRange(i + 1, new CodeInstruction[] { new CodeInstruction(OpCodes.Ldloc_S, 4), new CodeInstruction(OpCodes.Ldloc_S, 6), new CodeInstruction(OpCodes.Ldc_I4_2), new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(DroneManager), "BroadcastDroneOrder", new System.Type[] { typeof(int), typeof(int), typeof(int) })) }); break; } } if (!found) { NebulaModel.Logger.Log.Error("UpdateDrones transpiler 1 failed. Mod version not compatible with game version."); } found = false; for (int i = 0; i < codes.Count; i++) { if (codes[i].opcode == OpCodes.Br && codes[i - 1].opcode == OpCodes.Pop && codes[i + 2].opcode == OpCodes.Ldloc_S && codes[i + 1].opcode == OpCodes.Ldloc_0 && codes[i - 2].opcode == OpCodes.Callvirt && codes[i - 3].opcode == OpCodes.Ldloc_S) { found = true; codes.InsertRange(i + 5, new CodeInstruction[] { new CodeInstruction(OpCodes.Ldloc_S, 4), new CodeInstruction(OpCodes.Ldloc_0), new CodeInstruction(OpCodes.Ldloc_S, 4), new CodeInstruction(OpCodes.Ldelema, typeof(MechaDrone)), new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(MechaDrone), "targetObject")), new CodeInstruction(OpCodes.Ldc_I4_3), new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(DroneManager), "BroadcastDroneOrder", new System.Type[] { typeof(int), typeof(int), typeof(int) })) }); break; } } if (!found) { NebulaModel.Logger.Log.Error("UpdateDrones transpiler 2 failed. Mod version not compatible with game version."); } return(codes); }
//Refer FxHelper.SpawnFxOnGameObject static void ShowFxInfo(UnitEntityData unitEntityData) { //Choose FX GUILayout.Label($"Choose FX {FXIds.Length} available", GUILayout.Width(200f)); if (FXIds.Length == 0) { LoadFxLookup(); } GUILayout.BeginHorizontal(); fxIndex = (int)GUILayout.HorizontalSlider(fxIndex, 0, FXIds.Length - 1, GUILayout.Width(300)); if (GUILayout.Button("Prev", GUILayout.Width(45))) { fxIndex = fxIndex == 0 ? 0 : fxIndex - 1; } if (GUILayout.Button("Next", GUILayout.Width(45))) { fxIndex = fxIndex >= FXIds.Length - 1 ? FXIds.Length - 1 : fxIndex + 1; } var fxId = FXIds[fxIndex]; GUILayout.Label($"{LibraryThing.GetResourceGuidMap()[fxId]} {FXIds[fxIndex]}"); if (GUILayout.Button("Apply", GUILayout.Width(200))) { var prefab = ResourcesLibrary.TryGetResource <GameObject>(fxId); FxHelper.SpawnFxOnUnit(prefab, unitEntityData.View); } if (GUILayout.Button("Clear FX Cache", GUILayout.Width(200))) { LoadFxLookup(forceReload: true); } GUILayout.EndHorizontal(); //List of SpawnFxOnStart var spawnOnStart = unitEntityData.View.GetComponent <SpawnFxOnStart>(); if (spawnOnStart) { GUILayout.Label("Spawn on Start", GUILayout.Width(200f)); GUILayout.Label("FxOnStart " + spawnOnStart.FxOnStart?.Load()?.name, GUILayout.Width(400)); GUILayout.Label("FXFxOnDeath " + spawnOnStart.FxOnStart?.Load()?.name, GUILayout.Width(400)); } GUILayout.Label("Decals"); var decals = Traverse.Create(unitEntityData.View).Field("m_Decals").GetValue <List <FxDecal> >(); for (int i = decals.Count - 1; i >= 0; i--) { var decal = decals[i]; GUILayout.Label("Decal: " + decal.name, GUILayout.Width(400)); if (GUILayout.Button("Destroy", GUILayout.Width(200f))) { GameObject.Destroy(decal.gameObject); decals.RemoveAt(i); } } GUILayout.Label("CustomWeaponEffects", GUILayout.Width(200f)); var dollroom = Game.Instance.UI.Common.DollRoom; foreach (var kv in EffectsManager.WeaponEnchantments) { GUILayout.Label($"{kv.Key.Name} - {kv.Value.Count}"); foreach (var go in kv.Value) { GUILayout.BeginHorizontal(); GUILayout.Label($" {go?.name ?? "NULL"}"); if (dollroom != null && GUILayout.Button("UnscaleFXTimes", GUILayout.ExpandWidth(false))) { Traverse.Create(dollroom).Method("UnscaleFxTimes", new object[] { go }).GetValue(); } GUILayout.EndHorizontal(); } } GUILayout.Label("FXRoot", GUILayout.Width(200f)); foreach (Transform t in FxHelper.FxRoot.transform) { var pooledFX = t.gameObject.GetComponent <PooledFx>(); var snapToLocaters = (List <SnapToLocator>)AccessTools.Field(typeof(PooledFx), "m_SnapToLocators").GetValue(pooledFX); var fxBone = snapToLocaters.Select(s => s.Locator).FirstOrDefault(); UnitEntityView unit = null; if (fxBone != null) { var viewTransform = fxBone.Transform; while (viewTransform != null && unit == null) { unit = viewTransform.GetComponent <UnitEntityView>(); if (unit == null) { viewTransform = viewTransform.parent; } } } GUILayout.BeginHorizontal(); if (unit != null) { GUILayout.Label($"{pooledFX.name} - {unit.EntityData.CharacterName} - {unit.name}", GUILayout.Width(200f)); } else { GUILayout.Label($"{pooledFX.name}", GUILayout.Width(200f)); } if (GUILayout.Button("DestroyFX", GUILayout.Width(200))) { FxHelper.Destroy(t.gameObject); } GUILayout.EndHorizontal(); } }
public override void DoWindowContents(Rect canvas) { if (Event.current.type == EventType.Layout) { return; } // canvas.y += 35; // canvas.height -= 35f; // Widgets.DrawMenuSection(canvas); // TabDrawer.DrawTabs(canvas, MainTabs, 150f); var ListerBox = canvas.LeftPart(0.30f); ListerBox.width -= 10f; Widgets.DrawMenuSection(ListerBox); ListerBox = ListerBox.ContractedBy(4f); var innyrek = ListerBox.AtZero(); innyrek.width -= 16f; innyrek.height = moaner; var goat = 0f; Text.Anchor = TextAnchor.MiddleLeft; Text.Font = GameFont.Tiny; Widgets.BeginScrollView(ListerBox, ref scrolpostabs, innyrek); GUI.BeginGroup(innyrek); listing.Begin(innyrek); // var row = listing.getr foreach (var maintab in MainTabs) { Text.Font = GameFont.Small; Text.Anchor = TextAnchor.UpperLeft; goat += 40f; var row = listing.GetRect(30f); if (maintab.Selected) { Widgets.DrawOptionSelected(row); } if (Widgets.ButtonInvisible(row)) { maintab.clickedAction(); } row.x += 5f; Widgets.Label(row, maintab.label); TooltipHandler.TipRegion(row, maintab.Tip); Text.Anchor = TextAnchor.MiddleLeft; Text.Font = GameFont.Tiny; foreach (var mode in maintab.Modes) { if (!mode.Key.Basics && !Analyzer.Settings.AdvancedMode) { continue; } row = listing.GetRect(30f); Widgets.DrawHighlightIfMouseover(row); if (Analyzer.SelectedMode == mode.Key) { Widgets.DrawOptionSelected(row); } row.x += 20f; goat += 30f; Widgets.Label(row, mode.Key.name); if (Widgets.ButtonInvisible(row)) { if (ShowSettings) { ShowSettings = false; Analyzer.Settings.Write(); } if (Analyzer.SelectedMode != null) { AccessTools.Field(Analyzer.SelectedMode.typeRef, "Active").SetValue(null, false); } AccessTools.Field(mode.Value, "Active").SetValue(null, true); Analyzer.SelectedMode = mode.Key; Analyzer.Reset(); if (!mode.Key.IsPatched) { mode.Key.ProfilePatch(); } } TooltipHandler.TipRegion(row, mode.Key.tip); if (Analyzer.SelectedMode == mode.Key) { var doo = 0; foreach (var keySetting in mode.Key.Settings) { if (keySetting.Key.FieldType == typeof(bool)) { row = listing.GetRect(30f); row.x += 20f; GUI.color = Widgets.OptionSelectedBGBorderColor; Widgets.DrawLineVertical(row.x, row.y, 15f); if (doo != 0) { Widgets.DrawLineVertical(row.x, row.y - 15f, 15f); } row.x += 10f; Widgets.DrawLineHorizontal(row.x - 10f, row.y + 15f, 10f); GUI.color = Color.white; goat += 30f; bool cur = (bool)keySetting.Key.GetValue(null); if (DubGUI.Checkbox(row, keySetting.Value.name, ref cur)) { keySetting.Key.SetValue(null, cur); Analyzer.Reset(); } } if (keySetting.Key.FieldType == typeof(float) || keySetting.Key.FieldType == typeof(int)) { } doo++; } } } } listing.End(); moaner = goat; GUI.EndGroup(); Text.Font = GameFont.Small; Text.Anchor = TextAnchor.UpperLeft; Widgets.EndScrollView(); var inner = canvas.RightPart(0.70f).Rounded(); if (ShowSettings) { Analyzer.Settings.DoSettings(inner); } else { try { if (PatchedEverything) { if (Dialog_Graph.key != string.Empty) { Rect blurg = inner.TopPart(0.75f).Rounded(); Widgets.DrawMenuSection(blurg); blurg = blurg.ContractedBy(6f); DoThingTab(blurg); blurg = inner.BottomPart(0.25f).Rounded(); //blurg = blurg.BottomPartPixels(inner.height - 10f); Dialog_Graph.DoGraph(blurg); } else { Widgets.DrawMenuSection(inner); DoThingTab(inner.ContractedBy(6f)); } } else { Widgets.DrawMenuSection(inner); Text.Font = GameFont.Medium; Text.Anchor = TextAnchor.MiddleCenter; Widgets.Label(inner, $"Loading{GenText.MarchingEllipsis(0f)}"); Text.Font = GameFont.Small; Text.Anchor = TextAnchor.UpperLeft; } } catch (Exception e) { // Console.WriteLine(e); // throw; } } }
private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator il) { List <CodeInstruction> codes = new List <CodeInstruction>(instructions); Label yellowDuck = il.DefineLabel(); Label brownDuck = il.DefineLabel(); Label purpleDuck = il.DefineLabel(); Label greenDuck = il.DefineLabel(); Label blueDuck = il.DefineLabel(); Label redDuck = il.DefineLabel(); Label exitLabel = il.DefineLabel(); List <CodeInstruction> newCodes = new List <CodeInstruction>() { new CodeInstruction(OpCodes.Ldloc_S, 4), new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ConnectionStatusBar), "profile")), new CodeInstruction(OpCodes.Callvirt, AccessTools.Property(typeof(Profile), "networkIndex").GetGetMethod()), new CodeInstruction(OpCodes.Ldc_I4_1, null), new CodeInstruction(OpCodes.Bne_Un, yellowDuck), new CodeInstruction(OpCodes.Ldstr, "|LIGHTGRAY|"), new CodeInstruction(OpCodes.Stloc_S, 15), new CodeInstruction(OpCodes.Br, exitLabel), new CodeInstruction(OpCodes.Ldloc_S, 4) { labels = new List <Label>() { yellowDuck } }, new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ConnectionStatusBar), "profile")), new CodeInstruction(OpCodes.Callvirt, AccessTools.Property(typeof(Profile), "networkIndex").GetGetMethod()), new CodeInstruction(OpCodes.Ldc_I4_2, null), new CodeInstruction(OpCodes.Bne_Un, brownDuck), new CodeInstruction(OpCodes.Ldstr, "|DGYELLOW|"), new CodeInstruction(OpCodes.Stloc_S, 15), new CodeInstruction(OpCodes.Br, exitLabel), new CodeInstruction(OpCodes.Ldloc_S, 4) { labels = new List <Label>() { brownDuck } }, new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ConnectionStatusBar), "profile")), new CodeInstruction(OpCodes.Callvirt, AccessTools.Property(typeof(Profile), "networkIndex").GetGetMethod()), new CodeInstruction(OpCodes.Ldc_I4_3, null), new CodeInstruction(OpCodes.Bne_Un, purpleDuck), new CodeInstruction(OpCodes.Ldstr, "|MENUORANGE|"), new CodeInstruction(OpCodes.Stloc_S, 15), new CodeInstruction(OpCodes.Br, exitLabel), new CodeInstruction(OpCodes.Ldloc_S, 4) { labels = new List <Label>() { purpleDuck } }, new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ConnectionStatusBar), "profile")), new CodeInstruction(OpCodes.Callvirt, AccessTools.Property(typeof(Profile), "networkIndex").GetGetMethod()), new CodeInstruction(OpCodes.Ldc_I4_4, null), new CodeInstruction(OpCodes.Bne_Un, greenDuck), new CodeInstruction(OpCodes.Ldstr, "|DGPURPLE|"), new CodeInstruction(OpCodes.Stloc_S, 15), new CodeInstruction(OpCodes.Br, exitLabel), new CodeInstruction(OpCodes.Ldloc_S, 4) { labels = new List <Label>() { greenDuck } }, new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ConnectionStatusBar), "profile")), new CodeInstruction(OpCodes.Callvirt, AccessTools.Property(typeof(Profile), "networkIndex").GetGetMethod()), new CodeInstruction(OpCodes.Ldc_I4_5, null), new CodeInstruction(OpCodes.Bne_Un, blueDuck), new CodeInstruction(OpCodes.Ldstr, "|DGGREEN|"), new CodeInstruction(OpCodes.Stloc_S, 15), new CodeInstruction(OpCodes.Br, exitLabel), new CodeInstruction(OpCodes.Ldloc_S, 4) { labels = new List <Label>() { blueDuck } }, new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ConnectionStatusBar), "profile")), new CodeInstruction(OpCodes.Callvirt, AccessTools.Property(typeof(Profile), "networkIndex").GetGetMethod()), new CodeInstruction(OpCodes.Ldc_I4_6, null), new CodeInstruction(OpCodes.Bne_Un, redDuck), new CodeInstruction(OpCodes.Ldstr, "|DGBLUE|"), new CodeInstruction(OpCodes.Stloc_S, 15), new CodeInstruction(OpCodes.Br, exitLabel), new CodeInstruction(OpCodes.Ldloc_S, 4) { labels = new List <Label>() { redDuck } }, new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ConnectionStatusBar), "profile")), new CodeInstruction(OpCodes.Callvirt, AccessTools.Property(typeof(Profile), "networkIndex").GetGetMethod()), new CodeInstruction(OpCodes.Ldc_I4_7, null), new CodeInstruction(OpCodes.Bne_Un, exitLabel), new CodeInstruction(OpCodes.Ldstr, "|DGRED|"), new CodeInstruction(OpCodes.Stloc_S, 15), new CodeInstruction(OpCodes.Nop, null) { labels = new List <Label>() { exitLabel } }, }; codes.RemoveRange(360, 23); codes.InsertRange(360, newCodes); return(codes.AsEnumerable()); }
public static void SetField(this object instance, string fieldname, object setVal) => AccessTools.Field(instance.GetType(), fieldname).SetValue(instance, setVal);
public static void TakeItem(CharacterInventory __instance, Item takenItem, bool _tryToEquip) { try { // Gatherable, ItemContainerStatic (only not player), MerchantPouch, ItemContainer if (takenItem.ParentContainer is MerchantPouch || (takenItem.ParentContainer is ItemContainerStatic /*&& (takenItem.ParentContainer as ItemContainerStatic).IsChildToPlayer*/) || (takenItem.OwnerCharacter != null && !takenItem.OwnerCharacter.IsDead)) { //OLogger.Log($"forbiden"); return; // Only loot from dead enemies or when crafting } //OLogger.Log($"ParentContainer={takenItem.ParentContainer.GetType()}"); if ((!takenItem.IsFood && !takenItem.IsIngredient) || takenItem.IsDrink || takenItem.IsEquippable || takenItem.IsDeployable) //(takenItem.IsFood || takenItem.IsIngredient) && !takenItem.IsDrink && !takenItem.IsEquippable && !takenItem.IsDeployable { return; } //string iName = takenItem.name.Substring(0, takenItem.name.LastIndexOf('_')); string iName = takenItem.name.Split(new char[] { '_' })[0]; //OLogger.Log($"TakeItem={iName}"); //if (!m_recipes.ContainsKey(iName)) //{ // return; //} // Only ingredients not so common (like salt) // Alternative : add skills to unlock some recipes // Only items that have no RecipeItem ? Dictionary <string, Recipe> allRecipes = (Dictionary <string, Recipe>)AccessTools.Field(typeof(RecipeManager), "m_recipes").GetValue(RecipeManager.Instance); List <Recipe> lstRecipes = allRecipes.Where(r => r.Value.Ingredients.Any(i => i.ActionType == RecipeIngredient.ActionTypes.AddSpecificIngredient && i.AddedIngredient.ItemID == takenItem.ItemID) && !__instance.RecipeKnowledge.IsRecipeLearned(r.Key) // Ignore recipes already learned ).Select(r => r.Value).ToList(); foreach (var recipe in lstRecipes) { // Calculate chance of learning recipes based on item's value int itemValue = recipe.Results[0].RefItem.Value; __instance.RecipeKnowledge.LearnRecipe(recipe); //break; // only one recipe to add } } catch (Exception ex) { SelfEducatedVery.MyLogger.LogError("TakeItem: " + ex.Message); } }
public static void SetPrivateFieldValue(this object parentObject, string field, object value) { AccessTools.Field(parentObject.GetType(), field)?.SetValue(parentObject, value); }
public static IEnumerable <CodeInstruction> TranspilerPatchFor_ReinitializeComponents(IEnumerable <CodeInstruction> instructions, ILGenerator ilg) { var target_type = Type.GetType("Pathoschild.Stardew.ChestsAnywhere.Menus.Overlays.BaseChestOverlay, ChestsAnywhere"); var xna_Rectangle_ctor = AccessTools.Constructor(typeof(Microsoft.Xna.Framework.Rectangle), new Type[] { typeof(Int32), typeof(Int32), typeof(Int32), typeof(Int32) }); Boolean patched = false; var lblSkip = ilg.DefineLabel(); foreach (var instruction in instructions) { if (!patched && instruction.opcode == OpCodes.Call && (MethodBase)instruction.operand == xna_Rectangle_ctor) { yield return(instruction); yield return(new CodeInstruction(OpCodes.Ldarg_0)); yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(target_type, "Menu"))); yield return(new CodeInstruction(OpCodes.Isinst, typeof(Types.CustomTypes.ChestExMenu.MainMenu))); yield return(new CodeInstruction(OpCodes.Brfalse, lblSkip)); yield return(new CodeInstruction(OpCodes.Ldloca_S, 0)); yield return(new CodeInstruction(OpCodes.Ldarg_0)); yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(target_type, "Menu"))); yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(MenuWithInventory), "inventory"))); yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(IClickableMenu), "xPositionOnScreen"))); yield return(new CodeInstruction(OpCodes.Ldarg_0)); yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(target_type, "Menu"))); yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(MenuWithInventory), "inventory"))); yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(IClickableMenu), "yPositionOnScreen"))); yield return(new CodeInstruction(OpCodes.Ldarg_0)); yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(target_type, "Menu"))); yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(IClickableMenu), "width"))); yield return(new CodeInstruction(OpCodes.Ldarg_0)); yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(target_type, "Menu"))); yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(IClickableMenu), "height"))); yield return(instruction); var jmp = new CodeInstruction(OpCodes.Nop); jmp.labels.Add(lblSkip); yield return(jmp); patched = true; continue; } yield return(instruction); } if (patched) { GlobalVars.SMAPIMonitor.Log("Successfully patched 'ChestsAnywhere.Menus.Overlays.BaseChestOverlay.ReinitializeComponents'.", LogLevel.Info); } else { GlobalVars.SMAPIMonitor.Log("Could not patch 'ChestsAnywhere.Menus.Overlays.BaseChestOverlay.ReinitializeComponents' to move ChestsAnywhere buttons!", LogLevel.Error); } }