Skip to content

Items

Tutorials

ItemObject

ItemObject grain = MBObjectManager.Instance.GetObject<ItemObject>("grain");
Trade Items:

beer
butter
cheese
date_fruit
fish
grape
grain
meat
olives

charcoal
ironIngot1 (Crude Iron)
ironIngot2 (Wrought Iron)
ironIngot3 (Iron)
ironIngot4 (Steel)
ironIngot5 (Fine Steel)
ironIngot6 (Thamaskene Steel)

clay
cotton (Raw Silk)
flax
fur
hardwood
hides
jewelry
leather
linen
oil
pottery
salt
silver
spice
tools
velvet
wine
wool

cat
dog
chicken
goose
hog
sheep
cow

stolen_goods

ItemRoster

Class to describe all items the Party/Town/Hero has.

Properties

int     Count [get]
float   TotalWeight [get]
int     TotalFood [get]
int     FoodVariety [get]
int     TotalValue [get]
int     TradeGoodsTotalValue [get]
int     NumberOfPackAnimals [get]
int     NumberOfLivestockAnimals [get]
int     NumberOfMounts [get]

Examples

Count all food items in the ItemRoster
int itemCount = 0;
for (int i = 0; i < itemRoster.Count; i++)
{
    ItemObject item = itemRoster.GetItemAtIndex(i);
    if (item.IsFood)
    {
        itemCount += itemRoster.GetItemNumber(item);
    }
}

How many grain player party has:

PartyBase.MainParty.ItemRoster.GetItemNumber(MBObjectManager.Instance.GetObject<ItemObject>("grain"));

How many grain settlement has:

Settlement.ItemRoster.GetItemNumber(MBObjectManager.Instance.GetObject<ItemObject>("grain"));
Check how much of item X the party has example method
public static int GetPartyItemCount(MobileParty party, string itemID)
{
    if (party == null || party.ItemRoster == null) return 0;
    if (itemID.Length == 0) return 0;

    ItemObject item = MBObjectManager.Instance.GetObject<ItemObject>(itemID);
    if (item == null) return 0;

    return party.ItemRoster.GetItemNumber(item);
}
Check if party has X items example method
public static bool PartyHasItemCount(MobileParty party, string itemID, int count)
{
    if (party == null || party.ItemRoster == null) return false;
    if (itemID.Length == 0) return false;
    if (count < 0) return false;

    ItemObject item = MBObjectManager.Instance.GetObject<ItemObject>(itemID);
    if (item == null) return false;

    if (party.ItemRoster.GetItemNumber(item) >= count) return true;

    return false;
}

Add Item to ItemRoster

ItemObject butterItemObject = MBObjectManager.Instance.GetObject<ItemObject>("butter");
if (butterItemObject != null) {
    ItemRosterElement itemRoster = new ItemRosterElement(butterItemObject, 2, null);
    MobileParty.MainParty.ItemRoster.Add(itemRoster);
}

Add X items to the party method example
public static void AddItemsToParty(MobileParty party, string itemID, int count)
{
    if (party == null || party.ItemRoster == null) return;
    if (itemID.Length == 0) return;
    if (count < 0) return;

    ItemObject item = MBObjectManager.Instance.GetObject<ItemObject>(itemID);
    if (item == null) return;

    party.ItemRoster.Add(new ItemRosterElement(item, count, null));
}

Remove

ItemRosterElement itemRosterElement = new ItemRosterElement(itemObject, 10, null);
settlement.Stash.Remove(itemRosterElement);     // from settlement's stash
party.ItemRoster.Remove(itemRosterElement);     // from party

Remove X items from the party example method
public static void RemoveItemsFromParty(MobileParty party, string itemID, int count)
{
    if (party == null || party.ItemRoster == null) return;
    if (itemID.Length == 0) return;
    if (count < 0) return;

    ItemObject item = MBObjectManager.Instance.GetObject<ItemObject>(itemID);
    if (item == null) return;

    party.ItemRoster.Remove(new ItemRosterElement(item, count, null));
}

