feat(effect): 实现多个新技能效果逻辑

新增了多个宠物战斗中的技能效果实现,包括伤害反弹、必杀技增强、先手权调整、
回复机制以及特殊条件触发逻辑。同时修复了部分技能判断条件与执行顺序问题,
优化了 AI 在 NPC 战斗中的行为表现,并完善了相关配置文件内容。
This commit is contained in:
2025-11-26 18:39:23 +08:00
parent 0ea1a24419
commit f15f08189f
26 changed files with 332 additions and 17 deletions

View File

@@ -1,7 +1,10 @@
package effect
import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"github.com/shopspring/decimal"
)
// 11. 受到任何攻击都会反弹1/n的伤害给对方;a1: n
@@ -10,6 +13,25 @@ type NewSel11 struct {
NewSel0
}
func (e *NewSel11) Skill_Use_ex() bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
//不是技能
if e.Ctx().SkillEntity == nil {
return true
}
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: decimal.NewFromInt(int64(e.Ctx().Opp.SumDamage.IntPart())).Div(decimal.NewFromInt(int64(e.SideEffectArgs[0]))),
})
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 11, &NewSel11{})
}

View File

@@ -1,6 +1,8 @@
package effect
import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
)
@@ -10,6 +12,24 @@ type NewSel17 struct {
NewSel0
}
func (e *NewSel17) Action_start(a, b *action.SelectSkillAction) bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
//fmt.Println(e.Ctx().SkillEntity)
if e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
full32 := int64(e.Args()[0])<<32 | int64(e.Args()[1])
if e.Ctx().Our.CurrentPet.HP <= int(full32) {
e.Ctx().SkillEntity.CritRate = 16
}
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 17, &NewSel17{})
}

View File

@@ -1,6 +1,8 @@
package effect
import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
)
@@ -10,6 +12,20 @@ type NewSel18 struct {
NewSel0
}
func (e *NewSel18) Action_start(a, b *action.SelectSkillAction) bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
//fmt.Println(e.Ctx().SkillEntity)
if e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
e.Ctx().SkillEntity.MustHit = 1
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 18, &NewSel18{})
}

View File

@@ -1,7 +1,9 @@
package effect
import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/input"
"math"
)
// 19. 自身所有技能必先出手;
@@ -10,6 +12,32 @@ type NewSel19 struct {
NewSel0
}
func (e *NewSel19) Compare_Pre(fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
if fattack == nil {
return true
}
//先手是自己
if fattack.PlayerID == e.Ctx().Our.UserID {
return true
}
if sattack == nil {
return true
}
if sattack == nil {
return true
}
if sattack.SkillEntity == nil {
return true
}
//对调
sattack.SkillEntity.Priority = math.MaxInt
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 19, &NewSel19{})
}

View File

@@ -18,6 +18,9 @@ func (e *NewSel22) Damage_DIV_ex(t *info.DamageZone) bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
if t.Type != info.DamageType.Red {
return true
}
t.Damage = t.Damage.Mul(decimal.NewFromInt(int64(e.Args()[0])))
return true

View File

@@ -1,7 +1,12 @@
package effect
import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"math"
"github.com/shopspring/decimal"
)
// 23. 自身体力降到N以下时, 每次(针对多宠)攻击必定秒杀对方, 且必定先手;a1: high 16, a2: low 16
@@ -10,6 +15,46 @@ type NewSel23 struct {
NewSel0
}
func (e *NewSel23) Compare_Pre(fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
if fattack == nil {
return true
}
//先手是自己
if fattack.PlayerID == e.Ctx().Our.UserID {
return true
}
if sattack == nil {
return true
}
if sattack.SkillEntity == nil {
return true
}
full32 := int(e.Args()[0])<<16 | int(e.Args()[1])
if int(e.Ctx().Our.CurrentPet.Info.Hp) <= full32 {
sattack.SkillEntity.Priority = math.MaxInt
}
return true
}
func (e *NewSel23) OnSkill() bool {
full32 := int(e.Args()[0])<<16 | int(e.Args()[1])
if int(e.Ctx().Our.CurrentPet.Info.Hp) <= full32 {
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Red,
Damage: decimal.NewFromInt(int64(e.Ctx().Opp.GetPetInfo().Info.MaxHp)),
})
}
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 23, &NewSel23{})
}

