858 lines
25 KiB
Go
858 lines
25 KiB
Go
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
|