private static List <GameObject> RollLootTableInternal(LootTable lootTable, string objectName, Vector3 dropPoint, bool initializeObject) { var results = new List <GameObject>(); _weightedDropCountTable.Setup(lootTable.Drops, dropPair => dropPair.Length == 2 ? dropPair[1] : 1); var dropCountRollResult = _weightedDropCountTable.Roll(); var dropCount = dropCountRollResult.Length >= 1 ? dropCountRollResult[0] : 0; if (dropCount == 0) { return(results); } _weightedLootTable.Setup(lootTable.Loot, x => x.Weight); var selectedDrops = _weightedLootTable.Roll(dropCount); foreach (var ld in selectedDrops) { var lootDrop = ResolveLootDrop(ld, ld.Rarity); var itemPrefab = ObjectDB.instance.GetItemPrefab(lootDrop.Item); if (itemPrefab == null) { Debug.LogError($"Tried to spawn loot ({lootDrop.Item}) for ({objectName}), but the item prefab was not found!"); continue; } var randomRotation = Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f); ZNetView.m_forceDisableInit = !initializeObject; var item = Object.Instantiate(itemPrefab, dropPoint, randomRotation); ZNetView.m_forceDisableInit = false; var itemDrop = item.GetComponent <ItemDrop>(); if (EpicLoot.CanBeMagicItem(itemDrop.m_itemData) && !ArrayUtils.IsNullOrEmpty(lootDrop.Rarity)) { var itemData = new ExtendedItemData(itemDrop.m_itemData); var magicItemComponent = itemData.AddComponent <MagicItemComponent>(); var magicItem = RollMagicItem(lootDrop, itemData); magicItemComponent.SetMagicItem(magicItem); itemDrop.m_itemData = itemData; InitializeMagicItem(itemData); MagicItemGenerated?.Invoke(itemData, magicItem); } results.Add(item); } return(results); }
public static LootDrop[] GetLootForLevel([NotNull] LootTable lootTable, int level, bool useNextHighestIfNotPresent = true) { if (level == 3 && !ArrayUtils.IsNullOrEmpty(lootTable.Loot3)) { if (lootTable.LeveledLoot.Any(x => x.Level == level)) { EpicLoot.LogWarning($"Duplicated leveled loot for ({lootTable.Object} lvl {level}), using 'Loot{level}'"); } return(lootTable.Loot3.ToArray()); } if ((level == 2 || level == 3) && !ArrayUtils.IsNullOrEmpty(lootTable.Loot2)) { if (lootTable.LeveledLoot.Any(x => x.Level == level)) { EpicLoot.LogWarning($"Duplicated leveled loot for ({lootTable.Object} lvl {level}), using 'Loot{level}'"); } return(lootTable.Loot2.ToArray()); } if (level <= 3 && !ArrayUtils.IsNullOrEmpty(lootTable.Loot)) { if (lootTable.LeveledLoot.Any(x => x.Level == level)) { EpicLoot.LogWarning($"Duplicated leveled loot for ({lootTable.Object} lvl {level}), using 'Loot'"); } return(lootTable.Loot.ToArray()); } for (var lvl = level; lvl >= 1; --lvl) { var found = lootTable.LeveledLoot.Find(x => x.Level == lvl); if (found != null && !ArrayUtils.IsNullOrEmpty(found.Loot)) { return(found.Loot.ToArray()); } if (!useNextHighestIfNotPresent) { return(null); } } EpicLoot.LogError($"Could not find any leveled loot for ({lootTable.Object} lvl {level}), but a loot table exists for this object!"); return(null); }
public static List <KeyValuePair <int, float> > GetDropsForLevel([NotNull] LootTable lootTable, int level, bool useNextHighestIfNotPresent = true) { if (level == 3 && !ArrayUtils.IsNullOrEmpty(lootTable.Drops3)) { if (lootTable.LeveledLoot.Any(x => x.Level == level)) { EpicLoot.LogWarning($"Duplicated leveled drops for ({lootTable.Object} lvl {level}), using 'Drops{level}'"); } return(ToDropList(lootTable.Drops3)); } if ((level == 2 || level == 3) && !ArrayUtils.IsNullOrEmpty(lootTable.Drops2)) { if (lootTable.LeveledLoot.Any(x => x.Level == level)) { EpicLoot.LogWarning($"Duplicated leveled drops for ({lootTable.Object} lvl {level}), using 'Drops{level}'"); } return(ToDropList(lootTable.Drops2)); } if (level <= 3 && !ArrayUtils.IsNullOrEmpty(lootTable.Drops)) { if (lootTable.LeveledLoot.Any(x => x.Level == level)) { EpicLoot.LogWarning($"Duplicated leveled drops for ({lootTable.Object} lvl {level}), using 'Drops'"); } return(ToDropList(lootTable.Drops)); } for (var lvl = level; lvl >= 1; --lvl) { var found = lootTable.LeveledLoot.Find(x => x.Level == lvl); if (found != null && !ArrayUtils.IsNullOrEmpty(found.Drops)) { return(ToDropList(found.Drops)); } if (!useNextHighestIfNotPresent) { return(null); } } EpicLoot.LogError($"Could not find any leveled drops for ({lootTable.Object} lvl {level}), but a loot table exists for this object!"); return(null); }
private static void WriteLootTableItems(StringBuilder t, LootTable lootTable) { var highestLevel = lootTable.LeveledLoot != null && lootTable.LeveledLoot.Count > 0 ? lootTable.LeveledLoot.Max(x => x.Level) : 0; var limit = Mathf.Max(3, highestLevel); for (var i = 0; i < limit; i++) { var level = i + 1; var lootList = LootRoller.GetLootForLevel(lootTable, level, false); if (ArrayUtils.IsNullOrEmpty(lootList)) { continue; } WriteLootList(t, level, lootList); } }
public static void AddLootTable([NotNull] LootTable lootTable) { var key = lootTable.Object; if (string.IsNullOrEmpty(key) || lootTable.Loot.Length == 0 || lootTable.Drops.Length == 0) { return; } Debug.Log($"Added LootTable: {key}"); if (!LootTables.ContainsKey(key)) { LootTables.Add(key, new List <LootTable>()); } LootTables[key].Add(lootTable); }
public static void AddLootTable([NotNull] LootTable lootTable) { var key = lootTable.Object; if (string.IsNullOrEmpty(key)) { Debug.LogError("Loot table missing Object name!"); return; } Debug.Log($"Added LootTable: {key}"); if (!LootTables.ContainsKey(key)) { LootTables.Add(key, new List <LootTable>()); } LootTables[key].Add(lootTable); }
private static void WriteLootTableDrops(StringBuilder t, LootTable lootTable) { var dropTables = new[] { lootTable.Drops, lootTable.Drops2, lootTable.Drops3 }; for (var i = 0; i < 3; i++) { var levelDisplay = $" (lvl {i + 1})"; if (i == 0 && ArrayUtils.IsNullOrEmpty(lootTable.Drops2) && ArrayUtils.IsNullOrEmpty(lootTable.Drops3)) { levelDisplay = ""; } else if (i == 0 && ArrayUtils.IsNullOrEmpty(lootTable.Drops2)) { levelDisplay = " (lvl 1, 2)"; } else if (i == 0 && ArrayUtils.IsNullOrEmpty(lootTable.Drops3)) { levelDisplay = " (lvl 1, 3)"; } var dropTable = dropTables[i]; if (ArrayUtils.IsNullOrEmpty(dropTable)) { continue; } float total = lootTable.Drops.Sum(x => x.Length > 1 ? x[1] : 0); if (total > 0) { t.AppendLine($"> | Drops{levelDisplay} | Weight (Chance) |"); t.AppendLine($"> | -- | -- |"); foreach (var drop in dropTable) { var count = drop.Length > 0 ? drop[0] : 0; var value = drop.Length > 1 ? drop[1] : 0; var percent = (value / total) * 100; t.AppendLine($"> | {count} | {value} ({percent:0.#}%) |"); } } t.AppendLine(); } }
private static void WriteLootTableItems(StringBuilder t, LootTable lootTable) { var lootLists = new[] { lootTable.Loot, lootTable.Loot2, lootTable.Loot3 }; for (var i = 0; i < 3; i++) { var levelDisplay = $" (lvl {i + 1}+)"; if (i == 0 && ArrayUtils.IsNullOrEmpty(lootTable.Loot2) && ArrayUtils.IsNullOrEmpty(lootTable.Loot3)) { levelDisplay = ""; } var lootList = lootLists[i]; if (ArrayUtils.IsNullOrEmpty(lootList)) { continue; } WriteLootList(t, levelDisplay, lootList); } }
public static List <GameObject> RollLootTableAndSpawnObjects(LootTable lootTable, int level, string objectName, Vector3 dropPoint) { return(RollLootTableInternal(lootTable, level, objectName, dropPoint, true)); }
public static List <ItemDrop.ItemData> RollLootTable(LootTable lootTable, int level, string objectName, Vector3 dropPoint) { return(RollLootTable(new List <LootTable> { lootTable }, level, objectName, dropPoint)); }
public static void SpawnMagicItemWithEffect(Console __instance, string[] args) { if (args.Length < 3) { EpicLoot.LogError("Specify effect and item name"); return; } if (Player.m_localPlayer == null) { return; } var effectArg = args[1]; var itemPrefabNameArg = args[2]; __instance.AddString($"magicitem - {itemPrefabNameArg} with effect: {effectArg}"); var magicItemEffectDef = MagicItemEffectDefinitions.Get(effectArg); if (magicItemEffectDef == null) { __instance.AddString($"> Could not find effect: {effectArg}"); return; } var itemPrefab = ObjectDB.instance.GetItemPrefab(itemPrefabNameArg); if (itemPrefab == null) { __instance.AddString($"> Could not find item: {itemPrefabNameArg}"); return; } var fromItemData = itemPrefab.GetComponent <ItemDrop>().m_itemData; if (!EpicLoot.CanBeMagicItem(fromItemData)) { __instance.AddString($"> Can't be magic item: {itemPrefabNameArg}"); return; } var effectRequirements = magicItemEffectDef.Requirements; var itemRarity = effectRequirements.AllowedRarities.Count == 0 ? ItemRarity.Legendary : effectRequirements.AllowedRarities.First(); var rarityTable = GetRarityTable(itemRarity.ToString()); var loot = new LootTable { Object = "Console", Drops = new[] { new[] { 1, 1 } }, Loot = new[] { new LootDrop { Item = itemPrefab.name, Rarity = rarityTable } } }; var randomOffset = UnityEngine.Random.insideUnitSphere; var dropPoint = Player.m_localPlayer.transform.position + Player.m_localPlayer.transform.forward * 3 + Vector3.up * 1.5f + randomOffset; // TODO add better hook for desired effect - currently effect will be discarded on next game load // if effect was added when magicItem had maximum of available effect // however still good for debug LootRoller.CheatForceMagicEffect = true; LootRoller.ForcedMagicEffect = effectArg; LootRoller.RollLootTableAndSpawnObjects(loot, 1, loot.Object, dropPoint); LootRoller.CheatForceMagicEffect = false; LootRoller.ForcedMagicEffect = string.Empty; }
public static void MagicItem(Console __instance, string[] args) { var rarityArg = args.Length >= 2 ? args[1] : "random"; var itemArg = args.Length >= 3 ? args[2] : "random"; var count = args.Length >= 4 ? int.Parse(args[3]) : 1; var effectCount = args.Length >= 5 ? int.Parse(args[4]) : -1; __instance.AddString($"magicitem - rarity:{rarityArg}, item:{itemArg}, count:{count}"); var allItemNames = ObjectDB.instance.m_items .Where(x => EpicLoot.CanBeMagicItem(x.GetComponent <ItemDrop>().m_itemData)) .Where(x => x.name != "HelmetDverger" && x.name != "BeltStrength" && x.name != "Wishbone") .Select(x => x.name) .ToList(); if (Player.m_localPlayer == null) { return; } LootRoller.CheatEffectCount = effectCount; for (var i = 0; i < count; i++) { int[] rarityTable = GetRarityTable(rarityArg); var item = itemArg; if (item == "random") { var weightedRandomTable = new WeightedRandomCollection <string>(_random, allItemNames, x => 1); item = weightedRandomTable.Roll(); } if (ObjectDB.instance.GetItemPrefab(item) == null) { __instance.AddString($"> Could not find item: {item}"); break; } __instance.AddString($"> {i + 1} - rarity: [{string.Join(", ", rarityTable)}], item: {item}"); var loot = new LootTable() { Object = "Console", Drops = new[] { new[] { 1, 1 } }, Loot = new[] { new LootDrop() { Item = item, Rarity = rarityTable, Weight = 1 } } }; var randomOffset = UnityEngine.Random.insideUnitSphere; var dropPoint = Player.m_localPlayer.transform.position + Player.m_localPlayer.transform.forward * 3 + Vector3.up * 1.5f + randomOffset; LootRoller.RollLootTableAndSpawnObjects(loot, 1, loot.Object, dropPoint); } LootRoller.CheatEffectCount = -1; }
private static List <GameObject> RollLootTableInternal(LootTable lootTable, int level, string objectName, Vector3 dropPoint, bool initializeObject) { var results = new List <GameObject>(); if (lootTable == null || level <= 0 || string.IsNullOrEmpty(objectName)) { return(results); } var luckFactor = GetLuckFactor(dropPoint); var drops = GetDropsForLevel(lootTable, level); if (drops.Count == 0) { return(results); } if (EpicLoot.AlwaysDropCheat) { drops = drops.Where(x => x.Key > 0).ToList(); } _weightedDropCountTable.Setup(drops, dropPair => dropPair.Value); var dropCountRollResult = _weightedDropCountTable.Roll(); var dropCount = dropCountRollResult.Key; if (dropCount == 0) { return(results); } var loot = GetLootForLevel(lootTable, level); _weightedLootTable.Setup(loot, x => x.Weight); var selectedDrops = _weightedLootTable.Roll(dropCount); foreach (var ld in selectedDrops) { if (ld == null) { EpicLoot.LogError($"Loot drop was null! RollLootTableInternal({lootTable.Object}, {level}, {objectName})"); continue; } var lootDrop = ResolveLootDrop(ld); var itemID = CheatDisableGating ? lootDrop.Item : GatedItemTypeHelper.GetGatedItemID(lootDrop.Item); var itemPrefab = ObjectDB.instance.GetItemPrefab(itemID); if (itemPrefab == null) { EpicLoot.LogError($"Tried to spawn loot ({itemID}) for ({objectName}), but the item prefab was not found!"); continue; } var randomRotation = Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f); ZNetView.m_forceDisableInit = !initializeObject; var item = Object.Instantiate(itemPrefab, dropPoint, randomRotation); ZNetView.m_forceDisableInit = false; var itemDrop = item.GetComponent <ItemDrop>(); if (EpicLoot.CanBeMagicItem(itemDrop.m_itemData) && !ArrayUtils.IsNullOrEmpty(lootDrop.Rarity)) { var itemData = new ExtendedItemData(itemDrop.m_itemData); var magicItemComponent = itemData.AddComponent <MagicItemComponent>(); var magicItem = RollMagicItem(lootDrop, itemData, luckFactor); if (CheatForceMagicEffect) { AddDebugMagicEffects(magicItem); } magicItemComponent.SetMagicItem(magicItem); itemDrop.m_itemData = itemData; itemDrop.Save(); InitializeMagicItem(itemData); MagicItemGenerated?.Invoke(itemData, magicItem); } results.Add(item); } return(results); }
private static void SpawnLegendaryItemHelper(string legendaryID, string itemType, Terminal context) { if (!UniqueLegendaryHelper.TryGetLegendaryInfo(legendaryID, out var legendaryInfo)) { if (context != null) { context.AddString($"> Could not find info for legendaryID: ({legendaryID})"); } return; } if (string.IsNullOrEmpty(itemType)) { var dummyMagicItem = new MagicItem { Rarity = ItemRarity.Legendary }; var allowedItems = new List <ItemDrop>(); foreach (var itemName in GatedItemTypeHelper.ItemInfoByID.Keys) { var itemPrefab = ObjectDB.instance.GetItemPrefab(itemName); if (itemPrefab == null) { continue; } var itemDrop = itemPrefab.GetComponent <ItemDrop>(); if (itemDrop == null) { continue; } var itemData = itemDrop.m_itemData; if (legendaryInfo.Requirements.CheckRequirements(itemData, dummyMagicItem)) { allowedItems.Add(itemDrop); } } itemType = allowedItems.LastOrDefault()?.name; } if (string.IsNullOrEmpty(itemType)) { itemType = "Club"; } var loot = new LootTable { Object = "Console", Drops = new[] { new float[] { 1, 1 } }, Loot = new[] { new LootDrop { Item = itemType, Rarity = new float[] { 0, 0, 0, 1 } } } }; LootRoller.CheatForceLegendary = legendaryID; var previousDisableGatingState = LootRoller.CheatDisableGating; LootRoller.CheatDisableGating = true; var randomOffset = UnityEngine.Random.insideUnitSphere; var dropPoint = Player.m_localPlayer.transform.position + Player.m_localPlayer.transform.forward * 3 + Vector3.up * 1.5f + randomOffset; LootRoller.RollLootTableAndSpawnObjects(loot, 1, loot.Object, dropPoint); LootRoller.CheatForceLegendary = null; LootRoller.CheatDisableGating = previousDisableGatingState; }
public static void SpawnMagicItemWithEffect(Terminal context, string[] args) { if (args.Length < 3) { EpicLoot.LogError("Specify effect and item name"); return; } if (Player.m_localPlayer == null) { return; } var effectArg = args[1]; var itemPrefabNameArg = args[2]; context.AddString($"magicitem - {itemPrefabNameArg} with effect: {effectArg}"); var magicItemEffectDef = MagicItemEffectDefinitions.Get(effectArg); if (magicItemEffectDef == null) { context.AddString($"> Could not find effect: {effectArg}"); return; } var itemPrefab = ObjectDB.instance.GetItemPrefab(itemPrefabNameArg); if (itemPrefab == null) { context.AddString($"> Could not find item: {itemPrefabNameArg}"); return; } var fromItemData = itemPrefab.GetComponent <ItemDrop>().m_itemData; if (!EpicLoot.CanBeMagicItem(fromItemData)) { context.AddString($"> Can't be magic item: {itemPrefabNameArg}"); return; } var effectRequirements = magicItemEffectDef.Requirements; var itemRarity = effectRequirements.AllowedRarities.Count == 0 ? ItemRarity.Magic : effectRequirements.AllowedRarities.First(); var rarityTable = GetRarityTable(itemRarity.ToString()); var loot = new LootTable { Object = "Console", Drops = new[] { new float[] { 1, 1 } }, Loot = new[] { new LootDrop { Item = itemPrefab.name, Rarity = rarityTable } } }; var randomOffset = UnityEngine.Random.insideUnitSphere; var dropPoint = Player.m_localPlayer.transform.position + Player.m_localPlayer.transform.forward * 3 + Vector3.up * 1.5f + randomOffset; LootRoller.CheatForceMagicEffect = true; LootRoller.ForcedMagicEffect = effectArg; LootRoller.RollLootTableAndSpawnObjects(loot, 1, loot.Object, dropPoint); LootRoller.CheatForceMagicEffect = false; LootRoller.ForcedMagicEffect = string.Empty; }
public static void MagicItem(Console __instance, string[] args) { var rarityArg = args.Length >= 2 ? args[1] : "random"; var itemArg = args.Length >= 3 ? args[2] : "random"; var count = args.Length >= 4 ? int.Parse(args[3]) : 1; __instance.AddString($"magicitem - rarity:{rarityArg}, item:{itemArg}, count:{count}"); var items = new List <GameObject>(); var allItemNames = ObjectDB.instance.m_items .Where(x => EpicLoot.CanBeMagicItem(x.GetComponent <ItemDrop>().m_itemData)) .Select(x => x.name) .ToList(); if (Player.m_localPlayer == null) { return; } for (var i = 0; i < count; i++) { var rarityTable = new[] { 1, 1, 1, 1 }; switch (rarityArg.ToLowerInvariant()) { case "magic": rarityTable = new[] { 1, 0, 0, 0, }; break; case "rare": rarityTable = new[] { 0, 1, 0, 0, }; break; case "epic": rarityTable = new[] { 0, 0, 1, 0, }; break; case "legendary": rarityTable = new[] { 0, 0, 0, 1, }; break; } var item = itemArg; if (item == "random") { var weightedRandomTable = new WeightedRandomCollection <string>(_random, allItemNames, x => 1); item = weightedRandomTable.Roll(); } if (ObjectDB.instance.GetItemPrefab(item) == null) { __instance.AddString($"> Could not find item: {item}"); break; } __instance.AddString($" {i + 1} - rarity: [{string.Join(", ", rarityTable)}], item: {item}"); var loot = new LootTable() { Object = "Console", Drops = new[] { new[] { 1, 1 } }, Loot = new[] { new LootDrop() { Item = item, Rarity = rarityTable } } }; var randomOffset = UnityEngine.Random.insideUnitSphere; var dropPoint = Player.m_localPlayer.transform.position + Player.m_localPlayer.transform.forward * 3 + Vector3.up * 1.5f + randomOffset; items.AddRange(LootRoller.RollLootTableAndSpawnObjects(loot, loot.Object, dropPoint)); } }