diff --git a/logic/service/ai.go b/logic/service/ai.go index 8b5c8c21..46d3fc5c 100644 --- a/logic/service/ai.go +++ b/logic/service/ai.go @@ -7,9 +7,9 @@ import ( ) type AI_player struct { - FightC *FightC //绑定战斗标识 替代本身的是否战斗标记 //IsFighting bool - petinfo []model.PetInfo //精灵信息 - + FightC *FightC //绑定战斗标识 替代本身的是否战斗标记 //IsFighting bool + petinfo []model.PetInfo //精灵信息 + CanCapture bool } func NewAI_player(m model.PetInfo) *AI_player { diff --git a/logic/service/fight/battle/node/node.go b/logic/service/fight/battle/node/node.go index fbcd4702..25813697 100644 --- a/logic/service/fight/battle/node/node.go +++ b/logic/service/fight/battle/node/node.go @@ -67,3 +67,8 @@ func (this *EffectNode) GetArgSize() int { return this.ArgSize } +func (this *EffectNode) AttackTime() bool { + + return true + +} diff --git a/logic/service/fight/info/BattlePetEntity.go b/logic/service/fight/info/BattlePetEntity.go index 1ddeda2d..5e7a3b03 100644 --- a/logic/service/fight/info/BattlePetEntity.go +++ b/logic/service/fight/info/BattlePetEntity.go @@ -59,9 +59,50 @@ func (a *BattlePetEntity) SDefense() uint32 { return uint32(calculateRealValue(int64(a.Info.SpecialDefence), int(a.Prop.SpecialDefence))) } -func (a *BattlePetEntity) Accuracy(b int64) uint32 { - return uint32(calculateRealValue(b, int(a.Prop.Accuracy))) +// Accuracy 优化版命中率计算(用绝对值和正负判断处理等级) +func (a *BattlePetEntity) Accuracy(b int64) uint32 { + // 基础参数校验 + if b <= 0 { + return 0 + } + if b >= 100 { + return 100 + } + level := a.Prop.Accuracy + if level > 6 || level == 0 { //强化等级 + return uint32(calculateRealValue(int64(b), int(a.Prop.Accuracy))) + } + var temp float64 + switch level { + case -1: + temp = 0.85 + case -2: + temp = 0.7 + case -3: + temp = 0.55 + case -4: + temp = 0.45 + case -5: + temp = 0.35 + case -6: + temp = 0.25 + + } + return uint32( + decimal.NewFromInt(int64(b)). // 将b转为decimal类型 + Mul(decimal.NewFromFloat(temp)). // 精确乘以0.85 + Round(0). // 四舍五入到整数 + IntPart(), // 转为int64 + ) +} + +// 辅助函数:取整数绝对值(处理负等级) +func abs(x int8) int8 { + if x < 0 { + return -x + } + return x } type BattlePetEntity struct { diff --git a/logic/service/fight/info/BattleSkillEntity.go b/logic/service/fight/info/BattleSkillEntity.go index 160c8316..a9a9dd4e 100644 --- a/logic/service/fight/info/BattleSkillEntity.go +++ b/logic/service/fight/info/BattleSkillEntity.go @@ -164,6 +164,9 @@ var DamageC = enum.New[struct { // 计算是否命中 func (s *BattleSkillEntity) AttackTime() uint32 { + if s.MustHit != 0 { + return 1 + } if int64(s.Pet.Accuracy(int64(s.Accuracy))) > s.Rand.Int63n(100) { return 1 diff --git a/logic/service/fight/info/info.go b/logic/service/fight/info/info.go index 1fd30af7..ab755bfe 100644 --- a/logic/service/fight/info/info.go +++ b/logic/service/fight/info/info.go @@ -91,48 +91,48 @@ type AttackValue struct { } type WeakenedS struct { - Stack byte `struc:"skip"` - Round byte + Stack int8 `struc:"skip"` + Round int8 } type StatusDict struct { - Paralysis_0 byte // 0: 麻痹 - Poisoned_1 byte // 1: 中毒 - Burned_2 byte // 2: 烧伤 - DrainHP_3 byte // 3: 吸取对方的体力 - DrainedHP_4 byte // 4: 被对方吸取体力 - Frozen_5 byte // 5: 冻伤 - Fear_6 byte // 6: 害怕 - Tired_7 byte // 7: 疲惫 - Sleep_8 byte // 8: 睡眠 - Petrified_9 byte // 9: 石化 - Confused_10 byte // 10: 混乱 + Paralysis_0 int8 // 0: 麻痹 + Poisoned_1 int8 // 1: 中毒 + Burned_2 int8 // 2: 烧伤 + DrainHP_3 int8 // 3: 吸取对方的体力 + DrainedHP_4 int8 // 4: 被对方吸取体力 + Frozen_5 int8 // 5: 冻伤 + Fear_6 int8 // 6: 害怕 + Tired_7 int8 // 7: 疲惫 + Sleep_8 int8 // 8: 睡眠 + Petrified_9 int8 // 9: 石化 + Confused_10 int8 // 10: 混乱 Weakened_11 WeakenedS // 11: 衰弱 - MountainGodGuard_12 byte // 12: 山神守护 - Flammable_13 byte // 13: 易燃 - Berserk_14 byte // 14: 狂暴 - IceBound_15 byte // 15: 冰封 - Bleeding_16 byte // 16: 流血 - ImmuneToStatDrop_17 byte // 17: 免疫能力下降 - ImmuneToAbnormal_18 byte // 18: 免疫异常状态 - Paralyzed_19 byte // 19: 瘫痪 + MountainGodGuard_12 int8 // 12: 山神守护 + Flammable_13 int8 // 13: 易燃 + Berserk_14 int8 // 14: 狂暴 + IceBound_15 int8 // 15: 冰封 + Bleeding_16 int8 // 16: 流血 + ImmuneToStatDrop_17 int8 // 17: 免疫能力下降 + ImmuneToAbnormal_18 int8 // 18: 免疫异常状态 + Paralyzed_19 int8 // 19: 瘫痪 //Blind_20 byte // 20: 失明 } // 精灵的能力提升 type PropDict struct { // 攻击(@UInt long → uint32) - Attack byte + Attack int8 // 防御(@UInt long → uint32) - Defence byte + Defence int8 // 特攻(@UInt long → uint32) - SpecialAttack byte + SpecialAttack int8 // 特防(@UInt long → uint32) - SpecialDefence byte + SpecialDefence int8 // 速度(@UInt long → uint32) - Speed byte + Speed int8 // 命中(@UInt long → uint32) - Accuracy byte + Accuracy int8 } // BattleLevels 战斗属性等级结构体,对应原6字节数组 diff --git a/logic/service/fight/info/nodemanger.go b/logic/service/fight/info/nodemanger.go index 5d90005e..7c4f7733 100644 --- a/logic/service/fight/info/nodemanger.go +++ b/logic/service/fight/info/nodemanger.go @@ -19,9 +19,9 @@ type Effect interface { OnDamage() bool // 造成伤害时触发 SetArgs(param []int) //设置参数 - Shield() bool // 护盾值变化时触发 - PostDamage() bool // 伤害结算后触发(血量扣除后) - + Shield() bool // 护盾值变化时触发 + PostDamage() bool // 伤害结算后触发(血量扣除后) + AttackTime() bool //闪避率计算,,实际上是修改命中的判断 OnCritPostDamage() bool // 暴击伤害结算后触发 OnHit() bool // 技能命中时触发 diff --git a/logic/service/fightc.go b/logic/service/fightc.go index f961ac96..b46bdebe 100644 --- a/logic/service/fightc.go +++ b/logic/service/fightc.go @@ -175,6 +175,9 @@ func (f *FightC) ReadyFight(c PlayerI) { //判断捕捉率大于0 if gconv.Int(xmlres.PetMAP[int(f.Info.OpponentPetList[0].ID)].CatchRate) > 0 { rett.Info2.Catchable = 1 + t, _ := f.Opp.Player.(*AI_player) + t.CanCapture = true + } rrsult() @@ -347,12 +350,19 @@ func (f *FightC) battleLoop() { f.Broadcast(func(ff *Input) { //todo 将血量和技能pp传回enterturn tt, ok := ff.Player.(*Player) - if ok { - tt.Service.PetAdd(*f.Opp.CurrentPet.Info) - tt.CatchPetInfo(info.CatchMonsterOutboundInfo{ - CatchTime: uint32(f.Opp.CurrentPet.Info.CatchTime), - PetId: uint32(f.Opp.CurrentPet.ID), - }) + mo, ism := f.Opp.Player.(*AI_player) + + if ok { //如果获取玩家 + + if ism && mo.CanCapture { //如果获取到IA + tt.Service.PetAdd(*f.Opp.CurrentPet.Info) + tt.CatchPetInfo(info.CatchMonsterOutboundInfo{ + CatchTime: uint32(f.Opp.CurrentPet.Info.CatchTime), + PetId: uint32(f.Opp.CurrentPet.ID), + }) + } else { //说明不是可以捕捉的 + tt.CatchPetInfo(info.CatchMonsterOutboundInfo{}) + } } @@ -483,49 +493,64 @@ 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.BattlePetEntity) - attacker.Damage = spower + f.parseskill(skill) //解析effect // 记录技能信息 - attacker.AttackValue.SkillID = uint32(skill.Skill.ID) - attacker.AttackValue.AttackTime = skill.Skill.AttackTime() + attacker.AttackValue.SkillID = uint32(skill.Skill.ID) //获取技能ID + attacker.AttackValue.AttackTime = skill.Skill.AttackTime() //计算命中 - 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 - } + f.EffectS.Exec(func(t info.Effect) bool { //计算闪避 闪避就是命中率重新计算的结果 + //闪避本质上是算对方的命中重写函数? - //todo 暴击伤害 - if CritRateR <= int32(CritRate) { - attacker.AttackValue.IsCritical = 1 - } + if attacker.UserID == f.Our.Player.ID() { - if attacker.AttackValue.IsCritical == 1 { - attacker.Damage.Mul(decimal.NewFromInt(2)) //暴击翻倍 - } + } + if !t.GetOwner() { //先获取对方的 + return t.AttackTime() + } + return true + }) - if uint32(attacker.Damage.IntPart()) > defender.CurrentPet.Info.Hp { - defender.CurrentPet.Info.Hp = 0 - } else { - defender.CurrentPet.Info.Hp = defender.CurrentPet.Info.Hp - uint32(attacker.Damage.IntPart()) - } + if attacker.AttackValue.AttackTime == 1 { //如果命中 - // 扣减防御方血量 + spower := skill.Skill.CalculatePower(defender.BattlePetEntity) + attacker.Damage = spower + 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 + } + + if attacker.AttackValue.IsCritical == 1 { + attacker.Damage.Mul(decimal.NewFromInt(2)) //暴击翻倍 + } + + if uint32(attacker.Damage.IntPart()) > defender.CurrentPet.Info.Hp { + defender.CurrentPet.Info.Hp = 0 + } else { + defender.CurrentPet.Info.Hp = defender.CurrentPet.Info.Hp - uint32(attacker.Damage.IntPart()) + } + + // 扣减防御方血量 + } //todo 处理未命中效果 }