Price

Returns weird price, not the same as in the Trade screen.

town.GetItemPrice or village.GetItemPrice:

int GetItemPrice(ItemObject item, MobileParty tradingParty = null, bool isSelling = false)
int GetItemPrice(EquipmentElement itemRosterElement, MobileParty tradingParty = null, bool isSelling = false)


This returns the same price as in the Trade screen.

town.MarketData.GetPrice or village.MarketData.GetPrice

int GetPrice(ItemObject item, MobileParty tradingParty, bool isSelling, PartyBase merchantParty)

int itemPrice = village.MarketData.GetPrice(item, MobileParty.MainParty, false, village.Settlement.Party);


item.value - returns default item's value (from XML?)

Tier

Public enum ItemTiers
{
    Tier1,
    Tier2,
    Tier3,
    Tier4,
    Tier5,
    Tier6,
    NumTiers
}

Tier 0 (in GUI) == -1 when comparing with ItemTier.

For a head armor Tier is set automatically based on the <ItemComponent><Armor head_armor value

By price for other types of armors also:

InventoryManager

Screen(s) to trade/exchange items

InventoryManager.OpenScreenAsReceiveItems(itemRoster, new TextObject("Top Left Name"), new InventoryManager.DoneLogicExtrasDelegate(OnInventoryScreenDone));
More functions
public static void OpenScreenAsInventoryOfSubParty(MobileParty rightParty, MobileParty leftParty, DoneLogicExtrasDelegate doneLogicExtrasDelegate) // not used in-game, crash on exit
public static void OpenScreenAsInventoryForCraftedItemDecomposition(MobileParty party, CharacterObject character, DoneLogicExtrasDelegate doneLogicExtrasDelegate)
public static void OpenScreenAsInventory(DoneLogicExtrasDelegate doneLogicExtrasDelegate = null
public static void OpenScreenAsReceiveItems(ItemRoster items, TextObject leftRosterName, DoneLogicExtrasDelegate doneLogicDelegate = null)
public static void OpenScreenAsTrade(ItemRoster leftRoster, SettlementComponent settlementComponent, InventoryCategoryType merchantItemType = InventoryCategoryType.None, DoneLogicExtrasDelegate doneLogicExtrasDelegate = null)
public static void OpenScreenAsInventoryOf(MobileParty party, CharacterObject character)
public static void OpenScreenAsInventoryOf(PartyBase rightParty, PartyBase leftParty)
public static void OpenScreenAsLoot(Dictionary<PartyBase, ItemRoster> itemRostersToLoot)
public static void OpenScreenAsStash(ItemRoster stash)
public static void OpenTradeWithCaravanOrAlleyParty(MobileParty caravan, InventoryCategoryType merchantItemType = InventoryCategoryType.None)

Get Items in-game

Trade goods: Items.AllTradeGoods
Other: Items.All.Where(item => (whatever condition you want))

Items.All.Where(item => item.Type == ItemObject.ItemTypeEnum.Goods && !item.StringId.Contains("book")))

// get ordered by Name
var orderedItems = Items.All
  .Where(item => item.Type == ItemObject.ItemTypeEnum.Goods && !item.StringId.Contains("book"))
  .OrderBy(item => item.Name.ToString(), StringComparer.Ordinal);

