diff --git a/common/utils/tomap.go b/common/utils/tomap.go index fe802e44..eb131f0d 100644 --- a/common/utils/tomap.go +++ b/common/utils/tomap.go @@ -20,3 +20,18 @@ func ToSliceMap[T any, K comparable](slice []T, keyFunc func(T) K) map[K][]T { } return m } + +// 定义泛型约束:只允许数值类型(整数、浮点数等) +type Number interface { + int | int8 | int16 | int32 | int64 | + uint | uint8 | uint16 | uint32 | uint64 | + float32 | float64 +} + +// Max 泛型函数:接收两个同类型的 Number 参数,返回最大值 +func Max[T Number](a, b T) T { + if a > b { + return a + } + return b +} diff --git a/logic/service/fight/battle/node/node.go b/logic/service/fight/battle/node/node.go index 18d31b19..fbcd4702 100644 --- a/logic/service/fight/battle/node/node.go +++ b/logic/service/fight/battle/node/node.go @@ -20,6 +20,7 @@ type EffectNode struct { Success bool // 是否执行成功 成功XXX,失败XXX arget bool // 传出作用对象,默认0是自身,1是作用于对面 Flag int //过滤掉的战斗类型 pvp pve boss战斗,野怪全部生效 + Alive bool // 是否失效 effect返回值是否被取消,是否被删除 //增加owner target,如果owner target都为自身,就回合效果结束后再使用回合效果 } diff --git a/logic/service/fight/info/BattleSkillEntity.go b/logic/service/fight/info/BattleSkillEntity.go index 5168246f..ce7bda47 100644 --- a/logic/service/fight/info/BattleSkillEntity.go +++ b/logic/service/fight/info/BattleSkillEntity.go @@ -3,6 +3,7 @@ package info import ( element "blazing/common/data/Element" "blazing/common/data/xmlres" + "blazing/common/utils" "blazing/modules/blazing/model" "math/rand" @@ -42,6 +43,7 @@ type BattleSkillEntity struct { DamageValue decimal.Decimal // 伤害值 Rand *rand.Rand Pet *BattlePetEntity + First bool } // CreateBattleSkillWithInfinity 创建战斗技能实例(可指定是否无限PP) @@ -161,12 +163,7 @@ var DamageC = enum.New[struct { // } -// 暴击伤害 返回暴击率和是否暴击 -func (s *BattleSkillEntity) IsCritical() (decimal.Decimal, bool) { - return decimal.NewFromFloat(1), true - -} // 计算是否命中 func (s *BattleSkillEntity) AttackTime() uint32 { @@ -204,7 +201,7 @@ func (s *BattleSkillEntity) criticalrandom() decimal.Decimal { } // 计算技能威力 -func (s *BattleSkillEntity) CalculatePower(deftype int) uint32 { +func (s *BattleSkillEntity) CalculatePower(deftype *BattlePetEntity) uint32 { // 1. 计算等级因子 (level * 0.4 + 2) levelFactor := decimal.NewFromInt(int64(s.Pet.Info.Level)). @@ -255,7 +252,7 @@ func (s *BattleSkillEntity) CalculatePower(deftype int) uint32 { Div(decimal.NewFromInt(50)). Add(decimal.NewFromInt(2)) - t, _ := element.NewElementCalculator().GetOffensiveMultiplier(s.Type().ID, deftype) + t, _ := element.NewElementCalculator().GetOffensiveMultiplier(s.Type().ID, deftype.Type().ID) typeRate := decimal.NewFromFloat(t) diff --git a/logic/service/fightc.go b/logic/service/fightc.go index f7a36681..09e9aa7f 100644 --- a/logic/service/fightc.go +++ b/logic/service/fightc.go @@ -2,6 +2,7 @@ package service import ( "blazing/common/data/xmlres" + "blazing/common/utils" "blazing/logic/service/fight/info" "blazing/modules/blazing/model" "fmt" @@ -13,6 +14,7 @@ import ( "github.com/jinzhu/copier" "github.com/mohae/deepcopy" "github.com/panjf2000/ants/v2" + "github.com/shopspring/decimal" ) type PlayerI interface { @@ -415,20 +417,8 @@ func (f *FightC) newBPET(input *Input) *BPET { AttackValue: info.NewAttackValue(input.Player.ID()), Damage: 0, } -} // 定义泛型约束:只允许数值类型(整数、浮点数等) -type Number interface { - int | int8 | int16 | int32 | int64 | - uint | uint8 | uint16 | uint32 | uint64 | - float32 | float64 } -// Max 泛型函数:接收两个同类型的 Number 参数,返回最大值 -func Max[T Number](a, b T) T { - if a > b { - return a - } - return b -} func (f *FightC) initAttackers(fattack, sattack info.BattleActionI) { // 伤害值 @@ -454,19 +444,39 @@ func (f *FightC) initAttackers(fattack, sattack info.BattleActionI) { // 处理技能攻击逻辑 func (f *FightC) processSkillAttack(attacker, defender *BPET, skill *info.SelectSkillAction) { f.parseskill(skill) - spower := skill.Skill.CalculatePower(defender.Type().ID) + spower := skill.Skill.CalculatePower(defender.BattlePetEntity) attacker.Damage = spower // 记录技能信息 attacker.AttackValue.SkillID = uint32(skill.Skill.ID) attacker.AttackValue.AttackTime = skill.Skill.AttackTime() - // 判断是否暴击 - if _, ok := skill.Skill.IsCritical(); ok { + + CritRate := utils.Max(skill.Skill.CritRate, 1) + CritRateR := f.rand.Int31n(16) + //CritAtkFirst: 先出手时必定致命一击; 默认: 0 + if skill.Skill.CritAtkFirst != 0 && attacker == f.First { + CritRate = 16 + } + //CritAtkSecond: 后出手时必定致命一击; 默认: 0 + if skill.Skill.CritAtkSecond != 0 && attacker != f.First { + CritRate=16 + } + // CritSelfHalfHp: 自身体力低于一半时必定致命一击; 默认: 0 + if skill.Skill.CritSelfHalfHp != 0 && (attacker.CurrentPet.HP < int(attacker.CurrentPet.Info.MaxHp)/2) { + CritRate=16 + } + // CritFoeHalfHp: 对方体力低于一半时必定致命一击; 默认: 0 + if skill.Skill.CritSelfHalfHp != 0 && (defender.CurrentPet.HP < int(defender.CurrentPet.Info.MaxHp)/2) { + CritRate=16 + } + +//todo 暴击伤害 + if CritRateR <= int32(CritRate) { attacker.AttackValue.IsCritical = 1 } defender.CurrentPet.Info.Hp -= attacker.Damage - defender.CurrentPet.Info.Hp = Max((defender.CurrentPet.Info.Hp), 0) + defender.CurrentPet.Info.Hp = utils.Max((defender.CurrentPet.Info.Hp), 0) // 扣减防御方血量 }