diff --git a/logic/service/fight/effect/effect_10-16_94_99_114.go b/logic/service/fight/effect/effect_10-16_94_99_114.go index 102da3fa4..5976a4a4e 100644 --- a/logic/service/fight/effect/effect_10-16_94_99_114.go +++ b/logic/service/fight/effect/effect_10-16_94_99_114.go @@ -29,10 +29,10 @@ func init() { func registerStatusEffects() { statusList := map[int]info.EnumBattleStatus{ - 10: info.PetStatus.Paralysis, - 11: info.PetStatus.Poisoned, - 12: info.PetStatus.Burned, - 13: info.PetStatus.DrainedHP, + 10: info.PetStatus.Paralysis, + 11: info.PetStatus.Poisoned, + 12: info.PetStatus.Burned, + //13: info.PetStatus.DrainedHP, 14: info.PetStatus.Frozen, 15: info.PetStatus.Fear, 16: info.PetStatus.Sleep, @@ -81,6 +81,7 @@ func (e *Effect10) OnSkill(ctx input.Ctx) bool { } eff.Duration(duration) + eff.SetArgs(ctx.Input) //输入参数是对方 ctx.AddEffect(eff) return true } diff --git a/logic/service/fight/effect/effect_13.go b/logic/service/fight/effect/effect_13.go new file mode 100644 index 000000000..a88579d41 --- /dev/null +++ b/logic/service/fight/effect/effect_13.go @@ -0,0 +1,42 @@ +package effect + +import ( + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" +) + +// ----------------------------------------------------------- +// 通用状态效果(例如 麻痹 / 中毒 / 疲惫 / 混乱 等) +// ----------------------------------------------------------- +type Effect13 struct { + node.EffectNode + Status info.EnumBattleStatus // 要施加的状态类型 + +} + +func init() { + input.InitEffect(input.EffectType.Skill, 13, &Effect13{}) +} + +// ----------------------------------------------------------- +// 技能触发时调用 +// ----------------------------------------------------------- +func (e *Effect13) OnSkill(ctx input.Ctx) bool { + if !e.Hit() { + return true + } + + duration := e.EffectNode.SideEffectArgs[0] + //duration++ + // 获取状态效果 + eff := input.Geteffect(input.EffectType.Status, int(info.PetStatus.DrainedHP)) + if eff == nil { + return true + } + + eff.Duration(duration) + eff.SetArgs(ctx.Input) + ctx.AddEffect(eff) + return true +} diff --git a/logic/service/fight/effect/effect_21.go b/logic/service/fight/effect/effect_21.go new file mode 100644 index 000000000..e0813ac6b --- /dev/null +++ b/logic/service/fight/effect/effect_21.go @@ -0,0 +1,71 @@ +package effect + +import ( + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + "sync" + + "github.com/shopspring/decimal" +) + +/** + * m~n回合每回合反弹对手1/k的伤害 + */ + +func init() { + input.InitEffect(input.EffectType.Skill, 21, &Effect21{}) + +} + +type Effect21 struct { + node.EffectNode + + l sync.Once +} + +// 使用技能时,不可被继承,继承Miss和Hit就行 +func (e *Effect21) OnSkill(input.Ctx) bool { + if !e.Hit() { + return true + } + e.l.Do(func() { //保证技能使用后初始化一次就行 + + statIndex := e.SideEffectArgs[0] + endindex := e.SideEffectArgs[1] + //回合产生 + n := int(e.Input.FightC.GetRand().Int31n(int32(endindex-statIndex+1))) + statIndex + e.Duration(n) //产生回合收益 + //e.Input.AddEffect(input.Geteffect(input.EffectType.Status, int(info.PetStatus.Tired))) + }) + + return true +} + +// 被攻击时候反弹 +func (e *Effect21) Skill_Use(ctx input.Ctx) bool { + + //未命中 + if !e.Hit() { + return true + } + //不是技能 + if ctx.SkillEntity == nil { + return true + } + //0血不触发 + if e.Input.CurrentPet.Info.Hp <= 0 { + return true + } + eff := input.Ctx{ + Input: e.Input, + + SelectSkillAction: nil, + DamageZone: &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: decimal.NewFromInt(int64(ctx.DamageZone.Damage.IntPart())).Div(decimal.NewFromInt(int64(e.SideEffectArgs[0]))), + }, + } + ctx.Input.Damage(eff) + return true +} diff --git a/logic/service/fight/effect/effect_39.go b/logic/service/fight/effect/effect_39.go new file mode 100644 index 000000000..58a49332d --- /dev/null +++ b/logic/service/fight/effect/effect_39.go @@ -0,0 +1,35 @@ +package effect + +import ( + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" +) + +/** + * n%降低对手所有技能m点PP值,然后若对手所选择的技能PP值为0则当回合对手无法行动 + */ + +func init() { + input.InitEffect(input.EffectType.Skill, 39, &Effect39{ + EffectNode: node.EffectNode{}, + }) + +} + +type Effect39 struct { + node.EffectNode +} + +func (e *Effect39) OnSkill(ctx input.Ctx) bool { + if !e.Hit() { + return true + } + // 概率判定 + ok, _, _ := e.Input.Player.Roll(e.SideEffectArgs[0], 100) + if !ok { + return true + } + + ctx.DelPP(e.SideEffectArgs[1]) + return true +} diff --git a/logic/service/fight/effect/effect_62.go b/logic/service/fight/effect/effect_62.go index abffb7c0f..8b98637c2 100644 --- a/logic/service/fight/effect/effect_62.go +++ b/logic/service/fight/effect/effect_62.go @@ -1,8 +1,11 @@ package effect import ( + "blazing/logic/service/fight/info" "blazing/logic/service/fight/input" "blazing/logic/service/fight/node" + + "github.com/shopspring/decimal" ) /** @@ -11,9 +14,37 @@ import ( type Effect62 struct { node.EffectNode Hide bool // 是否隐藏 正常是命中就可用,镇魂歌是回合数到才可用 + opp *input.Input + e *Effect62_1 +} +type Effect62_1 struct { + node.EffectNode + bindpet *info.BattlePetEntity + opp *input.Input + + // Hide bool // 是否隐藏 正常是命中就可用,镇魂歌是回合数到才可用 } +func (e *Effect62_1) OnSkill(ctx input.Ctx) bool { + defer e.Alive(false) + if e.bindpet == e.opp.CurrentPet { //说明对方没有切换精灵 + //直接扣除所有血量OnSkill + eff := input.Ctx{ + Input: e.Input, + + SelectSkillAction: nil, + DamageZone: &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: decimal.NewFromInt(int64(e.Input.CurrentPet.Info.MaxHp)), + }, + } + + e.opp.Damage(eff) + + } + return true +} func init() { t := &Effect62{ EffectNode: node.EffectNode{}, @@ -22,19 +53,20 @@ func init() { input.InitEffect(input.EffectType.Skill, 62, t) } - -func (e *Effect62) OnSkill(ctx input.Ctx) bool { - if !e.Hit() { - return true +func (e *Effect62) Turn_Start(ctx input.Ctx) { + if ctx.Player != e.Input.Player { + return } + if e.Duration() != 1 { //说明还没到生效节点 e.Hide = true //隐藏效果 } else { e.Hide = false } - if !e.Hide { //说明是自身回合//如果还在隐藏,就直接返回 + //t.Duration(e.SideEffectArgs[0]) + e.opp.AddEffect(e.e) //defer e.EffectNode.NotALive() //失效 //应该是对方固定伤害等于自身血量 //e.Input.Death() //本只死亡 @@ -42,24 +74,38 @@ func (e *Effect62) OnSkill(ctx input.Ctx) bool { //否则触发秒杀 在对面使用技能后 //return true } - return false +} +func (e *Effect62) OnSkill(ctx input.Ctx) bool { + if !e.Hit() { + e.Alive(false) + return true + } + e.opp = ctx.Input + e.e = &Effect62_1{ + EffectNode: node.EffectNode{}, + bindpet: ctx.CurrentPet, + opp: ctx.Input, + } + //给对方添加我方施加的buff + e.e.SetArgs(e.Input, e.SideEffectArgs...) + return true } // 默认添加回合 func (e *Effect62) SetArgs(t *input.Input, a ...int) { e.EffectNode.SetArgs(t, a...) - e.EffectNode.Duration(e.EffectNode.SideEffectArgs[0]) + e.EffectNode.Duration(e.EffectNode.SideEffectArgs[0] + 1) } -// 因为对方切精灵,这个效果也要无效掉 -func (this *Effect62) OnSwitchIn(input.Ctx) bool { - if this.Hide { //如果还在隐藏,就直接返回 - return true - } - //this.GetBattle().Effects[this.GetInput().UserID].RemoveEffect(this) - //否则触发秒杀 在对面使用技能后 - return true +// // 因为对方切精灵,这个效果也要无效掉 +// func (this *Effect62) OnSwitchIn(input.Ctx) bool { +// if this.Hide { //如果还在隐藏,就直接返回 +// return true +// } +// //this.GetBattle().Effects[this.GetInput().UserID].RemoveEffect(this) +// //否则触发秒杀 在对面使用技能后 +// return true -} +// } diff --git a/logic/service/fight/effect/effect_power_doblue.go b/logic/service/fight/effect/effect_power_doblue.go index 1788180e6..0c3e6d504 100644 --- a/logic/service/fight/effect/effect_power_doblue.go +++ b/logic/service/fight/effect/effect_power_doblue.go @@ -31,7 +31,7 @@ type Effect96 struct { StatusID int } -func (e *Effect96) Skill_Hit(opp *input.Ctx) bool { +func (e *Effect96) Skill_Hit(opp input.Ctx) bool { if f := statusFuncRegistry.Get(e.StatusID); f != nil && f(e.Input, opp.Input) { opp.Power *= 2 } @@ -70,6 +70,9 @@ func init() { registerStatusFunc(102, func(i, o *input.Input) bool { return i.StatEffect_Exist(int(info.PetStatus.Paralysis)) }) + registerStatusFunc(132, func(i, o *input.Input) bool { + return i.CurrentPet.Info.Hp < o.CurrentPet.Info.MaxHp + }) registerStatusFunc(168, func(i, o *input.Input) bool { return i.StatEffect_Exist(int(info.PetStatus.Sleep)) }) diff --git a/logic/service/fight/effect/effect_status.go b/logic/service/fight/effect/effect_status.go index 41cc0d30f..efe93905b 100644 --- a/logic/service/fight/effect/effect_status.go +++ b/logic/service/fight/effect/effect_status.go @@ -30,6 +30,9 @@ type StatusSleep struct { //睡眠不能出手 ,这个挂载到对面来实现 } func (e *StatusSleep) Skill_Use(ctx input.Ctx) bool { + if ctx.SkillEntity == nil { + return true + } if ctx.SkillEntity.Category() != info.Category.STATUS { t := e.Input.GetEffect(input.EffectType.Status, int(info.PetStatus.Sleep)) if t != nil { @@ -83,13 +86,13 @@ func init() { f.Status = t input.InitEffect(input.EffectType.Status, int(t), f) } - input.InitEffect(input.EffectType.Status, int(info.PetStatus.DrainHP), &DrainedHP{}) //寄生种子 - input.InitEffect(input.EffectType.Status, int(info.PetStatus.Poisoned), &DrainHP{}) //中毒 - input.InitEffect(input.EffectType.Status, int(info.PetStatus.Frozen), &DrainHP{}) //冻伤 - input.InitEffect(input.EffectType.Status, int(info.PetStatus.Burned), &DrainHP{}) //烧伤 - tt(info.PetStatus.Paralysis, &StatusNotSkill{}) //麻痹 - tt(info.PetStatus.Tired, &StatusNotSkill{}) //疲惫 - tt(info.PetStatus.Fear, &StatusNotSkill{}) //害怕 - tt(info.PetStatus.Petrified, &StatusNotSkill{}) //石化 - input.InitEffect(input.EffectType.Status, 8, &StatusSleep{}) //睡眠 + input.InitEffect(input.EffectType.Status, int(info.PetStatus.DrainedHP), &DrainedHP{}) //寄生种子 + input.InitEffect(input.EffectType.Status, int(info.PetStatus.Poisoned), &DrainHP{}) //中毒 + input.InitEffect(input.EffectType.Status, int(info.PetStatus.Frozen), &DrainHP{}) //冻伤 + input.InitEffect(input.EffectType.Status, int(info.PetStatus.Burned), &DrainHP{}) //烧伤 + tt(info.PetStatus.Paralysis, &StatusNotSkill{}) //麻痹 + tt(info.PetStatus.Tired, &StatusNotSkill{}) //疲惫 + tt(info.PetStatus.Fear, &StatusNotSkill{}) //害怕 + tt(info.PetStatus.Petrified, &StatusNotSkill{}) //石化 + input.InitEffect(input.EffectType.Status, 8, &StatusSleep{}) //睡眠 } diff --git a/logic/service/fight/fightc.go b/logic/service/fight/fightc.go index 3a1460846..8702f8751 100644 --- a/logic/service/fight/fightc.go +++ b/logic/service/fight/fightc.go @@ -242,15 +242,6 @@ func (f *FightC) Broadcast(t func(ff *input.Input)) { // 处理技能攻击逻辑 func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.SelectSkillAction) { - attacker.Exec(func(t input.Effect) bool { //计算命中 miss改命中 - - t.Skill_Hit_Pre(input.Ctx{ //调基础命中 - Input: defender, - SelectSkillAction: a, - }) //相当于先调整基础命中,不光调整命中,这里还能调整技能属性,暴击率 - - return true - }) a.AttackTimeC(attacker.GetProp(5, true)) //计算命中 defender.Exec(func(t input.Effect) bool { //计算闪避 ,然后修改对方命中),同时相当于计算属性无效这种 t.Skill_Hit_to(input.Ctx{ //计算命中后,我方强制改命中效果 @@ -361,10 +352,6 @@ func copyskill(t *action.SelectSkillAction) *action.SelectSkillAction { func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { - if f.closefight { //战斗结束 - - return - } // 伤害值 // 根据攻击方归属设置当前战斗的主/次攻击方属性 @@ -464,18 +451,18 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { } } - // canuseskillok := attacker.Exec(func(t input.Effect) bool { //这个是能否使用技能 - // //结算状态 - // //然后这里还可以处理自爆类 - // return t.Skill_Hit_Pre(input.Ctx{ - // Input: defender, - // SelectSkillAction: currentskill, - // }) //返回本身结算,如果false,说明不能使用技能了 + canuseskillok := attacker.Exec(func(t input.Effect) bool { //这个是能否使用技能 + //结算状态 + //然后这里还可以处理自爆类 + return t.Skill_Hit_Pre(input.Ctx{ + Input: defender, + SelectSkillAction: currentskill, + }) //返回本身结算,如果false,说明不能使用技能了 - // }) - //结算状态 - //然后这里还可以处理自爆类 - if canuseskill { //可以使用技能 + }) + // 结算状态 + // 然后这里还可以处理自爆类 + if canuseskill && canuseskillok { //可以使用技能 f.processSkillAttack(attacker, defender, currentskill) currentskill = oldskill @@ -491,7 +478,10 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { //技能使用后 defender.Exec(func(t input.Effect) bool { - t.Skill_Use(input.Ctx{Input: attacker, SelectSkillAction: currentskill}) + t.Skill_Use(input.Ctx{Input: attacker, SelectSkillAction: currentskill, DamageZone: &info.DamageZone{ + Type: info.DamageType.Red, + Damage: attacker.DamageZone.Damage, + }}) return true }) @@ -512,9 +502,26 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { "自身剩余血量:", attacker.CurrentPet.Info.Hp, "对手剩余血量:", defender.CurrentPet.Info.Hp, ) + if attacker.CurrentPet.Info.Hp <= 0 { + if defender.CurrentPet.Info.Hp == 0 { //先手方死亡,触发反同归于尽 + + defender.CurrentPet.Info.Hp = 1 + } + if f.IsWin(defender, attacker.CurrentPet.Info.CatchTime) { //然后检查是否战斗结束 + + f.FightOverInfo.WinnerId = defender.UserID + + f.closefight = true + break + } + } + if defender.CurrentPet.Info.Hp == 0 { - // defender.AttackValue.SkillID = 0 - //todo 解耦成战斗循环defer + if attacker.CurrentPet.Info.Hp == 0 { //先手方死亡,触发反同归于尽 + + attacker.CurrentPet.Info.Hp = 1 + } + defender.CanChange = true //被打死就可以切精灵了 if f.IsWin(attacker, defender.CurrentPet.Info.CatchTime) { //然后检查是否战斗结束 var WinnerId uint32 @@ -526,7 +533,7 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { f.FightOverInfo.WinnerId = WinnerId f.closefight = true - + break } } @@ -547,11 +554,11 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { }) return true }) - f.First.AttackValue.RemainHp = int32(f.First.CurrentPet.Info.Hp) - f.First.AttackValue.SkillList = f.First.CurrentPet.Info.SkillList + f.First.RemainHp = int32(f.First.CurrentPet.Info.Hp) + f.First.SkillList = f.First.CurrentPet.Info.SkillList - f.Second.AttackValue.SkillList = f.Second.CurrentPet.Info.SkillList - f.Second.AttackValue.RemainHp = int32(f.Second.CurrentPet.Info.Hp) + f.Second.SkillList = f.Second.CurrentPet.Info.SkillList + f.Second.RemainHp = int32(f.Second.CurrentPet.Info.Hp) ret := info.AttackValueS{ FAttack: *f.First.AttackValue, SAttack: *f.Second.AttackValue, @@ -586,3 +593,49 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { }) f.Switch = []*action.ActiveSwitchAction{} } + +// 处理战斗中宠物死亡后的逻辑(同归于尽+胜利判定) +// i=0 表示当前攻击者是先手方,i=1 表示当前攻击者是后手方 +func (f *FightC) handlePetDeath(attacker, defender *input.Input, i int) { + // 辅助函数:根据攻击者顺序获取胜利者ID + getWinnerID := func() uint32 { + if i == 0 { + // 若攻击者是先手方,胜利方为后手方(defender对应的玩家) + return defender.Player.GetInfo().UserID + } + // 若攻击者是后手方,胜利方为先手方(attacker对应的玩家) + return attacker.Player.GetInfo().UserID + } + + // 1. 处理攻击方宠物死亡的情况 + if attacker.CurrentPet.Info.Hp <= 0 { + // 同归于尽:攻击方死亡时,若防守方也死亡,给防守方留1点血 + if defender.CurrentPet.Info.Hp == 0 { + defender.CurrentPet.Info.Hp = 1 + } + + // 检查是否战斗结束(攻击方死亡后,判定防守方胜利) + if f.IsWin(defender, attacker.CurrentPet.Info.CatchTime) { + f.FightOverInfo.WinnerId = getWinnerID() + f.closefight = true + return // 战斗结束,提前返回 + } + } + + // 2. 处理防守方宠物死亡的情况(若战斗未结束) + if !f.closefight && defender.CurrentPet.Info.Hp == 0 { + // 同归于尽:防守方死亡时,若攻击方也死亡,给攻击方留1点血 + if attacker.CurrentPet.Info.Hp == 0 { + attacker.CurrentPet.Info.Hp = 1 + } + + // 防守方被击败,允许切换精灵 + defender.CanChange = true + + // 检查是否战斗结束(防守方死亡后,判定攻击方胜利) + if f.IsWin(attacker, defender.CurrentPet.Info.CatchTime) { + f.FightOverInfo.WinnerId = getWinnerID() + f.closefight = true + } + } +} diff --git a/logic/service/fight/input/fight.go b/logic/service/fight/input/fight.go index 1dc4c4c08..72bad74a6 100644 --- a/logic/service/fight/input/fight.go +++ b/logic/service/fight/input/fight.go @@ -48,7 +48,7 @@ func (u *Input) UseSkill(opp *Input, skill *action.SelectSkillAction) { func (u *Input) Heal(ac action.BattleActionI, value decimal.Decimal) { //使用道具回血 - if _, ok := ac.(*action.UseItemAction); !ok { + if _, ok := ac.(*action.UseItemAction); !ok && ac != nil { u.AttackValue.GainHp = int32(value.IntPart()) //道具有专门的回血包 } @@ -76,6 +76,18 @@ func (u *Input) HealPP(value int) { } +} +func (u *Input) DelPP(value int) { + + for i := 0; i < len(u.CurrentPet.Info.SkillList); i++ { + if uint32(value) > u.CurrentPet.Info.SkillList[i].PP { + u.CurrentPet.Info.SkillList[i].PP = 0 + } else { + u.CurrentPet.Info.SkillList[i].PP -= uint32(value) + } + + } + } // 伤害落实 // 血量扣减节点比如触发回神,反弹也在这里实现 diff --git a/logic/service/fight/input/node.go b/logic/service/fight/input/node.go index d577e7440..a423a12d7 100644 --- a/logic/service/fight/input/node.go +++ b/logic/service/fight/input/node.go @@ -126,7 +126,7 @@ func (c *Input) AddEffect(e Effect) { //如果效果相同,id相同,参数相同,就是同一个,确认是否可以叠加,正常来说本身就可以共存 //衰弱本身参数也是相同的,区别只是传入的回合数不一样和层数不一样 - if v.ID() == e.ID() && + if e.ID() != 0 && v.ID() == e.ID() && v.Alive() && equalInts(v.GetArgs(), e.GetArgs()) && v.MaxStack() != 0 { //如果层数可以叠加或者是无限层数 diff --git a/logic/service/fight/loop.go b/logic/service/fight/loop.go index 0c9a4505d..b76552bcb 100644 --- a/logic/service/fight/loop.go +++ b/logic/service/fight/loop.go @@ -23,9 +23,10 @@ func (f *FightC) battleLoop() { for { if f.closefight { + f.Broadcast(func(ff *input.Input) { //todo 将血量和技能pp传回enterturn - + //<-time.After(10000) ff.Player.SendFightEndInfo(f.FightOverInfo) }) @@ -37,9 +38,6 @@ func (f *FightC) battleLoop() { fmt.Printf("—— 第 %d 回合开始 ——\n", f.Round) actions := f.collectPlayerActions(ourID, oppID) - if f.closefight { - break - } f.resolveRound(actions[ourID], actions[oppID]) } diff --git a/logic/service/fight/node/node.go b/logic/service/fight/node/node.go index d2d25602d..06eb6c5c7 100644 --- a/logic/service/fight/node/node.go +++ b/logic/service/fight/node/node.go @@ -21,6 +21,7 @@ type EffectNode struct { Flag int //过滤掉的战斗类型 pvp pve boss战斗,野怪全部生效 alive bool // 是否失效 effect返回值是否被取消,是否被删除 hit bool + //增加owner target,如果owner target都为自身,就回合效果结束后再使用回合效果 }