fix(logic): 修复登录逻辑和战斗系统的问题

- 修正登录时地图 ID 的处理逻辑
- 优化战斗宠物实体和技能实体的创建及使用
- 改进战斗伤害计算和处理方式
- 修复战斗结束后宠物信息更新问题
This commit is contained in:
2025-09-10 22:59:10 +08:00
parent a0441700e5
commit e0ec9ee1ec
4 changed files with 65 additions and 44 deletions

View File

@@ -57,7 +57,10 @@ func (h *Controller) Login(data *login.InInfo, c *service.Conn) (result *login.O
}
}
if t.MapID() > 10000 {
t.Info.MapID = 1
}
t.CompleteLogin() //通知客户端登录成功
glog.Debug(context.Background(), "登录成功,初始地图 人数:", space.GetSpace(t.Info.MapID).Len())

View File

@@ -66,7 +66,7 @@ func (a *BattlePetEntity) Accuracy(b int64) uint32 {
type BattlePetEntity struct {
xmlres.PetInfo
Info model.PetInfo //通过偏移赋值
Info *model.PetInfo //通过偏移赋值
statusConditions sync.Map // key: StatusCondition, value: int (剩余回合)
Skills [4]*BattleSkillEntity // 技能槽最多4个技能
@@ -139,7 +139,7 @@ func (s *BattlePetEntity) PutDamageZone(e EnumCategory, dtype EnumsZoneType, val
}
// 创建精灵实例
func CreateBattlePetEntity(info model.PetInfo, rand *rand.Rand) *BattlePetEntity {
func CreateBattlePetEntity(info *model.PetInfo, rand *rand.Rand) *BattlePetEntity {
ret := &BattlePetEntity{}
ret.PetInfo = xmlres.PetMAP[int(info.ID)] //注入精灵信息

View File

@@ -3,7 +3,6 @@ package info
import (
element "blazing/common/data/Element"
"blazing/common/data/xmlres"
"blazing/common/utils"
"blazing/modules/blazing/model"
"math/rand"
@@ -38,7 +37,7 @@ var Category = enum.New[struct {
// 战斗中可以修改技能实体值,比如是否暴击,是否必中等
type BattleSkillEntity struct {
xmlres.Move
PP int
Info *model.SkillInfo
DamageValue decimal.Decimal // 伤害值
Rand *rand.Rand
@@ -72,7 +71,7 @@ func CreateBattleSkillWithInfinity(skill *model.SkillInfo, rand *rand.Rand, pet
// if err == nil {
// ret.SideEffects = rf
// }
ret.PP = int(skill.PP)
ret.Info = skill
// ret.SideEffectArgs = sideEffectArgs
return &ret
@@ -97,7 +96,7 @@ func strSliceToIntSlice(strs []string) ([]int, error) {
// CanUse 检查技能是否可以使用PP是否充足
func (s *BattleSkillEntity) CanUse() bool {
return s.PP > 0
return s.Info.PP > 0
}
// 获取技能类型
@@ -163,8 +162,6 @@ var DamageC = enum.New[struct {
// }
// 计算是否命中
func (s *BattleSkillEntity) AttackTime() uint32 {
@@ -201,7 +198,7 @@ func (s *BattleSkillEntity) criticalrandom() decimal.Decimal {
}
// 计算技能威力
func (s *BattleSkillEntity) CalculatePower(deftype *BattlePetEntity) uint32 {
func (s *BattleSkillEntity) CalculatePower(deftype *BattlePetEntity) decimal.Decimal {
// 1. 计算等级因子 (level * 0.4 + 2)
levelFactor := decimal.NewFromInt(int64(s.Pet.Info.Level)).
@@ -237,7 +234,7 @@ func (s *BattleSkillEntity) CalculatePower(deftype *BattlePetEntity) uint32 {
//damageReduction = decimal.NewFromFloat(s.DamageZone[DamageMultiplierZoneEnum.SP_ATK_RESISTANCE])
default:
return 0
return decimal.NewFromInt(0)
}
if powerMul_p.IntPart() == 0 {
@@ -261,10 +258,7 @@ func (s *BattleSkillEntity) CalculatePower(deftype *BattlePetEntity) uint32 {
Mul(typeRate). // 克制系数
Mul(s.criticalrandom()) //随机波动
v, ok := s.IsCritical() //获取暴击
if ok {
damage.Mul(v)
}
return uint32(damage.IntPart())
return damage
}

View File

@@ -189,23 +189,23 @@ func NewFight(i info.NoteReadyToFightInfo, p1 PlayerI, p2 PlayerI) *FightC {
f.rand = rand.New(rand.NewSource(seed))
f.Our = &Input{
CurrentPet: info.CreateBattlePetEntity(p1.GetPetInfo()[0], f.rand),
CurrentPet: info.CreateBattlePetEntity(&p1.GetPetInfo()[0], f.rand),
Player: p1,
}
for k, v := range p1.GetPetInfo() {
if i.MAXPET == 0 || k < int(i.MAXPET) { //todo 待测试
f.Our.AllPet = append(f.Our.AllPet, info.CreateBattlePetEntity(v, f.rand))
f.Our.AllPet = append(f.Our.AllPet, info.CreateBattlePetEntity(&v, f.rand))
}
}
f.Opp = &Input{
CurrentPet: info.CreateBattlePetEntity(p2.GetPetInfo()[0], f.rand),
CurrentPet: info.CreateBattlePetEntity(&p2.GetPetInfo()[0], f.rand),
Player: p2,
}
for k, v := range p2.GetPetInfo() {
if i.MAXPET == 0 || k < int(i.MAXPET) {
f.Opp.AllPet = append(f.Opp.AllPet, info.CreateBattlePetEntity(v, f.rand))
f.Opp.AllPet = append(f.Opp.AllPet, info.CreateBattlePetEntity(&v, f.rand))
}
}
@@ -245,7 +245,7 @@ func (f *FightC) battleLoop() {
f.Round++ //回合数自增
if f.Round > 250 || f.actionChan == nil { //回合数超过250,战斗平局结束
if f.actionChan == nil { //回合数超过250,战斗平局结束f.Round > 250 ||
break
}
actions := make(map[uint32]info.BattleActionI) // 每个玩家一条记录
@@ -351,7 +351,7 @@ type BPET struct {
*info.AttackValue
*FightC
info.BattleActionI
Damage uint32 //造成伤害
Damage decimal.Decimal //造成伤害
}
// 被击败的ID
@@ -415,7 +415,6 @@ func (f *FightC) newBPET(input *Input) *BPET {
Input: input,
BattlePetEntity: input.CurrentPet,
AttackValue: info.NewAttackValue(input.Player.ID()),
Damage: 0,
}
}
@@ -459,41 +458,36 @@ func (f *FightC) processSkillAttack(attacker, defender *BPET, skill *info.Select
}
//CritAtkSecond: 后出手时必定致命一击; 默认: 0
if skill.Skill.CritAtkSecond != 0 && attacker != f.First {
CritRate=16
CritRate = 16
}
// CritSelfHalfHp: 自身体力低于一半时必定致命一击; 默认: 0
if skill.Skill.CritSelfHalfHp != 0 && (attacker.CurrentPet.HP < int(attacker.CurrentPet.Info.MaxHp)/2) {
CritRate=16
CritRate = 16
}
// CritFoeHalfHp: 对方体力低于一半时必定致命一击; 默认: 0
if skill.Skill.CritSelfHalfHp != 0 && (defender.CurrentPet.HP < int(defender.CurrentPet.Info.MaxHp)/2) {
CritRate=16
CritRate = 16
}
//todo 暴击伤害
//todo 暴击伤害
if CritRateR <= int32(CritRate) {
attacker.AttackValue.IsCritical = 1
}
defender.CurrentPet.Info.Hp -= attacker.Damage
defender.CurrentPet.Info.Hp = utils.Max((defender.CurrentPet.Info.Hp), 0)
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())
}
// 扣减防御方血量
}
// 检查战斗是否结束
func (f *FightC) winner(winner *BPET) func() {
return func() {
f.Broadcast(func(ff *Input) {
ff.Player.SendFightEndInfo(info.FightOverInfo{
WinnerId: winner.Player.ID(),
})
})
close(f.actionChan)
//f.actionChan = nil
}
}
func (f *FightC) enterturn(fattack, sattack info.BattleActionI) {
f.initAttackers(fattack, sattack) //初始化先后手
var attacker, defender *BPET
@@ -532,6 +526,36 @@ func (f *FightC) enterturn(fattack, sattack info.BattleActionI) {
WinnerId = f.Second.Player.ID()
}
defer f.Broadcast(func(ff *Input) {
//todo 将血量和技能pp传回enterturn
pl, ok := ff.Player.(*Player)
if ok { //说明是玩家,需要传回数据
var temp []model.PetInfo //先初始化一个临时的数据
for _, pi := range pl.Info.PetList {
for _, v := range attacker.AllPet {
if v.Info.CatchTime == pi.CatchTime { //如果找到精灵
pi.Hp = v.Info.Hp
for i, v := range v.Skills {
for _, v1 := range pi.SkillList {
if v1.ID == uint32(v.ID) {
pi.SkillList[i].PP = uint32(v.PP)
}
}
}
}
}
temp = append(temp, pi)
}
pl.Info.PetList = temp
}
ff.Player.SendFightEndInfo(info.FightOverInfo{
WinnerId: WinnerId,
})
@@ -550,9 +574,9 @@ func (f *FightC) enterturn(fattack, sattack info.BattleActionI) {
}
ret.FAttack.RemainHp = int32(f.First.CurrentPet.Info.Hp)
ret.FAttack.LostHp = uint32(f.First.Damage) //先手方造成血量
ret.FAttack.LostHp = uint32(f.First.Damage.IntPart()) //先手方造成血量
ret.SAttack.RemainHp = int32(f.Second.CurrentPet.Info.Hp)
ret.SAttack.LostHp = uint32(f.Second.Damage) //后手方造成血量
ret.SAttack.LostHp = uint32(f.Second.Damage.IntPart()) //后手方造成血量
//ret.SAttack.Status.Poisoned_1 = 1
ff.Player.SendAttackValue(ret)
})