package entity import ( "sync" "time" ) // RaceAlignment represents character alignment types type RaceAlignment int const ( AlignmentEvil RaceAlignment = 0 AlignmentGood RaceAlignment = 1 ) // InfoStruct contains all character statistics and information // This is a comprehensive structure that manages all entity stats, // equipment bonuses, and various game mechanics data type InfoStruct struct { // Basic character information name string class1 int8 // Primary class class2 int8 // Secondary class class3 int8 // Tertiary class race int8 // Character race gender int8 // Character gender level int16 // Current level maxLevel int16 // Maximum achievable level effectiveLevel int16 // Effective level for calculations tradeskillLevel int16 // Tradeskill level tradeskillMaxLevel int16 // Maximum tradeskill level // Concentration system (for maintaining spells) curConcentration int16 // Current concentration used maxConcentration int16 // Maximum concentration available // Combat statistics curAttack int32 // Current attack rating attackBase int32 // Base attack rating curMitigation int32 // Current mitigation (damage reduction) maxMitigation int32 // Maximum mitigation mitigationBase int32 // Base mitigation mitigationMod float32 // Mitigation modifier // Avoidance statistics avoidanceDisplay int16 // Display value for avoidance curAvoidance float32 // Current avoidance percentage baseAvoidancePct int16 // Base avoidance percentage avoidanceBase int16 // Base avoidance rating maxAvoidance int16 // Maximum avoidance parry float32 // Parry chance parryBase float32 // Base parry deflection int16 // Deflection rating deflectionBase int16 // Base deflection block int16 // Block rating blockBase int16 // Base block // Primary attributes str float32 // Strength sta float32 // Stamina agi float32 // Agility wis float32 // Wisdom intel float32 // Intelligence strBase float32 // Base strength staBase float32 // Base stamina agiBase float32 // Base agility wisBase float32 // Base wisdom intelBase float32 // Base intelligence // Resistances heat int16 // Heat resistance cold int16 // Cold resistance magic int16 // Magic resistance mental int16 // Mental resistance divine int16 // Divine resistance disease int16 // Disease resistance poison int16 // Poison resistance heatBase int16 // Base heat resistance coldBase int16 // Base cold resistance magicBase int16 // Base magic resistance mentalBase int16 // Base mental resistance divineBase int16 // Base divine resistance diseaseBase int16 // Base disease resistance poisonBase int16 // Base poison resistance elementalBase int16 // Base elemental resistance noxiousBase int16 // Base noxious resistance arcaneBase int16 // Base arcane resistance // Currency coinCopper int32 // Copper coins coinSilver int32 // Silver coins coinGold int32 // Gold coins coinPlat int32 // Platinum coins bankCoinCopper int32 // Banked copper bankCoinSilver int32 // Banked silver bankCoinGold int32 // Banked gold bankCoinPlat int32 // Banked platinum statusPoints int32 // Status points // Character details deity string // Deity name weight int32 // Current weight maxWeight int32 // Maximum carrying capacity // Tradeskill classes tradeskillClass1 int8 // Primary tradeskill class tradeskillClass2 int8 // Secondary tradeskill class tradeskillClass3 int8 // Tertiary tradeskill class // Account and character age accountAgeBase int16 // Base account age accountAgeBonus [19]int8 // Account age bonuses // Combat and damage absorb int32 // Damage absorption // Experience points xp int32 // Current experience xpNeeded int32 // Experience needed for next level xpDebt float32 // Experience debt xpYellow int32 // Yellow (bonus) experience xpYellowVitalityBar int32 // Yellow vitality bar xpBlueVitalityBar int32 // Blue vitality bar xpBlue int32 // Blue (rested) experience tsXp int32 // Tradeskill experience tsXpNeeded int32 // Tradeskill experience needed tradeskillExpYellow int32 // Tradeskill yellow experience tradeskillExpBlue int32 // Tradeskill blue experience xpVitality float32 // Experience vitality tradeskillXpVitality float32 // Tradeskill experience vitality // Flags and states flags int32 // General flags flags2 int32 // Additional flags // Specialized mitigation mitigationSkill1 int16 // Mitigation skill 1 mitigationSkill2 int16 // Mitigation skill 2 mitigationSkill3 int16 // Mitigation skill 3 mitigationPve int16 // PvE mitigation mitigationPvp int16 // PvP mitigation // Combat modifiers abilityModifier int16 // Ability modifier criticalMitigation int16 // Critical hit mitigation blockChance int16 // Block chance uncontestedParry int16 // Uncontested parry uncontestedBlock int16 // Uncontested block uncontestedDodge int16 // Uncontested dodge uncontestedRiposte int16 // Uncontested riposte critChance int16 // Critical hit chance critBonus int16 // Critical hit bonus potency int16 // Spell potency hateMod int16 // Hate modifier reuseSpeed int16 // Ability reuse speed castingSpeed int16 // Spell casting speed recoverySpeed int16 // Recovery speed spellReuseSpeed int16 // Spell reuse speed spellMultiAttack int16 // Spell multi-attack // Size and physical attributes sizeMod float32 // Size modifier ignoreSizeModCalc int8 // Ignore size modifier calculations dps int16 // Damage per second dpsMultiplier int16 // DPS multiplier attackSpeed int16 // Attack speed haste int16 // Haste multiAttack int16 // Multi-attack chance flurry int16 // Flurry chance meleeAe int16 // Melee area effect strikethrough int16 // Strikethrough accuracy int16 // Accuracy offensiveSpeed int16 // Offensive speed // Environmental rain int16 // Rain resistance/affinity wind int16 // Wind resistance/affinity alignment int8 // Character alignment // Pet information petId int32 // Pet ID petName string // Pet name petHealthPct float32 // Pet health percentage petPowerPct float32 // Pet power percentage petMovement int8 // Pet movement mode petBehavior int8 // Pet behavior mode // Character abilities vision int8 // Vision type breatheUnderwater int8 // Can breathe underwater biography string // Character biography drunk int8 // Drunk level // Regeneration powerRegen int16 // Power regeneration rate hpRegen int16 // Health regeneration rate powerRegenOverride int16 // Power regen override hpRegenOverride int16 // Health regen override // Movement types waterType int8 // Water movement type flyingType int8 // Flying movement type // Special flags noInterrupt int8 // Cannot be interrupted interactionFlag int8 // Interaction flag tag1 int8 // Tag 1 mood int8 // Mood state // Weapon timing rangeLastAttackTime int32 // Last ranged attack time primaryLastAttackTime int32 // Last primary attack time secondaryLastAttackTime int32 // Last secondary attack time primaryAttackDelay int32 // Primary attack delay secondaryAttackDelay int32 // Secondary attack delay rangedAttackDelay int32 // Ranged attack delay // Weapon information primaryWeaponType int8 // Primary weapon type secondaryWeaponType int8 // Secondary weapon type rangedWeaponType int8 // Ranged weapon type primaryWeaponDmgLow int16 // Primary weapon min damage primaryWeaponDmgHigh int16 // Primary weapon max damage secondaryWeaponDmgLow int16 // Secondary weapon min damage secondaryWeaponDmgHigh int16 // Secondary weapon max damage rangedWeaponDmgLow int16 // Ranged weapon min damage rangedWeaponDmgHigh int16 // Ranged weapon max damage wieldType int8 // Weapon wield type attackType int8 // Attack type primaryWeaponDelay int16 // Primary weapon delay secondaryWeaponDelay int16 // Secondary weapon delay rangedWeaponDelay int16 // Ranged weapon delay // Weapon overrides overridePrimaryWeapon int8 // Override primary weapon overrideSecondaryWeapon int8 // Override secondary weapon overrideRangedWeapon int8 // Override ranged weapon // NPC specific friendlyTargetNpc int8 // Friendly target NPC flag lastClaimTime int32 // Last claim time // Encounter system engagedEncounter int8 // Engaged in encounter lockableEncounter int8 // Encounter can be locked // Player flags firstWorldLogin int8 // First world login flag reloadPlayerSpells int8 // Reload player spells flag // Group settings groupLootMethod int8 // Group loot method groupLootItemsRarity int8 // Group loot rarity threshold groupAutoSplit int8 // Auto-split loot groupDefaultYell int8 // Default yell in group groupAutolock int8 // Auto-lock group groupLockMethod int8 // Group lock method groupSoloAutolock int8 // Solo auto-lock groupAutoLootMethod int8 // Auto-loot method assistAutoAttack int8 // Assist auto-attack // Action state actionState string // Current action state // Spell and ability reductions spellMulticastChance int16 // Spell multicast chance maxSpellReductionOverride int16 // Max spell reduction override maxChaseDistance float32 // Maximum chase distance // Thread safety mutex sync.RWMutex } // NewInfoStruct creates a new InfoStruct with default values // Initializes all fields to appropriate defaults for a new entity func NewInfoStruct() *InfoStruct { return &InfoStruct{ name: "", class1: 0, class2: 0, class3: 0, race: 0, gender: 0, level: 0, maxLevel: 0, effectiveLevel: 0, tradeskillLevel: 0, tradeskillMaxLevel: 0, curConcentration: 0, maxConcentration: 5, // Default max concentration curAttack: 0, attackBase: 0, curMitigation: 0, maxMitigation: 0, mitigationBase: 0, mitigationMod: 0, avoidanceDisplay: 0, curAvoidance: 0.0, baseAvoidancePct: 0, avoidanceBase: 0, maxAvoidance: 0, parry: 0.0, parryBase: 0.0, deflection: 0, deflectionBase: 0, block: 0, blockBase: 0, str: 0.0, sta: 0.0, agi: 0.0, wis: 0.0, intel: 0.0, strBase: 0.0, staBase: 0.0, agiBase: 0.0, wisBase: 0.0, intelBase: 0.0, heat: 0, cold: 0, magic: 0, mental: 0, divine: 0, disease: 0, poison: 0, heatBase: 0, coldBase: 0, magicBase: 0, mentalBase: 0, divineBase: 0, diseaseBase: 0, poisonBase: 0, elementalBase: 0, noxiousBase: 0, arcaneBase: 0, coinCopper: 0, coinSilver: 0, coinGold: 0, coinPlat: 0, bankCoinCopper: 0, bankCoinSilver: 0, bankCoinGold: 0, bankCoinPlat: 0, statusPoints: 0, deity: "", weight: 0, maxWeight: 0, tradeskillClass1: 0, tradeskillClass2: 0, tradeskillClass3: 0, accountAgeBase: 0, absorb: 0, xp: 0, xpNeeded: 0, xpDebt: 0.0, xpYellow: 0, xpYellowVitalityBar: 0, xpBlueVitalityBar: 0, xpBlue: 0, tsXp: 0, tsXpNeeded: 0, tradeskillExpYellow: 0, tradeskillExpBlue: 0, flags: 0, flags2: 0, xpVitality: 0, tradeskillXpVitality: 0, mitigationSkill1: 0, mitigationSkill2: 0, mitigationSkill3: 0, mitigationPve: 0, mitigationPvp: 0, abilityModifier: 0, criticalMitigation: 0, blockChance: 0, uncontestedParry: 0, uncontestedBlock: 0, uncontestedDodge: 0, uncontestedRiposte: 0, critChance: 0, critBonus: 0, potency: 0, hateMod: 0, reuseSpeed: 0, castingSpeed: 0, recoverySpeed: 0, spellReuseSpeed: 0, spellMultiAttack: 0, sizeMod: 0.0, ignoreSizeModCalc: 0, dps: 0, dpsMultiplier: 0, attackSpeed: 0, haste: 0, multiAttack: 0, flurry: 0, meleeAe: 0, strikethrough: 0, accuracy: 0, offensiveSpeed: 0, rain: 0, wind: 0, alignment: 0, petId: 0, petName: "", petHealthPct: 0.0, petPowerPct: 0.0, petMovement: 0, petBehavior: 0, vision: 0, breatheUnderwater: 0, biography: "", drunk: 0, powerRegen: 0, hpRegen: 0, powerRegenOverride: 0, hpRegenOverride: 0, waterType: 0, flyingType: 0, noInterrupt: 0, interactionFlag: 0, tag1: 0, mood: 0, rangeLastAttackTime: 0, primaryLastAttackTime: 0, secondaryLastAttackTime: 0, primaryAttackDelay: 0, secondaryAttackDelay: 0, rangedAttackDelay: 0, primaryWeaponType: 0, secondaryWeaponType: 0, rangedWeaponType: 0, primaryWeaponDmgLow: 0, primaryWeaponDmgHigh: 0, secondaryWeaponDmgLow: 0, secondaryWeaponDmgHigh: 0, rangedWeaponDmgLow: 0, rangedWeaponDmgHigh: 0, wieldType: 0, attackType: 0, primaryWeaponDelay: 0, secondaryWeaponDelay: 0, rangedWeaponDelay: 0, overridePrimaryWeapon: 0, overrideSecondaryWeapon: 0, overrideRangedWeapon: 0, friendlyTargetNpc: 0, lastClaimTime: 0, engagedEncounter: 0, lockableEncounter: 1, firstWorldLogin: 0, reloadPlayerSpells: 0, groupLootMethod: 1, groupLootItemsRarity: 0, groupAutoSplit: 1, groupDefaultYell: 1, groupAutolock: 0, groupLockMethod: 0, groupSoloAutolock: 0, groupAutoLootMethod: 0, assistAutoAttack: 0, actionState: "", spellMulticastChance: 0, maxSpellReductionOverride: 0, maxChaseDistance: 0.0, } } // GetName returns the entity's name func (info *InfoStruct) GetName() string { info.mutex.RLock() defer info.mutex.RUnlock() return info.name } // SetName updates the entity's name func (info *InfoStruct) SetName(name string) { info.mutex.Lock() defer info.mutex.Unlock() info.name = name } // GetLevel returns the entity's level func (info *InfoStruct) GetLevel() int16 { info.mutex.RLock() defer info.mutex.RUnlock() return info.level } // SetLevel updates the entity's level func (info *InfoStruct) SetLevel(level int16) { info.mutex.Lock() defer info.mutex.Unlock() info.level = level } // GetEffectiveLevel returns the entity's effective level for calculations func (info *InfoStruct) GetEffectiveLevel() int16 { info.mutex.RLock() defer info.mutex.RUnlock() return info.effectiveLevel } // SetEffectiveLevel updates the entity's effective level func (info *InfoStruct) SetEffectiveLevel(level int16) { info.mutex.Lock() defer info.mutex.Unlock() info.effectiveLevel = level } // GetClass1 returns the primary class func (info *InfoStruct) GetClass1() int8 { info.mutex.RLock() defer info.mutex.RUnlock() return info.class1 } // SetClass1 updates the primary class func (info *InfoStruct) SetClass1(class int8) { info.mutex.Lock() defer info.mutex.Unlock() info.class1 = class } // GetRace returns the entity's race func (info *InfoStruct) GetRace() int8 { info.mutex.RLock() defer info.mutex.RUnlock() return info.race } // SetRace updates the entity's race func (info *InfoStruct) SetRace(race int8) { info.mutex.Lock() defer info.mutex.Unlock() info.race = race } // GetGender returns the entity's gender func (info *InfoStruct) GetGender() int8 { info.mutex.RLock() defer info.mutex.RUnlock() return info.gender } // SetGender updates the entity's gender func (info *InfoStruct) SetGender(gender int8) { info.mutex.Lock() defer info.mutex.Unlock() info.gender = gender } // GetStr returns the strength stat func (info *InfoStruct) GetStr() float32 { info.mutex.RLock() defer info.mutex.RUnlock() return info.str } // SetStr updates the strength stat func (info *InfoStruct) SetStr(str float32) { info.mutex.Lock() defer info.mutex.Unlock() info.str = str } // GetSta returns the stamina stat func (info *InfoStruct) GetSta() float32 { info.mutex.RLock() defer info.mutex.RUnlock() return info.sta } // SetSta updates the stamina stat func (info *InfoStruct) SetSta(sta float32) { info.mutex.Lock() defer info.mutex.Unlock() info.sta = sta } // GetAgi returns the agility stat func (info *InfoStruct) GetAgi() float32 { info.mutex.RLock() defer info.mutex.RUnlock() return info.agi } // SetAgi updates the agility stat func (info *InfoStruct) SetAgi(agi float32) { info.mutex.Lock() defer info.mutex.Unlock() info.agi = agi } // GetWis returns the wisdom stat func (info *InfoStruct) GetWis() float32 { info.mutex.RLock() defer info.mutex.RUnlock() return info.wis } // SetWis updates the wisdom stat func (info *InfoStruct) SetWis(wis float32) { info.mutex.Lock() defer info.mutex.Unlock() info.wis = wis } // GetIntel returns the intelligence stat func (info *InfoStruct) GetIntel() float32 { info.mutex.RLock() defer info.mutex.RUnlock() return info.intel } // SetIntel updates the intelligence stat func (info *InfoStruct) SetIntel(intel float32) { info.mutex.Lock() defer info.mutex.Unlock() info.intel = intel } // GetMaxConcentration returns the maximum concentration func (info *InfoStruct) GetMaxConcentration() int16 { info.mutex.RLock() defer info.mutex.RUnlock() return info.maxConcentration } // SetMaxConcentration updates the maximum concentration func (info *InfoStruct) SetMaxConcentration(maxConcentration int16) { info.mutex.Lock() defer info.mutex.Unlock() info.maxConcentration = maxConcentration } // GetCurConcentration returns the current concentration used func (info *InfoStruct) GetCurConcentration() int16 { info.mutex.RLock() defer info.mutex.RUnlock() return info.curConcentration } // SetCurConcentration updates the current concentration used func (info *InfoStruct) SetCurConcentration(curConcentration int16) { info.mutex.Lock() defer info.mutex.Unlock() info.curConcentration = curConcentration } // AddConcentration adds to the current concentration used func (info *InfoStruct) AddConcentration(amount int16) bool { info.mutex.Lock() defer info.mutex.Unlock() if info.curConcentration+amount > info.maxConcentration { return false // Not enough concentration available } info.curConcentration += amount return true } // RemoveConcentration removes from the current concentration used func (info *InfoStruct) RemoveConcentration(amount int16) { info.mutex.Lock() defer info.mutex.Unlock() info.curConcentration -= amount if info.curConcentration < 0 { info.curConcentration = 0 } } // GetCoins returns total coin value in copper func (info *InfoStruct) GetCoins() int32 { info.mutex.RLock() defer info.mutex.RUnlock() return info.coinCopper + (info.coinSilver * 100) + (info.coinGold * 10000) + (info.coinPlat * 1000000) } // AddCoins adds coins to the entity (automatically distributes to appropriate denominations) func (info *InfoStruct) AddCoins(copperAmount int32) { info.mutex.Lock() defer info.mutex.Unlock() totalCopper := info.coinCopper + copperAmount // Convert to higher denominations info.coinPlat += totalCopper / 1000000 totalCopper %= 1000000 info.coinGold += totalCopper / 10000 totalCopper %= 10000 info.coinSilver += totalCopper / 100 info.coinCopper = totalCopper % 100 } // RemoveCoins removes coins from the entity func (info *InfoStruct) RemoveCoins(copperAmount int32) bool { info.mutex.Lock() defer info.mutex.Unlock() totalCopper := info.coinCopper + (info.coinSilver * 100) + (info.coinGold * 10000) + (info.coinPlat * 1000000) if totalCopper < copperAmount { return false // Not enough coins } totalCopper -= copperAmount // Redistribute info.coinPlat = totalCopper / 1000000 totalCopper %= 1000000 info.coinGold = totalCopper / 10000 totalCopper %= 10000 info.coinSilver = totalCopper / 100 info.coinCopper = totalCopper % 100 return true } // GetResistance returns the resistance value for a specific type func (info *InfoStruct) GetResistance(resistType string) int16 { info.mutex.RLock() defer info.mutex.RUnlock() switch resistType { case "heat": return info.heat case "cold": return info.cold case "magic": return info.magic case "mental": return info.mental case "divine": return info.divine case "disease": return info.disease case "poison": return info.poison default: return 0 } } // SetResistance updates a resistance value func (info *InfoStruct) SetResistance(resistType string, value int16) { info.mutex.Lock() defer info.mutex.Unlock() switch resistType { case "heat": info.heat = value case "cold": info.cold = value case "magic": info.magic = value case "mental": info.mental = value case "divine": info.divine = value case "disease": info.disease = value case "poison": info.poison = value } } // ResetEffects resets all temporary effects and bonuses // This method should be called when recalculating all bonuses func (info *InfoStruct) ResetEffects() { info.mutex.Lock() defer info.mutex.Unlock() // Reset stats to base values info.str = info.strBase info.sta = info.staBase info.agi = info.agiBase info.wis = info.wisBase info.intel = info.intelBase info.heat = info.heatBase info.cold = info.coldBase info.magic = info.magicBase info.mental = info.mentalBase info.divine = info.divineBase info.disease = info.diseaseBase info.poison = info.poisonBase info.parry = info.parryBase info.deflection = info.deflectionBase info.block = info.blockBase // Reset combat stats to base info.curAttack = info.attackBase info.curMitigation = info.mitigationBase info.curAvoidance = float32(info.baseAvoidancePct) } // CalculatePrimaryStat returns the highest primary stat value func (info *InfoStruct) CalculatePrimaryStat() float32 { info.mutex.RLock() defer info.mutex.RUnlock() primary := info.str if info.sta > primary { primary = info.sta } if info.agi > primary { primary = info.agi } if info.wis > primary { primary = info.wis } if info.intel > primary { primary = info.intel } return primary } // Clone creates a deep copy of the InfoStruct func (info *InfoStruct) Clone() *InfoStruct { info.mutex.RLock() defer info.mutex.RUnlock() clone := &InfoStruct{} *clone = *info // Copy all fields // Reset the mutex in the clone to avoid sharing the same mutex clone.mutex = sync.RWMutex{} // Copy the account age bonus array copy(clone.accountAgeBonus[:], info.accountAgeBonus[:]) return clone } // GetUptime returns how long the entity has been active (for players, time logged in) func (info *InfoStruct) GetUptime() time.Duration { // TODO: Implement when we have login tracking return time.Duration(0) } // TODO: Additional methods to implement: // - Experience calculation methods // - Weapon damage calculation methods // - Spell-related stat methods // - Group and encounter methods // - Equipment bonus application methods