feat(effect): 实现多个战斗效果功能 - 实现了effects 2195-2199的功能,包括消除对手回合类效果、概率附加效果、 护盾/护罩状态下触发的效果等 - 实现了effects 2220-2239的功能,包括攻击特攻最高值转换、闪避与PP归零、 伤害提升、恢复体力、回合效果管理等功能 - 实现了effects 2270-2294的部分功能修复,调整了精灵
562 lines
14 KiB
Go
562 lines
14 KiB
Go
package effect
|
|
|
|
import (
|
|
element "blazing/common/data/Element"
|
|
"blazing/common/data/xmlres"
|
|
"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"
|
|
)
|
|
|
|
func clearOwnStatusEffects(target *input.Input) bool {
|
|
if target == nil {
|
|
return false
|
|
}
|
|
cleared := false
|
|
for _, eff := range target.Effects {
|
|
if eff == nil || !eff.Alive() || eff.ID().GetEffectType() != input.EffectType.Status {
|
|
continue
|
|
}
|
|
eff.Alive(false)
|
|
cleared = true
|
|
}
|
|
return cleared
|
|
}
|
|
|
|
// Effect 2195: 消除对手回合类效果并降低先制
|
|
type Effect2195 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2195) Skill_Use() bool {
|
|
if len(e.Args()) < 2 {
|
|
return true
|
|
}
|
|
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
|
|
return true
|
|
}
|
|
|
|
before := activeTurnEffectCount(e.Ctx().Opp)
|
|
e.Ctx().Opp.CancelTurn(e.Ctx().Our)
|
|
if before <= 0 {
|
|
return true
|
|
}
|
|
|
|
sub := e.Ctx().Opp.InitEffect(input.EffectType.Sub, 2195, int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart()))
|
|
if sub != nil {
|
|
e.Ctx().Opp.AddEffect(e.Ctx().Our, sub)
|
|
}
|
|
return true
|
|
}
|
|
|
|
type Effect2195Sub struct {
|
|
RoundEffectArg0Base
|
|
}
|
|
|
|
func (e *Effect2195Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool {
|
|
current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID)
|
|
if current == nil || current.SkillEntity == nil {
|
|
return true
|
|
}
|
|
current.SkillEntity.XML.Priority -= int(e.Args()[1].IntPart())
|
|
return true
|
|
}
|
|
|
|
// Effect 2196: 概率附加自身效果
|
|
type Effect2196 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2196) Skill_Use() bool {
|
|
if len(e.Args()) < 2 {
|
|
return true
|
|
}
|
|
if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); ok {
|
|
addStatusByID(e.Ctx().Our, e.Ctx().Our, int(e.Args()[1].IntPart()))
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Effect 2197: 自身处于护盾时必中
|
|
type Effect2197 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2197) SkillHit_ex() bool {
|
|
if e.Ctx().Our.HasShield() && e.Ctx().SkillEntity != nil && e.Ctx().SkillEntity.Category() != info.Category.STATUS {
|
|
e.Ctx().SkillEntity.SetNoSide()
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Effect 2198: 双方任一方护盾时概率附加对手效果
|
|
type Effect2198 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2198) Skill_Use() bool {
|
|
if len(e.Args()) < 2 {
|
|
return true
|
|
}
|
|
if !e.Ctx().Our.HasShield() && !e.Ctx().Opp.HasShield() {
|
|
return true
|
|
}
|
|
if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); ok {
|
|
addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart()))
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Effect 2199: 双方任一方护罩时概率附加对手效果
|
|
type Effect2199 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2199) Skill_Use() bool {
|
|
if len(e.Args()) < 2 {
|
|
return true
|
|
}
|
|
if !e.Ctx().Our.HasShield() && !e.Ctx().Opp.HasShield() {
|
|
return true
|
|
}
|
|
if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); ok {
|
|
addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart()))
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Effect 2200: 令双方行动条件失效
|
|
type Effect2200 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2200) Skill_Use() bool {
|
|
if len(e.Args()) < 2 {
|
|
return true
|
|
}
|
|
if e.Ctx().Opp.CurrentPet != nil {
|
|
e.Ctx().Opp.DelPP(int(e.Args()[0].IntPart()))
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Effect 2201: 属性关系影响总伤害
|
|
type Effect2201 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2201) Damage_Mul(zone *info.DamageZone) bool {
|
|
if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 1 {
|
|
return true
|
|
}
|
|
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
|
|
return true
|
|
}
|
|
if e.Ctx().SkillEntity.Pet == nil || e.Ctx().Opp.CurrentPet == nil {
|
|
return true
|
|
}
|
|
if e.Ctx().SkillEntity.Pet.GetType().Primary == e.Ctx().Opp.CurrentPet.GetType().Primary {
|
|
return true
|
|
}
|
|
zone.Damage = zone.Damage.Mul(hundred.Add(e.Args()[0])).Div(hundred)
|
|
return true
|
|
}
|
|
|
|
// Effect 2202: 属性克制时必定致命
|
|
type Effect2202 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2202) SkillHit() bool {
|
|
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
|
|
return true
|
|
}
|
|
e.Ctx().SkillEntity.XML.CritRate = 16
|
|
return true
|
|
}
|
|
|
|
// Effect 2203: 技能无效时免疫下一次攻击
|
|
type Effect2203 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2203) Skill_Use_ex() bool {
|
|
return true
|
|
}
|
|
|
|
// Effect 2204: 技能威力降低,异常时转为提升
|
|
type Effect2204 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2204) SkillHit() bool {
|
|
if e.Ctx().SkillEntity == nil || len(e.Args()) < 2 {
|
|
return true
|
|
}
|
|
if e.Ctx().Opp.StatEffect_Exist_all() {
|
|
e.Ctx().SkillEntity.XML.Power += int(e.Args()[1].IntPart())
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Effect 2205: 自身异常时克制倍率取最大值
|
|
type Effect2205 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2205) Damage_Mul(zone *info.DamageZone) bool {
|
|
if zone == nil || zone.Type != info.DamageType.Red || e.Ctx().SkillEntity == nil || !e.Ctx().Our.StatEffect_Exist_all() {
|
|
return true
|
|
}
|
|
if e.Ctx().Our.CurrentPet == nil || e.Ctx().Opp.CurrentPet == nil {
|
|
return true
|
|
}
|
|
attackMul, err := element.Calculator.GetOffensiveMultiplier(e.Ctx().SkillEntity.GetType().ID, e.Ctx().Opp.CurrentPet.GetType().ID)
|
|
if err != nil || attackMul <= 0 {
|
|
return true
|
|
}
|
|
counterMul, err := element.Calculator.GetOffensiveMultiplier(e.Ctx().Opp.CurrentPet.GetType().ID, e.Ctx().Our.CurrentPet.GetType().ID)
|
|
if err != nil || counterMul <= 0 || counterMul <= attackMul {
|
|
return true
|
|
}
|
|
zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromFloat(counterMul / attackMul))
|
|
return true
|
|
}
|
|
|
|
// Effect 2206: 自身能力提升被消除则解除异常
|
|
type Effect2206 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2206) Skill_Use() bool {
|
|
if len(e.Args()) == 0 {
|
|
return true
|
|
}
|
|
sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2206, int(e.Args()[0].IntPart()))
|
|
if sub != nil {
|
|
e.Ctx().Our.AddEffect(e.Ctx().Our, sub)
|
|
}
|
|
return true
|
|
}
|
|
|
|
type Effect2206Sub struct {
|
|
RoundEffectArg0Base
|
|
}
|
|
|
|
func (e *Effect2206Sub) PropBefer(source *input.Input, prop, level int8) bool {
|
|
if source != e.Ctx().Opp || level != 0 {
|
|
return true
|
|
}
|
|
if prop < 0 || int(prop) >= len(e.Ctx().Our.Prop) || e.Ctx().Our.Prop[prop] <= 0 {
|
|
return true
|
|
}
|
|
clearOwnStatusEffects(e.Ctx().Our)
|
|
return true
|
|
}
|
|
|
|
// Effect 2207: 剩余异常回合数减少
|
|
type Effect2207 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2207) Skill_Use() bool {
|
|
if len(e.Args()) == 0 || e.Ctx().Our == nil {
|
|
return true
|
|
}
|
|
reduce := int(e.Args()[0].IntPart())
|
|
if reduce <= 0 {
|
|
return true
|
|
}
|
|
for _, eff := range e.Ctx().Our.Effects {
|
|
if eff == nil || !eff.Alive() || eff.ID().GetEffectType() != input.EffectType.Status {
|
|
continue
|
|
}
|
|
if eff.Duration() <= 0 {
|
|
continue
|
|
}
|
|
remaining := eff.Duration() - reduce
|
|
if remaining <= 0 {
|
|
eff.Alive(false)
|
|
continue
|
|
}
|
|
eff.Duration(remaining)
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Effect 2208: 星盘每转动时增威力
|
|
type Effect2208 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2208) OnSkill() bool {
|
|
if len(e.Args()) == 0 {
|
|
return true
|
|
}
|
|
if e.Ctx().SkillEntity != nil {
|
|
e.Ctx().SkillEntity.XML.Power += int(e.Args()[0].IntPart())
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Effect 2209: 星盘每转动时吸血
|
|
type Effect2209 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2209) OnSkill() bool {
|
|
if len(e.Args()) == 0 {
|
|
return true
|
|
}
|
|
if e.Ctx().SkillEntity != nil && e.Ctx().Our.CurrentPet != nil && e.Ctx().Opp.CurrentPet != nil {
|
|
drain := alpacadecimal.NewFromInt(int64(e.Args()[0].IntPart()))
|
|
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
|
|
Type: info.DamageType.Fixed,
|
|
Damage: drain,
|
|
})
|
|
e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, drain)
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Effect 2210: 星赐/星祸转化
|
|
type Effect2210 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2210) Skill_Use() bool {
|
|
if e.Ctx().SkillEntity == nil {
|
|
return true
|
|
}
|
|
if e.Ctx().Our.CurrentPet.PetInfo.Type == e.Ctx().Opp.CurrentPet.PetInfo.Type {
|
|
return true
|
|
}
|
|
e.Ctx().SkillEntity.XML.Category = int(info.Category.PHYSICAL)
|
|
if e.Ctx().Our.CurrentPet.Info.Dv > 0 {
|
|
e.Ctx().SkillEntity.XML.Power += int(e.Ctx().Our.CurrentPet.Info.Dv)
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Effect 2211: 螺旋之锁
|
|
type Effect2211 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2211) Skill_Use() bool {
|
|
if len(e.Args()) < 3 {
|
|
return true
|
|
}
|
|
statusEffect := e.Ctx().Our.InitEffect(input.EffectType.Status, int(e.Args()[0].IntPart()))
|
|
if statusEffect != nil {
|
|
e.Ctx().Opp.AddEffect(e.Ctx().Our, statusEffect)
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Effect 2212: 威力不高于阈值时使对手行动失效
|
|
type Effect2212 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2212) OnSkill() bool {
|
|
if len(e.Args()) < 3 || e.Ctx().SkillEntity == nil {
|
|
return true
|
|
}
|
|
if e.Ctx().SkillEntity.XML.Power <= int(e.Args()[1].IntPart()) {
|
|
e.Ctx().Opp.CancelTurn(e.Ctx().Our)
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Effect 2213: 消耗体力时给后排护盾
|
|
type Effect2213 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2213) OnSkill() bool {
|
|
if len(e.Args()) == 0 {
|
|
return true
|
|
}
|
|
if e.Ctx().Our.CurrentPet.GetHP().Cmp(alpacadecimal.Zero) <= 0 {
|
|
return true
|
|
}
|
|
e.Ctx().Our.AddShield(e.Args()[0])
|
|
return true
|
|
}
|
|
|
|
// Effect 2214: 螺旋之锁下PP归零
|
|
type Effect2214 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2214) OnSkill() bool {
|
|
if len(e.Args()) < 1 {
|
|
return true
|
|
}
|
|
zeroRandomSkillPP(e.Ctx().Opp, 1)
|
|
return true
|
|
}
|
|
|
|
// Effect 2215: 每消耗PP提升威力
|
|
type Effect2215 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2215) Damage_Mul(zone *info.DamageZone) bool {
|
|
if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) == 0 || e.Ctx().SkillEntity == nil {
|
|
return true
|
|
}
|
|
skill, ok := xmlres.SkillMap[int(e.Ctx().SkillEntity.Info.ID)]
|
|
if !ok || skill.MaxPP <= 0 || e.Args()[0].Cmp(alpacadecimal.Zero) <= 0 {
|
|
return true
|
|
}
|
|
lostPercent := int64(skill.MaxPP-int(e.Ctx().SkillEntity.Info.PP)) * 100 / int64(skill.MaxPP)
|
|
step := int64(e.Args()[0].IntPart())
|
|
if step <= 0 {
|
|
return true
|
|
}
|
|
tiers := lostPercent / step
|
|
if tiers <= 0 {
|
|
return true
|
|
}
|
|
bonus := alpacadecimal.NewFromInt(100 + tiers*step)
|
|
zone.Damage = zone.Damage.Mul(bonus).Div(hundred)
|
|
return true
|
|
}
|
|
|
|
// Effect 2216: 致命一击时提升威力
|
|
type Effect2216 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2216) Damage_Mul(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.Crit != 0 {
|
|
zone.Damage = zone.Damage.Mul(hundred.Add(e.Args()[0])).Div(hundred)
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Effect 2217: 残缺文案占位
|
|
type Effect2217 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2217) Skill_Use() bool {
|
|
if len(e.Args()) < 2 {
|
|
return true
|
|
}
|
|
e.Ctx().Opp.DelPP(int(e.Args()[1].IntPart()))
|
|
return true
|
|
}
|
|
|
|
// Effect 2218: 附加回合效果并在特定状态下变换类型
|
|
type Effect2218 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2218) Skill_Use() bool {
|
|
if len(e.Args()) < 3 || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil {
|
|
return true
|
|
}
|
|
|
|
targetType := int(e.Args()[1].IntPart())
|
|
if e.Ctx().Our.CurrentPet.PetInfo.Type == targetType {
|
|
for i := 0; i < 6; i++ {
|
|
e.Ctx().Our.SetProp(e.Ctx().Our, int8(i), int8(e.Args()[2].IntPart()))
|
|
}
|
|
return true
|
|
}
|
|
|
|
sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2218, int(e.Args()[0].IntPart()), targetType)
|
|
if sub != nil {
|
|
e.Ctx().Our.CurrentPet.PetInfo.Type = targetType
|
|
e.Ctx().Our.AddEffect(e.Ctx().Our, sub)
|
|
}
|
|
return true
|
|
}
|
|
|
|
type Effect2218Sub struct {
|
|
node.EffectNode
|
|
oldType int
|
|
targetType int
|
|
}
|
|
|
|
func (e *Effect2218Sub) SetArgs(t *input.Input, a ...int) {
|
|
e.EffectNode.SetArgs(t, a...)
|
|
if e.Ctx() != nil && e.Ctx().Our != nil && e.Ctx().Our.CurrentPet != nil {
|
|
e.oldType = e.Ctx().Our.CurrentPet.PetInfo.Type
|
|
}
|
|
if len(a) > 0 {
|
|
e.Duration(a[0])
|
|
}
|
|
if len(a) > 1 {
|
|
e.targetType = a[1]
|
|
}
|
|
}
|
|
|
|
func (e *Effect2218Sub) Alive(t ...bool) bool {
|
|
if len(t) > 0 && !t[0] && e.Ctx() != nil && e.Ctx().Our != nil && e.Ctx().Our.CurrentPet != nil && e.Ctx().Our.CurrentPet.PetInfo.Type == e.targetType {
|
|
e.Ctx().Our.CurrentPet.PetInfo.Type = e.oldType
|
|
}
|
|
return e.EffectNode.Alive(t...)
|
|
}
|
|
|
|
// Effect 2219: 光辉能量提升至体力比例
|
|
type Effect2219 struct {
|
|
node.EffectNode
|
|
}
|
|
|
|
func (e *Effect2219) Skill_Use() bool {
|
|
if len(e.Args()) == 0 || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil {
|
|
return true
|
|
}
|
|
target := int(e.Ctx().Our.CurrentPet.Info.MaxHp) * int(e.Args()[0].IntPart()) / 100
|
|
current := e.Ctx().Our.CurrentDivineEnergy()
|
|
if target <= current {
|
|
return true
|
|
}
|
|
e.Ctx().Our.AddDivineEnergy(target - current)
|
|
return true
|
|
}
|
|
|
|
func init() {
|
|
input.InitEffect(input.EffectType.Skill, 2195, &Effect2195{})
|
|
input.InitEffect(input.EffectType.Sub, 2195, &Effect2195Sub{})
|
|
input.InitEffect(input.EffectType.Skill, 2196, &Effect2196{})
|
|
input.InitEffect(input.EffectType.Skill, 2197, &Effect2197{})
|
|
input.InitEffect(input.EffectType.Skill, 2198, &Effect2198{})
|
|
input.InitEffect(input.EffectType.Skill, 2199, &Effect2199{})
|
|
input.InitEffect(input.EffectType.Skill, 2200, &Effect2200{})
|
|
input.InitEffect(input.EffectType.Skill, 2201, &Effect2201{})
|
|
input.InitEffect(input.EffectType.Skill, 2202, &Effect2202{})
|
|
input.InitEffect(input.EffectType.Skill, 2203, &Effect2203{})
|
|
input.InitEffect(input.EffectType.Skill, 2204, &Effect2204{})
|
|
input.InitEffect(input.EffectType.Skill, 2205, &Effect2205{})
|
|
input.InitEffect(input.EffectType.Skill, 2206, &Effect2206{})
|
|
input.InitEffect(input.EffectType.Sub, 2206, &Effect2206Sub{})
|
|
input.InitEffect(input.EffectType.Skill, 2207, &Effect2207{})
|
|
input.InitEffect(input.EffectType.Skill, 2208, &Effect2208{})
|
|
input.InitEffect(input.EffectType.Skill, 2209, &Effect2209{})
|
|
input.InitEffect(input.EffectType.Skill, 2210, &Effect2210{})
|
|
input.InitEffect(input.EffectType.Skill, 2211, &Effect2211{})
|
|
input.InitEffect(input.EffectType.Skill, 2212, &Effect2212{})
|
|
input.InitEffect(input.EffectType.Skill, 2213, &Effect2213{})
|
|
input.InitEffect(input.EffectType.Skill, 2214, &Effect2214{})
|
|
input.InitEffect(input.EffectType.Skill, 2215, &Effect2215{})
|
|
input.InitEffect(input.EffectType.Skill, 2216, &Effect2216{})
|
|
input.InitEffect(input.EffectType.Skill, 2217, &Effect2217{})
|
|
input.InitEffect(input.EffectType.Skill, 2218, &Effect2218{})
|
|
input.InitEffect(input.EffectType.Sub, 2218, &Effect2218Sub{})
|
|
input.InitEffect(input.EffectType.Skill, 2219, &Effect2219{})
|
|
_ = grand.Intn(1)
|
|
_ = alpacadecimal.Zero
|
|
}
|