foreach (ItemObject item in orderedItems) { // do something with the items }

XML

Folder

\Modules\SandBoxCore\ModuleData\items

Basic trade goods described in this file:
\Modules\SandBoxCore\ModuleData\items\horses_and_others.xml

For mods:

\MODFolder\ModuleData
PROBLEM: Items are not loaded from XML

Check your engine logs for item read errors/warning. As I said before a new behavior that I experienced with 1.2++ versions of the game that if you have a faulty item, all the item definitions coming after it will not load either, not just the one that is bad. So maybe there has always been one that was bad, you just didnt notice it among the hundreds of items. (hunharibo)

Properties

  • 'mesh' - 3D mesh
  • 'using_tableau' - true if an item (usually body armor) has banner/sigil on it
  • 'is_merchandise' - is used to determine whether an item is a merchandise or not. Used in the game code to determine if Item can be lost, on deciding rewards and something else
  • 'appearance' - used in calculating the item value (CalculateValue): return (int)(num2 * num * (1f + 0.2f * (item.Appearance - 1f)) + 100f * MathF.Max(0f, item.Appearance - 1f));
  • 'value' - price
  • 'weight'
  • 'culture' (optional) - Defined culture of the current item. If an item is set for a culture, the item will only be sold on the markets of the same culture. Can't have multiple values of the 'culture' attribute, so that the product is available for sale in towns of only two cultures. You can set it to neutral culture, but then it will show up everywhere.
  • 'difficulty' - (need confirmation) is used to indicate the level of difficulty in crafting an item
  • 'item_category' - (need confirmation) influences price range based on the market. Example - if item_category="jewelry" and item value="1000", in-game item can cost from ~1000 at start and drop to 150 after few weeks. Because jewelry prices drop in the region. If this item_category is changed to let's say 'book', then in-game same item costs ~1000 again.
  • 'subtype' - is used to provide additional information about the type of item being defined. The subtype property is often used in conjunction with the item_category property to further refine the classification of an item

ItemObject

Required skill/value:

ItemObject.RelevantSkill, ItemObject.Difficulty

Type

ItemTypeEnum
  • Invalid
  • Horse
  • OneHandedWeapon
  • TwoHandedWeapon
  • Polearm
  • Arrows
  • Bolts
  • Shield
  • Bow
  • Crossbow
  • Thrown
  • Goods
  • HeadArmor
  • BodyArmor
  • LegArmor
  • HandArmor
  • Pistol
  • Musket
  • Bullets
  • Animal
  • Book
  • ChestArmor
  • Cape
  • HorseHarness
  • Banner

Type="Goods" sets ItemObject.IsTradeGood == true and ItemObject.ItemType == "Goods"

Caravan Ambush mission

Gives 3 random "Goods" type items as a reward. So if your item type is "Goods", they will be given at some point.

Q. How to make certain items not appear in the lootpool and also in the marketplace?
A. Set is_merchandise="false" and assign to the culture that does not have markets, e.g. Looters/Bandits (Culture.looter)

It appears that items that are not for sale (is_merchandise="false") may appear as prizes in tournaments. But it probably depends on the cost of the item - the higher it is, the greater the likelihood.

Broken Item

Since 1.2.x, if a single item is broken, everything past that won't get loaded

So lets say you have a list of 100 items. If item 32 is broken, everything after doesn't appear in game.

If you want to more easily find out which it is check your logs in programdata (its a hidden folder so you gotta make hidden folders visible) and search for null or invalid.


How to find ItemID

Let's say we want to find ItemID for this item:

Easy way: use this mod

Hard way: Use ripgrep in the game's folder:

rg -C 5 "Thinhide Coif"

And you will see (among a lot of other stuff):

Modules\SandBoxCore\ModuleData\items\head_armors.xml
869-  </Item>
870-  <!-- #region Battania Armors -->
871-  <!-- #region Battania Head Armors -->
872-  <!-- #region Battania Light Head Armors -->
873-  <Item id="thinhide_coif"
874:        name="{=Q50hfNjW}Thinhide Coif"
875-        subtype="head_armor"
876-        mesh="battania_helmet_a"
877-        culture="Culture.battania"
878-        weight="0.5"
879-        difficulty="0"

This is what you need:

<Item id="thinhide_coif"

Then you can use it in your mod. Example:

<Equipments>
    <EquipmentRoster civilian="true">
        <equipment slot="Head"
            id="Item.thinhide_coif" />

...and mesh

Mesh (3D model's name) usually is different from the ItemID, and you can find it in the item's definition in the XML:

876-        mesh="battania_helmet_a"

You will need it for export from TpacTool and working with 3D program such as Blender.

Helmet Hair Coverage

Helmet Hair Coverage