Esempio n. 1
0
        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();
        }
Esempio n. 2
0
        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();
            };
        }
Esempio n. 3
0
        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();
            };
        }