public static void MonsterDrop_Postfix(GameLocation __instance, Monster monster, int x, int y, Farmer who) { try { if (who == Game1.player) { // Make the monster drop an augmentor if you're lucky double Chance = MachineAugmentorsMod.UserConfig.MonsterLootSettings.GetAugmentorDropChance(__instance, monster, out double BaseChance, out double LocationMultiplier, out double ExpMultiplier, out double HPMultiplier); bool Success = Augmentor.Randomizer.NextDouble() <= Chance; string LogMessage; if (Success) { int SpawnDirection = Augmentor.Randomizer.Next(4); int NumTypes = Enum.GetValues(typeof(AugmentorType)).Length; AugmentorType Type = (AugmentorType)Augmentor.Randomizer.Next(NumTypes); int Quantity = Augmentor.RollDice(0.1) ? 2 : 1; Game1.createItemDebris(Augmentor.CreateInstance(Type, Quantity), Game1.player.getStandingPosition(), SpawnDirection, null, -1); LogMessage = string.Format("Succeeded drop chance: Location = {0}, monster.ExperienceGained = {1}, monster.MaxHealth = {2}\n" + "BaseChance = {3} ({4}%), LocationMultiplier = {5} (+{6}%), ExpMultiplier = {7}, HPMultiplier = {8} (+{9}%), TotalChance = {10} ({11}%)", __instance.Name, monster.ExperienceGained, monster.MaxHealth, BaseChance, (BaseChance * 100.0).ToString("0.##"), LocationMultiplier, ((LocationMultiplier - 1.0) * 100.0).ToString("0.##"), ExpMultiplier.ToString("#.####"), HPMultiplier, ((HPMultiplier - 1.0) * 100.0).ToString("0.##"), Chance, (Chance * 100.0).ToString("0.###")); } else { LogMessage = string.Format("Failed drop chance: Location = {0}, monster.ExperienceGained = {1}, monster.MaxHealth = {2}\n" + "BaseChance = {3} ({4}%), LocationMultiplier = {5} (+{6}%), ExpMultiplier = {7}, HPMultiplier = {8} (+{9}%), TotalChance = {10} ({11}%)", __instance.Name, monster.ExperienceGained, monster.MaxHealth, BaseChance, (BaseChance * 100.0).ToString("0.##"), LocationMultiplier, ((LocationMultiplier - 1.0) * 100.0).ToString("0.##"), ExpMultiplier.ToString("#.####"), HPMultiplier, ((HPMultiplier - 1.0) * 100.0).ToString("0.##"), Chance, (Chance * 100.0).ToString("0.###")); } #if DEBUG MachineAugmentorsMod.ModInstance.Monitor.Log(LogMessage, LogLevel.Debug); #else MachineAugmentorsMod.ModInstance.Monitor.Log(LogMessage, LogLevel.Trace); #endif } } catch (Exception ex) { MachineAugmentorsMod.ModInstance.Monitor.Log(string.Format("Unhandled Error in {0}:\n{1}", nameof(MonsterDrop_Postfix), ex), LogLevel.Error); } }
public static void MonsterDrop_Postfix(GameLocation __instance, Monster monster, int x, int y, Farmer who) { try { MonsterLootSettings LootSettings = MonsterLootSettings; if (who.UniqueMultiplayerID == Game1.player.UniqueMultiplayerID && LootSettings.CanReceiveBagsAsDrops) { // Roll chance at receiving an ItemBag double Chance = LootSettings.GetItemBagDropChance(__instance, monster, out double BaseChance, out double LocationMultiplier, out double ExpMultiplier, out double HPMultiplier); bool Success = Randomizer.NextDouble() <= Chance; string LogMessage; if (Success) { if (MonsterLootSettings.LogDropChancesToConsole) { LogMessage = string.Format("Succeeded drop chance: Location = {0}, monster.ExperienceGained = {1}, monster.MaxHealth = {2}\n" + "BaseChance = {3} ({4}%), LocationMultiplier = {5} (+{6}%), ExpMultiplier = {7}, HPMultiplier = {8} (+{9}%), TotalChance = {10} ({11}%)", __instance.Name, monster.ExperienceGained, monster.MaxHealth, BaseChance, (BaseChance * 100.0).ToString("0.##"), LocationMultiplier, ((LocationMultiplier - 1.0) * 100.0).ToString("0.##"), ExpMultiplier.ToString("#.####"), HPMultiplier, ((HPMultiplier - 1.0) * 100.0).ToString("0.##"), Chance, (Chance * 100.0).ToString("0.###")); Monitor.Log(LogMessage, LogLevel.Info); } int SpawnDirection = Randomizer.Next(4); List <ItemBag> OwnedBags = ItemBag.GetAllBags(true); // Compute the odds of receiving each type of bag bool CanReceiveRucksack = LootSettings.RucksackDropSettings.SizeWeights.Any(size => size.Value > 0); int RucksackWeight = CanReceiveRucksack ? LootSettings.RucksackDropSettings.TypeWeight : 0; bool CanReceiveOmniBag = LootSettings.OmniBagDropSettings.SizeWeights.Any(size => size.Value > 0); int OmniBagWeight = CanReceiveOmniBag ? LootSettings.OmniBagDropSettings.TypeWeight : 0; bool CanReceiveBundleBag = LootSettings.BundleBagDropSettings.SizeWeights.Any(size => BundleBag.ValidSizes.Contains(size.Key) && size.Value > 0 && !IsSizeObsolete(OwnedBags, BundleBag.BundleBagTypeId, size.Key)); int BundleBagWeight = CanReceiveBundleBag ? LootSettings.BundleBagDropSettings.TypeWeight : 0; bool CanReceiveStandardBag = LootSettings.StandardBagDropSettings.SizeWeights.Any(size => size.Value > 0); int StandardBagWeight = CanReceiveStandardBag ? LootSettings.StandardBagDropSettings.TypeWeight : 0; int TotalTypeWeight = RucksackWeight + OmniBagWeight + BundleBagWeight + StandardBagWeight; if (TotalTypeWeight > 0) { ItemBag ChosenBag; // Pick the type of bag to spawn (Rucksack, OmniBag, BundleBag or a standard BoundedBag) int ChosenTypeWeight = Randomizer.Next(0, TotalTypeWeight); if (ChosenTypeWeight < RucksackWeight) { ContainerSize CurrentSize = GetWeightedRandomSize(LootSettings.RucksackDropSettings.SizeWeights); // Try to force a non-obsolete bag to spawn if (RollDice(LootSettings.ForceNewBagTypeChance)) { List <ContainerSize> ValidSizes = LootSettings.RucksackDropSettings.SizeWeights.Where(size => size.Value > 0).Select(size => size.Key).ToList(); ContainerSize MaxSize = ValidSizes.DefaultIfEmpty(ContainerSize.Small).Max(); while (CurrentSize < MaxSize && IsSizeObsolete(OwnedBags, Rucksack.RucksackTypeId, CurrentSize)) { CurrentSize = ValidSizes.Where(size => size > CurrentSize).OrderBy(size => size).First(); } } // Spawn a Rucksack ChosenBag = new Rucksack(CurrentSize, false); } else if (ChosenTypeWeight < RucksackWeight + OmniBagWeight) { ContainerSize CurrentSize = GetWeightedRandomSize(LootSettings.OmniBagDropSettings.SizeWeights); // Try to force a non-obsolete bag to spawn if (RollDice(LootSettings.ForceNewBagTypeChance)) { List <ContainerSize> ValidSizes = LootSettings.OmniBagDropSettings.SizeWeights.Where(size => size.Value > 0).Select(size => size.Key).ToList(); ContainerSize MaxSize = ValidSizes.DefaultIfEmpty(ContainerSize.Small).Max(); while (CurrentSize < MaxSize && IsSizeObsolete(OwnedBags, OmniBag.OmniBagTypeId, CurrentSize)) { CurrentSize = ValidSizes.Where(size => size > CurrentSize).OrderBy(size => size).First(); } } // Spawn an OmniBag ChosenBag = new OmniBag(CurrentSize); } else if (ChosenTypeWeight < RucksackWeight + OmniBagWeight + BundleBagWeight) { // Spawn a BundleBag ContainerSize Size = GetWeightedRandomSize(LootSettings.BundleBagDropSettings.SizeWeights.Where(size => BundleBag.ValidSizes.Contains(size.Key) && !IsSizeObsolete(OwnedBags, BundleBag.BundleBagTypeId, size.Key))); ChosenBag = new BundleBag(Size, true); } else { ContainerSize CurrentSize = GetWeightedRandomSize(LootSettings.StandardBagDropSettings.SizeWeights); // Get all standard BagTypes that are available in the chosen size List <BagType> StandardTypes = ItemBagsMod.BagConfig.BagTypes.Where(type => type.SizeSettings.Any(sizeCfg => sizeCfg.Size == CurrentSize)).ToList(); // Try to force a non-obsolete bag to spawn if (RollDice(LootSettings.ForceNewBagTypeChance)) { StandardTypes.RemoveAll(type => IsSizeObsolete(OwnedBags, type.Id, CurrentSize)); // If all bag types were obsolete, then keep incrementing the size until we find a non-obsolete bag to spawn if (!StandardTypes.Any()) { List <ContainerSize> ValidSizes = LootSettings.StandardBagDropSettings.SizeWeights.Where(size => size.Value > 0).Select(size => size.Key).ToList(); ContainerSize MaxSize = ValidSizes.DefaultIfEmpty(ContainerSize.Small).Max(); while (CurrentSize < MaxSize && !StandardTypes.Any()) { CurrentSize = ValidSizes.Where(size => size > CurrentSize).OrderBy(size => size).First(); StandardTypes = ItemBagsMod.BagConfig.BagTypes.Where(type => type.SizeSettings.Any(sizeCfg => sizeCfg.Size == CurrentSize) && !IsSizeObsolete(OwnedBags, type.Id, CurrentSize)).ToList(); } } } if (StandardTypes.Any()) { // Spawn a standard BoundedBag int ChosenTypeIndex = Randomizer.Next(StandardTypes.Count); ChosenBag = new BoundedBag(StandardTypes[ChosenTypeIndex], CurrentSize, false); } else { ChosenBag = null; } } if (ChosenBag != null) { Game1.createItemDebris(ChosenBag, Game1.player.getStandingPosition(), SpawnDirection, null, -1); } } } else if (MonsterLootSettings.LogDropChancesToConsole) { LogMessage = string.Format("Failed drop chance: Location = {0}, monster.ExperienceGained = {1}, monster.MaxHealth = {2}\n" + "BaseChance = {3} ({4}%), LocationMultiplier = {5} (+{6}%), ExpMultiplier = {7}, HPMultiplier = {8} (+{9}%), TotalChance = {10} ({11}%)", __instance.Name, monster.ExperienceGained, monster.MaxHealth, BaseChance, (BaseChance * 100.0).ToString("0.##"), LocationMultiplier, ((LocationMultiplier - 1.0) * 100.0).ToString("0.##"), ExpMultiplier.ToString("#.####"), HPMultiplier, ((HPMultiplier - 1.0) * 100.0).ToString("0.##"), Chance, (Chance * 100.0).ToString("0.###")); Monitor.Log(LogMessage, LogLevel.Info); } } } catch (Exception ex) { Monitor.Log(string.Format("Unhandled Error in {0}:\n{1}", nameof(MonsterDrop_Postfix), ex), LogLevel.Error); } }