refactor(fight/effect): 重构能力操作类型枚举命名,统一使用大写形式(ADD/SUB/COPY/RESET)并更新相关调用点
This commit is contained in:
42
logic/service/fight/effect/NewSeIdx_1.go
Normal file
42
logic/service/fight/effect/NewSeIdx_1.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package effect
|
||||||
|
|
||||||
|
import (
|
||||||
|
"blazing/logic/service/fight/info"
|
||||||
|
"blazing/logic/service/fight/input"
|
||||||
|
"blazing/logic/service/fight/node"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 基类特性
|
||||||
|
type NewSel0 struct {
|
||||||
|
node.EffectNode
|
||||||
|
Catchtime int //保存精灵的唯一指令,保证在上场时候正确注入
|
||||||
|
Hide bool //是否隐藏 ,所属精灵下场后特性就应该消失
|
||||||
|
//??如果2只精灵一个特性,怎么办,每次切精灵注入特性
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重写回合结束效果,特性都是无线回合类的
|
||||||
|
// 次数类本质上也是这种
|
||||||
|
func (e *NewSel0) TurnEnd(opp *input.Input) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 免疫"能力(battle_lv)下降"
|
||||||
|
type NewSel1 struct {
|
||||||
|
NewSel0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *NewSel0) BeferProp(in *input.Input, prop, level int8, ptype info.EnumAbilityOpType) bool {
|
||||||
|
|
||||||
|
//能力下降类
|
||||||
|
if level > 0 && ptype == info.AbilityOpType.SUB {
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
input.InitEffect(input.EffectType.NewSel, 1, &NewSel0{})
|
||||||
|
|
||||||
|
}
|
||||||
@@ -29,14 +29,14 @@ func init() {
|
|||||||
input.InitEffect(input.EffectType.Skill, 3, &Effect3{
|
input.InitEffect(input.EffectType.Skill, 3, &Effect3{
|
||||||
EffectNode: node.EffectNode{},
|
EffectNode: node.EffectNode{},
|
||||||
Level: -1,
|
Level: -1,
|
||||||
Etype: info.AbilityOpType.AbilityOpReset,
|
Etype: info.AbilityOpType.RESET,
|
||||||
})
|
})
|
||||||
// 消除对手能力提升状态
|
// 消除对手能力提升状态
|
||||||
input.InitEffect(input.EffectType.Skill, 33, &Effect3{
|
input.InitEffect(input.EffectType.Skill, 33, &Effect3{
|
||||||
EffectNode: node.EffectNode{},
|
EffectNode: node.EffectNode{},
|
||||||
Rev: true,
|
Rev: true,
|
||||||
Level: 1,
|
Level: 1,
|
||||||
Etype: info.AbilityOpType.AbilityOpReset,
|
Etype: info.AbilityOpType.RESET,
|
||||||
})
|
})
|
||||||
// 将能力下降状态反馈给对手
|
// 将能力下降状态反馈给对手
|
||||||
input.InitEffect(input.EffectType.Skill, 63, &Effect3{
|
input.InitEffect(input.EffectType.Skill, 63, &Effect3{
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ func (e *EffectStat) OnHit(opp *input.Input, skill *info.SkillEntity) {
|
|||||||
if !t { //没触发
|
if !t { //没触发
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ptype := info.AbilityOpType.AbilityOpIncrease
|
ptype := info.AbilityOpType.ADD
|
||||||
if e.EffectNode.SideEffectArgs[2] < 0 {
|
if e.EffectNode.SideEffectArgs[2] < 0 {
|
||||||
ptype = info.AbilityOpType.AbilityOpDecrease
|
ptype = info.AbilityOpType.SUB
|
||||||
}
|
}
|
||||||
if !e.Etype { //自身
|
if !e.Etype { //自身
|
||||||
e.Input.SetProp(e.Input, int8(e.EffectNode.SideEffectArgs[0]), int8(e.EffectNode.SideEffectArgs[2]), ptype)
|
e.Input.SetProp(e.Input, int8(e.EffectNode.SideEffectArgs[0]), int8(e.EffectNode.SideEffectArgs[2]), ptype)
|
||||||
|
|||||||
@@ -91,10 +91,10 @@ type Playerinvite struct { //挂载到[]Playerinvite上? 被邀请者->邀请
|
|||||||
type EnumAbilityOpType string
|
type EnumAbilityOpType string
|
||||||
|
|
||||||
var AbilityOpType = enum.New[struct {
|
var AbilityOpType = enum.New[struct {
|
||||||
AbilityOpIncrease EnumAbilityOpType `enum:"1"` // 能力增加(强化)
|
ADD EnumAbilityOpType `enum:"1"` // 能力增加(强化)
|
||||||
AbilityOpDecrease EnumAbilityOpType `enum:"2"` // 能力减少(弱化)
|
SUB EnumAbilityOpType `enum:"2"` // 能力减少(弱化)
|
||||||
AbilityOpCopy EnumAbilityOpType `enum:"3"` // 复制强化/弱化
|
COPY EnumAbilityOpType `enum:"3"` // 复制强化/弱化
|
||||||
AbilityOpReset EnumAbilityOpType `enum:"4"` // 能力重置
|
RESET EnumAbilityOpType `enum:"4"` // 能力重置
|
||||||
|
|
||||||
AbilityOpStealStrengthen EnumAbilityOpType `enum:"6"` // 吸取强化
|
AbilityOpStealStrengthen EnumAbilityOpType `enum:"6"` // 吸取强化
|
||||||
AbilityOpReverse EnumAbilityOpType `enum:"7"` // 反转强化/弱化
|
AbilityOpReverse EnumAbilityOpType `enum:"7"` // 反转强化/弱化
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package input
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"blazing/common/data/xmlres"
|
"blazing/common/data/xmlres"
|
||||||
|
"blazing/logic/service/fight/info"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
)
|
)
|
||||||
@@ -23,6 +26,115 @@ func getItemBonus(itemID uint32) float64 {
|
|||||||
return 1.0
|
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 捕捉详情
|
// CaptureDetails 捕捉详情
|
||||||
type CaptureDetails struct {
|
type CaptureDetails struct {
|
||||||
Success bool
|
Success bool
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ type Effect interface {
|
|||||||
PreAttacked(opp *Input, skill *info.SkillEntity) //预处理受击技能
|
PreAttacked(opp *Input, skill *info.SkillEntity) //预处理受击技能
|
||||||
BeforeAttacked(opp *Input, id *info.DamageZone) //受击前触发 这时候就是百分比减伤区间
|
BeforeAttacked(opp *Input, id *info.DamageZone) //受击前触发 这时候就是百分比减伤区间
|
||||||
Attacked(opp *Input, id *info.DamageZone) // 受击触发 这时候就是点数减伤
|
Attacked(opp *Input, id *info.DamageZone) // 受击触发 这时候就是点数减伤
|
||||||
Shield() bool // 护盾值变化时触发
|
|
||||||
|
PostDamage() bool // 伤害结算后触发(血量扣除后),比如触发回神,反弹也在这里实现
|
||||||
|
Shield() bool // 护盾值变化时触发
|
||||||
|
|
||||||
OnSwitchIn() bool // 精灵出战 / 上场时触发
|
OnSwitchIn() bool // 精灵出战 / 上场时触发
|
||||||
OnSwitchOut() bool // 精灵下场时触发
|
OnSwitchOut() bool // 精灵下场时触发
|
||||||
@@ -33,8 +35,6 @@ type Effect interface {
|
|||||||
PreBattleEnd() bool //战斗结束前
|
PreBattleEnd() bool //战斗结束前
|
||||||
OnBattleEnd() bool //战斗结束
|
OnBattleEnd() bool //战斗结束
|
||||||
|
|
||||||
// PostDamage() bool // 伤害结算后触发(血量扣除后)
|
|
||||||
// AfterAttacked() bool // 被攻击后触发(受击判定)
|
|
||||||
// OnSkillPP() bool //技能PP减少节点
|
// OnSkillPP() bool //技能PP减少节点
|
||||||
// // 治疗相关触发
|
// // 治疗相关触发
|
||||||
// OnBeforeHeal() bool // 治疗前触发
|
// OnBeforeHeal() bool // 治疗前触发
|
||||||
|
|||||||
@@ -93,61 +93,130 @@ func (u *Input) SetProp(in *Input, prop, level int8, ptype info.EnumAbilityOpTyp
|
|||||||
return t.BeferProp(in, prop, level, ptype) //返回本身结算,如果false,说明不能使用技能了
|
return t.BeferProp(in, prop, level, ptype) //返回本身结算,如果false,说明不能使用技能了
|
||||||
|
|
||||||
})
|
})
|
||||||
if canuseskill {
|
if !canuseskill {
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
var newValue int8
|
||||||
|
abfunc := func(prop, level int8, ptype info.EnumAbilityOpType) (ret bool) {
|
||||||
|
|
||||||
switch ptype {
|
switch ptype {
|
||||||
case info.AbilityOpType.AbilityOpIncrease:
|
case info.AbilityOpType.ADD:
|
||||||
newValue := utils.Min(u.AttackValue.Prop[prop]+int8(level), 6)
|
newValue = utils.Min(u.AttackValue.Prop[prop]+int8(level), 6)
|
||||||
|
|
||||||
if newValue > u.AttackValue.Prop[prop] {
|
if newValue > u.AttackValue.Prop[prop] {
|
||||||
fmt.Println("属性值会增加")
|
fmt.Println("属性值会增加")
|
||||||
ret = true
|
return true
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("属性值不会增加")
|
fmt.Println("属性值不会增加")
|
||||||
ret = false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行赋值
|
case info.AbilityOpType.SUB:
|
||||||
u.AttackValue.Prop[prop] = newValue
|
newValue = utils.Max(u.AttackValue.Prop[prop]+int8(level), -6)
|
||||||
|
if newValue < u.AttackValue.Prop[prop] {
|
||||||
|
fmt.Println("属性值会减少")
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
fmt.Println("属性值不会增加")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
case info.AbilityOpType.AbilityOpDecrease:
|
case info.AbilityOpType.RESET:
|
||||||
u.AttackValue.Prop[prop] = utils.Max(u.AttackValue.Prop[prop]+int8(level), -6)
|
|
||||||
|
|
||||||
case info.AbilityOpType.AbilityOpReset:
|
|
||||||
if level > 0 && u.AttackValue.Prop[prop] > 0 { //消强
|
if level > 0 && u.AttackValue.Prop[prop] > 0 { //消强
|
||||||
u.AttackValue.Prop[prop] = 0
|
newValue = 0
|
||||||
|
return true
|
||||||
|
|
||||||
}
|
}
|
||||||
if level < 0 && u.AttackValue.Prop[prop] < 0 { //解弱
|
if level < 0 && u.AttackValue.Prop[prop] < 0 { //解弱
|
||||||
u.AttackValue.Prop[prop] = 0
|
newValue = 0
|
||||||
}
|
return true
|
||||||
|
|
||||||
case info.AbilityOpType.AbilityOpStealStrengthen:
|
|
||||||
|
|
||||||
if in.AttackValue.Prop[prop] > 0 {
|
|
||||||
u.SetProp(u, prop, in.AttackValue.Prop[prop], info.AbilityOpType.AbilityOpIncrease)
|
|
||||||
|
|
||||||
in.SetProp(u, prop, 1, info.AbilityOpType.AbilityOpReset) //消除对面强化
|
|
||||||
}
|
|
||||||
case info.AbilityOpType.AbilityOpReverse:
|
|
||||||
if level > 0 && u.AttackValue.Prop[prop] > 0 { //反转强化,实际上是附带2倍的反转强化
|
|
||||||
|
|
||||||
u.SetProp(u, prop, u.AttackValue.Prop[prop]*2, info.AbilityOpType.AbilityOpDecrease)
|
|
||||||
|
|
||||||
}
|
|
||||||
if level < 0 && u.AttackValue.Prop[prop] < 0 {
|
|
||||||
u.SetProp(u, prop, -u.AttackValue.Prop[prop]*2, info.AbilityOpType.AbilityOpIncrease)
|
|
||||||
}
|
|
||||||
case info.AbilityOpType.AbilityOpBounceWeaken:
|
|
||||||
|
|
||||||
if u.AttackValue.Prop[prop] < 0 {
|
|
||||||
in.SetProp(u, prop, u.AttackValue.Prop[prop], info.AbilityOpType.AbilityOpDecrease)
|
|
||||||
|
|
||||||
u.SetProp(u, prop, -1, info.AbilityOpType.AbilityOpReset) //消除自身弱化
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
return
|
switch ptype {
|
||||||
|
|
||||||
|
case info.AbilityOpType.AbilityOpStealStrengthen:
|
||||||
|
|
||||||
|
temp := in.AttackValue.Prop[prop]
|
||||||
|
|
||||||
|
if temp <= 0 { //对方没有强化
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if abfunc(prop, temp, info.AbilityOpType.ADD) { //把对面的强化等级添加自身
|
||||||
|
u.AttackValue.Prop[prop] = newValue //成功把 强化更新
|
||||||
|
in.SetProp(u, prop, 1, info.AbilityOpType.RESET) //吸取后消除对面强化
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case info.AbilityOpType.AbilityOpReverse:
|
||||||
|
temp := u.AttackValue.Prop[prop]
|
||||||
|
|
||||||
|
switch {
|
||||||
|
|
||||||
|
case level > 0: //反转强化
|
||||||
|
if temp <= 0 { //没有强化
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if abfunc(prop, temp*2, info.AbilityOpType.SUB) {
|
||||||
|
u.AttackValue.Prop[prop] = newValue
|
||||||
|
if temp == -u.AttackValue.Prop[prop] { //成功到对应弱化
|
||||||
|
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { //自身免弱或已到-6
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
default: //反转弱化
|
||||||
|
if temp >= 0 { //没有弱化
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if abfunc(prop, -temp*2, info.AbilityOpType.ADD) {
|
||||||
|
u.AttackValue.Prop[prop] = newValue
|
||||||
|
if temp == -u.AttackValue.Prop[prop] { //成功到对应强化
|
||||||
|
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { //自身免弱或已到-6
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case info.AbilityOpType.AbilityOpBounceWeaken:
|
||||||
|
temp := u.AttackValue.Prop[prop]
|
||||||
|
if temp >= 0 { //没有弱化
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if in.SetProp(u, prop, temp, info.AbilityOpType.SUB) {
|
||||||
|
|
||||||
|
u.SetProp(u, prop, -1, info.AbilityOpType.RESET) //消除自身弱化
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
default: //增加减少重置
|
||||||
|
|
||||||
|
if abfunc(prop, level, ptype) {
|
||||||
|
// 执行赋值
|
||||||
|
u.AttackValue.Prop[prop] = newValue
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
func (i *Input) GetAction(opp *Input) {
|
func (i *Input) GetAction(opp *Input) {
|
||||||
//使用1#技能,实际上要按照四个技能权重去使用
|
//使用1#技能,实际上要按照四个技能权重去使用
|
||||||
@@ -4,10 +4,7 @@ import (
|
|||||||
"blazing/common/utils"
|
"blazing/common/utils"
|
||||||
"blazing/logic/service/common"
|
"blazing/logic/service/common"
|
||||||
"blazing/logic/service/fight/info"
|
"blazing/logic/service/fight/info"
|
||||||
"fmt"
|
|
||||||
"math"
|
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -87,112 +84,3 @@ func (i *Input) GetStatusBonus() float64 {
|
|||||||
|
|
||||||
return maxBonus
|
return maxBonus
|
||||||
}
|
}
|
||||||
|
|
||||||
// 特殊胶囊必定成功
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import (
|
|||||||
type EnumEffectType int
|
type EnumEffectType int
|
||||||
|
|
||||||
var EffectType = enum.New[struct {
|
var EffectType = enum.New[struct {
|
||||||
Skill EnumEffectType `enum:"1000000"` //技能
|
Skill EnumEffectType `enum:"1000000"` //技能
|
||||||
//Prop EnumEffectType `enum:"2000000"` //属性
|
NewSel EnumEffectType `enum:"2000000"` //特性
|
||||||
Status EnumEffectType `enum:"3000000"` //状态
|
Status EnumEffectType `enum:"3000000"` //状态
|
||||||
|
|
||||||
}]()
|
}]()
|
||||||
38
logic/service/player/cmd.go
Normal file
38
logic/service/player/cmd.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package player
|
||||||
|
|
||||||
|
import "blazing/logic/service/fight/info"
|
||||||
|
|
||||||
|
func (p *Player) SendAttackValue(b info.AttackValueS) {
|
||||||
|
t1 := NewTomeeHeader(2505, p.Info.UserID)
|
||||||
|
|
||||||
|
p.SendPack(t1.Pack(&b)) //准备包由各自发,因为协议不一样
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) SendChangePet(b info.ChangePetInfo) {
|
||||||
|
t1 := NewTomeeHeader(2407, p.Info.UserID)
|
||||||
|
|
||||||
|
p.SendPack(t1.Pack(&b)) //准备包由各自发,因为协议不一样
|
||||||
|
|
||||||
|
}
|
||||||
|
func (p *Player) SendReadyToFightInfo(b info.FightStartOutboundInfo) {
|
||||||
|
t1 := NewTomeeHeader(2504, p.Info.UserID)
|
||||||
|
p.SendPack(t1.Pack(&b))
|
||||||
|
}
|
||||||
|
func (p *Player) SendNoteReadyToFightInfo(b info.NoteReadyToFightInfo) {
|
||||||
|
t1 := NewTomeeHeader(2503, p.Info.UserID)
|
||||||
|
|
||||||
|
p.SendPack(t1.Pack(&b)) //准备包由各自发,因为协议不一样
|
||||||
|
}
|
||||||
|
func (p *Player) SendFightEndInfo(b info.FightOverInfo) {
|
||||||
|
t1 := NewTomeeHeader(2506, p.Info.UserID)
|
||||||
|
|
||||||
|
p.SendPack(t1.Pack(&b))
|
||||||
|
p.FightC = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) CatchPetInfo(b info.CatchMonsterOutboundInfo) {
|
||||||
|
t1 := NewTomeeHeader(2409, p.Info.UserID)
|
||||||
|
p.SendPack(t1.Pack(&b))
|
||||||
|
|
||||||
|
}
|
||||||
119
logic/service/player/fight.go
Normal file
119
logic/service/player/fight.go
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
package player
|
||||||
|
|
||||||
|
import (
|
||||||
|
"blazing/logic/service/common"
|
||||||
|
"blazing/logic/service/fight/info"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 邀请玩家加入战斗 邀请者,被邀请者,邀请模式
|
||||||
|
func (lw *Player) InvitePlayerToBattle(pinfo *info.PVPinfo) {
|
||||||
|
lw.PVPinfo = pinfo
|
||||||
|
Mainplayer.Range(func(key uint32, value *Player) bool {
|
||||||
|
|
||||||
|
if key == uint32(lw.PVPinfo.PlayerID) {
|
||||||
|
|
||||||
|
value.HavePVPinfo = append([]*Player{value}, value.HavePVPinfo...)
|
||||||
|
t1 := NewTomeeHeader(2501, value.Info.UserID)
|
||||||
|
t := info.NoteInviteToFightOutboundInfo{
|
||||||
|
UserID: lw.Info.UserID,
|
||||||
|
Nick: lw.Info.Nick,
|
||||||
|
Mode: pinfo.Mode,
|
||||||
|
}
|
||||||
|
value.SendPack(t1.Pack(&t))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消对战邀请
|
||||||
|
func (lw *Player) CancelBattle() {
|
||||||
|
|
||||||
|
if lw.PVPinfo == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Mainplayer.Range(func(key uint32, value *Player) bool {
|
||||||
|
|
||||||
|
if key == uint32(lw.PVPinfo.PlayerID) {
|
||||||
|
for idx, v := range value.HavePVPinfo {
|
||||||
|
if v != nil && v.GetInfo().UserID == lw.PVPinfo.PlayerID {
|
||||||
|
value.HavePVPinfo = append(value.HavePVPinfo[:idx], value.HavePVPinfo[idx+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
lw.PVPinfo = nil
|
||||||
|
}
|
||||||
|
func (lw *Player) CanBattle() bool {
|
||||||
|
|
||||||
|
for _, v := range lw.Info.PetList {
|
||||||
|
if v.Hp > 0 {
|
||||||
|
return true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func (p *Player) SendLoadPercent(b info.LoadPercentOutboundInfo) {
|
||||||
|
t1 := NewTomeeHeader(2441, p.Info.UserID)
|
||||||
|
|
||||||
|
p.SendPack(t1.Pack(&b)) //准备包由各自发,因为协议不一样
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同意对战
|
||||||
|
func (lw *Player) AgreeBattle(userid, flag uint32, mode info.EnumBattleMode) (bool, common.PlayerI) {
|
||||||
|
|
||||||
|
defer func(p *Player) {
|
||||||
|
p.HavePVPinfo = make([]*Player, 0)
|
||||||
|
|
||||||
|
}(lw) //删除对方的邀请信息
|
||||||
|
|
||||||
|
for _, v := range lw.HavePVPinfo {
|
||||||
|
if v == nil || v.Info.UserID != userid || v.PVPinfo == nil {
|
||||||
|
continue
|
||||||
|
|
||||||
|
}
|
||||||
|
t1 := NewTomeeHeader(2502, v.Info.UserID)
|
||||||
|
ret := &info.S2C_NOTE_HANDLE_FIGHT_INVITE{
|
||||||
|
UserID: lw.Info.UserID,
|
||||||
|
Nick: lw.Info.Nick,
|
||||||
|
}
|
||||||
|
|
||||||
|
if flag == 0 { //拒绝对战
|
||||||
|
|
||||||
|
v.SendPack(t1.Pack(ret))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if !lw.IsLogin { //玩家未登录
|
||||||
|
ret.Result = 4
|
||||||
|
v.SendPack(t1.Pack(ret))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if v.PVPinfo.PlayerID == userid && v.PVPinfo.Mode == mode { //成功找到,同意对战
|
||||||
|
if lw.CanBattle() {
|
||||||
|
ret.Result = 1
|
||||||
|
|
||||||
|
v.SendPack(t1.Pack(ret))
|
||||||
|
return true, v
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ret.Result = 3
|
||||||
|
v.SendPack(t1.Pack(ret))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
|
||||||
|
} //如果对方掉线
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
@@ -252,19 +252,7 @@ func (p *Player) SendPack(b []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Player) SendAttackValue(b info.AttackValueS) {
|
|
||||||
t1 := NewTomeeHeader(2505, p.Info.UserID)
|
|
||||||
|
|
||||||
p.SendPack(t1.Pack(&b)) //准备包由各自发,因为协议不一样
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) SendChangePet(b info.ChangePetInfo) {
|
|
||||||
t1 := NewTomeeHeader(2407, p.Info.UserID)
|
|
||||||
|
|
||||||
p.SendPack(t1.Pack(&b)) //准备包由各自发,因为协议不一样
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) Cheak(b error) {
|
func (p *Player) Cheak(b error) {
|
||||||
if b != nil {
|
if b != nil {
|
||||||
@@ -273,27 +261,6 @@ func (p *Player) Cheak(b error) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Player) SendReadyToFightInfo(b info.FightStartOutboundInfo) {
|
|
||||||
t1 := NewTomeeHeader(2504, p.Info.UserID)
|
|
||||||
p.SendPack(t1.Pack(&b))
|
|
||||||
}
|
|
||||||
func (p *Player) SendNoteReadyToFightInfo(b info.NoteReadyToFightInfo) {
|
|
||||||
t1 := NewTomeeHeader(2503, p.Info.UserID)
|
|
||||||
|
|
||||||
p.SendPack(t1.Pack(&b)) //准备包由各自发,因为协议不一样
|
|
||||||
}
|
|
||||||
func (p *Player) SendFightEndInfo(b info.FightOverInfo) {
|
|
||||||
t1 := NewTomeeHeader(2506, p.Info.UserID)
|
|
||||||
|
|
||||||
p.SendPack(t1.Pack(&b))
|
|
||||||
p.FightC = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) CatchPetInfo(b info.CatchMonsterOutboundInfo) {
|
|
||||||
t1 := NewTomeeHeader(2409, p.Info.UserID)
|
|
||||||
p.SendPack(t1.Pack(&b))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func LeaveMap(c common.PlayerI) {
|
func LeaveMap(c common.PlayerI) {
|
||||||
t := NewTomeeHeader(2002, c.GetInfo().UserID)
|
t := NewTomeeHeader(2002, c.GetInfo().UserID)
|
||||||
@@ -415,116 +382,3 @@ func (lw *Player) IsNewPlayer() bool {
|
|||||||
}
|
}
|
||||||
return false // 全部等于3则返回false
|
return false // 全部等于3则返回false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 邀请玩家加入战斗 邀请者,被邀请者,邀请模式
|
|
||||||
func (lw *Player) InvitePlayerToBattle(pinfo *info.PVPinfo) {
|
|
||||||
lw.PVPinfo = pinfo
|
|
||||||
Mainplayer.Range(func(key uint32, value *Player) bool {
|
|
||||||
|
|
||||||
if key == uint32(lw.PVPinfo.PlayerID) {
|
|
||||||
|
|
||||||
value.HavePVPinfo = append([]*Player{value}, value.HavePVPinfo...)
|
|
||||||
t1 := NewTomeeHeader(2501, value.Info.UserID)
|
|
||||||
t := info.NoteInviteToFightOutboundInfo{
|
|
||||||
UserID: lw.Info.UserID,
|
|
||||||
Nick: lw.Info.Nick,
|
|
||||||
Mode: pinfo.Mode,
|
|
||||||
}
|
|
||||||
value.SendPack(t1.Pack(&t))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 取消对战邀请
|
|
||||||
func (lw *Player) CancelBattle() {
|
|
||||||
|
|
||||||
if lw.PVPinfo == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Mainplayer.Range(func(key uint32, value *Player) bool {
|
|
||||||
|
|
||||||
if key == uint32(lw.PVPinfo.PlayerID) {
|
|
||||||
for idx, v := range value.HavePVPinfo {
|
|
||||||
if v != nil && v.GetInfo().UserID == lw.PVPinfo.PlayerID {
|
|
||||||
value.HavePVPinfo = append(value.HavePVPinfo[:idx], value.HavePVPinfo[idx+1:]...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
lw.PVPinfo = nil
|
|
||||||
}
|
|
||||||
func (lw *Player) CanBattle() bool {
|
|
||||||
|
|
||||||
for _, v := range lw.Info.PetList {
|
|
||||||
if v.Hp > 0 {
|
|
||||||
return true
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
func (p *Player) SendLoadPercent(b info.LoadPercentOutboundInfo) {
|
|
||||||
t1 := NewTomeeHeader(2441, p.Info.UserID)
|
|
||||||
|
|
||||||
p.SendPack(t1.Pack(&b)) //准备包由各自发,因为协议不一样
|
|
||||||
}
|
|
||||||
|
|
||||||
// 同意对战
|
|
||||||
func (lw *Player) AgreeBattle(userid, flag uint32, mode info.EnumBattleMode) (bool, common.PlayerI) {
|
|
||||||
|
|
||||||
defer func(p *Player) {
|
|
||||||
p.HavePVPinfo = make([]*Player, 0)
|
|
||||||
|
|
||||||
}(lw) //删除对方的邀请信息
|
|
||||||
|
|
||||||
for _, v := range lw.HavePVPinfo {
|
|
||||||
if v == nil || v.Info.UserID != userid || v.PVPinfo == nil {
|
|
||||||
continue
|
|
||||||
|
|
||||||
}
|
|
||||||
t1 := NewTomeeHeader(2502, v.Info.UserID)
|
|
||||||
ret := &info.S2C_NOTE_HANDLE_FIGHT_INVITE{
|
|
||||||
UserID: lw.Info.UserID,
|
|
||||||
Nick: lw.Info.Nick,
|
|
||||||
}
|
|
||||||
|
|
||||||
if flag == 0 { //拒绝对战
|
|
||||||
|
|
||||||
v.SendPack(t1.Pack(ret))
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
if !lw.IsLogin { //玩家未登录
|
|
||||||
ret.Result = 4
|
|
||||||
v.SendPack(t1.Pack(ret))
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
if v.PVPinfo.PlayerID == userid && v.PVPinfo.Mode == mode { //成功找到,同意对战
|
|
||||||
if lw.CanBattle() {
|
|
||||||
ret.Result = 1
|
|
||||||
|
|
||||||
v.SendPack(t1.Pack(ret))
|
|
||||||
return true, v
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ret.Result = 3
|
|
||||||
v.SendPack(t1.Pack(ret))
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, nil
|
|
||||||
|
|
||||||
} //如果对方掉线
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -23,15 +23,12 @@ import (
|
|||||||
|
|
||||||
_ "blazing/modules"
|
_ "blazing/modules"
|
||||||
|
|
||||||
"blazing/logic/service/task"
|
|
||||||
"blazing/login/internal/cmd"
|
"blazing/login/internal/cmd"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/os/gctx"
|
"github.com/gogf/gf/v2/os/gctx"
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var tt task.GetTaskBufOutboundInfo
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
//Test_kick()
|
//Test_kick()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user