156 lines
4.1 KiB
Go
156 lines
4.1 KiB
Go
package skills
|
|
|
|
import "eq2emu/internal/common"
|
|
|
|
// SkillBonusValue represents a single skill bonus value
|
|
type SkillBonusValue struct {
|
|
SkillID int32 // Skill being modified
|
|
Value float32 // Bonus value
|
|
}
|
|
|
|
// SkillBonus represents skill bonuses from a spell
|
|
type SkillBonus struct {
|
|
SpellID int32 // Spell providing the bonus
|
|
Skills map[int32]*SkillBonusValue // Map of skill ID to bonus value
|
|
}
|
|
|
|
// Skill represents a character skill
|
|
type Skill struct {
|
|
SkillID int32 // Unique skill identifier
|
|
CurrentVal int16 // Current skill value
|
|
PreviousVal int16 // Previous skill value (for deltas)
|
|
MaxVal int16 // Maximum skill value
|
|
SkillType int32 // Skill category type
|
|
Display int8 // Display setting
|
|
ShortName common.EQ2String16 // Short skill name
|
|
Name common.EQ2String16 // Full skill name
|
|
Description common.EQ2String16 // Skill description
|
|
SaveNeeded bool // Whether skill needs database save
|
|
ActiveSkill bool // Whether skill is active/usable
|
|
}
|
|
|
|
// NewSkill creates a new skill with default values
|
|
func NewSkill() *Skill {
|
|
return &Skill{
|
|
SkillID: 0,
|
|
CurrentVal: 0,
|
|
PreviousVal: 0,
|
|
MaxVal: 0,
|
|
SkillType: 0,
|
|
Display: 0,
|
|
SaveNeeded: false,
|
|
ActiveSkill: true,
|
|
}
|
|
}
|
|
|
|
// NewSkillFromSkill creates a copy of an existing skill
|
|
func NewSkillFromSkill(skill *Skill) *Skill {
|
|
if skill == nil {
|
|
return NewSkill()
|
|
}
|
|
|
|
return &Skill{
|
|
SkillID: skill.SkillID,
|
|
CurrentVal: skill.CurrentVal,
|
|
PreviousVal: skill.CurrentVal, // Copy current as previous
|
|
MaxVal: skill.MaxVal,
|
|
SkillType: skill.SkillType,
|
|
Display: skill.Display,
|
|
ShortName: skill.ShortName,
|
|
Name: skill.Name,
|
|
Description: skill.Description,
|
|
SaveNeeded: false,
|
|
ActiveSkill: true,
|
|
}
|
|
}
|
|
|
|
// CheckDisarmSkill checks disarm skill against a chest
|
|
// Returns 1 for success, 0 for fail (no trigger), -1 for fail with trigger
|
|
func (s *Skill) CheckDisarmSkill(targetLevel int16, chestDifficulty int8) int {
|
|
if chestDifficulty < 2 {
|
|
return DisarmSuccess // No triggers on easy chests
|
|
}
|
|
|
|
if targetLevel < 1 {
|
|
targetLevel = 1
|
|
}
|
|
|
|
chestDiffResult := int32(targetLevel) * int32(chestDifficulty)
|
|
baseDifficulty := float32(15.0)
|
|
failThreshold := float32(10.0)
|
|
|
|
// Calculate success chance
|
|
chance := (100.0 - baseDifficulty) * (float32(s.CurrentVal) / float32(chestDiffResult))
|
|
|
|
if chance > (100.0 - baseDifficulty) {
|
|
chance = 100.0 - baseDifficulty
|
|
}
|
|
|
|
// Roll d100
|
|
roll := makeRandomFloat(0, 100)
|
|
|
|
if roll <= chance {
|
|
return DisarmSuccess
|
|
} else if roll > (chance + failThreshold) {
|
|
return DisarmTrigger
|
|
}
|
|
|
|
return DisarmFail
|
|
}
|
|
|
|
// GetCurrentValue returns the current skill value
|
|
func (s *Skill) GetCurrentValue() int32 {
|
|
return int32(s.CurrentVal)
|
|
}
|
|
|
|
// GetMaxValue returns the maximum skill value
|
|
func (s *Skill) GetMaxValue() int32 {
|
|
return int32(s.MaxVal)
|
|
}
|
|
|
|
// GetName returns the skill name
|
|
func (s *Skill) GetName() string {
|
|
return s.Name.Data
|
|
}
|
|
|
|
// GetShortName returns the skill short name
|
|
func (s *Skill) GetShortName() string {
|
|
return s.ShortName.Data
|
|
}
|
|
|
|
// GetDescription returns the skill description
|
|
func (s *Skill) GetDescription() string {
|
|
return s.Description.Data
|
|
}
|
|
|
|
// GetSkillType returns the skill type
|
|
func (s *Skill) GetSkillType() int32 {
|
|
return s.SkillType
|
|
}
|
|
|
|
// IsActive returns whether the skill is active
|
|
func (s *Skill) IsActive() bool {
|
|
return s.ActiveSkill
|
|
}
|
|
|
|
// NeedsSave returns whether the skill needs to be saved
|
|
func (s *Skill) NeedsSave() bool {
|
|
return s.SaveNeeded
|
|
}
|
|
|
|
// SetSaveNeeded marks the skill as needing to be saved
|
|
func (s *Skill) SetSaveNeeded(needed bool) {
|
|
s.SaveNeeded = needed
|
|
}
|
|
|
|
// SetActive sets whether the skill is active
|
|
func (s *Skill) SetActive(active bool) {
|
|
s.ActiveSkill = active
|
|
}
|
|
|
|
// makeRandomFloat generates a random float between min and max
|
|
// TODO: Replace with proper random number generation when integrated
|
|
func makeRandomFloat(min, max float32) float32 {
|
|
// Placeholder implementation
|
|
return min + ((max - min) / 2.0)
|
|
} |