private static void RunOnBuildDropTable(On.RoR2.Run.orig_BuildDropTable orig, Run self) { orig(self); if (DefaultDrops) { // Setup default item lists DefaultItemDrops.AddDefaults(); } // These lists should be replaced soon. self.availableTier1DropList.Clear(); self.availableTier1DropList.AddRange(GetDefaultDropList(ItemTier.Tier1).Select(x => PickupCatalog.FindPickupIndex(x)) .ToList()); self.availableTier2DropList.Clear(); self.availableTier2DropList.AddRange(GetDefaultDropList(ItemTier.Tier2).Select(x => PickupCatalog.FindPickupIndex(x)) .ToList()); self.availableTier3DropList.Clear(); self.availableTier3DropList.AddRange(GetDefaultDropList(ItemTier.Tier3).Select(x => PickupCatalog.FindPickupIndex(x)) .ToList()); self.availableEquipmentDropList.Clear(); self.availableEquipmentDropList.AddRange(GetDefaultEquipmentDropList().Select(x => PickupCatalog.FindPickupIndex(x)) .ToList()); self.availableLunarDropList.Clear(); self.availableLunarDropList.AddRange(GetDefaultLunarDropList()); self.smallChestDropTierSelector.Clear(); self.smallChestDropTierSelector.AddChoice(self.availableTier1DropList, DefaultSmallChestTier1SelectorDropChance); self.smallChestDropTierSelector.AddChoice(self.availableTier2DropList, DefaultSmallChestTier2SelectorDropChance); self.smallChestDropTierSelector.AddChoice(self.availableTier3DropList, DefaultSmallChestTier3SelectorDropChance); self.mediumChestDropTierSelector.Clear(); self.mediumChestDropTierSelector.AddChoice(self.availableTier2DropList, DefaultMediumChestTier1SelectorDropChance); self.mediumChestDropTierSelector.AddChoice(self.availableTier3DropList, DefaultMediumChestTier2SelectorDropChance); self.largeChestDropTierSelector.Clear(); }
public static void InitHooks() { var itemDropApi_GetSelection = typeof(ItemDropAPI).GetMethodCached("GetSelection"); var xoroshiro_GetNextNormalizedFloat = typeof(Xoroshiro128Plus).GetMethodCached("get_nextNormalizedFloat"); IL.RoR2.BossGroup.OnCharacterDeathCallback += il => { var cursor = new ILCursor(il).Goto(0); cursor.GotoNext(x => x.MatchCall(typeof(PickupIndex).GetMethodCached("get_itemIndex"))); var itemIndex = (VariableDefinition)cursor.Next.Next.Operand; cursor.Goto(0); cursor.GotoNext(x => x.MatchCallvirt(typeof(List <PickupIndex>).GetMethodCached("get_Item"))); var pickupIndex = (VariableDefinition)cursor.Next.Next.Operand; cursor.GotoNext(MoveType.Before, x => x.MatchStloc(itemIndex.Index)); cursor.Emit(OpCodes.Stloc_S, itemIndex); cursor.Emit(OpCodes.Ldc_I4_0); cursor.Emit(OpCodes.Ldarg_0); cursor.Emit(OpCodes.Ldfld, typeof(BossGroup).GetFieldCached("rng")); cursor.Emit(OpCodes.Callvirt, xoroshiro_GetNextNormalizedFloat); cursor.Emit(OpCodes.Call, itemDropApi_GetSelection); cursor.Emit(OpCodes.Stloc_S, pickupIndex); cursor.Emit(OpCodes.Ldloca_S, pickupIndex); cursor.Emit(OpCodes.Call, typeof(PickupIndex).GetMethodCached("get_itemIndex")); }; var dropPickup = typeof(ChestBehavior).GetFieldCached("dropPickup"); var lunarChance = typeof(ChestBehavior).GetFieldCached("lunarChance"); var tier1Chance = typeof(ChestBehavior).GetFieldCached("tier1Chance"); var tier2Chance = typeof(ChestBehavior).GetFieldCached("tier2Chance"); var tier3Chance = typeof(ChestBehavior).GetFieldCached("tier3Chance"); IL.RoR2.ChestBehavior.RollItem += il => { var cursor = new ILCursor(il).Goto(0); cursor.GotoNext(x => x.MatchLdcI4(8)); cursor.Emit(OpCodes.Ldarg_0); cursor.EmitDelegate <Action <ChestBehavior> >(@this => { if ((PickupIndex)dropPickup.GetValue(@this) != PickupIndex.none) { return; } if ((float)lunarChance.GetValue(@this) >= 1f) { @this.dropPickup = GetSelection(ItemDropLocation.LunarChest, Run.instance.treasureRng.nextNormalizedFloat); } else if ((float)tier3Chance.GetValue(@this) >= 0.2f) { @this.dropPickup = GetSelection(ItemDropLocation.LargeChest, Run.instance.treasureRng.nextNormalizedFloat); } else if ((float)tier2Chance.GetValue(@this) >= 0.8f) { @this.dropPickup = GetSelection(ItemDropLocation.MediumChest, Run.instance.treasureRng.nextNormalizedFloat); } else if ((float)tier1Chance.GetValue(@this) <= 0.8f) { @this.dropPickup = GetSelection(ItemDropLocation.SmallChest, Run.instance.treasureRng.nextNormalizedFloat); } }); cursor.Emit(OpCodes.Ret); }; var weightedSelection_Evaluate = typeof(WeightedSelection <PickupIndex>).GetMethodCached("Evaluate"); IL.RoR2.ShrineChanceBehavior.AddShrineStack += il => { var cursor = new ILCursor(il).Goto(0); cursor.GotoNext(x => x.MatchCallvirt(weightedSelection_Evaluate)); cursor.Next.OpCode = OpCodes.Nop; cursor.Next.Operand = null; cursor.EmitDelegate <Func <WeightedSelection <PickupIndex>, float, PickupIndex> >((_, x) => GetSelection(ItemDropLocation.Shrine, x)); }; On.RoR2.Run.BuildDropTable += (orig, self) => { if (DefaultDrops) { // Setup default item lists DefaultItemDrops.AddDefaults(); } self.availableTier1DropList.Clear(); self.availableTier1DropList.AddRange(GetDefaultDropList(ItemTier.Tier1).Select(x => new PickupIndex(x)) .ToList()); self.availableTier2DropList.Clear(); self.availableTier2DropList.AddRange(GetDefaultDropList(ItemTier.Tier2).Select(x => new PickupIndex(x)) .ToList()); self.availableTier3DropList.Clear(); self.availableTier3DropList.AddRange(GetDefaultDropList(ItemTier.Tier3).Select(x => new PickupIndex(x)) .ToList()); self.availableEquipmentDropList.Clear(); self.availableEquipmentDropList.AddRange(GetDefaultEquipmentDropList().Select(x => new PickupIndex(x)) .ToList()); self.availableLunarDropList.Clear(); self.availableLunarDropList.AddRange(GetDefaultLunarDropList()); self.smallChestDropTierSelector.Clear(); self.smallChestDropTierSelector.AddChoice(self.availableTier1DropList, 0.8f); self.smallChestDropTierSelector.AddChoice(self.availableTier2DropList, 0.2f); self.smallChestDropTierSelector.AddChoice(self.availableTier3DropList, 0.01f); self.mediumChestDropTierSelector.Clear(); self.mediumChestDropTierSelector.AddChoice(self.availableTier2DropList, 0.8f); self.mediumChestDropTierSelector.AddChoice(self.availableTier3DropList, 0.2f); self.largeChestDropTierSelector.Clear(); }; }
internal static void InitHooks() { var itemDropApi_GetSelection = typeof(ItemDropAPI).GetMethodCached("GetSelection"); var xoroshiro_GetNextNormalizedFloat = typeof(Xoroshiro128Plus).GetMethodCached("get_nextNormalizedFloat"); Logger.LogDebug($"{nameof(ItemDropAPI)} - Hook 1"); IL.RoR2.BossGroup.OnCharacterDeathCallback += il => { var cursor = new ILCursor(il).Goto(0); cursor.GotoNext(x => x.MatchCall(typeof(PickupIndex).GetMethodCached("get_itemIndex"))); var itemIndex = (VariableDefinition)cursor.Next.Next.Operand; cursor.Goto(0); cursor.GotoNext(x => x.MatchCall(typeof(PickupIndex).GetConstructorCached(new[] { typeof(ItemIndex) }))); cursor.GotoPrev(x => x.OpCode == OpCodes.Ldloca_S); var pickupIndex = (VariableDefinition)cursor.Next.Operand; cursor.Goto(0); cursor.GotoNext(x => x.MatchStloc(itemIndex.Index)); cursor.Emit(OpCodes.Stloc_S, itemIndex); cursor.Emit(OpCodes.Ldc_I4_0); cursor.Emit(OpCodes.Ldarg_0); cursor.Emit(OpCodes.Ldfld, typeof(BossGroup).GetFieldCached("rng")); cursor.Emit(OpCodes.Callvirt, xoroshiro_GetNextNormalizedFloat); cursor.Emit(OpCodes.Call, itemDropApi_GetSelection); cursor.Emit(OpCodes.Stloc_S, pickupIndex); cursor.Emit(OpCodes.Ldloca_S, pickupIndex); cursor.Emit(OpCodes.Call, typeof(PickupIndex).GetMethodCached("get_itemIndex")); }; On.RoR2.ChestBehavior.RollItem += (orig, self) => { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.ChestBehavior::RollItem()' called on client"); return; } if (self.GetFieldValue <PickupIndex>("dropPickup") != PickupIndex.none) { return; } if (self.GetFieldValue <float>("lunarChance") >= 1f) { self.SetFieldValue("dropPickup", GetSelection(ItemDropLocation.LunarChest, Run.instance.treasureRng.nextNormalizedFloat)); } else if (self.GetFieldValue <float>("tier3Chance") >= 0.2f) { self.SetFieldValue("dropPickup", GetSelection(ItemDropLocation.LargeChest, Run.instance.treasureRng.nextNormalizedFloat)); } else if (self.GetFieldValue <float>("tier2Chance") >= 0.8f) { self.SetFieldValue("dropPickup", GetSelection(ItemDropLocation.MediumChest, Run.instance.treasureRng.nextNormalizedFloat)); } else if (self.GetFieldValue <float>("tier1Chance") <= 0.8f) { self.SetFieldValue("dropPickup", GetSelection(ItemDropLocation.SmallChest, Run.instance.treasureRng.nextNormalizedFloat)); } }; var weightedSelection_Evaluate = typeof(WeightedSelection <PickupIndex>).GetMethodCached("Evaluate"); Logger.LogDebug($"{nameof(ItemDropAPI)} - Hook 3"); IL.RoR2.ShrineChanceBehavior.AddShrineStack += il => { var cursor = new ILCursor(il).Goto(0); cursor.GotoNext(x => x.MatchCallvirt(weightedSelection_Evaluate)); cursor.Next.OpCode = OpCodes.Nop; cursor.Next.Operand = null; cursor.EmitDelegate <Func <WeightedSelection <PickupIndex>, float, PickupIndex> >((_, x) => GetSelection(ItemDropLocation.Shrine, x)); }; Logger.LogDebug($"{nameof(ItemDropAPI)} - Hook 4"); On.RoR2.Run.BuildDropTable += (orig, self) => { if (DefaultDrops) { // Setup default item lists DefaultItemDrops.AddDefaults(); } // These lists should be replaced soon. self.availableTier1DropList.Clear(); self.availableTier1DropList.AddRange(GetDefaultDropList(ItemTier.Tier1).Select(x => new PickupIndex(x)) .ToList()); self.availableTier2DropList.Clear(); self.availableTier2DropList.AddRange(GetDefaultDropList(ItemTier.Tier2).Select(x => new PickupIndex(x)) .ToList()); self.availableTier3DropList.Clear(); self.availableTier3DropList.AddRange(GetDefaultDropList(ItemTier.Tier3).Select(x => new PickupIndex(x)) .ToList()); self.availableEquipmentDropList.Clear(); self.availableEquipmentDropList.AddRange(GetDefaultEquipmentDropList().Select(x => new PickupIndex(x)) .ToList()); self.availableLunarDropList.Clear(); self.availableLunarDropList.AddRange(GetDefaultLunarDropList()); self.smallChestDropTierSelector.Clear(); self.smallChestDropTierSelector.AddChoice(self.availableTier1DropList, DefaultSmallChestTier1SelectorDropChance); self.smallChestDropTierSelector.AddChoice(self.availableTier2DropList, DefaultSmallChestTier2SelectorDropChance); self.smallChestDropTierSelector.AddChoice(self.availableTier3DropList, DefaultSmallChestTier3SelectorDropChance); self.mediumChestDropTierSelector.Clear(); self.mediumChestDropTierSelector.AddChoice(self.availableTier2DropList, DefaultMediumChestTier1SelectorDropChance); self.mediumChestDropTierSelector.AddChoice(self.availableTier3DropList, DefaultMediumChestTier2SelectorDropChance); self.largeChestDropTierSelector.Clear(); }; }