Files
bl/logic/service/fight/effect/600_605.go
xinian 5204615c28
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
feat: 新增战斗效果并优化现有逻辑
2026-04-03 00:22:05 +08:00

206 lines
5.3 KiB
Go

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 effectRelativeInput(our, opp *input.Input, code int) *input.Input {
if code == 1 {
return our
}
return opp
}
func applyEffectPropChanges(target *input.Input, source *input.Input, changes []int, normalizePositiveAsDebuff bool) {
if target == nil {
return
}
for i, delta := range changes {
if delta == 0 {
continue
}
if normalizePositiveAsDebuff && delta > 0 {
delta = -delta
}
target.SetProp(source, int8(i), int8(delta))
}
}
// Effect 600: 若对手是{0}则造成伤害提升{1}%,若对手不是{0},则有{2}%概率使对手{3}
type Effect600 struct {
node.EffectNode
}
func (e *Effect600) SkillHit() bool {
if e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().Opp.CurrentPet.Info.Gender == int(e.Args()[0].IntPart()) {
bonusPercent := e.Args()[1]
e.Ctx().SkillEntity.XML.Power += int(alpacadecimal.NewFromInt(int64(e.Ctx().SkillEntity.XML.Power)).Mul(bonusPercent).Div(alpacadecimal.NewFromInt(100)).IntPart())
return true
}
success, _, _ := e.Input.Player.Roll(int(e.Args()[2].IntPart()), 100)
if !success {
return true
}
statusEffect := e.Ctx().Our.InitEffect(input.EffectType.Status, int(e.Args()[3].IntPart()))
if statusEffect != nil {
e.Ctx().Opp.AddEffect(e.Ctx().Our, statusEffect)
}
return true
}
// Effect 601: 若本回合击败对手,下回合对方出场精灵{0}
type Effect601 struct {
FixedDuration1Base
pending bool
}
func (e *Effect601) SwitchOut(in *input.Input) bool {
if in == e.Input || in == e.Ctx().Our {
e.Alive(false)
return true
}
if in != e.Ctx().Opp {
return true
}
if e.Ctx().Opp.CurrentPet.Alive() {
return true
}
e.pending = true
return true
}
func (e *Effect601) SwitchIn(in *input.Input) bool {
if !e.pending || in != e.Ctx().Opp {
return true
}
changes := make([]int, len(e.SideEffectArgs))
for i, delta := range e.SideEffectArgs {
changes[i] = delta
}
// 601 的实际技能数据以正数记录削弱幅度,这里归一化为对登场精灵的能力下降。
applyEffectPropChanges(e.Ctx().Opp, e.Ctx().Our, changes, true)
e.pending = false
e.Alive(false)
return true
}
// Effect 602: {0}回合内若{1}使用攻击技能则{2}的{3}
type Effect602 struct {
RoundEffectArg0Base
}
func (e *Effect602) Skill_Use() bool {
return e.tryApplyOnSkillUse(true)
}
func (e *Effect602) Skill_Use_ex() bool {
return e.tryApplyOnSkillUse(false)
}
func (e *Effect602) tryApplyOnSkillUse(ownerUsedSkill bool) bool {
if len(e.SideEffectArgs) < 9 || e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
triggerTarget := effectRelativeInput(e.Ctx().Our, e.Ctx().Opp, e.SideEffectArgs[1])
expectedOwnerUsedSkill := triggerTarget == e.Ctx().Our
if ownerUsedSkill != expectedOwnerUsedSkill {
return true
}
affected := effectRelativeInput(e.Ctx().Our, e.Ctx().Opp, e.SideEffectArgs[2])
applyEffectPropChanges(affected, e.Ctx().Our, e.SideEffectArgs[3:], false)
return true
}
// Effect 603: {0}%概率使对手陷入{1}状态{2}回合
type Effect603 struct {
node.EffectNode
}
func (e *Effect603) OnSkill() bool {
success, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100)
if !success {
return true
}
statusEffect := e.Ctx().Our.InitEffect(input.EffectType.Status, int(e.Args()[1].IntPart()))
if statusEffect == nil {
return true
}
statusEffect.Duration(int(e.Args()[2].IntPart()))
e.Ctx().Opp.AddEffect(e.Ctx().Our, statusEffect)
return true
}
// Effect 604: 威力随机,随机范围{0}-{1},连续使用每次威力提升{2},最高提升至{3}
type Effect604 struct {
AddLvelEffect
}
func (e *Effect604) SkillHit() bool {
randomPower := grand.N(int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart()))
e.Ctx().SkillEntity.XML.Power = randomPower + int(e.GetStackOnlyADD(e.Args()[2], e.Args()[3]).IntPart())
return e.AddLvelEffect.SkillHit()
}
// Effect 605: 自身体力{0}对手时附加{1}值{2}%的百分比伤害
type Effect605 struct {
node.EffectNode
}
func (e *Effect605) OnSkill() bool {
ourHP := e.Ctx().Our.CurrentPet.GetHP()
oppHP := e.Ctx().Opp.CurrentPet.GetHP()
mode := int(e.Args()[0].IntPart())
if (mode == 0 && ourHP.Cmp(oppHP) <= 0) || (mode == 1 && ourHP.Cmp(oppHP) >= 0) {
return true
}
var base alpacadecimal.Decimal
switch int(e.Args()[1].IntPart()) {
case 0:
base = e.Ctx().Our.CurrentPet.GetMaxHP().Sub(e.Ctx().Our.CurrentPet.GetHP())
case 1:
base = e.Ctx().Our.CurrentPet.GetMaxHP()
case 2:
base = e.Ctx().Our.CurrentPet.GetHP()
default:
return true
}
damage := base.Mul(e.Args()[2]).Div(alpacadecimal.NewFromInt(100))
if damage.Cmp(alpacadecimal.Zero) <= 0 {
return true
}
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Fixed, Damage: damage})
return true
}
func init() {
input.InitEffect(input.EffectType.Skill, 600, &Effect600{})
input.InitEffect(input.EffectType.Skill, 601, &Effect601{})
input.InitEffect(input.EffectType.Skill, 602, &Effect602{})
input.InitEffect(input.EffectType.Skill, 603, &Effect603{})
input.InitEffect(input.EffectType.Skill, 604, &Effect604{})
input.InitEffect(input.EffectType.Skill, 605, &Effect605{})
}