View File

@@ -2,6 +2,8 @@ package effect
import (
"blazing/logic/service/fight/input"
"github.com/shopspring/decimal"
)
// 25. 如果 hp 被打成 0, 则立刻增加一些hp
@@ -10,6 +12,18 @@ type NewSel25 struct {
NewSel0
}
func (e *NewSel25) Action_end_ex() bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
if e.Ctx().Our.CurrentPet.Info.Hp == 0 {
e.Ctx().Our.Heal(e.Ctx().Our, nil, decimal.NewFromInt(1))
}
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 25, &NewSel25{})
}

View File

@@ -23,16 +23,15 @@ func (e *NewSel27) Damage_DIV_ex(t *info.DamageZone) bool {
if e.Ctx().SkillEntity == nil {
return true
}
if e.Args()[e.index] == e.Ctx().SkillEntity.Type {
return true
}
e.index++
if e.index >= len(e.Args()) {
e.index = 0
}
if e.Args()[e.index] == e.Ctx().SkillEntity.Type {
e.index++
return true
}
t.Damage = decimal.NewFromInt(0)
return true

View File

@@ -10,6 +10,24 @@ type NewSel31 struct {
NewSel0
}
func (e *NewSel31) Action_end_ex() bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
// 3. 概率判定Args()[1]为触发概率)
success, _, _ := e.Input.Player.Roll(e.Args()[0], 100)
if !success {
return true
}
if e.Ctx().Our.CurrentPet.Info.Hp == 0 {
e.Ctx().Our.CurrentPet.Info.Hp = uint32(e.Args()[1])
}
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 31, &NewSel31{})
}

View File

@@ -10,6 +10,24 @@ type NewSel33 struct {
NewSel0
}
func (e *NewSel33) Action_end_ex() bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
// 3. 概率判定Args()[1]为触发概率)
success, _, _ := e.Input.Player.Roll(e.Args()[0], 100)
if !success {
return true
}
if e.Ctx().Our.CurrentPet.Info.Hp == 0 {
e.Ctx().Our.Heal(e.Ctx().Our, nil, e.Ctx().Our.GetPetInfo().GetMaxHP())
}
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 33, &NewSel33{})
}

View File

@@ -30,7 +30,7 @@ func (e *NewSel34) Damage_DIV_ex(t *info.DamageZone) bool {
return true
}
e.Ctx().Opp.SetProp(e.Ctx().Our, int8(e.Args()[0]), 1, info.AbilityOpType.SUB)
e.Ctx().Opp.SetProp(e.Ctx().Opp, int8(e.Args()[0]), -1, info.AbilityOpType.SUB)
return true
}
func init() {

View File

@@ -12,6 +12,8 @@ type NewSel35 struct {
}
func (e *NewSel35) Damage_DIV_ex(t *info.DamageZone) bool {
// fmt.Println(e.ID().GetCatchTime(), e.Ctx().Our.CurrentPet.Info.CatchTime)
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}

View File

@@ -1,6 +1,7 @@
package effect
import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
)
@@ -10,6 +11,19 @@ type NewSel37 struct {
NewSel0
}
func (e *NewSel37) Damage_Lock_ex(t *info.DamageZone) bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
if t.Damage.IntPart() > int64(e.Args()[0]) {
e.Ctx().Opp.CurrentPet.Info.Hp = 0
}
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 37, &NewSel37{})
}

View File

@@ -1,7 +1,10 @@
package effect
import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"github.com/shopspring/decimal"
)
// 38. 自身造成的伤害增加n%;a1: n 百分比)
@@ -10,6 +13,16 @@ type NewSel38 struct {
NewSel0
}
func (e *NewSel39) Damage_ADD(t *info.DamageZone) bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
t.Damage = t.Damage.Add(t.Damage.Mul(decimal.NewFromInt(int64(e.Args()[0]))))
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 38, &NewSel38{})
}

View File

