Table of Contents

Class Item

Namespace
FishMMO.Shared
Assembly
FishMMO.Shared.dll

Represents an item instance in the game, including stackable, equippable, and generated properties. Handles initialization, attribute management, and tooltip generation. Implements ITooltip for consistent UI tooltip display.

public class Item : ITooltip
Inheritance
Item
Implements
Inherited Members

Constructors

Item(BaseItemTemplate, uint)

Constructs an item from a template and amount, initializing all components.

IMPORTANT: This constructor creates items with ID=0. The ID is assigned by the database on first persist, so an item built here is not yet a database row. It is still a fully formed gameplay item: every server-side grant path (merchant purchase, quest and achievement rewards, gathering nodes, world pickups, GiveItemAction) builds items through here.

public Item(BaseItemTemplate template, uint amount)

Parameters

template BaseItemTemplate

The item template.

amount uint

The stack amount.

Remarks

This used to construct only the stackable component, leaving Equippable and Generator null. EquipmentController refuses any item whose IsEquippable is false, so a sword you had just bought or looted could not be equipped at all until you relogged and the item came back through Item(long, int, int, uint), which does call Initialize(long, uint, int). Both constructors now go through the same initialization; there is no second, weaker kind of Item.

The seed is passed as 0 deliberately: Initialize(long, uint, int) derives one from the item's id, and an item built here has none yet. AssignPersistentID(long) derives it when the first persist returns the id, so the attributes this item rolls are the same ones it will roll when it is reloaded. (They were not, before that: a looted weapon generated from seed 0 and came back after a relog with a different roll.)

Item(long, int, BaseItemTemplate, uint)

Constructs an item from an ID, seed, template, and amount, initializing all components.

public Item(long id, int seed, BaseItemTemplate template, uint amount)

Parameters

id long

The item ID.

seed int

The random seed for generation.

template BaseItemTemplate

The item template.

amount uint

The stack amount.

Item(long, int, int, uint)

Constructs an item from an ID, seed, template ID, and amount, initializing all components.

public Item(long id, int seed, int templateID, uint amount)

Parameters

id long

The item ID.

seed int

The random seed for generation.

templateID int

The template ID.

amount uint

The stack amount.

Fields

Equippable

The equippable component for this item, if applicable.

public ItemEquippable Equippable

Field Value

ItemEquippable

Generator

The item generator responsible for random attributes and generation logic.

public ItemGenerator Generator

Field Value

ItemGenerator

Slot

The slot index this item is currently assigned to.

public int Slot

Field Value

int

Stackable

The stackable component for this item, if applicable.

public ItemStackable Stackable

Field Value

ItemStackable

Version

Version number for this item instance, used for client synchronization and updates. Incremented whenever the item's state changes in a way that requires client updates.

public long Version

Field Value

long

Properties

ID

This item's identity: the primary key of its row in character_item.

public long ID { get; }

Property Value

long

Remarks

There is exactly one item identity, and this is it. There used to be two — this, and a process-local InstanceID counter that the attribute ledger keyed on — because the database could not supply an identity that was usable. Items lived in three tables (character_inventory, character_equipment, character_bank), each row was keyed (character_id, slot), and each table had its own identity sequence. So a row id named a SLOT rather than an item: it changed when the item moved, it was reused by the next item through that slot, and the same number named three different items across the three tables. Keying an attribute contribution by it would have merged the bonuses of every item that ever passed through a socket.

The single character_item table removed all three problems at once, so the second identity had nothing left to do. container and slot are now ordinary columns on a row keyed by this value, which means it survives a move between slots, a move between containers, and a relog.

Zero means "not yet written". An item created at runtime — loot, a quest reward, a merchant purchase, a stack split — has no identity until its first persist returns one, which is what AssignPersistentID(long) is for. Nothing may key durable state by a zero id.

Icon

Gets the icon sprite from the item template.

public Sprite Icon { get; }

Property Value

Sprite

IsEquippable

Returns true if the item is equippable.

public bool IsEquippable { get; }

Property Value

bool

IsGenerated

Returns true if the item has a generator (is randomly generated).

public bool IsGenerated { get; }

Property Value

bool

IsStackable

Returns true if the item is stackable.

public bool IsStackable { get; }

Property Value

bool

Name

Gets the display name from the item template.

public string Name { get; }

Property Value

string

Template

The item template defining base properties and attributes.

public BaseItemTemplate Template { get; }

Property Value

BaseItemTemplate

Methods

AssignPersistentID(long)

Records the identity the database assigned to this item on its first write.

public bool AssignPersistentID(long id)

Parameters

id long

The identity the database assigned. Must be positive.

Returns

bool

True when the identity was applied.

Remarks

Publishes the item's attribute contribution, which is why this is a method. An item equipped before its first persist returned has written NO ledger entries at all: ItemGenerator.TryResolveLedgerSource declines for a zero id, because zero is the absence of an identity and two such items would collide on ModifierSource.Item(0). The release/re-apply pair below is what states the contribution for the first time, under the identity the database has just issued. The release half is a no-op today (there is nothing under the old key to release) and is kept because it is the correct shape if the zero-id rule ever changes; SetSource states a whole contribution rather than adding to one, so running both is idempotent either way.

And derives the generation seed, for the same reason. Initialize(long, uint, int) derives a generated item's seed from its id, and an item built with no id could not do that — so a looted weapon rolled its attributes from seed 0, and the reload after logout re-derived a real seed from the id the database had meanwhile assigned and rolled a DIFFERENT set. Deriving here closes that: the item's stats stop changing behind the player's back at the next relog. The re-key above then publishes the corrected values, because it re-reads the generator after this runs.

Ignores a second call with the same id, and refuses a non-positive one. Reassigning a live identity is not a thing that can legitimately happen and would silently move the item's ledger key, so it is refused rather than accommodated.

BuildTooltip(TooltipBuilder)

Populates the tooltip builder with this item's tooltip lines.

public void BuildTooltip(TooltipBuilder builder)

Parameters

builder TooltipBuilder

The tooltip builder to populate.

DeriveSeed(long)

The generation seed an item with this identity rolls its attributes from.

public static int DeriveSeed(long id)

Parameters

id long

The item's identity. Zero yields zero: there is nothing to derive from.

Returns

int

Remarks

Shared by Initialize(long, uint, int) and AssignPersistentID(long) so the seed an item is created with and the seed it is reloaded with cannot drift apart — which is exactly what happened while only the load path derived one.

Destroy()

Destroys the item, cleaning up generator, equippable, and stackable components and detaching events.

public void Destroy()

IsMatch(Item)

Determines if this item matches another item, comparing template ID and generation seed. Used for stacking and item comparison logic.

public bool IsMatch(Item other)

Parameters

other Item

The other item to compare.

Returns

bool

True if the items match, false otherwise.

ItemEquippable_OnEquip(ICharacter)

Event handler called when the item is equipped by a character. Applies generated attributes.

public void ItemEquippable_OnEquip(ICharacter character)

Parameters

character ICharacter

The character equipping the item.

ItemEquippable_OnUnequip(ICharacter)

Event handler called when the item is unequipped by a character. Removes generated attributes.

public void ItemEquippable_OnUnequip(ICharacter character)

Parameters

character ICharacter

The character unequipping the item.

Tooltip()

Returns the formatted tooltip string for this item, including ID, slot, template tooltip, and generator info.

public string Tooltip()

Returns

string

The formatted tooltip string.

Events

OnDestroy

Event triggered when the item is destroyed.

public event Action OnDestroy

Event Type

Action