refactor(fight): 重构战斗系统属性计算逻辑
- 移除 BattlePetEntity 中的冗余方法 - 优化属性计算逻辑,使用统一的 CalculateRealValue 方法 - 调整 SkillEntity 中的攻击命中计算 - 重构 AttackValue 结构,使用数组替代字典 - 优化 Input 结构,添加 GetProp 和 GetStatusEffect 方法 - 更新 PetInfo 结构,使用数组存储属性值
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:"我方当前护盾"`
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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:"生命学习力" `
|
||||
|
||||
Reference in New Issue
Block a user