refactor(fight): 重构战斗系统属性计算逻辑

- 移除 BattlePetEntity 中的冗余方法
- 优化属性计算逻辑,使用统一的 CalculateRealValue 方法
- 调整 SkillEntity 中的攻击命中计算
- 重构 AttackValue 结构,使用数组替代字典
- 优化 Input 结构,添加 GetProp 和 GetStatusEffect 方法
- 更新 PetInfo 结构,使用数组存储属性值
This commit is contained in:
2025-09-17 00:38:15 +08:00
parent a33f108f98
commit 29ac99c860
6 changed files with 130 additions and 113 deletions

View File

@@ -51,12 +51,7 @@ func (f *FightC) Compare(a, b BattleActionI) (BattleActionI, BattleActionI) {
return a, b
}
// 比较宠物相关属性(假设Value(4)返回速度相关值)
p2s := bskill.PetInfo.Info.Speed
//todo 待计算速度
f.Opp.Exec(fn func(input.Effect) bool)
p1s := askill.PetInfo.Info.Speed
p2 = int(bskill.PetInfo.Info.Speed) - int(askill.PetInfo.Speed())
p2 = int(f.Opp.GetProp(4)) - int(f.Our.GetProp(4))
if p2 > 0 {
return b, a
} else if p2 < 0 {

View File

@@ -3,12 +3,10 @@ package info
import (
element "blazing/common/data/Element"
"blazing/common/data/xmlres"
"blazing/logic/service/fight/input"
"blazing/modules/blazing/model"
"fmt"
"math/rand"
"sync"
"unsafe"
"github.com/shopspring/decimal"
"github.com/tnnmigga/enum"
@@ -24,79 +22,42 @@ const Pet_T_Ctx = "PET_T"
// 这里获得攻击,防御,特工,特防,速度
// * battle_lv: atk(0), def(1), sp_atk(2), sp_def(3), spd(4), accuracy(5)
// * battle_attr: 0:hp, 1:atk, 2:def, 3:sp_atk, 4:sp_def, 5:spd
func (a *BattlePetEntity) Value(tt uint32) uint32 {
// func (a *BattlePetEntity) Value(tt uint32) uint32 {
offsetAtk := unsafe.Offsetof(a.Info.Attack) // c字段的偏移量通常为4+16=20
// 2. 将结构体指针转换为原始内存地址uintptr
baseAddr := uintptr(unsafe.Pointer(&offsetAtk))
fmt.Println(*(*uint32)(unsafe.Pointer(&baseAddr)))
addrA := unsafe.Pointer(baseAddr + 4*uintptr(tt)) //根据0是攻击
offsetAtkP := unsafe.Offsetof(a.Prop.Attack) // c字段的偏移量通常为4+16=20
// 2. 将结构体指针转换为原始内存地址uintptr
baseAddrp := uintptr(unsafe.Pointer(&offsetAtkP))
fmt.Println(*(*uint32)(unsafe.Pointer(&offsetAtkP)))
addrB := unsafe.Pointer(baseAddrp + 4*uintptr(tt)) //根据0是攻击
fmt.Println(*(*uint32)(addrA))
ret := uint32(calculateRealValue(int64(*(*uint32)(addrA)), int(*(*byte)(addrB))))
return ret
}
func (a *BattlePetEntity) Speed() uint32 {
return uint32(calculateRealValue(int64(a.Info.Speed), int(a.Prop.Speed)))
// offsetAtk := unsafe.Offsetof(a.Info.Attack) // c字段的偏移量通常为4+16=20
// // 2. 将结构体指针转换为原始内存地址uintptr
// baseAddr := uintptr(unsafe.Pointer(&offsetAtk))
// fmt.Println(*(*uint32)(unsafe.Pointer(&baseAddr)))
// addrA := unsafe.Pointer(baseAddr + 4*uintptr(tt)) //根据0是攻击
// offsetAtkP := unsafe.Offsetof(a.Prop.Attack) // c字段的偏移量通常为4+16=20
// // 2. 将结构体指针转换为原始内存地址uintptr
// baseAddrp := uintptr(unsafe.Pointer(&offsetAtkP))
// fmt.Println(*(*uint32)(unsafe.Pointer(&offsetAtkP)))
// addrB := unsafe.Pointer(baseAddrp + 4*uintptr(tt)) //根据0是攻击
// fmt.Println(*(*uint32)(addrA))
// ret := uint32(calculateRealValue(int64(*(*uint32)(addrA)), int(*(*byte)(addrB))))
// return ret
// }
// func (a *BattlePetEntity) Speed() uint32 {
// return uint32(calculateRealValue(int64(a.Info.Speed), int(a.Prop.Speed)))
}
func (a *BattlePetEntity) Attack() uint32 {
return uint32(calculateRealValue(int64(a.Info.Attack), int(a.Prop.Attack)))
// }
// func (a *BattlePetEntity) Attack() uint32 {
// return uint32(calculateRealValue(int64(a.Info.Attack), int(a.Prop.Attack)))
}
func (a *BattlePetEntity) Defense() uint32 {
return uint32(calculateRealValue(int64(a.Info.Defence), int(a.Prop.Defence)))
// }
// func (a *BattlePetEntity) Defense() uint32 {
// return uint32(calculateRealValue(int64(a.Info.Defence), int(a.Prop.Defence)))
}
func (a *BattlePetEntity) SAttack() uint32 {
return uint32(calculateRealValue(int64(a.Info.SpecialAttack), int(a.Prop.SpecialAttack)))
// }
// func (a *BattlePetEntity) SAttack() uint32 {
// return uint32(calculateRealValue(int64(a.Info.SpecialAttack), int(a.Prop.SpecialAttack)))
}
func (a *BattlePetEntity) SDefense() uint32 {
return uint32(calculateRealValue(int64(a.Info.SpecialDefence), int(a.Prop.SpecialDefence)))
// }
// func (a *BattlePetEntity) SDefense() uint32 {
// return uint32(calculateRealValue(int64(a.Info.SpecialDefence), int(a.Prop.SpecialDefence)))
}
// Accuracy 优化版命中率计算(用绝对值和正负判断处理等级)
func (a *BattlePetEntity) Accuracy(b int64) uint32 {
// 基础参数校验
if b <= 0 {
return 0
}
if b >= 100 {
return 100
}
level := a.Prop.Accuracy
if level > 6 || level == 0 { //强化等级
return uint32(calculateRealValue(int64(b), int(a.Prop.Accuracy)))
}
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(b)). // 将b转为decimal类型
Mul(decimal.NewFromFloat(temp)). // 精确乘以0.85
Round(0). // 四舍五入到整数
IntPart(), // 转为int64
)
}
// }
// 辅助函数:取整数绝对值(处理负等级)
func abs(x int8) int8 {
@@ -109,7 +70,7 @@ func abs(x int8) int8 {
type BattlePetEntity struct {
xmlres.PetInfo
Info *model.PetInfo //通过偏移赋值
*input.Input
//*input.Input
statusConditions sync.Map // key: StatusCondition, value: int (剩余回合)
Skills [4]*SkillEntity // 技能槽最多4个技能
@@ -212,20 +173,20 @@ func CreateBattlePetEntity(info *model.PetInfo, rand *rand.Rand) *BattlePetEntit
// value 基础属性值
// stat 状态变化值(可正可负)
// 返回// 返回计算后的实际属性值确保结果至少为1
func calculateRealValue(value int64, stat int) int64 {
func CalculateRealValue(value uint32, stat int) uint32 {
if stat == 0 {
if value <= 0 {
return 1
}
return value
} else if stat > 0 {
r := int64(float64(value) * (float64(stat+2) / 2.0))
r := uint32(float64(value) * (float64(stat+2) / 2.0))
if r <= 0 {
return 1
}
return r
} else {
r := int64(float64(value) * (2.0 / float64(2-stat)))
r := uint32(float64(value) * (2.0 / float64(2-stat)))
if r <= 0 {
return 1
}

View File

@@ -165,13 +165,13 @@ var DamageC = enum.New[struct {
// }
// 计算是否命中
func (s *SkillEntity) AttackTimeC() {
func (s *SkillEntity) AttackTimeC(level int) {
s.AttackTime = 0 //先重置上一次的
if s.MustHit != 0 {
s.AttackTime = 2
}
if int64(s.Pet.Accuracy(int64(s.Accuracy))) > s.Rand.Int63n(100) {
if int64(s.GetAccuracy(level)) > s.Rand.Int63n(100) {
s.AttackTime = 1
}
@@ -202,6 +202,43 @@ func (s *SkillEntity) criticalrandom() decimal.Decimal {
}
// 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(uint32(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
)
}
// 计算技能威力
func (s *SkillEntity) CalculatePower(deftype *BattlePetEntity) decimal.Decimal {
@@ -227,15 +264,15 @@ func (s *SkillEntity) CalculatePower(deftype *BattlePetEntity) decimal.Decimal {
powerAdd_p = powerAdd_all.Add(s.Pet.GetAddValue(Category.PHYSICAL, DamageC.boost))
powerMul_p = powerMul_all.Add(s.Pet.GetMulValue(Category.PHYSICAL, DamageC.boost))
attackDec = decimal.NewFromInt(int64(s.Pet.Attack()))
defenseDec = decimal.NewFromInt(int64(s.Pet.Defense()))
attackDec = decimal.NewFromInt(int64(s.Pet.Info.Prop[0]))
defenseDec = decimal.NewFromInt(int64(s.Pet.Info.Prop[1]))
//damageReduction = decimal.NewFromFloat(s.DamageZone[DamageMultiplierZoneEnum.ATK_RESISTANCE])
case Category.SPECIAL:
powerAdd_p = powerAdd_all.Add(s.Pet.GetAddValue(Category.SPECIAL, DamageC.boost))
powerMul_p = powerMul_all.Add(s.Pet.GetMulValue(Category.SPECIAL, DamageC.boost))
attackDec = decimal.NewFromInt(int64(s.Pet.SAttack()))
defenseDec = decimal.NewFromInt(int64(s.Pet.SDefense()))
attackDec = decimal.NewFromInt(int64(s.Pet.Info.Prop[2]))
defenseDec = decimal.NewFromInt(int64(s.Pet.Info.Prop[3]))
//damageReduction = decimal.NewFromFloat(s.DamageZone[DamageMultiplierZoneEnum.SP_ATK_RESISTANCE])
default:

View File

@@ -65,8 +65,8 @@ func NewAttackValue(userid uint32) *AttackValue {
0,
[]model.SkillInfo{},
0,
StatusDict{},
PropDict{},
[20]int8{},
[6]int8{},
}
}
@@ -83,9 +83,9 @@ type AttackValue struct {
SkillListLen uint32 `struc:"sizeof=SkillList"`
SkillList []model.SkillInfo `json:"skillList" fieldDescription:"根据精灵的数据插入技能 最多4条 不定长"`
IsCritical uint32 `json:"isCritical" fieldDescription:"是否暴击"`
Status StatusDict //精灵的状态
Status [20]int8 //精灵的状态
//能力提升属性
Prop PropDict
Prop [6]int8
// OwnerMaxShield uint32 `json:"ownerMaxShield" fieldDescription:"我方最大护盾"`
// OwnerCurrentShield uint32 `json:"ownerCurrentShield" fieldDescription:"我方当前护盾"`
}

View File

@@ -20,6 +20,7 @@ type Effect interface {
// OnDamage() bool // 造成伤害时触发
//使用技能 可以取消用技能节点
SetInput(input *Input)
SetArgs(param []int)
IsCrit(opp *Input, skill *info.SkillEntity) //是否暴击
CalculateDamage(opp *Input, skill *info.SkillEntity) //击判定成功且伤害计算前触发
@@ -85,10 +86,36 @@ func InitPropEffect(id int, t Effect) {
NodeM[id+2000000] = t
}
// * battle_lv: atk(0), def(1), sp_atk(2), sp_def(3), spd(4), accuracy(5)
func (c *Input) GetProp(id int) uint32 {
//todo 插入获取前
t, ok := NodeM[id+2000000]
if ok {
if id < 5 {
return info.CalculateRealValue(c.CurrentPet.Info.Prop[id], t.GetMaxStack())
}
}
//todo 插入获取后函数
return 0
}
func InitStatusEffect(id int, t Effect) {
NodeM[id+3000000] = t
}
func (c *Input) GetStatusEffect(id int) (Effect, bool) {
//todo 获取前GetEffect
ret, ok := NodeM[id+3000000]
return ret, ok
//todo 获取后GetEffect
}
func getTypeName(v interface{}) string {
// 获取类型信息
t := reflect.TypeOf(v)
@@ -113,7 +140,7 @@ func (c *Input) AddEffect(e Effect) {
for _, eff := range c.Effects {
if eff.ID() == e.ID() {
//设置输入源
if eff.Stack(0) < eff.MaxStack() { //如果小于最大叠层
if eff.Stack(0) < eff.GetMaxStack() { //如果小于最大叠层
eff.Stack(eff.Stack(0)) //获取到当前叠层数然后叠加
} else {

View File

@@ -116,8 +116,8 @@ func GenPetInfo(id int, dv, natureId, abilityTypeEnum, shinyid, level []int) *Pe
p.Level,
p.EvHp,
)
attack := p.CalculatePetPanelSize(
// * battle_lv: atk(0), def(1), sp_atk(2), sp_def(3), spd(4), accuracy(5)
p.Prop[0] = p.CalculatePetPanelSize(
uint32(petxml.Atk),
p.Dv,
p.Level,
@@ -125,7 +125,7 @@ func GenPetInfo(id int, dv, natureId, abilityTypeEnum, shinyid, level []int) *Pe
naxml.AttackCorrect,
)
defense := p.CalculatePetPanelSize(
p.Prop[1] = p.CalculatePetPanelSize(
uint32(petxml.Def),
p.Dv,
p.Level,
@@ -133,7 +133,7 @@ func GenPetInfo(id int, dv, natureId, abilityTypeEnum, shinyid, level []int) *Pe
naxml.DefenseCorrect,
)
specialAttack := p.CalculatePetPanelSize(
p.Prop[2] = p.CalculatePetPanelSize(
uint32(petxml.SpAtk),
p.Dv,
p.Level,
@@ -141,7 +141,7 @@ func GenPetInfo(id int, dv, natureId, abilityTypeEnum, shinyid, level []int) *Pe
naxml.SaCorrect,
)
specialDefense := p.CalculatePetPanelSize(
p.Prop[3] = p.CalculatePetPanelSize(
uint32(petxml.SpDef),
p.Dv,
p.Level,
@@ -149,7 +149,7 @@ func GenPetInfo(id int, dv, natureId, abilityTypeEnum, shinyid, level []int) *Pe
naxml.SdCorrect,
)
speed := p.CalculatePetPanelSize(
p.Prop[4] = p.CalculatePetPanelSize(
uint32(petxml.Spd),
p.Dv,
p.Level,
@@ -160,11 +160,7 @@ func GenPetInfo(id int, dv, natureId, abilityTypeEnum, shinyid, level []int) *Pe
// 设置计算结果
p.MaxHp = hp
p.Hp = hp
p.Attack = attack
p.Defence = defense
p.SpecialAttack = specialAttack
p.SpecialDefence = specialDefense
p.Speed = speed
return p
}
@@ -213,21 +209,22 @@ type PetInfo struct {
// 最大生命(@UInt long → uint32
MaxHp uint32 `fieldDesc:"最大生命" `
// * battle_lv: atk(0), def(1), sp_atk(2), sp_def(3), spd(4), accuracy(5)
Prop [5]uint32 `fieldDesc:"属性" `
// // 攻击(@UInt long → uint32
// Attack uint32 `fieldDesc:"攻击" `
// 攻击@UInt long → uint32
Attack uint32 `fieldDesc:"攻击" `
// // 防御@UInt long → uint32
// Defence uint32 `fieldDesc:"防御" `
// 防御@UInt long → uint32
Defence uint32 `fieldDesc:"防御" `
// // 特攻@UInt long → uint32
// SpecialAttack uint32 `fieldDesc:"特攻" `
// 特攻@UInt long → uint32
SpecialAttack uint32 `fieldDesc:"特" `
// // 特防@UInt long → uint32
// SpecialDefence uint32 `fieldDesc:"特" `
// 特防@UInt long → uint32
SpecialDefence uint32 `fieldDesc:"特防" `
// 速度(@UInt long → uint32
Speed uint32 `fieldDesc:"速度" `
// // 速度@UInt long → uint32
// Speed uint32 `fieldDesc:"速度" `
// 生命学习力(@UInt long → uint32
EvHp uint32 `fieldDesc:"生命学习力" `