package player import ( "eq2emu/internal/entity" ) // InCombat sets the player's combat state func (p *Player) InCombat(val bool, ranged bool) { if val { // Entering combat if ranged { p.SetCharacterFlag(CF_RANGED_AUTO_ATTACK) p.SetRangeAttack(true) } else { p.SetCharacterFlag(CF_AUTO_ATTACK) } // Set combat state prevState := p.GetPlayerEngageCommands() if ranged { p.SetPlayerEngageCommands(prevState | RANGE_COMBAT_STATE) } else { p.SetPlayerEngageCommands(prevState | MELEE_COMBAT_STATE) } } else { // Leaving combat if ranged { p.ResetCharacterFlag(CF_RANGED_AUTO_ATTACK) p.SetRangeAttack(false) prevState := p.GetPlayerEngageCommands() p.SetPlayerEngageCommands(prevState & ^RANGE_COMBAT_STATE) } else { p.ResetCharacterFlag(CF_AUTO_ATTACK) prevState := p.GetPlayerEngageCommands() p.SetPlayerEngageCommands(prevState & ^MELEE_COMBAT_STATE) } // Clear combat target if leaving all combat if p.GetPlayerEngageCommands() == 0 { p.combatTarget = nil } } p.SetCharSheetChanged(true) } // ProcessCombat processes combat actions func (p *Player) ProcessCombat() { // Check if in combat if p.GetPlayerEngageCommands() == 0 { return } // Check if we have a valid target if p.combatTarget == nil || IsDead(p.combatTarget) { p.StopCombat(0) return } // Check distance to target distance := p.GetDistance(p.combatTarget.GetX(), p.combatTarget.GetY(), p.combatTarget.GetZ(), true) // Process based on combat type if p.rangeAttack { // Ranged combat maxRange := p.GetRangeWeaponRange() if distance > maxRange { // Too far for ranged // TODO: Send out of range message return } // TODO: Process ranged auto-attack } else { // Melee combat maxRange := p.GetMeleeWeaponRange() if distance > maxRange { // Too far for melee // TODO: Send out of range message return } // TODO: Process melee auto-attack } } // GetRangeWeaponRange returns the range of the equipped ranged weapon func (p *Player) GetRangeWeaponRange() float32 { // TODO: Get from equipped ranged weapon return 35.0 // Default bow range } // GetMeleeWeaponRange returns the range of melee weapons func (p *Player) GetMeleeWeaponRange() float32 { // TODO: Adjust based on weapon type and mob size return 5.0 // Default melee range } // SetCombatTarget sets the current combat target func (p *Player) SetCombatTarget(target *entity.Entity) { p.combatTarget = target } // GetCombatTarget returns the current combat target func (p *Player) GetCombatTarget() *entity.Entity { return p.combatTarget } // DamageEquippedItems damages equipped items by durability func (p *Player) DamageEquippedItems(amount int8, client *Client) bool { // TODO: Implement item durability damage // This would: // 1. Get all equipped items // 2. Reduce durability by amount // 3. Check if any items broke // 4. Send updates to client return false } // GetTSArrowColor returns the arrow color for tradeskill con func (p *Player) GetTSArrowColor(level int8) int8 { levelDiff := int(level) - int(p.GetTSLevel()) if levelDiff >= 10 { return 4 // Red } else if levelDiff >= 5 { return 3 // Orange } else if levelDiff >= 1 { return 2 // Yellow } else if levelDiff >= -5 { return 1 // White } else if levelDiff >= -9 { return 0 // Blue } else { return 6 // Green } } // CheckLevelStatus checks and updates level-based statuses func (p *Player) CheckLevelStatus(newLevel int16) bool { // TODO: Implement level status checks // This would check things like: // - Mentoring status // - Level-locked abilities // - Zone level requirements // - etc. return true } // CalculatePlayerHPPower calculates HP and Power for the player func (p *Player) CalculatePlayerHPPower(newLevel int16) { if newLevel == 0 { newLevel = int16(p.GetLevel()) } // TODO: Implement proper HP/Power calculation // This is a simplified version // Base HP calculation baseHP := int32(50 + (newLevel * 20)) staminaBonus := int32(p.GetInfoStruct().GetSta() * 10) totalHP := baseHP + staminaBonus // Base Power calculation basePower := int32(50 + (newLevel * 10)) primaryStatBonus := p.GetPrimaryStat() * 10 totalPower := basePower + primaryStatBonus // Set the values p.SetTotalHP(totalHP) p.SetTotalPower(totalPower) // Set current values if needed if p.GetHP() > totalHP { p.SetHP(totalHP) } if p.GetPower() > totalPower { p.SetPower(totalPower) } } // IsAllowedCombatEquip checks if combat equipment changes are allowed func (p *Player) IsAllowedCombatEquip(slot int8, sendMessage bool) bool { // Can't change equipment while: // - Dead // - In combat (for certain slots) // - Casting // - Stunned/Mezzed if p.IsDead() { if sendMessage { // TODO: Send "You cannot change equipment while dead" message } return false } // Check if in combat if p.GetPlayerEngageCommands() != 0 { // Some slots can't be changed in combat // TODO: Define which slots are restricted restrictedSlots := []int8{0, 1, 2} // Example: primary, secondary, ranged for _, restrictedSlot := range restrictedSlots { if slot == restrictedSlot || slot == -1 { // -1 = all slots if sendMessage { // TODO: Send "You cannot change that equipment in combat" message } return false } } } // Check if casting if p.IsCasting() { if sendMessage { // TODO: Send "You cannot change equipment while casting" message } return false } // Check control effects if p.IsStunned() || p.IsMezzed() { if sendMessage { // TODO: Send appropriate message } return false } return true } // IsCasting returns whether the player is currently casting func (p *Player) IsCasting() bool { // TODO: Check actual casting state return false } // DismissAllPets dismisses all of the player's pets func (p *Player) DismissAllPets() { // TODO: Implement pet dismissal // This would: // 1. Get all pets (combat, non-combat, deity, etc.) // 2. Remove them from world // 3. Clear pet references // 4. Send updates to client } // MentorTarget mentors the current target func (p *Player) MentorTarget() { target := p.GetTarget() if target == nil { // TODO: Send "Invalid mentor target" message return } targetPlayer, ok := target.(*Player) if !ok { return } // Check if target is valid for mentoring if targetPlayer.GetLevel() >= p.GetLevel() { // TODO: Send "Target must be lower level" message return } // Set mentor stats p.SetMentorStats(int32(targetPlayer.GetLevel()), targetPlayer.GetCharacterID(), true) } // SetMentorStats sets the player's effective level for mentoring func (p *Player) SetMentorStats(effectiveLevel int32, targetCharID int32, updateStats bool) { if effectiveLevel < 1 || effectiveLevel > int32(p.GetLevel()) { effectiveLevel = int32(p.GetLevel()) } p.GetInfoStruct().SetEffectiveLevel(int16(effectiveLevel)) if updateStats { // TODO: Recalculate all stats for new effective level p.CalculatePlayerHPPower(int16(effectiveLevel)) // TODO: Update other stats (mitigation, avoidance, etc.) } if effectiveLevel < int32(p.GetLevel()) { p.EnableResetMentorship() } p.SetCharSheetChanged(true) }