feat(fight): 优化战斗逻辑与精灵切换流程
- 在多个战斗控制器方法中添加 defer 调用,确保战斗操作正确延迟执行 - 修改 ChangePet 方法返回值类型,增强接口一致性 - 修复战斗准备阶段逻辑,重构战斗开始信息构建过程 - 移除冗余广播调用,调整 PVE 战斗初始化流程 - 更新 README 中的 pprof 命令地址并完善项目介绍部分 fix(effect): 修复效果叠加逻辑与ID解析问题 - 效果叠加时默认增加一层,而非直接相加参数 - 修正 EffectIDCombiner 类型、CatchTime 的掩码偏移计算错误 - 添加重复效果日志输出,便于调试追踪 feat(boss): 完善BOSS特性实现逻辑 - 修正 NewSel17 特性
This commit is contained in:
@@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
这是骄阳号开发团队的开源项目,请勿用于商业用途。
|
这是骄阳号开发团队的开源项目,请勿用于商业用途。
|
||||||
在软件开发中,repo、impl、mapper 和 model 是常见的分层架构组件
|
在软件开发中,repo、impl、mapper 和 model 是常见的分层架构组件
|
||||||
|
|
||||||
## 项目介绍
|
## 项目介绍
|
||||||
|
|
||||||
## seer-project
|
## seer-project
|
||||||
|
|
||||||
项目结构:
|
项目结构:
|
||||||
go tool pprof -http :8081 "http://125.208.20.223:54612/debug/debug/pprof/profile"
|
go tool pprof -http :8081 "http://125.208.20.223:54612/debug/debug/pprof/profile"
|
||||||
go tool pprof -http :8081 "http://127.0.0.1:9909/debug/debug/pprof/profile"
|
go tool pprof -http :8081 "http://127.0.0.1:9909/debug/pprof/profile"
|
||||||
|
|
||||||
详情查看 [文档](./docs)
|
详情查看 [文档](./docs)
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func (h Controller) OnReadyToFight(data *fight.ReadyToFightInboundInfo, c *playe
|
|||||||
if c.FightC == nil {
|
if c.FightC == nil {
|
||||||
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
||||||
}
|
}
|
||||||
c.FightC.ReadyFight(c)
|
defer c.FightC.ReadyFight(c)
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ func (h Controller) UseSkill(data *fight.UseSkillInInfo, c *player.Player) (resu
|
|||||||
if c.FightC == nil {
|
if c.FightC == nil {
|
||||||
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
||||||
}
|
}
|
||||||
c.FightC.UseSkill(c, (data.SkillId))
|
defer c.FightC.UseSkill(c, data.SkillId)
|
||||||
return nil, 0
|
return nil, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,17 +42,17 @@ func (h Controller) Escape(data *fight.EscapeFightInboundInfo, c *player.Player)
|
|||||||
|
|
||||||
return nil, errorcode.ErrorCodes.ErrCannotFleePlayerBattle
|
return nil, errorcode.ErrorCodes.ErrCannotFleePlayerBattle
|
||||||
}
|
}
|
||||||
c.FightC.Over(c, info.BattleOverReason.PlayerEscape)
|
defer c.FightC.Over(c, info.BattleOverReason.PlayerEscape)
|
||||||
return nil, 0
|
return nil, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// 切换精灵
|
// 切换精灵
|
||||||
func (h Controller) ChangePet(data *fight.ChangePetInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) ChangePet(data *fight.ChangePetInboundInfo, c *player.Player) (result *info.ChangePetInfo, err errorcode.ErrorCode) {
|
||||||
if c.FightC == nil {
|
if c.FightC == nil {
|
||||||
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
||||||
}
|
}
|
||||||
|
|
||||||
c.FightC.ChangePet(c, data.CatchTime)
|
defer c.FightC.ChangePet(c, data.CatchTime)
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ func (h Controller) Capture(data *fight.CatchMonsterInboundInfo, c *player.Playe
|
|||||||
if c.FightC == nil {
|
if c.FightC == nil {
|
||||||
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
||||||
}
|
}
|
||||||
c.FightC.Capture(c, data.CapsuleId)
|
defer c.FightC.Capture(c, data.CapsuleId)
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ func (h Controller) LoadPercent(data *fight.LoadPercentInboundInfo, c *player.Pl
|
|||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
c.FightC.LoadPercent(c, int32(data.Percent))
|
defer c.FightC.LoadPercent(c, int32(data.Percent))
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
func (h Controller) UsePetItemInboundInfo(data *fight.UsePetItemInboundInfo, c *player.Player) (result *info.UsePetIteminfo, err errorcode.ErrorCode) {
|
func (h Controller) UsePetItemInboundInfo(data *fight.UsePetItemInboundInfo, c *player.Player) (result *info.UsePetIteminfo, err errorcode.ErrorCode) {
|
||||||
@@ -80,7 +80,7 @@ func (h Controller) UsePetItemInboundInfo(data *fight.UsePetItemInboundInfo, c *
|
|||||||
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
||||||
}
|
}
|
||||||
|
|
||||||
c.FightC.UseItem(c, data.CatchTime, data.ItemId)
|
defer c.FightC.UseItem(c, data.CatchTime, data.ItemId)
|
||||||
|
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ func (h Controller) FightChat(data *fight.ChatInfo, c *player.Player) (result *f
|
|||||||
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
||||||
}
|
}
|
||||||
|
|
||||||
c.FightC.Chat(c, data.Message)
|
defer c.FightC.Chat(c, data.Message)
|
||||||
|
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ func (h Controller) ARENA_OWENR_ACCE(data *fight.ARENA_OWENR_ACCE, c *player.Pla
|
|||||||
s := c.GetSpace()
|
s := c.GetSpace()
|
||||||
|
|
||||||
if atomic.LoadUint32(&c.GetSpace().Owner.UserID) != c.GetInfo().UserID && c.GetInfo().UserID != atomic.LoadUint32(&c.GetSpace().Owner.ChallengerID) { //说明已经有人了
|
if atomic.LoadUint32(&c.GetSpace().Owner.UserID) != c.GetInfo().UserID && c.GetInfo().UserID != atomic.LoadUint32(&c.GetSpace().Owner.ChallengerID) { //说明已经有人了
|
||||||
return nil, errorcode.ErrorCodes.ErrChampionCannotCancel
|
return nil, -1
|
||||||
}
|
}
|
||||||
s.Owner.Set(c)
|
s.Owner.Set(c)
|
||||||
|
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ func (h *Controller) PlayerShowPet(
|
|||||||
copier.Copy(&result, onpet)
|
copier.Copy(&result, onpet)
|
||||||
result.Flag = data.Flag
|
result.Flag = data.Flag
|
||||||
result.UserID = data.Head.UserID
|
result.UserID = data.Head.UserID
|
||||||
c.GetSpace().Broadcast(c, data.Head.CMD, result)
|
defer c.GetSpace().Broadcast(c, data.Head.CMD, result)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -188,7 +188,8 @@ func (h *Controller) PetOneCure(
|
|||||||
|
|
||||||
_, onpet, ok := c.FindPet(data.CatchTime)
|
_, onpet, ok := c.FindPet(data.CatchTime)
|
||||||
if ok {
|
if ok {
|
||||||
onpet.Cure()
|
defer onpet.Cure()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pet.PetOneCureOutboundInfo{
|
return &pet.PetOneCureOutboundInfo{
|
||||||
@@ -226,7 +227,7 @@ func (h Controller) SetPetExp(data *pet.PetSetExpInboundInfo, c *player.Player)
|
|||||||
_, onpet, ok := c.FindPet(data.CatchTime)
|
_, onpet, ok := c.FindPet(data.CatchTime)
|
||||||
if ok {
|
if ok {
|
||||||
|
|
||||||
c.AddPetExp(onpet, data.Exp)
|
defer c.AddPetExp(onpet, data.Exp)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pet.PetSetExpOutboundInfo{
|
return &pet.PetSetExpOutboundInfo{
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"blazing/logic/service/fight/action"
|
"blazing/logic/service/fight/action"
|
||||||
"blazing/logic/service/fight/info"
|
"blazing/logic/service/fight/info"
|
||||||
"blazing/logic/service/fight/input"
|
"blazing/logic/service/fight/input"
|
||||||
"blazing/logic/service/player"
|
|
||||||
"context"
|
"context"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@@ -60,15 +59,17 @@ func (f *FightC) ChangePet(c common.PlayerI, id uint32) {
|
|||||||
cool.Loger.Debug(context.Background(), " 战斗chan已关闭")
|
cool.Loger.Debug(context.Background(), " 战斗chan已关闭")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
//todo 待实现无法切精灵的情况
|
||||||
selfinput := f.GetInputByPlayer(c, false)
|
|
||||||
InitAttackValue := *selfinput.AttackValue
|
|
||||||
oldpet := selfinput.CurrentPet
|
|
||||||
ret := &action.ActiveSwitchAction{
|
ret := &action.ActiveSwitchAction{
|
||||||
BaseAction: action.NewBaseAction(c.GetInfo().UserID),
|
BaseAction: action.NewBaseAction(c.GetInfo().UserID),
|
||||||
}
|
}
|
||||||
selfinput.CurrentPet, ret.Reason = selfinput.GetPet(id)
|
|
||||||
|
|
||||||
|
selfinput := f.GetInputByPlayer(c, false)
|
||||||
|
|
||||||
|
selfinput.CurrentPet, ret.Reason = selfinput.GetPet(id)
|
||||||
|
c.SendPackCmd(2407, &ret.Reason)
|
||||||
|
InitAttackValue := *selfinput.AttackValue
|
||||||
|
oldpet := selfinput.CurrentPet
|
||||||
f.Switch = append(f.Switch, ret)
|
f.Switch = append(f.Switch, ret)
|
||||||
selfinput.InitAttackValue() //切换精灵消除能力提升
|
selfinput.InitAttackValue() //切换精灵消除能力提升
|
||||||
//这时候精灵已经切换过了,可以直接给新精灵加效果
|
//这时候精灵已经切换过了,可以直接给新精灵加效果
|
||||||
@@ -83,13 +84,6 @@ func (f *FightC) ChangePet(c common.PlayerI, id uint32) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
f.Broadcast(func(ff *input.Input) { //先给自身广播
|
|
||||||
if ff.Player.GetInfo().UserID == c.GetInfo().UserID {
|
|
||||||
ff.Player.SendPackCmd(2407, &ret.Reason)
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
f.actionChan <- ret
|
f.actionChan <- ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,31 +129,12 @@ func (f *FightC) UseItem(c common.PlayerI, cacthid, itemid uint32) {
|
|||||||
|
|
||||||
// ReadyFight 处理玩家战斗准备逻辑,当满足条件时启动战斗循环
|
// ReadyFight 处理玩家战斗准备逻辑,当满足条件时启动战斗循环
|
||||||
func (f *FightC) ReadyFight(c common.PlayerI) {
|
func (f *FightC) ReadyFight(c common.PlayerI) {
|
||||||
// 1. 构建战斗开始信息(整理双方初始宠物信息)
|
|
||||||
fightStartInfo := f.buildFightStartInfo()
|
|
||||||
|
|
||||||
// 2. 标记当前玩家已准备完成
|
// 2. 标记当前玩家已准备完成
|
||||||
input := f.GetInputByPlayer(c, false)
|
input := f.GetInputByPlayer(c, false)
|
||||||
input.Finished = true
|
input.Finished = true
|
||||||
|
|
||||||
// 3. 根据战斗类型判断是否满足战斗启动条件,满足则启动
|
|
||||||
switch f.Info.Status {
|
|
||||||
|
|
||||||
case info.BattleMode.FIGHT_WITH_NPC: // NPC/野怪战斗:处理捕捉相关逻辑后启动
|
|
||||||
//f.handleNPCFightSpecial(&fightStartInfo)
|
|
||||||
|
|
||||||
if f.Opp.Player.(*player.AI_player).CanCapture > 0 {
|
|
||||||
f.Opp.CanCapture = f.Opp.Player.(*player.AI_player).CanCapture
|
|
||||||
fightStartInfo.Info2.Catchable = 1 //可以捕捉就置1
|
|
||||||
}
|
|
||||||
f.Opp.AttackValue.Prop = f.Opp.Player.(*player.AI_player).Prop
|
|
||||||
fightStartInfo.Info2.Prop = f.Opp.AttackValue.Prop
|
|
||||||
f.startBattle(fightStartInfo)
|
|
||||||
default: // PVP战斗:需双方都准备完成
|
|
||||||
if f.checkBothPlayersReady(c) {
|
if f.checkBothPlayersReady(c) {
|
||||||
f.startBattle(fightStartInfo)
|
f.startBattle(f.FightStartOutboundInfo)
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,12 +173,6 @@ func (f *FightC) startBattle(startInfo info.FightStartOutboundInfo) {
|
|||||||
log.Panic(context.Background(), "战斗循环提交失败", "error", err)
|
log.Panic(context.Background(), "战斗循环提交失败", "error", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
f.Broadcast(func(ff *input.Input) {
|
|
||||||
|
|
||||||
ff.InitEFFect(&startInfo)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
f.Broadcast(func(ff *input.Input) {
|
f.Broadcast(func(ff *input.Input) {
|
||||||
|
|
||||||
// 通知双方玩家准备完成,即将开始战斗
|
// 通知双方玩家准备完成,即将开始战斗
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ type NewSel1 struct {
|
|||||||
NewSel0
|
NewSel0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *NewSel1) BeferProp(in *input.Ctx, prop, level int8, ptype info.EnumAbilityOpType) bool {
|
func (e *NewSel1) Prop_Befer(in *input.Input, prop int8, level int8, ptype info.EnumAbilityOpType) bool {
|
||||||
|
|
||||||
//魂印特性有不在场的情况,绑定时候将精灵和特性绑定
|
//魂印特性有不在场的情况,绑定时候将精灵和特性绑定
|
||||||
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
|
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
|
||||||
@@ -35,7 +35,7 @@ func (e *NewSel1) BeferProp(in *input.Ctx, prop, level int8, ptype info.EnumAbil
|
|||||||
}
|
}
|
||||||
|
|
||||||
//能力下降类
|
//能力下降类
|
||||||
if level > 0 && ptype == info.AbilityOpType.SUB {
|
if ptype == info.AbilityOpType.SUB {
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"blazing/logic/service/fight/input"
|
"blazing/logic/service/fight/input"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 17. 自身体力降到N以下时,每次攻击必定致命一击;(a1: high 32, a2: low 32)
|
// 17. 自身体力降到N以下时,每次攻击必定致命一击;(a1: high 32 )
|
||||||
// TODO: 实现自身体力降到N以下时,每次攻击必定致命一击;(a1: high 32, a2: low 32)的核心逻辑
|
// TODO: 实现自身体力降到N以下时,每次攻击必定致命一击;(a1: high 32, a2: low 32)的核心逻辑
|
||||||
type NewSel17 struct {
|
type NewSel17 struct {
|
||||||
NewSel0
|
NewSel0
|
||||||
@@ -23,8 +23,8 @@ func (e *NewSel17) Action_start(a, b *action.SelectSkillAction) bool {
|
|||||||
if e.Ctx().SkillEntity.Category() == info.Category.STATUS {
|
if e.Ctx().SkillEntity.Category() == info.Category.STATUS {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
full32 := int64(e.Args()[0])<<32 | int64(e.Args()[1])
|
|
||||||
if e.Ctx().Our.CurrentPet.HP <= int(full32) {
|
if e.Ctx().Our.CurrentPet.HP <= int(e.Args()[0]) {
|
||||||
e.Ctx().SkillEntity.CritRate = 16
|
e.Ctx().SkillEntity.CritRate = 16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ func (e *NewSel27) Damage_DIV_ex(t *info.DamageZone) bool {
|
|||||||
if e.Ctx().SkillEntity == nil {
|
if e.Ctx().SkillEntity == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if t.Type != info.DamageType.Red {
|
||||||
|
return true
|
||||||
|
}
|
||||||
if e.index >= len(e.Args()) {
|
if e.index >= len(e.Args()) {
|
||||||
e.index = 0
|
e.index = 0
|
||||||
|
|
||||||
|
|||||||
@@ -11,19 +11,35 @@ import (
|
|||||||
// TODO: 实现偶数伤害(dmg) 提升到 n * dmg;(a1: n)的核心逻辑
|
// TODO: 实现偶数伤害(dmg) 提升到 n * dmg;(a1: n)的核心逻辑
|
||||||
type NewSel39 struct {
|
type NewSel39 struct {
|
||||||
NewSel0
|
NewSel0
|
||||||
|
can bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *NewSel39) Damage_DIV_ex(t *info.DamageZone) bool {
|
func (e *NewSel39) Damage_Mul(t *info.DamageZone) bool {
|
||||||
|
|
||||||
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
|
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.Damage.IntPart()%2 == 0 {
|
if !e.can {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
t.Damage = t.Damage.Mul(decimal.NewFromInt(int64(e.Args()[0])))
|
t.Damage = t.Damage.Mul(decimal.NewFromInt(int64(e.Args()[0])))
|
||||||
|
return true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *NewSel39) Skill_Use_ex() bool {
|
||||||
|
//fmt.Println("NewSel39", t.Damage.IntPart())
|
||||||
|
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if e.Ctx().Opp.SumDamage.IntPart()%2 == 0 {
|
||||||
|
e.can = true
|
||||||
|
} else {
|
||||||
|
e.can = false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
func init() {
|
func init() {
|
||||||
|
|||||||
@@ -11,21 +11,38 @@ import (
|
|||||||
// TODO: 实现奇数伤害(dmg) 改为 1/n * dmg;(a1: n)的核心逻辑
|
// TODO: 实现奇数伤害(dmg) 改为 1/n * dmg;(a1: n)的核心逻辑
|
||||||
type NewSel40 struct {
|
type NewSel40 struct {
|
||||||
NewSel0
|
NewSel0
|
||||||
|
can bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *NewSel40) Damage_DIV_ex(t *info.DamageZone) bool {
|
func (e *NewSel40) Damage_DIV_ex(t *info.DamageZone) bool {
|
||||||
|
|
||||||
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
|
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.Damage.IntPart()%2 != 0 {
|
if !e.can {
|
||||||
|
return true
|
||||||
t.Damage = t.Damage.Mul(decimal.NewFromInt(1 / int64(e.Args()[0])))
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.Damage = t.Damage.Mul(decimal.NewFromInt(1).Div(decimal.NewFromInt(int64(e.Args()[0]))))
|
||||||
|
return true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *NewSel40) Skill_Use_ex() bool {
|
||||||
|
//fmt.Println("NewSel39", t.Damage.IntPart())
|
||||||
|
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.Ctx().Opp.SumDamage.IntPart()%2 != 0 {
|
||||||
|
e.can = true
|
||||||
|
} else {
|
||||||
|
e.can = false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
input.InitEffect(input.EffectType.NewSel, 40, &NewSel40{})
|
input.InitEffect(input.EffectType.NewSel, 40, &NewSel40{})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ func (e *Weakened) Damage_DIV_ex(t *info.DamageZone) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. 校验并限制衰弱等级(≤0 直接返回,≥5 按5级算)
|
// 2. 校验并限制衰弱等级(≤0 直接返回,≥5 按5级算)
|
||||||
level := e.Status
|
level := e.Stack()
|
||||||
if level <= 0 {
|
if level <= 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"blazing/logic/service/fight/action"
|
"blazing/logic/service/fight/action"
|
||||||
"blazing/logic/service/fight/info"
|
"blazing/logic/service/fight/info"
|
||||||
"blazing/logic/service/fight/input"
|
"blazing/logic/service/fight/input"
|
||||||
|
"blazing/logic/service/player"
|
||||||
"blazing/logic/service/user"
|
"blazing/logic/service/user"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -22,7 +23,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type FightC struct {
|
type FightC struct {
|
||||||
|
//准备战斗信息
|
||||||
ReadyInfo info.NoteReadyToFightInfo
|
ReadyInfo info.NoteReadyToFightInfo
|
||||||
|
//开始战斗信息
|
||||||
|
info.FightStartOutboundInfo
|
||||||
Info info.Fightinfo
|
Info info.Fightinfo
|
||||||
IsReady bool
|
IsReady bool
|
||||||
ownerID uint32 // 战斗发起者ID
|
ownerID uint32 // 战斗发起者ID
|
||||||
@@ -221,6 +225,8 @@ func NewFight(p1, p2 common.PlayerI, fn func(*info.FightOverInfo)) (*FightC, err
|
|||||||
fmt.Println("NewFight", p1.GetInfo().UserID)
|
fmt.Println("NewFight", p1.GetInfo().UserID)
|
||||||
f := &FightC{}
|
f := &FightC{}
|
||||||
f.ownerID = p1.GetInfo().UserID
|
f.ownerID = p1.GetInfo().UserID
|
||||||
|
// 1. 构建战斗开始信息(整理双方初始宠物信息)
|
||||||
|
|
||||||
f.callback = fn //战斗结束的回调
|
f.callback = fn //战斗结束的回调
|
||||||
f.quit = make(chan struct{})
|
f.quit = make(chan struct{})
|
||||||
f.over = make(chan struct{})
|
f.over = make(chan struct{})
|
||||||
@@ -249,19 +255,28 @@ func NewFight(p1, p2 common.PlayerI, fn func(*info.FightOverInfo)) (*FightC, err
|
|||||||
f.ReadyInfo.OpponentInfo, f.ReadyInfo.OpponentPetList = initfightready(f.Opp)
|
f.ReadyInfo.OpponentInfo, f.ReadyInfo.OpponentPetList = initfightready(f.Opp)
|
||||||
var loadtime time.Duration = 120 * time.Second
|
var loadtime time.Duration = 120 * time.Second
|
||||||
//说明是PVE
|
//说明是PVE
|
||||||
if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC {
|
|
||||||
|
|
||||||
f.Opp.Finished = true //PVE 默认boss数据直接加载完成
|
|
||||||
loadtime = 60 * time.Second
|
|
||||||
}
|
|
||||||
|
|
||||||
f.Broadcast(func(ff *input.Input) {
|
f.Broadcast(func(ff *input.Input) {
|
||||||
ff.SetOPP(f.GetInputByPlayer(ff.Player, true))
|
ff.SetOPP(f.GetInputByPlayer(ff.Player, true))
|
||||||
|
|
||||||
})
|
})
|
||||||
|
f.FightStartOutboundInfo = f.buildFightStartInfo()
|
||||||
|
if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC {
|
||||||
|
|
||||||
|
f.Opp.Finished = true //PVE 默认boss数据直接加载完成
|
||||||
|
loadtime = 60 * time.Second
|
||||||
|
//f.handleNPCFightSpecial(&fightStartInfo)
|
||||||
|
|
||||||
|
if f.Opp.Player.(*player.AI_player).CanCapture > 0 {
|
||||||
|
f.Opp.CanCapture = f.Opp.Player.(*player.AI_player).CanCapture
|
||||||
|
f.FightStartOutboundInfo.Info2.Catchable = 1 //可以捕捉就置1
|
||||||
|
}
|
||||||
|
f.Opp.AttackValue.Prop = f.Opp.Player.(*player.AI_player).Prop
|
||||||
|
f.FightStartOutboundInfo.Info2.Prop = f.Opp.AttackValue.Prop
|
||||||
|
}
|
||||||
|
|
||||||
f.Broadcast(func(ff *input.Input) {
|
f.Broadcast(func(ff *input.Input) {
|
||||||
|
//ff.InitEFFect(&f.FightStartOutboundInfo)
|
||||||
ff.Player.SendPackCmd(2503, &f.ReadyInfo)
|
ff.Player.SendPackCmd(2503, &f.ReadyInfo)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ func (our *Input) AddEffect(in *Input, e Effect) Effect {
|
|||||||
if v.ID().Base == e.ID().Base && //找到相同的效果id
|
if v.ID().Base == e.ID().Base && //找到相同的效果id
|
||||||
v.Alive() && //如果之前的效果还存活
|
v.Alive() && //如果之前的效果还存活
|
||||||
equalInts(v.Args(), e.Args()) { //如果层数可以叠加或者是无限层数
|
equalInts(v.Args(), e.Args()) { //如果层数可以叠加或者是无限层数
|
||||||
|
fmt.Println("重复效果", e.ID().Suffix(), v.ID().Suffix())
|
||||||
|
|
||||||
if !v.CanStack() { //说明进行了替换
|
if !v.CanStack() { //说明进行了替换
|
||||||
v.Alive(false) //不允许叠层,取消效果
|
v.Alive(false) //不允许叠层,取消效果
|
||||||
@@ -194,7 +195,8 @@ func (our *Input) AddEffect(in *Input, e Effect) Effect {
|
|||||||
our.Effects = append(our.Effects, e)
|
our.Effects = append(our.Effects, e)
|
||||||
return v //这里把V替换掉了
|
return v //这里把V替换掉了
|
||||||
} else {
|
} else {
|
||||||
v.Stack(v.Stack() + e.Stack()) //获取到当前叠层数然后叠加
|
//默认给叠一层
|
||||||
|
v.Stack(v.Stack() + 1) //获取到当前叠层数然后叠加
|
||||||
//这里直接返回,不再继续执行后续效果,因为这里是可以叠加的效果
|
//这里直接返回,不再继续执行后续效果,因为这里是可以叠加的效果
|
||||||
//v.Duration(e.Duration()) //回合数覆盖
|
//v.Duration(e.Duration()) //回合数覆盖
|
||||||
v.Duration(utils.Max(e.Duration(), v.Duration()))
|
v.Duration(utils.Max(e.Duration(), v.Duration()))
|
||||||
@@ -264,10 +266,3 @@ func (our *Input) CancelTurn(in *Input) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// 初始化魂印
|
|
||||||
func (our *Input) InitEFFect(info *info.FightStartOutboundInfo) {
|
|
||||||
|
|
||||||
//our.AttackValue = info.NewAttackValue(our.Player.GetInfo().UserID)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -54,22 +54,26 @@ func (e *EffectIDCombiner) EffectID() int64 {
|
|||||||
return e.Base
|
return e.Base
|
||||||
}
|
}
|
||||||
|
|
||||||
// EffectType 读取/替换效果类型(读写一体)
|
// SetEffectType 设置效果类型(修复掩码偏移问题)
|
||||||
// 参数t:可选,传入则替换当前效果类型;不传则仅读取
|
// 参数t:必须传入有效值,否则panic(也可加len(t)==0判断)
|
||||||
// 返回:当前的效果类型(EnumEffectType)
|
func (e *EffectIDCombiner) SetEffectType(t EnumEffectType) {
|
||||||
func (e *EffectIDCombiner) SetEffectType(t ...EnumEffectType) {
|
|
||||||
e.Base = (e.Base & ^prefixMask) | (int64(t[0]) << prefixOffset)
|
// 修正:掩码左移到高16位,仅清空效果类型区域
|
||||||
|
clearMask := uint64(prefixMask) << prefixOffset
|
||||||
|
e.Base = (e.Base & ^int64(clearMask)) | (int64(t) << prefixOffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetEffectType 读取效果类型
|
||||||
func (e EffectIDCombiner) GetEffectType() EnumEffectType {
|
func (e EffectIDCombiner) GetEffectType() EnumEffectType {
|
||||||
|
return EnumEffectType((e.Base >> prefixOffset) & int64(prefixMask))
|
||||||
return EnumEffectType((e.Base >> prefixOffset) & 0xFFFF)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CatchTime 读取/替换CatchTime(读写一体,完全保留你的写法)
|
// SetCatchTime 设置CatchTime(修复掩码偏移问题,避免清空Suffix)
|
||||||
// 参数t:可选,传入则替换当前CatchTime;不传则仅读取
|
func (e *EffectIDCombiner) SetCatchTime(t uint32) {
|
||||||
// 返回:当前的CatchTime值
|
|
||||||
func (e *EffectIDCombiner) SetCatchTime(t ...uint32) {
|
// 修正:掩码左移到中32位,仅清空CatchTime区域
|
||||||
e.Base = (e.Base & ^catchMask) | (int64(t[0]) << catchOffset)
|
clearMask := uint64(catchMask) << catchOffset
|
||||||
|
e.Base = (e.Base & ^int64(clearMask)) | (int64(t) << catchOffset)
|
||||||
}
|
}
|
||||||
func (e EffectIDCombiner) GetCatchTime() uint32 {
|
func (e EffectIDCombiner) GetCatchTime() uint32 {
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package input
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"blazing/common/data/xmlres"
|
"blazing/common/data/xmlres"
|
||||||
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"blazing/logic/service/common"
|
"blazing/logic/service/common"
|
||||||
@@ -81,6 +82,7 @@ func (our *Input) SortPet() {
|
|||||||
t := Geteffect(EffectType.NewSel, e1.EID)
|
t := Geteffect(EffectType.NewSel, e1.EID)
|
||||||
if t != nil {
|
if t != nil {
|
||||||
ef := t.ID()
|
ef := t.ID()
|
||||||
|
fmt.Println("初始化特性", ef.Suffix())
|
||||||
|
|
||||||
ef.SetCatchTime(v.Info.CatchTime)
|
ef.SetCatchTime(v.Info.CatchTime)
|
||||||
|
|
||||||
@@ -154,6 +156,8 @@ func (our *Input) GetPet(id uint32) (ii *info.BattlePetEntity, Reason info.Chang
|
|||||||
Reason.UserId = our.Player.GetInfo().UserID
|
Reason.UserId = our.Player.GetInfo().UserID
|
||||||
|
|
||||||
ii = v
|
ii = v
|
||||||
|
|
||||||
|
return ii, Reason
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,9 @@ func (e *EffectNode) Stack(t ...int) int {
|
|||||||
|
|
||||||
}
|
}
|
||||||
func (e *EffectNode) ID(t ...input.EffectIDCombiner) input.EffectIDCombiner {
|
func (e *EffectNode) ID(t ...input.EffectIDCombiner) input.EffectIDCombiner {
|
||||||
|
|
||||||
if len(t) > 0 {
|
if len(t) > 0 {
|
||||||
|
|
||||||
e.id = t[0]
|
e.id = t[0]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
|
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
|
||||||
|
|
||||||
|
"blazing/common/data/xmlres"
|
||||||
_ "blazing/contrib/files/local"
|
_ "blazing/contrib/files/local"
|
||||||
"blazing/login/internal/cmd"
|
"blazing/login/internal/cmd"
|
||||||
|
|
||||||
@@ -21,8 +22,21 @@ import (
|
|||||||
"github.com/gogf/gf/v2/os/gctx"
|
"github.com/gogf/gf/v2/os/gctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
xmlres.Initfile()
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
|
// for _, i := range xmlres.ItemsMAP {
|
||||||
|
|
||||||
|
// cool.DBM(dict.NewDictInfoService().GetModel()).Insert(
|
||||||
|
// g.Map{"typeId": 6, "name": i.Name, "remark": i.ID, "ordernum": 1},
|
||||||
|
// )
|
||||||
|
// fmt.Println(i.ID, i.Name)
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
//input.Test()
|
//input.Test()
|
||||||
// element.TestAllScenarios()
|
// element.TestAllScenarios()
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ func init() {
|
|||||||
g.Server().BindMiddleware("/admin/*/open/*", BaseAuthorityMiddlewareOpen)
|
g.Server().BindMiddleware("/admin/*/open/*", BaseAuthorityMiddlewareOpen)
|
||||||
g.Server().BindMiddleware("/admin/*/comm/*", BaseAuthorityMiddlewareComm)
|
g.Server().BindMiddleware("/admin/*/comm/*", BaseAuthorityMiddlewareComm)
|
||||||
g.Server().BindMiddleware("/admin/*", BaseAuthorityMiddleware)
|
g.Server().BindMiddleware("/admin/*", BaseAuthorityMiddleware)
|
||||||
g.Server().BindMiddleware("/*", AutoI18n)
|
// g.Server().BindMiddleware("/*", AutoI18n)
|
||||||
g.Server().BindMiddleware("/*", MiddlewareCORS)
|
g.Server().BindMiddleware("/*", MiddlewareCORS)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ type Task struct {
|
|||||||
*cool.Model
|
*cool.Model
|
||||||
PlayerID uint64 `gorm:"not null;index:idx_task_by_player_id;comment:'所属玩家ID'" json:"player_id"`
|
PlayerID uint64 `gorm:"not null;index:idx_task_by_player_id;comment:'所属玩家ID'" json:"player_id"`
|
||||||
TaskID uint32 `gorm:"not null;comment:'任务ID'" json:"task_id"`
|
TaskID uint32 `gorm:"not null;comment:'任务ID'" json:"task_id"`
|
||||||
Data string `gorm:"type:text;not null;comment:'全部数据'" json:"data"`
|
Data string `gorm:"type:jsonb;not null;comment:'全部数据'" json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TaskEX 单个任务的详细信息,包含任务步骤状态和整体状态
|
// TaskEX 单个任务的详细信息,包含任务步骤状态和整体状态
|
||||||
|
|||||||
@@ -45,7 +45,10 @@ func (s *TaskService) Exec(id uint32, t func(*model.TaskEX) bool) {
|
|||||||
}
|
}
|
||||||
gg.PlayerID = uint64(s.userid)
|
gg.PlayerID = uint64(s.userid)
|
||||||
gg.TaskID = id
|
gg.TaskID = id
|
||||||
m1.Save(gg)
|
_, err := m1.Save(gg)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ func delChildDict(id int64) error {
|
|||||||
func NewDictInfoService() *DictInfoService {
|
func NewDictInfoService() *DictInfoService {
|
||||||
return &DictInfoService{
|
return &DictInfoService{
|
||||||
&cool.Service{
|
&cool.Service{
|
||||||
|
UniqueKey: map[string]string{"name": "名称不能重复"},
|
||||||
Model: model.NewDictInfo(),
|
Model: model.NewDictInfo(),
|
||||||
ListQueryOp: &cool.QueryOp{
|
ListQueryOp: &cool.QueryOp{
|
||||||
FieldEQ: []string{"typeId"},
|
FieldEQ: []string{"typeId"},
|
||||||
|
|||||||
@@ -445,10 +445,10 @@
|
|||||||
<NewSeIdx
|
<NewSeIdx
|
||||||
Idx="75" Stat="1" Eid="16" Args="5" />
|
Idx="75" Stat="1" Eid="16" Args="5" />
|
||||||
|
|
||||||
<NewSeIdx Idx="76" Stat="1" Eid="17" Args="0 200" />
|
<NewSeIdx Idx="76" Stat="1" Eid="17" Args="200" />
|
||||||
<NewSeIdx
|
<NewSeIdx
|
||||||
Idx="77" Stat="1" Eid="17" Args="0 375" />
|
Idx="77" Stat="1" Eid="17" Args="375" />
|
||||||
<NewSeIdx Idx="78" Stat="1" Eid="17" Args="0 5000" />
|
<NewSeIdx Idx="78" Stat="1" Eid="17" Args="5000" />
|
||||||
|
|
||||||
<NewSeIdx
|
<NewSeIdx
|
||||||
Idx="79" Stat="1" Eid="18" Args="" />
|
Idx="79" Stat="1" Eid="18" Args="" />
|
||||||
|
|||||||
10484
public/config/地图配置野怪.xml
10484
public/config/地图配置野怪.xml
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user