Files
bl/logic/service/fight/effect/678_703.go
xinian 023128be25
Some checks failed
ci/woodpecker/push/my-first-workflow Pipeline failed
feat: 新增战斗效果实现
新增大量战斗效果逻辑实现,包括效果ID 678-708、734-743、744-748,并更新对应的效果描述映射。
2026-03-30 20:19:41 +08:00

586 lines
13 KiB
Go

package effect
import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"math"
"github.com/alpacahq/alpacadecimal"
)
var effect697IgnoredLimitIDs = map[int]struct{}{
8: {},
125: {},
576: {},
}
func restoreTemporarilyDisabledEffects(effects []input.Effect) {
for _, effect := range effects {
if effect == nil {
continue
}
effect.Alive(true)
}
}
// Effect 678: 当回合未击败对手则下{0}回合每回合{1}+{2}
type Effect678 struct {
node.EffectNode
}
func (e *Effect678) Skill_Use() bool {
if len(e.Args()) < 3 || e.Ctx().Opp.CurrentPet.Info.Hp == 0 {
return true
}
effect := e.Ctx().Our.InitEffect(
input.EffectType.Sub,
678,
int(e.Args()[0].IntPart()),
int(e.Args()[1].IntPart()),
int(e.Args()[2].IntPart()),
)
if effect != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, effect)
}
return true
}
type Effect678Sub struct {
RoundEffectArg0Base
}
func (e *Effect678Sub) ActionStart(a, b *action.SelectSkillAction) bool {
if len(e.Args()) < 3 {
return true
}
propID := int8(e.Args()[1].IntPart())
if propID < 0 || int(propID) >= len(e.Ctx().Our.Prop) {
return true
}
e.Ctx().Our.SetProp(e.Ctx().Our, propID, int8(e.Args()[2].IntPart()))
return true
}
// Effect 679: {0}回合内对手无法通过自身技能恢复体力
type Effect679 struct {
node.EffectNode
}
func (e *Effect679) Skill_Use() bool {
if len(e.Args()) == 0 {
return true
}
effect := e.Ctx().Our.InitEffect(input.EffectType.Sub, 679, int(e.Args()[0].IntPart()))
if effect != nil {
e.Ctx().Opp.AddEffect(e.Ctx().Our, effect)
}
return true
}
type Effect679Sub struct {
RoundEffectArg0Base
}
func (e *Effect679Sub) Heal_Pre(ac action.BattleActionI, value *int) bool {
if value == nil || *value <= 0 {
return true
}
if _, ok := ac.(*action.SelectSkillAction); !ok || ac.GetPlayerID() != e.Ctx().Our.UserID {
return true
}
*value = 0
return true
}
// Effect 691: 命中后{0}%秒杀对手
type Effect691 struct {
node.EffectNode
}
func (e *Effect691) DamageFloor(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.AttackTime == 0 {
return true
}
success, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100)
if !success {
return true
}
zone.Damage = e.Ctx().Opp.CurrentPet.GetMaxHP()
return true
}
// Effect 692: {0}回合内免疫受到的致命一击伤害并直接扣除对手等量体力
type Effect692 struct {
node.EffectNode
}
func (e *Effect692) Skill_Use() bool {
if len(e.Args()) == 0 {
return true
}
effect := e.Ctx().Our.InitEffect(input.EffectType.Sub, 692, int(e.Args()[0].IntPart()))
if effect != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, effect)
}
return true
}
type Effect692Sub struct {
RoundEffectArg0Base
}
func (e *Effect692Sub) DamageLockEx(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red {
return true
}
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Crit == 0 {
return true
}
if zone.Damage.Cmp(alpacadecimal.Zero) <= 0 {
return true
}
damage := zone.Damage
zone.Damage = alpacadecimal.Zero
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: damage,
})
return true
}
// Effect 693: 下{0}回合造成的攻击伤害额外提升{1}%
type Effect693 struct {
node.EffectNode
}
func (e *Effect693) Skill_Use() bool {
if len(e.Args()) < 2 {
return true
}
effect := e.Ctx().Our.InitEffect(
input.EffectType.Sub,
693,
int(e.Args()[0].IntPart()),
int(e.Args()[1].IntPart()),
)
if effect != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, effect)
}
return true
}
type Effect693Sub struct {
RoundEffectArg0Base
}
func (e *Effect693Sub) Damage_Mul(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 2 {
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()[1])).Div(hundred)
return true
}
// Effect 694: 下{0}回合攻击必定先出手
type Effect694 struct {
node.EffectNode
}
func (e *Effect694) Skill_Use() bool {
if len(e.Args()) == 0 {
return true
}
effect := e.Ctx().Our.InitEffect(input.EffectType.Sub, 694, int(e.Args()[0].IntPart()))
if effect != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, effect)
}
return true
}
type Effect694Sub struct {
RoundEffectArg0Base
}
func (e *Effect694Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool {
current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID)
if current == nil || current.SkillEntity == nil {
return true
}
if current.SkillEntity.Category() == info.Category.STATUS {
return true
}
current.SkillEntity.XML.Priority = math.MaxInt
return true
}
// Effect 695: {0}回合内{1}%令对手使用的属性技能无效
type Effect695 struct {
node.EffectNode
}
func (e *Effect695) Skill_Use() bool {
if len(e.Args()) < 2 {
return true
}
effect := e.Ctx().Our.InitEffect(
input.EffectType.Sub,
695,
int(e.Args()[0].IntPart()),
int(e.Args()[1].IntPart()),
)
if effect != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, effect)
}
return true
}
type Effect695Sub struct {
RoundEffectArg0Base
}
func (e *Effect695Sub) SkillHit_ex() bool {
if len(e.Args()) < 2 || e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().SkillEntity.Category() != info.Category.STATUS {
return true
}
success, _, _ := e.Input.Player.Roll(int(e.Args()[1].IntPart()), 100)
if success {
e.Ctx().SkillEntity.SetNoSide()
}
return true
}
// Effect 696: 暴击率提升{0}%,每次使用额外提升{1}%,最高概率{2}%
type Effect696 struct {
node.EffectNode
skillID int
useCount int
}
func (e *Effect696) ActionStart(a, b *action.SelectSkillAction) bool {
if len(e.Args()) < 3 || e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
currentSkillID := e.Ctx().SkillEntity.XML.ID
if e.skillID != 0 && e.skillID != currentSkillID {
e.skillID = 0
e.useCount = 0
e.Alive(false)
return true
}
chance := int(e.Args()[0].IntPart()) + e.useCount*int(e.Args()[1].IntPart())
maxChance := int(e.Args()[2].IntPart())
if chance > maxChance {
chance = maxChance
}
e.Ctx().SkillEntity.XML.CritRate += chance
return true
}
func (e *Effect696) SkillHit() bool {
if len(e.Args()) < 3 || e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().SkillEntity.Category() == info.Category.STATUS || e.Ctx().SkillEntity.AttackTime == 0 {
return true
}
e.Duration(-1)
e.CanStack(true)
e.skillID = e.Ctx().SkillEntity.XML.ID
e.useCount++
return true
}
func (e *Effect696) SwitchOut(in *input.Input) bool {
if in == e.Ctx().Our {
e.Alive(false)
}
return true
}
// Effect 697: 无视伤害限制效果
type Effect697 struct {
node.EffectNode
disabled []input.Effect
}
func (e *Effect697) SkillHit() bool {
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
e.disabled = e.disabled[:0]
for _, effect := range e.Ctx().Opp.Effects {
if effect == nil || !effect.Alive() {
continue
}
if _, ok := effect697IgnoredLimitIDs[int(effect.ID().Suffix())]; !ok {
continue
}
effect.Alive(false)
e.disabled = append(e.disabled, effect)
}
return true
}
func (e *Effect697) Skill_Use() bool {
restoreTemporarilyDisabledEffects(e.disabled)
e.disabled = e.disabled[:0]
return true
}
func (e *Effect697) Action_end() bool {
restoreTemporarilyDisabledEffects(e.disabled)
e.disabled = e.disabled[:0]
return true
}
// Effect 698: 当回合击败对手时,对方下只精灵出战时{0}%{1}
type Effect698 struct {
FixedDuration1Base
pending bool
}
func (e *Effect698) SwitchOut(in *input.Input) bool {
if in == e.Ctx().Our {
e.Alive(false)
return true
}
if in != e.Ctx().Opp || e.Ctx().Opp.CurrentPet.Info.Hp > 0 {
return true
}
e.pending = true
return true
}
func (e *Effect698) SwitchIn(in *input.Input) bool {
if !e.pending || in != e.Ctx().Opp || len(e.Args()) < 2 {
return true
}
success, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 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.pending = false
e.Alive(false)
return true
}
// Effect 699: 无视攻击免疫效果
type Effect699 struct {
node.EffectNode
disabled []input.Effect
}
func (e *Effect699) SkillHit() bool {
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
e.disabled = e.disabled[:0]
for _, effect := range e.Ctx().Opp.Effects {
if effect == nil || !effect.Alive() {
continue
}
if _, ok := effect1508IgnoredImmunityIDs[int(effect.ID().Suffix())]; !ok {
continue
}
effect.Alive(false)
e.disabled = append(e.disabled, effect)
}
return true
}
func (e *Effect699) Skill_Use() bool {
restoreTemporarilyDisabledEffects(e.disabled)
e.disabled = e.disabled[:0]
return true
}
func (e *Effect699) Action_end() bool {
restoreTemporarilyDisabledEffects(e.disabled)
e.disabled = e.disabled[:0]
return true
}
// Effect 700: 先出手时降低对手所有PP{0}点
type Effect700 struct {
node.EffectNode
}
func (e *Effect700) OnSkill() bool {
if len(e.Args()) == 0 || !e.IsFirst() {
return true
}
e.Ctx().Opp.DelPP(int(e.Args()[0].IntPart()))
return true
}
// Effect 701: 若对手本回合恢复体力,则下{0}回合自身所有攻击致命一击
type Effect701 struct {
FixedDuration1Base
}
func (e *Effect701) TurnEnd() {
if len(e.Args()) > 0 && e.Ctx().Opp.AttackValue.GainHp > 0 {
effect := e.Ctx().Our.InitEffect(input.EffectType.Sub, 701, int(e.Args()[0].IntPart()))
if effect != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, effect)
}
}
e.EffectNode.TurnEnd()
}
type Effect701Sub struct {
RoundEffectArg0Base
}
func (e *Effect701Sub) ActionStart(a, b *action.SelectSkillAction) bool {
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
e.Ctx().SkillEntity.XML.CritRate = 16
return true
}
// Effect 702: 下{0}回合若打出致命一击则必定恢复全部体力
type Effect702 struct {
node.EffectNode
}
func (e *Effect702) Skill_Use() bool {
if len(e.Args()) == 0 {
return true
}
effect := e.Ctx().Our.InitEffect(input.EffectType.Sub, 702, int(e.Args()[0].IntPart()))
if effect != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, effect)
}
return true
}
type Effect702Sub struct {
RoundEffectArg0Base
}
func (e *Effect702Sub) Skill_Use() bool {
skill := e.Ctx().SkillEntity
if skill == nil || skill.Category() == info.Category.STATUS || skill.AttackTime == 0 || skill.Crit == 0 {
return true
}
e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, e.Ctx().Our.CurrentPet.GetMaxHP())
return true
}
// Effect 703: {0}回合内若对手使用属性技能降低对手最大体力的1/{1}
type Effect703 struct {
node.EffectNode
}
func (e *Effect703) Skill_Use() bool {
if len(e.Args()) < 2 {
return true
}
effect := e.Ctx().Our.InitEffect(
input.EffectType.Sub,
703,
int(e.Args()[0].IntPart()),
int(e.Args()[1].IntPart()),
)
if effect != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, effect)
}
return true
}
type Effect703Sub struct {
RoundEffectArg0Base
}
func (e *Effect703Sub) Skill_Use_ex() bool {
if len(e.Args()) < 2 || e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().SkillEntity.Category() != info.Category.STATUS || e.Args()[1].Cmp(alpacadecimal.Zero) <= 0 {
return true
}
damage := e.Ctx().Opp.CurrentPet.GetMaxHP().Div(e.Args()[1])
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Percent,
Damage: damage,
})
return true
}
func init() {
input.InitEffect(input.EffectType.Skill, 678, &Effect678{})
input.InitEffect(input.EffectType.Sub, 678, &Effect678Sub{})
input.InitEffect(input.EffectType.Skill, 679, &Effect679{})
input.InitEffect(input.EffectType.Sub, 679, &Effect679Sub{})
input.InitEffect(input.EffectType.Skill, 691, &Effect691{})
input.InitEffect(input.EffectType.Skill, 692, &Effect692{})
input.InitEffect(input.EffectType.Sub, 692, &Effect692Sub{})
input.InitEffect(input.EffectType.Skill, 693, &Effect693{})
input.InitEffect(input.EffectType.Sub, 693, &Effect693Sub{})
input.InitEffect(input.EffectType.Skill, 694, &Effect694{})
input.InitEffect(input.EffectType.Sub, 694, &Effect694Sub{})
input.InitEffect(input.EffectType.Skill, 695, &Effect695{})
input.InitEffect(input.EffectType.Sub, 695, &Effect695Sub{})
input.InitEffect(input.EffectType.Skill, 696, &Effect696{})
input.InitEffect(input.EffectType.Skill, 697, &Effect697{})
input.InitEffect(input.EffectType.Skill, 698, &Effect698{})
input.InitEffect(input.EffectType.Skill, 699, &Effect699{})
input.InitEffect(input.EffectType.Skill, 700, &Effect700{})
input.InitEffect(input.EffectType.Skill, 701, &Effect701{})
input.InitEffect(input.EffectType.Sub, 701, &Effect701Sub{})
input.InitEffect(input.EffectType.Skill, 702, &Effect702{})
input.InitEffect(input.EffectType.Sub, 702, &Effect702Sub{})
input.InitEffect(input.EffectType.Skill, 703, &Effect703{})
input.InitEffect(input.EffectType.Sub, 703, &Effect703Sub{})
}