All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
feat(fight): 添加旧组队协议支持并优化战斗系统 - 实现了旧组队协议相关功能,包括GroupReadyFightFinish、GroupUseSkill、 GroupUseItem、GroupChangePet和GroupEscape方法 - 新增组队战斗相关的入站信息结构体定义 - 实现了组队BOSS战斗逻辑,添加groupBossSlotLimit常量 - 重构宠物技能设置逻辑,调整金币消耗时机 - 优化战斗循环逻辑,添加对无行动槽位的处理 - 改进AI行动逻辑,增加多位置目标选择
250 lines
6.9 KiB
Go
250 lines
6.9 KiB
Go
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)
|
||
// }
|
||
// }
|