package combat import ( "sync" "time" ) // Entity represents any combat-capable entity (Player, NPC, etc.) type Entity interface { GetID() int32 GetLevel() int32 GetHP() int32 GetTotalHP() int32 GetPower() int32 GetTotalPower() int32 GetX() float32 GetY() float32 GetZ() float32 GetHeading() float32 GetStat(statType int32) int32 SetHP(hp int32) SetPower(power int32) IsAlive() bool SetAlive(alive bool) IsPlayer() bool IsNPC() bool IsPet() bool IsBot() bool GetClass() int8 GetRace() int8 GetName() string GetFactionID() int32 GetZoneID() int32 GetAttackable() int8 SetAttackable(attackable int8) IsMezzedOrStunned() bool IsDazed() bool IsDualWield() bool GetPrimaryLastAttackTime() int64 GetSecondaryLastAttackTime() int64 GetRangeLastAttackTime() int64 GetPrimaryAttackDelay() int64 GetSecondaryAttackDelay() int64 GetRangeAttackDelay() int64 SetPrimaryLastAttackTime(time int64) SetSecondaryLastAttackTime(time int64) SetRangeLastAttackTime(time int64) GetLockedNoLoot() int32 IsEngagedBySpawnID(spawnID int32) bool GetInfoStruct() InfoStruct } // InfoStruct interface for entity info type InfoStruct interface { GetLockableEncounter() bool GetAlignment() int32 } // Item represents a weapon or equipment item type Item interface { GetID() int32 GetName() string GetItemType() int8 GetSkillType() int8 GetDamageType() int8 GetMinDamage() int32 GetMaxDamage() int32 GetSpeed() float32 IsRanged() bool IsAmmo() bool IsThrown() bool GetRangeInfo() *RangeInfo } // RangeInfo contains ranged weapon information type RangeInfo struct { RangeLow float32 RangeHigh float32 } // Client represents a player client type Client interface { GetVersion() int32 SimpleMessage(channel int32, message string) Message(channel int32, format string, args ...any) QueuePacket(packet []byte) GetPlayer() Entity } // CombatManager manages all combat operations type CombatManager struct { // Combat sessions activeSessions map[int32]*CombatSession sessionMutex sync.RWMutex // Hate management hateLists map[int32]*HateList hatesMutex sync.RWMutex // Statistics totalAttacks int64 totalDamage int64 totalHealing int64 sessionStats map[int32]*SessionStats statsMutex sync.RWMutex // Configuration config *CombatConfig // Dependencies database Database ruleManager RuleManager spellManager SpellManager itemManager ItemManager zoneManager ZoneManager hateManager *HateManager pvpManager *PVPManager weaponTiming *WeaponTimingManager } // CombatSession represents an active combat session type CombatSession struct { SessionID int32 AttackerID int32 DefenderID int32 StartTime time.Time LastActivity time.Time DamageDealt int64 DamageTaken int64 HealingDealt int64 HealingTaken int64 AttacksLanded int32 AttacksMissed int32 SpellsCast int32 SpellsResisted int32 IsActive bool CombatType int8 mutex sync.RWMutex } // HateList manages hate/threat for an entity type HateList struct { OwnerID int32 HateEntries map[int32]*HateEntry MostHated int32 LastUpdate time.Time mutex sync.RWMutex } // HateEntry represents hate toward a specific target type HateEntry struct { TargetID int32 HateAmount int32 DamageAmount int64 LastHit time.Time IsLocked bool } // AttackResult contains the outcome of an attack type AttackResult struct { HitType int8 DamageDealt int32 DamageType int8 WeaponSkill int8 CriticalHit bool Blocked bool Dodged bool Parried bool Riposte bool Interrupted bool Resisted bool Immune bool TotalDamage int32 Mitigation float32 Weapon Item SkillIncrease bool } // WeaponTiming tracks weapon attack timers type WeaponTiming struct { PrimaryReady bool SecondaryReady bool RangedReady bool LastPrimaryTime int64 LastSecondaryTime int64 LastRangedTime int64 PrimaryDelay int64 SecondaryDelay int64 RangedDelay int64 mutex sync.RWMutex } // DamageInfo contains damage calculation details type DamageInfo struct { BaseDamage int32 ScaledDamage int32 FinalDamage int32 DamageType int8 Mitigation float32 Resistance float32 CriticalMod float32 SpellDamage int32 WeaponDamage int32 EffectiveLevelAttacker int16 EffectiveLevelDefender int16 } // HealInfo contains healing calculation details type HealInfo struct { BaseHealing int32 ScaledHealing int32 FinalHealing int32 CriticalMod float32 SpellHealing int32 WisdomBonus int32 HealingFocus float32 Overheal int32 } // CombatConfig holds combat system configuration type CombatConfig struct { EnablePVP bool PVPType int32 PVPLevelRange int32 MaxMitigationPercent float32 BaseHitChance float32 BaseCriticalChance float32 BaseDodgeChance float32 BaseParryChance float32 BaseBlockChance float32 HateDecayRate float32 CombatTimeout time.Duration EnableArmorMitigation bool EnableSpellResist bool EnableMultiAttack bool EnableFlurry bool EnableBerserk bool EnableRiposte bool } // SessionStats tracks statistics for a combat session type SessionStats struct { TotalDamageDealt int64 TotalDamageTaken int64 TotalHealingDealt int64 TotalHealingTaken int64 AttacksLanded int32 AttacksMissed int32 CriticalHits int32 SpellsCast int32 SpellsResisted int32 Duration time.Duration } // Database interface for combat persistence type Database interface { // Combat logs LogCombatEvent(event *CombatEvent) error GetCombatHistory(entityID int32, limit int32) ([]*CombatEvent, error) // Hate persistence (for NPCs that need to persist hate across server restarts) SaveHateList(ownerID int32, hateList *HateList) error LoadHateList(ownerID int32) (*HateList, error) ClearHateList(ownerID int32) error // Combat statistics SaveCombatStats(stats *SessionStats) error GetPlayerCombatStats(playerID int32) (*SessionStats, error) } // CombatEvent represents a combat event for logging type CombatEvent struct { ID int64 Timestamp time.Time AttackerID int32 DefenderID int32 DamageType int8 HitType int8 DamageAmount int32 WeaponType int8 SpellID int32 ZoneID int32 X float32 Y float32 Z float32 } // RuleManager interface for rule access type RuleManager interface { GetBool(category, rule string) bool GetInt32(category, rule string) int32 GetFloat32(category, rule string) float32 GetZoneBool(zoneID int32, category, rule string) bool GetZoneInt32(zoneID int32, category, rule string) int32 GetZoneFloat32(zoneID int32, category, rule string) float32 } // SpellManager interface for spell integration type SpellManager interface { GetSpell(spellID int32) Spell IsSpellCasting(entityID int32) bool InterruptSpell(entityID int32) bool CheckFizzle(entityID int32, spell Spell) bool } // Spell interface for combat spell integration type Spell interface { GetID() int32 GetName() string GetDamageType() int8 GetBaseDamage() int32 GetCastTime() int32 GetRecoveryTime() int32 GetRange() float32 GetTargetType() int8 IsOffensive() bool IsHealing() bool } // ItemManager interface for weapon/equipment access type ItemManager interface { GetItem(itemID int32) Item GetEquippedItem(entityID int32, slot int8) Item GetWeaponSkill(weapon Item) int8 GetArmorMitigation(entityID int32) float32 } // ZoneManager interface for zone operations type ZoneManager interface { GetEntitiesInRange(x, y, z, range_ float32, zoneID int32) []Entity SendCombatMessage(zoneID int32, message string, x, y, z float32) ProcessEntityCommand(entityID int32, command string, args []string) } // CombatPacketBuilder handles combat packet construction type CombatPacketBuilder interface { BuildAttackPacket(attacker, defender Entity, result *AttackResult) ([]byte, error) BuildDamagePacket(victim Entity, damage *DamageInfo) ([]byte, error) BuildHealPacket(target Entity, healing *HealInfo) ([]byte, error) BuildCombatLogPacket(event *CombatEvent) ([]byte, error) BuildInterruptPacket(target Entity) ([]byte, error) } // NewCombatSession creates a new combat session func NewCombatSession(attackerID, defenderID int32, combatType int8) *CombatSession { return &CombatSession{ SessionID: generateSessionID(), AttackerID: attackerID, DefenderID: defenderID, StartTime: time.Now(), LastActivity: time.Now(), IsActive: true, CombatType: combatType, } } // NewHateList creates a new hate list for an entity func NewHateList(ownerID int32) *HateList { return &HateList{ OwnerID: ownerID, HateEntries: make(map[int32]*HateEntry), MostHated: 0, LastUpdate: time.Now(), } } // NewHateEntry creates a new hate entry func NewHateEntry(targetID int32, initialHate int32) *HateEntry { return &HateEntry{ TargetID: targetID, HateAmount: initialHate, DamageAmount: 0, LastHit: time.Now(), IsLocked: false, } } // generateSessionID generates a unique session ID func generateSessionID() int32 { // Simple implementation - in production would use proper ID generation return int32(time.Now().UnixNano() & 0x7FFFFFFF) }