public static void ActionIntTextField(ref int value, String name, Action <int> action, Action enterAction, params GUILayoutOption[] options ) { bool changed = false; bool hitEnter = false; String str = $"{value}"; UI.ActionTextField(ref str, name, (text) => { changed = true; }, () => { hitEnter = true; }, options); Int32.TryParse(str, out value); if (changed) { action(value); } if (hitEnter) { enterAction(); } }
static public void OnGUI <T>(String callerKey, UnitEntityData unit, List <T> facts, Func <T, BlueprintScriptableObject> blueprint, IEnumerable <BlueprintScriptableObject> blueprints, Func <T, String> title, Func <T, String> description = null, Func <T, int> value = null, IEnumerable <BlueprintAction> actions = null ) { bool searchChanged = false; if (actions == null) { actions = new List <BlueprintAction>(); } if (callerKey != prevCallerKey) { searchChanged = true; showAll = false; } prevCallerKey = callerKey; var mutatorLookup = actions.Distinct().ToDictionary(a => a.name, a => a); UI.BeginHorizontal(); UI.Space(100); UI.ActionTextField(ref searchText, "searhText", null, () => { searchChanged = true; }, UI.Width(320)); UI.Space(25); UI.Label("Limit", UI.ExpandWidth(false)); UI.ActionIntTextField(ref searchLimit, "searchLimit", null, () => { searchChanged = true; }, UI.Width(175)); if (searchLimit > 1000) { searchLimit = 1000; } UI.Space(25); UI.Toggle("Show GUIDs", ref Main.settings.showAssetIDs); UI.Space(25); UI.Toggle("Dividers", ref Main.settings.showDivisions); UI.Space(25); searchChanged |= UI.DisclosureToggle("Show All".orange().bold(), ref showAll); UI.EndHorizontal(); UI.BeginHorizontal(); UI.Space(100); UI.ActionButton("Search", () => { searchChanged = true; }, UI.AutoWidth()); UI.Space(25); if (matchCount > 0 && searchText.Length > 0) { String matchesText = "Matches: ".green().bold() + $"{matchCount}".orange().bold(); if (matchCount > searchLimit) { matchesText += " => ".cyan() + $"{searchLimit}".cyan().bold(); } UI.Label(matchesText, UI.ExpandWidth(false)); } #if false UI.Label("Repeat Count", UI.ExpandWidth(false)); UI.ActionIntTextField( ref repeatCount, "repeatCount", (limit) => { }, () => { }, UI.Width(200)); #endif UI.EndHorizontal(); if (showAll) { // TODO - do we need this logic or can we make blueprint filtering fast enough to do keys by key searching? //if (filteredBPs == null || searchChanged) { UpdateSearchResults(searchText, searchLimit, blueprints); //} BlueprintListUI.OnGUI(unit, filteredBPs, 100); return; } var terms = searchText.Split(' ').Select(s => s.ToLower()).ToHashSet(); BlueprintAction add = mutatorLookup.GetValueOrDefault("Add", null); BlueprintAction remove = mutatorLookup.GetValueOrDefault("Remove", null); BlueprintAction decrease = mutatorLookup.GetValueOrDefault("<", null); BlueprintAction increase = mutatorLookup.GetValueOrDefault(">", null); mutatorLookup.Remove("Add"); mutatorLookup.Remove("Remove"); mutatorLookup.Remove("<"); mutatorLookup.Remove(">"); BlueprintScriptableObject toAdd = null; BlueprintScriptableObject toRemove = null; BlueprintScriptableObject toIncrease = null; BlueprintScriptableObject toDecrease = null; var toValues = new Dictionary <String, BlueprintScriptableObject>(); var sorted = facts.OrderBy((f) => title(f)); matchCount = 0; UI.Div(100); foreach (var fact in sorted) { if (fact == null) { continue; } var bp = blueprint(fact); String name = title(fact); String nameLower = name.ToLower(); if (name != null && name.Length > 0 && (searchText.Length == 0 || terms.All(term => nameLower.Contains(term)))) { matchCount++; UI.BeginHorizontal(); UI.Space(100); UI.Label($"{name}".cyan().bold(), UI.Width(400)); UI.Space(30); if (value != null) { var v = value(fact); decrease.BlueprintActionButton(unit, bp, () => { toDecrease = bp; }, 50); UI.Space(10f); UI.Label($"{v}".orange().bold(), UI.Width(30)); increase.BlueprintActionButton(unit, bp, () => { toIncrease = bp; }, 50); } #if false UI.Space(30); add.BlueprintActionButton(unit, bp, () => { toAdd = bp; }, 150); #endif UI.Space(30); remove.BlueprintActionButton(unit, bp, () => { toRemove = bp; }, 150); #if false foreach (var action in actions) { action.MutatorButton(unit, bp, () => { toValues[action.name] = bp; }, 150); } #endif if (description != null) { UI.Space(30); var assetID = Main.settings.showAssetIDs ? blueprint(fact).AssetGuid.magenta() + " " : ""; UI.Label(assetID + description(fact).green(), UI.AutoWidth()); } UI.EndHorizontal(); UI.Div(100); } } if (toAdd != null) { add.action(toAdd, unit, repeatCount); toAdd = null; } if (toRemove != null) { remove.action(toRemove, unit, repeatCount); toRemove = null; } if (toDecrease != null) { decrease.action(toDecrease, unit, repeatCount); toDecrease = null; } if (toIncrease != null) { increase.action(toIncrease, unit, repeatCount); toIncrease = null; } foreach (var item in toValues) { var muator = mutatorLookup[item.Key]; if (muator != null) { muator.action(item.Value, unit, repeatCount); } } toValues.Clear(); }
public static IEnumerable OnGUI() { // Stackable browser using (UI.HorizontalScope(UI.Width(450))) { // First column - Type Selection Grid using (UI.VerticalScope(GUI.skin.box)) { UI.ActionSelectionGrid(ref settings.selectedBPTypeFilter, blueprintTypeFilters.Select(tf => tf.name).ToArray(), 1, (selected) => { UpdateSearchResults(); }, UI.buttonStyle, UI.Width(200)); } bool collationChanged = false; if (collatedBPs != null) { using (UI.VerticalScope(GUI.skin.box)) { UI.ActionSelectionGrid(ref selectedCollationIndex, collationKeys.ToArray(), 1, (selected) => { collationChanged = true; BlueprintListUI.needsLayout = true; }, UI.buttonStyle, UI.Width(200)); } } // Section Column - Main Area float remainingWidth = Main.ummWidth - 325; using (UI.VerticalScope(UI.Width(remainingWidth))) { // Search Field and modifiers using (UI.HorizontalScope()) { UI.ActionTextField( ref settings.searchText, "searhText", (text) => { }, () => { UpdateSearchResults(); }, UI.Width(400)); UI.Label("Limit", UI.ExpandWidth(false)); UI.ActionIntTextField( ref settings.searchLimit, "searchLimit", (limit) => { }, () => { UpdateSearchResults(); }, UI.Width(200)); if (settings.searchLimit > 1000) { settings.searchLimit = 1000; } UI.Space(25); UI.Toggle("Show GUIDs", ref settings.showAssetIDs); UI.Space(25); UI.Toggle("Components", ref settings.showComponents); UI.Space(25); UI.Toggle("Elements", ref settings.showElements); UI.Space(25); UI.Toggle("Dividers", ref settings.showDivisions); } // Search Button and Results Summary using (UI.HorizontalScope()) { UI.ActionButton("Search", () => { UpdateSearchResults(); }, UI.AutoWidth()); UI.Space(25); if (firstSearch) { UI.Label("please note the first search may take a few seconds.".green(), UI.AutoWidth()); } else if (matchCount > 0) { String title = "Matches: ".green().bold() + $"{matchCount}".orange().bold(); if (matchCount > settings.searchLimit) { title += " => ".cyan() + $"{settings.searchLimit}".cyan().bold(); } UI.Label(title, UI.ExpandWidth(false)); } UI.Space(50); UI.Label($"".green(), UI.AutoWidth()); } UI.Space(10); if (filteredBPs != null) { CharacterPicker.OnGUI(); UnitReference selected = CharacterPicker.GetSelectedCharacter(); var bps = filteredBPs; if (selectedCollationIndex == 0) { selectedCollatedBPs = null; } if (selectedCollationIndex > 0) { if (collationChanged) { var key = collationKeys.ElementAt(selectedCollationIndex); var selectedKey = collationKeys.ElementAt(selectedCollationIndex); foreach (var group in collatedBPs) { if (group.Key == selectedKey) { selectedCollatedBPs = group.Take(settings.searchLimit).ToArray(); } } BlueprintListUI.needsLayout = true; } bps = selectedCollatedBPs; } BlueprintListUI.OnGUI(selected, bps, 0, remainingWidth, null, selectedTypeFilter); } UI.Space(25); } } return(null); }
public static IEnumerable OnGUI() { UI.ActionSelectionGrid(ref settings.selectedBPTypeFilter, blueprintTypeFilters.Select(tf => tf.name).ToArray(), 10, (selected) => { UpdateSearchResults(); }, UI.MinWidth(200)); UI.Space(10); UI.BeginHorizontal(); UI.ActionTextField( ref settings.searchText, "searhText", (text) => { }, () => { UpdateSearchResults(); }, UI.Width(400)); UI.Label("Limit", UI.ExpandWidth(false)); UI.ActionIntTextField( ref settings.searchLimit, "searchLimit", (limit) => { }, () => { UpdateSearchResults(); }, UI.Width(200)); if (settings.searchLimit > 1000) { settings.searchLimit = 1000; } UI.Space(25); UI.Toggle("Show GUIs", ref settings.showAssetIDs); UI.Space(25); UI.Toggle("Dividers", ref settings.showDivisions); UI.EndHorizontal(); UI.BeginHorizontal(); UI.ActionButton("Search", () => { UpdateSearchResults(); }, UI.AutoWidth()); UI.Space(25); if (firstSearch) { UI.Label("please note the first search may take a few seconds.".green(), UI.AutoWidth()); } else if (matchCount > 0) { String title = "Matches: ".green().bold() + $"{matchCount}".orange().bold(); if (matchCount > settings.searchLimit) { title += " => ".cyan() + $"{settings.searchLimit}".cyan().bold(); } if (collatedBPs != null) { foreach (var group in collatedBPs) { title += $" {group.Key} ({group.Count()})"; } } UI.Label(title, UI.ExpandWidth(false)); } UI.Space(50); UI.Label("".green(), UI.AutoWidth()); UI.EndHorizontal(); UI.Space(10); if (filteredBPs != null) { CharacterPicker.OnGUI(); UnitReference selected = CharacterPicker.GetSelectedCharacter(); BlueprintListUI.OnGUI(selected, filteredBPs, collatedBPs, 0, null, selectedTypeFilter); } UI.Space(25); return(null); }
public static void OnGUI() { #if DEBUG UI.Div(0, 25); var inventory = Game.Instance.Player.Inventory; var items = inventory.ToList(); UI.HStack("Inventory", 1, () => { UI.ActionButton("Export", () => items.Export("inventory.json"), UI.Width(150)); UI.Space(25); UI.ActionButton("Import", () => inventory.Import("inventory.json"), UI.Width(150)); UI.Space(25); UI.ActionButton("Replace", () => inventory.Import("inventory.json", true), UI.Width(150)); }, () => { } ); #endif UI.Div(0, 25); UI.HStack("Loot", 1, () => { UI.BindableActionButton(MassLootBox, UI.Width(200)); UI.Space(5); UI.Label("Area exit loot screen useful with the mod Cleaner to clear junk loot mid dungeon leaving less clutter on the map".green()); }, () => { UI.ActionButton("Reveal Ground Loot", () => LootHelper.ShowAllChestsOnMap(), UI.Width(200)); UI.Space(210); UI.Label("Shows all chests/bags/etc on the map excluding hidden".green()); }, () => { UI.ActionButton("Reveal Hidden Ground Loot", () => LootHelper.ShowAllChestsOnMap(true), UI.Width(200)); UI.Space(210); UI.Label("Shows all chests/bags/etc on the map including hidden".green()); }, () => { UI.ActionButton("Reveal Inevitable Loot", () => LootHelper.ShowAllInevitablePortalLoot(), UI.Width(200)); UI.Space(210); UI.Label("Shows unlocked Inevitable Excess DLC rewards on the map".green()); }, () => { UI.Toggle("Mass Loot Shows Everything When Leaving Map", ref settings.toggleMassLootEverything); UI.Space(100); UI.Label("Some items might be invisible until looted".green()); }, () => { UI.Toggle("Color Items By Rarity", ref settings.toggleColorLootByRarity); UI.Space(25); using (UI.VerticalScope()) { UI.Label($"This makes loot function like Diablo or Borderlands. {"Note: turning this off requires you to save and reload for it to take effect.".orange()}".green()); UI.Label("The coloring of rarity goes as follows:".green()); UI.HStack("Rarity".orange(), 1, () => { UI.Label("Trash".Rarity(RarityType.Trash).bold(), UI.rarityStyle, UI.Width(200)); UI.Space(5); UI.Label("Common".Rarity(RarityType.Common).bold(), UI.rarityStyle, UI.Width(200)); UI.Space(5); UI.Label("Uncommon".Rarity(RarityType.Uncommon).bold(), UI.rarityStyle, UI.Width(200)); }, () => { UI.Space(3); UI.Label("Rare".Rarity(RarityType.Rare).bold(), UI.rarityStyle, UI.Width(200)); UI.Space(5); UI.Label("Epic".Rarity(RarityType.Epic).bold(), UI.rarityStyle, UI.Width(200)); UI.Space(5); UI.Label("Legendary".Rarity(RarityType.Legendary).bold(), UI.rarityStyle, UI.Width(200)); }, () => { UI.Space(5); UI.Label("Mythic".Rarity(RarityType.Mythic).bold(), UI.rarityStyle, UI.Width(200)); UI.Space(5); UI.Label("Godly".Rarity(RarityType.Godly).bold(), UI.rarityStyle, UI.Width(200)); UI.Space(5); UI.Label("Notable".Rarity(RarityType.Notable).bold() + "*".orange().bold(), UI.rarityStyle, UI.Width(200)); }, () => { UI.Space(3); UI.Label("*".orange().bold() + " Notable".Rarity(RarityType.Notable) + " denotes items that are deemed to be significant for plot reasons or have significant subtle properties".green(), UI.Width(615)); }, () => { } ); } // The following options let you configure loot filtering and auto sell levels:".green()); }, #if false () => UI.RarityGrid("Hide Level ", ref settings.lootFilterIgnore, 0, UI.AutoWidth()), () => UI.RarityGrid("Auto Sell Level ", ref settings.lootFilterAutoSell, 0, UI.AutoWidth()), #endif () => { } ); UI.Div(0, 25); var isEmpty = true; UI.HStack("Loot Checklist", 1, () => { var areaName = ""; if (Main.IsInGame) { areaName = Game.Instance.CurrentlyLoadedArea.AreaDisplayName; var areaPrivateName = Game.Instance.CurrentlyLoadedArea.name; if (areaPrivateName != areaName) { areaName += $"\n({areaPrivateName})".yellow(); } } UI.Label(areaName.orange().bold(), UI.Width(300)); UI.Label("Rarity: ".cyan(), UI.AutoWidth()); UI.RarityGrid(ref settings.lootChecklistFilterRarity, 4, UI.AutoWidth()); }, () => { UI.ActionTextField( ref searchText, "itemSearchText", (text) => { }, () => { }, UI.Width(300)); UI.Space(25); UI.Toggle("Show Friendly", ref settings.toggleLootChecklistFilterFriendlies); UI.Space(25); UI.Toggle("Blueprint", ref settings.toggleLootChecklistFilterBlueprint, UI.AutoWidth()); UI.Space(25); UI.Toggle("Description", ref settings.toggleLootChecklistFilterDescription, UI.AutoWidth()); }, () => { if (!Main.IsInGame) { UI.Label("Not available in the Main Menu".orange()); return; } var presentGroups = LootHelper.GetMassLootFromCurrentArea().GroupBy(p => p.InteractionLoot != null ? "Containers" : "Units"); var indent = 3; using (UI.VerticalScope()) { foreach (var group in presentGroups.Reverse()) { var presents = group.AsEnumerable().OrderByDescending(p => { var loot = p.GetLewtz(searchText); if (loot.Count == 0) { return(0); } else { return((int)loot.Max(l => l.Rarity())); } }); var rarity = settings.lootChecklistFilterRarity; var count = presents.Where(p => p.Unit == null || (settings.toggleLootChecklistFilterFriendlies && !p.Unit.IsPlayersEnemy || p.Unit.IsPlayersEnemy) || (!settings.toggleLootChecklistFilterFriendlies && p.Unit.IsPlayersEnemy)).Count(p => p.GetLewtz(searchText).Lootable(rarity).Count() > 0); UI.Label($"{group.Key.cyan()}: {count}"); UI.Div(indent); foreach (var present in presents) { var pahtLewts = present.GetLewtz(searchText).Lootable(rarity).OrderByDescending(l => l.Rarity()); var unit = present.Unit; if (pahtLewts.Count() > 0 && (unit == null || (settings.toggleLootChecklistFilterFriendlies && !unit.IsPlayersEnemy || unit.IsPlayersEnemy) || (!settings.toggleLootChecklistFilterFriendlies && unit.IsPlayersEnemy))) { isEmpty = false; UI.Div(); using (UI.HorizontalScope()) { UI.Space(indent); UI.Label($"{present.GetName()}".orange().bold(), UI.Width(325)); if (present.InteractionLoot != null) { if (present.InteractionLoot?.Owner?.PerceptionCheckDC > 0) { UI.Label($" Perception DC: {present.InteractionLoot?.Owner?.PerceptionCheckDC}".green().bold(), UI.Width(125)); } else { UI.Label($" Perception DC: NA".orange().bold(), UI.Width(125)); } int?trickDc = present.InteractionLoot?.Owner?.Get <DisableDeviceRestrictionPart>()?.DC; if (trickDc > 0) { UI.Label($" Trickery DC: {trickDc}".green().bold(), UI.Width(125)); } else { UI.Label($" Trickery DC: NA".orange().bold(), UI.Width(125)); } } UI.Space(25); using (UI.VerticalScope()) { foreach (var lewt in pahtLewts) { var description = lewt.Blueprint.Description; var showBP = settings.toggleLootChecklistFilterBlueprint; var showDesc = settings.toggleLootChecklistFilterDescription && description != null && description.Length > 0; using (UI.HorizontalScope()) { //Main.Log($"rarity: {lewt.Blueprint.Rarity()} - color: {lewt.Blueprint.Rarity().color()}"); UI.Label(lewt.Name.Rarity(lewt.Blueprint.Rarity()), showDesc || showBP ? UI.Width(350) : UI.AutoWidth()); if (showBP) { UI.Space(100); UI.Label(lewt.Blueprint.GetDisplayName().grey(), showDesc ? UI.Width(350) : UI.AutoWidth()); } if (showDesc) { UI.Space(100); UI.Label(description.StripHTML().green()); } } } } } UI.Space(25); } } UI.Space(25); } } }, () => { if (isEmpty) { using (UI.HorizontalScope()) { UI.Label("No Loot Available".orange(), UI.AutoWidth()); } } } ); }