Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion EpicLoot/Crafting/AugmentChoiceDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public void Show(ItemDrop.ItemData fromItem, int effectIndex, Action<ItemDrop.It
var button = EffectChoiceButtons[index];
button.gameObject.SetActive(true);
var text = button.GetComponentInChildren<TMP_Text>();
text.text = Localization.instance.Localize((index == 0 ? "<color=white>($mod_epicloot_augment_keep)</color> " : "") + MagicItem.GetEffectText(effect, rarity, true));
text.text = Localization.instance.Localize((index == 0 ? "<color=white>($mod_epicloot_augment_keep)</color> " : "") + MagicItem.GetEffectText(effect, rarity, magicItem.Quality, fromItem.m_shared.m_name, true, magicItem.LegendaryID));
text.color = rarityColor;

if (EpicLoot.HasAuga)
Expand Down
4 changes: 2 additions & 2 deletions EpicLoot/Crafting/AugmentHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public static List<MagicItemEffectDefinition> GetAvailableAugments(AugmentRecipe
if (recipe.EffectIndex >= 0 && recipe.EffectIndex < magicItem.Effects.Count)
{
var currentEffectDef = MagicItemEffectDefinitions.Get(magicItem.Effects[recipe.EffectIndex].EffectType);
valuelessEffect = currentEffectDef.GetValuesForRarity(rarity) == null;
valuelessEffect = currentEffectDef.GetValuesForRarity(rarity, item.m_shared.m_name, magicItem.Quality) == null;
}

return MagicItemEffectDefinitions.GetAvailableEffects(item.Extended(), item.GetMagicItem(), valuelessEffect ? -1 : recipe.EffectIndex);
Expand All @@ -179,7 +179,7 @@ public static string GetAugmentSelectorText(MagicItem magicItem, int i, IReadOnl
{
var pip = EpicLoot.GetMagicEffectPip(magicItem.IsEffectAugmented(i));
bool free = EnchantCostsHelper.EffectIsDeprecated(augmentableEffects[i].EffectType);
return $"{pip} {Localization.instance.Localize(MagicItem.GetEffectText(augmentableEffects[i], rarity, true))}{(free ? " [<color=yellow>*FREE</color>]" : "")}";
return $"{pip} {Localization.instance.Localize(MagicItem.GetEffectText(augmentableEffects[i], rarity, magicItem.Quality, magicItem.ItemName, true, magicItem.LegendaryID))}{(free ? " [<color=yellow>*FREE</color>]" : "")}";
}

public static List<KeyValuePair<ItemDrop, int>> GetAugmentCosts(ItemDrop.ItemData item, int recipeEffectIndex)
Expand Down
2 changes: 1 addition & 1 deletion EpicLoot/Crafting/AugmentsAvailableDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public void Show(AugmentHelper.AugmentRecipe recipe)

foreach (var effectDef in availableEffects)
{
var values = effectDef.GetValuesForRarity(item.GetRarity());
var values = effectDef.GetValuesForRarity(item.GetRarity(), item.m_shared.m_name, magicItem.Quality);
var valueDisplay = values != null ? Mathf.Approximately(values.MinValue, values.MaxValue) ? $"{values.MinValue}" : $"({values.MinValue}-{values.MaxValue})" : "";
t.AppendLine($"‣ {string.Format(Localization.instance.Localize(effectDef.DisplayText), valueDisplay)}");
}
Expand Down
8 changes: 4 additions & 4 deletions EpicLoot/CraftingV2/EnchantingUIController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ private static string GetEnchantInfo(ItemDrop.ItemData item, MagicRarityUnity _r

foreach (var effectDef in availableEffects)
{
var values = effectDef.GetValuesForRarity(rarity);
var values = effectDef.GetValuesForRarity(rarity, item.m_shared.m_name, ItemQuality.Normal);
var valueDisplay = values != null ? Mathf.Approximately(values.MinValue, values.MaxValue) ? $"{values.MinValue}" : $"({values.MinValue}-{values.MaxValue})" : "";
sb.AppendLine($"‣ {string.Format(Localization.instance.Localize(effectDef.DisplayText), valueDisplay)}");
}
Expand Down Expand Up @@ -418,7 +418,7 @@ private static GameObject EnchantItemAndReturnSuccessDialog(ItemDrop.ItemData it
previousDurabilityPercent = item.m_durability / item.GetMaxDurability();

var luckFactor = player.GetTotalActiveMagicEffectValue(MagicEffectType.Luck, 0.01f);
var magicItem = LootRoller.RollMagicItem((ItemRarity)rarity, item, luckFactor);
var magicItem = LootRoller.RollMagicItem((ItemRarity)rarity, ItemQuality.Normal, item, luckFactor);

var magicItemComponent = item.Data().GetOrCreate<MagicItemComponent>();
magicItemComponent.SetMagicItem(magicItem);
Expand Down Expand Up @@ -520,7 +520,7 @@ private static string GetAvailableAugmentEffects(ItemDrop.ItemData item, int aug
if (augmentindex >= 0 && augmentindex < magicItem.Effects.Count)
{
var currentEffectDef = MagicItemEffectDefinitions.Get(magicItem.Effects[augmentindex].EffectType);
valuelessEffect = currentEffectDef.GetValuesForRarity(rarity) == null;
valuelessEffect = currentEffectDef.GetValuesForRarity(rarity, item.m_shared.m_name, magicItem.Quality) == null;
}

var availableEffects = MagicItemEffectDefinitions.GetAvailableEffects(item.Extended(), item.GetMagicItem(), valuelessEffect ? -1 : augmentindex);
Expand All @@ -529,7 +529,7 @@ private static string GetAvailableAugmentEffects(ItemDrop.ItemData item, int aug
sb.Append($"<color={rarityColor}>");
foreach (var effectDef in availableEffects)
{
var values = effectDef.GetValuesForRarity(item.GetRarity());
var values = effectDef.GetValuesForRarity(item.GetRarity(), item.m_shared.m_name, magicItem.Quality);
var valueDisplay = values != null ? Mathf.Approximately(values.MinValue, values.MaxValue) ? $"{values.MinValue}" : $"({values.MinValue}-{values.MaxValue})" : "";
sb.AppendLine($"‣ {string.Format(Localization.instance.Localize(effectDef.DisplayText), valueDisplay)}");
}
Expand Down
15 changes: 13 additions & 2 deletions EpicLoot/EpicLoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ public enum GatedBountyMode
BossKillUnlocksNextBiomeBounties
}

public enum EffectValueRollDistributionTypes
{
Linear,
TendsToLowAverage
}

public class Assets
{
public AssetBundle AssetBundle;
Expand Down Expand Up @@ -112,6 +118,8 @@ public class EpicLoot : BaseUnityPlugin
//private static ConfigEntry<int> _mythicMaterialIconColor;
public static ConfigEntry<bool> UseScrollingCraftDescription;
public static ConfigEntry<bool> TransferMagicItemToCrafts;
public static ConfigEntry<EffectValueRollDistributionTypes> EffectValueRollDistribution;
public static ConfigEntry<bool> UseLootFilters;
public static ConfigEntry<CraftingTabStyle> CraftingTabStyle;
private static ConfigEntry<bool> _loggingEnabled;
private static ConfigEntry<LogLevel> _logLevel;
Expand Down Expand Up @@ -235,6 +243,8 @@ private void Awake()
GlobalDropRateModifier = SyncedConfig("Balance", "Global Drop Rate Modifier", 1.0f, "A global percentage that modifies how likely items are to drop. 1 = Exactly what is in the loot tables will drop. 0 = Nothing will drop. 2 = The number of items in the drop table are twice as likely to drop (note, this doesn't double the number of items dropped, just doubles the relative chance for them to drop). Min = 0, Max = 4");
ItemsToMaterialsDropRatio = SyncedConfig("Balance", "Items To Materials Drop Ratio", 0.0f, "Sets the chance that item drops are instead dropped as magic crafting materials. 0 = all items, no materials. 1 = all materials, no items. Values between 0 and 1 change the ratio of items to materials that drop. At 0.5, half of everything that drops would be items and the other half would be materials. Min = 0, Max = 1");
TransferMagicItemToCrafts = SyncedConfig("Balance", "Transfer Enchants to Crafted Items", false, "When enchanted items are used as ingredients in recipes, transfer the highest enchant to the newly crafted item. Default: False.");
EffectValueRollDistribution = SyncedConfig("Balance", "Effect Value Roll Distribution", EffectValueRollDistributionTypes.Linear, "Function to be used for rolling effect values on an item. Linear: any number in the possible effect value range can be rolled with equal chance. TendsToLowAverage: values close to min and especially max of the range are very unlikely to be rolled. Default: Linear.");
UseLootFilters = SyncedConfig("Balance", "Use Loot Filters", false, "If set to true, all item drop will be affected by loot filters (defined in lootfilters.json). Loot filters allow to prevent dropping of the items you don't need anymore or auto sacrifice the unneeded items into materials on drop.");

AlwaysShowWelcomeMessage = Config.Bind("Debug", "AlwaysShowWelcomeMessage", false, "Just a debug flag for testing the welcome message, do not use.");
OutputPatchedConfigFiles = Config.Bind("Debug", "OutputPatchedConfigFiles", false, "Just a debug flag for testing the patching system, do not use.");
Expand Down Expand Up @@ -488,6 +498,7 @@ public static void InitializeConfig()
LoadJsonFile<AbilityConfig>("abilities.json", AbilityDefinitions.Initialize, ConfigType.Synced);
LoadJsonFile<MaterialConversionsConfig>("materialconversions.json", MaterialConversions.Initialize, ConfigType.Synced);
LoadJsonFile<EnchantingUpgradesConfig>("enchantingupgrades.json", EnchantingTableUpgrades.InitializeConfig, ConfigType.Synced);
LoadJsonFile<LootFiltersConfig>("lootfilters.json", LootFilterDefinitions.Initialize, ConfigType.Synced);

WatchNewPatchConfig();
}
Expand Down Expand Up @@ -1483,7 +1494,7 @@ private static void WriteLootTableDrops(StringBuilder t, LootTable lootTable)
for (var i = 0; i < limit; i++)
{
var level = i + 1;
var dropTable = LootRoller.GetDropsForLevel(lootTable, level, false);
var dropTable = LootRoller.GetDropsForLevelOrDistance(lootTable, level, 0, false);
if (dropTable == null || dropTable.Count == 0)
{
continue;
Expand Down Expand Up @@ -1513,7 +1524,7 @@ private static void WriteLootTableItems(StringBuilder t, LootTable lootTable)
for (var i = 0; i < limit; i++)
{
var level = i + 1;
var lootList = LootRoller.GetLootForLevel(lootTable, level, false);
var lootList = LootRoller.GetLootForLevelOrDistance(lootTable, level, 0, false);
if (ArrayUtils.IsNullOrEmpty(lootList))
{
continue;
Expand Down
3 changes: 3 additions & 0 deletions EpicLoot/EpicLoot.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
<Compile Include="Adventure\Game_Patch.cs" />
<Compile Include="Adventure\MinimapController.cs" />
<Compile Include="Attack_Patch.cs" />
<Compile Include="LootFilter.cs" />
<Compile Include="CraftingV2\EnchantingTable_Patch.cs" />
<Compile Include="CraftingV2\EnchantingUIAugaFixup.cs" />
<Compile Include="CraftingV2\EnchantingUIController.cs" />
Expand Down Expand Up @@ -287,6 +288,7 @@
<None Include="translations.json" />
<None Include="loottables.json" />
<None Include="magiceffects.json" />
<None Include="lootfilters.json" />
<None Include="manifest.json" />
<None Include="CHANGELOG.md" />
<None Include="todo.md" />
Expand Down Expand Up @@ -338,6 +340,7 @@
xcopy "$(ProjectDir)legendaries.json" "G:\Steam\steamapps\common\Valheim-Dev\BepInEx\plugins\$(ProjectName)\" /q /y /i
xcopy "$(ProjectDir)abilities.json" "G:\Steam\steamapps\common\Valheim-Dev\BepInEx\plugins\$(ProjectName)\" /q /y /i
xcopy "$(ProjectDir)materialconversions.json" "G:\Steam\steamapps\common\Valheim-Dev\BepInEx\plugins\$(ProjectName)\" /q /y /i
xcopy "$(ProjectDir)lootfilter.json" "G:\Steam\steamapps\common\Valheim-Dev\BepInEx\plugins\$(ProjectName)\" /q /y /i
</PostBuildEvent>
</PropertyGroup>
<Import Project="..\packages\ILRepack.Lib.MSBuild.Task.2.0.18.2\build\ILRepack.Lib.MSBuild.Task.targets" Condition="Exists('..\packages\ILRepack.Lib.MSBuild.Task.2.0.18.2\build\ILRepack.Lib.MSBuild.Task.targets')" />
Expand Down
56 changes: 25 additions & 31 deletions EpicLoot/GatedItemType/GatedItemTypeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,24 +111,9 @@ public static string GetGatedItemID(string itemID, GatedItemTypeMode mode, List<
return null;
}

while (CheckIfItemNeedsGate(mode, itemID, itemName))
if (ItemNotAllowedYet(mode, itemID, itemName))
{
//EpicLoot.Log("Yes...");

var index = info.Items.IndexOf(itemID);
if (index < 0)
{
// Items list is empty, no need to gate any items from of this type
return itemID;
}
if (index == 0)
{
return string.IsNullOrEmpty(info.Fallback) ? itemID : GetGatedFallbackItem(info.Fallback, mode, itemID, usedTypes);
}

itemID = info.Items[index - 1];
itemName = GetItemName(itemID);
//EpicLoot.Log($"Next lower tier item is ({itemID} - {itemName})");
return null;
}

return itemID;
Expand All @@ -154,24 +139,33 @@ private static string GetItemName(string itemID)
return item.m_shared.m_name;
}

private static bool CheckIfItemNeedsGate(GatedItemTypeMode mode, string itemID, string itemName)
private static bool ItemNotAllowedYet(GatedItemTypeMode mode, string itemID, string itemName)
{
if (!BossPerItem.ContainsKey(itemID))
if (mode == GatedItemTypeMode.PlayerMustKnowRecipe)
{
EpicLoot.LogWarning($"Item ({itemID}) was not registered in iteminfo.json with any particular boss");
return false;
return Player.m_localPlayer != null && !Player.m_localPlayer.IsRecipeKnown(itemName);
}

var bossKeyForItem = BossPerItem[itemID];
var prevBossKey = Bosses.GetPrevBossKey(bossKeyForItem);
//EpicLoot.Log($"Checking if item ({itemID}) needs gating (boss: {bossKeyForItem}, prev boss: {prevBossKey}");
switch (mode)
else if (mode == GatedItemTypeMode.PlayerMustHaveCraftedItem)
{
case GatedItemTypeMode.BossKillUnlocksCurrentBiomeItems: return !ZoneSystem.instance.GetGlobalKey(bossKeyForItem);
case GatedItemTypeMode.BossKillUnlocksNextBiomeItems: return !(string.IsNullOrEmpty(prevBossKey) || ZoneSystem.instance.GetGlobalKey(prevBossKey));
case GatedItemTypeMode.PlayerMustKnowRecipe: return Player.m_localPlayer != null && !Player.m_localPlayer.IsRecipeKnown(itemName);
case GatedItemTypeMode.PlayerMustHaveCraftedItem: return Player.m_localPlayer != null && !Player.m_localPlayer.m_knownMaterial.Contains(itemName);
default: return false;
return Player.m_localPlayer != null && !Player.m_localPlayer.m_knownMaterial.Contains(itemName);
}
else
{
if (!BossPerItem.ContainsKey(itemID))
{
EpicLoot.LogWarning($"Item ({itemID}) was not registered in iteminfo.json with any particular boss");
return false;
}

var bossKeyForItem = BossPerItem[itemID];
var prevBossKey = Bosses.GetPrevBossKey(bossKeyForItem);
//EpicLoot.Log($"Checking if item ({itemID}) needs gating (boss: {bossKeyForItem}, prev boss: {prevBossKey}");
switch (mode)
{
case GatedItemTypeMode.BossKillUnlocksCurrentBiomeItems: return !ZoneSystem.instance.GetGlobalKey(bossKeyForItem);
case GatedItemTypeMode.BossKillUnlocksNextBiomeItems: return !(string.IsNullOrEmpty(prevBossKey) || ZoneSystem.instance.GetGlobalKey(prevBossKey));
default: return false;
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions EpicLoot/LegendarySystem/LegendaryItemConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public class LegendaryInfo
public string Description;
public MagicItemEffectRequirements Requirements;
public List<GuaranteedMagicEffect> GuaranteedMagicEffects = new List<GuaranteedMagicEffect>();
public List<GuaranteedMagicEffect> GuaranteedMagicEffectsExceptional = new List<GuaranteedMagicEffect>();
public List<GuaranteedMagicEffect> GuaranteedMagicEffectsElite = new List<GuaranteedMagicEffect>();
public int GuaranteedEffectCount = -1;
public float SelectionWeight = 1;
public string EquipFx;
Expand Down
17 changes: 16 additions & 1 deletion EpicLoot/LegendarySystem/UniqueLegendaryHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,25 @@ public static IList<LegendaryInfo> GetAvailableLegendaries(ItemDrop.ItemData bas
return availableLegendaries;
}

public static MagicItemEffectDefinition.ValueDef GetLegendaryEffectValues(string legendaryID, string effectType)
public static MagicItemEffectDefinition.ValueDef GetLegendaryEffectValues(string legendaryID, string effectType, ItemQuality quality)
{
if (LegendaryInfo.TryGetValue(legendaryID, out var legendaryInfo))
{
if (quality == ItemQuality.Elite)
{
if (legendaryInfo.GuaranteedMagicEffectsElite.Count() > 0 && legendaryInfo.GuaranteedMagicEffectsElite.TryFind(x => x.Type == effectType, out var guaranteedMagicEffectElite))
{
return guaranteedMagicEffectElite.Values;
}
}
else if (quality == ItemQuality.Exceptional)
{
if (legendaryInfo.GuaranteedMagicEffectsExceptional.Count() > 0 && legendaryInfo.GuaranteedMagicEffectsExceptional.TryFind(x => x.Type == effectType, out var guaranteedMagicEffectExceptional))
{
return guaranteedMagicEffectExceptional.Values;
}
}

if (legendaryInfo.GuaranteedMagicEffects.TryFind(x => x.Type == effectType, out var guaranteedMagicEffect))
{
return guaranteedMagicEffect.Values;
Expand Down
10 changes: 10 additions & 0 deletions EpicLoot/LootConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class LootDrop
public string Item;
public float Weight = 1;
public float[] Rarity;
public float[] Quality;
}

[Serializable]
Expand All @@ -19,6 +20,14 @@ public class LeveledLootDef
public LootDrop[] Loot;
}

[Serializable]
public class DistanceLootDef
{
public int Distance;
public float[][] Drops;
public LootDrop[] Loot;
}

[Serializable]
public class LootTable
{
Expand All @@ -31,6 +40,7 @@ public class LootTable
public LootDrop[] Loot2;
public LootDrop[] Loot3;
public List<LeveledLootDef> LeveledLoot = new List<LeveledLootDef>();
public List<DistanceLootDef> DistanceLoot = new List<DistanceLootDef>();
}

[Serializable]
Expand Down
Loading