// Make our mod-specific updates to the blueprint based on the data stored in assetId. Return a string which // is the AssetGuid of the supplied blueprint plus our customization again, or null if we couldn't change the // blueprint. static string ApplyBlueprintPatch(BlueprintItemEquipment blueprint, string assetId) { Match match = blueprintRegex.Match(assetId); if (match.Success) { int casterLevel = int.Parse(match.Groups[2].Value); blueprint.CasterLevel = casterLevel; int spellLevel = -1; if (match.Groups[3].Success) { spellLevel = int.Parse(match.Groups[4].Value); blueprint.SpellLevel = spellLevel; } string spellId = null; if (match.Groups[5].Success) { spellId = match.Groups[6].Value; blueprint.Ability = (BlueprintAbility)ResourcesLibrary.TryGetBlueprint(spellId); } blueprint.DC = 10 + spellLevel * 3 / 2; Traverse.Create(blueprint).Field("m_Cost").SetValue(0); // Allow the game to auto-calculate the cost return(BuildCustomItemGuid(blueprint.AssetGuid, casterLevel, spellLevel, spellId)); } else { storedModEntry.Logger.Warning($"Failed to find expected substring in custom blueprint assetId ${assetId}"); return(null); } }
static bool Prefix(ItemEntityArmor __instance, UnitDescriptor owner, ref bool __result) { BlueprintItemEquipment blueprint = __instance.Blueprint as BlueprintItemEquipment; if (blueprint == null || !Helpers.isBodyArmor(__instance.Blueprint)) { return(true); } __result = blueprint.CanBeEquippedBy(owner); return(false); }
public static void RestoreAllItemCharges() { foreach (ItemEntity itemEntity in Game.Instance.Player.Inventory) { BlueprintItemEquipment blueprint = itemEntity.Blueprint as BlueprintItemEquipment; if (blueprint != null && blueprint.GainAbility && blueprint.SpendCharges) { itemEntity.Charges = blueprint.Charges; } } }
public static void Postfix(bool __state, ItemEntity __instance, ref bool __result, UnitDescriptor user) { if (__state) { BlueprintItemEquipment blueprintItemEquipment = __instance.Blueprint as BlueprintItemEquipment; if (!blueprintItemEquipment || !blueprintItemEquipment.GainAbility) { __result = false; return; } if (!__instance.IsSpendCharges) { __result = true; return; } bool hasNoCharges = false; if (__instance.Charges > 0) { ItemEntityUsable itemEntityUsable = new ItemEntityUsable((BlueprintItemEquipmentUsable)__instance.Blueprint); if (user.State.Features.HandOfMagusDan && itemEntityUsable.Blueprint.Type == UsableItemType.Scroll) { RuleRollDice ruleRollDice = new RuleRollDice(user.Unit, new DiceFormula(1, DiceType.D100)); Rulebook.Trigger(ruleRollDice); if (ruleRollDice.Result <= 25) { __result = true; return; } } if (user.IsPlayerFaction) { __result = true; return; } --__instance.Charges; } else { hasNoCharges = true; } if (__instance.Charges >= 1 || blueprintItemEquipment.RestoreChargesOnRest) { __result = !hasNoCharges; return; } if (__instance.Count > 1) { __instance.DecrementCount(1); __instance.Charges = 1; } else { ItemsCollection collection = __instance.Collection; collection?.Remove(__instance); } __result = !hasNoCharges; } }
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; } } }
static void AddItemBlueprintForSpell(BlueprintAbility spell, UsableItemType itemType, BlueprintItemEquipment item) { if (!spellIdToItem.ContainsKey(itemType)) { spellIdToItem.Add(itemType, new Dictionary <string, List <BlueprintItemEquipment> >()); } if (!spellIdToItem[itemType].ContainsKey(item.Ability.AssetGuid)) { spellIdToItem[itemType][item.Ability.AssetGuid] = new List <BlueprintItemEquipment>(); } spellIdToItem[itemType][item.Ability.AssetGuid].Add(item); }