hotfix: weak reference to CalamityMod
for overriding the Plantera boss bag
This commit is contained in:
parent
cf7416010d
commit
a0c69dc497
2 changed files with 16 additions and 160 deletions
|
@ -5,7 +5,6 @@ using Terraria.ID;
|
|||
using Terraria.ModLoader;
|
||||
using Terraria.GameContent.ItemDropRules;
|
||||
using Continuity.Content.Items;
|
||||
using continuity.Utilities;
|
||||
|
||||
namespace Continuity.Content
|
||||
{
|
||||
|
@ -22,6 +21,7 @@ namespace Continuity.Content
|
|||
}
|
||||
}
|
||||
|
||||
[JITWhenModsEnabled("CalamityMod")]
|
||||
public class PlanteraBossBag : GlobalItem
|
||||
{
|
||||
public override void ModifyItemLoot(Item item, ItemLoot itemLoot)
|
||||
|
@ -29,6 +29,23 @@ namespace Continuity.Content
|
|||
if (item.type == ItemID.PlanteraBossBag)
|
||||
{
|
||||
itemLoot.Add(ItemDropRule.Common(ModContent.ItemType<PalishadeTissue>(), 1, 25, 35));
|
||||
|
||||
itemLoot.RemoveWhere(rule => rule is CommonDrop drop
|
||||
&& drop.itemId == ItemID.TempleKey);
|
||||
|
||||
foreach (var rule in itemLoot.Get())
|
||||
{
|
||||
itemLoot.RemoveWhere(rule => rule is OneFromRulesRule);
|
||||
|
||||
if (ModLoader.HasMod("CalamityMod"))
|
||||
{
|
||||
itemLoot.RemoveWhere(rule => rule is CalamityMod.DropHelper.AllOptionsAtOnceWithPityDropRule);
|
||||
|
||||
if (ModLoader.TryGetMod("CalamityMod", out Mod calamityMod) && calamityMod.TryFind<ModItem>("BlossomFlux", out ModItem BlossomFlux)) {
|
||||
itemLoot.RemoveWhere(rule => rule is CommonDrop drop
|
||||
&& drop.itemId == BlossomFlux.Type);
|
||||
}
|
||||
} else {
|
||||
short[] toRemove = {
|
||||
ItemID.TheAxe,
|
||||
ItemID.PygmyStaff,
|
||||
|
@ -40,20 +57,6 @@ namespace Continuity.Content
|
|||
itemLoot.RemoveWhere(rule => rule is CommonDropNotScalingWithLuck drop
|
||||
&& drop.itemId == i);
|
||||
}
|
||||
itemLoot.RemoveWhere(rule => rule is CommonDrop drop
|
||||
&& drop.itemId == ItemID.TempleKey);
|
||||
|
||||
foreach (var rule in itemLoot.Get())
|
||||
{
|
||||
itemLoot.RemoveWhere(rule => rule is OneFromRulesRule);
|
||||
if (ModLoader.HasMod("CalamityMod"))
|
||||
{
|
||||
itemLoot.RemoveWhere(rule => rule is CalamityDropHelper.AllOptionsAtOnceWithPityDropRule);
|
||||
|
||||
if (ModLoader.TryGetMod("CalamityMod", out Mod calamityMod) && calamityMod.TryFind<ModItem>("BlossomFlux", out ModItem BlossomFlux)) {
|
||||
itemLoot.RemoveWhere(rule => rule is CommonDrop drop
|
||||
&& drop.itemId == BlossomFlux.Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,147 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
using Terraria.GameContent.ItemDropRules;
|
||||
using Terraria.Utilities;
|
||||
using Terraria;
|
||||
|
||||
// Repurposed from https://github.com/CalamityTeam/CalamityModPublic/blob/1.4.4/Utilities/DropHelper.cs
|
||||
namespace continuity.Utilities
|
||||
{
|
||||
internal class CalamityDropHelper
|
||||
{
|
||||
public struct Fraction
|
||||
{
|
||||
internal readonly int numerator;
|
||||
internal readonly int denominator;
|
||||
|
||||
public Fraction(int n, int d)
|
||||
{
|
||||
numerator = n < 0 ? 0 : n;
|
||||
denominator = d <= 0 ? 1 : d;
|
||||
}
|
||||
|
||||
public static implicit operator float(Fraction f) => f.numerator / (float)f.denominator;
|
||||
}
|
||||
|
||||
|
||||
public struct WeightedItemStack
|
||||
{
|
||||
public const float DefaultWeight = 1f;
|
||||
public const float MinisiculeWeight = 1E-6f;
|
||||
|
||||
internal int itemID;
|
||||
internal float weight;
|
||||
internal int minQuantity;
|
||||
internal int maxQuantity;
|
||||
|
||||
internal WeightedItemStack(int id, float w)
|
||||
{
|
||||
itemID = id;
|
||||
weight = w;
|
||||
minQuantity = 1;
|
||||
maxQuantity = 1;
|
||||
}
|
||||
|
||||
internal WeightedItemStack(int id, float w, int quantity)
|
||||
{
|
||||
itemID = id;
|
||||
weight = w;
|
||||
minQuantity = quantity;
|
||||
maxQuantity = quantity;
|
||||
}
|
||||
|
||||
internal WeightedItemStack(int id, float w, int min, int max)
|
||||
{
|
||||
itemID = id;
|
||||
weight = w;
|
||||
minQuantity = min;
|
||||
maxQuantity = max;
|
||||
}
|
||||
|
||||
internal int ChooseQuantity(UnifiedRandom rng) => rng.Next(minQuantity, maxQuantity + 1);
|
||||
|
||||
// Allow for implicitly casting integer item IDs into weighted item stacks.
|
||||
// Stack size is assumed to be 1. Weight is assumed to be default.
|
||||
public static implicit operator WeightedItemStack(int id)
|
||||
{
|
||||
return new WeightedItemStack(id, DefaultWeight, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public class AllOptionsAtOnceWithPityDropRule : IItemDropRule
|
||||
{
|
||||
public WeightedItemStack[] stacks;
|
||||
public Fraction dropRate;
|
||||
public bool usesLuck;
|
||||
public List<IItemDropRuleChainAttempt> ChainedRules { get; set; }
|
||||
|
||||
public AllOptionsAtOnceWithPityDropRule(Fraction dropRate, bool luck, params WeightedItemStack[] stacks)
|
||||
{
|
||||
this.dropRate = dropRate;
|
||||
this.stacks = stacks;
|
||||
usesLuck = luck;
|
||||
ChainedRules = new List<IItemDropRuleChainAttempt>();
|
||||
}
|
||||
|
||||
public AllOptionsAtOnceWithPityDropRule(Fraction dropRate, bool luck, params int[] itemIDs)
|
||||
{
|
||||
this.dropRate = dropRate;
|
||||
stacks = new WeightedItemStack[itemIDs.Length];
|
||||
for (int i = 0; i < stacks.Length; ++i)
|
||||
stacks[i] = itemIDs[i]; // implicit conversion operator
|
||||
usesLuck = luck;
|
||||
ChainedRules = new List<IItemDropRuleChainAttempt>();
|
||||
}
|
||||
|
||||
public bool CanDrop(DropAttemptInfo info) => true;
|
||||
|
||||
public ItemDropAttemptResult TryDroppingItem(DropAttemptInfo info)
|
||||
{
|
||||
bool droppedAnything = false;
|
||||
|
||||
// Roll for each drop individually.
|
||||
foreach (WeightedItemStack stack in stacks)
|
||||
{
|
||||
bool rngRoll = usesLuck ? info.player.RollLuck(dropRate.denominator) < dropRate.numerator : info.rng.NextFloat() < dropRate;
|
||||
droppedAnything |= rngRoll;
|
||||
if (rngRoll)
|
||||
CommonCode.DropItem(info, stack.itemID, stack.ChooseQuantity(info.rng));
|
||||
}
|
||||
|
||||
// If everything fails to drop, force drop one item from the set.
|
||||
if (!droppedAnything)
|
||||
{
|
||||
WeightedItemStack stack = info.rng.NextFromList(stacks);
|
||||
CommonCode.DropItem(info, stack.itemID, stack.ChooseQuantity(info.rng));
|
||||
}
|
||||
|
||||
// Calamity style drops cannot fail. You will always get at least one item.
|
||||
ItemDropAttemptResult result = default;
|
||||
result.State = ItemDropAttemptResultState.Success;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void ReportDroprates(List<DropRateInfo> drops, DropRateInfoChainFeed ratesInfo)
|
||||
{
|
||||
int numDrops = stacks.Length;
|
||||
float rawDropRate = dropRate;
|
||||
// Combinatorics:
|
||||
// OPTION 1: [The item drops = Raw Drop Rate]
|
||||
// +
|
||||
// OPTION 2: [ALL items fail to drop = (1-x)^n] * [This item is chosen as pity = 1/n]
|
||||
float dropRateWithPityRoll = rawDropRate + (float)(Math.Pow(1f - rawDropRate, numDrops) * (1f / numDrops));
|
||||
float dropRateAdjustedForParent = dropRateWithPityRoll * ratesInfo.parentDroprateChance;
|
||||
|
||||
// Report the drop rate of each individual item. This calculation includes the fact that each individual item can be guaranteed as pity.
|
||||
foreach (WeightedItemStack stack in stacks)
|
||||
drops.Add(new DropRateInfo(stack.itemID, stack.minQuantity, stack.maxQuantity, dropRateAdjustedForParent, ratesInfo.conditions));
|
||||
|
||||
Chains.ReportDroprates(ChainedRules, rawDropRate, drops, ratesInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in a new issue