Files
bl/logic/service/fight/effect/1630_1634.go
2026-04-04 05:12:30 +08:00

198 lines
5.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 {
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 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.AttackTime == 0 {
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 {
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{})
}