コード例 #1
0
        static string RandomBaseBlueprintId(ItemTypeData selectedItemData)
        {
            string[] guids;
            switch (selectedItemData.Type)
            {
            case UsableItemType.Scroll:
                guids = new string[] {
                    "17959707c7004bd4abad2983f8a4af66",
                    "be452dba5acdd9441841d2189e1ae55a",
                    "fbdd06f0414c3ef458eb4b2a8072e502",
                    "358ee9cb540a9af4e9bc76cc1af62e86",
                    "e5700c45eb88bdd40a324e10d3de4a07",
                    "33ea3e3e578d4db4c8e57632fca4c9ec",
                    "68d5aa212b7323e4e95e0fe731ea50cf"
                };
                break;

            case UsableItemType.Wand:
                guids = new string[] {
                    "4bf15a56d9ade8f47bf93fda7aa84d8b",
                    "85a4ff725c5236b4f9e0adb17fb64e2b",
                    "ce90a6251242af745b3daa56f84a5fe5",
                    "a20d40dc97457f041a2c29bdb2e2efe8",
                    "229fcbd357a9d6b48bc63b79188cdbd6",
                    "021b4a12739c59541922e3857f3fb3a4",
                    "394d337603392eb4c817994c45877fc0",
                    "8cb627da1a91069428ce87d9a114cdd6",
                    "85a4ff725c5236b4f9e0adb17fb64e2b"
                };
                break;

            default:
                return(null);
            }
            return(guids[random.Next(guids.Length)]);
        }
