完善多人世界队伍

This commit is contained in:
huangxiaolei
2022-12-10 19:48:35 +08:00
parent 50de81588b
commit edd8a98f92
17 changed files with 313 additions and 485 deletions

View File

@@ -5,8 +5,10 @@ import (
"hk4e/gate/entity/gm" "hk4e/gate/entity/gm"
"hk4e/gate/kcp" "hk4e/gate/kcp"
"hk4e/gs/dao" "hk4e/gs/dao"
"hk4e/gs/model"
"hk4e/pkg/alg" "hk4e/pkg/alg"
"hk4e/pkg/logger" "hk4e/pkg/logger"
"hk4e/pkg/reflection"
"hk4e/protocol/cmd" "hk4e/protocol/cmd"
"hk4e/protocol/proto" "hk4e/protocol/proto"
) )
@@ -35,7 +37,7 @@ func NewGameManager(dao *dao.Dao, netMsgInput chan *cmd.NetMsg, netMsgOutput cha
GAME_MANAGER = r GAME_MANAGER = r
LOCAL_EVENT_MANAGER = NewLocalEventManager() LOCAL_EVENT_MANAGER = NewLocalEventManager()
ROUTE_MANAGER = NewRouteManager() ROUTE_MANAGER = NewRouteManager()
USER_MANAGER = NewUserManager(dao, LOCAL_EVENT_MANAGER.localEventChan) USER_MANAGER = NewUserManager(dao)
WORLD_MANAGER = NewWorldManager(r.snowflake) WORLD_MANAGER = NewWorldManager(r.snowflake)
TICK_MANAGER = NewTickManager() TICK_MANAGER = NewTickManager()
COMMAND_MANAGER = NewCommandManager() COMMAND_MANAGER = NewCommandManager()
@@ -92,6 +94,27 @@ func (g *GameManager) SendMsg(cmdId uint16, userId uint32, clientSeq uint32, pay
g.netMsgInput <- netMsg g.netMsgInput <- netMsg
} }
// CommonRetError 通用返回错误码
func (g *GameManager) CommonRetError(cmdId uint16, player *model.Player, rsp pb.Message, retCode ...proto.Retcode) {
if rsp == nil {
return
}
ret := int32(proto.Retcode_RET_FAIL)
if len(retCode) == 0 {
ret = int32(proto.Retcode_RET_SVR_ERROR)
} else if len(retCode) == 1 {
ret = int32(retCode[0])
} else {
return
}
ok := reflection.SetStructFieldValue(rsp, "Retcode", ret)
if !ok {
return
}
logger.LOG.Debug("send common error: %v", rsp)
g.SendMsg(cmdId, player.PlayerID, player.ClientSeq, rsp)
}
func (g *GameManager) ReconnectPlayer(userId uint32) { func (g *GameManager) ReconnectPlayer(userId uint32) {
g.SendMsg(cmd.ClientReconnectNotify, userId, 0, new(proto.ClientReconnectNotify)) g.SendMsg(cmd.ClientReconnectNotify, userId, 0, new(proto.ClientReconnectNotify))
} }

View File