@@ -1,7 +1,10 @@
package effect
import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"github.com/shopspring/decimal"
)
// 39. 偶数伤害(dmg) 提升到 n * dmg;a1: n
@@ -10,6 +13,19 @@ type NewSel39 struct {
NewSel0
}
func (e *NewSel39) Damage_Floor(t *info.DamageZone) bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
if t.Damage.IntPart()%2 == 0 {
t.Damage = t.Damage.Mul(decimal.NewFromInt(int64(e.Args()[0])))
}
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 39, &NewSel39{})
}

View File

@@ -1,7 +1,10 @@
package effect
import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"github.com/shopspring/decimal"
)
// 40. 奇数伤害(dmg) 改为 1/n * dmg;a1: n
@@ -10,6 +13,19 @@ type NewSel40 struct {
NewSel0
}
func (e *NewSel40) Damage_Floor(t *info.DamageZone) bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
if t.Damage.IntPart()%2 != 0 {
t.Damage = t.Damage.Mul(decimal.NewFromInt(1 / int64(e.Args()[0])))
}
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 40, &NewSel40{})
}

View File

@@ -2,6 +2,8 @@ package effect
import (
"blazing/logic/service/fight/input"
"github.com/shopspring/decimal"
)
// 41. 每回合恢复自身n点体力a1: n
@@ -10,6 +12,11 @@ type NewSel41 struct {
NewSel0
}
func (e *NewSel41) Turn_End() {
e.Ctx().Our.Heal(e.Ctx().Our, nil, decimal.NewFromInt(int64(e.Args()[0])))
}
func init() {
input.InitEffect(input.EffectType.NewSel, 41, &NewSel41{})
}

View File

@@ -1,6 +1,8 @@
package effect
import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
)
@@ -10,6 +12,21 @@ type NewSel45 struct {
NewSel0
}
func (e *NewSel45) Action_start(a, b *action.SelectSkillAction) bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
//fmt.Println(e.Ctx().SkillEntity)
if e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
e.Ctx().SkillEntity.CritRate = e.Args()[0]
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 45, &NewSel45{})
}

View File