コード例 #2
0
        static void OnGui(UnityModManager.ModEntry modEntry)
        {
            if (!modEnabled)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label("The mod is disabled.  Loading saved games with custom items will cause them to revert to regular versions.");
                GUILayout.EndHorizontal();
                return;
            }

            UnitEntityData mainCharacterValue = Game.Instance?.Player?.MainCharacter.Value;

            if (mainCharacterValue == null || !mainCharacterValue.IsViewActive || (
                    Game.Instance.CurrentMode != GameModeType.Default &&
                    Game.Instance.CurrentMode != GameModeType.GlobalMap &&
                    Game.Instance.CurrentMode != GameModeType.FullScreenUi &&
                    Game.Instance.CurrentMode != GameModeType.Pause &&
                    Game.Instance.CurrentMode != GameModeType.EscMode &&
                    Game.Instance.CurrentMode != GameModeType.Rest &&
                    Game.Instance.CurrentMode != GameModeType.Kingdom
                    ))
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label("Item crafting is not available in this game state.");
                GUILayout.EndHorizontal();
                return;
            }

            GUILayout.BeginHorizontal();
            GUILayout.Label($"Number of custom Craft Magic Items blueprints loaded: {customBlueprintGUIDs.Count}");
            GUILayout.EndHorizontal();

            RenderSelection(ref selectedItemTypeIndex, "Item Type: ", itemTypeNames, 3);
            ItemTypeData selectedType = itemTypeData[selectedItemTypeIndex];

            // Only allow remote companions if in Oleg's (in Act I) or your capital (in Act II+)
            bool remote = Game.Instance.CurrentlyLoadedArea.IsCapital;
            List <UnitEntityData> partySpellCasters = (from entity in UIUtility.GetGroup(remote)
                                                       where entity.IsPlayerFaction &&
                                                       !entity.Descriptor.IsPet &&
                                                       entity.Descriptor.Spellbooks != null &&
                                                       entity.Descriptor.Spellbooks.Any() &&
                                                       !entity.Descriptor.State.IsFinallyDead
                                                       select entity).ToList <UnitEntityData>();

            if (partySpellCasters.Count == 0)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label("No characters with spells available.");
                GUILayout.EndHorizontal();
                return;
            }

            GUILayout.BeginVertical();
            string[] partyNames = (from entity in partySpellCasters select entity.CharacterName).ToArray <string>();
            RenderSelection(ref selectedSpellcasterIndex, "Caster: ", partyNames, 8);
            UnitEntityData   caster     = partySpellCasters[selectedSpellcasterIndex];
            List <Spellbook> spellbooks = (from book in caster.Descriptor.Spellbooks where book.CasterLevel > 0 select book).ToList <Spellbook>();

            if (spellbooks.Count == 0)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label($"{caster.CharacterName} is not yet able to cast spells.");
                GUILayout.EndHorizontal();
            }
            else if (spellbooks.Count == 1)
            {
                selectedSpellbookIndex = 0;
            }
            else
            {
                string[] spellbookNames = (from book in spellbooks select book.Blueprint.Name.ToString()).ToArray <string>();
                RenderSelection(ref selectedSpellbookIndex, "Class: ", spellbookNames, 10);
            }

            if (selectedSpellbookIndex < spellbooks.Count)
            {
                Spellbook spellbook       = spellbooks[selectedSpellbookIndex];
                int       maxLevel        = Math.Min(spellbook.MaxSpellLevel, selectedType.MaxSpellLevel);
                string[]  spellLevelNames = (from index in Enumerable.Range(0, maxLevel) select $"Level {index}").ToArray <string>();
                RenderSelection(ref selectedSpellLevelIndex, "Select spell level: ", spellLevelNames, 10);
                int spellLevel = selectedSpellLevelIndex;
                IEnumerable <AbilityData> spellOptions = null;
                if (spellLevel == 0)
                {
                    // Cantrips/Orisons are special.
                    spellOptions = spellbook.GetKnownSpells(spellLevel);
                }
                else if (spellbook.Blueprint.Spontaneous)
                {
                    // Spontaneous spellcaster
                    if (spellbook.GetSpontaneousSlots(spellLevel) > 0)
                    {
                        GUILayout.BeginHorizontal();
                        GUILayout.Label($"{caster.CharacterName} can cast {spellbook.GetSpontaneousSlots(spellLevel)} more level {spellLevel} spells today.");
                        GUILayout.EndHorizontal();
                        spellOptions = spellbook.GetKnownSpells(spellLevel);
                    }
                }
                else
                {
                    // Prepared spellcaster
                    spellOptions = (from slot in spellbook.GetMemorizedSpells(spellLevel) where slot.Spell != null && slot.Available select slot.Spell);
                }
                if (spellOptions == null || !spellOptions.Any())
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Label($"{caster.CharacterName} cannot currently cast any level {spellLevel} spells.");
                    GUILayout.EndHorizontal();
                }
                else
                {
                    int minCasterLevel = Math.Max(1, 2 * spellLevel - 1);
                    if (minCasterLevel < spellbook.CasterLevel)
                    {
                        selectedCasterLevel = Mathf.RoundToInt(Mathf.Clamp(selectedCasterLevel, minCasterLevel, spellbook.CasterLevel));
                        GUILayout.BeginHorizontal();
                        GUILayout.Label("Caster level: ", GUILayout.ExpandWidth(false));
                        selectedCasterLevel = Mathf.RoundToInt(GUILayout.HorizontalSlider(selectedCasterLevel, minCasterLevel, spellbook.CasterLevel, GUILayout.Width(300)));
                        GUILayout.Label($"{selectedCasterLevel}", GUILayout.ExpandWidth(false));
                        GUILayout.EndHorizontal();
                    }
                    else
                    {
                        selectedCasterLevel = minCasterLevel;
                        GUILayout.BeginHorizontal();
                        GUILayout.Label($"Caster level: {selectedCasterLevel}", GUILayout.ExpandWidth(false));
                        GUILayout.EndHorizontal();
                    }
                    foreach (AbilityData spell in spellOptions.OrderBy(spell => spell.Name).Distinct())
                    {
                        if (spell.MetamagicData != null && spell.MetamagicData.NotEmpty)
                        {
                            GUILayout.Label($"Cannot craft {itemTypeNames[selectedItemTypeIndex]} of {spell.Name} with metamagic applied.");
                        }
                        else if (spell.Blueprint.HasVariants)
                        {
                            // Spells with choices (e.g. Protection from Alignment, which can be Protection from Evil, Good, Chaos or Law)
                            foreach (BlueprintAbility variant in spell.Blueprint.Variants)
                            {
                                RenderCraftItemControl(spellbook, spell, variant, spellLevel, selectedCasterLevel);
                            }
                        }
                        else
                        {
                            RenderCraftItemControl(spellbook, spell, spell.Blueprint, spellLevel, selectedCasterLevel);
                        }
                    }
                }

                GUILayout.BeginHorizontal();
                GUILayout.Label($"Current Money: {Game.Instance.Player.Money}");
                GUILayout.EndHorizontal();
            }
            GUILayout.EndVertical();
        }
