package info import ( element "blazing/common/data/Element" "blazing/common/data/xmlres" "blazing/modules/blazing/model" "math/rand" "fmt" "strconv" "github.com/alpacahq/alpacadecimal" "github.com/shopspring/decimal" "github.com/tnnmigga/enum" ) const BattleSkillEntityCtx = "skill" // EnumSkillType 技能类型枚举基础类型 type EnumCategory int // SkillType 技能类型枚举实例(使用enum包创建) // 与原Java枚举保持相同的数值映射:PHYSICAL=1, SPECIAL=2, STATUS=4 var Category = enum.New[struct { PHYSICAL EnumCategory `enum:"1"` // 物理攻击 SPECIAL EnumCategory `enum:"2"` // 特殊攻击 STATUS EnumCategory `enum:"4"` // 状态技能 //ALL EnumCategory //任何类型 }]() type EnumDamageType int var DamageType = enum.New[struct { Red EnumDamageType `enum:"0"` Fixed EnumDamageType // 固定伤害 Percent EnumDamageType // 百分比伤害 True EnumDamageType // 真伤 }]() type DamageZone struct { Type EnumDamageType Damage alpacadecimal.Decimal } func (d *DamageZone) Mul(n int) { d.Damage = d.Damage.Mul(alpacadecimal.NewFromInt(int64(n))) } // SkillEntity 战斗技能实体 // 实现了战斗中技能的所有属性和行为,包括PP管理、技能使用、属性获取等 // 战斗中可以修改技能实体值,比如是否暴击,是否必中等 type SkillEntity struct { xmlres.Move Info *model.SkillInfo // DamageValue decimal.Decimal // 伤害值 Rand *rand.Rand Pet *BattlePetEntity //MaxValue func(ahp, bhp uint32) decimal.Decimal Crit uint32 AttackTime uint32 Side bool } // CreateSkill 创建战斗技能实例(可指定是否无限PP) func CreateSkill(skill *model.SkillInfo, rand *rand.Rand, pet *BattlePetEntity) *SkillEntity { var ret SkillEntity ret.Rand = rand ret.Pet = pet // 从资源仓库获取技能数据 move, ok := xmlres.SkillMap[int(skill.ID)] if ok { ret.Move = move } ret.Info = skill return &ret } // 将字符串切片转换为整数切片 func strSliceToIntSlice(strs []string) ([]int, error) { intSlice := make([]int, 0, len(strs)) // 预分配容量,提高性能 for _, s := range strs { // 将字符串转换为整数 num, err := strconv.Atoi(s) if err != nil { // 转换失败时返回错误(包含具体的错误信息和失败的字符串) return nil, fmt.Errorf("无法将字符串 '%s' 转换为整数: %v", s, err) } intSlice = append(intSlice, num) } return intSlice, nil } // CanUse 检查技能是否可以使用(PP是否充足) func (s *SkillEntity) CanUse() bool { return s.Info.PP > 0 } func (s *SkillEntity) SetMiss() bool { if s.AttackTime == 1 { s.SetNoSide() s.AttackTime = 0 return true } return false } // 无效掉附带属性 func (s *SkillEntity) SetNoSide() bool { s.Side = false return true } // 获取技能类型 func (s *SkillEntity) Category() EnumCategory { return EnumCategory(s.Move.Category) } // 获取技能属性 func (s *SkillEntity) GetType() *element.ElementCombination { ret, _ := element.Calculator.GetCombination(s.Move.Type) return ret } // // 技能产生effect // func (u *BattleSkillEntity) NewEffect(ctx context.Context)*node.EffectNode { // ret := node.EffectNode{} // ctx = context.WithValue(ctx, BattleSkillEntityCtx, &ret) //添加用户到上下文 // ret.ctx = ctx // } // 解析副作用参数字符串为整数列表 // 获取技能名称,为空时使用ID func getSkillName(move *SkillEntity) string { if move.Name == "" { return strconv.FormatInt(int64(move.ID), 10) } return move.Name } // 获取副作用列表,处理空值情况 // func getSideEffects(move *BattleSkillEntity) []int { // if move.SideEffect == "" { // return []int{} // } // return move.SideEffects // } // func (s *BattleSkillEntity) Random() *random.RandomXS128 { // battle, _ := s.ctx.Value(BattleContainerCtx).(*Battle1V1) // return battle.Rand // } // func (s *BattleSkillEntity) Pet() (*BattlePetEntity, bool) { // pet, ok := s.ctx.Value(Pet_O_Ctx).(*BattlePetEntity) // return pet, ok // } // 计算是否命中 func (s *SkillEntity) AttackTimeC(level int) uint32 { s.AttackTime = 0 //先重置上一次的 if s.MustHit != 0 { s.AttackTime = 2 s.Side = true return s.AttackTime } a := int64(s.GetAccuracy(level)) r := s.Rand.Int63n(100) if a >= r { s.Side = true s.AttackTime = 1 } return s.AttackTime } func (s *SkillEntity) CriticalsameTypeBonus() alpacadecimal.Decimal { // 同系加成默认倍率为1.0 sameTypeBonus := alpacadecimal.NewFromFloat(1.0) skillType := s.GetType() petType := s.Pet.GetType() // 收集技能的所有属性(主属性必存在,次属性可能为nil) skillAttrs := []element.ElementType{skillType.Primary} if skillType.Secondary != nil { skillAttrs = append(skillAttrs, *skillType.Secondary) } // 收集宠物的所有属性(主属性必存在,次属性可能为nil) petAttrs := []element.ElementType{petType.Primary} if petType.Secondary != nil { petAttrs = append(petAttrs, *petType.Secondary) } // 检查技能属性与宠物属性是否有任一匹配 for _, sa := range skillAttrs { for _, pa := range petAttrs { if sa == pa { // 存在匹配属性,触发1.5倍加成 sameTypeBonus = alpacadecimal.NewFromFloat(1.5) return sameTypeBonus // 一旦匹配,直接返回,避免多余循环 } } } return sameTypeBonus } func (s *SkillEntity) Criticalrandom() alpacadecimal.Decimal { randomnum := s.Rand.Int31n(39) + 217 // 10. 随机倍率,随机值除以255 randomFactor := alpacadecimal.NewFromInt(int64(randomnum)).Div(alpacadecimal.NewFromInt(255)) return randomFactor } // Accuracy 优化版命中率计算(用绝对值和正负判断处理等级) func (a *SkillEntity) GetAccuracy(level int) uint32 { // 基础参数校验 if level >= 0 { //强化等级 return uint32(CalculateRealValue((a.Accuracy), level)) } var temp float64 switch level { case -1: temp = 0.85 case -2: temp = 0.7 case -3: temp = 0.55 case -4: temp = 0.45 case -5: temp = 0.35 case -6: temp = 0.25 } return uint32( decimal.NewFromInt(int64(a.Accuracy)). // 将b转为decimal类型 Mul(decimal.NewFromFloat(temp)). // 精确乘以0.85 //Round(0). // 四舍五入到整数 IntPart(), // 转为int64 ) }