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

277 lines
6.6 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/shopspring/decimal"
)
func (u *Input) UseSkill(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 info.DamageZone) {
attacker.Exec(func(t Effect) bool {
t.BeforeAttack(u, &id) //红伤落实前,我方增伤
return true
})
attacker.Exec(func(t Effect) bool {
t.Attack(u, &id) //红伤落实前,我方增伤
return true
})
attacker.DamageZone.OldAttack = attacker.DamageZone.Attack //反弹伤害记录
u.Exec(func(t Effect) bool {
t.BeforeAttacked(attacker, &id) //红伤落实,内部有befer
return true
})
u.Exec(func(t Effect) bool {
t.Attacked(attacker, &id) //红伤落实,内部有befer
return true
})
switch id.Type {
case info.DamageType.Red:
attacker.AttackValue.LostHp = uint32(id.Damage.IntPart()) //红伤落实
}
if uint32(id.Damage.IntPart()) > u.CurrentPet.Info.Hp {
//这里其实是受到致死伤害
//然后先触发死亡效果消除所有buff
//然后触发回神效果
u.CurrentPet.Info.Hp = 0
} else {
u.CurrentPet.Info.Hp = u.CurrentPet.Info.Hp - attacker.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 {
return false
}
var newValue int8
abfunc := func(prop, level int8, ptype info.EnumAbilityOpType) (ret bool) {
switch ptype {
case info.AbilityOpType.ADD:
newValue = utils.Min(u.AttackValue.Prop[prop]+int8(level), 6)
if newValue > u.AttackValue.Prop[prop] {
fmt.Println("属性值会增加")
return true
} else {
fmt.Println("属性值不会增加")
return false
}
case info.AbilityOpType.SUB:
newValue = utils.Max(u.AttackValue.Prop[prop]+int8(level), -6)
if newValue < u.AttackValue.Prop[prop] {
fmt.Println("属性值会减少")
return true
} else {
fmt.Println("属性值不会增加")
return false
}
case info.AbilityOpType.RESET:
if level > 0 && u.AttackValue.Prop[prop] > 0 { //消强
newValue = 0
return true
}
if level < 0 && u.AttackValue.Prop[prop] < 0 { //解弱
newValue = 0
return true
}
}
return false
}
switch ptype {
case info.AbilityOpType.AbilityOpStealStrengthen:
temp := in.AttackValue.Prop[prop]
if temp <= 0 { //对方没有强化
return false
}
if abfunc(prop, temp, info.AbilityOpType.ADD) { //把对面的强化等级添加自身
u.AttackValue.Prop[prop] = newValue //成功把 强化更新
in.SetProp(u, prop, 1, info.AbilityOpType.RESET) //吸取后消除对面强化
}
case info.AbilityOpType.AbilityOpReverse:
temp := u.AttackValue.Prop[prop]
switch {
case level > 0: //反转强化
if temp <= 0 { //没有强化
return false
}
if abfunc(prop, temp*2, info.AbilityOpType.SUB) {
u.AttackValue.Prop[prop] = newValue
if temp == -u.AttackValue.Prop[prop] { //成功到对应弱化
return true
} else {
return true
}
} else { //自身免弱或已到-6
return false
}
default: //反转弱化
if temp >= 0 { //没有弱化
return false
}
if abfunc(prop, -temp*2, info.AbilityOpType.ADD) {
u.AttackValue.Prop[prop] = newValue
if temp == -u.AttackValue.Prop[prop] { //成功到对应强化
return true
} else {
return true
}
} else { //自身免弱或已到-6
return false
}
}
case info.AbilityOpType.AbilityOpBounceWeaken:
temp := u.AttackValue.Prop[prop]
if temp >= 0 { //没有弱化
return false
}
if in.SetProp(u, prop, temp, info.AbilityOpType.SUB) {
u.SetProp(u, prop, -1, info.AbilityOpType.RESET) //消除自身弱化
return true
}
default: //增加减少重置
if abfunc(prop, level, ptype) {
// 执行赋值
u.AttackValue.Prop[prop] = newValue
return true
}
}
return false
}
func (i *Input) GetAction(opp *Input) {
//使用1#技能,实际上要按照四个技能权重去使用
i.FightC.UseSkill(i.Player, int32(i.FightC.GetCurrPET(i.Player).Skills[0].ID))
}
// 计算技能威力
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:
attackDec = decimal.NewFromInt(int64(i.GetProp(0, false)))
defenseDec = decimal.NewFromInt(int64(deftype.GetProp(1, false)))
case info.Category.SPECIAL:
attackDec = decimal.NewFromInt(int64(i.GetProp(2, false)))
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
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
}