From 10b8110216cce54a2d3eef1e23a61aafe8f63b54 Mon Sep 17 00:00:00 2001 From: georgeto Date: Sat, 27 Dec 2025 14:18:30 +0100 Subject: [PATCH] [G3] Document inventory and treasure sets --- docs/genome/inventory/index.md | 29 ++++++ docs/genome/inventory/treasure_sets.md | 127 +++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 docs/genome/inventory/index.md create mode 100644 docs/genome/inventory/treasure_sets.md diff --git a/docs/genome/inventory/index.md b/docs/genome/inventory/index.md new file mode 100644 index 0000000000..0c91e6b8f8 --- /dev/null +++ b/docs/genome/inventory/index.md @@ -0,0 +1,29 @@ +# Inventory + +The `gCInventory_PS` property set manages the inventory of an entity (such as NPC, Hero or chest). +The inventory is a list of inventory stacks (`gCInventoryStack`). +Each inventory stack references a `Template` that is the blueprint for the item contained in the stack. +The `Quality` and `Amount` of the item is also stored as part of the stack. +When an item gets equipped to a slot, a physical object with a 3D mesh, physics, and location is spawned in the world and attached to the holding entity (see `Slot` and `Item`). +The inventory can contain multiple stacks referencing the same template, but with a different quality, equip status or stack type. + +Both the category of an item (`gCItem.Category`) and the stack type with which the item gets inserted into the inventory (see also [Treasure Sets](treasure_sets.md)) control in which contexts an inventory stack is visible and usable: + +- Regular inventory +- Trade inventory +- Plunder inventory +- Skills +- Spellbook +- ... + +## Skills and Spells +The skills and spells that the hero can learn are represented by items in his inventory with the category `gEItemCategory_Spellbook` respectively `gEItemCategory_Skill`. + +The `ActivationCount` of a stack is only relevant for stacks containing skills or spells. Its content is related to the `Learned` flag of the stack, because if `ActivationCount` has a value > 0, the skill or spell is activated for the hero. + +The difference between the two is important: + +- If `Learned` is set to `true`, the hero has permanently learned the skill or spell and can no longer unlearn it. +- The `ActivationCount`, on the other hand, is always increased by 1 when the hero equips an item that grants this skill or spell as a bonus. When the item is unequipped, the counter is decreased by 1 again. If all items are unequipped, the skills are no longer active for the hero. + +Since the hero receives his skills, spells, etc. via code at the start of the game, setting the `ActivationCount` or `Learned` flag for a stack is of no practical use. diff --git a/docs/genome/inventory/treasure_sets.md b/docs/genome/inventory/treasure_sets.md new file mode 100644 index 0000000000..7b42c31877 --- /dev/null +++ b/docs/genome/inventory/treasure_sets.md @@ -0,0 +1,127 @@ +# Treasure Sets + +Treasure Sets are templates (located in `Templates/Treasure`) that are used to define NPC weapon loadouts, NPC plunder/pickpocket/trade inventories, and the contents of chests. +Up to five treasure sets can be assigned to an NPC via the `TreasureSet1` to `TreasureSet5` properties of its `gCInventory_PS` property set. + +## Plunder Inventory + +### gETreasureDistribution_Plunder +```text +TransferStacks = Random selection from the interval [MinTransferStacks, MaxTransferStacks] + +If TransferStacks < 1: + TransferStacks = 1 + +Repeat TransferStacks times: + Stack = Select a random stack from the TreasureSet + + If Stack.Amount > 1: + Amount = Random selection from the interval [Stack.Amount / 2, Stack.Amount] + Otherwise: + Amount = Stack.Amount + + Inventory.Add(Stack.Template, Amount, GetCombinedQuality(Stack), gEStackType_Treasure) +``` + +### gETreasureDistribution_Unique +```text +Stack = Stack with the lowest gold value among all stacks of the TreasureSet that are not yet marked as already generated + +If all stacks are already marked as generated: + Stack = Random stack from the TreasureSet + +If Stack.Amount > 1: + Amount = Random selection from the interval [Stack.Amount / 2, Stack.Amount] +Otherwise: + Amount = Stack.Amount + +Inventory.Add(Stack.Template, Amount, GetCombinedQuality(Stack), gEStackType_Treasure) + +Mark Stack as generated +``` + +### gETreasureDistribution_Trophy +```text +Repeat for each stack: + If Stack.UseType == gEUseType_TrophyTeeth and the player has NOT learned Perk_TrophyTeeth: + Skip stack + + If Stack.UseType == gEUseType_TrophyFur and the player has NOT learned Perk_TrophyFur: + Skip stack + + If Stack.UseType == gEUseType_TrophySkin and the player has NOT learned Perk_TrophySkin: + Skip stack + + Inventory.Add(Stack.Template, Stack.Amount, GetCombinedQuality(Stack), gEStackType_Treasure) +``` + +### gETreasureDistribution_Mining +```text +Repeat for each stack: + If the player has learned Perk_Mining: + Amount = 2 * Stack.Amount + Otherwise: + Amount = Stack.Amount + + Inventory.Add(Stack.Template, Amount, Stack.Quality, gEStackType_Treasure) +``` + +## Trade Inventory + +### gETreasureDistribution_Trade_Generate +```text +TransferStacks = Random selection from the interval [MinTransferStacks, MaxTransferStacks] + +Repeat TransferStacks times: + Stack = Select a random stack from the TreasureSet + + If Stack.Amount > 1: + Amount = Random selection from the interval [Stack.Amount / 2, Stack.Amount] + Otherwise: + Amount = Stack.Amount + + Inventory.Add(Stack.Template, Amount, GetCombinedQuality(Stack), gEStackType_Merchandise) +``` + +### gETreasureDistribution_Trade_Refresh +```text +Repeat for each stack: + If Stack.Amount > 1: + Amount = Random selection from the interval [Stack.Amount / 2, Stack.Amount] + Otherwise: + Amount = Stack.Amount + + Inventory.Add(Stack.Template, Amount, GetCombinedQuality(Stack), gEStackType_Merchandise) +``` + +### gETreasureDistribution_Trade_NotRandom +Each stack is generated into the trade inventory in exactly the specified amount. (see also Modder Handbook 1.7.6) +```text +Repeat for each stack: + Inventory.Add(Stack.Template, Stack.Amount, Stack.Quality, gEStackType_Merchandise) +``` +## Pickpocket Inventory + +### gETreasureDistribution_Pickpocket +```text +Stack = Select a random stack + +Inventory.AddAndEquip(Stack.Template, Stack.Amount, Stack.Quality, gEStackType_Normal) +``` + +## Weaponry + +### gETreasureDistribution_Weaponry +```text +Repeat for each stack: + Quality = Stack.Quality + if ( Stack.UseType != gEUseType_Arrow and Stack.UseType != gEUseType_Bolt ) + Quality |= gEItemQuality_Worn; + Inventory.AddAndEquip(Stack.Template, Stack.Amount, Quality, gEStackType_Normal) +``` + +Min/MaxTransferStacks do not matter for Weaponry treasure sets. The engine simply processes the full list of stacks contained in the TreasureSet. Also note, that only the first Weaponry treasure set is considered. + +If alternative balancing is enabled, once an NPC has been defeated by the hero (`PSNpc::DefeatedByPlayer == true`), that NPC's weaponry is no longer derived from its TreasureSets, but instead the NPC receives a standard weapon that depends on its species (Orc or Human) and political alignment. + +