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) { 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 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] 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, }) 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 }) } 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 } 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] { 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{}) }