@@ -1,6 +1,7 @@
package effect
import (
element "blazing/common/data/Element"
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
)
@@ -19,6 +20,9 @@ func (e *NewSel6) Damage_Lock_ex(t *info.DamageZone) bool {
if e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().SkillEntity.Type != int(element.ElementTypeNormal) {
return true
}
// 3. 概率判定Args()[1]为触发概率)
success, _, _ := e.Input.Player.Roll(e.Args()[1], 100)

View File

@@ -10,6 +10,19 @@ type NewSel9 struct {
NewSel0
}
func (e *NewSel9) Action_end_ex() bool {
if e.ID().GetCatchTime() != e.Ctx().Our.CurrentPet.Info.CatchTime {
return true
}
full32 := int64(e.Args()[0])<<32 | int64(e.Args()[1])
if e.Ctx().Our.CurrentPet.Info.Hp > uint32(e.Args()[0]) && e.Ctx().Our.CurrentPet.Info.Hp < uint32(full32) {
e.Ctx().Our.Heal(e.Ctx().Our, nil, e.Ctx().Our.CurrentPet.GetMaxHP())
}
return true
}
func init() {
input.InitEffect(input.EffectType.NewSel, 9, &NewSel9{})
}

View File

@@ -5,6 +5,7 @@ import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"math"
)
/**
@@ -49,8 +50,14 @@ func (e *Effect83) Compare_Pre(fattack *action.SelectSkillAction, sattack *actio
if fattack.PlayerID == e.Ctx().Our.UserID {
return true
}
if sattack == nil {
return true
}
if sattack.SkillEntity == nil {
return true
}
//对调
*fattack, *sattack = *sattack, *fattack
sattack.SkillEntity.Priority = math.MaxInt
return true
}

View File

@@ -6,6 +6,7 @@ import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/player"
"blazing/modules/blazing/model"
"fmt"
"reflect"
@@ -299,6 +300,13 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
f.closefight = true
// break
}
if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC {
if _, ok := defender.Player.(*player.AI_player); ok {
defender.GetAction(f.Our)
//panic("AI自动技能")
}
}
attacker.CanChange = true
break
}
@@ -325,8 +333,11 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
} else {
if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC {
defender.GetAction(f.Our)
//panic("AI自动技能")
if _, ok := defender.Player.(*player.AI_player); ok {
defender.GetAction(f.Our)
//panic("AI自动技能")
}
}
}
break

View File

@@ -69,7 +69,7 @@ func (e EffectIDCombiner) GetEffectType() EnumEffectType {
// 参数t可选传入则替换当前CatchTime不传则仅读取
// 返回当前的CatchTime值
func (e *EffectIDCombiner) SetCatchTime(t ...uint32) {
e.Base = (e.Base & ^catchMask) | (int64(t[0]) << catchOffset)
}
func (e EffectIDCombiner) GetCatchTime() uint32 {

View File

@@ -81,8 +81,11 @@ func (our *Input) SortPet() {
t := Geteffect(EffectType.NewSel, e1.EID)
if t != nil {
ef := t.ID()
ef.SetCatchTime(v.Info.CatchTime)
t.ID(ef)
t.Duration(-1)
t.SetArgs(our, e1.Args...) //设置入参,施加方永远是我方
our.AddEffect(our, t)

View File

@@ -307,17 +307,22 @@ func (f *FightC) handleSkillActions(a1, a2 action.BattleActionI) {
switch {
case s1 == nil || s1.SkillEntity == nil:
if s2.CD != nil {
f.waittime = *s2.CD
if s2.SkillEntity != nil {
if s2.CD != nil {
f.waittime = *s2.CD
}
}
f.enterturn(s2, nil)
fmt.Println("1 空过 2玩家执行技能:", s2.PlayerID, s2.Info.ID)
// fmt.Println("1 空过 2玩家执行技能:", s2.PlayerID, s2.Info.ID)
case s2 == nil || s2.SkillEntity == nil:
if s1.CD != nil {
f.waittime = *s1.CD
if s1.SkillEntity != nil {
if s1.CD != nil {
f.waittime = *s1.CD
}
}
f.enterturn(s1, nil)
fmt.Println("2 空过 玩家执行技能:", s1.PlayerID, s1.Info.ID)
//fmt.Println("2 空过 玩家执行技能:", s1.PlayerID, s1.Info.ID)
default:
if s1.CD != nil {
f.waittime = *s1.CD

View File

@@ -384,6 +384,7 @@ eg:
<Map ID="6" Name="动力室" InitX="138" InitY="246" StarExplorationID="22">
<Bosses>
<Boss AppearTime="0 23" BossVisible="0" >
<BossMon MonID="1 4 7" Hp="10" Lv="2" />
</Boss>
@@ -413,6 +414,8 @@ eg:
<Bosses>
<Boss Id="0" AppearTime="0 23" BossVisible="0" >
<BossMon MonID="125" Hp="5000" Lv="100" NewSeIdxs="1 2 58 78 80 86"/>
<BossMon MonID="111" Hp="5000" Lv="100" NewSeIdxs="1 2 58 78 80 86"/>
<BossMon MonID="50" Hp="5000" Lv="100" NewSeIdxs="1 2 58 78 80 86"/>
</Boss>
<Boss Id="1" BossCatchable="1" TaskID="1122" AppearTime="19 21" BossVisible="0" BossFinTaskWay="2">
<BossMon MonID="807" Hp="68" Lv="25" />
@@ -1802,6 +1805,7 @@ eg:
<Boss Id="0" TaskID="311" AppearTime="0 23" BossVisible="0" Name="SPT哈莫雷特"
BonusProbability="20" BonusTotalProbability="1000" BonusID="5017" ItemBonusOutID="2">
<BossMon MonID="216" Hp="3000" Lv="80" NewSeIdxs="10 89 90"/>
</Boss>
<!-- <Boss Id="0" TaskID="353" BossVisible="0" AppearTime="0 23" Name="SPT克鲁斯" SptLevel="1">
<BossMon MonID="1521" Hp="6000" Lv="100" NewSeIdxs="58 95 300 301 311 1489 1490" />