```
refactor(fight): 重构战斗逻辑中技能实体传递方式 将战斗逻辑中使用的 action.SelectSkillAction 替换为 info.SkillEntity, 以统一技能数据结构。同时更新相关函数签名和字段引用。 此外,移除了未使用的 Attack 字段,并调整了部分逻辑实现以提高代码清晰度。 还修复了 effect_power_doblue.go 中对输入参数的错误引用问题。 最后,修改了通道命名规范(ActionChan -> actionChan, GetActionChan -> GetOverChan), 并引入 overchan 用于战斗结束通知,提升并发安全性与语义明确性。 ```
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"blazing/logic/service/fight/action"
|
||||
"blazing/logic/service/fight/info"
|
||||
"math/rand"
|
||||
)
|
||||
@@ -19,5 +18,5 @@ type FightI interface {
|
||||
UseItem(c PlayerI, cacthid, itemid uint32)
|
||||
CanEscape() bool
|
||||
IsFirst(c PlayerI) bool
|
||||
GetActionChan() chan action.BattleActionI
|
||||
GetOverChan() chan struct{}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ type SelectSkillAction struct {
|
||||
BaseAction
|
||||
*info.SkillEntity // 使用的技能
|
||||
//PetInfo *info.BattlePetEntity // 使用技能的宠物
|
||||
Attack info.AttackValue
|
||||
//Attack info.AttackValue
|
||||
}
|
||||
|
||||
// Priority 返回动作优先级
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package action
|
||||
|
||||
func CanUse(s *SelectSkillAction) bool {
|
||||
import "blazing/logic/service/fight/info"
|
||||
|
||||
func CanUse(s *info.SkillEntity) bool {
|
||||
if s == nil {
|
||||
return false
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ func (e *Effect117) OnSkill(ctx input.Ctx) bool {
|
||||
return true
|
||||
}
|
||||
duration := int(e.Input.FightC.GetRand().Int31n(2)) // 默认随机 1~3 回合
|
||||
duration++
|
||||
|
||||
eff.Duration(duration)
|
||||
ctx.AddEffect(eff)
|
||||
}
|
||||
|
||||
@@ -62,19 +62,19 @@ func init() {
|
||||
return false
|
||||
})
|
||||
registerStatusFunc(96, func(i, o *input.Input) bool {
|
||||
return i.StatEffect_Exist(int(info.PetStatus.Burned))
|
||||
return o.StatEffect_Exist(int(info.PetStatus.Burned))
|
||||
})
|
||||
registerStatusFunc(97, func(i, o *input.Input) bool {
|
||||
return i.StatEffect_Exist(int(info.PetStatus.Frozen))
|
||||
return o.StatEffect_Exist(int(info.PetStatus.Frozen))
|
||||
})
|
||||
registerStatusFunc(102, func(i, o *input.Input) bool {
|
||||
return i.StatEffect_Exist(int(info.PetStatus.Paralysis))
|
||||
return o.StatEffect_Exist(int(info.PetStatus.Paralysis))
|
||||
})
|
||||
registerStatusFunc(132, func(i, o *input.Input) bool {
|
||||
return i.CurrentPet.Info.Hp < o.CurrentPet.Info.MaxHp
|
||||
return i.CurrentPet.Info.Hp < o.CurrentPet.Info.Hp
|
||||
})
|
||||
registerStatusFunc(168, func(i, o *input.Input) bool {
|
||||
return i.StatEffect_Exist(int(info.PetStatus.Sleep))
|
||||
return o.StatEffect_Exist(int(info.PetStatus.Sleep))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ type FightC struct {
|
||||
|
||||
rand *rand.Rand
|
||||
StartTime time.Time
|
||||
ActionChan chan action.BattleActionI // 所有操作统一从这里进入
|
||||
actionChan chan action.BattleActionI // 所有操作统一从这里进入
|
||||
Round int //回合数
|
||||
|
||||
overchan chan struct{}
|
||||
First *input.Input
|
||||
Second *input.Input
|
||||
closefight bool
|
||||
@@ -170,7 +170,7 @@ func (f *FightC) initplayer(c common.PlayerI, opp bool) bool {
|
||||
func NewFight(mode, status info.EnumBattleMode, p1 common.PlayerI, p2 common.PlayerI) *FightC {
|
||||
f := &FightC{}
|
||||
f.ownerID = p1.GetInfo().UserID
|
||||
|
||||
f.overchan = make(chan struct{})
|
||||
f.StartTime = time.Now()
|
||||
seed := f.StartTime.UnixNano() ^ int64(p1.GetInfo().UserID) ^ int64(p2.GetInfo().UserID) // ^ int64(f.Round) // 用异或运算混合多维度信息
|
||||
f.rand = rand.New(rand.NewSource(seed))
|
||||
@@ -240,13 +240,13 @@ func (f *FightC) Broadcast(t func(ff *input.Input)) {
|
||||
}
|
||||
|
||||
// 处理技能攻击逻辑
|
||||
func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.SelectSkillAction) {
|
||||
func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *info.SkillEntity) {
|
||||
|
||||
a.AttackTimeC(attacker.GetProp(5, true)) //计算命中
|
||||
defender.Exec(func(t input.Effect) bool { //计算闪避 ,然后修改对方命中),同时相当于计算属性无效这种
|
||||
t.Skill_Hit_to(input.Ctx{ //计算命中后,我方强制改命中效果
|
||||
Input: attacker,
|
||||
SelectSkillAction: a,
|
||||
Input: attacker,
|
||||
SkillEntity: a,
|
||||
})
|
||||
|
||||
return true
|
||||
@@ -256,8 +256,8 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.S
|
||||
attacker.Exec(func(t input.Effect) bool { //计算命中 miss改命中
|
||||
|
||||
t.Calculate_Pre(input.Ctx{ //计算视为效果
|
||||
Input: defender,
|
||||
SelectSkillAction: a,
|
||||
Input: defender,
|
||||
SkillEntity: a,
|
||||
}) //相当于先调整基础命中,不光调整命中,这里还能调整技能属性,暴击率
|
||||
|
||||
return true
|
||||
@@ -265,8 +265,8 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.S
|
||||
attacker.Exec(func(t input.Effect) bool { //计算命中 miss改命中
|
||||
|
||||
t.Skill_Hit(input.Ctx{ //计算变威力
|
||||
Input: defender,
|
||||
SelectSkillAction: a,
|
||||
Input: defender,
|
||||
SkillEntity: a,
|
||||
}) //相当于先调整基础命中,不光调整命中,这里还能调整技能属性,暴击率
|
||||
|
||||
return true
|
||||
@@ -281,15 +281,15 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.S
|
||||
attacker.CalculateCrit(defender, a) //暴击计算
|
||||
attacker.AttackValue.IsCritical = a.Crit
|
||||
|
||||
attacker.DamageZone.Damage = attacker.CalculatePower(defender, a.SkillEntity)
|
||||
attacker.DamageZone.Damage = attacker.CalculatePower(defender, a)
|
||||
//睡眠受击消除
|
||||
|
||||
if attacker.AttackValue.IsCritical == 1 {
|
||||
//暴击破防
|
||||
if a.SkillEntity.Category() == info.Category.PHYSICAL && defender.Prop[1] > 0 {
|
||||
if a.Category() == info.Category.PHYSICAL && defender.Prop[1] > 0 {
|
||||
|
||||
defender.Prop[1] = 0
|
||||
} else if a.SkillEntity.Category() == info.Category.SPECIAL && defender.Prop[3] > 0 {
|
||||
} else if a.Category() == info.Category.SPECIAL && defender.Prop[3] > 0 {
|
||||
defender.Prop[3] = 0
|
||||
}
|
||||
|
||||
@@ -313,9 +313,9 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.S
|
||||
attacker.Exec(func(t input.Effect) bool {
|
||||
|
||||
t.OnSkill(input.Ctx{
|
||||
Input: defender,
|
||||
SelectSkillAction: a,
|
||||
DamageZone: &info.DamageZone{}, //给个空的,方便传递
|
||||
Input: defender,
|
||||
SkillEntity: a,
|
||||
DamageZone: &info.DamageZone{}, //给个空的,方便传递
|
||||
}) //调用伤害计算
|
||||
|
||||
return true
|
||||
@@ -325,7 +325,7 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.S
|
||||
|
||||
Input: attacker,
|
||||
|
||||
SelectSkillAction: a,
|
||||
SkillEntity: a,
|
||||
DamageZone: &info.DamageZone{
|
||||
Type: info.DamageType.Red,
|
||||
Damage: attacker.DamageZone.Damage,
|
||||
@@ -342,11 +342,11 @@ func IsNil(x interface{}) bool {
|
||||
rv := reflect.ValueOf(x)
|
||||
return rv.Kind() == reflect.Ptr && rv.IsNil()
|
||||
}
|
||||
func copyskill(t *action.SelectSkillAction) *action.SelectSkillAction {
|
||||
func copyskill(t *info.SkillEntity) *info.SkillEntity {
|
||||
|
||||
oldskill, _ := deepcopy.Anything(t) //备份技能
|
||||
|
||||
return oldskill.(*action.SelectSkillAction)
|
||||
return oldskill.(*info.SkillEntity)
|
||||
}
|
||||
|
||||
//回合有先手方和后手方,同时有攻击方和被攻击方
|
||||
@@ -425,40 +425,37 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
|
||||
})
|
||||
//开始回合操作
|
||||
for i := 0; i < 2; i++ {
|
||||
var oldskill *action.SelectSkillAction //原始技能
|
||||
var currentskill *action.SelectSkillAction //当前技能
|
||||
if i == 0 { //
|
||||
var oldskill *info.SkillEntity //原始技能
|
||||
var currentskill *info.SkillEntity //当前技能
|
||||
if i == 0 { //
|
||||
attacker, defender = f.First, f.Second
|
||||
oldskill = copyskill(fattack)
|
||||
currentskill = fattack
|
||||
oldskill = copyskill(fattack.SkillEntity)
|
||||
|
||||
} else {
|
||||
attacker, defender = f.Second, f.First
|
||||
oldskill = copyskill(sattack)
|
||||
currentskill = sattack
|
||||
oldskill = copyskill(sattack.SkillEntity)
|
||||
|
||||
}
|
||||
|
||||
currentskill = oldskill
|
||||
currentskill.Rand = f.rand
|
||||
fmt.Println("开始攻击", oldskill.Power)
|
||||
canuseskill := true
|
||||
// 实际上攻击方 还有系统选择放弃出手的
|
||||
if IsNil(currentskill) || attacker.CurrentPet.Info.Hp <= 0 {
|
||||
if !action.CanUse(currentskill) || attacker.CurrentPet.Info.Hp <= 0 {
|
||||
|
||||
// attacker.AttackValue.SkillID = 0
|
||||
canuseskill = false
|
||||
|
||||
} else {
|
||||
if !action.CanUse(currentskill) {
|
||||
// attacker.AttackValue.SkillID = 0
|
||||
canuseskill = false
|
||||
}
|
||||
}
|
||||
|
||||
canuseskillok := attacker.Exec(func(t input.Effect) bool { //这个是能否使用技能
|
||||
//结算状态
|
||||
//然后这里还可以处理自爆类
|
||||
return t.Skill_Hit_Pre(input.Ctx{
|
||||
Input: defender,
|
||||
SelectSkillAction: currentskill,
|
||||
DamageZone: &info.DamageZone{},
|
||||
Input: defender,
|
||||
SkillEntity: currentskill,
|
||||
DamageZone: &info.DamageZone{},
|
||||
}) //返回本身结算,如果false,说明不能使用技能了
|
||||
|
||||
})
|
||||
@@ -468,6 +465,8 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
|
||||
|
||||
f.processSkillAttack(attacker, defender, currentskill)
|
||||
currentskill = oldskill
|
||||
fmt.Println("结束攻击1", oldskill.Power)
|
||||
fmt.Println("结束攻击", currentskill.Power)
|
||||
_, skill, ok := utils.FindWithIndex(attacker.CurrentPet.Info.SkillList, func(item model.SkillInfo) bool {
|
||||
return item.ID == currentskill.Info.ID
|
||||
})
|
||||
@@ -480,7 +479,7 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
|
||||
|
||||
//技能使用后
|
||||
defender.Exec(func(t input.Effect) bool {
|
||||
t.Skill_Use(input.Ctx{Input: attacker, SelectSkillAction: currentskill, DamageZone: &info.DamageZone{
|
||||
t.Skill_Use(input.Ctx{Input: attacker, SkillEntity: currentskill, DamageZone: &info.DamageZone{
|
||||
Type: info.DamageType.Red,
|
||||
Damage: attacker.DamageZone.Damage,
|
||||
}})
|
||||
@@ -490,7 +489,7 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
|
||||
|
||||
//技能使用后
|
||||
attacker.Exec(func(t input.Effect) bool { //技能使用后的我方效果
|
||||
t.Skill_Useed(input.Ctx{Input: defender, SelectSkillAction: currentskill, DamageZone: &info.DamageZone{
|
||||
t.Skill_Useed(input.Ctx{Input: defender, SkillEntity: currentskill, DamageZone: &info.DamageZone{
|
||||
Type: info.DamageType.Red,
|
||||
Damage: attacker.DamageZone.Damage,
|
||||
}})
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"blazing/logic/service/fight/action"
|
||||
"blazing/logic/service/fight/info"
|
||||
)
|
||||
|
||||
type Ctx struct {
|
||||
*Input //施加方
|
||||
*action.SelectSkillAction //action本身
|
||||
*Input //施加方
|
||||
*info.SkillEntity //action本身
|
||||
|
||||
*info.DamageZone //伤害
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
// 计算暴击
|
||||
func (u *Input) CalculateCrit(opp *Input, skill *action.SelectSkillAction) {
|
||||
func (u *Input) CalculateCrit(opp *Input, skill *info.SkillEntity) {
|
||||
|
||||
skill.Crit = 0
|
||||
if skill.Category() == info.Category.STATUS { //属性技能不用算暴击
|
||||
|
||||
@@ -84,14 +84,8 @@ func (c *Input) GetEffect(etype EnumEffectType, id int) Effect {
|
||||
return nil
|
||||
}
|
||||
func (c *Input) StatEffect_Exist(id int) bool {
|
||||
for _, v := range c.Effects {
|
||||
if v.ID()+int(EffectType.Status) == id && v.Alive() {
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false
|
||||
return c.GetEffect(EffectType.Status, id-int(EffectType.Status)) != nil
|
||||
}
|
||||
func (c *Input) StatEffect_Exist_all() bool {
|
||||
for _, v := range c.Effects {
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
func (f *FightC) battleLoop() {
|
||||
f.ActionChan = make(chan action.BattleActionI, 2)
|
||||
f.actionChan = make(chan action.BattleActionI, 2)
|
||||
fmt.Println("战斗开始精灵", f.Our.Player.GetInfo().PetList[0].CatchTime)
|
||||
|
||||
ourID := f.Our.Player.GetInfo().UserID
|
||||
@@ -30,7 +30,8 @@ func (f *FightC) battleLoop() {
|
||||
ff.Player.SendFightEndInfo(f.FightOverInfo)
|
||||
|
||||
})
|
||||
close(f.ActionChan)
|
||||
close(f.actionChan)
|
||||
close(f.overchan)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -52,7 +53,7 @@ func (f *FightC) collectPlayerActions(ourID, oppID uint32) map[uint32]action.Bat
|
||||
|
||||
for len(actions) < 2 {
|
||||
select {
|
||||
case paction, ok := <-f.ActionChan:
|
||||
case paction, ok := <-f.actionChan:
|
||||
if !ok || f.closefight {
|
||||
return actions
|
||||
}
|
||||
@@ -247,8 +248,7 @@ func (f *FightC) getPlayerByID(id uint32) common.PlayerI {
|
||||
}
|
||||
|
||||
// 根据玩家ID返回对应对象
|
||||
func (f *FightC) GetActionChan( ) chan action.BattleActionI {
|
||||
|
||||
return f.ActionChan
|
||||
func (f *FightC) GetOverChan() chan struct{} {
|
||||
|
||||
return f.overchan
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ func (f *FightC) Over(c common.PlayerI, res info.EnumBattleOverReason) {
|
||||
Reason: res,
|
||||
}
|
||||
|
||||
f.ActionChan <- ret
|
||||
f.actionChan <- ret
|
||||
}
|
||||
|
||||
// 切换精灵 主动和被驱逐
|
||||
@@ -77,7 +77,7 @@ func (f *FightC) ChangePet(c common.PlayerI, id uint32) {
|
||||
|
||||
return true
|
||||
})
|
||||
f.ActionChan <- ret
|
||||
f.actionChan <- ret
|
||||
}
|
||||
|
||||
// 玩家使用技能
|
||||
@@ -98,7 +98,7 @@ func (f *FightC) UseSkill(c common.PlayerI, id int32) {
|
||||
}
|
||||
|
||||
}
|
||||
f.ActionChan <- ret
|
||||
f.actionChan <- ret
|
||||
}
|
||||
|
||||
// 玩家使用技能
|
||||
@@ -107,7 +107,7 @@ func (f *FightC) Capture(c common.PlayerI, id uint32) {
|
||||
cool.Loger.Debug(context.Background(), " 战斗chan已关闭")
|
||||
return
|
||||
}
|
||||
f.ActionChan <- &action.UseItemAction{BaseAction: action.NewBaseAction(c.GetInfo().UserID), ItemID: id}
|
||||
f.actionChan <- &action.UseItemAction{BaseAction: action.NewBaseAction(c.GetInfo().UserID), ItemID: id}
|
||||
}
|
||||
|
||||
func (f *FightC) UseItem(c common.PlayerI, cacthid, itemid uint32) {
|
||||
@@ -115,7 +115,7 @@ func (f *FightC) UseItem(c common.PlayerI, cacthid, itemid uint32) {
|
||||
cool.Loger.Debug(context.Background(), " 战斗chan已关闭")
|
||||
return
|
||||
}
|
||||
f.ActionChan <- &action.UseItemAction{BaseAction: action.NewBaseAction(c.GetInfo().UserID), ItemID: itemid, CacthTime: cacthid}
|
||||
f.actionChan <- &action.UseItemAction{BaseAction: action.NewBaseAction(c.GetInfo().UserID), ItemID: itemid, CacthTime: cacthid}
|
||||
}
|
||||
|
||||
// 战斗准备
|
||||
|
||||
@@ -331,7 +331,7 @@ func (p *Player) Save() {
|
||||
}()
|
||||
p.FightC.Over(p, info.BattleOverReason.PlayerOffline) //玩家逃跑,但是不能锁线程
|
||||
}()
|
||||
<-p.FightC.GetActionChan() //等待结束
|
||||
<-p.FightC.GetOverChan() //等待结束
|
||||
}
|
||||
p.Info.TimeToday = p.Info.TimeToday + uint32(time.Now().Unix()) - uint32(p.Onlinetime) //保存电池时间
|
||||
p.Onlinetime = uint32(time.Now().Unix())
|
||||
|
||||
Reference in New Issue
Block a user