@@ -150,11 +150,7 @@ func (t *TickManager) onTick10Second(now int64) {
for _, player := range world.playerMap { for _, player := range world.playerMap {
if world.multiplayer || !world.owner.Pause { if world.multiplayer || !world.owner.Pause {
// 改面板 // 改面板
team := player.TeamConfig.GetActiveTeam() for _, avatarId := range world.GetPlayerAvatarIdList(player) {
for _, avatarId := range team.AvatarIdList {
if avatarId == 0 {
break
}
avatar := player.AvatarMap[avatarId] avatar := player.AvatarMap[avatarId]
avatar.FightPropMap[uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_ATTACK)] = 1000000 avatar.FightPropMap[uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_ATTACK)] = 1000000
avatar.FightPropMap[uint32(constant.FightPropertyConst.FIGHT_PROP_CRITICAL)] = 1.0 avatar.FightPropMap[uint32(constant.FightPropertyConst.FIGHT_PROP_CRITICAL)] = 1.0

View File

@@ -89,7 +89,6 @@ func (g *GameManager) WearUserAvatarEquip(userId uint32, avatarId uint32, weapon
world := WORLD_MANAGER.GetWorldByID(player.WorldId) world := WORLD_MANAGER.GetWorldByID(player.WorldId)
scene := world.GetSceneById(player.SceneId) scene := world.GetSceneById(player.SceneId)
playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID)
team := player.TeamConfig.GetActiveTeam()
if weapon.AvatarId != 0 { if weapon.AvatarId != 0 {
// 武器在别的角色身上 // 武器在别的角色身上
@@ -105,10 +104,7 @@ func (g *GameManager) WearUserAvatarEquip(userId uint32, avatarId uint32, weapon
weakAvatar := player.AvatarMap[weakAvatarId] weakAvatar := player.AvatarMap[weakAvatarId]
weakWeapon := player.WeaponMap[weakAvatar.EquipWeapon.WeaponId] weakWeapon := player.WeaponMap[weakAvatar.EquipWeapon.WeaponId]
for _, aid := range team.AvatarIdList { for _, aid := range world.GetPlayerAvatarIdList(player) {
if aid == 0 {
break
}
if aid == weakAvatar.AvatarId { if aid == weakAvatar.AvatarId {
playerTeamEntity.weaponEntityMap[weakWeapon.WeaponId] = scene.CreateEntityWeapon() playerTeamEntity.weaponEntityMap[weakWeapon.WeaponId] = scene.CreateEntityWeapon()
} }
@@ -125,10 +121,7 @@ func (g *GameManager) WearUserAvatarEquip(userId uint32, avatarId uint32, weapon
player.WearWeapon(avatarId, weaponId) player.WearWeapon(avatarId, weaponId)
} }
for _, aid := range team.AvatarIdList { for _, aid := range world.GetPlayerAvatarIdList(player) {
if aid == 0 {
break
}
if aid == avatarId { if aid == avatarId {
playerTeamEntity.weaponEntityMap[weaponId] = scene.CreateEntityWeapon() playerTeamEntity.weaponEntityMap[weaponId] = scene.CreateEntityWeapon()
} }

View File

@@ -148,7 +148,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
if motionInfo.Pos == nil || motionInfo.Rot == nil { if motionInfo.Pos == nil || motionInfo.Rot == nil {
continue continue
} }
activeAvatarId := player.TeamConfig.GetActiveAvatarId() activeAvatarId := world.GetPlayerActiveAvatarId(player)
playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID)
playerActiveAvatarEntityId := playerTeamEntity.avatarEntityMap[activeAvatarId] playerActiveAvatarEntityId := playerTeamEntity.avatarEntityMap[activeAvatarId]
if entityMoveInfo.EntityId == playerActiveAvatarEntityId { if entityMoveInfo.EntityId == playerActiveAvatarEntityId {
@@ -232,8 +232,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
} }
} }
// 把队伍中的其他非活跃角色也同步进行移动 // 把队伍中的其他非活跃角色也同步进行移动
team := player.TeamConfig.GetActiveTeam() for _, avatarId := range world.GetPlayerAvatarIdList(player) {
for _, avatarId := range team.AvatarIdList {
// 跳过当前的活跃角色 // 跳过当前的活跃角色
if avatarId == activeAvatarId { if avatarId == activeAvatarId {
continue continue

View File

@@ -33,7 +33,7 @@ func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq u
player.InitAll() player.InitAll()
player.TeamConfig.UpdateTeam() player.TeamConfig.UpdateTeam()
// 创建世界 // 创建世界
world := WORLD_MANAGER.CreateWorld(player, false) world := WORLD_MANAGER.CreateWorld(player)
world.AddPlayer(player, player.SceneId) world.AddPlayer(player, player.SceneId)
player.WorldId = world.id player.WorldId = world.id
@@ -107,7 +107,7 @@ func (g *GameManager) OnUserOffline(userId uint32) {
player.OfflineTime = uint32(time.Now().Unix()) player.OfflineTime = uint32(time.Now().Unix())
player.Online = false player.Online = false
player.TotalOnlineTime += uint32(time.Now().UnixMilli()) - player.OnlineTime player.TotalOnlineTime += uint32(time.Now().UnixMilli()) - player.OnlineTime
USER_MANAGER.OfflineUser(player) USER_MANAGER.DeleteUser(player)
} }
func (g *GameManager) LoginNotify(userId uint32, player *model.Player, clientSeq uint32) { func (g *GameManager) LoginNotify(userId uint32, player *model.Player, clientSeq uint32) {
@@ -258,10 +258,7 @@ func (g *GameManager) PacketAvatarDataNotify(player *model.Player) *proto.Avatar
} }
for teamIndex, team := range player.TeamConfig.TeamList { for teamIndex, team := range player.TeamConfig.TeamList {
var teamAvatarGuidList []uint64 = nil var teamAvatarGuidList []uint64 = nil
for _, avatarId := range team.AvatarIdList { for _, avatarId := range team.GetAvatarIdList() {
if avatarId == 0 {
break
}
teamAvatarGuidList = append(teamAvatarGuidList, player.AvatarMap[avatarId].Guid) teamAvatarGuidList = append(teamAvatarGuidList, player.AvatarMap[avatarId].Guid)
} }
avatarDataNotify.AvatarTeamMap[uint32(teamIndex)+1] = &proto.AvatarTeam{ avatarDataNotify.AvatarTeamMap[uint32(teamIndex)+1] = &proto.AvatarTeam{
@@ -375,7 +372,7 @@ func (g *GameManager) CreatePlayer(userId uint32, nickName string, mainCharAvata
player.WearWeapon(mainCharAvatarId, weaponId) player.WearWeapon(mainCharAvatarId, weaponId)
player.TeamConfig = model.NewTeamInfo() player.TeamConfig = model.NewTeamInfo()
player.TeamConfig.AddAvatarToTeam(mainCharAvatarId, 0) player.TeamConfig.SetTeamAvatar(0, []uint32{mainCharAvatarId})
return player return player
} }

View File

@@ -1,7 +1,6 @@
package game package game
import ( import (
"encoding/json"
"sync" "sync"
"time" "time"
@@ -12,24 +11,20 @@ import (
) )
type UserManager struct { type UserManager struct {
dao *dao.Dao dao *dao.Dao
playerMap map[uint32]*model.Player playerMap map[uint32]*model.Player
playerMapLock sync.RWMutex playerMapLock sync.RWMutex
localEventChan chan *LocalEvent
} }
func NewUserManager(dao *dao.Dao, localEventChan chan *LocalEvent) (r *UserManager) { func NewUserManager(dao *dao.Dao) (r *UserManager) {
r = new(UserManager) r = new(UserManager)
r.dao = dao r.dao = dao
r.playerMap = make(map[uint32]*model.Player) r.playerMap = make(map[uint32]*model.Player)
r.localEventChan = localEventChan
return r return r
} }
func (u *UserManager) GetUserOnlineState(userId uint32) bool { func (u *UserManager) GetUserOnlineState(userId uint32) bool {
u.playerMapLock.RLock()
player, exist := u.playerMap[userId] player, exist := u.playerMap[userId]
u.playerMapLock.RUnlock()
if !exist { if !exist {
return false return false
} else { } else {
@@ -38,9 +33,7 @@ func (u *UserManager) GetUserOnlineState(userId uint32) bool {
} }
func (u *UserManager) GetOnlineUser(userId uint32) *model.Player { func (u *UserManager) GetOnlineUser(userId uint32) *model.Player {
u.playerMapLock.RLock()
player, exist := u.playerMap[userId] player, exist := u.playerMap[userId]
u.playerMapLock.RUnlock()
if !exist { if !exist {
return nil return nil
} else { } else {
@@ -54,14 +47,12 @@ func (u *UserManager) GetOnlineUser(userId uint32) *model.Player {
func (u *UserManager) GetAllOnlineUserList() map[uint32]*model.Player { func (u *UserManager) GetAllOnlineUserList() map[uint32]*model.Player {
onlinePlayerMap := make(map[uint32]*model.Player) onlinePlayerMap := make(map[uint32]*model.Player)
u.playerMapLock.RLock()
for userId, player := range u.playerMap { for userId, player := range u.playerMap {
if player.Online == false { if player.Online == false {
continue continue
} }
onlinePlayerMap[userId] = player onlinePlayerMap[userId] = player
} }
u.playerMapLock.RUnlock()
return onlinePlayerMap return onlinePlayerMap
} }
@@ -73,9 +64,7 @@ type PlayerRegInfo struct {
} }
func (u *UserManager) CheckUserExistOnReg(userId uint32, req *proto.SetPlayerBornDataReq, clientSeq uint32) (exist bool, asyncWait bool) { func (u *UserManager) CheckUserExistOnReg(userId uint32, req *proto.SetPlayerBornDataReq, clientSeq uint32) (exist bool, asyncWait bool) {
u.playerMapLock.RLock()
_, exist = u.playerMap[userId] _, exist = u.playerMap[userId]
u.playerMapLock.RUnlock()
if exist { if exist {
return true, false return true, false
} else { } else {
@@ -85,7 +74,7 @@ func (u *UserManager) CheckUserExistOnReg(userId uint32, req *proto.SetPlayerBor
if player != nil { if player != nil {
exist = true exist = true
} }
u.localEventChan <- &LocalEvent{ LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{
EventId: CheckUserExistOnRegFromDbFinish, EventId: CheckUserExistOnRegFromDbFinish,
Msg: &PlayerRegInfo{ Msg: &PlayerRegInfo{
Exist: exist, Exist: exist,
@@ -100,9 +89,7 @@ func (u *UserManager) CheckUserExistOnReg(userId uint32, req *proto.SetPlayerBor
} }
func (u *UserManager) LoadTempOfflineUserSync(userId uint32) *model.Player { func (u *UserManager) LoadTempOfflineUserSync(userId uint32) *model.Player {
u.playerMapLock.RLock()
player, exist := u.playerMap[userId] player, exist := u.playerMap[userId]
u.playerMapLock.RUnlock()
if exist { if exist {
return player return player
} else { } else {
@@ -110,10 +97,7 @@ func (u *UserManager) LoadTempOfflineUserSync(userId uint32) *model.Player {
if player == nil { if player == nil {
return nil return nil
} }
player.DbState = model.DbOffline
u.playerMapLock.Lock()
u.playerMap[player.PlayerID] = player u.playerMap[player.PlayerID] = player
u.playerMapLock.Unlock()
return player return player
} }
} }
@@ -132,9 +116,7 @@ func (u *UserManager) AddUser(player *model.Player) {
return return
} }
u.ChangeUserDbState(player, model.DbInsert) u.ChangeUserDbState(player, model.DbInsert)
u.playerMapLock.Lock()
u.playerMap[player.PlayerID] = player u.playerMap[player.PlayerID] = player
u.playerMapLock.Unlock()
} }
func (u *UserManager) DeleteUser(player *model.Player) { func (u *UserManager) DeleteUser(player *model.Player) {
@@ -142,19 +124,7 @@ func (u *UserManager) DeleteUser(player *model.Player) {
return return
} }
u.ChangeUserDbState(player, model.DbDelete) u.ChangeUserDbState(player, model.DbDelete)
u.playerMapLock.Lock()
u.playerMap[player.PlayerID] = player u.playerMap[player.PlayerID] = player
u.playerMapLock.Unlock()
}
func (u *UserManager) UpdateUser(player *model.Player) {
if player == nil {
return
}
u.ChangeUserDbState(player, model.DbUpdate)
u.playerMapLock.Lock()
u.playerMap[player.PlayerID] = player
u.playerMapLock.Unlock()
} }
type PlayerLoginInfo struct { type PlayerLoginInfo struct {
@@ -164,9 +134,7 @@ type PlayerLoginInfo struct {
} }
func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32) (*model.Player, bool) { func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32) (*model.Player, bool) {
u.playerMapLock.RLock()
player, exist := u.playerMap[userId] player, exist := u.playerMap[userId]
u.playerMapLock.RUnlock()
if exist { if exist {
u.ChangeUserDbState(player, model.DbNormal) u.ChangeUserDbState(player, model.DbNormal)
return player, false return player, false
@@ -179,7 +147,7 @@ func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32) (*model.Player
u.playerMap[player.PlayerID] = player u.playerMap[player.PlayerID] = player
u.playerMapLock.Unlock() u.playerMapLock.Unlock()
} }
u.localEventChan <- &LocalEvent{ LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{
EventId: LoadLoginUserFromDbFinish, EventId: LoadLoginUserFromDbFinish,
Msg: &PlayerLoginInfo{ Msg: &PlayerLoginInfo{
UserId: userId, UserId: userId,
@@ -192,53 +160,27 @@ func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32) (*model.Player
} }
} }
func (u *UserManager) OfflineUser(player *model.Player) {
if player == nil {
return
}
u.ChangeUserDbState(player, model.DbOffline)
u.playerMapLock.Lock()
u.playerMap[player.PlayerID] = player
u.playerMapLock.Unlock()
}
func (u *UserManager) ChangeUserDbState(player *model.Player, state int) { func (u *UserManager) ChangeUserDbState(player *model.Player, state int) {
if player == nil { if player == nil {
return return
} }
switch player.DbState { switch player.DbState {
case model.DbInsert: case model.DbInsert:
if state == model.DbDelete { break
player.DbState = model.DbDelete
}
case model.DbDelete: case model.DbDelete:
case model.DbUpdate: if state == model.DbNormal {
if state == model.DbDelete { player.DbState = model.DbNormal
player.DbState = model.DbDelete
} else if state == model.DbOffline {
player.DbState = model.DbOffline
} }
case model.DbNormal: case model.DbNormal:
if state == model.DbDelete { if state == model.DbDelete {
player.DbState = model.DbDelete player.DbState = model.DbDelete
} else if state == model.DbUpdate {
player.DbState = model.DbUpdate
} else if state == model.DbOffline {
player.DbState = model.DbOffline
}
case model.DbOffline:
if state == model.DbDelete {
player.DbState = model.DbDelete
} else if state == model.DbUpdate {
player.DbState = model.DbUpdate
} else if state == model.DbNormal {
player.DbState = model.DbNormal
} }
} }
} }
// 用户数据库定时同步协程
func (u *UserManager) StartAutoSaveUser() { func (u *UserManager) StartAutoSaveUser() {
// 用户数据库定时同步协程
go func() { go func() {
ticker := time.NewTicker(time.Minute * 5) ticker := time.NewTicker(time.Minute * 5)
for { for {
@@ -249,57 +191,44 @@ func (u *UserManager) StartAutoSaveUser() {
} }
func (u *UserManager) SaveUser() { func (u *UserManager) SaveUser() {
logger.LOG.Info("auto save user start") playerMapSave := make(map[uint32]*model.Player, len(u.playerMap))
playerMapTemp := make(map[uint32]*model.Player)
u.playerMapLock.RLock() u.playerMapLock.RLock()
for k, v := range u.playerMap { for k, v := range u.playerMap {
playerMapTemp[k] = v playerMapSave[k] = v
} }
u.playerMapLock.RUnlock() u.playerMapLock.RUnlock()
logger.LOG.Info("copyLocalTeamToWorld user map finish")
insertList := make([]*model.Player, 0) insertList := make([]*model.Player, 0)
deleteList := make([]uint32, 0)
updateList := make([]*model.Player, 0) updateList := make([]*model.Player, 0)
for k, v := range playerMapTemp { for uid, player := range playerMapSave {
switch v.DbState { if uid < 100000000 {
case model.DbInsert:
insertList = append(insertList, v)
playerMapTemp[k].DbState = model.DbNormal
case model.DbDelete:
deleteList = append(deleteList, v.PlayerID)
delete(playerMapTemp, k)
case model.DbUpdate:
updateList = append(updateList, v)
playerMapTemp[k].DbState = model.DbNormal
case model.DbNormal:
continue continue
case model.DbOffline: }
updateList = append(updateList, v) switch player.DbState {
delete(playerMapTemp, k) case model.DbInsert:
insertList = append(insertList, player)
playerMapSave[uid].DbState = model.DbNormal
case model.DbDelete:
updateList = append(updateList, player)
delete(playerMapSave, uid)
case model.DbNormal:
updateList = append(updateList, player)
}
if !player.Online {
delete(playerMapSave, uid)
} }
} }
insertListJson, err := json.Marshal(insertList) err := u.dao.InsertPlayerList(insertList)
logger.LOG.Debug("insertList: %v", string(insertListJson))
deleteListJson, err := json.Marshal(deleteList)
logger.LOG.Debug("deleteList: %v", string(deleteListJson))
updateListJson, err := json.Marshal(updateList)
logger.LOG.Debug("updateList: %v", string(updateListJson))
logger.LOG.Info("db state init finish")
err = u.dao.InsertPlayerList(insertList)
if err != nil { if err != nil {
logger.LOG.Error("insert player list error: %v", err) logger.LOG.Error("insert player list error: %v", err)
} return
err = u.dao.DeletePlayerList(deleteList)
if err != nil {
logger.LOG.Error("delete player error: %v", err)
} }
err = u.dao.UpdatePlayerList(updateList) err = u.dao.UpdatePlayerList(updateList)
if err != nil { if err != nil {
logger.LOG.Error("update player error: %v", err) logger.LOG.Error("update player list error: %v", err)
return
} }
logger.LOG.Info("db write finish")
u.playerMapLock.Lock() u.playerMapLock.Lock()
u.playerMap = playerMapTemp u.playerMap = playerMapSave
u.playerMapLock.Unlock() u.playerMapLock.Unlock()
logger.LOG.Info("auto save user finish") logger.LOG.Info("save user finish, insert user count: %v, update user count: %v", len(insertList), len(updateList))
} }

View File

@@ -84,7 +84,7 @@ func (g *GameManager) TeleportPlayer(player *model.Player, sceneId uint32, pos *
} }
world := WORLD_MANAGER.GetWorldByID(player.WorldId) world := WORLD_MANAGER.GetWorldByID(player.WorldId)
oldScene := world.GetSceneById(oldSceneId) oldScene := world.GetSceneById(oldSceneId)
activeAvatarId := player.TeamConfig.GetActiveAvatarId() activeAvatarId := world.GetPlayerActiveAvatarId(player)
playerTeamEntity := oldScene.GetPlayerTeamEntity(player.PlayerID) playerTeamEntity := oldScene.GetPlayerTeamEntity(player.PlayerID)
g.RemoveSceneEntityNotifyBroadcast(oldScene, proto.VisionType_VISION_TYPE_REMOVE, []uint32{playerTeamEntity.avatarEntityMap[activeAvatarId]}) g.RemoveSceneEntityNotifyBroadcast(oldScene, proto.VisionType_VISION_TYPE_REMOVE, []uint32{playerTeamEntity.avatarEntityMap[activeAvatarId]})
if jumpScene { if jumpScene {

View File

@@ -269,7 +269,7 @@ func (g *GameManager) UserDealEnterWorld(hostPlayer *model.Player, otherUid uint
// 仅仅把当前的场上角色的实体消失掉 // 仅仅把当前的场上角色的实体消失掉
scene := world.GetSceneById(hostPlayer.SceneId) scene := world.GetSceneById(hostPlayer.SceneId)
playerTeamEntity := scene.GetPlayerTeamEntity(hostPlayer.PlayerID) playerTeamEntity := scene.GetPlayerTeamEntity(hostPlayer.PlayerID)
activeAvatarId := hostPlayer.TeamConfig.GetActiveAvatarId() activeAvatarId := world.GetPlayerActiveAvatarId(hostPlayer)
g.RemoveSceneEntityNotifyToPlayer(hostPlayer, proto.VisionType_VISION_TYPE_MISS, []uint32{playerTeamEntity.avatarEntityMap[activeAvatarId]}) g.RemoveSceneEntityNotifyToPlayer(hostPlayer, proto.VisionType_VISION_TYPE_MISS, []uint32{playerTeamEntity.avatarEntityMap[activeAvatarId]})
} }
@@ -295,7 +295,7 @@ func (g *GameManager) UserWorldAddPlayer(world *World, player *model.Player) {
} }
world.AddPlayer(player, player.SceneId) world.AddPlayer(player, player.SceneId)
player.WorldId = world.id player.WorldId = world.id
if len(world.playerMap) > 1 { if world.GetWorldPlayerNum() > 1 {
g.UpdateWorldPlayerInfo(world, player) g.UpdateWorldPlayerInfo(world, player)
} }
} }
@@ -316,7 +316,7 @@ func (g *GameManager) UserWorldRemovePlayer(world *World, player *model.Player)
// 仅仅把当前的场上角色的实体消失掉 // 仅仅把当前的场上角色的实体消失掉
playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID)
activeAvatarId := player.TeamConfig.GetActiveAvatarId() activeAvatarId := world.GetPlayerActiveAvatarId(player)
g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_TYPE_MISS, []uint32{playerTeamEntity.avatarEntityMap[activeAvatarId]}) g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_TYPE_MISS, []uint32{playerTeamEntity.avatarEntityMap[activeAvatarId]})
delTeamEntityNotify := g.PacketDelTeamEntityNotify(scene, player) delTeamEntityNotify := g.PacketDelTeamEntityNotify(scene, player)
@@ -328,14 +328,14 @@ func (g *GameManager) UserWorldRemovePlayer(world *World, player *model.Player)
} }
g.SendMsg(cmd.PlayerQuitFromMpNotify, player.PlayerID, player.ClientSeq, playerQuitFromMpNotify) g.SendMsg(cmd.PlayerQuitFromMpNotify, player.PlayerID, player.ClientSeq, playerQuitFromMpNotify)
activeAvatarId := player.TeamConfig.GetActiveAvatarId() activeAvatarId := world.GetPlayerActiveAvatarId(player)
playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID)
g.RemoveSceneEntityNotifyBroadcast(scene, proto.VisionType_VISION_TYPE_REMOVE, []uint32{playerTeamEntity.avatarEntityMap[activeAvatarId]}) g.RemoveSceneEntityNotifyBroadcast(scene, proto.VisionType_VISION_TYPE_REMOVE, []uint32{playerTeamEntity.avatarEntityMap[activeAvatarId]})
} }
world.RemovePlayer(player) world.RemovePlayer(player)
player.WorldId = 0 player.WorldId = 0
if world.multiplayer && len(world.playerMap) > 0 { if world.multiplayer && world.GetWorldPlayerNum() > 0 {
g.UpdateWorldPlayerInfo(world, player) g.UpdateWorldPlayerInfo(world, player)
} }
if world.owner.PlayerID == player.PlayerID { if world.owner.PlayerID == player.PlayerID {
@@ -370,7 +370,7 @@ func (g *GameManager) UpdateWorldPlayerInfo(hostWorld *World, excludePlayer *mod
NameCardId: subWorldPlayer.NameCard, NameCardId: subWorldPlayer.NameCard,
Signature: subWorldPlayer.Signature, Signature: subWorldPlayer.Signature,
ProfilePicture: &proto.ProfilePicture{AvatarId: subWorldPlayer.HeadImage}, ProfilePicture: &proto.ProfilePicture{AvatarId: subWorldPlayer.HeadImage},
CurPlayerNumInWorld: uint32(len(hostWorld.playerMap)), CurPlayerNumInWorld: uint32(hostWorld.GetWorldPlayerNum()),
} }
worldPlayerInfoNotify.PlayerInfoList = append(worldPlayerInfoNotify.PlayerInfoList, onlinePlayerInfo) worldPlayerInfoNotify.PlayerInfoList = append(worldPlayerInfoNotify.PlayerInfoList, onlinePlayerInfo)
@@ -395,7 +395,7 @@ func (g *GameManager) UpdateWorldPlayerInfo(hostWorld *World, excludePlayer *mod
NameCardId: worldPlayer.NameCard, NameCardId: worldPlayer.NameCard,
Signature: worldPlayer.Signature, Signature: worldPlayer.Signature,
ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage}, ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage},
CurPlayerNumInWorld: uint32(len(hostWorld.playerMap)), CurPlayerNumInWorld: uint32(hostWorld.GetWorldPlayerNum()),
} }
scenePlayerInfoNotify.PlayerInfoList = append(scenePlayerInfoNotify.PlayerInfoList, &proto.ScenePlayerInfo{ scenePlayerInfoNotify.PlayerInfoList = append(scenePlayerInfoNotify.PlayerInfoList, &proto.ScenePlayerInfo{
Uid: worldPlayer.PlayerID, Uid: worldPlayer.PlayerID,
@@ -407,7 +407,7 @@ func (g *GameManager) UpdateWorldPlayerInfo(hostWorld *World, excludePlayer *mod
} }
g.SendMsg(cmd.ScenePlayerInfoNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, scenePlayerInfoNotify) g.SendMsg(cmd.ScenePlayerInfoNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, scenePlayerInfoNotify)
sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotifyMp(hostWorld) sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(hostWorld)
g.SendMsg(cmd.SceneTeamUpdateNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, sceneTeamUpdateNotify) g.SendMsg(cmd.SceneTeamUpdateNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, sceneTeamUpdateNotify)
syncTeamEntityNotify := &proto.SyncTeamEntityNotify{ syncTeamEntityNotify := &proto.SyncTeamEntityNotify{

View File

@@ -58,7 +58,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
NameCardId: worldPlayer.NameCard, NameCardId: worldPlayer.NameCard,
Signature: worldPlayer.Signature, Signature: worldPlayer.Signature,
ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage}, ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage},
CurPlayerNumInWorld: uint32(len(world.playerMap)), CurPlayerNumInWorld: uint32(world.GetWorldPlayerNum()),
} }
worldPlayerInfoNotify.PlayerInfoList = append(worldPlayerInfoNotify.PlayerInfoList, onlinePlayerInfo) worldPlayerInfoNotify.PlayerInfoList = append(worldPlayerInfoNotify.PlayerInfoList, onlinePlayerInfo)
worldPlayerInfoNotify.PlayerUidList = append(worldPlayerInfoNotify.PlayerUidList, worldPlayer.PlayerID) worldPlayerInfoNotify.PlayerUidList = append(worldPlayerInfoNotify.PlayerUidList, worldPlayer.PlayerID)
@@ -116,7 +116,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
g.SendMsg(cmd.PlayerGameTimeNotify, player.PlayerID, player.ClientSeq, playerGameTimeNotify) g.SendMsg(cmd.PlayerGameTimeNotify, player.PlayerID, player.ClientSeq, playerGameTimeNotify)
empty := new(proto.AbilitySyncStateInfo) empty := new(proto.AbilitySyncStateInfo)
activeAvatarId := player.TeamConfig.GetActiveAvatarId() activeAvatarId := world.GetPlayerActiveAvatarId(player)
playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID)
playerEnterSceneInfoNotify := &proto.PlayerEnterSceneInfoNotify{ playerEnterSceneInfoNotify := &proto.PlayerEnterSceneInfoNotify{
CurAvatarEntityId: playerTeamEntity.avatarEntityMap[activeAvatarId], CurAvatarEntityId: playerTeamEntity.avatarEntityMap[activeAvatarId],
@@ -133,11 +133,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
}, },
AvatarEnterInfo: make([]*proto.AvatarEnterSceneInfo, 0), AvatarEnterInfo: make([]*proto.AvatarEnterSceneInfo, 0),
} }
activeTeam := player.TeamConfig.GetActiveTeam() for _, avatarId := range world.GetPlayerAvatarIdList(player) {
for _, avatarId := range activeTeam.AvatarIdList {
if avatarId == 0 {
break
}
avatar := player.AvatarMap[avatarId] avatar := player.AvatarMap[avatarId]
avatarEnterSceneInfo := &proto.AvatarEnterSceneInfo{ avatarEnterSceneInfo := &proto.AvatarEnterSceneInfo{
AvatarGuid: avatar.Guid, AvatarGuid: avatar.Guid,
@@ -170,7 +166,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
NameCardId: worldPlayer.NameCard, NameCardId: worldPlayer.NameCard,
Signature: worldPlayer.Signature, Signature: worldPlayer.Signature,
ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage}, ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage},
CurPlayerNumInWorld: uint32(len(world.playerMap)), CurPlayerNumInWorld: uint32(world.GetWorldPlayerNum()),
} }
scenePlayerInfoNotify.PlayerInfoList = append(scenePlayerInfoNotify.PlayerInfoList, &proto.ScenePlayerInfo{ scenePlayerInfoNotify.PlayerInfoList = append(scenePlayerInfoNotify.PlayerInfoList, &proto.ScenePlayerInfo{
Uid: worldPlayer.PlayerID, Uid: worldPlayer.PlayerID,
@@ -182,12 +178,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
} }
g.SendMsg(cmd.ScenePlayerInfoNotify, player.PlayerID, player.ClientSeq, scenePlayerInfoNotify) g.SendMsg(cmd.ScenePlayerInfoNotify, player.PlayerID, player.ClientSeq, scenePlayerInfoNotify)
var sceneTeamUpdateNotify *proto.SceneTeamUpdateNotify = nil sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world)
if world.multiplayer {
sceneTeamUpdateNotify = g.PacketSceneTeamUpdateNotifyMp(world)
} else {
sceneTeamUpdateNotify = g.PacketSceneTeamUpdateNotify(world)
}
g.SendMsg(cmd.SceneTeamUpdateNotify, player.PlayerID, player.ClientSeq, sceneTeamUpdateNotify) g.SendMsg(cmd.SceneTeamUpdateNotify, player.PlayerID, player.ClientSeq, sceneTeamUpdateNotify)
syncTeamEntityNotify := &proto.SyncTeamEntityNotify{ syncTeamEntityNotify := &proto.SyncTeamEntityNotify{
@@ -240,7 +231,7 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess
var visionType = proto.VisionType_VISION_TYPE_TRANSPORT var visionType = proto.VisionType_VISION_TYPE_TRANSPORT
playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID)
activeAvatarId := player.TeamConfig.GetActiveAvatarId() activeAvatarId := world.GetPlayerActiveAvatarId(player)
if world.IsPlayerFirstEnter(player) { if world.IsPlayerFirstEnter(player) {
visionType = proto.VisionType_VISION_TYPE_BORN visionType = proto.VisionType_VISION_TYPE_BORN
} }
@@ -463,10 +454,10 @@ func (g *GameManager) AddSceneEntityNotify(player *model.Player, visionType prot
logger.LOG.Error("get scene player is nil, world id: %v, scene id: %v", world.id, scene.id) logger.LOG.Error("get scene player is nil, world id: %v, scene id: %v", world.id, scene.id)
continue continue
} }
if entity.avatarEntity.avatarId != scenePlayer.TeamConfig.GetActiveAvatarId() { if entity.avatarEntity.avatarId != world.GetPlayerActiveAvatarId(scenePlayer) {
continue continue
} }
sceneEntityInfoAvatar := g.PacketSceneEntityInfoAvatar(scene, scenePlayer, scenePlayer.TeamConfig.GetActiveAvatarId()) sceneEntityInfoAvatar := g.PacketSceneEntityInfoAvatar(scene, scenePlayer, world.GetPlayerActiveAvatarId(scenePlayer))
entityList = append(entityList, sceneEntityInfoAvatar) entityList = append(entityList, sceneEntityInfoAvatar)
case uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_WEAPON): case uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_WEAPON):
case uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_MONSTER): case uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_MONSTER):
@@ -707,9 +698,9 @@ func (g *GameManager) PacketSceneAvatarInfo(scene *Scene, player *model.Player,
BornTime: uint32(player.AvatarMap[avatarId].BornTime), BornTime: uint32(player.AvatarMap[avatarId].BornTime),
TeamResonanceList: make([]uint32, 0), TeamResonanceList: make([]uint32, 0),
} }
for id := range player.TeamConfig.TeamResonances { //for id := range player.TeamConfig.TeamResonances {
sceneAvatarInfo.TeamResonanceList = append(sceneAvatarInfo.TeamResonanceList, uint32(id)) // sceneAvatarInfo.TeamResonanceList = append(sceneAvatarInfo.TeamResonanceList, uint32(id))
} //}
return sceneAvatarInfo return sceneAvatarInfo
} }

View File

@@ -49,6 +49,7 @@ func (g *GameManager) SetPlayerBirthdayReq(player *model.Player, payloadMsg pb.M
logger.LOG.Debug("user set birthday, uid: %v", player.PlayerID) logger.LOG.Debug("user set birthday, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.SetPlayerBirthdayReq) req := payloadMsg.(*proto.SetPlayerBirthdayReq)
_ = req _ = req
g.CommonRetError(cmd.SetPlayerBirthdayRsp, player, &proto.SetPlayerBirthdayRsp{})
} }
func (g *GameManager) SetNameCardReq(player *model.Player, payloadMsg pb.Message) { func (g *GameManager) SetNameCardReq(player *model.Player, payloadMsg pb.Message) {
@@ -336,7 +337,7 @@ func (g *GameManager) PacketOnlinePlayerInfo(player *model.Player) *proto.Online
} }
world := WORLD_MANAGER.GetWorldByID(player.WorldId) world := WORLD_MANAGER.GetWorldByID(player.WorldId)
if world != nil && world.playerMap != nil { if world != nil && world.playerMap != nil {
onlinePlayerInfo.CurPlayerNumInWorld = uint32(len(world.playerMap)) onlinePlayerInfo.CurPlayerNumInWorld = uint32(world.GetWorldPlayerNum())
} }
return onlinePlayerInfo return onlinePlayerInfo
} }

View File

@@ -27,7 +27,12 @@ func (g *GameManager) SceneAvatarStaminaStepReq(player *model.Player, payloadMsg
} else if req.Rot.X > 270 && req.Rot.X < 360 { } else if req.Rot.X > 270 && req.Rot.X < 360 {
angleRevise = int32(req.Rot.X - 360.0) angleRevise = int32(req.Rot.X - 360.0)
} else { } else {
logger.LOG.Error("invalid rot x angle: %v", req.Rot.X) logger.LOG.Error("invalid rot x angle: %v, uid: %v", req.Rot.X, player.PlayerID)
sceneAvatarStaminaStepRsp := &proto.SceneAvatarStaminaStepRsp{
Retcode: int32(proto.Retcode_RET_FAIL),
}
g.SendMsg(cmd.SceneAvatarStaminaStepRsp, player.PlayerID, player.ClientSeq, sceneAvatarStaminaStepRsp)
return
} }
// 攀爬耐力修正曲线 // 攀爬耐力修正曲线
// angle >= 0 cost = -x + 10 // angle >= 0 cost = -x + 10
@@ -49,12 +54,6 @@ func (g *GameManager) SceneAvatarStaminaStepReq(player *model.Player, payloadMsg
// PacketSceneAvatarStaminaStepRsp // PacketSceneAvatarStaminaStepRsp
sceneAvatarStaminaStepRsp := new(proto.SceneAvatarStaminaStepRsp) sceneAvatarStaminaStepRsp := new(proto.SceneAvatarStaminaStepRsp)
// 角度超过范围返回值为错误
if (req.Rot.X >= 0 && req.Rot.X < 90) || (req.Rot.X > 270 && req.Rot.X < 360) {
sceneAvatarStaminaStepRsp.Retcode = int32(proto.Retcode_RET_SUCC)
} else {
sceneAvatarStaminaStepRsp.Retcode = int32(proto.Retcode_RET_FAIL)
}
sceneAvatarStaminaStepRsp.UseClientRot = true sceneAvatarStaminaStepRsp.UseClientRot = true
sceneAvatarStaminaStepRsp.Rot = req.Rot sceneAvatarStaminaStepRsp.Rot = req.Rot
g.SendMsg(cmd.SceneAvatarStaminaStepRsp, player.PlayerID, player.ClientSeq, sceneAvatarStaminaStepRsp) g.SendMsg(cmd.SceneAvatarStaminaStepRsp, player.PlayerID, player.ClientSeq, sceneAvatarStaminaStepRsp)
@@ -62,6 +61,10 @@ func (g *GameManager) SceneAvatarStaminaStepReq(player *model.Player, payloadMsg
// HandleStamina 处理即时耐力消耗 // HandleStamina 处理即时耐力消耗
func (g *GameManager) HandleStamina(player *model.Player, motionState proto.MotionState) { func (g *GameManager) HandleStamina(player *model.Player, motionState proto.MotionState) {
// 玩家暂停状态不更新耐力
if player.Pause {
return
}
staminaInfo := player.StaminaInfo staminaInfo := player.StaminaInfo
//logger.LOG.Debug("stamina handle, uid: %v, motionState: %v", player.PlayerID, motionState) //logger.LOG.Debug("stamina handle, uid: %v, motionState: %v", player.PlayerID, motionState)
@@ -129,6 +132,10 @@ func (g *GameManager) HandleSkillStartStamina(player *model.Player, skillId uint
// StaminaHandler 处理持续耐力消耗 // StaminaHandler 处理持续耐力消耗
func (g *GameManager) StaminaHandler(player *model.Player) { func (g *GameManager) StaminaHandler(player *model.Player) {
// 玩家暂停状态不更新耐力
if player.Pause {
return
}
staminaInfo := player.StaminaInfo staminaInfo := player.StaminaInfo
// 添加的耐力大于0为恢复 // 添加的耐力大于0为恢复
@@ -222,12 +229,13 @@ func (g *GameManager) UpdateStamina(player *model.Player, staminaCost int32) {
// SetStamina 设置玩家的耐力 // SetStamina 设置玩家的耐力
func (g *GameManager) SetStamina(player *model.Player, stamina uint32) { func (g *GameManager) SetStamina(player *model.Player, stamina uint32) {
prop := constant.PlayerPropertyConst.PROP_CUR_PERSIST_STAMINA prop := constant.PlayerPropertyConst.PROP_CUR_PERSIST_STAMINA
// 设置玩家的耐力prop
player.PropertiesMap[prop] = stamina
//logger.LOG.Debug("player curr stamina: %v", stamina)
// 当前无变动不要频繁发包 // 当前无变动不要频繁发包
if player.PropertiesMap[constant.PlayerPropertyConst.PROP_MAX_STAMINA] == player.PropertiesMap[constant.PlayerPropertyConst.PROP_CUR_PERSIST_STAMINA] { if player.PropertiesMap[constant.PlayerPropertyConst.PROP_MAX_STAMINA] == player.PropertiesMap[constant.PlayerPropertyConst.PROP_CUR_PERSIST_STAMINA] {
return return
} }
// 设置玩家的耐力prop
player.PropertiesMap[prop] = stamina
// PacketPlayerPropNotify // PacketPlayerPropNotify
playerPropNotify := new(proto.PlayerPropNotify) playerPropNotify := new(proto.PlayerPropNotify)

View File

@@ -21,18 +21,14 @@ func (g *GameManager) ChangeAvatarReq(player *model.Player, payloadMsg pb.Messag
scene := world.GetSceneById(player.SceneId) scene := world.GetSceneById(player.SceneId)
playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID) playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID)
oldAvatarId := player.TeamConfig.GetActiveAvatarId() oldAvatarId := world.GetPlayerActiveAvatarId(player)
oldAvatar := player.AvatarMap[oldAvatarId] oldAvatar := player.AvatarMap[oldAvatarId]
if oldAvatar.Guid == targetAvatarGuid { if oldAvatar.Guid == targetAvatarGuid {
logger.LOG.Error("can not change to the same avatar, uid: %v, oldAvatarId: %v, oldAvatarGuid: %v", player.PlayerID, oldAvatarId, oldAvatar.Guid) logger.LOG.Error("can not change to the same avatar, uid: %v, oldAvatarId: %v, oldAvatarGuid: %v", player.PlayerID, oldAvatarId, oldAvatar.Guid)
return return
} }
activeTeam := player.TeamConfig.GetActiveTeam()
index := -1 index := -1
for avatarIndex, avatarId := range activeTeam.AvatarIdList { for avatarIndex, avatarId := range world.GetPlayerAvatarIdList(player) {
if avatarId == 0 {
break
}
if targetAvatarGuid == player.AvatarMap[avatarId].Guid { if targetAvatarGuid == player.AvatarMap[avatarId].Guid {
index = avatarIndex index = avatarIndex
} }
@@ -42,6 +38,7 @@ func (g *GameManager) ChangeAvatarReq(player *model.Player, payloadMsg pb.Messag
return return
} }
player.TeamConfig.CurrAvatarIndex = uint8(index) player.TeamConfig.CurrAvatarIndex = uint8(index)
world.SetPlayerLocalAvatarIndex(player, index)
entity := scene.GetEntity(playerTeamEntity.avatarEntityMap[oldAvatarId]) entity := scene.GetEntity(playerTeamEntity.avatarEntityMap[oldAvatarId])
if entity == nil { if entity == nil {
@@ -57,10 +54,12 @@ func (g *GameManager) ChangeAvatarReq(player *model.Player, payloadMsg pb.Messag
g.SendMsg(cmd.SceneEntityDisappearNotify, scenePlayer.PlayerID, scenePlayer.ClientSeq, sceneEntityDisappearNotify) g.SendMsg(cmd.SceneEntityDisappearNotify, scenePlayer.PlayerID, scenePlayer.ClientSeq, sceneEntityDisappearNotify)
} }
newAvatarId := world.GetPlayerActiveAvatarId(player)
newAvatarEntity := g.PacketSceneEntityInfoAvatar(scene, player, newAvatarId)
sceneEntityAppearNotify := &proto.SceneEntityAppearNotify{ sceneEntityAppearNotify := &proto.SceneEntityAppearNotify{
AppearType: proto.VisionType_VISION_TYPE_REPLACE, AppearType: proto.VisionType_VISION_TYPE_REPLACE,
Param: playerTeamEntity.avatarEntityMap[oldAvatarId], Param: playerTeamEntity.avatarEntityMap[oldAvatarId],
EntityList: []*proto.SceneEntityInfo{g.PacketSceneEntityInfoAvatar(scene, player, player.TeamConfig.GetActiveAvatarId())}, EntityList: []*proto.SceneEntityInfo{newAvatarEntity},
} }
for _, scenePlayer := range scene.playerMap { for _, scenePlayer := range scene.playerMap {
g.SendMsg(cmd.SceneEntityAppearNotify, scenePlayer.PlayerID, scenePlayer.ClientSeq, sceneEntityAppearNotify) g.SendMsg(cmd.SceneEntityAppearNotify, scenePlayer.PlayerID, scenePlayer.ClientSeq, sceneEntityAppearNotify)
@@ -74,25 +73,22 @@ func (g *GameManager) ChangeAvatarReq(player *model.Player, payloadMsg pb.Messag
} }
func (g *GameManager) SetUpAvatarTeamReq(player *model.Player, payloadMsg pb.Message) { func (g *GameManager) SetUpAvatarTeamReq(player *model.Player, payloadMsg pb.Message) {
logger.LOG.Debug("user change team, uid: %v", player.PlayerID) logger.LOG.Debug("user change team avatar, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.SetUpAvatarTeamReq) req := payloadMsg.(*proto.SetUpAvatarTeamReq)
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
if world.multiplayer {
g.CommonRetError(cmd.SetUpAvatarTeamRsp, player, &proto.SetUpAvatarTeamRsp{})
return
}
teamId := req.TeamId teamId := req.TeamId
if teamId <= 0 || teamId >= 5 { if teamId <= 0 || teamId >= 5 {
setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{ g.CommonRetError(cmd.SetUpAvatarTeamRsp, player, &proto.SetUpAvatarTeamRsp{})
Retcode: int32(proto.Retcode_RET_SVR_ERROR),
}
g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp)
return return
} }
avatarGuidList := req.AvatarTeamGuidList avatarGuidList := req.AvatarTeamGuidList
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
selfTeam := teamId == uint32(player.TeamConfig.GetActiveTeamId()) selfTeam := teamId == uint32(player.TeamConfig.GetActiveTeamId())
if (selfTeam && len(avatarGuidList) == 0) || len(avatarGuidList) > 4 || world.multiplayer { if (selfTeam && len(avatarGuidList) == 0) || len(avatarGuidList) > 4 {
setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{ g.CommonRetError(cmd.SetUpAvatarTeamRsp, player, &proto.SetUpAvatarTeamRsp{})
Retcode: int32(proto.Retcode_RET_SVR_ERROR),
}
g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp)
return return
} }
avatarIdList := make([]uint32, 0) avatarIdList := make([]uint32, 0)
@@ -104,17 +100,7 @@ func (g *GameManager) SetUpAvatarTeamReq(player *model.Player, payloadMsg pb.Mes
} }
} }
player.TeamConfig.ClearTeamAvatar(uint8(teamId - 1)) player.TeamConfig.ClearTeamAvatar(uint8(teamId - 1))
for _, avatarId := range avatarIdList { player.TeamConfig.SetTeamAvatar(uint8(teamId-1), avatarIdList)
player.TeamConfig.AddAvatarToTeam(avatarId, uint8(teamId-1))
}
if world.multiplayer {
setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{
Retcode: int32(proto.Retcode_RET_SVR_ERROR),
}
g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp)
return
}
avatarTeamUpdateNotify := &proto.AvatarTeamUpdateNotify{ avatarTeamUpdateNotify := &proto.AvatarTeamUpdateNotify{
AvatarTeamMap: make(map[uint32]*proto.AvatarTeam), AvatarTeamMap: make(map[uint32]*proto.AvatarTeam),
@@ -124,10 +110,7 @@ func (g *GameManager) SetUpAvatarTeamReq(player *model.Player, payloadMsg pb.Mes
TeamName: team.Name, TeamName: team.Name,
AvatarGuidList: make([]uint64, 0), AvatarGuidList: make([]uint64, 0),
} }
for _, avatarId := range team.AvatarIdList { for _, avatarId := range team.GetAvatarIdList() {
if avatarId == 0 {
break
}
avatarTeam.AvatarGuidList = append(avatarTeam.AvatarGuidList, player.AvatarMap[avatarId].Guid) avatarTeam.AvatarGuidList = append(avatarTeam.AvatarGuidList, player.AvatarMap[avatarId].Guid)
} }
avatarTeamUpdateNotify.AvatarTeamMap[uint32(teamIndex)+1] = avatarTeam avatarTeamUpdateNotify.AvatarTeamMap[uint32(teamIndex)+1] = avatarTeam
@@ -137,40 +120,27 @@ func (g *GameManager) SetUpAvatarTeamReq(player *model.Player, payloadMsg pb.Mes
if selfTeam { if selfTeam {
player.TeamConfig.CurrAvatarIndex = 0 player.TeamConfig.CurrAvatarIndex = 0
player.TeamConfig.UpdateTeam() player.TeamConfig.UpdateTeam()
world.SetPlayerLocalAvatarIndex(player, 0)
world.SetPlayerLocalTeam(player, avatarIdList)
world.UpdateMultiplayerTeam()
scene := world.GetSceneById(player.SceneId) scene := world.GetSceneById(player.SceneId)
scene.UpdatePlayerTeamEntity(player) scene.UpdatePlayerTeamEntity(player)
sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world) sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world)
g.SendMsg(cmd.SceneTeamUpdateNotify, player.PlayerID, player.ClientSeq, sceneTeamUpdateNotify) g.SendMsg(cmd.SceneTeamUpdateNotify, player.PlayerID, player.ClientSeq, sceneTeamUpdateNotify)
setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{
TeamId: teamId,
CurAvatarGuid: player.AvatarMap[player.TeamConfig.GetActiveAvatarId()].Guid,
AvatarTeamGuidList: make([]uint64, 0),
}
team := player.TeamConfig.GetTeamByIndex(uint8(teamId - 1))
for _, avatarId := range team.AvatarIdList {
if avatarId == 0 {
break
}
setUpAvatarTeamRsp.AvatarTeamGuidList = append(setUpAvatarTeamRsp.AvatarTeamGuidList, player.AvatarMap[avatarId].Guid)
}
g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp)
} else {
setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{
TeamId: teamId,
CurAvatarGuid: player.AvatarMap[player.TeamConfig.GetActiveAvatarId()].Guid,
AvatarTeamGuidList: make([]uint64, 0),
}
team := player.TeamConfig.GetTeamByIndex(uint8(teamId - 1))
for _, avatarId := range team.AvatarIdList {
if avatarId == 0 {
break
}
setUpAvatarTeamRsp.AvatarTeamGuidList = append(setUpAvatarTeamRsp.AvatarTeamGuidList, player.AvatarMap[avatarId].Guid)
}
g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp)
} }
activeAvatarId := world.GetPlayerActiveAvatarId(player)
setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{
TeamId: teamId,
CurAvatarGuid: player.AvatarMap[activeAvatarId].Guid,
AvatarTeamGuidList: make([]uint64, 0),
}
team := player.TeamConfig.GetTeamByIndex(uint8(teamId - 1))
for _, avatarId := range team.GetAvatarIdList() {
setUpAvatarTeamRsp.AvatarTeamGuidList = append(setUpAvatarTeamRsp.AvatarTeamGuidList, player.AvatarMap[avatarId].Guid)
}
g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp)
} }
func (g *GameManager) ChooseCurAvatarTeamReq(player *model.Player, payloadMsg pb.Message) { func (g *GameManager) ChooseCurAvatarTeamReq(player *model.Player, payloadMsg pb.Message) {
@@ -179,15 +149,19 @@ func (g *GameManager) ChooseCurAvatarTeamReq(player *model.Player, payloadMsg pb
teamId := req.TeamId teamId := req.TeamId
world := WORLD_MANAGER.GetWorldByID(player.WorldId) world := WORLD_MANAGER.GetWorldByID(player.WorldId)
if world.multiplayer { if world.multiplayer {
g.CommonRetError(cmd.ChooseCurAvatarTeamRsp, player, &proto.ChooseCurAvatarTeamRsp{})
return return
} }
team := player.TeamConfig.GetTeamByIndex(uint8(teamId) - 1) team := player.TeamConfig.GetTeamByIndex(uint8(teamId) - 1)
if team == nil || len(team.AvatarIdList) == 0 { if team == nil || len(team.GetAvatarIdList()) == 0 {
return return
} }
player.TeamConfig.CurrTeamIndex = uint8(teamId) - 1 player.TeamConfig.CurrTeamIndex = uint8(teamId) - 1
player.TeamConfig.CurrAvatarIndex = 0 player.TeamConfig.CurrAvatarIndex = 0
player.TeamConfig.UpdateTeam() player.TeamConfig.UpdateTeam()
world.SetPlayerLocalAvatarIndex(player, 0)
world.SetPlayerLocalTeam(player, team.GetAvatarIdList())
world.UpdateMultiplayerTeam()
scene := world.GetSceneById(player.SceneId) scene := world.GetSceneById(player.SceneId)
scene.UpdatePlayerTeamEntity(player) scene.UpdatePlayerTeamEntity(player)
@@ -201,17 +175,13 @@ func (g *GameManager) ChooseCurAvatarTeamReq(player *model.Player, payloadMsg pb
} }
func (g *GameManager) ChangeMpTeamAvatarReq(player *model.Player, payloadMsg pb.Message) { func (g *GameManager) ChangeMpTeamAvatarReq(player *model.Player, payloadMsg pb.Message) {
logger.LOG.Debug("user change mp team, uid: %v", player.PlayerID) logger.LOG.Debug("user change mp team avatar, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.ChangeMpTeamAvatarReq) req := payloadMsg.(*proto.ChangeMpTeamAvatarReq)
currAvatarGuid := req.CurAvatarGuid
avatarGuidList := req.AvatarGuidList avatarGuidList := req.AvatarGuidList
world := WORLD_MANAGER.GetWorldByID(player.WorldId) world := WORLD_MANAGER.GetWorldByID(player.WorldId)
if len(avatarGuidList) == 0 || len(avatarGuidList) > 4 || !world.multiplayer { if !world.multiplayer || len(avatarGuidList) == 0 || len(avatarGuidList) > 4 {
changeMpTeamAvatarRsp := &proto.ChangeMpTeamAvatarRsp{ g.CommonRetError(cmd.ChangeMpTeamAvatarRsp, player, &proto.ChangeMpTeamAvatarRsp{})
Retcode: int32(proto.Retcode_RET_SVR_ERROR),
}
g.SendMsg(cmd.ChangeMpTeamAvatarRsp, player.PlayerID, player.ClientSeq, changeMpTeamAvatarRsp)
return return
} }
@@ -221,26 +191,14 @@ func (g *GameManager) ChangeMpTeamAvatarReq(player *model.Player, payloadMsg pb.
avatarIdList = append(avatarIdList, avatarId) avatarIdList = append(avatarIdList, avatarId)
} }
world.SetPlayerLocalTeam(player, avatarIdList) world.SetPlayerLocalTeam(player, avatarIdList)
world.SetPlayerLocalAvatarIndex(player, 0)
currAvatarId := player.GetAvatarIdByGuid(currAvatarGuid)
localTeam := world.multiplayerTeam.localTeamMap[player.PlayerID]
avatarIndex := 0
for index, worldTeamAvatar := range localTeam {
if worldTeamAvatar.avatarId == 0 {
continue
}
if worldTeamAvatar.avatarId == currAvatarId {
avatarIndex = index
}
}
world.SetPlayerLocalAvatarIndex(player, avatarIndex)
world.UpdateMultiplayerTeam() world.UpdateMultiplayerTeam()
scene := world.GetSceneById(player.SceneId) scene := world.GetSceneById(player.SceneId)
scene.UpdatePlayerTeamEntity(player) scene.UpdatePlayerTeamEntity(player)
for _, worldPlayer := range world.playerMap { for _, worldPlayer := range world.playerMap {
sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotifyMp(world) sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world)
g.SendMsg(cmd.SceneTeamUpdateNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, sceneTeamUpdateNotify) g.SendMsg(cmd.SceneTeamUpdateNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, sceneTeamUpdateNotify)
} }
@@ -259,113 +217,7 @@ func (g *GameManager) PacketSceneTeamUpdateNotify(world *World) *proto.SceneTeam
IsInMp: world.multiplayer, IsInMp: world.multiplayer,
} }
empty := new(proto.AbilitySyncStateInfo) empty := new(proto.AbilitySyncStateInfo)
for _, worldPlayer := range world.playerMap { for _, worldTeamAvatar := range world.GetWorldTeamAvatarList() {
worldPlayerScene := world.GetSceneById(worldPlayer.SceneId)
worldPlayerTeamEntity := worldPlayerScene.GetPlayerTeamEntity(worldPlayer.PlayerID)
team := worldPlayer.TeamConfig.GetActiveTeam()
for _, avatarId := range team.AvatarIdList {
if avatarId == 0 {
break
}
worldPlayerAvatar := worldPlayer.AvatarMap[avatarId]
equipIdList := make([]uint32, 0)
weapon := worldPlayerAvatar.EquipWeapon
equipIdList = append(equipIdList, weapon.ItemId)
for _, reliquary := range worldPlayerAvatar.EquipReliquaryList {
equipIdList = append(equipIdList, reliquary.ItemId)
}
sceneTeamAvatar := &proto.SceneTeamAvatar{
PlayerUid: worldPlayer.PlayerID,
AvatarGuid: worldPlayerAvatar.Guid,
SceneId: worldPlayer.SceneId,
EntityId: worldPlayerTeamEntity.avatarEntityMap[avatarId],
SceneEntityInfo: g.PacketSceneEntityInfoAvatar(worldPlayerScene, worldPlayer, avatarId),
WeaponGuid: worldPlayerAvatar.EquipWeapon.Guid,
WeaponEntityId: worldPlayerTeamEntity.weaponEntityMap[worldPlayerAvatar.EquipWeapon.WeaponId],
IsPlayerCurAvatar: worldPlayer.TeamConfig.GetActiveAvatarId() == avatarId,
IsOnScene: worldPlayer.TeamConfig.GetActiveAvatarId() == avatarId,
AvatarAbilityInfo: empty,
WeaponAbilityInfo: empty,
AbilityControlBlock: new(proto.AbilityControlBlock),
}
if world.multiplayer {
sceneTeamAvatar.AvatarInfo = g.PacketAvatarInfo(worldPlayerAvatar)
sceneTeamAvatar.SceneAvatarInfo = g.PacketSceneAvatarInfo(worldPlayerScene, worldPlayer, avatarId)
}
// add AbilityControlBlock
avatarDataConfig := gdc.CONF.AvatarDataMap[int32(avatarId)]
acb := sceneTeamAvatar.AbilityControlBlock
embryoId := 0
// add avatar abilities
if avatarDataConfig != nil {
for _, abilityId := range avatarDataConfig.Abilities {
embryoId++
emb := &proto.AbilityEmbryo{
AbilityId: uint32(embryoId),
AbilityNameHash: uint32(abilityId),
AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME),
}
acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb)
}
}
// add default abilities
for _, abilityId := range constant.GameConstantConst.DEFAULT_ABILITY_HASHES {
embryoId++
emb := &proto.AbilityEmbryo{
AbilityId: uint32(embryoId),
AbilityNameHash: uint32(abilityId),
AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME),
}
acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb)
}
// add team resonances
for id := range worldPlayer.TeamConfig.TeamResonancesConfig {
embryoId++
emb := &proto.AbilityEmbryo{
AbilityId: uint32(embryoId),
AbilityNameHash: uint32(id),
AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME),
}
acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb)
}
// add skill depot abilities
skillDepot := gdc.CONF.AvatarSkillDepotDataMap[int32(worldPlayerAvatar.SkillDepotId)]
if skillDepot != nil && len(skillDepot.Abilities) != 0 {
for _, id := range skillDepot.Abilities {
embryoId++
emb := &proto.AbilityEmbryo{
AbilityId: uint32(embryoId),
AbilityNameHash: uint32(id),
AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME),
}
acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb)
}
}
// add equip abilities
for skill := range worldPlayerAvatar.ExtraAbilityEmbryos {
embryoId++
emb := &proto.AbilityEmbryo{
AbilityId: uint32(embryoId),
AbilityNameHash: uint32(endec.Hk4eAbilityHashCode(skill)),
AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME),
}
acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb)
}
sceneTeamUpdateNotify.SceneTeamAvatarList = append(sceneTeamUpdateNotify.SceneTeamAvatarList, sceneTeamAvatar)
}
}
return sceneTeamUpdateNotify
}
func (g *GameManager) PacketSceneTeamUpdateNotifyMp(world *World) *proto.SceneTeamUpdateNotify {
sceneTeamUpdateNotify := &proto.SceneTeamUpdateNotify{
IsInMp: world.multiplayer,
}
empty := new(proto.AbilitySyncStateInfo)
for _, worldTeamAvatar := range world.multiplayerTeam.worldTeam {
if worldTeamAvatar.avatarId == 0 {
continue
}
worldPlayer := USER_MANAGER.GetOnlineUser(worldTeamAvatar.uid) worldPlayer := USER_MANAGER.GetOnlineUser(worldTeamAvatar.uid)
worldPlayerScene := world.GetSceneById(worldPlayer.SceneId) worldPlayerScene := world.GetSceneById(worldPlayer.SceneId)
worldPlayerTeamEntity := worldPlayerScene.GetPlayerTeamEntity(worldPlayer.PlayerID) worldPlayerTeamEntity := worldPlayerScene.GetPlayerTeamEntity(worldPlayer.PlayerID)
@@ -420,16 +272,16 @@ func (g *GameManager) PacketSceneTeamUpdateNotifyMp(world *World) *proto.SceneTe
} }
acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb) acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb)
} }
// add team resonances //// add team resonances
for id := range worldPlayer.TeamConfig.TeamResonancesConfig { //for id := range worldPlayer.TeamConfig.TeamResonancesConfig {
embryoId++ // embryoId++
emb := &proto.AbilityEmbryo{ // emb := &proto.AbilityEmbryo{
AbilityId: uint32(embryoId), // AbilityId: uint32(embryoId),
AbilityNameHash: uint32(id), // AbilityNameHash: uint32(id),
AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME), // AbilityOverrideNameHash: uint32(constant.GameConstantConst.DEFAULT_ABILITY_NAME),
} // }
acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb) // acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb)
} //}
// add skill depot abilities // add skill depot abilities
skillDepot := gdc.CONF.AvatarSkillDepotDataMap[int32(worldPlayerAvatar.SkillDepotId)] skillDepot := gdc.CONF.AvatarSkillDepotDataMap[int32(worldPlayerAvatar.SkillDepotId)]
if skillDepot != nil && len(skillDepot.Abilities) != 0 { if skillDepot != nil && len(skillDepot.Abilities) != 0 {

View File

@@ -43,7 +43,7 @@ func (w *WorldManager) GetWorldMap() map[uint32]*World {
return w.worldMap return w.worldMap
} }
func (w *WorldManager) CreateWorld(owner *model.Player, multiplayer bool) *World { func (w *WorldManager) CreateWorld(owner *model.Player) *World {
worldId := uint32(w.snowflake.GenId()) worldId := uint32(w.snowflake.GenId())
world := &World{ world := &World{
id: worldId, id: worldId,
@@ -52,7 +52,7 @@ func (w *WorldManager) CreateWorld(owner *model.Player, multiplayer bool) *World
sceneMap: make(map[uint32]*Scene), sceneMap: make(map[uint32]*Scene),
entityIdCounter: 0, entityIdCounter: 0,
worldLevel: 0, worldLevel: 0,
multiplayer: multiplayer, multiplayer: false,
mpLevelEntityId: 0, mpLevelEntityId: 0,
chatMsgList: make([]*proto.ChatInfo, 0), chatMsgList: make([]*proto.ChatInfo, 0),
// aoi划分 // aoi划分
@@ -88,38 +88,22 @@ func (w *WorldManager) DestroyWorld(worldId uint32) {
delete(w.worldMap, worldId) delete(w.worldMap, worldId)
} }
// GetBigWorld 获取本服务器的AI世界
func (w *WorldManager) GetBigWorld() *World { func (w *WorldManager) GetBigWorld() *World {
return w.bigWorld return w.bigWorld
} }
// InitBigWorld 初始化世界 // InitBigWorld 初始化AI世界
func (w *WorldManager) InitBigWorld(owner *model.Player) { func (w *WorldManager) InitBigWorld(owner *model.Player) {
w.bigWorld = w.GetWorldByID(owner.WorldId) w.bigWorld = w.GetWorldByID(owner.WorldId)
w.bigWorld.ChangeToMultiplayer() w.bigWorld.ChangeToMultiplayer()
} }
// WorldTeamAvatar 通用世界队伍角色项 func (w *World) IsBigWorld() bool {
type WorldTeamAvatar struct { return w.owner.PlayerID == 1
uid uint32
avatarId uint32
} }
type MultiplayerTeam struct { // 世界数据结构
// key:uid value:玩家的本地队伍
localTeamMap map[uint32][]*WorldTeamAvatar
// key:uid value:玩家当前角色索引
localAvatarIndexMap map[uint32]int
// 最终的世界队伍
worldTeam []*WorldTeamAvatar
}
func CreateMultiplayerTeam() (r *MultiplayerTeam) {
r = new(MultiplayerTeam)
r.localTeamMap = make(map[uint32][]*WorldTeamAvatar)
r.localAvatarIndexMap = make(map[uint32]int)
r.worldTeam = make([]*WorldTeamAvatar, 0)
return r
}
type World struct { type World struct {
id uint32 id uint32
@@ -144,6 +128,7 @@ func (w *World) GetNextWorldEntityId(entityType uint16) uint32 {
return ret return ret
} }
// GetPlayerPeerId 获取当前玩家世界内编号
func (w *World) GetPlayerPeerId(player *model.Player) uint32 { func (w *World) GetPlayerPeerId(player *model.Player) uint32 {
for peerId, worldPlayer := range w.peerMap { for peerId, worldPlayer := range w.peerMap {
if worldPlayer.PlayerID == player.PlayerID { if worldPlayer.PlayerID == player.PlayerID {
@@ -153,10 +138,12 @@ func (w *World) GetPlayerPeerId(player *model.Player) uint32 {
return 0 return 0
} }
// GetNextPeerId 获取下一个世界内玩家编号
func (w *World) GetNextPeerId() uint32 { func (w *World) GetNextPeerId() uint32 {
return uint32(len(w.playerMap) + 1) return uint32(len(w.playerMap) + 1)
} }
// GetWorldPlayerNum 获取世界中玩家的数量
func (w *World) GetWorldPlayerNum() int { func (w *World) GetWorldPlayerNum() int {
return len(w.playerMap) return len(w.playerMap)
} }
@@ -166,7 +153,14 @@ func (w *World) AddPlayer(player *model.Player, sceneId uint32) {
w.playerMap[player.PlayerID] = player w.playerMap[player.PlayerID] = player
// 将玩家自身当前的队伍角色信息复制到世界的玩家本地队伍 // 将玩家自身当前的队伍角色信息复制到世界的玩家本地队伍
team := player.TeamConfig.GetActiveTeam() team := player.TeamConfig.GetActiveTeam()
w.SetPlayerLocalTeam(player, team.AvatarIdList) if player.PlayerID == w.owner.PlayerID {
w.SetPlayerLocalTeam(player, team.AvatarIdList)
w.SetPlayerLocalAvatarIndex(player, int(player.TeamConfig.CurrAvatarIndex))
} else {
// 非房主最多复制前两个角色
w.SetPlayerLocalTeam(player, team.AvatarIdList[0:2])
w.SetPlayerLocalAvatarIndex(player, 0)
}
w.UpdateMultiplayerTeam() w.UpdateMultiplayerTeam()
scene := w.GetSceneById(sceneId) scene := w.GetSceneById(sceneId)
scene.AddPlayer(player) scene.AddPlayer(player)
@@ -183,17 +177,44 @@ func (w *World) RemovePlayer(player *model.Player) {
w.UpdateMultiplayerTeam() w.UpdateMultiplayerTeam()
} }
// WorldAvatar 通用世界角色
type WorldAvatar struct {
uid uint32
avatarId uint32
}
type MultiplayerTeam struct {
// key:uid value:玩家的本地队伍
localTeamMap map[uint32][]*WorldAvatar
// key:uid value:玩家当前角色索引
localAvatarIndexMap map[uint32]int
// 最终的世界队伍
worldTeam []*WorldAvatar
}
func CreateMultiplayerTeam() (r *MultiplayerTeam) {
r = new(MultiplayerTeam)
r.localTeamMap = make(map[uint32][]*WorldAvatar)
r.localAvatarIndexMap = make(map[uint32]int)
r.worldTeam = make([]*WorldAvatar, 0)
return r
}
func (w *World) GetPlayerLocalTeam(player *model.Player) []*WorldAvatar {
return w.multiplayerTeam.localTeamMap[player.PlayerID]
}
func (w *World) SetPlayerLocalTeam(player *model.Player, avatarIdList []uint32) { func (w *World) SetPlayerLocalTeam(player *model.Player, avatarIdList []uint32) {
localTeam := make([]*WorldTeamAvatar, 4) localTeam := make([]*WorldAvatar, 4)
for index := 0; index < 4; index++ { for index := 0; index < 4; index++ {
if index > len(avatarIdList)-1 { if index > len(avatarIdList)-1 {
localTeam[index] = &WorldTeamAvatar{ localTeam[index] = &WorldAvatar{
uid: 0, uid: 0,
avatarId: 0, avatarId: 0,
} }
} else { } else {
avatarId := avatarIdList[index] avatarId := avatarIdList[index]
localTeam[index] = &WorldTeamAvatar{ localTeam[index] = &WorldAvatar{
uid: player.PlayerID, uid: player.PlayerID,
avatarId: avatarId, avatarId: avatarId,
} }
@@ -202,12 +223,16 @@ func (w *World) SetPlayerLocalTeam(player *model.Player, avatarIdList []uint32)
w.multiplayerTeam.localTeamMap[player.PlayerID] = localTeam w.multiplayerTeam.localTeamMap[player.PlayerID] = localTeam
} }
func (w *World) ClearPlayerLocalTeam(player *model.Player) {
w.multiplayerTeam.localTeamMap[player.PlayerID] = make([]*WorldAvatar, 4)
}
func (w *World) GetPlayerLocalAvatarIndex(player *model.Player) int { func (w *World) GetPlayerLocalAvatarIndex(player *model.Player) int {
return w.multiplayerTeam.localAvatarIndexMap[player.PlayerID] return w.multiplayerTeam.localAvatarIndexMap[player.PlayerID]
} }
func (w *World) SetPlayerLocalAvatarIndex(player *model.Player, index int) { func (w *World) SetPlayerLocalAvatarIndex(player *model.Player, index int) {
if index > len(w.multiplayerTeam.localTeamMap[player.PlayerID])-1 { if index > len(w.GetPlayerLocalTeam(player))-1 {
return return
} }
w.multiplayerTeam.localAvatarIndexMap[player.PlayerID] = index w.multiplayerTeam.localAvatarIndexMap[player.PlayerID] = index
@@ -215,16 +240,39 @@ func (w *World) SetPlayerLocalAvatarIndex(player *model.Player, index int) {
func (w *World) GetPlayerActiveAvatarId(player *model.Player) uint32 { func (w *World) GetPlayerActiveAvatarId(player *model.Player) uint32 {
avatarIndex := w.GetPlayerLocalAvatarIndex(player) avatarIndex := w.GetPlayerLocalAvatarIndex(player)
localTeam := w.multiplayerTeam.localTeamMap[player.PlayerID] localTeam := w.GetPlayerLocalTeam(player)
worldTeamAvatar := localTeam[avatarIndex] worldTeamAvatar := localTeam[avatarIndex]
return worldTeamAvatar.avatarId return worldTeamAvatar.avatarId
} }
func (w *World) GetPlayerAvatarIdList(player *model.Player) []uint32 {
localTeam := w.GetPlayerLocalTeam(player)
avatarIdList := make([]uint32, 0)
for _, worldAvatar := range localTeam {
if worldAvatar.avatarId == 0 {
continue
}
avatarIdList = append(avatarIdList, worldAvatar.avatarId)
}
return avatarIdList
}
func (w *World) GetWorldTeamAvatarList() []*WorldAvatar {
worldAvatarList := make([]*WorldAvatar, 0)
for _, worldAvatar := range w.multiplayerTeam.worldTeam {
if worldAvatar.avatarId == 0 {
continue
}
worldAvatarList = append(worldAvatarList, worldAvatar)
}
return worldAvatarList
}
func (w *World) copyLocalTeamToWorld(start int, end int, peerId uint32) { func (w *World) copyLocalTeamToWorld(start int, end int, peerId uint32) {
localTeamIndex := 0 localTeamIndex := 0
for index := start; index <= end; index++ { for index := start; index <= end; index++ {
player := w.peerMap[peerId] player := w.peerMap[peerId]
localTeam := w.multiplayerTeam.localTeamMap[player.PlayerID] localTeam := w.GetPlayerLocalTeam(player)
w.multiplayerTeam.worldTeam[index] = localTeam[localTeamIndex] w.multiplayerTeam.worldTeam[index] = localTeam[localTeamIndex]
localTeamIndex++ localTeamIndex++
} }
@@ -232,7 +280,7 @@ func (w *World) copyLocalTeamToWorld(start int, end int, peerId uint32) {
// UpdateMultiplayerTeam 整合所有玩家的本地队伍计算出世界队伍 // UpdateMultiplayerTeam 整合所有玩家的本地队伍计算出世界队伍
func (w *World) UpdateMultiplayerTeam() { func (w *World) UpdateMultiplayerTeam() {
w.multiplayerTeam.worldTeam = make([]*WorldTeamAvatar, 4) w.multiplayerTeam.worldTeam = make([]*WorldAvatar, 4)
switch w.GetWorldPlayerNum() { switch w.GetWorldPlayerNum() {
case 1: case 1:
// 1P*4 // 1P*4
@@ -257,6 +305,35 @@ func (w *World) UpdateMultiplayerTeam() {
} }
} }
// 世界聊天
func (w *World) AddChat(chatInfo *proto.ChatInfo) {
w.chatMsgList = append(w.chatMsgList, chatInfo)
}
func (w *World) GetChatList() []*proto.ChatInfo {
return w.chatMsgList
}
// ChangeToMultiplayer 转换为多人世界
func (w *World) ChangeToMultiplayer() {
w.multiplayer = true
}
// IsPlayerFirstEnter 获取玩家是否首次加入本世界
func (w *World) IsPlayerFirstEnter(player *model.Player) bool {
_, exist := w.playerFirstEnterMap[player.PlayerID]
if !exist {
return true
} else {
return false
}
}
func (w *World) PlayerEnter(player *model.Player) {
w.playerFirstEnterMap[player.PlayerID] = time.Now().UnixMilli()
}
func (w *World) CreateScene(sceneId uint32) *Scene { func (w *World) CreateScene(sceneId uint32) *Scene {
scene := &Scene{ scene := &Scene{
id: sceneId, id: sceneId,
@@ -281,34 +358,7 @@ func (w *World) GetSceneById(sceneId uint32) *Scene {
return scene return scene
} }
func (w *World) AddChat(chatInfo *proto.ChatInfo) { // 场景数据结构
w.chatMsgList = append(w.chatMsgList, chatInfo)
}
func (w *World) GetChatList() []*proto.ChatInfo {
return w.chatMsgList
}
func (w *World) IsBigWorld() bool {
return w.owner.PlayerID == 1
}
func (w *World) ChangeToMultiplayer() {
w.multiplayer = true
}
func (w *World) IsPlayerFirstEnter(player *model.Player) bool {
_, exist := w.playerFirstEnterMap[player.PlayerID]
if !exist {
return true
} else {
return false
}
}
func (w *World) PlayerEnter(player *model.Player) {
w.playerFirstEnterMap[player.PlayerID] = time.Now().UnixMilli()
}
type Scene struct { type Scene struct {
id uint32 id uint32
@@ -334,6 +384,8 @@ type GadgetEntity struct {
gatherId uint32 gatherId uint32
} }
// 场景实体数据结构
type Entity struct { type Entity struct {
id uint32 id uint32
scene *Scene scene *Scene
@@ -388,34 +440,9 @@ func (s *Scene) CreatePlayerTeamEntity(player *model.Player) {
} }
func (s *Scene) UpdatePlayerTeamEntity(player *model.Player) { func (s *Scene) UpdatePlayerTeamEntity(player *model.Player) {
if s.world.multiplayer {
s.UpdatePlayerTeamEntityMp(player)
return
}
team := player.TeamConfig.GetActiveTeam()
playerTeamEntity := s.playerTeamEntityMap[player.PlayerID] playerTeamEntity := s.playerTeamEntityMap[player.PlayerID]
for _, avatarId := range team.AvatarIdList { for _, worldTeamAvatar := range s.world.GetWorldTeamAvatarList() {
if avatarId == 0 { if worldTeamAvatar.uid != player.PlayerID {
break
}
avatar := player.AvatarMap[avatarId]
avatarEntityId, exist := playerTeamEntity.avatarEntityMap[avatarId]
if exist {
s.DestroyEntity(avatarEntityId)
}
playerTeamEntity.avatarEntityMap[avatarId] = s.CreateEntityAvatar(player, avatarId)
weaponEntityId, exist := playerTeamEntity.weaponEntityMap[avatar.EquipWeapon.WeaponId]
if exist {
s.DestroyEntity(weaponEntityId)
}
playerTeamEntity.weaponEntityMap[avatar.EquipWeapon.WeaponId] = s.CreateEntityWeapon()
}
}
func (s *Scene) UpdatePlayerTeamEntityMp(player *model.Player) {
playerTeamEntity := s.playerTeamEntityMap[player.PlayerID]
for _, worldTeamAvatar := range s.world.multiplayerTeam.worldTeam {
if worldTeamAvatar.uid != player.PlayerID || worldTeamAvatar.avatarId == 0 {
continue continue
} }
avatar := player.AvatarMap[worldTeamAvatar.avatarId] avatar := player.AvatarMap[worldTeamAvatar.avatarId]
@@ -469,7 +496,7 @@ func (s *Scene) CreateEntityAvatar(player *model.Player, avatarId uint32) uint32
}, },
} }
s.entityMap[entity.id] = entity s.entityMap[entity.id] = entity
if avatarId == player.TeamConfig.GetActiveAvatarId() { if avatarId == s.world.GetPlayerActiveAvatarId(player) {
s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z)) s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
} }
return entity.id return entity.id

View File

@@ -43,9 +43,9 @@ func (i *InvokeHandler[T]) AddEntry(forward proto.ForwardType, entry *T) {
i.EntryListForwardHost = append(i.EntryListForwardHost, entry) i.EntryListForwardHost = append(i.EntryListForwardHost, entry)
case proto.ForwardType_FORWARD_TYPE_ONLY_SERVER: case proto.ForwardType_FORWARD_TYPE_ONLY_SERVER:
i.EntryListForwardServer = append(i.EntryListForwardServer, entry) i.EntryListForwardServer = append(i.EntryListForwardServer, entry)
logger.LOG.Error("fwd server entry: %v", entry) //logger.LOG.Error("forward server entry: %v", entry)
default: default:
logger.LOG.Error("forward: %v, entry: %v", forward, entry) logger.LOG.Error("forward type: %v, entry: %v", forward, entry)
} }
} }

View File

@@ -6,11 +6,9 @@ import (
) )
const ( const (
DbInsert = iota DbNormal = iota
DbInsert
DbDelete DbDelete
DbUpdate
DbNormal
DbOffline
) )
const ( const (

View File

@@ -10,6 +10,17 @@ type Team struct {
AvatarIdList []uint32 `bson:"avatarIdList"` AvatarIdList []uint32 `bson:"avatarIdList"`
} }
func (t *Team) GetAvatarIdList() []uint32 {
avatarIdList := make([]uint32, 0)
for _, avatarId := range t.AvatarIdList {
if avatarId == 0 {
continue
}
avatarIdList = append(avatarIdList, avatarId)
}
return avatarIdList
}
type TeamInfo struct { type TeamInfo struct {
TeamList []*Team `bson:"teamList"` TeamList []*Team `bson:"teamList"`
CurrTeamIndex uint8 `bson:"currTeamIndex"` CurrTeamIndex uint8 `bson:"currTeamIndex"`
@@ -39,10 +50,7 @@ func (t *TeamInfo) UpdateTeam() {
t.TeamResonancesConfig = make(map[int32]bool) t.TeamResonancesConfig = make(map[int32]bool)
teamElementTypeCountMap := make(map[uint16]uint8) teamElementTypeCountMap := make(map[uint16]uint8)
avatarSkillDepotDataMapConfig := gdc.CONF.AvatarSkillDepotDataMap avatarSkillDepotDataMapConfig := gdc.CONF.AvatarSkillDepotDataMap
for _, avatarId := range activeTeam.AvatarIdList { for _, avatarId := range activeTeam.GetAvatarIdList() {
if avatarId == 0 {
break
}
skillData := avatarSkillDepotDataMapConfig[int32(avatarId)] skillData := avatarSkillDepotDataMapConfig[int32(avatarId)]
if skillData != nil { if skillData != nil {
teamElementTypeCountMap[skillData.ElementType.Value] += 1 teamElementTypeCountMap[skillData.ElementType.Value] += 1
@@ -90,26 +98,10 @@ func (t *TeamInfo) ClearTeamAvatar(teamIndex uint8) {
team.AvatarIdList = make([]uint32, 4) team.AvatarIdList = make([]uint32, 4)
} }
func (t *TeamInfo) AddAvatarToTeam(avatarId uint32, teamIndex uint8) { func (t *TeamInfo) SetTeamAvatar(teamIndex uint8, avatarIdList []uint32) {
team := t.GetTeamByIndex(teamIndex) team := t.GetTeamByIndex(teamIndex)
if team == nil { if team == nil {
return return
} }
for i, v := range team.AvatarIdList { team.AvatarIdList = avatarIdList
if v == 0 {
team.AvatarIdList[i] = avatarId
break
}
}
}
func (t *TeamInfo) GetActiveAvatarId() uint32 {
activeTeam := t.GetActiveTeam()
if activeTeam == nil {
return 0
}
if t.CurrAvatarIndex >= uint8(len(activeTeam.AvatarIdList)) {
return 0
}
return activeTeam.AvatarIdList[t.CurrAvatarIndex]
} }

View File

@@ -25,3 +25,25 @@ func ConvStructToMap(value any) map[string]any {
} }
return result return result
} }
func SetStructFieldValue(structPointer any, fieldName string, value any) bool {
refType := reflect.TypeOf(structPointer)
if refType.Kind() != reflect.Ptr {
return false
}
refType = refType.Elem()
if refType.Kind() != reflect.Struct {
return false
}
refValue := reflect.ValueOf(structPointer)
if refValue.Kind() != reflect.Ptr {
return false
}
refValue = refValue.Elem()
field := refValue.FieldByName(fieldName)
if field.Type() != reflect.TypeOf(value) {
return false
}
field.Set(reflect.ValueOf(value))
return true
}