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

242 lines
6.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 执行捕捉 ,捕捉精灵,使用的道具,模式
func (c *Input) Capture(pet *info.BattlePetEntity, ItemID uint32, ownerpet int) (bool, CaptureDetails) {
if getItemBonus(ItemID) >= 255 {
return true, CaptureDetails{
Success: true,
Mode: "特殊胶囊必定成功",
BaseRate: 100.0,
ModifiedRate: 100.0,
GuaranteeBonus: 0,
StatusBonus: c.GetStatusBonus(),
Details: fmt.Sprintf("道具ID=%d必定成功", ItemID),
}
}
// 锁定模式
if ownerpet == 0 {
return false, CaptureDetails{
Success: false,
Mode: "锁定模式",
BaseRate: 0,
ModifiedRate: 0,
GuaranteeBonus: 0,
StatusBonus: c.GetStatusBonus(),
Details: "已拥有数量为0无法捕捉",
}
}
// 计算基础捕捉率
baseRate := c.calcBaseRate(pet, ItemID)
denominator := c.Player.GetPlayerCaptureContext().Denominator
numerator := int(baseRate * float64(denominator))
// 衰减模式
if ownerpet > 0 {
decay := math.Pow(1-c.Player.GetPlayerCaptureContext().DecayFactor, float64(ownerpet))
baseRate *= decay
if baseRate < 0.01 {
baseRate = 0.01 // 最低1%成功率
}
numerator = int(baseRate * float64(denominator))
}
// 走统一保底判定
success, basePct, bonusPct := c.Player.Roll(numerator, denominator)
return success, CaptureDetails{
Success: success,
Mode: map[int]string{-1: "保底模式", 0: "锁定模式", 1: "衰减模式"}[ownerpet],
BaseRate: basePct,
ModifiedRate: basePct + bonusPct,
GuaranteeBonus: bonusPct,
StatusBonus: c.GetStatusBonus(),
Details: fmt.Sprintf("a=%d, 分子=%d, 分母=%d", c.calcBaseA(pet, ItemID), numerator, denominator),
}
}
// calcBaseA 按公式计算a值
func (c *Input) calcBaseA(pet *info.BattlePetEntity, ItemID uint32) int {
catchRate := gconv.Int(pet.CatchRate)
catchRate = (catchRate * c.Player.GetPlayerCaptureContext().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)
statusBonus := c.GetStatusBonus()
return int(hpRatio * float64(catchRate) * itemBonus * statusBonus)
}
// calcBaseRate 按公式计算基础成功率
func (c *Input) calcBaseRate(pet *info.BattlePetEntity, ItemID uint32) float64 {
if getItemBonus(ItemID) >= 255 {
return 1.0
}
a := c.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)
// }
// }