package info import ( element "blazing/common/data/Element" "blazing/common/data/xmlres" "blazing/modules/blazing/model" "math/rand" "context" "fmt" "strconv" "github.com/gogf/gf/v2/os/glog" "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"` // 状态技能 Fixed EnumCategory // 固定伤害 Percent EnumCategory // 百分比伤害 True EnumCategory // 真伤 ALL EnumCategory //任何类型 }]() // 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 } // CreateSkill 创建战斗技能实例(可指定是否无限PP) func CreateSkill(skill *model.SkillInfo, rand *rand.Rand, pet *BattlePetEntity) *SkillEntity { //如果PP是-1 ,那就是无限PP // ID小于10001的视为无效技能 if skill.ID < 10001 { return nil } var ret SkillEntity ret.Rand = rand ret.Pet = pet // 从资源仓库获取技能数据 move, ok := xmlres.SkillMap[int(skill.ID)] if !ok { glog.Error(context.Background(), "技能ID无效", "id", skill.ID) } ret.Move = move // // 解析副作用参数 // sideEffectArgs := parseSideEffectArgs(move.SideEffectArg) // tt := strings.Split(move.SideEffect, " ") // rf, err := strSliceToIntSlice(tt) // if err == nil { // ret.SideEffects = rf // } ret.Info = skill // ret.SideEffectArgs = sideEffectArgs 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) Category() EnumCategory { return EnumCategory(s.Move.Category) } // 获取技能属性 func (s *SkillEntity) Type() *element.ElementCombination { ret, _ := element.NewElementCombination(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 // } type EnumsZoneType int var DamageZone = enum.New[struct { add EnumsZoneType // 加区 nul EnumsZoneType // 乘区 }]() var DamageC = enum.New[struct { boost EnumsZoneType //增伤区 reduction EnumsZoneType // 减伤区 }]() // 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) { s.AttackTime = 0 //先重置上一次的 if s.MustHit != 0 { s.AttackTime = 2 } if int64(s.GetAccuracy(level)) > s.Rand.Int63n(100) { s.AttackTime = 1 } } func (s *SkillEntity) CriticalsameTypeBonus() decimal.Decimal { // 6. 同系加成(属性相同则乘以同系加成倍率,否则1) sameTypeBonus := decimal.NewFromFloat(1.0) if s.Type() == s.Pet.Type() { //使用本系 sameTypeBonus = decimal.NewFromFloat(1.5) } stype := s.Type() ptype := s.Pet.Type() if stype.Secondary == nil && ptype.Secondary != nil && (stype.Primary == ptype.Primary || stype.Primary == *ptype.Secondary) { //判断技能属性是否是精灵双属性之一 sameTypeBonus = decimal.NewFromFloat(1.5) } return sameTypeBonus } func (s *SkillEntity) Criticalrandom() decimal.Decimal { randomnum := s.Rand.Int31n(39) + 217 // 10. 随机倍率,随机值除以255 randomFactor := decimal.NewFromInt(int64(randomnum)).Div(decimal.NewFromInt(255)) return randomFactor } // Accuracy 优化版命中率计算(用绝对值和正负判断处理等级) func (a *SkillEntity) GetAccuracy(level int) uint32 { // 基础参数校验 if a.Accuracy == 0 { return 0 } if a.Accuracy >= 100 { return 100 } if level > 6 || 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 ) }