573 lines
21 KiB
Go
573 lines
21 KiB
Go
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")
|
|
)
|