Files
bl/logic/service/fight/input/Capture.go

250 lines
6.9 KiB
Go
Raw Normal View History

package input
import (
"blazing/common/data/xmlres"
"blazing/logic/service/fight/info"
"fmt"
"math"
"github.com/gogf/gf/v2/util/gconv"
)
// 异常状态常量定义(对应数组索引)
const (
StatusParalysis = 0 // 麻痹
StatusPoison = 1 // 中毒
StatusSleep = 8 // 睡眠
StatusFreeze = 3 // 冰冻
// 预留其他状态到19
)
// getItemBonus 获取道具倍率
func getItemBonus(itemID uint32) float64 {
if bonus, ok := xmlres.ItemsMAP[int(itemID)]; ok {
return gconv.Float64(bonus.Bonus)
}
return 1.0
}
// 特殊胶囊必定成功
// CaptureParams 捕捉参数
// type CaptureParams struct {
// PetID int // 精灵ID
// MaxHP int // 目标最大HP
// CurrentHP int // 目标当前HP
// CatchRate int // 目标捕获率分子
// CatchDenom int // 捕获率分母如100、1000
// ItemID int // 使用的道具ID
// Statuses [20]byte // 异常状态数组存在的状态对应位置为1
// OwnedCount int // 已拥有数量(-1=保底0=锁定≥1=衰减)
// -1是保底模式0是锁定模式》0是衰减模式
// Capture 执行捕捉 ,捕捉精灵,使用的道具,模式
2025-11-11 05:54:24 +00:00
func (our *Input) Capture(pet *info.BattlePetEntity, ItemID uint32, ownerpet int) (bool, CaptureDetails) {
captureCtx := our.Player.GetPlayerCaptureContext()
if captureCtx == nil {
captureCtx = info.NewPlayerCaptureContext()
}
if getItemBonus(ItemID) >= 255 {
return true, CaptureDetails{
Success: true,
Mode: "特殊胶囊必定成功",
BaseRate: 100.0,
ModifiedRate: 100.0,
GuaranteeBonus: 0,
2025-11-11 05:54:24 +00:00
StatusBonus: our.GetStatusBonus(),
Details: fmt.Sprintf("道具ID=%d必定成功", ItemID),
}
}
// 锁定模式
if ownerpet == 0 {
return false, CaptureDetails{
Success: false,
Mode: "锁定模式",
BaseRate: 0,
ModifiedRate: 0,
GuaranteeBonus: 0,
2025-11-11 05:54:24 +00:00
StatusBonus: our.GetStatusBonus(),
Details: "已拥有数量为0无法捕捉",
}
}
// 计算基础捕捉率
2025-11-11 05:54:24 +00:00
baseRate := our.calcBaseRate(pet, ItemID)
denominator := captureCtx.Denominator
numerator := int(baseRate * float64(denominator))
// 衰减模式
if ownerpet > 0 {
decay := math.Pow(1-captureCtx.DecayFactor, float64(ownerpet))
baseRate *= decay
if baseRate < 0.01 {
baseRate = 0.01 // 最低1%成功率
}
numerator = int(baseRate * float64(denominator))
}
// 走统一保底判定
success, basePct, bonusPct := captureCtx.Roll(numerator, denominator)
return success, CaptureDetails{
Success: success,
Mode: map[int]string{-1: "保底模式", 0: "锁定模式", 1: "衰减模式"}[ownerpet],
BaseRate: basePct,
ModifiedRate: basePct + bonusPct,
GuaranteeBonus: bonusPct,
2025-11-11 05:54:24 +00:00
StatusBonus: our.GetStatusBonus(),
Details: fmt.Sprintf("a=%d, 分子=%d, 分母=%d", our.calcBaseA(pet, ItemID), numerator, denominator),
}
}
// calcBaseA 按公式计算a值
2025-11-11 05:54:24 +00:00
func (our *Input) calcBaseA(pet *info.BattlePetEntity, ItemID uint32) int {
captureCtx := our.Player.GetPlayerCaptureContext()
if captureCtx == nil {
captureCtx = info.NewPlayerCaptureContext()
}
catchRate := gconv.Int(pet.CatchRate)
catchRate = (catchRate * captureCtx.Denominator) / 1000 // 归一化到1000分母
if catchRate < 3 {
catchRate = 3
}
currentHP := pet.Info.Hp
if currentHP <= 0 {
currentHP = 1
}
hpRatio := (3.0*float64(pet.Info.MaxHp) - 2.0*float64(currentHP)) / (3.0 * float64(pet.Info.MaxHp))
if hpRatio < 0 {
hpRatio = 0
}
itemBonus := getItemBonus(ItemID)
2025-11-11 05:54:24 +00:00
statusBonus := our.GetStatusBonus()
return int(hpRatio * float64(catchRate) * itemBonus * statusBonus)
}
// calcBaseRate 按公式计算基础成功率
2025-11-11 05:54:24 +00:00
func (our *Input) calcBaseRate(pet *info.BattlePetEntity, ItemID uint32) float64 {
if getItemBonus(ItemID) >= 255 {
return 1.0
}
2025-11-11 05:54:24 +00:00
a := our.calcBaseA(pet, ItemID)
if a >= 255 {
return 1.0
}
g := int(1048560.0 / math.Floor(math.Sqrt(math.Floor(math.Sqrt(math.Floor(16711680.0/float64(a)))))))
return math.Pow(float64(g)/65536.0, 4.0)
}
// CaptureDetails 捕捉详情
type CaptureDetails struct {
Success bool
Mode string
BaseRate float64
ModifiedRate float64
GuaranteeBonus float64 // 百分比
StatusBonus float64 // 状态倍率
Details string
}
// func main() {
// ctx := NewPlayerCaptureContext()
// fmt.Println("=== 精灵捕捉系统测试(状态数组版) ===")
// // 测试1不同异常状态组合
// fmt.Println("\n--- 异常状态测试 ---")
// // 无异常状态
// var noStatus [20]byte
// // 中毒状态
// var poisonStatus [20]byte
// poisonStatus[StatusPoison] = 1
// // 睡眠+冰冻状态取最高倍率2.0
// var multipleStatus [20]byte
// multipleStatus[StatusSleep] = 1
// multipleStatus[StatusFreeze] = 1
// statusTests := []struct {
// name string
// status [20]byte
// }{
// {"无异常状态", noStatus},
// {"中毒状态", poisonStatus},
// {"睡眠+冰冻状态", multipleStatus},
// }
// for _, test := range statusTests {
// params := CaptureParams{
// PetID: 1001,
// MaxHP: 100,
// CurrentHP: 10,
// CatchRate: 50,
// CatchDenom: 100,
// ItemID: 300001,
// Statuses: test.status,
// OwnedCount: -1,
// }
// _, details := ctx.Capture(params)
// fmt.Printf("%s: 状态倍率=%.1f | 基础成功率=%.2f%%\n",
// test.name, details.StatusBonus, details.BaseRate)
// }
// // 测试2无敌胶囊
// fmt.Println("\n--- 无敌胶囊测试 ---")
// invincibleParams := CaptureParams{
// PetID: 9999,
// MaxHP: 1000,
// CurrentHP: 1000,
// CatchRate: 1,
// CatchDenom: 1000,
// ItemID: 300006,
// Statuses: noStatus,
// OwnedCount: -1,
// }
// success, details := ctx.Capture(invincibleParams)
// fmt.Printf("捕捉结果: %v | 模式: %s | 成功率: %.2f%%\n",
// success, details.Mode, details.ModifiedRate)
// // 测试3锁定模式
// fmt.Println("\n--- 锁定模式测试 ---")
// lockParams := CaptureParams{
// PetID: 1002,
// MaxHP: 50,
// CurrentHP: 1,
// CatchRate: 100,
// CatchDenom: 100,
// ItemID: 300003,
// Statuses: poisonStatus,
// OwnedCount: 0,
// }
// success, details = ctx.Capture(lockParams)
// fmt.Printf("捕捉结果: %v | 模式: %s | 成功率: %.2f%%\n",
// success, details.Mode, details.ModifiedRate)
// // 测试4衰减模式
// fmt.Println("\n--- 衰减模式测试 ---")
// decayParams := CaptureParams{
// PetID: 1003,
// MaxHP: 100,
// CurrentHP: 10,
// CatchRate: 50,
// CatchDenom: 100,
// ItemID: 300002,
// Statuses: multipleStatus,
// OwnedCount: 1,
// }
// for i := 1; i <= 5; i++ {
// decayParams.OwnedCount = i
// success, details := ctx.Capture(decayParams)
// fmt.Printf("拥有%d只 - 结果: %v | 基础成功率: %.2f%% | 实际成功率: %.2f%%\n",
// i, success, details.BaseRate, details.ModifiedRate)
// }
// }