diff --git a/logic/service/common/fight.go b/logic/service/common/fight.go index a260cf07..cfdbd8bd 100644 --- a/logic/service/common/fight.go +++ b/logic/service/common/fight.go @@ -15,4 +15,6 @@ type FightI interface { Capture(c PlayerI, id uint32) GetRand() *rand.Rand LoadPercent(c PlayerI, percent int32) + + IsFirst(c PlayerI) bool } diff --git a/logic/service/fight/action/BattleAction.go b/logic/service/fight/action/BattleAction.go index 67f79a30..3acb475d 100644 --- a/logic/service/fight/action/BattleAction.go +++ b/logic/service/fight/action/BattleAction.go @@ -13,17 +13,16 @@ type EnumPlayerOperation int // 定义读秒倒计时期间玩家可执行的操作枚举 var PlayerOperations = enum.New[struct { - SystemGiveUp EnumPlayerOperation `enum:"-1"` // 系统选择放弃出手(比如没有PP) - SelectSkill EnumPlayerOperation `enum:"0"` // 选择技能-6到6 - ActiveSwitch EnumPlayerOperation `enum:"2"` // 主动切换(中切) - UsePotion EnumPlayerOperation `enum:"3"` // 使用药剂(捕捉、逃跑等) - Escape EnumPlayerOperation `enum:"4"` // 逃跑(等级最高,以及掉线) - PlayerOffline EnumPlayerOperation `enum:"5"` // 玩家掉线 + //SystemGiveUp EnumPlayerOperation `enum:"-1"` // 系统选择放弃出手(比如没有PP) + //系统放弃出手就是SKILL ID=0 + SelectSkill EnumPlayerOperation `enum:"0"` // 选择技能-6到6 + ActiveSwitch EnumPlayerOperation `enum:"2"` // 主动切换(中切) + UsePotion EnumPlayerOperation `enum:"3"` // 使用药剂(捕捉、逃跑等) + Escape EnumPlayerOperation `enum:"4"` // 逃跑(等级最高,以及掉线) + PlayerOffline EnumPlayerOperation `enum:"5"` // 玩家掉线 // BeExpelledSwitch EnumPlayerOperation `enum:"6"` // 被驱逐切换 }]() - - // BattleActionI 战斗动作接口 type BattleActionI interface { GetPlayerID() uint32 @@ -33,14 +32,10 @@ type BattleActionI interface { // SelectSkillAction 选择技能的战斗动作 type SelectSkillAction struct { - PlayerID uint32 // 玩家ID - Skill *info.SkillEntity // 使用的技能 - PetInfo *info.BattlePetEntity // 使用技能的宠物 - Attack info.AttackValue -} - -func (s *SelectSkillAction) GetPlayerID() uint32 { - return s.PlayerID + BaseAction + Skill *info.SkillEntity // 使用的技能 + //PetInfo *info.BattlePetEntity // 使用技能的宠物 + Attack info.AttackValue } // Priority 返回动作优先级 @@ -126,18 +121,6 @@ func (e *OverTimeAction) Priority() int { return int(PlayerOperations.PlayerOffline) } -// SystemGiveUpAction 系统强制放弃出手的动作 -type SystemGiveUpAction struct { - BaseAction - Reason string // 放弃原因(如没有PP值、宠物全部倒下等) - LastPet info.BattlePetEntity // 最后在场的宠物 -} - -// Priority 返回动作优先级 -func (s *SystemGiveUpAction) Priority() int { - return int(PlayerOperations.SystemGiveUp) -} - // PlayerOfflineAction 玩家掉线的战斗动作 type PlayerOfflineAction struct { BaseAction diff --git a/logic/service/fight/fightc.go b/logic/service/fight/fightc.go index b4b91b73..9b312045 100644 --- a/logic/service/fight/fightc.go +++ b/logic/service/fight/fightc.go @@ -1,7 +1,6 @@ package fight import ( - "blazing/common/data/xmlres" "blazing/logic/service/common" "blazing/logic/service/fight/action" "blazing/logic/service/fight/info" @@ -78,6 +77,17 @@ func (f *FightC) GetRand() *rand.Rand { } +// 获取随机数 +func (f *FightC) IsFirst(play common.PlayerI) bool { + + if f.First.Player == play { + + return true + + } + return false +} + // 加载进度 func (f *FightC) LoadPercent(c common.PlayerI, percent int32) { f.GetInputByPlayer(c, true).Player.SendLoadPercent(info.LoadPercentOutboundInfo{ @@ -323,8 +333,8 @@ func (f *FightC) battleLoop() { f.closefight = true case *action.ActiveSwitchAction: //切换上场的,切换方放弃出手 - f.enterturn(BattleActionI[1], - &action.SystemGiveUpAction{BaseAction: action.NewBaseAction(BattleActionI[0].GetPlayerID())}) //切换,相当于后手直接出手 + f.enterturn(BattleActionI[1].(*action.SelectSkillAction), + &action.SelectSkillAction{BaseAction: action.NewBaseAction(BattleActionI[0].GetPlayerID())}) //切换,相当于后手直接出手 case *action.UseItemAction: //使用道具 //fmt.Println(faction.ItemID) @@ -333,7 +343,7 @@ func (f *FightC) battleLoop() { case faction.ItemID >= 30001 && faction.ItemID <= 300010: //胶囊 //todo 将血量和技能pp传回enterturn - tt, ok := f.Our.Player.(*player.Player) + //tt, ok := f.Our.Player.(*player.Player) mo, ism := f.Opp.Player.(*player.AI_player) if ok && ism && mo.CanCapture { //如果获取玩家 @@ -369,11 +379,11 @@ func (f *FightC) battleLoop() { // 其他情况 fmt.Println("ItemID 不在指定范围内") } - f.enterturn(BattleActionI[1], &action.SystemGiveUpAction{BaseAction: action.NewBaseAction(BattleActionI[0].GetPlayerID())}) //切换,相当于后手直接出手 + f.enterturn(BattleActionI[1].(*action.SelectSkillAction), &action.SelectSkillAction{BaseAction: action.NewBaseAction(BattleActionI[0].GetPlayerID())}) //切换,相当于后手直接出手 default: //选择技能或者放弃出手 //回合前操作,比如挂载buff - f.enterturn(BattleActionI[0], BattleActionI[1]) + f.enterturn(BattleActionI[0].(*action.SelectSkillAction), BattleActionI[1].(*action.SelectSkillAction)) //回合后操作 } @@ -382,67 +392,25 @@ func (f *FightC) battleLoop() { } -// 解析并 施加effect -func (f *FightC) parseskill(attacker, defender *input.Input, id *action.SelectSkillAction) { - temparg := id.Skill.SideEffectArgS - for _, v := range id.Skill.SideEffectS { - - t := input.Geteffect(input.EffectType.Skill, v) - - args := xmlres.EffectArgs[v] - if t.ID != 0 { - if t.Effect.GetOwner() { //如果取反,说明是给对方添加的回合效果 - //实际上,owner永远为反,说明是对方给我添加的 - t.Effect.SetArgs(attacker, temparg[:args]...) //设置入参,施加方永远是我方 - //给双方添加 - defender.AddEffect(t) - } else { - t.Effect.SetArgs(attacker, temparg[:args]...) //设置入参 - attacker.AddEffect(t) - } - } - - temparg = temparg[args:] - } -} - -func (f *FightC) initAttackers(fattack action.BattleActionI) { - // 伤害值 - - // 根据攻击方归属设置当前战斗的主/次攻击方属性 - - if fattack.GetPlayerID() == f.ownerID { - f.First, f.Second = f.Our, f.Opp // 攻击方为我方时,主攻击方是我方 - - } else { - f.First, f.Second = f.Opp, f.Our // 攻击方为对方时,主攻击方是对方 - - } - - fmt.Println("先手", f.First.CurrentPet.Info.CatchTime, "后手", f.Second.CurrentPet.Info.CatchTime) - - // TODO: 在这里调用技能结算逻辑 -} - // 处理技能攻击逻辑 func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.SelectSkillAction) { - f.parseskill(attacker, defender, a) //是否miss都应该施加解析effect - attacker.Exec(func(t input.Effect) bool { //计算命中 - t.Skill_Pre(input.Ctx{ + a.Skill.AttackTimeC(attacker.GetProp(5, true)) //计算命中 + + defender.Exec(func(t input.Effect) bool { //计算闪避 ,然后修改对方命中),同时相当于计算属性无效这种 + t.Skill_Hit_to(input.Ctx{ Input: attacker, - SkillEntity: a.Skill, - }) //相当于先调整基础命中,不光调整命中,这里还能调整技能属性,暴击率 + SkillEntity: a.Skill, //相当于先调整基础命中,不光调整命中,这里还能调整技能属性,暴击率 + }) return true }) + attacker.Exec(func(t input.Effect) bool { //计算命中 miss改命中 - a.Skill.AttackTimeC(attacker.GetProp(5, true)) //计算命中 - defender.Exec(func(t input.Effect) bool { //计算闪避 ,然后修改对方命中),同时相当于计算属性无效这种 - t.Skill_PreUse(input.Ctx{ + t.Skill_Hit(input.Ctx{ //计算变威力 Input: attacker, SkillEntity: a.Skill, - }) + }) //相当于先调整基础命中,不光调整命中,这里还能调整技能属性,暴击率 return true }) @@ -468,6 +436,7 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.S } attacker.Exec(func(t input.Effect) bool { + //这里实现应该参考本地技能是否命中,然后 t.Hit(true) //我方效果命中 return true @@ -510,24 +479,55 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.S //回合有先手方和后手方,同时有攻击方和被攻击方 -func (f *FightC) enterturn(fattack, sattack action.BattleActionI) { +func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { if f.closefight { //战斗结束 return } - f.initAttackers(fattack) //初始化先后手 - var attacker, defender *input.Input + // 伤害值 + + // 根据攻击方归属设置当前战斗的主/次攻击方属性 + + if fattack.GetPlayerID() == f.ownerID { + f.First, f.Second = f.Our, f.Opp // 攻击方为我方时,主攻击方是我方 + + } else { + f.First, f.Second = f.Opp, f.Our // 攻击方为对方时,主攻击方是对方 + + } + + fmt.Println("先手", f.First.CurrentPet.Info.CatchTime, "后手", f.Second.CurrentPet.Info.CatchTime) + + //是否miss都应该施加解析effect + f.First.Parseskill(f.Second, fattack) + + f.First.Exec(func(t input.Effect) bool { //回合开始前 + + //结算状态 + t.Compare_Pre(fattack, sattack) //先结算技能的优先级 + return true + }) + switch { + + case fattack.Skill.Priority < sattack.Skill.Priority: + + fattack, sattack = sattack, fattack //互换先手权 + case fattack.Skill.Priority == sattack.Skill.Priority: + + if f.Second.GetProp(4, false) > f.First.GetProp(4, false) { + fattack, sattack = sattack, fattack //互换先手权 + } + + } + + f.First.First = true + f.Second.First = false //开始回合操作 for i := 0; i < 2; i++ { var attackeraction action.BattleActionI - if i == 0 { // - attacker, defender = f.First, f.Second - attackeraction = fattack - attacker.First = true //先手技能 - - } else { + if i != 0 { attacker, defender = f.Second, f.First attackeraction = sattack attacker.First = false //先手技能 @@ -554,7 +554,7 @@ func (f *FightC) enterturn(fattack, sattack action.BattleActionI) { canuseskillok := attacker.Exec(func(t input.Effect) bool { //这个是能否使用技能 //结算状态 //然后这里还可以处理自爆类 - return t.Skill_Can(input.Ctx{ + return t.Skill_Hit_Pre(input.Ctx{ Input: attacker, SkillEntity: skill.Skill, }) //返回本身结算,如果false,说明不能使用技能了 diff --git a/logic/service/fight/info/BattlePetEntity.go b/logic/service/fight/info/BattlePetEntity.go index 24622005..abf07e6c 100644 --- a/logic/service/fight/info/BattlePetEntity.go +++ b/logic/service/fight/info/BattlePetEntity.go @@ -85,4 +85,3 @@ func (u *BattlePetEntity) Type() *element.ElementCombination { return ff } - diff --git a/logic/service/fight/input/effecti.go b/logic/service/fight/input/effecti.go index f7ad8d55..07013941 100644 --- a/logic/service/fight/input/effecti.go +++ b/logic/service/fight/input/effecti.go @@ -6,14 +6,17 @@ import ( ) type Effect interface { + Compare_Pre(fattack, sattack *action.SelectSkillAction) bool Fight_Start(ctx Ctx) bool //战斗开始 Turn_Start(ctx Ctx) //回合开始,注入特性 - Skill_Pre(ctx Ctx) //对技能修改,比如变威力 行动开始前,注入视为等参数在这里实现 - Skill_PreUse(ctx Ctx) // 技能命中前触发//预处理受击技能 被攻击方效果,比如受击时无效技能这样 - OnSkill(ctx Ctx) // 触发on miss onhit + //技能命中前的返回值代表是否可以出手 ,对命中本身的修改应该是对上下文本身的修改 + Skill_Hit_Pre(ctx Ctx) bool //对技能修改 行动开始前,注入视为等参数在这里实现 + Skill_Hit(ctx Ctx) bool //这是是命中后的对技能的修改,比如变威力 + Skill_Hit_to(ctx Ctx) bool // 技能命中前触发//预处理受击技能 被攻击方效果,比如受击时无效技能这样 + OnSkill(ctx Ctx) bool // 触发on miss onhit - Skill_Can(ctx Ctx) bool //使用技能 可以取消用技能节点 技能无效节点锁定伤害加上 + //Skill_Can(ctx Ctx) bool //使用技能 可以取消用技能节点 技能无效节点锁定伤害加上 Damage_ADD(ctx Ctx) bool // 攻击前触发 ,这时候就是+区间 Damage_Mul(ctx Ctx) bool // 攻击触发 diff --git a/logic/service/fight/input/fight.go b/logic/service/fight/input/fight.go index bcb6afd6..6c1db207 100644 --- a/logic/service/fight/input/fight.go +++ b/logic/service/fight/input/fight.go @@ -19,7 +19,7 @@ func (u *Input) UseSkill(opp *Input, skill *info.SkillEntity) { CritRate := utils.Max(skill.CritRate, 1) //CritAtkFirst: 先出手时必定致命一击; 默认: 0 - if skill.CritAtkFirst != 0 && u.First { + if skill.CritAtkFirst != 0 && u.FightC { CritRate = 16 } //CritAtkSecond: 后出手时必定致命一击; 默认: 0 diff --git a/logic/service/fight/input/input.go b/logic/service/fight/input/input.go index e228bf92..2b928e56 100644 --- a/logic/service/fight/input/input.go +++ b/logic/service/fight/input/input.go @@ -1,8 +1,10 @@ package input import ( + "blazing/common/data/xmlres" "blazing/common/utils" "blazing/logic/service/common" + "blazing/logic/service/fight/action" "blazing/logic/service/fight/info" "github.com/jinzhu/copier" @@ -10,11 +12,12 @@ import ( ) type Input struct { - CanChange bool //是否可以死亡切换CanChange - CurrentPet *info.BattlePetEntity //当前精灵 - AllPet []*info.BattlePetEntity - Player common.PlayerI - Finished bool //是否加载完成 + CanChange bool //是否可以死亡切换CanChange + CurrentPet *info.BattlePetEntity //当前精灵 + AllPet []*info.BattlePetEntity + Player common.PlayerI + EffectCache []Effect + Finished bool //是否加载完成 *info.AttackValue FightC common.FightI // info.BattleActionI @@ -32,7 +35,7 @@ type Input struct { //OldAttack int //攻击伤害被挡前伤害记录 } //伤害容器 - First bool //是否先手 + //First bool //是否先手 } func NewInput(c common.FightI, p common.PlayerI) *Input { @@ -97,3 +100,33 @@ func (i *Input) GetStatusBonus() float64 { return maxBonus } + +// 解析并 施加effect +func (i *Input) Parseskill(defender *Input, skill *action.SelectSkillAction) { + temparg := skill.Skill.SideEffectArgS + + for _, v := range skill.Skill.SideEffectS { + + t := Geteffect(EffectType.Skill, v) + + args := xmlres.EffectArgs[v] + if t.ID != 0 { + t.Effect.SetArgs(i, temparg[:args]...) //设置入参,施加方永远是我方 + + // if t.Effect.GetOwner() { //如果取反,说明是给对方添加的回合效果 + // //实际上,owner永远为反,说明是对方给我添加的 + // t.Effect.SetArgs(attacker, temparg[:args]...) //设置入参,施加方永远是我方 + // //给双方添加 + // defender.AddEffect(t) + // } else { + // t.Effect.SetArgs(attacker, temparg[:args]...) //设置入参 + // attacker.AddEffect(t) + // } + //ret = append(ret, t.Effect) + i.EffectCache = append(i.EffectCache, t.Effect) + } + + temparg = temparg[args:] + } + +} diff --git a/logic/service/fight/node/skill.go b/logic/service/fight/node/skill.go index 6b3c1d1e..42f2ed38 100644 --- a/logic/service/fight/node/skill.go +++ b/logic/service/fight/node/skill.go @@ -5,15 +5,15 @@ import ( "blazing/logic/service/fight/input" ) -func (e *EffectNode) Skill_Pre(ctx input.Ctx) { - +func (e *EffectNode) Skill_Pre(ctx input.Ctx) bool { + return true } -func (e *EffectNode) Skill_PreUse(ctx input.Ctx) { - +func (e *EffectNode) Skill_PreUse(ctx input.Ctx) bool { + return true } -func (e *EffectNode) OnSkill(ctx input.Ctx) { +func (e *EffectNode) OnSkill(ctx input.Ctx) bool { if e.Effect != nil { if e.Hit() { //没命中 e.OnHit(ctx.Input, ctx.SkillEntity) @@ -21,7 +21,7 @@ func (e *EffectNode) OnSkill(ctx input.Ctx) { e.OnMiss(ctx.Input, ctx.SkillEntity) } } - + return true } func (e *EffectNode) Skill_Can(ctx input.Ctx) bool { diff --git a/logic/service/fight/playeraction.go b/logic/service/fight/playeraction.go index adfb19a8..9ba26e5b 100644 --- a/logic/service/fight/playeraction.go +++ b/logic/service/fight/playeraction.go @@ -23,32 +23,6 @@ func (f *FightC) Compare(a, b action.BattleActionI) (action.BattleActionI, actio } else if p1 < 0 { return a, b } - _, ok := b.(*action.SystemGiveUpAction) - - if ok { - if _, ok := a.(*action.SystemGiveUpAction); ok { - return b, a - } - return a, b - } - - bskill := b.(*action.SelectSkillAction) - askill := a.(*action.SelectSkillAction) - // 如果是选择技能操作,进一步比较技能优先级和宠物属性 - - p2 := bskill.Skill.Priority - askill.Skill.Priority - if p2 > 0 { - return b, a - } else if p2 < 0 { - return a, b - } - - p2 = int(f.Opp.GetProp(4, false)) - int(f.Our.GetProp(4, false)) - if p2 > 0 { - return b, a - } else if p2 < 0 { - return a, b - } return a, b // 速度相同时,发起方优先 } @@ -108,16 +82,12 @@ func (f *FightC) ChangePet(c common.PlayerI, id uint32) { // 玩家使用技能 func (f *FightC) UseSkill(c common.PlayerI, id int32) { - if id == 0 { - f.actionChan <- &action.SystemGiveUpAction{BaseAction: action.NewBaseAction(c.GetInfo().UserID)} - return - } ret := &action.SelectSkillAction{ PlayerID: c.GetInfo().UserID, } - ret.PetInfo = f.GetInputByPlayer(c, false).CurrentPet + //ret.PetInfo = f.GetInputByPlayer(c, false).CurrentPet - for _, v := range ret.PetInfo.Skills { + for _, v := range f.GetInputByPlayer(c, false).CurrentPet.Skills { if v != nil && v.ID == int(id) { ret.Skill = v