diff --git a/logic/controller/pet_info.go b/logic/controller/pet_info.go index 380150ae9..13addf3d1 100644 --- a/logic/controller/pet_info.go +++ b/logic/controller/pet_info.go @@ -6,10 +6,43 @@ import ( "blazing/logic/service/fight" "blazing/logic/service/pet" "blazing/logic/service/player" - - "github.com/jinzhu/copier" + "blazing/modules/player/model" ) +func buildPetShortInfo(info model.PetInfo) pet.PetShortInfo { + return pet.PetShortInfo{ + ID: info.ID, + CatchTime: info.CatchTime, + Level: info.Level, + SkinID: info.SkinID, + ShinyLen: info.ShinyLen, + ShinyInfo: info.ShinyInfo, + } +} + +func buildPetListOutboundInfo(petList []model.Pet) *pet.GetPetListOutboundInfo { + result := &pet.GetPetListOutboundInfo{ + ShortInfoList: make([]pet.PetShortInfo, len(petList)), + } + for i := range petList { + result.ShortInfoList[i] = buildPetShortInfo(petList[i].Data) + } + return result +} + +func buildPetShowOutboundInfo(userID, flag uint32, info *model.PetInfo) *pet.PetShowOutboundInfo { + return &pet.PetShowOutboundInfo{ + UserID: userID, + CatchTime: info.CatchTime, + ID: info.ID, + Flag: flag, + Dv: info.Dv, + ShinyLen: info.ShinyLen, + ShinyInfo: info.ShinyInfo, + SkinID: info.SkinID, + } +} + // GetPetInfo 获取精灵信息 // data: 包含精灵捕获时间的输入信息 // player: 当前玩家对象 @@ -44,14 +77,7 @@ func (h Controller) GetPetList( data *pet.GetPetListInboundEmpty, player *player.Player) (result *pet.GetPetListOutboundInfo, err errorcode.ErrorCode) { - result = &pet.GetPetListOutboundInfo{} - - petList := player.Service.Pet.PetInfo(0) // 获取未放生的精灵 - result.ShortInfoList = make([]pet.PetShortInfo, len(petList)) - for i, petItem := range petList { - copier.Copy(&result.ShortInfoList[i], &petItem.Data) - } - return result, 0 + return buildPetListOutboundInfo(player.Service.Pet.PetInfo(0)), 0 } // GetPetReleaseList 获取放生列表 @@ -62,14 +88,7 @@ func (h Controller) GetPetReleaseList( data *pet.GetPetListFreeInboundEmpty, player *player.Player) (result *pet.GetPetListOutboundInfo, err errorcode.ErrorCode) { - result = &pet.GetPetListOutboundInfo{} - - petList := player.Service.Pet.PetInfo(1) // 获取已放生的精灵 - result.ShortInfoList = make([]pet.PetShortInfo, len(petList)) - for i, petItem := range petList { - copier.Copy(&result.ShortInfoList[i], &petItem.Data) - } - return result, 0 + return buildPetListOutboundInfo(player.Service.Pet.PetInfo(1)), 0 } // PetReleaseToWarehouse 将精灵从仓库包中放生 @@ -174,9 +193,7 @@ func (h Controller) PlayerShowPet( _, currentPet, ok := player.FindPet(data.CatchTime) if ok { - copier.Copy(&result, currentPet) - result.Flag = data.Flag - result.UserID = data.Head.UserID + result = buildPetShowOutboundInfo(data.Head.UserID, data.Flag, currentPet) defer player.GetSpace().Broadcast(player, data.Head.CMD, result) } return @@ -228,14 +245,9 @@ func (h Controller) PetFirst( func (h Controller) SetPetExp(data *pet.PetSetExpInboundInfo, player *player.Player) (result *pet.PetSetExpOutboundInfo, err errorcode.ErrorCode) { _, currentPet, found := player.FindPet(data.CatchTime) if found && currentPet.Level < 100 { - player.AddPetExp(currentPet, data.Exp) - return &pet.PetSetExpOutboundInfo{ - Exp: player.Info.ExpPool, - }, 0 + return &pet.PetSetExpOutboundInfo{Exp: player.Info.ExpPool}, 0 } - return &pet.PetSetExpOutboundInfo{ - Exp: player.Info.ExpPool, - }, errorcode.ErrorCodes.ErrSystemError + return &pet.PetSetExpOutboundInfo{Exp: player.Info.ExpPool}, errorcode.ErrorCodes.ErrSystemError } diff --git a/logic/service/fight/effect/1067_1071.go b/logic/service/fight/effect/1067_1071.go new file mode 100644 index 000000000..792a519cb --- /dev/null +++ b/logic/service/fight/effect/1067_1071.go @@ -0,0 +1,204 @@ +package effect + +import ( + "blazing/logic/service/fight/action" + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" +) + +// Effect 1067: {0}回合内每回合使用技能恢复自身最大体力的1/{1},恢复体力时若自身体力低于最大体力的1/{2}则恢复效果转变为吸取对手最大体力的1/{3} +type Effect1067 struct{ node.EffectNode } + +func (e *Effect1067) Skill_Use() bool { + if len(e.Args()) < 4 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1067, e.SideEffectArgs...) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1067Sub struct{ RoundEffectArg0Base } + +func (e *Effect1067Sub) OnSkill() bool { + if len(e.Args()) < 4 || e.Args()[1].Cmp(alpacadecimal.Zero) <= 0 { + return true + } + if e.Args()[2].Cmp(alpacadecimal.Zero) > 0 && e.Ctx().Our.CurrentPet.GetHP().Mul(e.Args()[2]).Cmp(e.Ctx().Our.CurrentPet.GetMaxHP()) < 0 && e.Args()[3].Cmp(alpacadecimal.Zero) > 0 { + damage := e.Ctx().Opp.CurrentPet.GetMaxHP().Div(e.Args()[3]) + if damage.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Percent, Damage: damage}) + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, damage) + } + return true + } + heal := e.Ctx().Our.CurrentPet.GetMaxHP().Div(e.Args()[1]) + if heal.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, heal) + } + return true +} + +// Effect 1068: 下{0}回合受到致命伤害时残留{1}点体力 +type Effect1068 struct{ node.EffectNode } + +func (e *Effect1068) Skill_Use() bool { + if len(e.Args()) < 2 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1068, int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1068Sub struct { + RoundEffectArg0Base + remainHP alpacadecimal.Decimal +} + +func (e *Effect1068Sub) SetArgs(t *input.Input, a ...int) { + e.RoundEffectArg0Base.SetArgs(t, a...) + if len(a) > 1 { + e.remainHP = alpacadecimal.NewFromInt(int64(a[1])) + } +} + +func (e *Effect1068Sub) DamageLockEx(zone *info.DamageZone) bool { + if zone == nil || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil { + return true + } + currentHP := e.Ctx().Our.CurrentPet.GetHP() + if currentHP.Cmp(e.remainHP) <= 0 || zone.Damage.Cmp(currentHP) < 0 { + return true + } + zone.Damage = currentHP.Sub(e.remainHP) + e.Alive(false) + return true +} + +// Effect 1069: 反转自身能力下降状态,反转成功则{0}回合内躲避所有攻击 +type Effect1069 struct{ node.EffectNode } + +func (e *Effect1069) Skill_Use() bool { + reversed := false + for i, v := range e.Ctx().Our.Prop[:] { + if v >= 0 { + continue + } + if e.Ctx().Our.SetProp(e.Ctx().Our, int8(i), -2*v) { + reversed = true + } + } + if !reversed || len(e.Args()) == 0 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1069, int(e.Args()[0].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1069Sub struct{ RoundEffectArg0Base } + +func (e *Effect1069Sub) SkillHit_ex() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + e.Ctx().SkillEntity.SetMiss() + return true +} + +// Effect 1070: 对手处于能力下降状态时自身先制+1 +type Effect1070 struct{ node.EffectNode } + +func (e *Effect1070) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if !e.Ctx().Opp.HasPropSub() { + return true + } + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current != nil && current.SkillEntity != nil { + current.SkillEntity.XML.Priority += 1 + } + return true +} + +// Effect 1071: {0}回合内若对手恢复体力(药剂恢复除外),则{1}回合内自身攻击附加{2}点固定伤害 +type Effect1071 struct{ node.EffectNode } + +func (e *Effect1071) Skill_Use() bool { + if len(e.Args()) < 3 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1071, e.SideEffectArgs...) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1071Sub struct{ RoundEffectArg0Base } + +func (e *Effect1071Sub) Heal_Pre(_ action.BattleActionI, value *int) bool { + if value == nil || *value <= 0 || len(e.Args()) < 3 { + return true + } + sub := e.Ctx().Opp.InitEffect(input.EffectType.Sub, 10711, int(e.Args()[1].IntPart()), int(e.Args()[2].IntPart())) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Opp, sub) + } + return true +} + +type Effect1071BoostSub struct { + node.EffectNode + remaining int + damage alpacadecimal.Decimal +} + +func (e *Effect1071BoostSub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + if len(a) > 0 { + e.remaining = a[0] + } + if len(a) > 1 { + e.damage = alpacadecimal.NewFromInt(int64(a[1])) + } +} + +func (e *Effect1071BoostSub) OnSkill() bool { + if e.remaining <= 0 || e.damage.Cmp(alpacadecimal.Zero) <= 0 { + e.Alive(false) + return true + } + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Fixed, Damage: e.damage}) + e.remaining-- + if e.remaining <= 0 { + e.Alive(false) + } + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1067, &Effect1067{}) + input.InitEffect(input.EffectType.Sub, 1067, &Effect1067Sub{}) + input.InitEffect(input.EffectType.Skill, 1068, &Effect1068{}) + input.InitEffect(input.EffectType.Sub, 1068, &Effect1068Sub{}) + input.InitEffect(input.EffectType.Skill, 1069, &Effect1069{}) + input.InitEffect(input.EffectType.Sub, 1069, &Effect1069Sub{}) + input.InitEffect(input.EffectType.Skill, 1070, &Effect1070{}) + input.InitEffect(input.EffectType.Skill, 1071, &Effect1071{}) + input.InitEffect(input.EffectType.Sub, 1071, &Effect1071Sub{}) + input.InitEffect(input.EffectType.Sub, 10711, &Effect1071BoostSub{}) +} diff --git a/logic/service/fight/effect/1117_1121.go b/logic/service/fight/effect/1117_1121.go new file mode 100644 index 000000000..8add3b162 --- /dev/null +++ b/logic/service/fight/effect/1117_1121.go @@ -0,0 +1,150 @@ +package effect + +import ( + "blazing/logic/service/fight/action" + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" +) + +// Effect 1117: 若自身体力低于最大体力的1/2则先制+2 +type Effect1117 struct{ node.EffectNode } + +func (e *Effect1117) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if e.Ctx().Our.CurrentPet.GetHP().Mul(alpacadecimal.NewFromInt(2)).Cmp(e.Ctx().Our.CurrentPet.GetMaxHP()) >= 0 { + return true + } + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current != nil && current.SkillEntity != nil { + current.SkillEntity.XML.Priority += 2 + } + return true +} + +// Effect 1118: {0}回合内对手若使用攻击技能则{1}%{2},若使用属性技能则全属性-{3} +type Effect1118 struct{ node.EffectNode } + +func (e *Effect1118) Skill_Use() bool { + if len(e.Args()) < 4 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1118, e.SideEffectArgs...) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1118Sub struct{ RoundEffectArg0Base } + +func (e *Effect1118Sub) Skill_Use_ex() bool { + if len(e.Args()) < 4 || e.Ctx().SkillEntity == nil { + return true + } + if e.Ctx().SkillEntity.Category() == info.Category.STATUS { + applyAllPropDown(e.Ctx().Our, e.Ctx().Opp, int8(e.Args()[3].IntPart())) + return true + } + success, _, _ := e.Input.Player.Roll(int(e.Args()[1].IntPart()), 100) + if success { + applyStatus(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[2].IntPart())) + } + return true +} + +// Effect 1119: 消除双方能力提升状态,消除任意一方成功则使自身下{0}回合先制+{1} +type Effect1119 struct{ node.EffectNode } + +func (e *Effect1119) Skill_Use() bool { + if len(e.Args()) < 2 { + return true + } + cleared := clearPositiveProps(e.Ctx().Our, e.Ctx().Our) + if clearPositiveProps(e.Ctx().Opp, e.Ctx().Our) { + cleared = true + } + if !cleared { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1119, int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1119Sub struct{ RoundEffectArg0Base } + +func (e *Effect1119Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current != nil && current.SkillEntity != nil && len(e.Args()) > 1 { + current.SkillEntity.XML.Priority += int(e.Args()[1].IntPart()) + } + return true +} + +// Effect 1120: 造成的伤害低于{0}则为自身附加{1}点护盾 +type Effect1120 struct{ node.EffectNode } + +func (e *Effect1120) Skill_Use() bool { + if len(e.Args()) < 2 || e.Ctx().Our.SumDamage.Cmp(e.Args()[0]) >= 0 { + return true + } + e.Ctx().Our.AddShield(e.Args()[1]) + return true +} + +// Effect 1121: 下{0}次受到的固定伤害和百分比伤害减少{1}% +type Effect1121 struct{ node.EffectNode } + +func (e *Effect1121) Skill_Use() bool { + if len(e.Args()) < 2 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1121, int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1121Sub struct { + node.EffectNode + remaining int +} + +func (e *Effect1121Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + if len(a) > 0 { + e.remaining = a[0] + } +} + +func (e *Effect1121Sub) DamageDivEx(zone *info.DamageZone) bool { + if zone == nil || e.remaining <= 0 || len(e.Args()) < 2 { + return true + } + if zone.Type != info.DamageType.Fixed && zone.Type != info.DamageType.Percent { + return true + } + zone.Damage = zone.Damage.Mul(hundred.Sub(e.Args()[1])).Div(hundred) + e.remaining-- + if e.remaining <= 0 { + e.Alive(false) + } + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1117, &Effect1117{}) + input.InitEffect(input.EffectType.Skill, 1118, &Effect1118{}) + input.InitEffect(input.EffectType.Sub, 1118, &Effect1118Sub{}) + input.InitEffect(input.EffectType.Skill, 1119, &Effect1119{}) + input.InitEffect(input.EffectType.Sub, 1119, &Effect1119Sub{}) + input.InitEffect(input.EffectType.Skill, 1120, &Effect1120{}) + input.InitEffect(input.EffectType.Skill, 1121, &Effect1121{}) + input.InitEffect(input.EffectType.Sub, 1121, &Effect1121Sub{}) +} diff --git a/logic/service/fight/effect/1168_1172.go b/logic/service/fight/effect/1168_1172.go new file mode 100644 index 000000000..9403a7685 --- /dev/null +++ b/logic/service/fight/effect/1168_1172.go @@ -0,0 +1,155 @@ +package effect + +import ( + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" + "github.com/gogf/gf/v2/util/grand" +) + +func clearAllStatusEffects1169(target *input.Input) { + if target == nil { + return + } + for _, eff := range target.Effects { + if eff == nil || !eff.Alive() || eff.ID().GetEffectType() != input.EffectType.Status { + continue + } + eff.Alive(false) + } +} + +// Effect 1168: 全属性+{0},双方任意一方处于异常状态则强化效果翻倍 +type Effect1168 struct{ node.EffectNode } + +func (e *Effect1168) Skill_Use() bool { + if len(e.Args()) == 0 { + return true + } + level := int8(e.Args()[0].IntPart()) + if e.Ctx().Our.StatEffect_Exist_all() || e.Ctx().Opp.StatEffect_Exist_all() { + level *= 2 + } + applyAllPropUp(e.Ctx().Our, level) + return true +} + +// Effect 1169: 若自身处于异常状态则造成的攻击伤害额外提升{0}%且回合结束后解除自身所有异常状态 +type Effect1169 struct{ node.EffectNode } + +func (e *Effect1169) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) == 0 || !e.Ctx().Our.StatEffect_Exist_all() { + return true + } + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + zone.Damage = zone.Damage.Mul(hundred.Add(e.Args()[0])).Div(hundred) + return true +} + +func (e *Effect1169) TurnEnd() { + if e.Ctx().Our.StatEffect_Exist_all() { + clearAllStatusEffects1169(e.Ctx().Our) + } +} + +// Effect 1170: 消除对手能力提升状态,消除成功则附加{0}点固定伤害 +type Effect1170 struct{ node.EffectNode } + +func (e *Effect1170) OnSkill() bool { + if len(e.Args()) == 0 || !clearPositiveProps(e.Ctx().Opp, e.Ctx().Our) { + return true + } + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Fixed, Damage: e.Args()[0]}) + return true +} + +// Effect 1171: 未击败对手则使自身下{0}回合受到的伤害减少{1}点 +type Effect1171 struct{ node.EffectNode } + +func (e *Effect1171) Skill_Use() bool { + if len(e.Args()) < 2 || e.Ctx().Opp.CurrentPet.Info.Hp <= 0 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1171, int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1171Sub struct{ RoundEffectArg0Base } + +func (e *Effect1171Sub) DamageSubEx(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 2 { + return true + } + reduce := e.Args()[1] + if zone.Damage.Cmp(reduce) <= 0 { + zone.Damage = alpacadecimal.Zero + return true + } + zone.Damage = zone.Damage.Sub(reduce) + return true +} + +// Effect 1172: {0}回合做{1}~{2}次攻击,每次攻击都有{3}%的概率令自身{4} +// 当前战斗模型未逐段执行多段攻击,这里按随机连击次数折算为红伤倍率,并按命中段数独立判定附加状态。 +type Effect1172 struct { + RoundEffectArg0Base + addStatus bool +} + +func (e *Effect1172) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 5 { + return true + } + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + minHits := int(e.Args()[1].IntPart()) + maxHits := int(e.Args()[2].IntPart()) + if minHits <= 0 { + minHits = 1 + } + if maxHits < minHits { + maxHits = minHits + } + hits := minHits + if maxHits > minHits { + hits += grand.Intn(maxHits - minHits + 1) + } + zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(int64(hits))) + e.addStatus = false + for i := 0; i < hits; i++ { + if ok, _, _ := e.Input.Player.Roll(int(e.Args()[3].IntPart()), 100); ok { + e.addStatus = true + break + } + } + return true +} + +func (e *Effect1172) Skill_Use() bool { + if !e.addStatus || len(e.Args()) < 5 { + return true + } + statusEffect := e.Ctx().Our.InitEffect(input.EffectType.Status, int(e.Args()[4].IntPart())) + if statusEffect != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, statusEffect) + } + e.addStatus = false + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1168, &Effect1168{}) + input.InitEffect(input.EffectType.Skill, 1169, &Effect1169{}) + input.InitEffect(input.EffectType.Skill, 1170, &Effect1170{}) + input.InitEffect(input.EffectType.Skill, 1171, &Effect1171{}) + input.InitEffect(input.EffectType.Sub, 1171, &Effect1171Sub{}) + input.InitEffect(input.EffectType.Skill, 1172, &Effect1172{}) +} diff --git a/logic/service/fight/effect/815_819.go b/logic/service/fight/effect/815_819.go new file mode 100644 index 000000000..b3a9c34f0 --- /dev/null +++ b/logic/service/fight/effect/815_819.go @@ -0,0 +1,174 @@ +package effect + +import ( + "blazing/common/data/xmlres" + "blazing/logic/service/fight/action" + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" +) + +// Effect 815: 后出手时附加自身当前体力{0}%的百分比伤害 +type Effect815 struct{ node.EffectNode } + +func (e *Effect815) Skill_Use() bool { + if len(e.Args()) == 0 || e.IsFirst() { + return true + } + damage := e.Ctx().Our.CurrentPet.GetHP().Mul(e.Args()[0]).Div(hundred) + if damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Percent, Damage: damage}) + return true +} + +// Effect 816: 免疫对手下次攻击技能造成的伤害并直接扣除对手等量体力 +type Effect816 struct{ node.EffectNode } + +func (e *Effect816) Skill_Use() bool { + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 816) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect816Sub struct { + node.EffectNode + attackRemain int + extraRemain int +} + +func (e *Effect816Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + e.attackRemain = 1 +} + +func (e *Effect816Sub) DamageLockEx(zone *info.DamageZone) bool { + if zone == nil || e.attackRemain <= 0 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + damage := zone.Damage + zone.Damage = alpacadecimal.Zero + e.attackRemain-- + if move, ok := xmlres.SkillMap[int(e.Ctx().SkillEntity.Info.ID)]; ok && move.MaxPP > 0 && int(e.Ctx().SkillEntity.Info.PP) == move.MaxPP { + e.extraRemain++ + } + if damage.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Fixed, Damage: damage}) + } + if e.attackRemain <= 0 && e.extraRemain <= 0 { + e.Alive(false) + } + return true +} + +func (e *Effect816Sub) DamageDivEx(zone *info.DamageZone) bool { + if zone == nil || e.extraRemain <= 0 { + return true + } + if zone.Type != info.DamageType.Fixed && zone.Type != info.DamageType.Percent { + return true + } + zone.Damage = alpacadecimal.Zero + e.extraRemain-- + if e.attackRemain <= 0 && e.extraRemain <= 0 { + e.Alive(false) + } + return true +} + +// Effect 817: {0}回合内受到攻击则对手下回合受到的伤害翻倍 +type Effect817 struct{ node.EffectNode } + +func (e *Effect817) Skill_Use() bool { + if len(e.Args()) == 0 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 817, int(e.Args()[0].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect817Sub struct { + RoundEffectArg0Base + triggered bool +} + +func (e *Effect817Sub) DamageSubEx(zone *info.DamageZone) bool { + if zone == nil || zone.Damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + e.triggered = true + return true +} + +func (e *Effect817Sub) TurnEnd() { + if e.triggered { + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 8171) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + e.Alive(false) + return + } + e.RoundEffectArg0Base.TurnEnd() +} + +type Effect817BoostSub struct{ FixedDuration1Base } + +func (e *Effect817BoostSub) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red { + return true + } + zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(2)) + return true +} + +// Effect 818: 出手时本回合若受到伤害,则将伤害反馈给对手 +type Effect818 struct{ node.EffectNode } + +func (e *Effect818) OnSkill() bool { + if e.Ctx().Opp.SumDamage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Fixed, Damage: e.Ctx().Opp.SumDamage}) + return true +} + +// Effect 819: 出手时本回合若未受到攻击伤害,则附加自身{0}值{1}%的百分比伤害,并恢复等量体力 +type Effect819 struct{ node.EffectNode } + +func (e *Effect819) OnSkill() bool { + if len(e.Args()) < 2 || e.Ctx().Opp.SumDamage.Cmp(alpacadecimal.Zero) > 0 { + return true + } + propID := int(e.Args()[0].IntPart()) + if propID < 0 || propID >= 6 { + return true + } + damage := e.Ctx().Our.GetProp(propID).Mul(e.Args()[1]).Div(hundred) + if damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Fixed, Damage: damage}) + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, damage) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 815, &Effect815{}) + input.InitEffect(input.EffectType.Skill, 816, &Effect816{}) + input.InitEffect(input.EffectType.Sub, 816, &Effect816Sub{}) + input.InitEffect(input.EffectType.Skill, 817, &Effect817{}) + input.InitEffect(input.EffectType.Sub, 817, &Effect817Sub{}) + input.InitEffect(input.EffectType.Sub, 8171, &Effect817BoostSub{}) + input.InitEffect(input.EffectType.Skill, 818, &Effect818{}) + input.InitEffect(input.EffectType.Skill, 819, &Effect819{}) +}