Files
bl/logic/service/fight/input/attr.go

267 lines
7.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package input
import (
element "blazing/common/data/Element"
"blazing/common/utils"
"blazing/logic/service/fight/info"
"fmt"
"github.com/mohae/deepcopy"
"github.com/shopspring/decimal"
)
func (u *Input) BeforeSkill(opp *Input, skill *info.SkillEntity) {
skill.AttackTimeC(int(u.GetProp(5, true))) //计算命中
skill.Crit = 0
if skill.Category() == info.Category.STATUS { //属性技能不用算暴击
return
}
CritRate := utils.Max(skill.CritRate, 1)
//CritAtkFirst: 先出手时必定致命一击; 默认: 0
if skill.CritAtkFirst != 0 && u.First {
CritRate = 16
}
//CritAtkSecond: 后出手时必定致命一击; 默认: 0
if skill.CritAtkSecond != 0 && !u.First {
CritRate = 16
}
// CritSelfHalfHp: 自身体力低于一半时必定致命一击; 默认: 0
if skill.CritSelfHalfHp != 0 && (u.CurrentPet.HP < int(u.CurrentPet.Info.MaxHp)/2) {
CritRate = 16
}
// CritFoeHalfHp: 对方体力低于一半时必定致命一击; 默认: 0
if skill.CritSelfHalfHp != 0 && (opp.CurrentPet.HP < int(opp.CurrentPet.Info.MaxHp)/2) {
CritRate = 16
}
//todo 暴击伤害
if t, _, _ := u.Player.Roll(625*CritRate, 10000); t {
skill.Crit = 1
}
}
// 伤害落实
func (u *Input) Damage(attacker *Input, id int) {
attacker.Exec(func(t Effect) bool {
t.BeforeAttack(u, attacker.GetDamage(0)) //红伤落实前,我方增伤
return true
})
attacker.Exec(func(t Effect) bool {
t.Attack(u, attacker.GetEffect(EffectType.Damage, id)) //红伤落实前,我方增伤
return true
})
u.Exec(func(t Effect) bool {
t.BeforeAttacked(attacker, attacker.GetEffect(EffectType.Damage, id)) //红伤落实,内部有befer
return true
})
u.Exec(func(t Effect) bool {
t.Attacked(attacker, attacker.GetEffect(EffectType.Damage, id)) //红伤落实,内部有befer
return true
})
if uint32(attacker.GetEffect(EffectType.Damage, id).Effect.Stack()) > u.CurrentPet.Info.Hp {
//这里其实是受到致死伤害
//然后先触发死亡效果消除所有buff
//然后触发回神效果
u.CurrentPet.Info.Hp = 0
} else {
u.CurrentPet.Info.Hp = u.CurrentPet.Info.Hp - u.AttackValue.LostHp
}
//todo 待实现死亡effet
}
// 施加方,类型,等级,操作类别,是否成功
func (u *Input) SetProp(in *Input, prop, level int8, ptype info.EnumAbilityOpType) (ret bool) {
canuseskill := u.Exec(func(t Effect) bool { //这个是能否使用技能
//结算状态
return t.BeferProp(in, prop, level, ptype) //返回本身结算,如果false,说明不能使用技能了
})
if canuseskill {
switch ptype {
case info.AbilityOpType.AbilityOpIncrease:
newValue := utils.Min(u.AttackValue.Prop[prop]+int8(level), 6)
if newValue > u.AttackValue.Prop[prop] {
fmt.Println("属性值会增加")
ret = true
} else {
fmt.Println("属性值不会增加")
ret = false
}
// 执行赋值
u.AttackValue.Prop[prop] = newValue
case info.AbilityOpType.AbilityOpDecrease:
u.AttackValue.Prop[prop] = utils.Max(u.AttackValue.Prop[prop]+int8(level), -6)
case info.AbilityOpType.AbilityOpReset:
if level > 0 && u.AttackValue.Prop[prop] > 0 { //消强
u.AttackValue.Prop[prop] = 0
}
if level < 0 && u.AttackValue.Prop[prop] < 0 { //解弱
u.AttackValue.Prop[prop] = 0
}
case info.AbilityOpType.AbilityOpStealStrengthen:
if in.AttackValue.Prop[prop] > 0 {
u.SetProp(u, prop, in.AttackValue.Prop[prop], info.AbilityOpType.AbilityOpIncrease)
in.SetProp(u, prop, 1, info.AbilityOpType.AbilityOpReset) //消除对面强化
}
case info.AbilityOpType.AbilityOpReverse:
if level > 0 && u.AttackValue.Prop[prop] > 0 { //反转强化实际上是附带2倍的反转强化
u.SetProp(u, prop, u.AttackValue.Prop[prop]*2, info.AbilityOpType.AbilityOpDecrease)
}
if level < 0 && u.AttackValue.Prop[prop] < 0 {
u.SetProp(u, prop, -u.AttackValue.Prop[prop]*2, info.AbilityOpType.AbilityOpIncrease)
}
case info.AbilityOpType.AbilityOpBounceWeaken:
if u.AttackValue.Prop[prop] < 0 {
in.SetProp(u, prop, u.AttackValue.Prop[prop], info.AbilityOpType.AbilityOpDecrease)
u.SetProp(u, prop, -1, info.AbilityOpType.AbilityOpReset) //消除自身弱化
}
}
}
return
}
func (i *Input) GetAction(opp *Input) {
//使用1#技能,实际上要按照四个技能权重去使用
i.FightC.UseSkill(i.Player, int32(i.FightC.GetCurrPET(i.Player).Skills[0].ID))
}
// todo获取属性待实现获取后改回原属性
func (i *Input) Prop(in *Input, f func()) {
oldourr := deepcopy.Copy(in).(*Input)
in.Exec(func(t Effect) bool { //属性获取后
t.AfterProp(i) //视为xx 需要在里面判断来源
return true
})
f()
in = oldourr
//opp.CurrentPet = oldouo //恢复
}
// todo获取属性待实现获取后改回原属性
func (i *Input) Pet(in *Input, f func()) {
oldour := deepcopy.Copy(i.CurrentPet).(*info.BattlePetEntity)
//oldouo := deepcopy.Copy(opp.CurrentPet).(*info.BattlePetEntity)
i.Exec(func(t Effect) bool { //属性获取前
t.BeferAttr(i.CurrentPet) //使XX为XX
return true
})
oldourr := deepcopy.Copy(in.CurrentPet).(*info.BattlePetEntity)
in.Exec(func(t Effect) bool { //属性获取后
t.AfterAttr(i.CurrentPet) //视为xx 需要在里面判断来源
return true
})
f()
in.CurrentPet = oldourr
i.CurrentPet = oldour //恢复
//opp.CurrentPet = oldouo //恢复
}
func (i *Input) Skill(in *info.SkillEntity, f func()) {
oldour := deepcopy.Copy(in).(*info.SkillEntity)
//oldouo := deepcopy.Copy(opp.CurrentPet).(*info.BattlePetEntity)
i.Exec(func(t Effect) bool { //属性获取前
t.BeforeSkill(i, in) //使XX为XX
return true
})
f()
in = oldour //恢复
}
// 计算技能威力
func (i *Input) CalculatePower(deftype *Input, skill *info.SkillEntity) decimal.Decimal {
// 1. 计算等级因子 (level * 0.4 + 2)
levelFactor := decimal.NewFromInt(int64(i.CurrentPet.Info.Level)).
Mul(decimal.NewFromFloat(0.4)).Add(decimal.NewFromInt(2))
var (
attackDec decimal.Decimal //攻击值
defenseDec decimal.Decimal //防御值
)
switch skill.Category() { //判断技能类型
case info.Category.PHYSICAL:
i.Pet(i, func() { //我方取我方攻击
attackDec = decimal.NewFromInt(int64(i.GetProp(0, false)))
})
deftype.Pet(i, func() { //我方取敌方防御
defenseDec = decimal.NewFromInt(int64(deftype.GetProp(1, false)))
})
case info.Category.SPECIAL:
i.Pet(i, func() { //我方取我方攻击
attackDec = decimal.NewFromInt(int64(i.GetProp(2, false)))
})
deftype.Pet(i, func() { //我方取敌方防御
defenseDec = decimal.NewFromInt(int64(deftype.GetProp(3, false)))
})
default:
return decimal.NewFromInt(0)
}
// 5. 基础伤害公式:等级因子 * 威力因子 * 攻击 / 防御 / 50 + 2
baseDamage := levelFactor.
Mul(decimal.NewFromInt(int64(skill.Power))).
Mul(attackDec).
Div(defenseDec).
Div(decimal.NewFromInt(50)).
Add(decimal.NewFromInt(2))
var typeRate decimal.Decimal
deftype.Pet(i, func() { //我方取敌方属性,得到敌方的实际和我方的视为
t, _ := element.NewElementCalculator().GetOffensiveMultiplier(skill.Type().ID, deftype.CurrentPet.Type().ID)
typeRate = decimal.NewFromFloat(t)
})
damage := baseDamage.
Mul(skill.CriticalsameTypeBonus()). // 同属性加成
Mul(typeRate). // 克制系数
Mul(skill.Criticalrandom()) //随机波动
return damage
}