mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 15:52:27 +08:00
多人世界队伍
This commit is contained in:
@@ -256,7 +256,7 @@ func (u *UserManager) SaveUser() {
|
||||
playerMapTemp[k] = v
|
||||
}
|
||||
u.playerMapLock.RUnlock()
|
||||
logger.LOG.Info("copy user map finish")
|
||||
logger.LOG.Info("copyLocalTeamToWorld user map finish")
|
||||
insertList := make([]*model.Player, 0)
|
||||
deleteList := make([]uint32, 0)
|
||||
updateList := make([]*model.Player, 0)
|
||||
|
||||
@@ -52,7 +52,6 @@ func (g *GameManager) PlayerApplyEnterMpResultReq(player *model.Player, payloadM
|
||||
|
||||
func (g *GameManager) PlayerGetForceQuitBanInfoReq(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.LOG.Debug("user get world exit ban info, uid: %v", player.PlayerID)
|
||||
|
||||
result := true
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
for _, worldPlayer := range world.playerMap {
|
||||
@@ -72,7 +71,6 @@ func (g *GameManager) PlayerGetForceQuitBanInfoReq(player *model.Player, payload
|
||||
|
||||
func (g *GameManager) BackMyWorldReq(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.LOG.Debug("user back world, uid: %v", player.PlayerID)
|
||||
|
||||
// 其他玩家
|
||||
ok := g.UserLeaveWorld(player)
|
||||
|
||||
@@ -87,7 +85,6 @@ func (g *GameManager) BackMyWorldReq(player *model.Player, payloadMsg pb.Message
|
||||
|
||||
func (g *GameManager) ChangeWorldToSingleModeReq(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.LOG.Debug("user change world to single, uid: %v", player.PlayerID)
|
||||
|
||||
// 房主
|
||||
ok := g.UserLeaveWorld(player)
|
||||
|
||||
@@ -103,8 +100,15 @@ func (g *GameManager) ChangeWorldToSingleModeReq(player *model.Player, payloadMs
|
||||
func (g *GameManager) SceneKickPlayerReq(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.LOG.Debug("user kick player, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.SceneKickPlayerReq)
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
if player.PlayerID != world.owner.PlayerID {
|
||||
sceneKickPlayerRsp := &proto.SceneKickPlayerRsp{
|
||||
Retcode: int32(proto.Retcode_RETCODE_RET_SVR_ERROR),
|
||||
}
|
||||
g.SendMsg(cmd.SceneKickPlayerRsp, player.PlayerID, player.ClientSeq, sceneKickPlayerRsp)
|
||||
return
|
||||
}
|
||||
targetUid := req.TargetUid
|
||||
|
||||
targetPlayer := USER_MANAGER.GetOnlineUser(targetUid)
|
||||
ok := g.UserLeaveWorld(targetPlayer)
|
||||
if ok {
|
||||
@@ -112,7 +116,6 @@ func (g *GameManager) SceneKickPlayerReq(player *model.Player, payloadMsg pb.Mes
|
||||
TargetUid: targetUid,
|
||||
KickerUid: player.PlayerID,
|
||||
}
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
for _, worldPlayer := range world.playerMap {
|
||||
g.SendMsg(cmd.SceneKickPlayerNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, sceneKickPlayerNotify)
|
||||
}
|
||||
@@ -130,10 +133,8 @@ func (g *GameManager) SceneKickPlayerReq(player *model.Player, payloadMsg pb.Mes
|
||||
func (g *GameManager) JoinPlayerSceneReq(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.LOG.Debug("user join player scene, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.JoinPlayerSceneReq)
|
||||
|
||||
hostPlayer := USER_MANAGER.GetOnlineUser(req.TargetUid)
|
||||
hostWorld := WORLD_MANAGER.GetWorldByID(hostPlayer.WorldId)
|
||||
|
||||
_, exist := hostWorld.waitEnterPlayerMap[player.PlayerID]
|
||||
if !exist {
|
||||
return
|
||||
@@ -234,8 +235,7 @@ func (g *GameManager) UserDealEnterWorld(hostPlayer *model.Player, otherUid uint
|
||||
if world.multiplayer {
|
||||
return
|
||||
}
|
||||
|
||||
world.ChangeToMP()
|
||||
world.ChangeToMultiplayer()
|
||||
|
||||
worldDataNotify := &proto.WorldDataNotify{
|
||||
WorldPropMap: make(map[uint32]*proto.PropValue),
|
||||
@@ -312,7 +312,6 @@ func (g *GameManager) UserWorldRemovePlayer(world *World, player *model.Player)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scene := world.GetSceneById(player.SceneId)
|
||||
|
||||
// 仅仅把当前的场上角色的实体消失掉
|
||||
@@ -336,11 +335,9 @@ func (g *GameManager) UserWorldRemovePlayer(world *World, player *model.Player)
|
||||
|
||||
world.RemovePlayer(player)
|
||||
player.WorldId = 0
|
||||
|
||||
if world.multiplayer && len(world.playerMap) > 0 {
|
||||
g.UpdateWorldPlayerInfo(world, player)
|
||||
}
|
||||
|
||||
if world.owner.PlayerID == player.PlayerID {
|
||||
// 房主离开销毁世界
|
||||
WORLD_MANAGER.DestroyWorld(world.id)
|
||||
@@ -402,7 +399,7 @@ func (g *GameManager) UpdateWorldPlayerInfo(hostWorld *World, excludePlayer *mod
|
||||
}
|
||||
scenePlayerInfoNotify.PlayerInfoList = append(scenePlayerInfoNotify.PlayerInfoList, &proto.ScenePlayerInfo{
|
||||
Uid: worldPlayer.PlayerID,
|
||||
PeerId: worldPlayer.PeerId,
|
||||
PeerId: hostWorld.GetPlayerPeerId(worldPlayer),
|
||||
Name: worldPlayer.NickName,
|
||||
SceneId: worldPlayer.SceneId,
|
||||
OnlinePlayerInfo: onlinePlayerInfo,
|
||||
@@ -410,7 +407,7 @@ func (g *GameManager) UpdateWorldPlayerInfo(hostWorld *World, excludePlayer *mod
|
||||
}
|
||||
g.SendMsg(cmd.ScenePlayerInfoNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, scenePlayerInfoNotify)
|
||||
|
||||
sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(hostWorld)
|
||||
sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotifyMp(hostWorld)
|
||||
g.SendMsg(cmd.SceneTeamUpdateNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, sceneTeamUpdateNotify)
|
||||
|
||||
syncTeamEntityNotify := &proto.SyncTeamEntityNotify{
|
||||
@@ -426,7 +423,7 @@ func (g *GameManager) UpdateWorldPlayerInfo(hostWorld *World, excludePlayer *mod
|
||||
worldPlayerTeamEntity := worldPlayerScene.GetPlayerTeamEntity(worldPlayer.PlayerID)
|
||||
teamEntityInfo := &proto.TeamEntityInfo{
|
||||
TeamEntityId: worldPlayerTeamEntity.teamEntityId,
|
||||
AuthorityPeerId: worldPlayer.PeerId,
|
||||
AuthorityPeerId: hostWorld.GetPlayerPeerId(worldPlayer),
|
||||
TeamAbilityInfo: new(proto.AbilitySyncStateInfo),
|
||||
}
|
||||
syncTeamEntityNotify.TeamEntityInfoList = append(syncTeamEntityNotify.TeamEntityInfoList, teamEntityInfo)
|
||||
|
||||
@@ -22,8 +22,8 @@ func (g *GameManager) EnterSceneReadyReq(player *model.Player, payloadMsg pb.Mes
|
||||
|
||||
enterScenePeerNotify := &proto.EnterScenePeerNotify{
|
||||
DestSceneId: player.SceneId,
|
||||
PeerId: player.PeerId,
|
||||
HostPeerId: world.owner.PeerId,
|
||||
PeerId: world.GetPlayerPeerId(player),
|
||||
HostPeerId: world.GetPlayerPeerId(world.owner),
|
||||
EnterSceneToken: player.EnterSceneToken,
|
||||
}
|
||||
g.SendMsg(cmd.EnterScenePeerNotify, player.PlayerID, player.ClientSeq, enterScenePeerNotify)
|
||||
@@ -99,7 +99,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
|
||||
|
||||
hostPlayerNotify := &proto.HostPlayerNotify{
|
||||
HostUid: world.owner.PlayerID,
|
||||
HostPeerId: world.owner.PeerId,
|
||||
HostPeerId: world.GetPlayerPeerId(world.owner),
|
||||
}
|
||||
g.SendMsg(cmd.HostPlayerNotify, player.PlayerID, player.ClientSeq, hostPlayerNotify)
|
||||
|
||||
@@ -174,7 +174,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
|
||||
}
|
||||
scenePlayerInfoNotify.PlayerInfoList = append(scenePlayerInfoNotify.PlayerInfoList, &proto.ScenePlayerInfo{
|
||||
Uid: worldPlayer.PlayerID,
|
||||
PeerId: worldPlayer.PeerId,
|
||||
PeerId: world.GetPlayerPeerId(worldPlayer),
|
||||
Name: worldPlayer.NickName,
|
||||
SceneId: worldPlayer.SceneId,
|
||||
OnlinePlayerInfo: onlinePlayerInfo,
|
||||
@@ -182,7 +182,12 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
|
||||
}
|
||||
g.SendMsg(cmd.ScenePlayerInfoNotify, player.PlayerID, player.ClientSeq, scenePlayerInfoNotify)
|
||||
|
||||
sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world)
|
||||
var sceneTeamUpdateNotify *proto.SceneTeamUpdateNotify = nil
|
||||
if world.multiplayer {
|
||||
sceneTeamUpdateNotify = g.PacketSceneTeamUpdateNotifyMp(world)
|
||||
} else {
|
||||
sceneTeamUpdateNotify = g.PacketSceneTeamUpdateNotify(world)
|
||||
}
|
||||
g.SendMsg(cmd.SceneTeamUpdateNotify, player.PlayerID, player.ClientSeq, sceneTeamUpdateNotify)
|
||||
|
||||
syncTeamEntityNotify := &proto.SyncTeamEntityNotify{
|
||||
@@ -198,7 +203,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
|
||||
worldPlayerTeamEntity := worldPlayerScene.GetPlayerTeamEntity(worldPlayer.PlayerID)
|
||||
teamEntityInfo := &proto.TeamEntityInfo{
|
||||
TeamEntityId: worldPlayerTeamEntity.teamEntityId,
|
||||
AuthorityPeerId: worldPlayer.PeerId,
|
||||
AuthorityPeerId: world.GetPlayerPeerId(worldPlayer),
|
||||
TeamAbilityInfo: new(proto.AbilitySyncStateInfo),
|
||||
}
|
||||
syncTeamEntityNotify.TeamEntityInfoList = append(syncTeamEntityNotify.TeamEntityInfoList, teamEntityInfo)
|
||||
@@ -679,11 +684,12 @@ func (g *GameManager) PacketSceneAvatarInfo(scene *Scene, player *model.Player,
|
||||
for _, reliquary := range player.AvatarMap[avatarId].EquipReliquaryList {
|
||||
equipIdList = append(equipIdList, reliquary.ItemId)
|
||||
}
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
sceneAvatarInfo := &proto.SceneAvatarInfo{
|
||||
Uid: player.PlayerID,
|
||||
AvatarId: avatarId,
|
||||
Guid: player.AvatarMap[avatarId].Guid,
|
||||
PeerId: player.PeerId,
|
||||
PeerId: world.GetPlayerPeerId(player),
|
||||
EquipIdList: equipIdList,
|
||||
SkillDepotId: player.AvatarMap[avatarId].SkillDepotId,
|
||||
Weapon: &proto.SceneWeaponInfo{
|
||||
|
||||
@@ -87,9 +87,8 @@ func (g *GameManager) SetUpAvatarTeamReq(player *model.Player, payloadMsg pb.Mes
|
||||
}
|
||||
avatarGuidList := req.AvatarTeamGuidList
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
multiTeam := teamId == 4
|
||||
selfTeam := teamId == uint32(player.TeamConfig.GetActiveTeamId())
|
||||
if (multiTeam && len(avatarGuidList) == 0) || (selfTeam && len(avatarGuidList) == 0) || len(avatarGuidList) > 4 || world.multiplayer {
|
||||
if (selfTeam && len(avatarGuidList) == 0) || len(avatarGuidList) > 4 || world.multiplayer {
|
||||
setUpAvatarTeamRsp := &proto.SetUpAvatarTeamRsp{
|
||||
Retcode: int32(proto.Retcode_RETCODE_RET_SVR_ERROR),
|
||||
}
|
||||
@@ -204,6 +203,7 @@ 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)
|
||||
req := payloadMsg.(*proto.ChangeMpTeamAvatarReq)
|
||||
currAvatarGuid := req.CurAvatarGuid
|
||||
avatarGuidList := req.AvatarGuidList
|
||||
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
@@ -214,38 +214,42 @@ func (g *GameManager) ChangeMpTeamAvatarReq(player *model.Player, payloadMsg pb.
|
||||
g.SendMsg(cmd.ChangeMpTeamAvatarRsp, player.PlayerID, player.ClientSeq, changeMpTeamAvatarRsp)
|
||||
return
|
||||
}
|
||||
|
||||
avatarIdList := make([]uint32, 0)
|
||||
for _, avatarGuid := range avatarGuidList {
|
||||
for avatarId, avatar := range player.AvatarMap {
|
||||
if avatarGuid == avatar.Guid {
|
||||
avatarIdList = append(avatarIdList, avatarId)
|
||||
}
|
||||
avatarId := player.GetAvatarIdByGuid(avatarGuid)
|
||||
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
|
||||
}
|
||||
}
|
||||
player.TeamConfig.ClearTeamAvatar(3)
|
||||
for _, avatarId := range avatarIdList {
|
||||
player.TeamConfig.AddAvatarToTeam(avatarId, 3)
|
||||
}
|
||||
player.TeamConfig.CurrAvatarIndex = 0
|
||||
player.TeamConfig.UpdateTeam()
|
||||
world.SetPlayerLocalAvatarIndex(player, avatarIndex)
|
||||
|
||||
world.UpdateMultiplayerTeam()
|
||||
scene := world.GetSceneById(player.SceneId)
|
||||
scene.UpdatePlayerTeamEntity(player)
|
||||
|
||||
for _, worldPlayer := range world.playerMap {
|
||||
sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotify(world)
|
||||
sceneTeamUpdateNotify := g.PacketSceneTeamUpdateNotifyMp(world)
|
||||
g.SendMsg(cmd.SceneTeamUpdateNotify, worldPlayer.PlayerID, worldPlayer.ClientSeq, sceneTeamUpdateNotify)
|
||||
}
|
||||
|
||||
avatarId := world.GetPlayerActiveAvatarId(player)
|
||||
avatar := player.AvatarMap[avatarId]
|
||||
|
||||
changeMpTeamAvatarRsp := &proto.ChangeMpTeamAvatarRsp{
|
||||
CurAvatarGuid: player.AvatarMap[player.TeamConfig.GetActiveAvatarId()].Guid,
|
||||
AvatarGuidList: make([]uint64, 0),
|
||||
}
|
||||
team := player.TeamConfig.GetTeamByIndex(3)
|
||||
for _, avatarId := range team.AvatarIdList {
|
||||
if avatarId == 0 {
|
||||
break
|
||||
}
|
||||
changeMpTeamAvatarRsp.AvatarGuidList = append(changeMpTeamAvatarRsp.AvatarGuidList, player.AvatarMap[avatarId].Guid)
|
||||
CurAvatarGuid: avatar.Guid,
|
||||
AvatarGuidList: req.AvatarGuidList,
|
||||
}
|
||||
g.SendMsg(cmd.ChangeMpTeamAvatarRsp, player.PlayerID, player.ClientSeq, changeMpTeamAvatarRsp)
|
||||
}
|
||||
@@ -352,3 +356,104 @@ func (g *GameManager) PacketSceneTeamUpdateNotify(world *World) *proto.SceneTeam
|
||||
}
|
||||
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)
|
||||
worldPlayerScene := world.GetSceneById(worldPlayer.SceneId)
|
||||
worldPlayerTeamEntity := worldPlayerScene.GetPlayerTeamEntity(worldPlayer.PlayerID)
|
||||
worldPlayerAvatar := worldPlayer.AvatarMap[worldTeamAvatar.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[worldTeamAvatar.avatarId],
|
||||
SceneEntityInfo: g.PacketSceneEntityInfoAvatar(worldPlayerScene, worldPlayer, worldTeamAvatar.avatarId),
|
||||
WeaponGuid: worldPlayerAvatar.EquipWeapon.Guid,
|
||||
WeaponEntityId: worldPlayerTeamEntity.weaponEntityMap[worldPlayerAvatar.EquipWeapon.WeaponId],
|
||||
IsPlayerCurAvatar: world.GetPlayerActiveAvatarId(worldPlayer) == worldTeamAvatar.avatarId,
|
||||
IsOnScene: world.GetPlayerActiveAvatarId(worldPlayer) == worldTeamAvatar.avatarId,
|
||||
AvatarAbilityInfo: empty,
|
||||
WeaponAbilityInfo: empty,
|
||||
AbilityControlBlock: new(proto.AbilityControlBlock),
|
||||
}
|
||||
if world.multiplayer {
|
||||
sceneTeamAvatar.AvatarInfo = g.PacketAvatarInfo(worldPlayerAvatar)
|
||||
sceneTeamAvatar.SceneAvatarInfo = g.PacketSceneAvatarInfo(worldPlayerScene, worldPlayer, worldTeamAvatar.avatarId)
|
||||
}
|
||||
// add AbilityControlBlock
|
||||
avatarDataConfig := gdc.CONF.AvatarDataMap[int32(worldTeamAvatar.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
|
||||
}
|
||||
|
||||
@@ -64,6 +64,8 @@ func (w *WorldManager) CreateWorld(owner *model.Player, multiplayer bool) *World
|
||||
),
|
||||
playerFirstEnterMap: make(map[uint32]int64),
|
||||
waitEnterPlayerMap: make(map[uint32]int64),
|
||||
multiplayerTeam: CreateMultiplayerTeam(),
|
||||
peerMap: make(map[uint32]*model.Player),
|
||||
}
|
||||
if world.IsBigWorld() {
|
||||
world.aoiManager = aoi.NewAoiManager(
|
||||
@@ -90,9 +92,33 @@ func (w *WorldManager) GetBigWorld() *World {
|
||||
return w.bigWorld
|
||||
}
|
||||
|
||||
// InitBigWorld 初始化大世界
|
||||
func (w *WorldManager) InitBigWorld(owner *model.Player) {
|
||||
w.bigWorld = w.GetWorldByID(owner.WorldId)
|
||||
w.bigWorld.multiplayer = true
|
||||
w.bigWorld.ChangeToMultiplayer()
|
||||
}
|
||||
|
||||
// WorldTeamAvatar 通用世界队伍角色项
|
||||
type WorldTeamAvatar struct {
|
||||
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 {
|
||||
@@ -100,14 +126,16 @@ type World struct {
|
||||
owner *model.Player
|
||||
playerMap map[uint32]*model.Player
|
||||
sceneMap map[uint32]*Scene
|
||||
entityIdCounter uint32
|
||||
worldLevel uint8
|
||||
multiplayer bool
|
||||
entityIdCounter uint32 // 世界的实体id生成计数器
|
||||
worldLevel uint8 // 世界等级
|
||||
multiplayer bool // 是否多人世界
|
||||
mpLevelEntityId uint32
|
||||
chatMsgList []*proto.ChatInfo
|
||||
aoiManager *aoi.AoiManager // 当前世界地图的aoi管理器
|
||||
playerFirstEnterMap map[uint32]int64
|
||||
waitEnterPlayerMap map[uint32]int64
|
||||
chatMsgList []*proto.ChatInfo // 世界聊天消息列表
|
||||
aoiManager *aoi.AoiManager // 当前世界地图的aoi管理器
|
||||
playerFirstEnterMap map[uint32]int64 // 玩家第一次进入世界的时间 key:uid value:进入时间
|
||||
waitEnterPlayerMap map[uint32]int64 // 等待进入世界的列表 key:uid value:开始时间
|
||||
multiplayerTeam *MultiplayerTeam
|
||||
peerMap map[uint32]*model.Player // key:玩家编号 value:player对象
|
||||
}
|
||||
|
||||
func (w *World) GetNextWorldEntityId(entityType uint16) uint32 {
|
||||
@@ -116,18 +144,117 @@ func (w *World) GetNextWorldEntityId(entityType uint16) uint32 {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (w *World) GetPlayerPeerId(player *model.Player) uint32 {
|
||||
for peerId, worldPlayer := range w.peerMap {
|
||||
if worldPlayer.PlayerID == player.PlayerID {
|
||||
return peerId
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (w *World) GetNextPeerId() uint32 {
|
||||
return uint32(len(w.playerMap) + 1)
|
||||
}
|
||||
|
||||
func (w *World) GetWorldPlayerNum() int {
|
||||
return len(w.playerMap)
|
||||
}
|
||||
|
||||
func (w *World) AddPlayer(player *model.Player, sceneId uint32) {
|
||||
player.PeerId = uint32(len(w.playerMap) + 1)
|
||||
w.peerMap[w.GetNextPeerId()] = player
|
||||
w.playerMap[player.PlayerID] = player
|
||||
// 将玩家自身当前的队伍角色信息复制到世界的玩家本地队伍
|
||||
team := player.TeamConfig.GetActiveTeam()
|
||||
w.SetPlayerLocalTeam(player, team.AvatarIdList)
|
||||
w.UpdateMultiplayerTeam()
|
||||
scene := w.GetSceneById(sceneId)
|
||||
scene.AddPlayer(player)
|
||||
}
|
||||
|
||||
func (w *World) RemovePlayer(player *model.Player) {
|
||||
delete(w.peerMap, w.GetPlayerPeerId(player))
|
||||
scene := w.sceneMap[player.SceneId]
|
||||
scene.RemovePlayer(player)
|
||||
delete(w.playerMap, player.PlayerID)
|
||||
delete(w.playerFirstEnterMap, player.PlayerID)
|
||||
delete(w.multiplayerTeam.localTeamMap, player.PlayerID)
|
||||
delete(w.multiplayerTeam.localAvatarIndexMap, player.PlayerID)
|
||||
w.UpdateMultiplayerTeam()
|
||||
}
|
||||
|
||||
func (w *World) SetPlayerLocalTeam(player *model.Player, avatarIdList []uint32) {
|
||||
localTeam := make([]*WorldTeamAvatar, 4)
|
||||
for index := 0; index < 4; index++ {
|
||||
if index > len(avatarIdList)-1 {
|
||||
localTeam[index] = &WorldTeamAvatar{
|
||||
uid: 0,
|
||||
avatarId: 0,
|
||||
}
|
||||
} else {
|
||||
avatarId := avatarIdList[index]
|
||||
localTeam[index] = &WorldTeamAvatar{
|
||||
uid: player.PlayerID,
|
||||
avatarId: avatarId,
|
||||
}
|
||||
}
|
||||
}
|
||||
w.multiplayerTeam.localTeamMap[player.PlayerID] = localTeam
|
||||
}
|
||||
|
||||
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 {
|
||||
return
|
||||
}
|
||||
w.multiplayerTeam.localAvatarIndexMap[player.PlayerID] = index
|
||||
}
|
||||
|
||||
func (w *World) GetPlayerActiveAvatarId(player *model.Player) uint32 {
|
||||
avatarIndex := w.GetPlayerLocalAvatarIndex(player)
|
||||
localTeam := w.multiplayerTeam.localTeamMap[player.PlayerID]
|
||||
worldTeamAvatar := localTeam[avatarIndex]
|
||||
return worldTeamAvatar.avatarId
|
||||
}
|
||||
|
||||
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]
|
||||
w.multiplayerTeam.worldTeam[index] = localTeam[localTeamIndex]
|
||||
localTeamIndex++
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateMultiplayerTeam 整合所有玩家的本地队伍计算出世界队伍
|
||||
func (w *World) UpdateMultiplayerTeam() {
|
||||
w.multiplayerTeam.worldTeam = make([]*WorldTeamAvatar, 4)
|
||||
switch w.GetWorldPlayerNum() {
|
||||
case 1:
|
||||
// 1P*4
|
||||
w.copyLocalTeamToWorld(0, 3, 1)
|
||||
case 2:
|
||||
// 1P*2 + 2P*2
|
||||
w.copyLocalTeamToWorld(0, 1, 1)
|
||||
w.copyLocalTeamToWorld(2, 3, 2)
|
||||
case 3:
|
||||
// 1P*2 + 2P*1 + 3P*1
|
||||
w.copyLocalTeamToWorld(0, 1, 1)
|
||||
w.copyLocalTeamToWorld(2, 2, 2)
|
||||
w.copyLocalTeamToWorld(3, 3, 3)
|
||||
case 4:
|
||||
// 1P*1 + 2P*1 + 3P*1 + 4P*1
|
||||
w.copyLocalTeamToWorld(0, 0, 1)
|
||||
w.copyLocalTeamToWorld(1, 1, 2)
|
||||
w.copyLocalTeamToWorld(2, 2, 3)
|
||||
w.copyLocalTeamToWorld(3, 3, 4)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func (w *World) CreateScene(sceneId uint32) *Scene {
|
||||
@@ -166,7 +293,7 @@ func (w *World) IsBigWorld() bool {
|
||||
return w.owner.PlayerID == 1
|
||||
}
|
||||
|
||||
func (w *World) ChangeToMP() {
|
||||
func (w *World) ChangeToMultiplayer() {
|
||||
w.multiplayer = true
|
||||
}
|
||||
|
||||
@@ -189,10 +316,10 @@ type Scene struct {
|
||||
playerMap map[uint32]*model.Player
|
||||
entityMap map[uint32]*Entity
|
||||
playerTeamEntityMap map[uint32]*PlayerTeamEntity
|
||||
gameTime uint32
|
||||
gameTime uint32 // 游戏内提瓦特大陆的时间
|
||||
attackQueue *alg.RAQueue[*Attack]
|
||||
createTime int64
|
||||
meeoIndex uint32
|
||||
meeoIndex uint32 // 客户端风元素染色同步协议的计数器
|
||||
}
|
||||
|
||||
type AvatarEntity struct {
|
||||
@@ -261,6 +388,10 @@ 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 {
|
||||
@@ -281,6 +412,26 @@ func (s *Scene) UpdatePlayerTeamEntity(player *model.Player) {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
avatar := player.AvatarMap[worldTeamAvatar.avatarId]
|
||||
avatarEntityId, exist := playerTeamEntity.avatarEntityMap[worldTeamAvatar.avatarId]
|
||||
if exist {
|
||||
s.DestroyEntity(avatarEntityId)
|
||||
}
|
||||
playerTeamEntity.avatarEntityMap[worldTeamAvatar.avatarId] = s.CreateEntityAvatar(player, worldTeamAvatar.avatarId)
|
||||
weaponEntityId, exist := playerTeamEntity.weaponEntityMap[avatar.EquipWeapon.WeaponId]
|
||||
if exist {
|
||||
s.DestroyEntity(weaponEntityId)
|
||||
}
|
||||
playerTeamEntity.weaponEntityMap[avatar.EquipWeapon.WeaponId] = s.CreateEntityWeapon()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Scene) AddPlayer(player *model.Player) {
|
||||
s.playerMap[player.PlayerID] = player
|
||||
s.CreatePlayerTeamEntity(player)
|
||||
|
||||
@@ -75,6 +75,15 @@ func (p *Player) InitAvatar(avatar *Avatar) {
|
||||
return
|
||||
}
|
||||
|
||||
func (p *Player) GetAvatarIdByGuid(guid uint64) uint32 {
|
||||
for avatarId, avatar := range p.AvatarMap {
|
||||
if guid == avatar.Guid {
|
||||
return avatarId
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (p *Player) AddAvatar(avatarId uint32) {
|
||||
avatarDataConfig, ok := gdc.CONF.AvatarDataMap[int32(avatarId)]
|
||||
if !ok {
|
||||
|
||||
@@ -56,7 +56,6 @@ type Player struct {
|
||||
EnterSceneToken uint32 `bson:"-"` // 玩家的世界进入令牌
|
||||
DbState int `bson:"-"` // 数据库存档状态
|
||||
WorldId uint32 `bson:"-"` // 所在的世界id
|
||||
PeerId uint32 `bson:"-"` // 多人世界的玩家编号
|
||||
GameObjectGuidCounter uint64 `bson:"-"` // 游戏对象guid计数器
|
||||
ClientTime uint32 `bson:"-"` // 玩家客户端的本地时钟
|
||||
ClientRTT uint32 `bson:"-"` // 玩家客户端往返时延
|
||||
|
||||
Reference in New Issue
Block a user