Files
bl/logic/service/fight/effect/1498_1502.go
xinian 87fdccaddf
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
feat: 实现大量技能效果及战斗逻辑修复
2026-03-30 00:51:18 +08:00

268 lines
5.9 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"
"github.com/alpacahq/alpacadecimal"
"github.com/gogf/gf/v2/util/grand"
)
const petStatusDazed info.EnumPetStatus = 29
var effect1498Statuses = []int{
int(info.PetStatus.Burned),
int(info.PetStatus.Frozen),
int(info.PetStatus.Blind),
int(petStatusDazed),
}
func applyRandomStatuses1498(owner, target *input.Input, count int) int {
if owner == nil || target == nil || count <= 0 {
return 0
}
if count > len(effect1498Statuses) {
count = len(effect1498Statuses)
}
added := 0
indexes := grand.Perm(len(effect1498Statuses))
for _, idx := range indexes[:count] {
statusEffect := owner.InitEffect(input.EffectType.Status, effect1498Statuses[idx])
if statusEffect == nil {
continue
}
before := len(target.Effects)
target.AddEffect(owner, statusEffect)
if len(target.Effects) > before {
added++
}
}
return added
}
func reduceRandomSkillPP(target *input.Input) {
if target == nil {
return
}
skills := target.CurrentPet.Info.SkillList
if len(skills) == 0 {
return
}
idx := grand.Intn(len(skills))
if skills[idx].PP > 0 {
skills[idx].PP--
}
}
func hasDarkSeed(target *input.Input) bool {
if target == nil {
return false
}
effect := target.GetEffect(input.EffectType.Sub, 1501)
return effect != nil && effect.Alive()
}
// Effect 1498: 随机附加烧伤,冻伤,失明,失神中的{0}种异常状态,未触发则自身下{1}回合造成的伤害提升{2}%
type Effect1498 struct {
node.EffectNode
}
func (e *Effect1498) OnSkill() bool {
if len(e.Args()) < 3 {
return true
}
if applyRandomStatuses1498(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[0].IntPart())) > 0 {
return true
}
boostEffect := e.Ctx().Our.InitEffect(
input.EffectType.Sub,
1498,
int(e.Args()[1].IntPart()),
int(e.Args()[2].IntPart()),
)
if boostEffect != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, boostEffect)
}
return true
}
type Effect1498Sub struct {
node.EffectNode
percent alpacadecimal.Decimal
}
func (e *Effect1498Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
if len(a) > 0 {
e.Duration(a[0])
}
if len(a) > 1 {
e.percent = alpacadecimal.NewFromInt(int64(a[1]))
}
}
func (e *Effect1498Sub) Damage_Mul(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red {
return true
}
zone.Damage = zone.Damage.Mul(hundred.Add(e.percent)).Div(hundred)
return true
}
// Effect 1499: 体力低于最大体力的1/3时先制+3
type Effect1499 struct {
node.EffectNode
}
func (e *Effect1499) ComparePre(fattack, sattack *action.SelectSkillAction) bool {
current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID)
if current == nil || current.SkillEntity == nil {
return true
}
maxHP := e.Ctx().Our.CurrentPet.GetMaxHP()
if e.Ctx().Our.CurrentPet.GetHP().Mul(alpacadecimal.NewFromInt(3)).Cmp(maxHP) >= 0 {
return true
}
current.SkillEntity.XML.Priority += 3
return true
}
// Effect 1500: 1回合做{0}-{1}次攻击,自身处于护盾状态下连击上限为{2}
// 当前战斗模型未逐段执行多段攻击,这里按随机连击次数折算为红伤倍率提升。
type Effect1500 struct {
node.EffectNode
}
func (e *Effect1500) Damage_Mul(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red {
return true
}
if len(e.Args()) < 3 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
minHits := int(e.Args()[0].IntPart())
maxHits := int(e.Args()[1].IntPart())
if minHits <= 0 {
minHits = 1
}
if maxHits < minHits {
maxHits = minHits
}
if e.Ctx().Our.HasShield() {
shieldCap := int(e.Args()[2].IntPart())
if shieldCap > 0 && shieldCap < maxHits {
maxHits = shieldCap
}
if maxHits < minHits {
maxHits = minHits
}
}
hits := minHits
if maxHits > minHits {
hits += grand.Intn(maxHits - minHits + 1)
}
zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(int64(hits)))
return true
}
// Effect 1501: 命中后为对手种下一颗黑暗之种
type Effect1501 struct {
node.EffectNode
}
func (e *Effect1501) Skill_Use() bool {
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.AttackTime == 0 {
return true
}
if e.Ctx().Opp.CurrentPet.Info.Hp <= 0 {
return true
}
darkSeed := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1501)
if darkSeed != nil {
e.Ctx().Opp.AddEffect(e.Ctx().Our, darkSeed)
}
return true
}
type Effect1501Sub struct {
node.EffectNode
stage int
}
func (e *Effect1501Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.Duration(-1)
e.CanStack(false)
}
func (e *Effect1501Sub) SwitchOut(in *input.Input) bool {
if in == e.Ctx().Our {
e.Alive(false)
}
return true
}
func (e *Effect1501Sub) TurnEnd() {
if e.Ctx().Our.CurrentPet.Info.Hp <= 0 {
return
}
if e.stage >= 4 {
e.Ctx().Our.DelPP(1)
return
}
reduceRandomSkillPP(e.Ctx().Our)
e.stage++
}
// Effect 1502: 对手身上存在黑暗之种时先制+1
type Effect1502 struct {
node.EffectNode
}
func (e *Effect1502) ComparePre(fattack, sattack *action.SelectSkillAction) bool {
if !hasDarkSeed(e.Ctx().Opp) {
return true
}
current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID)
if current == nil || current.SkillEntity == nil {
return true
}
current.SkillEntity.XML.Priority += 1
return true
}
func init() {
dazed := &StatusCannotAct{}
dazed.Status = petStatusDazed
input.InitEffect(input.EffectType.Status, int(petStatusDazed), dazed)
input.InitEffect(input.EffectType.Skill, 1498, &Effect1498{})
input.InitEffect(input.EffectType.Sub, 1498, &Effect1498Sub{})
input.InitEffect(input.EffectType.Skill, 1499, &Effect1499{})
input.InitEffect(input.EffectType.Skill, 1500, &Effect1500{})
input.InitEffect(input.EffectType.Skill, 1501, &Effect1501{})
input.InitEffect(input.EffectType.Sub, 1501, &Effect1501Sub{})
input.InitEffect(input.EffectType.Skill, 1502, &Effect1502{})
}