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 (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, StatusBonus: our.GetStatusBonus(), Details: fmt.Sprintf("道具ID=%d,必定成功", ItemID), } } // 锁定模式 if ownerpet == 0 { return false, CaptureDetails{ Success: false, Mode: "锁定模式", BaseRate: 0, ModifiedRate: 0, GuaranteeBonus: 0, StatusBonus: our.GetStatusBonus(), Details: "已拥有数量为0,无法捕捉", } } // 计算基础捕捉率 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, StatusBonus: our.GetStatusBonus(), Details: fmt.Sprintf("a=%d, 分子=%d, 分母=%d", our.calcBaseA(pet, ItemID), numerator, denominator), } } // calcBaseA 按公式计算a值 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) statusBonus := our.GetStatusBonus() return int(hpRatio * float64(catchRate) * itemBonus * statusBonus) } // calcBaseRate 按公式计算基础成功率 func (our *Input) calcBaseRate(pet *info.BattlePetEntity, ItemID uint32) float64 { if getItemBonus(ItemID) >= 255 { return 1.0 } 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) // } // }