Files
bl/logic/service/fight/info/BattleSkillEntity.go

263 lines
6.2 KiB
Go
Raw Normal View History

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"` // 状态技能
feat(player): 新增玩家累计经验查询接口 新增 PlayerExp 控制器方法,用于返回玩家的累计经验值。同时调整了经验池字段类型为 uint32 并修复相关使用逻辑。 feat(pet): 实现宠物经验增加与升级逻辑 在 Player 结构体中新增 AddPetExp 方法,支持宠物经验增长、自动升级及进化判断。升级后会重新计算面板属性并推送更新包。 feat(fight): 重构战斗伤害计算与效果系统 引入 DamageZone 和 EnumDamageType 类型,统一红伤处理流程;移除旧有的 Pet/Skill/Prop 属性获取临时修改机制,改为直接访问真实属性。更新多个技能效果实现以适配新结构。 refactor(effect): 优化技能效果初始化和生命周期方法 统一技能效果初始化方式,明确各阶段回调函数职责,如 PreActionStart、PreAttacked 等。删除已废弃的属性修改钩子函数,并更新状态类效果实现。 refactor(input): 移除 deepcopy 依赖并替换为 go-deepcopy 将原先使用的 mohae/deepcopy 替换为 barkimedes/go-deepcopy,用于战斗节点中的 effect 拷贝逻辑,提升性能和安全性。 refactor(model): 调整玩家信息字段类型 将 PlayerInfo 中的 GoldBean 字段由 int32 改为 uint32,ExpPool 字段由 int64 改为 uint32,确保数据类型一致性与合理性。 feat(nono): 增加 Nono 跟随/收回协议结构定义 新增 NonoFollowOrHomeInInfo 和 NonoFollowOutInfo 结构体,用于处理 Nono 宠物的跟随与收回操作指令。 chore(deps): 添加 go-deepcopy 依赖 在 go.mod 中引入 github.com/barkimedes/go-deepcopy 依赖库,用于替代原有的 deepcopy 工具。
2025-09-26 13:33:55 +08:00
//ALL EnumCategory //任何类型
}]()
type EnumDamageType int
var DamageType = enum.New[struct {
2025-11-11 05:54:24 +00:00
Red EnumDamageType `enum:"0"`
feat(player): 新增玩家累计经验查询接口 新增 PlayerExp 控制器方法,用于返回玩家的累计经验值。同时调整了经验池字段类型为 uint32 并修复相关使用逻辑。 feat(pet): 实现宠物经验增加与升级逻辑 在 Player 结构体中新增 AddPetExp 方法,支持宠物经验增长、自动升级及进化判断。升级后会重新计算面板属性并推送更新包。 feat(fight): 重构战斗伤害计算与效果系统 引入 DamageZone 和 EnumDamageType 类型,统一红伤处理流程;移除旧有的 Pet/Skill/Prop 属性获取临时修改机制,改为直接访问真实属性。更新多个技能效果实现以适配新结构。 refactor(effect): 优化技能效果初始化和生命周期方法 统一技能效果初始化方式,明确各阶段回调函数职责,如 PreActionStart、PreAttacked 等。删除已废弃的属性修改钩子函数,并更新状态类效果实现。 refactor(input): 移除 deepcopy 依赖并替换为 go-deepcopy 将原先使用的 mohae/deepcopy 替换为 barkimedes/go-deepcopy,用于战斗节点中的 effect 拷贝逻辑,提升性能和安全性。 refactor(model): 调整玩家信息字段类型 将 PlayerInfo 中的 GoldBean 字段由 int32 改为 uint32,ExpPool 字段由 int64 改为 uint32,确保数据类型一致性与合理性。 feat(nono): 增加 Nono 跟随/收回协议结构定义 新增 NonoFollowOrHomeInInfo 和 NonoFollowOutInfo 结构体,用于处理 Nono 宠物的跟随与收回操作指令。 chore(deps): 添加 go-deepcopy 依赖 在 go.mod 中引入 github.com/barkimedes/go-deepcopy 依赖库,用于替代原有的 deepcopy 工具。
2025-09-26 13:33:55 +08:00
Fixed EnumDamageType // 固定伤害
Percent EnumDamageType // 百分比伤害
True EnumDamageType // 真伤
}]()
feat(player): 新增玩家累计经验查询接口 新增 PlayerExp 控制器方法,用于返回玩家的累计经验值。同时调整了经验池字段类型为 uint32 并修复相关使用逻辑。 feat(pet): 实现宠物经验增加与升级逻辑 在 Player 结构体中新增 AddPetExp 方法,支持宠物经验增长、自动升级及进化判断。升级后会重新计算面板属性并推送更新包。 feat(fight): 重构战斗伤害计算与效果系统 引入 DamageZone 和 EnumDamageType 类型,统一红伤处理流程;移除旧有的 Pet/Skill/Prop 属性获取临时修改机制,改为直接访问真实属性。更新多个技能效果实现以适配新结构。 refactor(effect): 优化技能效果初始化和生命周期方法 统一技能效果初始化方式,明确各阶段回调函数职责,如 PreActionStart、PreAttacked 等。删除已废弃的属性修改钩子函数,并更新状态类效果实现。 refactor(input): 移除 deepcopy 依赖并替换为 go-deepcopy 将原先使用的 mohae/deepcopy 替换为 barkimedes/go-deepcopy,用于战斗节点中的 effect 拷贝逻辑,提升性能和安全性。 refactor(model): 调整玩家信息字段类型 将 PlayerInfo 中的 GoldBean 字段由 int32 改为 uint32,ExpPool 字段由 int64 改为 uint32,确保数据类型一致性与合理性。 feat(nono): 增加 Nono 跟随/收回协议结构定义 新增 NonoFollowOrHomeInInfo 和 NonoFollowOutInfo 结构体,用于处理 Nono 宠物的跟随与收回操作指令。 chore(deps): 添加 go-deepcopy 依赖 在 go.mod 中引入 github.com/barkimedes/go-deepcopy 依赖库,用于替代原有的 deepcopy 工具。
2025-09-26 13:33:55 +08:00
type DamageZone struct {
Type EnumDamageType
Damage alpacadecimal.Decimal
}
func (d *DamageZone) Mul(n int) {
d.Damage = d.Damage.Mul(alpacadecimal.NewFromInt(int64(n)))
feat(player): 新增玩家累计经验查询接口 新增 PlayerExp 控制器方法,用于返回玩家的累计经验值。同时调整了经验池字段类型为 uint32 并修复相关使用逻辑。 feat(pet): 实现宠物经验增加与升级逻辑 在 Player 结构体中新增 AddPetExp 方法,支持宠物经验增长、自动升级及进化判断。升级后会重新计算面板属性并推送更新包。 feat(fight): 重构战斗伤害计算与效果系统 引入 DamageZone 和 EnumDamageType 类型,统一红伤处理流程;移除旧有的 Pet/Skill/Prop 属性获取临时修改机制,改为直接访问真实属性。更新多个技能效果实现以适配新结构。 refactor(effect): 优化技能效果初始化和生命周期方法 统一技能效果初始化方式,明确各阶段回调函数职责,如 PreActionStart、PreAttacked 等。删除已废弃的属性修改钩子函数,并更新状态类效果实现。 refactor(input): 移除 deepcopy 依赖并替换为 go-deepcopy 将原先使用的 mohae/deepcopy 替换为 barkimedes/go-deepcopy,用于战斗节点中的 effect 拷贝逻辑,提升性能和安全性。 refactor(model): 调整玩家信息字段类型 将 PlayerInfo 中的 GoldBean 字段由 int32 改为 uint32,ExpPool 字段由 int64 改为 uint32,确保数据类型一致性与合理性。 feat(nono): 增加 Nono 跟随/收回协议结构定义 新增 NonoFollowOrHomeInInfo 和 NonoFollowOutInfo 结构体,用于处理 Nono 宠物的跟随与收回操作指令。 chore(deps): 添加 go-deepcopy 依赖 在 go.mod 中引入 github.com/barkimedes/go-deepcopy 依赖库,用于替代原有的 deepcopy 工具。
2025-09-26 13:33:55 +08:00
}
// SkillEntity 战斗技能实体
// 实现了战斗中技能的所有属性和行为包括PP管理、技能使用、属性获取等
// 战斗中可以修改技能实体值,比如是否暴击,是否必中等
type SkillEntity struct {
xmlres.Move
Info *model.SkillInfo
2025-09-29 02:40:35 +08:00
// 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 {
2025-09-07 05:58:47 +08:00
var ret SkillEntity
2025-09-07 05:58:47 +08:00
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)
2025-09-07 05:58:47 +08:00
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
// }
2025-09-07 05:58:47 +08:00
// 计算是否命中
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
2025-09-07 05:58:47 +08:00
}
return s.AttackTime
2025-09-07 05:58:47 +08:00
}
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)
2025-09-07 05:58:47 +08:00
}
// 收集宠物的所有属性主属性必存在次属性可能为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 // 一旦匹配,直接返回,避免多余循环
}
}
2025-09-07 05:58:47 +08:00
}
2025-09-07 05:58:47 +08:00
return sameTypeBonus
}
func (s *SkillEntity) Criticalrandom() alpacadecimal.Decimal {
2025-09-07 05:58:47 +08:00
randomnum := s.Rand.Int31n(39) + 217
// 10. 随机倍率随机值除以255
randomFactor := alpacadecimal.NewFromInt(int64(randomnum)).Div(alpacadecimal.NewFromInt(255))
2025-09-07 05:58:47 +08:00
return randomFactor
2025-09-07 05:58:47 +08:00
}
// 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
)
}