Files
bl/logic/service/fight/effect/1097_1101.go

599 lines
14 KiB
Go
Raw Normal View History

package effect
import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"blazing/modules/player/model"
"github.com/alpacahq/alpacadecimal"
"github.com/gogf/gf/v2/util/grand"
)
var hundred = alpacadecimal.NewFromInt(100)
// Effect 1097: 造成的攻击伤害若低于280则令对手疲惫未击败对手则令对手下1回合使用的攻击技能无效;
// 技能结束后对手体力值高于0则50%进行一次额外行动以触发星皇之怒
type Effect1097 struct {
node.EffectNode
starFuryActive bool
}
func (e *Effect1097) Skill_Use() bool {
source := e.SourceInput()
target := e.TargetInput()
if source == nil || target == nil {
return true
}
skill := e.Ctx().SkillEntity
if skill == nil || skill.Category() == info.Category.STATUS {
return true
}
if skill.AttackTime != 0 && source.SumDamage.Cmp(alpacadecimal.NewFromInt(280)) < 0 {
tiredEffect := source.InitEffect(input.EffectType.Status, int(info.PetStatus.Tired))
if tiredEffect != nil {
tiredEffect.Duration(1)
target.AddEffect(source, tiredEffect)
}
}
if target.CurPet[0].Info.Hp > 0 {
disableAttack := source.InitEffect(input.EffectType.Sub, 1097, 1, 0)
if disableAttack != nil {
target.AddEffect(source, disableAttack)
}
}
if e.starFuryActive {
if target.CurPet[0].Info.Hp <= 0 {
return true
}
success, _, _ := source.Player.Roll(50, 100)
if success {
blindEffect := source.InitEffect(input.EffectType.Status, int(info.PetStatus.Blind))
if blindEffect != nil {
target.AddEffect(source, blindEffect)
}
return true
}
disableStatus := source.InitEffect(input.EffectType.Sub, 1097, 2, 1)
if disableStatus != nil {
target.AddEffect(source, disableStatus)
}
return true
}
if target.CurPet[0].Info.Hp <= 0 {
return true
}
success, _, _ := source.Player.Roll(50, 100)
if !success {
return true
}
furySkill := cloneSkillEntity(skill)
if furySkill == nil {
return true
}
if furySkill.Category() != info.Category.STATUS {
furySkill.XML.Power = halvePower(furySkill.XML.Power)
}
e.starFuryActive = true
executeExtraSkill(source, target, furySkill)
e.starFuryActive = false
return true
}
// Effect 1097 sub: 令对手攻击技能或属性技能失效
type Effect1097Sub struct {
node.EffectNode
armed bool
mode int
}
func (e *Effect1097Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
if len(a) > 0 {
e.Duration(a[0])
}
if len(a) > 1 {
e.mode = a[1]
}
}
func (e *Effect1097Sub) ActionStart(a, b *action.SelectSkillAction) bool {
if e.Ctx().SkillEntity == nil {
return true
}
switch e.mode {
case 0:
if !e.armed || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
e.Ctx().SkillEntity.SetMiss()
case 1:
if e.Ctx().SkillEntity.Category() != info.Category.STATUS {
return true
}
e.Ctx().SkillEntity.SetNoSide()
}
return true
}
func (e *Effect1097Sub) TurnEnd() {
if e.mode == 0 && !e.armed {
e.armed = true
}
e.EffectNode.TurnEnd()
}
// Effect 1098: 致命一击率提升20%每次使用增加20%最高100%打出致命一击后令自身下2次技能触发的星皇之怒威力不再减少;
// 技能结束后对手体力值高于0则50%进行一次额外行动以触发星皇之怒
type Effect1098 struct {
node.EffectNode
critChance int
fullPowerFuryCount int
starFuryActive bool
}
func (e *Effect1098) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
if old := t.GetEffect(input.EffectType.Skill, 1098); old != nil {
if prev, ok := old.(*Effect1098); ok {
e.critChance = prev.critChance
e.fullPowerFuryCount = prev.fullPowerFuryCount
}
}
if e.critChance <= 0 {
e.critChance = 20
}
}
func (e *Effect1098) SkillHit() bool {
source := e.SourceInput()
if source == nil {
return true
}
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
success, _, _ := source.Player.Roll(e.critChance, 100)
if success {
e.Ctx().SkillEntity.XML.CritRate = 16
}
return true
}
func (e *Effect1098) Skill_Use() bool {
source := e.SourceInput()
target := e.TargetInput()
if source == nil || target == nil {
return true
}
skill := e.Ctx().SkillEntity
if skill == nil {
return true
}
if skill.Category() != info.Category.STATUS && skill.Crit != 0 {
e.fullPowerFuryCount = 2
}
if e.critChance < 100 {
e.critChance += 20
if e.critChance > 100 {
e.critChance = 100
}
}
if e.starFuryActive {
priorityEffect := source.InitEffect(input.EffectType.Sub, 1098, 2)
if priorityEffect != nil {
source.AddEffect(source, priorityEffect)
}
return true
}
if target.CurPet[0].Info.Hp <= 0 {
return true
}
success, _, _ := source.Player.Roll(50, 100)
if !success {
return true
}
furySkill := cloneSkillEntity(skill)
if furySkill == nil {
return true
}
if furySkill.Category() != info.Category.STATUS {
if e.fullPowerFuryCount > 0 {
e.fullPowerFuryCount--
} else {
furySkill.XML.Power = halvePower(furySkill.XML.Power)
}
}
e.starFuryActive = true
executeExtraSkill(source, target, furySkill)
e.starFuryActive = false
return true
}
// Effect 1098 sub: 下2次自身使用的攻击技能先制+2
type Effect1098Sub struct {
node.EffectNode
remaining int
}
func (e *Effect1098Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.Duration(-1)
if len(a) > 0 {
e.remaining = a[0]
}
}
func (e *Effect1098Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool {
if e.remaining <= 0 {
e.Alive(false)
return true
}
source := e.SourceInput()
if source == nil {
return true
}
current := actionByPlayer(fattack, sattack, source.UserID)
if current == nil || current.SkillEntity == nil || current.SkillEntity.Category() == info.Category.STATUS {
return true
}
current.SkillEntity.XML.Priority += 2
e.remaining--
if e.remaining <= 0 {
e.Alive(false)
}
return true
}
// Effect 1099: 消除对手能力提升状态,消除成功则自身免疫下{0}次受到的异常状态
type Effect1099 struct {
node.EffectNode
}
func (e *Effect1099) Skill_Use() bool {
source := e.SourceInput()
target := e.TargetInput()
if source == nil || target == nil {
return true
}
cleared := false
for i, level := range target.Prop[:] {
if level <= 0 {
continue
}
if target.SetProp(source, int8(i), 0) {
cleared = true
}
}
if !cleared {
return true
}
immuneEffect := source.InitEffect(input.EffectType.Sub, 1099, int(e.Args()[0].IntPart()))
if immuneEffect != nil {
source.AddEffect(source, immuneEffect)
}
return true
}
// Effect 1099 sub: 免疫下N次异常状态
type Effect1099Sub struct {
node.EffectNode
remaining int
}
func (e *Effect1099Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.Duration(-1)
if len(a) > 0 {
e.remaining = a[0]
}
}
func (e *Effect1099Sub) EFFect_Befer(in *input.Input, effEffect input.Effect) bool {
if e.remaining <= 0 {
e.Alive(false)
return true
}
if in != e.OpponentInput() || !input.IS_Stat(effEffect) {
return true
}
e.remaining--
if e.remaining <= 0 {
e.Alive(false)
}
return false
}
// Effect 1100: {0}回合内若对手使用属性技能则随机进入烧伤、冻伤、中毒、麻痹、害怕、睡眠中的一种异常状态,未触发则下{1}回合造成的伤害提高{2}%
type Effect1100 struct {
RoundEffectArg0Base
triggered bool
}
func (e *Effect1100) Skill_Use_ex() bool {
source := e.SourceInput()
target := e.TargetInput()
if source == nil || target == nil {
return true
}
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() != info.Category.STATUS {
return true
}
e.triggered = true
statusEffect := source.InitEffect(input.EffectType.Status, randomStatus1100())
if statusEffect != nil {
target.AddEffect(source, statusEffect)
}
return true
}
func (e *Effect1100) TurnEnd() {
source := e.SourceInput()
if !e.triggered && e.Duration() == 1 {
if source == nil {
e.EffectNode.TurnEnd()
return
}
boostEffect := source.InitEffect(input.EffectType.Sub, 1100, int(e.Args()[1].IntPart()), int(e.Args()[2].IntPart()))
if boostEffect != nil {
source.AddEffect(source, boostEffect)
}
}
e.EffectNode.TurnEnd()
}
// Effect 1100 sub: 下M回合造成的伤害提高K%
type Effect1100Sub struct {
node.EffectNode
percent alpacadecimal.Decimal
}
func (e *Effect1100Sub) 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 *Effect1100Sub) 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 1101: 命中后{0}%秒杀对方若MISS则自身死亡使对手随机{1}个技能的PP值归零且全属性-{2}
type Effect1101 struct {
node.EffectNode
}
func (e *Effect1101) DamageFloor(zone *info.DamageZone) bool {
source := e.SourceInput()
target := e.OpponentInput()
if zone == nil || zone.Type != info.DamageType.Red {
return true
}
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.AttackTime == 0 {
return true
}
if source == nil {
return true
}
success, _, _ := source.Player.Roll(int(e.Args()[0].IntPart()), 100)
if !success {
return true
}
if target == nil {
return true
}
zone.Damage = target.CurPet[0].GetMaxHP()
return true
}
func (e *Effect1101) Skill_Use() bool {
source := e.SourceInput()
target := e.TargetInput()
if source == nil || target == nil {
return true
}
if e.Ctx().SkillEntity != nil && e.Ctx().SkillEntity.AttackTime == 0 {
source.CurPet[0].Info.Hp = 0
}
zeroRandomSkillPP(target, int(e.Args()[1].IntPart()))
applyAllPropDown(source, target, int8(e.Args()[2].IntPart()))
return true
}
func executeExtraSkill(attacker, defender *input.Input, skill *info.SkillEntity) {
2026-04-04 04:34:43 +08:00
if attacker == nil || defender == nil || skill == nil || attacker.CurPet[0].Info.Hp == 0 {
return
}
skill.XML.MustHit = 1
skill.AttackTimeC(attacker.Prop[5])
defender.ExecWithOpponent(attacker, func(effect input.Effect) bool {
effect.Ctx().SkillEntity = skill
effect.SkillHit_ex()
return true
})
attacker.ExecWithOpponent(defender, func(effect input.Effect) bool {
effect.Ctx().SkillEntity = skill
effect.SkillHit()
return true
})
var originalProps [2][6]int8
var originalPetInfo [2]model.PetInfo
originalProps[0], originalProps[1] = attacker.Prop, defender.Prop
2026-04-04 04:34:43 +08:00
originalPetInfo[0], originalPetInfo[1] = attacker.CurPet[0].Info, defender.CurPet[0].Info
attacker.ExecWithOpponent(defender, func(effect input.Effect) bool {
effect.Ctx().SkillEntity = skill
effect.CalculatePre()
return true
})
var sumDamage alpacadecimal.Decimal
if skill.AttackTime != 0 {
sumDamage = attacker.CalculatePower(defender, skill)
attacker.CalculateCrit(defender, skill)
attacker.IsCritical = skill.Crit
}
attacker.Prop, defender.Prop = originalProps[0], originalProps[1]
2026-04-04 04:34:43 +08:00
attacker.CurPet[0].Info, defender.CurPet[0].Info = originalPetInfo[0], originalPetInfo[1]
if attacker.IsCritical == 1 {
if skill.Category() == info.Category.PHYSICAL && defender.Prop[1] > 0 {
defender.Prop[1] = 0
} else if skill.Category() == info.Category.SPECIAL && defender.Prop[3] > 0 {
defender.Prop[3] = 0
}
sumDamage = sumDamage.Mul(alpacadecimal.NewFromInt(2))
}
attacker.ExecWithOpponent(defender, func(effect input.Effect) bool {
effect.Ctx().SkillEntity = skill
effect.OnSkill()
return true
})
defender.Damage(attacker, &info.DamageZone{
Type: info.DamageType.Red,
Damage: sumDamage,
})
2026-04-04 04:34:43 +08:00
if defender.CurPet[0].Info.Hp > 0 {
defender.ExecWithOpponent(attacker, func(effect input.Effect) bool {
effect.Ctx().SkillEntity = skill
effect.Skill_Use_ex()
return true
})
}
2026-04-04 04:34:43 +08:00
if attacker.CurPet[0].Info.Hp > 0 {
attacker.ExecWithOpponent(defender, func(effect input.Effect) bool {
effect.Ctx().SkillEntity = skill
effect.Skill_Use()
return true
})
}
defender.ExecWithOpponent(attacker, func(effect input.Effect) bool {
effect.Ctx().SkillEntity = skill
effect.Action_end_ex()
return true
})
attacker.ExecWithOpponent(defender, func(effect input.Effect) bool {
effect.Ctx().SkillEntity = skill
effect.Action_end()
return true
})
}
func halvePower(power int) int {
if power <= 1 {
return 1
}
power /= 2
if power <= 0 {
return 1
}
return power
}
func actionByPlayer(fattack, sattack *action.SelectSkillAction, playerID uint32) *action.SelectSkillAction {
if fattack != nil && fattack.PlayerID == playerID {
return fattack
}
if sattack != nil && sattack.PlayerID == playerID {
return sattack
}
return nil
}
func randomStatus1100() int {
statusTypes := []int{
int(info.PetStatus.Burned),
int(info.PetStatus.Frozen),
int(info.PetStatus.Poisoned),
int(info.PetStatus.Paralysis),
int(info.PetStatus.Fear),
int(info.PetStatus.Sleep),
}
return statusTypes[grand.Intn(len(statusTypes))]
}
func zeroRandomSkillPP(target *input.Input, count int) {
if target == nil || count <= 0 {
return
}
2026-04-04 04:34:43 +08:00
skills := target.CurPet[0].Info.SkillList
if len(skills) == 0 {
return
}
if count > len(skills) {
count = len(skills)
}
indexes := grand.Perm(len(skills))
for _, idx := range indexes[:count] {
2026-04-04 04:34:43 +08:00
target.CurPet[0].Info.SkillList[idx].PP = 0
}
}
func applyAllPropDown(owner, target *input.Input, level int8) {
if owner == nil || target == nil || level <= 0 {
return
}
for i := range target.Prop {
target.SetProp(owner, int8(i), -level)
}
}
func init() {
input.InitEffect(input.EffectType.Skill, 1097, &Effect1097{})
input.InitEffect(input.EffectType.Sub, 1097, &Effect1097Sub{})
input.InitEffect(input.EffectType.Skill, 1098, &Effect1098{})
input.InitEffect(input.EffectType.Sub, 1098, &Effect1098Sub{})
input.InitEffect(input.EffectType.Skill, 1099, &Effect1099{})
input.InitEffect(input.EffectType.Sub, 1099, &Effect1099Sub{})
input.InitEffect(input.EffectType.Skill, 1100, &Effect1100{})
input.InitEffect(input.EffectType.Sub, 1100, &Effect1100Sub{})
input.InitEffect(input.EffectType.Skill, 1101, &Effect1101{})
}