完善多人世界队伍

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/kcp"
"hk4e/gs/dao"
"hk4e/gs/model"
"hk4e/pkg/alg"
"hk4e/pkg/logger"
"hk4e/pkg/reflection"
"hk4e/protocol/cmd"
"hk4e/protocol/proto"
)
@@ -35,7 +37,7 @@ func NewGameManager(dao *dao.Dao, netMsgInput chan *cmd.NetMsg, netMsgOutput cha
GAME_MANAGER = r
LOCAL_EVENT_MANAGER = NewLocalEventManager()
ROUTE_MANAGER = NewRouteManager()
USER_MANAGER = NewUserManager(dao, LOCAL_EVENT_MANAGER.localEventChan)
USER_MANAGER = NewUserManager(dao)
WORLD_MANAGER = NewWorldManager(r.snowflake)
TICK_MANAGER = NewTickManager()
COMMAND_MANAGER = NewCommandManager()
@@ -92,6 +94,27 @@ func (g *GameManager) SendMsg(cmdId uint16, userId uint32, clientSeq uint32, pay
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) {
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 {
if world.multiplayer || !world.owner.Pause {
// 改面板
team := player.TeamConfig.GetActiveTeam()
for _, avatarId := range team.AvatarIdList {
if avatarId == 0 {
break
}
for _, avatarId := range world.GetPlayerAvatarIdList(player) {
avatar := player.AvatarMap[avatarId]
avatar.FightPropMap[uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_ATTACK)] = 1000000
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)
scene := world.GetSceneById(player.SceneId)
playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID)
team := player.TeamConfig.GetActiveTeam()
if weapon.AvatarId != 0 {
// 武器在别的角色身上
@@ -105,10 +104,7 @@ func (g *GameManager) WearUserAvatarEquip(userId uint32, avatarId uint32, weapon
weakAvatar := player.AvatarMap[weakAvatarId]
weakWeapon := player.WeaponMap[weakAvatar.EquipWeapon.WeaponId]
for _, aid := range team.AvatarIdList {
if aid == 0 {
break
}
for _, aid := range world.GetPlayerAvatarIdList(player) {
if aid == weakAvatar.AvatarId {
playerTeamEntity.weaponEntityMap[weakWeapon.WeaponId] = scene.CreateEntityWeapon()
}
@@ -125,10 +121,7 @@ func (g *GameManager) WearUserAvatarEquip(userId uint32, avatarId uint32, weapon
player.WearWeapon(avatarId, weaponId)
}
for _, aid := range team.AvatarIdList {
if aid == 0 {
break
}
for _, aid := range world.GetPlayerAvatarIdList(player) {
if aid == avatarId {
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 {
continue
}
activeAvatarId := player.TeamConfig.GetActiveAvatarId()
activeAvatarId := world.GetPlayerActiveAvatarId(player)
playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID)
playerActiveAvatarEntityId := playerTeamEntity.avatarEntityMap[activeAvatarId]
if entityMoveInfo.EntityId == playerActiveAvatarEntityId {
@@ -232,8 +232,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
}
}
// 把队伍中的其他非活跃角色也同步进行移动
team := player.TeamConfig.GetActiveTeam()
for _, avatarId := range team.AvatarIdList {
for _, avatarId := range world.GetPlayerAvatarIdList(player) {
// 跳过当前的活跃角色
if avatarId == activeAvatarId {
continue

View File

@@ -33,7 +33,7 @@ func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq u
player.InitAll()
player.TeamConfig.UpdateTeam()
// 创建世界
world := WORLD_MANAGER.CreateWorld(player, false)
world := WORLD_MANAGER.CreateWorld(player)
world.AddPlayer(player, player.SceneId)
player.WorldId = world.id
@@ -107,7 +107,7 @@ func (g *GameManager) OnUserOffline(userId uint32) {
player.OfflineTime = uint32(time.Now().Unix())
player.Online = false
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) {
@@ -258,10 +258,7 @@ func (g *GameManager) PacketAvatarDataNotify(player *model.Player) *proto.Avatar
}
for teamIndex, team := range player.TeamConfig.TeamList {
var teamAvatarGuidList []uint64 = nil
for _, avatarId := range team.AvatarIdList {
if avatarId == 0 {
break
}
for _, avatarId := range team.GetAvatarIdList() {
teamAvatarGuidList = append(teamAvatarGuidList, player.AvatarMap[avatarId].Guid)
}
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.TeamConfig = model.NewTeamInfo()
player.TeamConfig.AddAvatarToTeam(mainCharAvatarId, 0)
player.TeamConfig.SetTeamAvatar(0, []uint32{mainCharAvatarId})
return player
}

View File

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

View File

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

View File

@@ -58,7 +58,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
NameCardId: worldPlayer.NameCard,
Signature: worldPlayer.Signature,
ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage},
CurPlayerNumInWorld: uint32(len(world.playerMap)),
CurPlayerNumInWorld: uint32(world.GetWorldPlayerNum()),
}
worldPlayerInfoNotify.PlayerInfoList = append(worldPlayerInfoNotify.PlayerInfoList, onlinePlayerInfo)
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)
empty := new(proto.AbilitySyncStateInfo)
activeAvatarId := player.TeamConfig.GetActiveAvatarId()
activeAvatarId := world.GetPlayerActiveAvatarId(player)
playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID)
playerEnterSceneInfoNotify := &proto.PlayerEnterSceneInfoNotify{
CurAvatarEntityId: playerTeamEntity.avatarEntityMap[activeAvatarId],
@@ -133,11 +133,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
},
AvatarEnterInfo: make([]*proto.AvatarEnterSceneInfo, 0),
}
activeTeam := player.TeamConfig.GetActiveTeam()
for _, avatarId := range activeTeam.AvatarIdList {
if avatarId == 0 {
break
}
for _, avatarId := range world.GetPlayerAvatarIdList(player) {
avatar := player.AvatarMap[avatarId]
avatarEnterSceneInfo := &proto.AvatarEnterSceneInfo{
AvatarGuid: avatar.Guid,
@@ -170,7 +166,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
NameCardId: worldPlayer.NameCard,
Signature: worldPlayer.Signature,
ProfilePicture: &proto.ProfilePicture{AvatarId: worldPlayer.HeadImage},
CurPlayerNumInWorld: uint32(len(world.playerMap)),
CurPlayerNumInWorld: uint32(world.GetWorldPlayerNum()),
}
scenePlayerInfoNotify.PlayerInfoList = append(scenePlayerInfoNotify.PlayerInfoList, &proto.ScenePlayerInfo{
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)
var sceneTeamUpdateNotify *proto.SceneTeamUpdateNotify = nil
if world.multiplayer {
sceneTeamUpdateNotify = g.PacketSceneTeamUpdateNotifyMp(world)
} else {
sceneTeamUpdateNotify = g.PacketSceneTeamUpdateNotify(world)
}
sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world)
g.SendMsg(cmd.SceneTeamUpdateNotify, player.PlayerID, player.ClientSeq, sceneTeamUpdateNotify)
syncTeamEntityNotify := &proto.SyncTeamEntityNotify{
@@ -240,7 +231,7 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess
var visionType = proto.VisionType_VISION_TYPE_TRANSPORT
playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID)
activeAvatarId := player.TeamConfig.GetActiveAvatarId()
activeAvatarId := world.GetPlayerActiveAvatarId(player)
if world.IsPlayerFirstEnter(player) {
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)
continue
}
if entity.avatarEntity.avatarId != scenePlayer.TeamConfig.GetActiveAvatarId() {
if entity.avatarEntity.avatarId != world.GetPlayerActiveAvatarId(scenePlayer) {
continue
}
sceneEntityInfoAvatar := g.PacketSceneEntityInfoAvatar(scene, scenePlayer, scenePlayer.TeamConfig.GetActiveAvatarId())
sceneEntityInfoAvatar := g.PacketSceneEntityInfoAvatar(scene, scenePlayer, world.GetPlayerActiveAvatarId(scenePlayer))
entityList = append(entityList, sceneEntityInfoAvatar)
case uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_WEAPON):
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),
TeamResonanceList: make([]uint32, 0),
}
for id := range player.TeamConfig.TeamResonances {
sceneAvatarInfo.TeamResonanceList = append(sceneAvatarInfo.TeamResonanceList, uint32(id))
}
//for id := range player.TeamConfig.TeamResonances {
// sceneAvatarInfo.TeamResonanceList = append(sceneAvatarInfo.TeamResonanceList, uint32(id))
//}
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)
req := payloadMsg.(*proto.SetPlayerBirthdayReq)
_ = req
g.CommonRetError(cmd.SetPlayerBirthdayRsp, player, &proto.SetPlayerBirthdayRsp{})
}
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)
if world != nil && world.playerMap != nil {
onlinePlayerInfo.CurPlayerNumInWorld = uint32(len(world.playerMap))
onlinePlayerInfo.CurPlayerNumInWorld = uint32(world.GetWorldPlayerNum())
}
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 {
angleRevise = int32(req.Rot.X - 360.0)
} 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
@@ -49,12 +54,6 @@ func (g *GameManager) SceneAvatarStaminaStepReq(player *model.Player, payloadMsg
// PacketSceneAvatarStaminaStepRsp
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.Rot = req.Rot
g.SendMsg(cmd.SceneAvatarStaminaStepRsp, player.PlayerID, player.ClientSeq, sceneAvatarStaminaStepRsp)
@@ -62,6 +61,10 @@ func (g *GameManager) SceneAvatarStaminaStepReq(player *model.Player, payloadMsg
// HandleStamina 处理即时耐力消耗
func (g *GameManager) HandleStamina(player *model.Player, motionState proto.MotionState) {
// 玩家暂停状态不更新耐力
if player.Pause {
return
}
staminaInfo := player.StaminaInfo
//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 处理持续耐力消耗
func (g *GameManager) StaminaHandler(player *model.Player) {
// 玩家暂停状态不更新耐力
if player.Pause {
return
}
staminaInfo := player.StaminaInfo
// 添加的耐力大于0为恢复
@@ -222,12 +229,13 @@ func (g *GameManager) UpdateStamina(player *model.Player, staminaCost int32) {
// SetStamina 设置玩家的耐力
func (g *GameManager) SetStamina(player *model.Player, stamina uint32) {
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] {
return
}
// 设置玩家的耐力prop
player.PropertiesMap[prop] = stamina
// PacketPlayerPropNotify
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)
playerTeamEntity := scene.GetPlayerTeamEntity(player.PlayerID)
oldAvatarId := player.TeamConfig.GetActiveAvatarId()
oldAvatarId := world.GetPlayerActiveAvatarId(player)
oldAvatar := player.AvatarMap[oldAvatarId]
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)
return
}
activeTeam := player.TeamConfig.GetActiveTeam()
index := -1
for avatarIndex, avatarId := range activeTeam.AvatarIdList {
if avatarId == 0 {
break
}
for avatarIndex, avatarId := range world.GetPlayerAvatarIdList(player) {
if targetAvatarGuid == player.AvatarMap[avatarId].Guid {
index = avatarIndex
}
@@ -42,6 +38,7 @@ func (g *GameManager) ChangeAvatarReq(player *model.Player, payloadMsg pb.Messag
return
}
player.TeamConfig.CurrAvatarIndex = uint8(index)
world.SetPlayerLocalAvatarIndex(player, index)
entity := scene.GetEntity(playerTeamEntity.avatarEntityMap[oldAvatarId])
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)
}
newAvatarId := world.GetPlayerActiveAvatarId(player)
newAvatarEntity := g.PacketSceneEntityInfoAvatar(scene, player, newAvatarId)
sceneEntityAppearNotify := &proto.SceneEntityAppearNotify{
AppearType: proto.VisionType_VISION_TYPE_REPLACE,
Param: playerTeamEntity.avatarEntityMap[oldAvatarId],
EntityList: []*proto.SceneEntityInfo{g.PacketSceneEntityInfoAvatar(scene, player, player.TeamConfig.GetActiveAvatarId())},
EntityList: []*proto.SceneEntityInfo{newAvatarEntity},
}
for _, scenePlayer := range scene.playerMap {
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) {
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)
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
if world.multiplayer {
g.CommonRetError(cmd.SetUpAvatarTeamRsp, player, &proto.SetUpAvatarTeamRsp{})
return
}
teamId := req.TeamId
if teamId <= 0 || teamId >= 5 {
setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{
Retcode: int32(proto.Retcode_RET_SVR_ERROR),
}
g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp)
g.CommonRetError(cmd.SetUpAvatarTeamRsp, player, &proto.SetUpAvatarTeamRsp{})
return
}
avatarGuidList := req.AvatarTeamGuidList
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
selfTeam := teamId == uint32(player.TeamConfig.GetActiveTeamId())
if (selfTeam && len(avatarGuidList) == 0) || len(avatarGuidList) > 4 || world.multiplayer {
setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{
Retcode: int32(proto.Retcode_RET_SVR_ERROR),
}
g.SendMsg(cmd.SetUpAvatarTeamRsp, player.PlayerID, player.ClientSeq, setUpAvatarTeamRsp)
if (selfTeam && len(avatarGuidList) == 0) || len(avatarGuidList) > 4 {
g.CommonRetError(cmd.SetUpAvatarTeamRsp, player, &proto.SetUpAvatarTeamRsp{})
return
}
avatarIdList := make([]uint32, 0)
@@ -104,17 +100,7 @@ func (g *GameManager) SetUpAvatarTeamReq(player *model.Player, payloadMsg pb.Mes
}
}
player.TeamConfig.ClearTeamAvatar(uint8(teamId - 1))
for _, avatarId := range 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
}
player.TeamConfig.SetTeamAvatar(uint8(teamId-1), avatarIdList)
avatarTeamUpdateNotify := &proto.AvatarTeamUpdateNotify{
AvatarTeamMap: make(map[uint32]*proto.AvatarTeam),
@@ -124,10 +110,7 @@ func (g *GameManager) SetUpAvatarTeamReq(player *model.Player, payloadMsg pb.Mes
TeamName: team.Name,
AvatarGuidList: make([]uint64, 0),
}
for _, avatarId := range team.AvatarIdList {
if avatarId == 0 {
break
}
for _, avatarId := range team.GetAvatarIdList() {
avatarTeam.AvatarGuidList = append(avatarTeam.AvatarGuidList, player.AvatarMap[avatarId].Guid)
}
avatarTeamUpdateNotify.AvatarTeamMap[uint32(teamIndex)+1] = avatarTeam
@@ -137,40 +120,27 @@ func (g *GameManager) SetUpAvatarTeamReq(player *model.Player, payloadMsg pb.Mes
if selfTeam {
player.TeamConfig.CurrAvatarIndex = 0
player.TeamConfig.UpdateTeam()
world.SetPlayerLocalAvatarIndex(player, 0)
world.SetPlayerLocalTeam(player, avatarIdList)
world.UpdateMultiplayerTeam()
scene := world.GetSceneById(player.SceneId)
scene.UpdatePlayerTeamEntity(player)
sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world)
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) {
@@ -179,15 +149,19 @@ func (g *GameManager) ChooseCurAvatarTeamReq(player *model.Player, payloadMsg pb
teamId := req.TeamId
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
if world.multiplayer {
g.CommonRetError(cmd.ChooseCurAvatarTeamRsp, player, &proto.ChooseCurAvatarTeamRsp{})
return
}
team := player.TeamConfig.GetTeamByIndex(uint8(teamId) - 1)
if team == nil || len(team.AvatarIdList) == 0 {
if team == nil || len(team.GetAvatarIdList()) == 0 {
return
}
player.TeamConfig.CurrTeamIndex = uint8(teamId) - 1
player.TeamConfig.CurrAvatarIndex = 0
player.TeamConfig.UpdateTeam()
world.SetPlayerLocalAvatarIndex(player, 0)
world.SetPlayerLocalTeam(player, team.GetAvatarIdList())
world.UpdateMultiplayerTeam()
scene := world.GetSceneById(player.SceneId)
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) {
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)
currAvatarGuid := req.CurAvatarGuid
avatarGuidList := req.AvatarGuidList
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
if len(avatarGuidList) == 0 || len(avatarGuidList) > 4 || !world.multiplayer {
changeMpTeamAvatarRsp := &proto.ChangeMpTeamAvatarRsp{
Retcode: int32(proto.Retcode_RET_SVR_ERROR),
}
g.SendMsg(cmd.ChangeMpTeamAvatarRsp, player.PlayerID, player.ClientSeq, changeMpTeamAvatarRsp)
if !world.multiplayer || len(avatarGuidList) == 0 || len(avatarGuidList) > 4 {
g.CommonRetError(cmd.ChangeMpTeamAvatarRsp, player, &proto.ChangeMpTeamAvatarRsp{})
return
}
@@ -221,26 +191,14 @@ func (g *GameManager) ChangeMpTeamAvatarReq(player *model.Player, payloadMsg pb.
avatarIdList = append(avatarIdList, avatarId)
}
world.SetPlayerLocalTeam(player, avatarIdList)
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.SetPlayerLocalAvatarIndex(player, 0)
world.UpdateMultiplayerTeam()
scene := world.GetSceneById(player.SceneId)
scene.UpdatePlayerTeamEntity(player)
for _, worldPlayer := range world.playerMap {
sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotifyMp(world)
sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world)
g.SendMsg(cmd.SceneTeamUpdateNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, sceneTeamUpdateNotify)
}
@@ -259,113 +217,7 @@ func (g *GameManager) PacketSceneTeamUpdateNotify(world *World) *proto.SceneTeam
IsInMp: world.multiplayer,
}
empty := new(proto.AbilitySyncStateInfo)
for _, worldPlayer := range world.playerMap {
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
}
for _, worldTeamAvatar := range world.GetWorldTeamAvatarList() {
worldPlayer := USER_MANAGER.GetOnlineUser(worldTeamAvatar.uid)
worldPlayerScene := world.GetSceneById(worldPlayer.SceneId)
worldPlayerTeamEntity := worldPlayerScene.GetPlayerTeamEntity(worldPlayer.PlayerID)
@@ -420,16 +272,16 @@ func (g *GameManager) PacketSceneTeamUpdateNotifyMp(world *World) *proto.SceneTe
}
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 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 {

View File

@@ -43,7 +43,7 @@ func (w *WorldManager) GetWorldMap() map[uint32]*World {
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())
world := &World{
id: worldId,
@@ -52,7 +52,7 @@ func (w *WorldManager) CreateWorld(owner *model.Player, multiplayer bool) *World
sceneMap: make(map[uint32]*Scene),
entityIdCounter: 0,
worldLevel: 0,
multiplayer: multiplayer,
multiplayer: false,
mpLevelEntityId: 0,
chatMsgList: make([]*proto.ChatInfo, 0),
// aoi划分
@@ -88,38 +88,22 @@ func (w *WorldManager) DestroyWorld(worldId uint32) {
delete(w.worldMap, worldId)
}
// GetBigWorld 获取本服务器的AI世界
func (w *WorldManager) GetBigWorld() *World {
return w.bigWorld
}
// InitBigWorld 初始化世界
// InitBigWorld 初始化AI世界
func (w *WorldManager) InitBigWorld(owner *model.Player) {
w.bigWorld = w.GetWorldByID(owner.WorldId)
w.bigWorld.ChangeToMultiplayer()
}
// WorldTeamAvatar 通用世界队伍角色项
type WorldTeamAvatar struct {
uid uint32
avatarId uint32
func (w *World) IsBigWorld() bool {
return w.owner.PlayerID == 1
}
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 {
id uint32
@@ -144,6 +128,7 @@ func (w *World) GetNextWorldEntityId(entityType uint16) uint32 {
return ret
}
// GetPlayerPeerId 获取当前玩家世界内编号
func (w *World) GetPlayerPeerId(player *model.Player) uint32 {
for peerId, worldPlayer := range w.peerMap {
if worldPlayer.PlayerID == player.PlayerID {
@@ -153,10 +138,12 @@ func (w *World) GetPlayerPeerId(player *model.Player) uint32 {
return 0
}
// GetNextPeerId 获取下一个世界内玩家编号
func (w *World) GetNextPeerId() uint32 {
return uint32(len(w.playerMap) + 1)
}
// GetWorldPlayerNum 获取世界中玩家的数量
func (w *World) GetWorldPlayerNum() int {
return len(w.playerMap)
}
@@ -166,7 +153,14 @@ func (w *World) AddPlayer(player *model.Player, sceneId uint32) {
w.playerMap[player.PlayerID] = player
// 将玩家自身当前的队伍角色信息复制到世界的玩家本地队伍
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()
scene := w.GetSceneById(sceneId)
scene.AddPlayer(player)
@@ -183,17 +177,44 @@ func (w *World) RemovePlayer(player *model.Player) {
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) {
localTeam := make([]*WorldTeamAvatar, 4)
localTeam := make([]*WorldAvatar, 4)
for index := 0; index < 4; index++ {
if index > len(avatarIdList)-1 {
localTeam[index] = &WorldTeamAvatar{
localTeam[index] = &WorldAvatar{
uid: 0,
avatarId: 0,
}
} else {
avatarId := avatarIdList[index]
localTeam[index] = &WorldTeamAvatar{
localTeam[index] = &WorldAvatar{
uid: player.PlayerID,
avatarId: avatarId,
}
@@ -202,12 +223,16 @@ func (w *World) SetPlayerLocalTeam(player *model.Player, avatarIdList []uint32)
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 {
return w.multiplayerTeam.localAvatarIndexMap[player.PlayerID]
}
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
}
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 {
avatarIndex := w.GetPlayerLocalAvatarIndex(player)
localTeam := w.multiplayerTeam.localTeamMap[player.PlayerID]
localTeam := w.GetPlayerLocalTeam(player)
worldTeamAvatar := localTeam[avatarIndex]
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) {
localTeamIndex := 0
for index := start; index <= end; index++ {
player := w.peerMap[peerId]
localTeam := w.multiplayerTeam.localTeamMap[player.PlayerID]
localTeam := w.GetPlayerLocalTeam(player)
w.multiplayerTeam.worldTeam[index] = localTeam[localTeamIndex]
localTeamIndex++
}
@@ -232,7 +280,7 @@ func (w *World) copyLocalTeamToWorld(start int, end int, peerId uint32) {
// UpdateMultiplayerTeam 整合所有玩家的本地队伍计算出世界队伍
func (w *World) UpdateMultiplayerTeam() {
w.multiplayerTeam.worldTeam = make([]*WorldTeamAvatar, 4)
w.multiplayerTeam.worldTeam = make([]*WorldAvatar, 4)
switch w.GetWorldPlayerNum() {
case 1:
// 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 {
scene := &Scene{
id: sceneId,
@@ -281,34 +358,7 @@ func (w *World) GetSceneById(sceneId uint32) *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 {
id uint32
@@ -334,6 +384,8 @@ type GadgetEntity struct {
gatherId uint32
}
// 场景实体数据结构
type Entity struct {
id uint32
scene *Scene
@@ -388,34 +440,9 @@ func (s *Scene) CreatePlayerTeamEntity(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]
for _, avatarId := range team.AvatarIdList {
if avatarId == 0 {
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 {
for _, worldTeamAvatar := range s.world.GetWorldTeamAvatarList() {
if worldTeamAvatar.uid != player.PlayerID {
continue
}
avatar := player.AvatarMap[worldTeamAvatar.avatarId]
@@ -469,7 +496,7 @@ func (s *Scene) CreateEntityAvatar(player *model.Player, avatarId uint32) uint32
},
}
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))
}
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)
case proto.ForwardType_FORWARD_TYPE_ONLY_SERVER:
i.EntryListForwardServer = append(i.EntryListForwardServer, entry)
logger.LOG.Error("fwd server entry: %v", entry)
//logger.LOG.Error("forward server entry: %v", entry)
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 (
DbInsert = iota
DbNormal = iota
DbInsert
DbDelete
DbUpdate
DbNormal
DbOffline
)
const (

View File

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