Files
bl/logic/service/fight/effect/2195_2219.go
昔念 07758266d5 ```
feat(effect): 实现多个战斗效果功能

- 实现了effects 2195-2199的功能,包括消除对手回合类效果、概率附加效果、
  护盾/护罩状态下触发的效果等

- 实现了effects 2220-2239的功能,包括攻击特攻最高值转换、闪避与PP归零、
  伤害提升、恢复体力、回合效果管理等功能

- 实现了effects 2270-2294的部分功能修复,调整了精灵
2026-03-31 06:51:54 +08:00

562 lines
14 KiB
Go

package effect
import (
element "blazing/common/data/Element"
"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"
"github.com/gogf/gf/v2/util/grand"
)
func clearOwnStatusEffects(target *input.Input) bool {
if target == nil {
return false
}
cleared := false
for _, eff := range target.Effects {
if eff == nil || !eff.Alive() || eff.ID().GetEffectType() != input.EffectType.Status {
continue
}
eff.Alive(false)
cleared = true
}
return cleared
}
// Effect 2195: 消除对手回合类效果并降低先制
type Effect2195 struct {
node.EffectNode
}
func (e *Effect2195) Skill_Use() bool {
if len(e.Args()) < 2 {
return true
}
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
before := activeTurnEffectCount(e.Ctx().Opp)
e.Ctx().Opp.CancelTurn(e.Ctx().Our)
if before <= 0 {
return true
}
sub := e.Ctx().Opp.InitEffect(input.EffectType.Sub, 2195, int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart()))
if sub != nil {
e.Ctx().Opp.AddEffect(e.Ctx().Our, sub)
}
return true
}
type Effect2195Sub struct {
RoundEffectArg0Base
}
func (e *Effect2195Sub) 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 -= int(e.Args()[1].IntPart())
return true
}
// Effect 2196: 概率附加自身效果
type Effect2196 struct {
node.EffectNode
}
func (e *Effect2196) Skill_Use() bool {
if len(e.Args()) < 2 {
return true
}
if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); ok {
addStatusByID(e.Ctx().Our, e.Ctx().Our, int(e.Args()[1].IntPart()))
}
return true
}
// Effect 2197: 自身处于护盾时必中
type Effect2197 struct {
node.EffectNode
}
func (e *Effect2197) SkillHit_ex() bool {
if e.Ctx().Our.HasShield() && e.Ctx().SkillEntity != nil && e.Ctx().SkillEntity.Category() != info.Category.STATUS {
e.Ctx().SkillEntity.SetNoSide()
}
return true
}
// Effect 2198: 双方任一方护盾时概率附加对手效果
type Effect2198 struct {
node.EffectNode
}
func (e *Effect2198) Skill_Use() bool {
if len(e.Args()) < 2 {
return true
}
if !e.Ctx().Our.HasShield() && !e.Ctx().Opp.HasShield() {
return true
}
if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); ok {
addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart()))
}
return true
}
// Effect 2199: 双方任一方护罩时概率附加对手效果
type Effect2199 struct {
node.EffectNode
}
func (e *Effect2199) Skill_Use() bool {
if len(e.Args()) < 2 {
return true
}
if !e.Ctx().Our.HasShield() && !e.Ctx().Opp.HasShield() {
return true
}
if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); ok {
addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart()))
}
return true
}
// Effect 2200: 令双方行动条件失效
type Effect2200 struct {
node.EffectNode
}
func (e *Effect2200) Skill_Use() bool {
if len(e.Args()) < 2 {
return true
}
if e.Ctx().Opp.CurrentPet != nil {
e.Ctx().Opp.DelPP(int(e.Args()[0].IntPart()))
}
return true
}
// Effect 2201: 属性关系影响总伤害
type Effect2201 struct {
node.EffectNode
}
func (e *Effect2201) Damage_Mul(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 1 {
return true
}
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
if e.Ctx().SkillEntity.Pet == nil || e.Ctx().Opp.CurrentPet == nil {
return true
}
if e.Ctx().SkillEntity.Pet.GetType().Primary == e.Ctx().Opp.CurrentPet.GetType().Primary {
return true
}
zone.Damage = zone.Damage.Mul(hundred.Add(e.Args()[0])).Div(hundred)
return true
}
// Effect 2202: 属性克制时必定致命
type Effect2202 struct {
node.EffectNode
}
func (e *Effect2202) SkillHit() bool {
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
e.Ctx().SkillEntity.XML.CritRate = 16
return true
}
// Effect 2203: 技能无效时免疫下一次攻击
type Effect2203 struct {
node.EffectNode
}
func (e *Effect2203) Skill_Use_ex() bool {
return true
}
// Effect 2204: 技能威力降低,异常时转为提升
type Effect2204 struct {
node.EffectNode
}
func (e *Effect2204) SkillHit() bool {
if e.Ctx().SkillEntity == nil || len(e.Args()) < 2 {
return true
}
if e.Ctx().Opp.StatEffect_Exist_all() {
e.Ctx().SkillEntity.XML.Power += int(e.Args()[1].IntPart())
}
return true
}
// Effect 2205: 自身异常时克制倍率取最大值
type Effect2205 struct {
node.EffectNode
}
func (e *Effect2205) Damage_Mul(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red || e.Ctx().SkillEntity == nil || !e.Ctx().Our.StatEffect_Exist_all() {
return true
}
if e.Ctx().Our.CurrentPet == nil || e.Ctx().Opp.CurrentPet == nil {
return true
}
attackMul, err := element.Calculator.GetOffensiveMultiplier(e.Ctx().SkillEntity.GetType().ID, e.Ctx().Opp.CurrentPet.GetType().ID)
if err != nil || attackMul <= 0 {
return true
}
counterMul, err := element.Calculator.GetOffensiveMultiplier(e.Ctx().Opp.CurrentPet.GetType().ID, e.Ctx().Our.CurrentPet.GetType().ID)
if err != nil || counterMul <= 0 || counterMul <= attackMul {
return true
}
zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromFloat(counterMul / attackMul))
return true
}
// Effect 2206: 自身能力提升被消除则解除异常
type Effect2206 struct {
node.EffectNode
}
func (e *Effect2206) Skill_Use() bool {
if len(e.Args()) == 0 {
return true
}
sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2206, int(e.Args()[0].IntPart()))
if sub != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, sub)
}
return true
}
type Effect2206Sub struct {
RoundEffectArg0Base
}
func (e *Effect2206Sub) PropBefer(source *input.Input, prop, level int8) bool {
if source != e.Ctx().Opp || level != 0 {
return true
}
if prop < 0 || int(prop) >= len(e.Ctx().Our.Prop) || e.Ctx().Our.Prop[prop] <= 0 {
return true
}
clearOwnStatusEffects(e.Ctx().Our)
return true
}
// Effect 2207: 剩余异常回合数减少
type Effect2207 struct {
node.EffectNode
}
func (e *Effect2207) Skill_Use() bool {
if len(e.Args()) == 0 || e.Ctx().Our == nil {
return true
}
reduce := int(e.Args()[0].IntPart())
if reduce <= 0 {
return true
}
for _, eff := range e.Ctx().Our.Effects {
if eff == nil || !eff.Alive() || eff.ID().GetEffectType() != input.EffectType.Status {
continue
}
if eff.Duration() <= 0 {
continue
}
remaining := eff.Duration() - reduce
if remaining <= 0 {
eff.Alive(false)
continue
}
eff.Duration(remaining)
}
return true
}
// Effect 2208: 星盘每转动时增威力
type Effect2208 struct {
node.EffectNode
}
func (e *Effect2208) OnSkill() bool {
if len(e.Args()) == 0 {
return true
}
if e.Ctx().SkillEntity != nil {
e.Ctx().SkillEntity.XML.Power += int(e.Args()[0].IntPart())
}
return true
}
// Effect 2209: 星盘每转动时吸血
type Effect2209 struct {
node.EffectNode
}
func (e *Effect2209) OnSkill() bool {
if len(e.Args()) == 0 {
return true
}
if e.Ctx().SkillEntity != nil && e.Ctx().Our.CurrentPet != nil && e.Ctx().Opp.CurrentPet != nil {
drain := alpacadecimal.NewFromInt(int64(e.Args()[0].IntPart()))
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 2210: 星赐/星祸转化
type Effect2210 struct {
node.EffectNode
}
func (e *Effect2210) Skill_Use() bool {
if e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().Our.CurrentPet.PetInfo.Type == e.Ctx().Opp.CurrentPet.PetInfo.Type {
return true
}
e.Ctx().SkillEntity.XML.Category = int(info.Category.PHYSICAL)
if e.Ctx().Our.CurrentPet.Info.Dv > 0 {
e.Ctx().SkillEntity.XML.Power += int(e.Ctx().Our.CurrentPet.Info.Dv)
}
return true
}
// Effect 2211: 螺旋之锁
type Effect2211 struct {
node.EffectNode
}
func (e *Effect2211) Skill_Use() bool {
if len(e.Args()) < 3 {
return true
}
statusEffect := e.Ctx().Our.InitEffect(input.EffectType.Status, int(e.Args()[0].IntPart()))
if statusEffect != nil {
e.Ctx().Opp.AddEffect(e.Ctx().Our, statusEffect)
}
return true
}
// Effect 2212: 威力不高于阈值时使对手行动失效
type Effect2212 struct {
node.EffectNode
}
func (e *Effect2212) OnSkill() bool {
if len(e.Args()) < 3 || e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().SkillEntity.XML.Power <= int(e.Args()[1].IntPart()) {
e.Ctx().Opp.CancelTurn(e.Ctx().Our)
}
return true
}
// Effect 2213: 消耗体力时给后排护盾
type Effect2213 struct {
node.EffectNode
}
func (e *Effect2213) OnSkill() bool {
if len(e.Args()) == 0 {
return true
}
if e.Ctx().Our.CurrentPet.GetHP().Cmp(alpacadecimal.Zero) <= 0 {
return true
}
e.Ctx().Our.AddShield(e.Args()[0])
return true
}
// Effect 2214: 螺旋之锁下PP归零
type Effect2214 struct {
node.EffectNode
}
func (e *Effect2214) OnSkill() bool {
if len(e.Args()) < 1 {
return true
}
zeroRandomSkillPP(e.Ctx().Opp, 1)
return true
}
// Effect 2215: 每消耗PP提升威力
type Effect2215 struct {
node.EffectNode
}
func (e *Effect2215) Damage_Mul(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) == 0 || e.Ctx().SkillEntity == nil {
return true
}
skill, ok := xmlres.SkillMap[int(e.Ctx().SkillEntity.Info.ID)]
if !ok || skill.MaxPP <= 0 || e.Args()[0].Cmp(alpacadecimal.Zero) <= 0 {
return true
}
lostPercent := int64(skill.MaxPP-int(e.Ctx().SkillEntity.Info.PP)) * 100 / int64(skill.MaxPP)
step := int64(e.Args()[0].IntPart())
if step <= 0 {
return true
}
tiers := lostPercent / step
if tiers <= 0 {
return true
}
bonus := alpacadecimal.NewFromInt(100 + tiers*step)
zone.Damage = zone.Damage.Mul(bonus).Div(hundred)
return true
}
// Effect 2216: 致命一击时提升威力
type Effect2216 struct {
node.EffectNode
}
func (e *Effect2216) Damage_Mul(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) == 0 {
return true
}
if e.Ctx().SkillEntity != nil && e.Ctx().SkillEntity.Crit != 0 {
zone.Damage = zone.Damage.Mul(hundred.Add(e.Args()[0])).Div(hundred)
}
return true
}
// Effect 2217: 残缺文案占位
type Effect2217 struct {
node.EffectNode
}
func (e *Effect2217) Skill_Use() bool {
if len(e.Args()) < 2 {
return true
}
e.Ctx().Opp.DelPP(int(e.Args()[1].IntPart()))
return true
}
// Effect 2218: 附加回合效果并在特定状态下变换类型
type Effect2218 struct {
node.EffectNode
}
func (e *Effect2218) Skill_Use() bool {
if len(e.Args()) < 3 || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil {
return true
}
targetType := int(e.Args()[1].IntPart())
if e.Ctx().Our.CurrentPet.PetInfo.Type == targetType {
for i := 0; i < 6; i++ {
e.Ctx().Our.SetProp(e.Ctx().Our, int8(i), int8(e.Args()[2].IntPart()))
}
return true
}
sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2218, int(e.Args()[0].IntPart()), targetType)
if sub != nil {
e.Ctx().Our.CurrentPet.PetInfo.Type = targetType
e.Ctx().Our.AddEffect(e.Ctx().Our, sub)
}
return true
}
type Effect2218Sub struct {
node.EffectNode
oldType int
targetType int
}
func (e *Effect2218Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
if e.Ctx() != nil && e.Ctx().Our != nil && e.Ctx().Our.CurrentPet != nil {
e.oldType = e.Ctx().Our.CurrentPet.PetInfo.Type
}
if len(a) > 0 {
e.Duration(a[0])
}
if len(a) > 1 {
e.targetType = a[1]
}
}
func (e *Effect2218Sub) Alive(t ...bool) bool {
if len(t) > 0 && !t[0] && e.Ctx() != nil && e.Ctx().Our != nil && e.Ctx().Our.CurrentPet != nil && e.Ctx().Our.CurrentPet.PetInfo.Type == e.targetType {
e.Ctx().Our.CurrentPet.PetInfo.Type = e.oldType
}
return e.EffectNode.Alive(t...)
}
// Effect 2219: 光辉能量提升至体力比例
type Effect2219 struct {
node.EffectNode
}
func (e *Effect2219) Skill_Use() bool {
if len(e.Args()) == 0 || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil {
return true
}
target := int(e.Ctx().Our.CurrentPet.Info.MaxHp) * int(e.Args()[0].IntPart()) / 100
current := e.Ctx().Our.CurrentDivineEnergy()
if target <= current {
return true
}
e.Ctx().Our.AddDivineEnergy(target - current)
return true
}
func init() {
input.InitEffect(input.EffectType.Skill, 2195, &Effect2195{})
input.InitEffect(input.EffectType.Sub, 2195, &Effect2195Sub{})
input.InitEffect(input.EffectType.Skill, 2196, &Effect2196{})
input.InitEffect(input.EffectType.Skill, 2197, &Effect2197{})
input.InitEffect(input.EffectType.Skill, 2198, &Effect2198{})
input.InitEffect(input.EffectType.Skill, 2199, &Effect2199{})
input.InitEffect(input.EffectType.Skill, 2200, &Effect2200{})
input.InitEffect(input.EffectType.Skill, 2201, &Effect2201{})
input.InitEffect(input.EffectType.Skill, 2202, &Effect2202{})
input.InitEffect(input.EffectType.Skill, 2203, &Effect2203{})
input.InitEffect(input.EffectType.Skill, 2204, &Effect2204{})
input.InitEffect(input.EffectType.Skill, 2205, &Effect2205{})
input.InitEffect(input.EffectType.Skill, 2206, &Effect2206{})
input.InitEffect(input.EffectType.Sub, 2206, &Effect2206Sub{})
input.InitEffect(input.EffectType.Skill, 2207, &Effect2207{})
input.InitEffect(input.EffectType.Skill, 2208, &Effect2208{})
input.InitEffect(input.EffectType.Skill, 2209, &Effect2209{})
input.InitEffect(input.EffectType.Skill, 2210, &Effect2210{})
input.InitEffect(input.EffectType.Skill, 2211, &Effect2211{})
input.InitEffect(input.EffectType.Skill, 2212, &Effect2212{})
input.InitEffect(input.EffectType.Skill, 2213, &Effect2213{})
input.InitEffect(input.EffectType.Skill, 2214, &Effect2214{})
input.InitEffect(input.EffectType.Skill, 2215, &Effect2215{})
input.InitEffect(input.EffectType.Skill, 2216, &Effect2216{})
input.InitEffect(input.EffectType.Skill, 2217, &Effect2217{})
input.InitEffect(input.EffectType.Skill, 2218, &Effect2218{})
input.InitEffect(input.EffectType.Sub, 2218, &Effect2218Sub{})
input.InitEffect(input.EffectType.Skill, 2219, &Effect2219{})
_ = grand.Intn(1)
_ = alpacadecimal.Zero
}