package player import ( "math" ) // GetXPVitality returns the player's adventure XP vitality func (p *Player) GetXPVitality() float32 { return p.GetInfoStruct().GetXPVitality() } // GetTSXPVitality returns the player's tradeskill XP vitality func (p *Player) GetTSXPVitality() float32 { return p.GetInfoStruct().GetTSXPVitality() } // AdventureXPEnabled returns whether adventure XP is enabled func (p *Player) AdventureXPEnabled() bool { return p.GetInfoStruct().GetXPDebt() < 95.0 && p.GetCharacterFlag(CF_COMBAT_EXPERIENCE_ENABLED) } // TradeskillXPEnabled returns whether tradeskill XP is enabled func (p *Player) TradeskillXPEnabled() bool { return p.GetInfoStruct().GetTSXPDebt() < 95.0 && p.GetCharacterFlag(CF_QUEST_EXPERIENCE_ENABLED) } // SetNeededXP sets the needed XP to a specific value func (p *Player) SetNeededXP(val int32) { p.GetInfoStruct().SetXPNeeded(val) } // SetNeededXP sets the needed XP based on current level func (p *Player) SetNeededXPByLevel() { p.GetInfoStruct().SetXPNeeded(GetNeededXPByLevel(p.GetLevel())) } // SetXP sets the current XP func (p *Player) SetXP(val int32) { p.GetInfoStruct().SetXP(val) } // SetNeededTSXP sets the needed tradeskill XP to a specific value func (p *Player) SetNeededTSXP(val int32) { p.GetInfoStruct().SetTSXPNeeded(val) } // SetNeededTSXPByLevel sets the needed tradeskill XP based on current level func (p *Player) SetNeededTSXPByLevel() { p.GetInfoStruct().SetTSXPNeeded(GetNeededXPByLevel(p.GetTSLevel())) } // SetTSXP sets the current tradeskill XP func (p *Player) SetTSXP(val int32) { p.GetInfoStruct().SetTSXP(val) } // GetNeededXP returns the XP needed for next level func (p *Player) GetNeededXP() int32 { return p.GetInfoStruct().GetXPNeeded() } // GetXPDebt returns the current XP debt percentage func (p *Player) GetXPDebt() float32 { return p.GetInfoStruct().GetXPDebt() } // GetXP returns the current XP func (p *Player) GetXP() int32 { return p.GetInfoStruct().GetXP() } // GetNeededTSXP returns the tradeskill XP needed for next level func (p *Player) GetNeededTSXP() int32 { return p.GetInfoStruct().GetTSXPNeeded() } // GetTSXP returns the current tradeskill XP func (p *Player) GetTSXP() int32 { return p.GetInfoStruct().GetTSXP() } // AddXP adds adventure XP to the player func (p *Player) AddXP(xpAmount int32) bool { if xpAmount <= 0 { return false } info := p.GetInfoStruct() currentXP := info.GetXP() neededXP := info.GetXPNeeded() totalXP := currentXP + xpAmount // Check if we've reached next level if totalXP >= neededXP { // Level up! if p.GetLevel() < 100 { // Assuming max level is 100 // Calculate overflow XP overflow := totalXP - neededXP // Level up p.SetLevel(p.GetLevel()+1, true) p.SetNeededXPByLevel() // Set XP to overflow amount p.SetXP(overflow) // TODO: Send level up packet/message // TODO: Update stats for new level // TODO: Check for new abilities/spells return true } else { // At max level, just set to max p.SetXP(neededXP - 1) } } else { p.SetXP(totalXP) } // TODO: Send XP update packet p.SetCharSheetChanged(true) return true } // AddTSXP adds tradeskill XP to the player func (p *Player) AddTSXP(xpAmount int32) bool { if xpAmount <= 0 { return false } info := p.GetInfoStruct() currentXP := info.GetTSXP() neededXP := info.GetTSXPNeeded() totalXP := currentXP + xpAmount // Check if we've reached next level if totalXP >= neededXP { // Level up! if p.GetTSLevel() < 100 { // Assuming max TS level is 100 // Calculate overflow XP overflow := totalXP - neededXP // Level up p.SetTSLevel(p.GetTSLevel()+1) p.SetNeededTSXPByLevel() // Set XP to overflow amount p.SetTSXP(overflow) // TODO: Send level up packet/message // TODO: Update stats for new level // TODO: Check for new recipes return true } else { // At max level, just set to max p.SetTSXP(neededXP - 1) } } else { p.SetTSXP(totalXP) } // TODO: Send XP update packet p.SetCharSheetChanged(true) return true } // DoubleXPEnabled returns whether double XP is enabled func (p *Player) DoubleXPEnabled() bool { // TODO: Check for double XP events, potions, etc. return false } // CalculateXP calculates the XP reward from a victim func (p *Player) CalculateXP(victim *entity.Spawn) float32 { if victim == nil { return 0 } // TODO: Implement full XP calculation formula // This is a simplified version victimLevel := victim.GetLevel() playerLevel := p.GetLevel() levelDiff := int(victimLevel) - int(playerLevel) // Base XP value baseXP := float32(100 + (victimLevel * 10)) // Level difference modifier var levelMod float32 = 1.0 if levelDiff < -5 { // Grey con, minimal XP levelMod = 0.1 } else if levelDiff < -2 { // Green con, reduced XP levelMod = 0.5 } else if levelDiff <= 2 { // Blue/White con, normal XP levelMod = 1.0 } else if levelDiff <= 4 { // Yellow con, bonus XP levelMod = 1.2 } else { // Orange/Red con, high bonus XP levelMod = 1.5 } // Group modifier groupMod := float32(1.0) if p.group != nil { // TODO: Calculate group bonus groupMod = 0.8 // Simplified group penalty } // Vitality modifier vitalityMod := float32(1.0) if p.GetXPVitality() > 0 { vitalityMod = 2.0 // Double XP with vitality } // Double XP modifier doubleXPMod := float32(1.0) if p.DoubleXPEnabled() { doubleXPMod = 2.0 } totalXP := baseXP * levelMod * groupMod * vitalityMod * doubleXPMod return totalXP } // CalculateTSXP calculates tradeskill XP for a given level func (p *Player) CalculateTSXP(level int8) float32 { // TODO: Implement tradeskill XP calculation // This is a simplified version levelDiff := int(level) - int(p.GetTSLevel()) baseXP := float32(50 + (level * 5)) // Level difference modifier var levelMod float32 = 1.0 if levelDiff < -5 { levelMod = 0.1 } else if levelDiff < -2 { levelMod = 0.5 } else if levelDiff <= 2 { levelMod = 1.0 } else if levelDiff <= 4 { levelMod = 1.2 } else { levelMod = 1.5 } // Vitality modifier vitalityMod := float32(1.0) if p.GetTSXPVitality() > 0 { vitalityMod = 2.0 } return baseXP * levelMod * vitalityMod } // CalculateOfflineDebtRecovery calculates debt recovery while offline func (p *Player) CalculateOfflineDebtRecovery(unixTimestamp int32) { currentTime := int32(time.Now().Unix()) timeDiff := currentTime - unixTimestamp if timeDiff <= 0 { return } // Calculate hours offline hoursOffline := float32(timeDiff) / 3600.0 // Debt recovery rate per hour (example: 1% per hour) debtRecoveryRate := float32(1.0) // Calculate adventure debt recovery currentDebt := p.GetInfoStruct().GetXPDebt() if currentDebt > 0 { recovery := debtRecoveryRate * hoursOffline newDebt := currentDebt - recovery if newDebt < 0 { newDebt = 0 } p.GetInfoStruct().SetXPDebt(newDebt) } // Calculate tradeskill debt recovery currentTSDebt := p.GetInfoStruct().GetTSXPDebt() if currentTSDebt > 0 { recovery := debtRecoveryRate * hoursOffline newDebt := currentTSDebt - recovery if newDebt < 0 { newDebt = 0 } p.GetInfoStruct().SetTSXPDebt(newDebt) } } // GetTSLevel returns the player's tradeskill level func (p *Player) GetTSLevel() int8 { return p.GetInfoStruct().GetTSLevel() } // SetTSLevel sets the player's tradeskill level func (p *Player) SetTSLevel(level int8) { p.GetInfoStruct().SetTSLevel(level) p.SetCharSheetChanged(true) }