package items import ( "sync" "time" ) // Item effect types type ItemEffectType int const ( NoEffectType ItemEffectType = 0 EffectCureTypeTrauma ItemEffectType = 1 EffectCureTypeArcane ItemEffectType = 2 EffectCureTypeNoxious ItemEffectType = 3 EffectCureTypeElemental ItemEffectType = 4 EffectCureTypeCurse ItemEffectType = 5 EffectCureTypeMagic ItemEffectType = 6 EffectCureTypeAll ItemEffectType = 7 ) // Inventory slot types type InventorySlotType int const ( HouseVault InventorySlotType = -5 SharedBank InventorySlotType = -4 Bank InventorySlotType = -3 Overflow InventorySlotType = -2 UnknownInvSlotType InventorySlotType = -1 BaseInventory InventorySlotType = 0 ) // Lock reasons for items type LockReason uint32 const ( LockReasonNone LockReason = 0 LockReasonHouse LockReason = 1 << 0 LockReasonCrafting LockReason = 1 << 1 LockReasonShop LockReason = 1 << 2 ) // Add item types for tracking how items were added type AddItemType int const ( NotSet AddItemType = 0 BuyFromBroker AddItemType = 1 GMCommand AddItemType = 2 ) // ItemStatsValues represents the complete stat bonuses from an item type ItemStatsValues struct { // Base stats Str int16 `json:"str"` Sta int16 `json:"sta"` Agi int16 `json:"agi"` Wis int16 `json:"wis"` Int int16 `json:"int"` // Resistances VsSlash int16 `json:"vs_slash"` VsCrush int16 `json:"vs_crush"` VsPierce int16 `json:"vs_pierce"` VsPhysical int16 `json:"vs_physical"` VsHeat int16 `json:"vs_heat"` VsCold int16 `json:"vs_cold"` VsMagic int16 `json:"vs_magic"` VsMental int16 `json:"vs_mental"` VsDivine int16 `json:"vs_divine"` VsDisease int16 `json:"vs_disease"` VsPoison int16 `json:"vs_poison"` // Pools Health int16 `json:"health"` Power int16 `json:"power"` Concentration int8 `json:"concentration"` // Abilities and damage AbilityModifier int16 `json:"ability_modifier"` CriticalMitigation int16 `json:"critical_mitigation"` ExtraShieldBlockChance int16 `json:"extra_shield_block_chance"` BeneficialCritChance int16 `json:"beneficial_crit_chance"` CritBonus int16 `json:"crit_bonus"` Potency int16 `json:"potency"` HateGainMod int16 `json:"hate_gain_mod"` AbilityReuseSpeed int16 `json:"ability_reuse_speed"` AbilityCastingSpeed int16 `json:"ability_casting_speed"` AbilityRecoverySpeed int16 `json:"ability_recovery_speed"` SpellReuseSpeed int16 `json:"spell_reuse_speed"` SpellMultiAttackChance int16 `json:"spell_multi_attack_chance"` DPS int16 `json:"dps"` AttackSpeed int16 `json:"attack_speed"` MultiAttackChance int16 `json:"multi_attack_chance"` Flurry int16 `json:"flurry"` AEAutoattackChance int16 `json:"ae_autoattack_chance"` Strikethrough int16 `json:"strikethrough"` Accuracy int16 `json:"accuracy"` OffensiveSpeed int16 `json:"offensive_speed"` // Uncontested stats UncontestedParry float32 `json:"uncontested_parry"` UncontestedBlock float32 `json:"uncontested_block"` UncontestedDodge float32 `json:"uncontested_dodge"` UncontestedRiposte float32 `json:"uncontested_riposte"` // Other SizeMod float32 `json:"size_mod"` } // ItemCore contains the core data for an item instance type ItemCore struct { ItemID int32 `json:"item_id"` SOEId int32 `json:"soe_id"` BagID int32 `json:"bag_id"` InvSlotID int32 `json:"inv_slot_id"` SlotID int16 `json:"slot_id"` EquipSlotID int16 `json:"equip_slot_id"` // used when a bag is equipped AppearanceType int16 `json:"appearance_type"` // 0 for combat armor, 1 for appearance armor Index int8 `json:"index"` Icon int16 `json:"icon"` ClassicIcon int16 `json:"classic_icon"` Count int16 `json:"count"` Tier int8 `json:"tier"` NumSlots int8 `json:"num_slots"` UniqueID int64 `json:"unique_id"` NumFreeSlots int8 `json:"num_free_slots"` RecommendedLevel int16 `json:"recommended_level"` ItemLocked bool `json:"item_locked"` LockFlags int32 `json:"lock_flags"` NewItem bool `json:"new_item"` NewIndex int16 `json:"new_index"` } // ItemStat represents a single stat on an item type ItemStat struct { StatName string `json:"stat_name"` StatType int32 `json:"stat_type"` StatSubtype int16 `json:"stat_subtype"` StatTypeCombined int16 `json:"stat_type_combined"` Value float32 `json:"value"` Level int8 `json:"level"` } // ItemSet represents an item set piece type ItemSet struct { ItemID int32 `json:"item_id"` ItemCRC int32 `json:"item_crc"` ItemIcon int16 `json:"item_icon"` ItemStackSize int16 `json:"item_stack_size"` ItemListColor int32 `json:"item_list_color"` Name string `json:"name"` Language int8 `json:"language"` } // Classifications represents item classifications type Classifications struct { ClassificationID int32 `json:"classification_id"` ClassificationName string `json:"classification_name"` } // ItemLevelOverride represents level overrides for specific classes type ItemLevelOverride struct { AdventureClass int8 `json:"adventure_class"` TradeskillClass int8 `json:"tradeskill_class"` Level int16 `json:"level"` } // ItemClass represents class requirements for an item type ItemClass struct { AdventureClass int8 `json:"adventure_class"` TradeskillClass int8 `json:"tradeskill_class"` Level int16 `json:"level"` } // ItemAppearance represents visual appearance data type ItemAppearance struct { Type int16 `json:"type"` Red int8 `json:"red"` Green int8 `json:"green"` Blue int8 `json:"blue"` HighlightRed int8 `json:"highlight_red"` HighlightGreen int8 `json:"highlight_green"` HighlightBlue int8 `json:"highlight_blue"` } // QuestRewardData represents quest reward information type QuestRewardData struct { QuestID int32 `json:"quest_id"` IsTemporary bool `json:"is_temporary"` Description string `json:"description"` IsCollection bool `json:"is_collection"` HasDisplayed bool `json:"has_displayed"` TmpCoin int64 `json:"tmp_coin"` TmpStatus int32 `json:"tmp_status"` DbSaved bool `json:"db_saved"` DbIndex int32 `json:"db_index"` } // Generic_Info contains general item information type GenericInfo struct { ShowName int8 `json:"show_name"` CreatorFlag int8 `json:"creator_flag"` ItemFlags int16 `json:"item_flags"` ItemFlags2 int16 `json:"item_flags2"` Condition int8 `json:"condition"` Weight int32 `json:"weight"` // num/10 SkillReq1 int32 `json:"skill_req1"` SkillReq2 int32 `json:"skill_req2"` SkillMin int16 `json:"skill_min"` ItemType int8 `json:"item_type"` AppearanceID int16 `json:"appearance_id"` AppearanceRed int8 `json:"appearance_red"` AppearanceGreen int8 `json:"appearance_green"` AppearanceBlue int8 `json:"appearance_blue"` AppearanceHighlightRed int8 `json:"appearance_highlight_red"` AppearanceHighlightGreen int8 `json:"appearance_highlight_green"` AppearanceHighlightBlue int8 `json:"appearance_highlight_blue"` Collectable int8 `json:"collectable"` OffersQuestID int32 `json:"offers_quest_id"` PartOfQuestID int32 `json:"part_of_quest_id"` MaxCharges int16 `json:"max_charges"` DisplayCharges int8 `json:"display_charges"` AdventureClasses int64 `json:"adventure_classes"` TradeskillClasses int64 `json:"tradeskill_classes"` AdventureDefaultLevel int16 `json:"adventure_default_level"` TradeskillDefaultLevel int16 `json:"tradeskill_default_level"` Usable int8 `json:"usable"` Harvest int8 `json:"harvest"` BodyDrop int8 `json:"body_drop"` PvPDescription int8 `json:"pvp_description"` MercOnly int8 `json:"merc_only"` MountOnly int8 `json:"mount_only"` SetID int32 `json:"set_id"` CollectableUnk int8 `json:"collectable_unk"` OffersQuestName string `json:"offers_quest_name"` RequiredByQuestName string `json:"required_by_quest_name"` TransmutedMaterial int8 `json:"transmuted_material"` } // ArmorInfo contains armor-specific information type ArmorInfo struct { MitigationLow int16 `json:"mitigation_low"` MitigationHigh int16 `json:"mitigation_high"` } // AdornmentInfo contains adornment-specific information type AdornmentInfo struct { Duration float32 `json:"duration"` ItemTypes int16 `json:"item_types"` SlotType int16 `json:"slot_type"` } // WeaponInfo contains weapon-specific information type WeaponInfo struct { WieldType int16 `json:"wield_type"` DamageLow1 int16 `json:"damage_low1"` DamageHigh1 int16 `json:"damage_high1"` DamageLow2 int16 `json:"damage_low2"` DamageHigh2 int16 `json:"damage_high2"` DamageLow3 int16 `json:"damage_low3"` DamageHigh3 int16 `json:"damage_high3"` Delay int16 `json:"delay"` Rating float32 `json:"rating"` } // ShieldInfo contains shield-specific information type ShieldInfo struct { ArmorInfo ArmorInfo `json:"armor_info"` } // RangedInfo contains ranged weapon information type RangedInfo struct { WeaponInfo WeaponInfo `json:"weapon_info"` RangeLow int16 `json:"range_low"` RangeHigh int16 `json:"range_high"` } // BagInfo contains bag-specific information type BagInfo struct { NumSlots int8 `json:"num_slots"` WeightReduction int16 `json:"weight_reduction"` } // FoodInfo contains food/drink information type FoodInfo struct { Type int8 `json:"type"` // 0=water, 1=food Level int8 `json:"level"` Duration float32 `json:"duration"` Satiation int8 `json:"satiation"` } // BaubleInfo contains bauble-specific information type BaubleInfo struct { Cast int16 `json:"cast"` Recovery int16 `json:"recovery"` Duration int32 `json:"duration"` Recast float32 `json:"recast"` DisplaySlotOptional int8 `json:"display_slot_optional"` DisplayCastTime int8 `json:"display_cast_time"` DisplayBaubleType int8 `json:"display_bauble_type"` EffectRadius float32 `json:"effect_radius"` MaxAOETargets int32 `json:"max_aoe_targets"` DisplayUntilCancelled int8 `json:"display_until_cancelled"` } // BookInfo contains book-specific information type BookInfo struct { Language int8 `json:"language"` Author string `json:"author"` Title string `json:"title"` } // BookInfoPages represents a book page type BookInfoPages struct { Page int8 `json:"page"` PageText string `json:"page_text"` PageTextVAlign int8 `json:"page_text_valign"` PageTextHAlign int8 `json:"page_text_halign"` } // SkillInfo contains skill book information type SkillInfo struct { SpellID int32 `json:"spell_id"` SpellTier int32 `json:"spell_tier"` } // HouseItemInfo contains house item information type HouseItemInfo struct { StatusRentReduction int32 `json:"status_rent_reduction"` CoinRentReduction float32 `json:"coin_rent_reduction"` HouseOnly int8 `json:"house_only"` HouseLocation int8 `json:"house_location"` // 0 = floor, 1 = ceiling, 2 = wall } // HouseContainerInfo contains house container information type HouseContainerInfo struct { AllowedTypes int64 `json:"allowed_types"` NumSlots int8 `json:"num_slots"` BrokerCommission int8 `json:"broker_commission"` FenceCommission int8 `json:"fence_commission"` } // RecipeBookInfo contains recipe book information type RecipeBookInfo struct { Recipes []uint32 `json:"recipes"` RecipeID int32 `json:"recipe_id"` Uses int8 `json:"uses"` } // ItemSetInfo contains item set information type ItemSetInfo struct { ItemID int32 `json:"item_id"` ItemCRC int32 `json:"item_crc"` ItemIcon int16 `json:"item_icon"` ItemStackSize int32 `json:"item_stack_size"` ItemListColor int32 `json:"item_list_color"` SOEItemIDUnsigned int32 `json:"soe_item_id_unsigned"` SOEItemCRCUnsigned int32 `json:"soe_item_crc_unsigned"` } // ThrownInfo contains thrown weapon information type ThrownInfo struct { Range int32 `json:"range"` DamageModifier int32 `json:"damage_modifier"` HitBonus float32 `json:"hit_bonus"` DamageType int32 `json:"damage_type"` } // ItemEffect represents an item effect type ItemEffect struct { Effect string `json:"effect"` Percentage int8 `json:"percentage"` SubBulletFlag int8 `json:"sub_bullet_flag"` } // BookPage represents a book page type BookPage struct { Page int8 `json:"page"` PageText string `json:"page_text"` VAlign int8 `json:"valign"` HAlign int8 `json:"halign"` } // ItemStatString represents a string-based item stat type ItemStatString struct { StatString string `json:"stat_string"` } // Item represents a complete item with all its properties type Item struct { // Basic item information LowerName string `json:"lower_name"` Name string `json:"name"` Description string `json:"description"` StackCount int16 `json:"stack_count"` SellPrice int32 `json:"sell_price"` SellStatus int32 `json:"sell_status"` MaxSellValue int32 `json:"max_sell_value"` BrokerPrice int64 `json:"broker_price"` // Search and state flags IsSearchStoreItem bool `json:"is_search_store_item"` IsSearchInInventory bool `json:"is_search_in_inventory"` SaveNeeded bool `json:"save_needed"` NoBuyBack bool `json:"no_buy_back"` NoSale bool `json:"no_sale"` NeedsDeletion bool `json:"needs_deletion"` Crafted bool `json:"crafted"` Tinkered bool `json:"tinkered"` // Item metadata WeaponType int8 `json:"weapon_type"` Adornment string `json:"adornment"` Creator string `json:"creator"` SellerName string `json:"seller_name"` SellerCharID int32 `json:"seller_char_id"` SellerHouseID int64 `json:"seller_house_id"` Created time.Time `json:"created"` GroupedCharIDs map[int32]bool `json:"grouped_char_ids"` EffectType ItemEffectType `json:"effect_type"` BookLanguage int8 `json:"book_language"` // Adornment slots Adorn0 int32 `json:"adorn0"` Adorn1 int32 `json:"adorn1"` Adorn2 int32 `json:"adorn2"` // Spell information SpellID int32 `json:"spell_id"` SpellTier int8 `json:"spell_tier"` ItemScript string `json:"item_script"` // Collections and arrays Classifications []*Classifications `json:"classifications"` ItemStats []*ItemStat `json:"item_stats"` ItemSets []*ItemSet `json:"item_sets"` ItemStringStats []*ItemStatString `json:"item_string_stats"` ItemLevelOverrides []*ItemLevelOverride `json:"item_level_overrides"` ItemEffects []*ItemEffect `json:"item_effects"` BookPages []*BookPage `json:"book_pages"` SlotData []int8 `json:"slot_data"` // Core item data Details ItemCore `json:"details"` GenericInfo GenericInfo `json:"generic_info"` // Type-specific information (pointers to allow nil for unused types) WeaponInfo *WeaponInfo `json:"weapon_info,omitempty"` RangedInfo *RangedInfo `json:"ranged_info,omitempty"` ArmorInfo *ArmorInfo `json:"armor_info,omitempty"` AdornmentInfo *AdornmentInfo `json:"adornment_info,omitempty"` BagInfo *BagInfo `json:"bag_info,omitempty"` FoodInfo *FoodInfo `json:"food_info,omitempty"` BaubleInfo *BaubleInfo `json:"bauble_info,omitempty"` BookInfo *BookInfo `json:"book_info,omitempty"` BookInfoPages *BookInfoPages `json:"book_info_pages,omitempty"` HouseItemInfo *HouseItemInfo `json:"house_item_info,omitempty"` HouseContainerInfo *HouseContainerInfo `json:"house_container_info,omitempty"` SkillInfo *SkillInfo `json:"skill_info,omitempty"` RecipeBookInfo *RecipeBookInfo `json:"recipe_book_info,omitempty"` ItemSetInfo *ItemSetInfo `json:"item_set_info,omitempty"` ThrownInfo *ThrownInfo `json:"thrown_info,omitempty"` // Thread safety mutex sync.RWMutex } // MasterItemList manages all items in the game type MasterItemList struct { items map[int32]*Item `json:"items"` mappedItemStatsStrings map[string]int32 `json:"mapped_item_stats_strings"` mappedItemStatTypeIDs map[int32]string `json:"mapped_item_stat_type_ids"` brokerItemMap map[*VersionRange]map[int64]int64 `json:"-"` // Complex type, exclude from JSON mutex sync.RWMutex } // VersionRange represents a version range for broker item mapping type VersionRange struct { MinVersion int32 `json:"min_version"` MaxVersion int32 `json:"max_version"` } // PlayerItemList manages a player's inventory type PlayerItemList struct { maxSavedIndex int32 `json:"max_saved_index"` indexedItems map[int32]*Item `json:"indexed_items"` items map[int32]map[int8]map[int16]*Item `json:"items"` overflowItems []*Item `json:"overflow_items"` packetCount int16 `json:"packet_count"` xorPacket []byte `json:"-"` // Exclude from JSON origPacket []byte `json:"-"` // Exclude from JSON mutex sync.RWMutex } // EquipmentItemList manages equipped items for a character type EquipmentItemList struct { items [NumSlots]*Item `json:"items"` appearanceType int8 `json:"appearance_type"` // 0 for normal equip, 1 for appearance xorPacket []byte `json:"-"` // Exclude from JSON origPacket []byte `json:"-"` // Exclude from JSON mutex sync.RWMutex } // ItemManagerStats represents statistics about item management type ItemManagerStats struct { TotalItems int32 `json:"total_items"` ItemsByType map[int8]int32 `json:"items_by_type"` ItemsByTier map[int8]int32 `json:"items_by_tier"` PlayersWithItems int32 `json:"players_with_items"` TotalItemInstances int64 `json:"total_item_instances"` AverageItemsPerPlayer float32 `json:"average_items_per_player"` LastUpdate time.Time `json:"last_update"` } // ItemSearchCriteria represents search criteria for items type ItemSearchCriteria struct { Name string `json:"name"` ItemType int64 `json:"item_type"` LocationType int64 `json:"location_type"` BrokerType int64 `json:"broker_type"` MinPrice int64 `json:"min_price"` MaxPrice int64 `json:"max_price"` MinSkill int8 `json:"min_skill"` MaxSkill int8 `json:"max_skill"` Seller string `json:"seller"` Adornment string `json:"adornment"` MinTier int8 `json:"min_tier"` MaxTier int8 `json:"max_tier"` MinLevel int16 `json:"min_level"` MaxLevel int16 `json:"max_level"` ItemClass int8 `json:"item_class"` AdditionalCriteria map[string]string `json:"additional_criteria"` } // ItemValidationResult represents the result of item validation type ItemValidationResult struct { Valid bool `json:"valid"` Errors []string `json:"errors,omitempty"` } // ItemError represents an item-specific error type ItemError struct { message string } func (e *ItemError) Error() string { return e.message } // NewItemError creates a new item error func NewItemError(message string) *ItemError { return &ItemError{message: message} } // IsItemError checks if an error is an ItemError func IsItemError(err error) bool { _, ok := err.(*ItemError) return ok } // Common item errors var ( ErrItemNotFound = NewItemError("item not found") ErrInvalidItem = NewItemError("invalid item") ErrItemLocked = NewItemError("item is locked") ErrInsufficientSpace = NewItemError("insufficient inventory space") ErrCannotEquip = NewItemError("cannot equip item") ErrCannotTrade = NewItemError("cannot trade item") ErrItemExpired = NewItemError("item has expired") )