All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
feat(fight): 添加旧组队协议支持并优化战斗系统 - 实现了旧组队协议相关功能,包括GroupReadyFightFinish、GroupUseSkill、 GroupUseItem、GroupChangePet和GroupEscape方法 - 新增组队战斗相关的入站信息结构体定义 - 实现了组队BOSS战斗逻辑,添加groupBossSlotLimit常量 - 重构宠物技能设置逻辑,调整金币消耗时机 - 优化战斗循环逻辑,添加对无行动槽位的处理 - 改进AI行动逻辑,增加多位置目标选择机制 - 完善捕获系统上下文处理,修复空指针问题 - 添加战斗状态更新和数据同步机制 fix(pet-skill): 修复宠物技能设置中的金币扣除逻辑错误 - 将金币扣除逻辑移到验证之后 - 修正宠物技能数量限制检查的顺序 - 防止重复添加已有技能的情况 refactor(fight): 重构战斗系统代码结构 - 分离新旧组队协议的战斗创建逻辑 - 优化战斗输入验证和处理流程 - 改进战斗循环中的错误处理机制 ```
685 lines
20 KiB
Go
685 lines
20 KiB
Go
package fight
|
|
|
|
import (
|
|
"blazing/logic/service/common"
|
|
"blazing/logic/service/fight/action"
|
|
"blazing/logic/service/fight/info"
|
|
"blazing/logic/service/fight/input"
|
|
"blazing/modules/player/model"
|
|
)
|
|
|
|
const (
|
|
groupCmdReadyToFight uint32 = 7555
|
|
groupCmdReadyFightFinish uint32 = 7556
|
|
groupCmdStartFight uint32 = 7557
|
|
groupCmdUseSkill uint32 = 7558
|
|
groupCmdSkillHurt uint32 = 7559
|
|
groupCmdFightOver uint32 = 7560
|
|
groupCmdSpriteDie uint32 = 7561
|
|
groupCmdUseItem uint32 = 7562
|
|
groupCmdChangePet uint32 = 7563
|
|
groupCmdEscape uint32 = 7565
|
|
groupCmdBoutDone uint32 = 7566
|
|
groupCmdChangePetSuc uint32 = 7567
|
|
groupCmdEscapeSuc uint32 = 7568
|
|
groupCmdChat uint32 = 7569
|
|
groupCmdLoadPercent uint32 = 7571
|
|
groupCmdLoadPercentNotice uint32 = 7572
|
|
groupCmdSpriteNotice uint32 = 7573
|
|
groupCmdFightWinClose uint32 = 7574
|
|
groupCmdFightOvertime uint32 = 7585
|
|
groupCmdSkillPlayOver uint32 = 7586
|
|
groupCmdFightTimeoutExit uint32 = 7587
|
|
groupCmdFightRelation uint32 = 7588
|
|
groupModelNPC uint32 = 3
|
|
groupModelBoss uint32 = 4
|
|
groupModelPlayerSingle uint32 = 5
|
|
groupModelPlayerMulti uint32 = 6
|
|
)
|
|
|
|
type fightPacketKind uint8
|
|
|
|
const (
|
|
fightPacketReady fightPacketKind = iota
|
|
fightPacketStart
|
|
fightPacketSkillResult
|
|
fightPacketOver
|
|
fightPacketChangePetSuccess
|
|
fightPacketUseItem
|
|
fightPacketChat
|
|
fightPacketLoadPercentNotice
|
|
)
|
|
|
|
type legacyEscapeSuccessInfo struct {
|
|
UserID uint32 `struc:"uint32"`
|
|
Nick string `struc:"[16]byte"`
|
|
Side uint8 `struc:"uint8"`
|
|
ActorIndex uint8 `struc:"uint8"`
|
|
}
|
|
|
|
type legacyBoutDoneInfo struct {
|
|
Round uint32 `struc:"uint32"`
|
|
}
|
|
|
|
type legacySpriteDieInfo struct {
|
|
Count uint8 `struc:"uint8"`
|
|
Side uint8 `struc:"uint8"`
|
|
ActorIndex uint8 `struc:"uint8"`
|
|
Flag uint8 `struc:"uint8"`
|
|
HasBackup uint32 `struc:"uint32"`
|
|
}
|
|
|
|
type legacyLegacySpriteDieItem struct {
|
|
Flag uint8 `struc:"uint8"`
|
|
Side uint8 `struc:"uint8"`
|
|
ActorIndex uint8 `struc:"uint8"`
|
|
Reserve uint8 `struc:"uint8"`
|
|
HasBackup uint32 `struc:"uint32"`
|
|
}
|
|
|
|
type legacyGroupReadyToFightInfo struct {
|
|
Model uint32 `struc:"uint32"`
|
|
GroupOneInfo legacyReadyToFightTeam `struc:""`
|
|
GroupTwoInfo legacyReadyToFightTeam `struc:""`
|
|
}
|
|
|
|
type legacyReadyToFightTeam struct {
|
|
InvitorID uint8 `struc:"uint8"`
|
|
LeaderID uint32 `struc:"uint32"`
|
|
GroupMembCnt uint8 `struc:"sizeof=GroupList"`
|
|
GroupList []legacyReadyFightUser `struc:""`
|
|
}
|
|
|
|
type legacyReadyFightUser struct {
|
|
UserID uint32 `struc:"uint32"`
|
|
Nick string `struc:"[16]byte"`
|
|
MonCnt uint32 `struc:"sizeof=MonList"`
|
|
MonList []legacyReadyFightPet `struc:""`
|
|
}
|
|
|
|
type legacyReadyFightPet struct {
|
|
ID uint32 `struc:"uint32"`
|
|
MoveCnt uint32 `struc:"sizeof=MoveList"`
|
|
MoveList []uint32 `struc:"[]uint32"`
|
|
}
|
|
|
|
type legacyGroupStartInfo struct {
|
|
IsGank uint8 `struc:"uint8"`
|
|
GroupOneN uint8 `struc:"sizeof=GroupOne"`
|
|
GroupOne []legacyGroupStartPet `struc:""`
|
|
GroupTwoN uint8 `struc:"sizeof=GroupTwo"`
|
|
GroupTwo []legacyGroupStartPet `struc:""`
|
|
}
|
|
|
|
type legacyGroupStartPet struct {
|
|
Side uint8 `struc:"uint8"`
|
|
Pos uint8 `struc:"uint8"`
|
|
UserID uint32 `struc:"uint32"`
|
|
IsChange uint8 `struc:"uint8"`
|
|
PetID uint32 `struc:"uint32"`
|
|
CatchTime uint32 `struc:"uint32"`
|
|
Hp uint32 `struc:"uint32"`
|
|
MaxHp uint32 `struc:"uint32"`
|
|
Level uint32 `struc:"uint32"`
|
|
Reserve uint32 `struc:"uint32"`
|
|
Flag uint32 `struc:"uint32"`
|
|
}
|
|
|
|
type legacyGroupSkillHurtPacket struct {
|
|
IsGank uint8 `struc:"uint8"`
|
|
Attack legacyGroupSkillAttackInfo `struc:""`
|
|
Attacked legacyGroupSkillDefendInfo `struc:""`
|
|
}
|
|
|
|
type legacyGroupSkillAttackInfo struct {
|
|
IsAttackor uint8 `struc:"uint8"`
|
|
Side uint8 `struc:"uint8"`
|
|
Pos uint8 `struc:"uint8"`
|
|
UserID uint32 `struc:"uint32"`
|
|
StatusList [20]uint8 `struc:"[20]byte"`
|
|
Reserve1 uint8 `struc:"uint8"`
|
|
Reserve2 uint8 `struc:"uint8"`
|
|
BatLvList [6]uint8 `struc:"[6]byte"`
|
|
PetID uint32 `struc:"uint32"`
|
|
MoveID uint32 `struc:"uint32"`
|
|
Hp uint32 `struc:"uint32"`
|
|
MaxHp uint32 `struc:"uint32"`
|
|
MoveCnt uint32 `struc:"sizeof=MoveMap"`
|
|
MoveMap []legacyGroupSkillMoveInfo `struc:""`
|
|
Flag uint32 `struc:"uint32"`
|
|
IsCrit uint32 `struc:"uint32"`
|
|
EffectName uint32 `struc:"uint32"`
|
|
AtkTimes uint32 `struc:"uint32"`
|
|
Dmg int32 `struc:"int32"`
|
|
ChgHp int32 `struc:"int32"`
|
|
SideEffectLen uint32 `struc:"uint32"`
|
|
}
|
|
|
|
type legacyGroupSkillDefendInfo struct {
|
|
IsAttackor uint8 `struc:"uint8"`
|
|
Side uint8 `struc:"uint8"`
|
|
Pos uint8 `struc:"uint8"`
|
|
UserID uint32 `struc:"uint32"`
|
|
StatusList [20]uint8 `struc:"[20]byte"`
|
|
Reserve1 uint8 `struc:"uint8"`
|
|
Reserve2 uint8 `struc:"uint8"`
|
|
BatLvList [6]uint8 `struc:"[6]byte"`
|
|
PetID uint32 `struc:"uint32"`
|
|
MoveID uint32 `struc:"uint32"`
|
|
Hp uint32 `struc:"uint32"`
|
|
MaxHp uint32 `struc:"uint32"`
|
|
MoveCnt uint32 `struc:"sizeof=MoveMap"`
|
|
MoveMap []legacyGroupSkillMoveInfo `struc:""`
|
|
Flag uint32 `struc:"uint32"`
|
|
SideEffectLen uint32 `struc:"uint32"`
|
|
}
|
|
|
|
type legacyGroupSkillMoveInfo struct {
|
|
MoveID uint32 `struc:"uint32"`
|
|
PP uint32 `struc:"uint32"`
|
|
}
|
|
|
|
type legacyGroupFightOverInfo struct {
|
|
IsGank uint8 `struc:"uint8"`
|
|
Reason uint32 `struc:"uint32"`
|
|
WinnerID uint32 `struc:"uint32"`
|
|
Reserve uint32 `struc:"uint32"`
|
|
TwoTimes uint32 `struc:"uint32"`
|
|
ThreeTimes uint32 `struc:"uint32"`
|
|
AutoFightTime uint32 `struc:"uint32"`
|
|
Reserve2 uint32 `struc:"uint32"`
|
|
EnergyTime uint32 `struc:"uint32"`
|
|
LearnTimes uint32 `struc:"uint32"`
|
|
}
|
|
|
|
type legacyGroupChangePetSuccessInfo struct {
|
|
Side uint8 `struc:"uint8"`
|
|
Pos uint8 `struc:"uint8"`
|
|
UserID uint32 `struc:"uint32"`
|
|
PetID uint32 `struc:"uint32"`
|
|
CatchTime uint32 `struc:"uint32"`
|
|
Level uint32 `struc:"uint32"`
|
|
Hp uint32 `struc:"uint32"`
|
|
MaxHp uint32 `struc:"uint32"`
|
|
SkinID uint32 `struc:"uint32"`
|
|
}
|
|
|
|
func groupModelByFight(f *FightC) uint32 {
|
|
if f == nil {
|
|
return groupModelBoss
|
|
}
|
|
switch {
|
|
case f.Info.Status == 0:
|
|
return groupModelNPC
|
|
case f.Info.Status == 1 && f.Info.Mode == 1:
|
|
return groupModelPlayerSingle
|
|
case f.Info.Status == 1:
|
|
return groupModelPlayerMulti
|
|
default:
|
|
return groupModelBoss
|
|
}
|
|
}
|
|
|
|
func (f *FightC) fightPacketCmd(kind fightPacketKind) uint32 {
|
|
switch kind {
|
|
case fightPacketReady:
|
|
return 2503
|
|
case fightPacketStart:
|
|
return 2504
|
|
case fightPacketSkillResult:
|
|
return 2505
|
|
case fightPacketOver:
|
|
return 2506
|
|
case fightPacketChangePetSuccess:
|
|
if f != nil && f.LegacyGroupProtocol {
|
|
return groupCmdChangePetSuc
|
|
}
|
|
return 2407
|
|
case fightPacketUseItem:
|
|
if f != nil && f.LegacyGroupProtocol {
|
|
return groupCmdUseItem
|
|
}
|
|
return 2406
|
|
case fightPacketChat:
|
|
if f != nil && f.LegacyGroupProtocol {
|
|
return groupCmdChat
|
|
}
|
|
return 50002
|
|
case fightPacketLoadPercentNotice:
|
|
if f != nil && f.LegacyGroupProtocol {
|
|
return groupCmdLoadPercentNotice
|
|
}
|
|
return 2441
|
|
default:
|
|
return 0
|
|
}
|
|
}
|
|
|
|
func (f *FightC) sendFightPacket(player common.PlayerI, kind fightPacketKind, payload any) {
|
|
if player == nil {
|
|
return
|
|
}
|
|
cmd := f.fightPacketCmd(kind)
|
|
if cmd == 0 {
|
|
return
|
|
}
|
|
player.SendPackCmd(cmd, payload)
|
|
}
|
|
|
|
func (f *FightC) sendLegacyGroupReady(player common.PlayerI) {
|
|
if f == nil || !f.LegacyGroupProtocol || player == nil {
|
|
return
|
|
}
|
|
player.SendPackCmd(groupCmdReadyToFight, f.buildLegacyGroupReadyInfo())
|
|
}
|
|
|
|
func (f *FightC) buildLegacyGroupReadyInfo() *legacyGroupReadyToFightInfo {
|
|
return &legacyGroupReadyToFightInfo{
|
|
Model: groupModelByFight(f),
|
|
GroupOneInfo: f.buildLegacyReadyTeam(f.OurPlayers, f.Our),
|
|
GroupTwoInfo: f.buildLegacyReadyTeam(f.OppPlayers, f.Opp),
|
|
}
|
|
}
|
|
|
|
func (f *FightC) buildLegacyReadyTeam(players []common.PlayerI, inputs []*input.Input) legacyReadyToFightTeam {
|
|
team := legacyReadyToFightTeam{InvitorID: 1}
|
|
users := make([]legacyReadyFightUser, 0, len(players))
|
|
for _, p := range players {
|
|
if p == nil || p.GetInfo() == nil {
|
|
continue
|
|
}
|
|
users = append(users, legacyReadyFightUser{
|
|
UserID: p.GetInfo().UserID,
|
|
Nick: p.GetInfo().Nick,
|
|
MonList: collectLegacyReadyPetsByController(inputs, p.GetInfo().UserID),
|
|
})
|
|
}
|
|
if len(users) == 0 {
|
|
if fallback := firstNonNilInput(inputs); fallback != nil && fallback.Player != nil && fallback.Player.GetInfo() != nil {
|
|
info := fallback.Player.GetInfo()
|
|
users = append(users, legacyReadyFightUser{
|
|
UserID: info.UserID,
|
|
Nick: info.Nick,
|
|
MonList: collectLegacyReadyPetsByController(inputs, info.UserID),
|
|
})
|
|
}
|
|
}
|
|
for idx := range users {
|
|
users[idx].MonCnt = uint32(len(users[idx].MonList))
|
|
}
|
|
if len(users) > 0 {
|
|
team.LeaderID = users[0].UserID
|
|
}
|
|
team.GroupList = users
|
|
return team
|
|
}
|
|
|
|
func collectLegacyReadyPetsByController(inputs []*input.Input, controllerID uint32) []legacyReadyFightPet {
|
|
pets := make([]legacyReadyFightPet, 0, 6)
|
|
for _, in := range inputs {
|
|
if in == nil || !in.ControlledBy(controllerID) {
|
|
continue
|
|
}
|
|
currentPet := in.CurrentPet()
|
|
if currentPet == nil {
|
|
continue
|
|
}
|
|
pets = append(pets, buildLegacyReadyFightPet(currentPet))
|
|
}
|
|
return pets
|
|
}
|
|
|
|
func buildLegacyReadyFightPet(pet *info.BattlePetEntity) legacyReadyFightPet {
|
|
result := legacyReadyFightPet{}
|
|
if pet == nil {
|
|
return result
|
|
}
|
|
moves := make([]uint32, 0, len(pet.Info.SkillList))
|
|
for _, skill := range pet.Info.SkillList {
|
|
if skill.ID == 0 {
|
|
continue
|
|
}
|
|
moves = append(moves, skill.ID)
|
|
}
|
|
result.ID = pet.Info.ID
|
|
result.MoveList = moves
|
|
return result
|
|
}
|
|
|
|
func firstNonNilInput(inputs []*input.Input) *input.Input {
|
|
for _, in := range inputs {
|
|
if in != nil {
|
|
return in
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (f *FightC) sendLegacyGroupStart(player common.PlayerI) {
|
|
if f == nil || !f.LegacyGroupProtocol || player == nil {
|
|
return
|
|
}
|
|
player.SendPackCmd(groupCmdStartFight, f.buildLegacyGroupStartInfo())
|
|
}
|
|
|
|
func (f *FightC) buildLegacyGroupStartInfo() *legacyGroupStartInfo {
|
|
return &legacyGroupStartInfo{
|
|
IsGank: 0,
|
|
GroupOne: f.collectLegacyGroupStartPets(f.Our, 1),
|
|
GroupTwo: f.collectLegacyGroupStartPets(f.Opp, 2),
|
|
}
|
|
}
|
|
|
|
func (f *FightC) collectLegacyGroupStartPets(inputs []*input.Input, side uint8) []legacyGroupStartPet {
|
|
ret := make([]legacyGroupStartPet, 0, len(inputs))
|
|
for pos, in := range inputs {
|
|
if in == nil {
|
|
continue
|
|
}
|
|
currentPet := in.CurrentPet()
|
|
if currentPet == nil {
|
|
continue
|
|
}
|
|
userID := uint32(0)
|
|
if in.Player != nil && in.Player.GetInfo() != nil {
|
|
userID = in.Player.GetInfo().UserID
|
|
}
|
|
ret = append(ret, legacyGroupStartPet{
|
|
Side: side,
|
|
Pos: uint8(pos),
|
|
UserID: userID,
|
|
IsChange: 0,
|
|
PetID: currentPet.Info.ID,
|
|
CatchTime: currentPet.Info.CatchTime,
|
|
Hp: currentPet.Info.Hp,
|
|
MaxHp: currentPet.Info.MaxHp,
|
|
Level: currentPet.Info.Level,
|
|
Reserve: 0,
|
|
Flag: 1,
|
|
})
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func (f *FightC) sendLegacyGroupOver(player common.PlayerI, over *model.FightOverInfo) {
|
|
if f == nil || !f.LegacyGroupProtocol || player == nil {
|
|
return
|
|
}
|
|
player.SendPackCmd(groupCmdFightOver, f.buildLegacyGroupOverInfo(over))
|
|
}
|
|
|
|
func (f *FightC) buildLegacyGroupOverInfo(over *model.FightOverInfo) *legacyGroupFightOverInfo {
|
|
result := &legacyGroupFightOverInfo{}
|
|
if over != nil {
|
|
result.Reason = resolveLegacyGroupFightOverReason(over)
|
|
result.WinnerID = over.WinnerId
|
|
}
|
|
if our := f.primaryOurPlayer(); our != nil && our.GetInfo() != nil {
|
|
playerInfo := our.GetInfo()
|
|
result.TwoTimes = uint32(playerInfo.TwoTimes)
|
|
result.ThreeTimes = uint32(playerInfo.ThreeTimes)
|
|
result.AutoFightTime = playerInfo.AutoFightTime
|
|
result.EnergyTime = uint32(playerInfo.EnergyTime)
|
|
result.LearnTimes = playerInfo.LearnTimes
|
|
}
|
|
return result
|
|
}
|
|
|
|
func mapLegacyGroupFightOverReason(reason model.EnumBattleOverReason) uint32 {
|
|
switch reason {
|
|
case model.BattleOverReason.PlayerOffline:
|
|
return 2
|
|
case model.BattleOverReason.PlayerOVerTime:
|
|
return 3
|
|
case model.BattleOverReason.NOTwind:
|
|
return 4
|
|
case model.BattleOverReason.DefaultEnd:
|
|
return 1
|
|
case model.BattleOverReason.PlayerEscape:
|
|
return 6
|
|
default:
|
|
return 5
|
|
}
|
|
}
|
|
|
|
func resolveLegacyGroupFightOverReason(over *model.FightOverInfo) uint32 {
|
|
if over == nil {
|
|
return 5
|
|
}
|
|
switch over.Reason {
|
|
case model.BattleOverReason.PlayerOffline:
|
|
return 2
|
|
case model.BattleOverReason.PlayerOVerTime:
|
|
return 3
|
|
case model.BattleOverReason.PlayerEscape:
|
|
return 6
|
|
case model.BattleOverReason.NOTwind:
|
|
return 4
|
|
}
|
|
if over.WinnerId != 0 {
|
|
return 1
|
|
}
|
|
return mapLegacyGroupFightOverReason(over.Reason)
|
|
}
|
|
|
|
func (f *FightC) sendLegacyGroupChangePetSuccess(player common.PlayerI, in *input.Input, reason *info.ChangePetInfo) {
|
|
if f == nil || !f.LegacyGroupProtocol || player == nil || in == nil || reason == nil {
|
|
return
|
|
}
|
|
player.SendPackCmd(groupCmdChangePetSuc, f.buildLegacyGroupChangePetSuccessInfo(in, reason))
|
|
}
|
|
|
|
func (f *FightC) buildLegacyGroupChangePetSuccessInfo(in *input.Input, reason *info.ChangePetInfo) *legacyGroupChangePetSuccessInfo {
|
|
result := &legacyGroupChangePetSuccessInfo{}
|
|
if in == nil || reason == nil {
|
|
return result
|
|
}
|
|
if !f.isOurPlayerID(in.UserID) {
|
|
result.Side = 2
|
|
} else {
|
|
result.Side = 1
|
|
}
|
|
result.Pos = uint8(in.TeamSlotIndex())
|
|
result.UserID = reason.UserId
|
|
result.PetID = reason.ID
|
|
result.CatchTime = reason.CatchTime
|
|
result.Level = reason.Level
|
|
result.Hp = reason.Hp
|
|
result.MaxHp = reason.MaxHp
|
|
if currentPet := in.CurrentPet(); currentPet != nil {
|
|
result.SkinID = currentPet.Info.SkinID
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (f *FightC) SendLegacyEscapeSuccess(player common.PlayerI, actorIndex int) {
|
|
if f == nil || !f.LegacyGroupProtocol || player == nil {
|
|
return
|
|
}
|
|
side := uint8(1)
|
|
if !f.isOurPlayerID(player.GetInfo().UserID) {
|
|
side = 2
|
|
}
|
|
payload := legacyEscapeSuccessInfo{
|
|
UserID: player.GetInfo().UserID,
|
|
Nick: player.GetInfo().Nick,
|
|
Side: side,
|
|
ActorIndex: uint8(actorIndex),
|
|
}
|
|
f.BroadcastPlayers(func(p common.PlayerI) {
|
|
p.SendPackCmd(groupCmdEscapeSuc, &payload)
|
|
})
|
|
}
|
|
|
|
func (f *FightC) sendLegacyRoundBroadcast(firstAttack, secondAttack *action.SelectSkillAction) {
|
|
if f == nil || !f.LegacyGroupProtocol {
|
|
return
|
|
}
|
|
if firstAttack != nil {
|
|
f.sendLegacyGroupSkillHurt(firstAttack)
|
|
}
|
|
if secondAttack != nil {
|
|
f.sendLegacyGroupSkillHurt(secondAttack)
|
|
}
|
|
f.sendLegacyGroupBoutDone()
|
|
}
|
|
|
|
func (f *FightC) sendLegacyGroupSkillHurt(skillAction *action.SelectSkillAction) {
|
|
if f == nil || !f.LegacyGroupProtocol || skillAction == nil {
|
|
return
|
|
}
|
|
packet := f.buildLegacyGroupSkillHurtPacket(skillAction)
|
|
if packet == nil {
|
|
return
|
|
}
|
|
f.BroadcastPlayers(func(p common.PlayerI) {
|
|
p.SendPackCmd(groupCmdSkillHurt, packet)
|
|
})
|
|
}
|
|
|
|
func (f *FightC) buildLegacyGroupSkillHurtPacket(skillAction *action.SelectSkillAction) *legacyGroupSkillHurtPacket {
|
|
attacker := f.GetInputByAction(skillAction, false)
|
|
defender := f.GetInputByAction(skillAction, true)
|
|
if attacker == nil || defender == nil {
|
|
return nil
|
|
}
|
|
return &legacyGroupSkillHurtPacket{
|
|
IsGank: 0,
|
|
Attack: f.buildLegacyGroupSkillAttackInfo(skillAction, attacker),
|
|
Attacked: f.buildLegacyGroupSkillDefendInfo(defender),
|
|
}
|
|
}
|
|
|
|
func (f *FightC) fillLegacyGroupSkillCommonFields(
|
|
self *input.Input,
|
|
isAttackor uint8,
|
|
statusList *[20]uint8,
|
|
batLvList *[6]uint8,
|
|
) (side uint8, pos uint8, userID uint32, petID uint32, hp uint32, maxHP uint32, moveMap []legacyGroupSkillMoveInfo, flag uint32) {
|
|
if self == nil {
|
|
return
|
|
}
|
|
if !f.isOurPlayerID(self.UserID) {
|
|
side = 2
|
|
} else {
|
|
side = 1
|
|
}
|
|
pos = uint8(self.TeamSlotIndex())
|
|
userID = self.UserID
|
|
attackValue := self.AttackValue
|
|
if attackValue == nil {
|
|
attackValue = info.NewAttackValue(self.UserID)
|
|
}
|
|
for i := 0; i < len(attackValue.Status) && i < 20; i++ {
|
|
statusList[i] = uint8(attackValue.Status[i])
|
|
}
|
|
for i := 0; i < len(attackValue.Prop) && i < len(batLvList); i++ {
|
|
batLvList[i] = uint8(attackValue.Prop[i])
|
|
}
|
|
currentPet := self.CurrentPet()
|
|
if currentPet != nil {
|
|
petID = currentPet.Info.ID
|
|
hp = currentPet.Info.Hp
|
|
maxHP = currentPet.Info.MaxHp
|
|
moveMap = collectLegacyGroupSkillMoves(currentPet.Info.SkillList)
|
|
} else {
|
|
hp = clampLegacyInt32ToUint32(attackValue.RemainHp)
|
|
maxHP = attackValue.MaxHp
|
|
moveMap = collectLegacyGroupSkillMoves(attackValue.SkillList)
|
|
}
|
|
flag = attackValue.State
|
|
return
|
|
}
|
|
|
|
func (f *FightC) buildLegacyGroupSkillAttackInfo(skillAction *action.SelectSkillAction, self *input.Input) legacyGroupSkillAttackInfo {
|
|
result := legacyGroupSkillAttackInfo{}
|
|
if self == nil {
|
|
return result
|
|
}
|
|
result.IsAttackor = 0
|
|
result.Side, result.Pos, result.UserID, result.PetID, result.Hp, result.MaxHp, result.MoveMap, result.Flag =
|
|
f.fillLegacyGroupSkillCommonFields(self, result.IsAttackor, &result.StatusList, &result.BatLvList)
|
|
attackValue := self.AttackValue
|
|
if attackValue == nil {
|
|
attackValue = info.NewAttackValue(self.UserID)
|
|
}
|
|
if skillAction != nil && skillAction.SkillEntity != nil {
|
|
result.MoveID = uint32(skillAction.SkillEntity.XML.ID)
|
|
} else {
|
|
result.MoveID = attackValue.SkillID
|
|
}
|
|
result.IsCrit = attackValue.IsCritical
|
|
result.EffectName = attackValue.State
|
|
result.AtkTimes = 1
|
|
result.Dmg = int32(attackValue.LostHp)
|
|
result.ChgHp = attackValue.GainHp
|
|
return result
|
|
}
|
|
|
|
func (f *FightC) buildLegacyGroupSkillDefendInfo(self *input.Input) legacyGroupSkillDefendInfo {
|
|
result := legacyGroupSkillDefendInfo{}
|
|
if self == nil {
|
|
return result
|
|
}
|
|
result.IsAttackor = 1
|
|
result.Side, result.Pos, result.UserID, result.PetID, result.Hp, result.MaxHp, result.MoveMap, result.Flag =
|
|
f.fillLegacyGroupSkillCommonFields(self, result.IsAttackor, &result.StatusList, &result.BatLvList)
|
|
result.MoveID = 0
|
|
return result
|
|
}
|
|
|
|
func collectLegacyGroupSkillMoves(skills []model.SkillInfo) []legacyGroupSkillMoveInfo {
|
|
moves := make([]legacyGroupSkillMoveInfo, 0, len(skills))
|
|
for _, skill := range skills {
|
|
if skill.ID == 0 {
|
|
continue
|
|
}
|
|
moves = append(moves, legacyGroupSkillMoveInfo{
|
|
MoveID: skill.ID,
|
|
PP: skill.PP,
|
|
})
|
|
}
|
|
return moves
|
|
}
|
|
|
|
func clampLegacyInt32ToUint32(v int32) uint32 {
|
|
if v < 0 {
|
|
return 0
|
|
}
|
|
return uint32(v)
|
|
}
|
|
|
|
func (f *FightC) sendLegacyGroupBoutDone() {
|
|
if f == nil || !f.LegacyGroupProtocol {
|
|
return
|
|
}
|
|
payload := legacyBoutDoneInfo{Round: f.Round}
|
|
f.BroadcastPlayers(func(p common.PlayerI) {
|
|
p.SendPackCmd(groupCmdBoutDone, &payload)
|
|
})
|
|
}
|
|
|
|
func (f *FightC) sendLegacySpriteDie(in *input.Input, hasBackup bool) {
|
|
if f == nil || !f.LegacyGroupProtocol || in == nil {
|
|
return
|
|
}
|
|
side := uint8(1)
|
|
if !f.isOurPlayerID(in.UserID) {
|
|
side = 2
|
|
}
|
|
var data uint32
|
|
if hasBackup {
|
|
data = 1
|
|
}
|
|
payload := legacySpriteDieInfo{
|
|
Count: 1,
|
|
Side: side,
|
|
ActorIndex: uint8(in.TeamSlotIndex()),
|
|
Flag: 1,
|
|
HasBackup: data,
|
|
}
|
|
f.BroadcastPlayers(func(p common.PlayerI) {
|
|
p.SendPackCmd(groupCmdSpriteDie, &payload)
|
|
})
|
|
}
|