コード例 #3
0
        static void RenderCraftItemControl(Spellbook spellbook, AbilityData spell, BlueprintAbility spellBlueprint, int spellLevel, int casterLevel)
        {
            ItemTypeData selectedItemData = itemTypeData[selectedItemTypeIndex];
            List <BlueprintItemEquipment> itemBlueprintList = FindItemBlueprintForSpell(spellBlueprint, selectedItemData.Type);

            if (itemBlueprintList == null && selectedItemData.Type == UsableItemType.Potion)
            {
                GUILayout.Label($"There is no {itemTypeNames[selectedItemTypeIndex]} of {spellBlueprint.Name}");
                return;
            }
            BlueprintItemEquipment existingItemBlueprint = (itemBlueprintList == null) ? null : itemBlueprintList.Find(bp => bp.SpellLevel == spellLevel && bp.CasterLevel == casterLevel);
            int    goldCost  = selectedItemData.BaseItemGoldCost * Math.Max(1, spellLevel) * casterLevel / (spellLevel == 0 ? 8 : 4);
            bool   canAfford = (Game.Instance.Player.Money >= goldCost);
            string cost      = $"{goldCost} gold{(canAfford ? "" : " (which you can't afford)")}";

            if (spell.RequireMaterialComponent)
            {
                int count = spellBlueprint.MaterialComponent.Count * selectedItemData.Charges;
                cost += $" and {count} {spellBlueprint.MaterialComponent.Item.Name}";
                if (!Game.Instance.Player.Inventory.Contains(spellBlueprint.MaterialComponent.Item, count))
                {
                    canAfford = false;
                    cost     += " (which you don't have)";
                }
            }
            string custom = (itemBlueprintList == null || existingItemBlueprint == null || existingItemBlueprint.AssetGuid.Length > vanillaAssetIdLength) ? "(custom) " : "";

            if (!canAfford)
            {
                GUILayout.Label($"Craft {custom}{itemTypeNames[selectedItemTypeIndex]} of {spellBlueprint.Name} for {cost}");
            }
            else if (GUILayout.Button($"Craft {custom}{itemTypeNames[selectedItemTypeIndex]} of {spellBlueprint.Name} for {cost}", GUILayout.ExpandWidth(false)))
            {
                Game.Instance.Player.SpendMoney(goldCost);
                spell.SpendFromSpellbook();
                if (spell.RequireMaterialComponent)
                {
                    int count = spellBlueprint.MaterialComponent.Count * selectedItemData.Charges;
                    Game.Instance.Player.Inventory.Remove(spellBlueprint.MaterialComponent.Item, count);
                }
                string blueprintId = null;
                if (itemBlueprintList == null)
                {
                    // Create a custom blueprint with casterLevel, spellLevel and spellId
                    blueprintId = BuildCustomItemGuid(RandomBaseBlueprintId(selectedItemData), casterLevel, spellLevel, spell.Blueprint.AssetGuid);
                }
                else if (existingItemBlueprint == null)
                {
                    // Create a custom blueprint with casterLevel and optionally SpellLevel
                    blueprintId = BuildCustomItemGuid(itemBlueprintList[0].AssetGuid, casterLevel, itemBlueprintList[0].SpellLevel == spellLevel ? -1 : spellLevel);
                }
                else
                {
                    // Use an existing blueprint
                    blueprintId = existingItemBlueprint.AssetGuid;
                }
                BlueprintItemEquipment actualBlueprint = (BlueprintItemEquipment)ResourcesLibrary.TryGetBlueprint(blueprintId);
                ItemEntity             item            = ItemsEntityFactory.CreateEntity(actualBlueprint);
                item.IsIdentified = true;                     // Mark the item as identified.
                item.Charges      = selectedItemData.Charges; // Set the charges, since wand blueprints have random values.
                Game.Instance.Player.Inventory.Add(item);
                if (existingItemBlueprint == null)
                {
                    AddItemBlueprintForSpell(spell.Blueprint, selectedItemData.Type, actualBlueprint);
                }
                switch (selectedItemData.Type)
                {
                case UsableItemType.Scroll:
                    Game.Instance.UI.Common.UISound.Play(UISoundType.NewInformation);
                    break;

                case UsableItemType.Potion:
                    Game.Instance.UI.Common.UISound.PlayItemSound(SlotAction.Take, item, false);
                    break;

                case UsableItemType.Wand:
                    Game.Instance.UI.Common.UISound.Play(UISoundType.SettlementBuildStart);
                    break;
                }
            }
        }