diff --git a/docs/effect-unimplemented-tasks/task-199-effects-1609-1613.md b/docs/effect-unimplemented-tasks/task-199-effects-1609-1613.md deleted file mode 100644 index 1555cd1c2..000000000 --- a/docs/effect-unimplemented-tasks/task-199-effects-1609-1613.md +++ /dev/null @@ -1,36 +0,0 @@ -# Task 199: Effects 1609-1613 - -## 目标 - -- 补齐以下 5 个(或最后一组不足 5 个)当前判定未实现的 skill effect。 -- 实现位置优先放在 `logic/service/fight/effect/`。 -- 如 effect 需要展示说明,同步更新 `logic/service/fight/effect/effect_info_map.go`。 -- 完成后至少执行:`cd /workspace/logic && go test ./service/fight/effect`。 - -## Effect 列表 - -### Effect 1609 -- `argsNum`: `0` -- `info`: `召唤自己的伙伴进行5-10次攻击,布布犬发起时可额外令自身下回合攻击造成的伤害翻倍` - -### Effect 1610 -- `argsNum`: `0` -- `info`: `召唤自己的伙伴进行5-10次攻击,布布熊发起时可额外令对手下回合属性技能失效` - -### Effect 1611 -- `argsNum`: `0` -- `info`: `攻击命中后5%的概率汲取泰坦源脉的力量,本次攻击造成5倍伤害且战斗结束后获得5000泰坦之灵(每日上限50000)` - -### Effect 1612 -- `argsNum`: `5` -- `info`: `{0}回合内受到的伤害低于{1}时{2}%令对手{3},未触发则附加{4}点固定伤害` -- `param`: `1,3,3` - -### Effect 1613 -- `argsNum`: `2` -- `info`: `自身不处于能力提升状态则吸取对手{0}点体力,若先出手则额外吸取{1}点体力` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-201-effects-1620-1624.md b/docs/effect-unimplemented-tasks/task-201-effects-1620-1624.md deleted file mode 100644 index 600ab7798..000000000 --- a/docs/effect-unimplemented-tasks/task-201-effects-1620-1624.md +++ /dev/null @@ -1,36 +0,0 @@ -# Task 201: Effects 1620-1624 - -## 目标 - -- 补齐以下 5 个(或最后一组不足 5 个)当前判定未实现的 skill effect。 -- 实现位置优先放在 `logic/service/fight/effect/`。 -- 如 effect 需要展示说明,同步更新 `logic/service/fight/effect/effect_info_map.go`。 -- 完成后至少执行:`cd /workspace/logic && go test ./service/fight/effect`。 - -## Effect 列表 - -### Effect 1620 -- `argsNum`: `1` -- `info`: `对手基础速度值高于{0}则下回合先制-1` - -### Effect 1621 -- `argsNum`: `2` -- `info`: `{0}%令对手所有技能PP值-{1},自身满体力时效果翻倍` - -### Effect 1622 -- `argsNum`: `4` -- `info`: `{0}回合内每回合{1}%对手属性技能无效,未触发则下{2}次受到的攻击伤害减少{3}%` - -### Effect 1623 -- `argsNum`: `3` -- `info`: `若对手是{0}精灵则下{1}回合对手受到的伤害提高{2}%` -- `param`: `5,0,0` - -### Effect 1624 -- `argsNum`: `1` -- `info`: `对手不处于异常状态时随机附加{0}种异常状态` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-203-effects-1630-1634.md b/docs/effect-unimplemented-tasks/task-203-effects-1630-1634.md deleted file mode 100644 index 80f97d0dc..000000000 --- a/docs/effect-unimplemented-tasks/task-203-effects-1630-1634.md +++ /dev/null @@ -1,37 +0,0 @@ -# Task 203: Effects 1630-1634 - -## 目标 - -- 补齐以下 5 个(或最后一组不足 5 个)当前判定未实现的 skill effect。 -- 实现位置优先放在 `logic/service/fight/effect/`。 -- 如 effect 需要展示说明,同步更新 `logic/service/fight/effect/effect_info_map.go`。 -- 完成后至少执行:`cd /workspace/logic && go test ./service/fight/effect`。 - -## Effect 列表 - -### Effect 1630 -- `argsNum`: `2` -- `info`: `若对手当回合使用的技能为攻击技能则自身必定先出手且命中后{0}%令对手{1}` -- `param`: `1,1,1` - -### Effect 1631 -- `argsNum`: `2` -- `info`: `{0}回合内每回合若自身未受到攻击伤害则回合结束后附加对手最大体力1/{1}的百分比伤害(自身体力为0时也可触发)` - -### Effect 1632 -- `argsNum`: `3` -- `info`: `吸取对手{0}点体力,若对手任意1项技能PP值小于{1}点则额外吸取{2}点体力` - -### Effect 1633 -- `argsNum`: `2` -- `info`: `使自身体力百分比与对手体力百分比对调,自身体力百分比高于对手时{0}%令对手{1}` -- `param`: `1,1,1` - -### Effect 1634 -- `argsNum`: `0` -- `info`: `自身体力低于250时必定先手` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/logic/service/fight/action.go b/logic/service/fight/action.go index 7f909d20d..cd0d7409f 100644 --- a/logic/service/fight/action.go +++ b/logic/service/fight/action.go @@ -6,6 +6,7 @@ import ( "blazing/logic/service/fight/info" "blazing/logic/service/fight/input" "blazing/modules/player/model" + "github.com/jinzhu/copier" ) @@ -39,6 +40,7 @@ func (f *FightC) closeActionWindow() { f.pendingActions = f.pendingActions[:0] f.actionRound.Store(0) f.actionMu.Unlock() + } func (f *FightC) submitAction(act action.BattleActionI) { diff --git a/logic/service/fight/effect/1609_1613.go b/logic/service/fight/effect/1609_1613.go new file mode 100644 index 000000000..0e35185c2 --- /dev/null +++ b/logic/service/fight/effect/1609_1613.go @@ -0,0 +1,237 @@ +package effect + +import ( + "strings" + + "blazing/common/data/share" + "blazing/logic/service/fight/action" + "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" +) + +const titanSpiritItemID = 1400352 + +// Effect 1609: 召唤自己的伙伴进行5-10次攻击,布布犬发起时可额外令自身下回合攻击造成的伤害翻倍 +type Effect1609 struct{ node.EffectNode } + +func (e *Effect1609) SkillHit() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || e.Ctx().SkillEntity.AttackTime == 0 { + return true + } + hits := 5 + grand.Intn(6) + if hits > 1 { + e.Ctx().SkillEntity.AttackTime += uint32(hits - 1) + } + return true +} + +func (e *Effect1609) Skill_Use() bool { + if e.Ctx().Our == nil || e.Ctx().Our.CurPet[0] == nil { + return true + } + if strings.TrimSpace(e.Ctx().Our.CurPet[0].PetInfo.DefName) != "布布犬" { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1609) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1609Sub struct { + node.EffectNode +} + +func (e *Effect1609Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(1) + e.CanStack(false) +} + +func (e *Effect1609Sub) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(2)) + return true +} + +// Effect 1610: 召唤自己的伙伴进行5-10次攻击,布布熊发起时可额外令对手下回合属性技能失效 +type Effect1610 struct{ node.EffectNode } + +func (e *Effect1610) SkillHit() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || e.Ctx().SkillEntity.AttackTime == 0 { + return true + } + hits := 5 + grand.Intn(6) + if hits > 1 { + e.Ctx().SkillEntity.AttackTime += uint32(hits - 1) + } + return true +} + +func (e *Effect1610) Skill_Use() bool { + if e.Ctx().Opp == nil || e.Ctx().Our == nil || e.Ctx().Our.CurPet[0] == nil { + return true + } + if strings.TrimSpace(e.Ctx().Our.CurPet[0].PetInfo.DefName) != "布布熊" { + return true + } + sub := e.Ctx().Opp.InitEffect(input.EffectType.Sub, 1610) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1610Sub struct { + FixedDuration1Base +} + +func (e *Effect1610Sub) SkillHit_ex() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() != info.Category.STATUS { + return true + } + e.Ctx().SkillEntity.SetNoSide() + return true +} + +// Effect 1611: 攻击命中后5%的概率汲取泰坦源脉的力量,本次攻击造成5倍伤害且战斗结束后获得5000泰坦之灵(每日上限50000) +type Effect1611 struct { + node.EffectNode + rolled bool + triggered bool + rewarded bool +} + +func (e *Effect1611) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) +} + +func (e *Effect1611) SkillHit() bool { + e.rolled = false + e.triggered = false + return true +} + +func (e *Effect1611) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + if !e.rolled { + e.rolled = true + if ok, _, _ := e.Input.Player.Roll(5, 100); ok { + e.triggered = true + e.rewarded = true + } + } + if !e.triggered { + return true + } + zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(5)) + return true +} + +func (e *Effect1611) OnBattleEnd() bool { + if !e.rewarded { + return true + } + player := e.Ctx().Our.Player + if player == nil || player.GetInfo().UserID == 0 { + return true + } + count, err := share.GlobalCounterManager.GetCount(&share.DailyPeriod, player.GetInfo().UserID, 1611) + if err != nil && err != share.ErrCacheMiss { + return true + } + if err == share.ErrCacheMiss { + count = 0 + } + if count >= 10 { + return true + } + if !player.ItemAdd(titanSpiritItemID, 5000) { + return true + } + _, _ = share.GlobalCounterManager.IncrCount(&share.DailyPeriod, player.GetInfo().UserID, 1611) + return true +} + +// Effect 1612: {0}回合内受到的伤害低于{1}时{2}%令对手{3},未触发则附加{4}点固定伤害 +type Effect1612 struct{ node.EffectNode } + +func (e *Effect1612) Skill_Use() bool { + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1612, e.SideEffectArgs...) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1612Sub struct{ RoundEffectArg0Base } + +func (e *Effect1612Sub) DamageSubEx(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 5 { + return true + } + if zone.Damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + threshold := e.Args()[1] + chance := int(e.Args()[2].IntPart()) + statusID := int(e.Args()[3].IntPart()) + fallback := e.Args()[4] + triggered := false + if zone.Damage.Cmp(threshold) < 0 && chance > 0 && statusID > 0 { + if ok, _, _ := e.Input.Player.Roll(chance, 100); ok { + addStatusByID(e.Ctx().Our, e.Ctx().Opp, statusID) + triggered = true + } + } + if !triggered && fallback.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Fixed, Damage: fallback}) + } + return true +} + +// Effect 1613: 自身不处于能力提升状态则吸取对手{0}点体力,若先出手则额外吸取{1}点体力 +type Effect1613 struct{ node.EffectNode } + +func (e *Effect1613) Skill_Use() bool { + if len(e.Args()) < 2 || e.Ctx().Opp == nil { + return true + } + if e.Ctx().Our == nil || e.Ctx().Our.CurPet[0] == nil { + return true + } + drain := alpacadecimal.Zero + if !e.Ctx().Our.HasPropADD() { + drain = drain.Add(e.Args()[0]) + } + if e.IsFirst() { + drain = drain.Add(e.Args()[1]) + } + if drain.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + damageByFixed(e.Ctx().Our, e.Ctx().Opp, drain.IntPart()) + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, drain) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1609, &Effect1609{}) + input.InitEffect(input.EffectType.Sub, 1609, &Effect1609Sub{}) + input.InitEffect(input.EffectType.Skill, 1610, &Effect1610{}) + input.InitEffect(input.EffectType.Sub, 1610, &Effect1610Sub{}) + input.InitEffect(input.EffectType.Skill, 1611, &Effect1611{}) + input.InitEffect(input.EffectType.Skill, 1612, &Effect1612{}) + input.InitEffect(input.EffectType.Sub, 1612, &Effect1612Sub{}) + input.InitEffect(input.EffectType.Skill, 1613, &Effect1613{}) +} diff --git a/logic/service/fight/effect/1620_1624.go b/logic/service/fight/effect/1620_1624.go new file mode 100644 index 000000000..49c74c073 --- /dev/null +++ b/logic/service/fight/effect/1620_1624.go @@ -0,0 +1,221 @@ +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 1620: 对手基础速度值高于{0}则下回合先制-1 +type Effect1620 struct{ node.EffectNode } + +func (e *Effect1620) Skill_Use() bool { + if len(e.Args()) < 1 || e.Ctx().Opp == nil || e.Ctx().Opp.CurPet[0] == nil { + return true + } + threshold := e.Args()[0].IntPart() + if threshold < 0 { + threshold = 0 + } + if int64(e.Ctx().Opp.CurPet[0].PetInfo.Spd) <= threshold { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1620, -1) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1620Sub struct { + node.EffectNode + priority int +} + +func (e *Effect1620Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(1) + e.CanStack(false) + if len(a) > 0 { + e.priority = a[0] + } +} + +func (e *Effect1620Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current == nil || current.SkillEntity == nil { + return true + } + current.SkillEntity.XML.Priority += e.priority + return true +} + +// Effect 1621: {0}%令对手所有技能PP值-{1},自身满体力时效果翻倍 +type Effect1621 struct{ node.EffectNode } + +func (e *Effect1621) Skill_Use() bool { + if len(e.Args()) < 2 || e.Ctx().Opp == nil || e.Ctx().Opp.CurPet[0] == nil { + return true + } + if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); !ok { + return true + } + amount := int(e.Args()[1].IntPart()) + if amount <= 0 { + return true + } + if e.Ctx().Our != nil && e.Ctx().Our.CurPet[0] != nil && + e.Ctx().Our.CurPet[0].Info.Hp == e.Ctx().Our.CurPet[0].Info.MaxHp { + amount *= 2 + } + e.Ctx().Opp.DelPP(amount) + return true +} + +// Effect 1622: {0}回合内每回合{1}%对手属性技能无效,未触发则下{2}次受到的攻击伤害减少{3}% +type Effect1622 struct{ node.EffectNode } + +func (e *Effect1622) Skill_Use() bool { + if len(e.Args()) < 4 || e.Ctx().Opp == nil { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1622, + int(e.Args()[0].IntPart()), + int(e.Args()[1].IntPart()), + int(e.Args()[2].IntPart()), + int(e.Args()[3].IntPart()), + ) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1622Sub struct{ RoundEffectArg0Base } + +func (e *Effect1622Sub) SkillHit_ex() bool { + if len(e.Args()) < 4 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() != info.Category.STATUS { + return true + } + if ok, _, _ := e.Input.Player.Roll(int(e.Args()[1].IntPart()), 100); ok { + e.Ctx().SkillEntity.SetNoSide() + e.Ctx().SkillEntity.AttackTime = 0 + return true + } + count := int(e.Args()[2].IntPart()) + percent := int(e.Args()[3].IntPart()) + if count <= 0 || percent <= 0 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 16221, count, percent) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1622DamageSub struct { + node.EffectNode + remaining int + reduction alpacadecimal.Decimal +} + +func (e *Effect1622DamageSub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.CanStack(false) + e.Duration(-1) + if len(a) > 0 { + e.remaining = a[0] + } + if len(a) > 1 { + if a[1] < 0 { + a[1] = 0 + } + e.reduction = alpacadecimal.NewFromInt(int64(a[1])) + } +} + +func (e *Effect1622DamageSub) DamageDivEx(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || e.remaining <= 0 || e.reduction.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + if zone.Damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + factor := hundred.Sub(e.reduction) + if factor.Cmp(alpacadecimal.Zero) < 0 { + factor = alpacadecimal.Zero + } + zone.Damage = zone.Damage.Mul(factor).Div(hundred) + e.remaining-- + if e.remaining <= 0 { + e.Alive(false) + } + return true +} + +// Effect 1623: 若对手是{0}精灵则下{1}回合对手受到的伤害提高{2}% +type Effect1623 struct{ node.EffectNode } + +func (e *Effect1623) Skill_Use() bool { + if len(e.Args()) < 3 || e.Ctx().Opp == nil || e.Ctx().Opp.CurPet[0] == nil { + return true + } + if int(e.Ctx().Opp.CurPet[0].PetInfo.Type) != int(e.Args()[0].IntPart()) { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1623, + int(e.Args()[1].IntPart()), + int(e.Args()[2].IntPart()), + ) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1623Sub struct{ RoundEffectArg0Base } + +func (e *Effect1623Sub) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 2 { + return true + } + if zone.Damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + percent := e.Args()[1] + if percent.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + zone.Damage = zone.Damage.Mul(hundred.Add(percent)).Div(hundred) + return true +} + +// Effect 1624: 对手不处于异常状态时随机附加{0}种异常状态 +type Effect1624 struct{ node.EffectNode } + +func (e *Effect1624) Skill_Use() bool { + if len(e.Args()) < 1 || e.Ctx().Opp == nil || e.Args()[0].IntPart() <= 0 { + return true + } + if e.Ctx().Opp.StatEffect_Exist_all() { + return true + } + applyRandomStatuses1394(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[0].IntPart())) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1620, &Effect1620{}) + input.InitEffect(input.EffectType.Sub, 1620, &Effect1620Sub{}) + input.InitEffect(input.EffectType.Skill, 1621, &Effect1621{}) + input.InitEffect(input.EffectType.Skill, 1622, &Effect1622{}) + input.InitEffect(input.EffectType.Sub, 1622, &Effect1622Sub{}) + input.InitEffect(input.EffectType.Sub, 16221, &Effect1622DamageSub{}) + input.InitEffect(input.EffectType.Skill, 1623, &Effect1623{}) + input.InitEffect(input.EffectType.Sub, 1623, &Effect1623Sub{}) + input.InitEffect(input.EffectType.Skill, 1624, &Effect1624{}) +} diff --git a/logic/service/fight/effect/1630_1634.go b/logic/service/fight/effect/1630_1634.go new file mode 100644 index 000000000..67ed68ddf --- /dev/null +++ b/logic/service/fight/effect/1630_1634.go @@ -0,0 +1,197 @@ +package effect + +import ( + "math" + + "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 1630: 若对手当回合使用的技能为攻击技能则自身必定先出手且命中后{0}%令对手{1} +type Effect1630 struct { + node.EffectNode + armed bool +} + +func (e *Effect1630) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + e.armed = false + if len(e.Args()) < 2 || e.Ctx().Opp == nil { + return true + } + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + oppAction := actionByPlayer(fattack, sattack, e.Ctx().Opp.UserID) + if current == nil || current.SkillEntity == nil || oppAction == nil || oppAction.SkillEntity == nil { + return true + } + if oppAction.SkillEntity.Category() == info.Category.STATUS || current.SkillEntity.Category() == info.Category.STATUS { + return true + } + current.SkillEntity.XML.Priority = math.MaxInt + e.armed = true + return true +} + +func (e *Effect1630) OnSkill() bool { + if !e.armed || len(e.Args()) < 2 || e.Ctx().Opp == nil { + return true + } + chance := int(e.Args()[0].IntPart()) + if chance <= 0 { + e.armed = false + return true + } + success, _, _ := e.Input.Player.Roll(chance, 100) + if success { + statusEffect := e.Ctx().Our.InitEffect(input.EffectType.Status, int(e.Args()[1].IntPart())) + if statusEffect != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, statusEffect) + } + } + e.armed = false + return true +} + +// Effect 1631: {0}回合内每回合若自身未受到攻击伤害则回合结束后附加对手最大体力1/{1}的百分比伤害(自身体力为0时也可触发) +type Effect1631 struct { + RoundEffectArg0Base + hitThisRound bool +} + +func (e *Effect1631) DamageSubEx(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 2 { + return true + } + if zone.Damage.Cmp(alpacadecimal.Zero) > 0 { + e.hitThisRound = true + } + return true +} + +func (e *Effect1631) TurnEnd() { + if !e.hitThisRound && len(e.Args()) >= 2 && e.Ctx().Opp != nil && e.Ctx().Opp.CurPet[0] != nil { + denom := e.Args()[1] + if denom.Cmp(alpacadecimal.Zero) > 0 { + damage := e.Ctx().Opp.CurPet[0].GetMaxHP().Div(denom) + if damage.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Percent, + Damage: damage, + }) + } + } + } + e.hitThisRound = false + e.EffectNode.TurnEnd() +} + +// Effect 1632: 吸取对手{0}点体力,若对手任意1项技能PP值小于{1}点则额外吸取{2}点体力 +type Effect1632 struct { + node.EffectNode +} + +func (e *Effect1632) Skill_Use() bool { + if len(e.Args()) < 3 || e.Ctx().Opp == nil || e.Ctx().Opp.CurPet[0] == nil || e.Ctx().Our == nil { + return true + } + drain := alpacadecimal.Zero + if e.Args()[0].Cmp(alpacadecimal.Zero) > 0 { + drain = drain.Add(e.Args()[0]) + } + threshold := int(e.Args()[1].IntPart()) + if threshold > 0 { + for _, skill := range e.Ctx().Opp.CurPet[0].Info.SkillList { + if int(skill.PP) < threshold { + if e.Args()[2].Cmp(alpacadecimal.Zero) > 0 { + drain = drain.Add(e.Args()[2]) + } + break + } + } + } + if drain.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: drain, + }) + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, drain) + return true +} + +// Effect 1633: 使自身体力百分比与对手体力百分比对调,自身体力百分比高于对手时{0}%令对手{1} +type Effect1633 struct { + node.EffectNode +} + +func clampHP(dec alpacadecimal.Decimal, max uint32) uint32 { + value := dec.IntPart() + if value < 0 { + return 0 + } + if int64(value) > int64(max) { + return max + } + return uint32(value) +} + +func (e *Effect1633) Skill_Use() bool { + if len(e.Args()) < 2 || e.Ctx().Opp == nil || e.Ctx().Opp.CurPet[0] == nil || e.Ctx().Our == nil || e.Ctx().Our.CurPet[0] == nil { + return true + } + ourPet := e.Ctx().Our.CurPet[0] + oppPet := e.Ctx().Opp.CurPet[0] + ourMax := ourPet.GetMaxHP() + oppMax := oppPet.GetMaxHP() + if ourMax.Cmp(alpacadecimal.Zero) <= 0 || oppMax.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + ourPercent := ourPet.GetHP().Div(ourMax) + oppPercent := oppPet.GetHP().Div(oppMax) + shouldInflict := ourPercent.Cmp(oppPercent) > 0 + ourPet.Info.Hp = clampHP(oppPercent.Mul(ourMax), ourPet.Info.MaxHp) + oppPet.Info.Hp = clampHP(ourPercent.Mul(oppMax), oppPet.Info.MaxHp) + if shouldInflict && e.Args()[0].Cmp(alpacadecimal.Zero) > 0 { + chance := int(e.Args()[0].IntPart()) + success, _, _ := e.Input.Player.Roll(chance, 100) + if success { + statusEffect := e.Ctx().Our.InitEffect(input.EffectType.Status, int(e.Args()[1].IntPart())) + if statusEffect != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, statusEffect) + } + } + } + return true +} + +// Effect 1634: 自身体力低于250时必定先手 +type Effect1634 struct { + node.EffectNode +} + +func (e *Effect1634) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if e.Ctx().Our == nil || e.Ctx().Our.CurPet[0] == nil { + return true + } + if int64(e.Ctx().Our.CurPet[0].Info.Hp) >= 250 { + return true + } + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current == nil || current.SkillEntity == nil || current.SkillEntity.Category() == info.Category.STATUS { + return true + } + current.SkillEntity.XML.Priority = math.MaxInt + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1630, &Effect1630{}) + input.InitEffect(input.EffectType.Skill, 1631, &Effect1631{}) + input.InitEffect(input.EffectType.Skill, 1632, &Effect1632{}) + input.InitEffect(input.EffectType.Skill, 1633, &Effect1633{}) + input.InitEffect(input.EffectType.Skill, 1634, &Effect1634{}) +} diff --git a/logic/service/fight/effect/effect_info_map.go b/logic/service/fight/effect/effect_info_map.go index a445f933f..c7a4322dc 100644 --- a/logic/service/fight/effect/effect_info_map.go +++ b/logic/service/fight/effect/effect_info_map.go @@ -1055,6 +1055,11 @@ var effectInfoByID = map[int]string{ 1598: "命中后50%令对手害怕,若对手为甜甜粽则概率翻倍", 1599: "{0}回合内受到攻击则{1}%令对手{2},未触发则{3}%令对手{4}", 1600: "命中后{0}%令对手{1},未触发则自身下{2}回合攻击必定致命一击,触发后{3}回合内对手主动切换精灵则登场精灵{4}%进入{5}状态", + 1630: "若对手当回合使用的技能为攻击技能则自身必定先出手且命中后{0}%令对手{1}", + 1631: "{0}回合内每回合若自身未受到攻击伤害则回合结束后附加对手最大体力1/{1}的百分比伤害(自身体力为0时也可触发)", + 1632: "吸取对手{0}点体力,若对手任意1项技能PP值小于{1}点则额外吸取{2}点体力", + 1633: "使自身体力百分比与对手体力百分比对调,自身体力百分比高于对手时{0}%令对手{1}", + 1634: "自身体力低于250时必定先手", 1601: "命中后附加自身最大体力{0}%的百分比伤害,若打出的攻击伤害为奇数则额外恢复等量体力值", 1602: "{0}回合内每回合使用技能恢复自身最大体力的1/{1},恢复体力时若自身为满体力则恢复己方所有不在场精灵{2}点体力", 1603: "{0}%降低对手所有PP值{1}点", @@ -1063,6 +1068,16 @@ var effectInfoByID = map[int]string{ 1606: "反转自身能力下降状态,反转成功则吸取对手最大体力的1/{0}", 1607: "当回合未击败对手则附加自身最大体力1/{0}的百分比伤害", 1608: "召唤自己的伙伴进行5-10次攻击,布布鸟发起时可额外令自身下回合所有技能先制+3", + 1609: "召唤自己的伙伴进行5-10次攻击,布布犬发起时可额外令自身下回合攻击造成的伤害翻倍", + 1610: "召唤自己的伙伴进行5-10次攻击,布布熊发起时可额外令对手下回合属性技能失效", + 1611: "攻击命中后5%的概率汲取泰坦源脉的力量,本次攻击造成5倍伤害且战斗结束后获得5000泰坦之灵(每日上限50000)", + 1612: "{0}回合内受到的伤害低于{1}时{2}%令对手{3},未触发则附加{4}点固定伤害", + 1613: "自身不处于能力提升状态则吸取对手{0}点体力,若先出手则额外吸取{1}点体力", + 1620: "对手基础速度值高于{0}则下回合先制-1", + 1621: "{0}%令对手所有技能PP值-{1},自身满体力时效果翻倍", + 1622: "{0}回合内每回合{1}%对手属性技能无效,未触发则下{2}次受到的攻击伤害减少{3}%", + 1623: "若对手是{0}精灵则下{1}回合对手受到的伤害提高{2}%", + 1624: "对手不处于异常状态时随机附加{0}种异常状态", 1670: "{0}%令对手{1},对手为自身天敌时概率提升{2}%,未触发则消除对手回合类效果", 1671: "造成的攻击伤害不低于{0},若对手处于能力提升状态则造成的攻击伤害不低于{1}", 1672: "出手时若自身未满体力则吸取对手{0}点体力", diff --git a/logic/service/fight/input/input.go b/logic/service/fight/input/input.go index 37e41f3d9..334d09328 100644 --- a/logic/service/fight/input/input.go +++ b/logic/service/fight/input/input.go @@ -24,14 +24,15 @@ type Input struct { Opp *Input CanCapture int Finished bool //是否加载完成 - *model.AttackValue - FightC common.FightI // info.BattleActionI Effects []Effect //effects 实际上全局就是effect无限回合 //effects容器 技能的 EffectCache []Effect //这里是命中前执行的容器,也就是命中前执行的所有逻辑相关,理论上一个effect被激活,就应该同时将其他的effect取消激活 EffectLost []Effect // 删掉伤害记录,可以在回调中记录,而不是每次调用记录 + *model.AttackValue + FightC common.FightI SumDamage alpacadecimal.Decimal //伤害 + ShieldDamageTaken alpacadecimal.Decimal // 记录上一回合结束时的能力等级,供效果727等回溯使用。 LastTurnEndProp [6]int8 // DamageZone struct {