From 0f862453cb9a639972323d89ae184801bb3988a2 Mon Sep 17 00:00:00 2001 From: xinian Date: Sat, 4 Apr 2026 01:17:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=E6=88=98=E6=96=97?= =?UTF-8?q?=E6=95=88=E6=9E=9C1543-1547=E5=92=8C1573-1577?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- logic/service/fight/effect/1543_1547.go | 179 +++++++++++++++++ logic/service/fight/effect/1573_1577.go | 243 ++++++++++++++++++++++++ 2 files changed, 422 insertions(+) create mode 100644 logic/service/fight/effect/1543_1547.go create mode 100644 logic/service/fight/effect/1573_1577.go diff --git a/logic/service/fight/effect/1543_1547.go b/logic/service/fight/effect/1543_1547.go new file mode 100644 index 000000000..84eb60862 --- /dev/null +++ b/logic/service/fight/effect/1543_1547.go @@ -0,0 +1,179 @@ +package effect + +import ( + "sync" + + "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" +) + +type chargeRecord struct { + mu sync.Mutex + layers int + skipConsume bool +} + +var chargeRegistry sync.Map // key uint32 -> *chargeRecord + +func getChargeRecord(in *input.Input) *chargeRecord { + if in == nil || in.Player == nil { + return nil + } + userID := in.Player.GetInfo().UserID + value, _ := chargeRegistry.LoadOrStore(userID, &chargeRecord{}) + return value.(*chargeRecord) +} + +func (c *chargeRecord) addLayers(delta int) { + c.mu.Lock() + defer c.mu.Unlock() + c.layers += delta + if c.layers < 0 { + c.layers = 0 + } +} + +func (c *chargeRecord) setSkipConsume(skip bool) { + if c == nil { + return + } + c.mu.Lock() + c.skipConsume = skip + c.mu.Unlock() +} + +func (c *chargeRecord) getLayers() int { + if c == nil { + return 0 + } + c.mu.Lock() + defer c.mu.Unlock() + return c.layers +} + +func (c *chargeRecord) shouldSkipConsume() bool { + if c == nil { + return false + } + c.mu.Lock() + defer c.mu.Unlock() + skip := c.skipConsume + c.skipConsume = false + return skip +} + +// Effect 1543: 当回合击败对手则不消耗蓄力层数 +type Effect1543 struct { + node.EffectNode +} + +func (e *Effect1543) TurnEnd() { + if e.Ctx().Opp != nil && e.Ctx().Opp.CurrentPet != nil && e.Ctx().Opp.CurrentPet.Info.Hp == 0 { + setChargeSkip(e.Ctx().Our) + } + e.EffectNode.TurnEnd() +} + +func setChargeSkip(our *input.Input) { + if rec := getChargeRecord(our); rec != nil { + rec.setSkipConsume(true) + } +} + +// Effect 1544: 对手存在护盾时先制+1 +type Effect1544 struct { + node.EffectNode +} + +func (e *Effect1544) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if e.Ctx().Opp == nil || e.Ctx().Opp.CurrentShield().Cmp(alpacadecimal.Zero) <= 0 { + return true + } + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current == nil || current.SkillEntity == nil { + return true + } + current.SkillEntity.XML.Priority++ + return true +} + +// Effect 1545: 消除对手所有护盾效果,消除成功则为自身附加等量的护盾值 +type Effect1545 struct { + node.EffectNode +} + +func (e *Effect1545) Skill_Use() bool { + if e.Ctx().Opp == nil || e.Ctx().Our == nil { + return true + } + shield := e.Ctx().Opp.ConsumeAllShield() + if shield.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Our.AddShield(shield) + } + return true +} + +// Effect 1546: 1回合做{0}-{1}次攻击,自身每存在1层蓄力则连击上限次数额外增加{2}次 +type Effect1546 struct { + node.EffectNode +} + +func (e *Effect1546) SkillHit() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || len(e.Args()) < 3 { + return true + } + min := int(e.Args()[0].IntPart()) + max := int(e.Args()[1].IntPart()) + if max < min { + min, max = max, min + } + if max < 1 { + max = 1 + } + hits := min + if max > min { + hits += grand.Intn(max - min + 1) + } + if rec := getChargeRecord(e.Ctx().Our); rec != nil { + hits += rec.getLayers() * int(e.Args()[2].IntPart()) + } + if hits <= 0 { + hits = 1 + } + e.Ctx().SkillEntity.AttackTime = uint32(hits) + return true +} + +// Effect 1547: 自身每存在3层蓄力先制额外+1 +type Effect1547 struct { + node.EffectNode +} + +func (e *Effect1547) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if e.Ctx().SkillEntity == nil { + return true + } + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current == nil || current.SkillEntity == nil { + return true + } + layers := getChargeRecord(e.Ctx().Our).getLayers() + if layers <= 0 { + return true + } + current.SkillEntity.XML.Priority += layers / 3 + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1543, &Effect1543{}) + input.InitEffect(input.EffectType.Skill, 1544, &Effect1544{}) + input.InitEffect(input.EffectType.Skill, 1545, &Effect1545{}) + input.InitEffect(input.EffectType.Skill, 1546, &Effect1546{}) + input.InitEffect(input.EffectType.Skill, 1547, &Effect1547{}) +} diff --git a/logic/service/fight/effect/1573_1577.go b/logic/service/fight/effect/1573_1577.go new file mode 100644 index 000000000..bc8e6e108 --- /dev/null +++ b/logic/service/fight/effect/1573_1577.go @@ -0,0 +1,243 @@ +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 ( + statusSaintEffect = 3001 + statusDemonEffect = 3002 +) + +var hundred = alpacadecimal.NewFromInt(100) + +func isStatusActive(target *input.Input, statusID int) bool { + if target == nil || statusID <= 0 { + return false + } + eff := target.GetEffect(input.EffectType.Status, statusID) + return eff != nil && eff.Alive() +} + +func addStatusByID(owner, target *input.Input, statusID int) bool { + if owner == nil || target == nil || statusID <= 0 { + return false + } + eff := owner.InitEffect(input.EffectType.Status, statusID) + if eff == nil { + return false + } + target.AddEffect(owner, eff) + return true +} + +// Effect 1573: 自身为圣念状态时下2回合受到的攻击伤害减少50%,自身为邪念状态时下2回合造成的攻击伤害提升50% +type Effect1573 struct{ node.EffectNode } + +func (e *Effect1573) DamageDivEx(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red { + return true + } + if hasSaint := isStatusActive(e.Ctx().Our, statusSaintEffect); hasSaint { + zone.Damage = zone.Damage.Div(alpacadecimal.NewFromInt(2)) + return true + } + if isStatusActive(e.Ctx().Our, statusDemonEffect) { + zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(3)).Div(alpacadecimal.NewFromInt(2)) + } + return true +} + +// Effect 1574: 附加自身攻击值与速度值总和{0}%的百分比伤害,每次使用增加{1}%,最高{2}% +type Effect1574 struct { + node.EffectNode + currentPercent alpacadecimal.Decimal + increment alpacadecimal.Decimal + maxPercent alpacadecimal.Decimal +} + +func (e *Effect1574) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + if len(a) >= 1 { + e.currentPercent = alpacadecimal.NewFromInt(int64(a[0])) + } + if len(a) >= 2 { + e.increment = alpacadecimal.NewFromInt(int64(a[1])) + } + if len(a) >= 3 { + e.maxPercent = alpacadecimal.NewFromInt(int64(a[2])) + } + if e.maxPercent.Cmp(alpacadecimal.Zero) <= 0 { + e.maxPercent = alpacadecimal.NewFromInt(100) + } +} + +func (e *Effect1574) DamageAdd(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + if e.currentPercent.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + sum := e.Ctx().Our.GetProp(0).Add(e.Ctx().Our.GetProp(4)) + if sum.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + extra := sum.Mul(e.currentPercent).Div(hundred) + if extra.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + zone.Damage = zone.Damage.Add(extra) + + if e.increment.Cmp(alpacadecimal.Zero) > 0 && e.currentPercent.Cmp(e.maxPercent) < 0 { + e.currentPercent = e.currentPercent.Add(e.increment) + if e.currentPercent.Cmp(e.maxPercent) > 0 { + e.currentPercent = e.maxPercent + } + } + return true +} + +// Effect 1575: 下{0}回合后出手则对手{1} +type Effect1575 struct{ node.EffectNode } + +func (e *Effect1575) Skill_Use() bool { + if len(e.Args()) < 2 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1575, int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1575Sub struct { + RoundEffectArg0Base + statusID int +} + +func (e *Effect1575Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + e.CanStack(false) + if len(a) >= 1 { + e.Duration(a[0]) + } + if len(a) >= 2 { + e.statusID = a[1] + } +} + +func (e *Effect1575Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + if e.IsFirst() { + return true + } + addStatusByID(e.Ctx().Our, e.Ctx().Opp, e.statusID) + e.Alive(false) + return true +} + +// Effect 1576: 消耗自身全部体力,使对手{0}回合内无法通过自身技能恢复体力 +type Effect1576 struct{ node.EffectNode } + +func (e *Effect1576) Skill_Use() bool { + if e.Ctx().Our == nil || e.Ctx().Opp == nil || e.Ctx().Our.CurrentPet == nil { + return true + } + damage := e.Ctx().Our.CurrentPet.GetHP() + if damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Fixed, Damage: damage}) + + if len(e.Args()) == 0 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1576, int(e.Args()[0].IntPart())) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1576Sub struct { + RoundEffectArg0Base +} + +func (e *Effect1576Sub) Heal_Pre(ac action.BattleActionI, value *int) bool { + if value == nil || *value <= 0 { + return true + } + skill, ok := ac.(*action.SelectSkillAction) + if !ok || skill.GetPlayerID() != e.Ctx().Opp.Player.GetInfo().UserID { + return true + } + *value = 0 + return true +} + +// Effect 1577: {0}回合做{1}-{2}次攻击,当前技能PP值小于{3}时连击上限为{4} +type Effect1577 struct { + RoundEffectArg0Base +} + +func (e *Effect1577) Skill_Use() bool { + if len(e.Args()) < 5 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1577, e.SideEffectArgs...) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +func (e *Effect1577) SkillHit() bool { + if len(e.Args()) < 5 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || e.Ctx().SkillEntity.AttackTime == 0 { + return true + } + + minHits := int(e.Args()[1].IntPart()) + maxHits := int(e.Args()[2].IntPart()) + if maxHits < minHits { + maxHits = minHits + } + times := minHits + if maxHits > minHits { + times = minHits + grand.Intn(maxHits-minHits+1) + } + if skill := e.Ctx().SkillEntity.Info; skill != nil { + threshold := e.Args()[3].IntPart() + if threshold >= 0 && int(skill.PP) <= int(threshold) { + times = int(e.Args()[4].IntPart()) + } + } + if times <= 1 { + return true + } + + e.Ctx().SkillEntity.AttackTime += uint32(times - 1) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1573, &Effect1573{}) + input.InitEffect(input.EffectType.Skill, 1574, &Effect1574{}) + input.InitEffect(input.EffectType.Skill, 1575, &Effect1575{}) + input.InitEffect(input.EffectType.Sub, 1575, &Effect1575Sub{}) + input.InitEffect(input.EffectType.Skill, 1576, &Effect1576{}) + input.InitEffect(input.EffectType.Sub, 1576, &Effect1576Sub{}) + input.InitEffect(input.EffectType.Skill, 1577, &Effect1577{}) +}