溺水安全位置完善 载具地图显示

This commit is contained in:
UnKownOwO
2022-12-21 18:57:06 +08:00
parent c4bc4b8ca1
commit 998c388306
7 changed files with 120 additions and 85 deletions

View File

@@ -143,39 +143,39 @@ func (t *TickManager) onTick5Second(now int64) {
} }
} }
for _, player := range world.playerMap { for _, player := range world.playerMap {
if world.multiplayer { // 多人世界其他玩家的坐标位置广播
scene := world.GetSceneById(player.SceneId) worldPlayerLocationNotify := &proto.WorldPlayerLocationNotify{
PlayerWorldLocList: make([]*proto.PlayerWorldLocationInfo, 0),
// 多人世界其他玩家的坐标位置广播 }
worldPlayerLocationNotify := &proto.WorldPlayerLocationNotify{ for _, worldPlayer := range world.playerMap {
PlayerWorldLocList: make([]*proto.PlayerWorldLocationInfo, 0), playerWorldLocationInfo := &proto.PlayerWorldLocationInfo{
} SceneId: worldPlayer.SceneId,
for _, worldPlayer := range world.playerMap { PlayerLoc: &proto.PlayerLocationInfo{
playerWorldLocationInfo := &proto.PlayerWorldLocationInfo{ Uid: worldPlayer.PlayerID,
SceneId: worldPlayer.SceneId, Pos: &proto.Vector{
PlayerLoc: &proto.PlayerLocationInfo{ X: float32(worldPlayer.Pos.X),
Uid: worldPlayer.PlayerID, Y: float32(worldPlayer.Pos.Y),
Pos: &proto.Vector{ Z: float32(worldPlayer.Pos.Z),
X: float32(worldPlayer.Pos.X),
Y: float32(worldPlayer.Pos.Y),
Z: float32(worldPlayer.Pos.Z),
},
Rot: &proto.Vector{
X: float32(worldPlayer.Rot.X),
Y: float32(worldPlayer.Rot.Y),
Z: float32(worldPlayer.Rot.Z),
},
}, },
} Rot: &proto.Vector{
worldPlayerLocationNotify.PlayerWorldLocList = append(worldPlayerLocationNotify.PlayerWorldLocList, playerWorldLocationInfo) X: float32(worldPlayer.Rot.X),
Y: float32(worldPlayer.Rot.Y),
Z: float32(worldPlayer.Rot.Z),
},
},
} }
GAME_MANAGER.SendMsg(cmd.WorldPlayerLocationNotify, player.PlayerID, 0, worldPlayerLocationNotify) worldPlayerLocationNotify.PlayerWorldLocList = append(worldPlayerLocationNotify.PlayerWorldLocList, playerWorldLocationInfo)
}
GAME_MANAGER.SendMsg(cmd.WorldPlayerLocationNotify, player.PlayerID, 0, worldPlayerLocationNotify)
for _, scene := range world.sceneMap {
scenePlayerLocationNotify := &proto.ScenePlayerLocationNotify{ scenePlayerLocationNotify := &proto.ScenePlayerLocationNotify{
SceneId: player.SceneId, SceneId: scene.id,
PlayerLocList: make([]*proto.PlayerLocationInfo, 0), PlayerLocList: make([]*proto.PlayerLocationInfo, 0),
VehicleLocList: make([]*proto.VehicleLocationInfo, 0),
} }
for _, scenePlayer := range scene.playerMap { for _, scenePlayer := range scene.playerMap {
// 玩家位置
playerLocationInfo := &proto.PlayerLocationInfo{ playerLocationInfo := &proto.PlayerLocationInfo{
Uid: scenePlayer.PlayerID, Uid: scenePlayer.PlayerID,
Pos: &proto.Vector{ Pos: &proto.Vector{
@@ -190,6 +190,35 @@ func (t *TickManager) onTick5Second(now int64) {
}, },
} }
scenePlayerLocationNotify.PlayerLocList = append(scenePlayerLocationNotify.PlayerLocList, playerLocationInfo) scenePlayerLocationNotify.PlayerLocList = append(scenePlayerLocationNotify.PlayerLocList, playerLocationInfo)
// 载具位置
for _, entityId := range scenePlayer.VehicleInfo.LastCreateEntityIdMap {
entity := scene.GetEntity(entityId)
// 确保实体类型是否为载具
if entity != nil && entity.gadgetEntity != nil && entity.gadgetEntity.gadgetVehicleEntity != nil {
vehicleLocationInfo := &proto.VehicleLocationInfo{
Rot: &proto.Vector{
X: float32(entity.rot.X),
Y: float32(entity.rot.Y),
Z: float32(entity.rot.Z),
},
EntityId: entity.id,
CurHp: entity.fightProp[uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_HP)],
OwnerUid: entity.gadgetEntity.gadgetVehicleEntity.owner.PlayerID,
Pos: &proto.Vector{
X: float32(entity.pos.X),
Y: float32(entity.pos.Y),
Z: float32(entity.pos.Z),
},
UidList: make([]uint32, 0, len(entity.gadgetEntity.gadgetVehicleEntity.memberMap)),
GadgetId: entity.gadgetEntity.gadgetVehicleEntity.vehicleId,
MaxHp: entity.fightProp[uint32(constant.FightPropertyConst.FIGHT_PROP_MAX_HP)],
}
for _, p := range entity.gadgetEntity.gadgetVehicleEntity.memberMap {
vehicleLocationInfo.UidList = append(vehicleLocationInfo.UidList, p.PlayerID)
}
scenePlayerLocationNotify.VehicleLocList = append(scenePlayerLocationNotify.VehicleLocList, vehicleLocationInfo)
}
}
} }
GAME_MANAGER.SendMsg(cmd.ScenePlayerLocationNotify, player.PlayerID, 0, scenePlayerLocationNotify) GAME_MANAGER.SendMsg(cmd.ScenePlayerLocationNotify, player.PlayerID, 0, scenePlayerLocationNotify)
} }
@@ -209,20 +238,31 @@ func (t *TickManager) onTickSecond(now int64) {
worldPlayerRTTNotify.PlayerRttList = append(worldPlayerRTTNotify.PlayerRttList, playerRTTInfo) worldPlayerRTTNotify.PlayerRttList = append(worldPlayerRTTNotify.PlayerRttList, playerRTTInfo)
} }
GAME_MANAGER.SendMsg(cmd.WorldPlayerRTTNotify, player.PlayerID, 0, worldPlayerRTTNotify) GAME_MANAGER.SendMsg(cmd.WorldPlayerRTTNotify, player.PlayerID, 0, worldPlayerRTTNotify)
// 玩家安全位置更新
switch player.StaminaInfo.State {
case proto.MotionState_MOTION_STATE_DANGER_RUN, proto.MotionState_MOTION_STATE_RUN,
proto.MotionState_MOTION_STATE_DANGER_STANDBY_MOVE, proto.MotionState_MOTION_STATE_DANGER_STANDBY, proto.MotionState_MOTION_STATE_LADDER_TO_STANDBY, proto.MotionState_MOTION_STATE_STANDBY_MOVE, proto.MotionState_MOTION_STATE_STANDBY,
proto.MotionState_MOTION_STATE_DANGER_WALK, proto.MotionState_MOTION_STATE_WALK,
proto.MotionState_MOTION_STATE_DASH:
// 仅在陆地时更新玩家安全位置
player.SafePos.X = player.Pos.X
player.SafePos.Y = player.Pos.Y
player.SafePos.Z = player.Pos.Z
}
}
if !world.IsBigWorld() && world.owner.SceneLoadState == model.SceneEnterDone {
// 刷怪 // 刷怪
if !world.IsBigWorld() && world.owner.SceneLoadState == model.SceneEnterDone { scene := world.GetSceneById(3)
scene := world.GetSceneById(3) monsterEntityCount := 0
monsterEntityCount := 0 for _, entity := range scene.entityMap {
for _, entity := range scene.entityMap { if entity.entityType == uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_MONSTER) {
if entity.entityType == uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_MONSTER) { monsterEntityCount++
monsterEntityCount++
}
}
if monsterEntityCount < 30 {
monsterEntityId := t.createMonster(world.owner, scene)
GAME_MANAGER.AddSceneEntityNotify(world.owner, proto.VisionType_VISION_TYPE_BORN, []uint32{monsterEntityId}, true, false)
} }
} }
if monsterEntityCount < 30 {
monsterEntityId := t.createMonster(scene)
GAME_MANAGER.AddSceneEntityNotify(world.owner, proto.VisionType_VISION_TYPE_BORN, []uint32{monsterEntityId}, true, false)
}
} }
} }
} }
@@ -241,7 +281,7 @@ func (t *TickManager) onTick200MilliSecond(now int64) {
func (t *TickManager) onTick100MilliSecond(now int64) { func (t *TickManager) onTick100MilliSecond(now int64) {
} }
func (t *TickManager) createMonster(player *model.Player, scene *Scene) uint32 { func (t *TickManager) createMonster(scene *Scene) uint32 {
pos := &model.Vector{ pos := &model.Vector{
X: 2747, X: 2747,
Y: 194, Y: 194,

View File

@@ -119,23 +119,12 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
if sceneEntity.avatarEntity != nil { if sceneEntity.avatarEntity != nil {
// 玩家实体在移动 // 玩家实体在移动
// 更新玩家的位置信息 // 更新玩家的位置信息
switch player.StaminaInfo.State { player.Pos.X = float64(motionInfo.Pos.X)
case proto.MotionState_MOTION_STATE_DANGER_RUN, proto.MotionState_MOTION_STATE_RUN, player.Pos.Y = float64(motionInfo.Pos.Y)
proto.MotionState_MOTION_STATE_DANGER_STANDBY_MOVE, proto.MotionState_MOTION_STATE_DANGER_STANDBY, proto.MotionState_MOTION_STATE_LADDER_TO_STANDBY, proto.MotionState_MOTION_STATE_STANDBY_MOVE, proto.MotionState_MOTION_STATE_STANDBY, player.Pos.Z = float64(motionInfo.Pos.Z)
proto.MotionState_MOTION_STATE_DANGER_WALK, proto.MotionState_MOTION_STATE_WALK, player.Rot.X = float64(motionInfo.Rot.X)
proto.MotionState_MOTION_STATE_DASH: player.Rot.Y = float64(motionInfo.Rot.Y)
// 仅在陆地时更新玩家位置 player.Rot.Z = float64(motionInfo.Rot.Z)
player.Pos.X = float64(motionInfo.Pos.X)
player.Pos.Y = float64(motionInfo.Pos.Y)
player.Pos.Z = float64(motionInfo.Pos.Z)
player.Rot.X = float64(motionInfo.Rot.X)
player.Rot.Y = float64(motionInfo.Rot.Y)
player.Rot.Z = float64(motionInfo.Rot.Z)
default:
player.StaminaInfo.ActiveAvatarPos.X = float64(motionInfo.Pos.X)
player.StaminaInfo.ActiveAvatarPos.Y = float64(motionInfo.Pos.Y)
player.StaminaInfo.ActiveAvatarPos.Z = float64(motionInfo.Pos.Z)
}
// 处理耐力消耗 // 处理耐力消耗
g.ImmediateStamina(player, motionInfo.State) g.ImmediateStamina(player, motionInfo.State)

View File

@@ -47,6 +47,12 @@ func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq u
// 初始化 // 初始化
player.InitAll() player.InitAll()
// player.TeamConfig.UpdateTeam() // player.TeamConfig.UpdateTeam()
// 确保玩家位置安全
player.Pos.X = player.SafePos.X
player.Pos.Y = player.SafePos.Y
player.Pos.Z = player.SafePos.Z
// 创建世界 // 创建世界
world := WORLD_MANAGER.CreateWorld(player) world := WORLD_MANAGER.CreateWorld(player)
world.AddPlayer(player, player.SceneId) world.AddPlayer(player, player.SceneId)
@@ -374,6 +380,7 @@ func (g *GameManager) CreatePlayer(userId uint32, nickName string, mainCharAvata
player.CostumeList = append(player.CostumeList, 201601) player.CostumeList = append(player.CostumeList, 201601)
player.CostumeList = append(player.CostumeList, 203101) player.CostumeList = append(player.CostumeList, 203101)
player.SafePos = &model.Vector{X: 2747, Y: 194, Z: -1719}
player.Pos = &model.Vector{X: 2747, Y: 194, Z: -1719} player.Pos = &model.Vector{X: 2747, Y: 194, Z: -1719}
player.Rot = &model.Vector{X: 0, Y: 307, Z: 0} player.Rot = &model.Vector{X: 0, Y: 307, Z: 0}

View File

@@ -4,8 +4,6 @@ import (
"strings" "strings"
"time" "time"
gdc "hk4e/gs/config"
"hk4e/gdconf" "hk4e/gdconf"
"hk4e/gs/constant" "hk4e/gs/constant"
"hk4e/gs/model" "hk4e/gs/model"
@@ -438,11 +436,12 @@ func (g *GameManager) DrownBackHandler(player *model.Player) {
return return
} }
// TODO // TODO 耐力未完成的内容:
// 溺水安全点可能需要读取附近锚点坐标 // 一直溺水回到距离最近的位置 ?
// 多次溺水后提示溺水的死亡信息 // 溺水队伍扣血
// 官服 游戏离线也会回到安全位置 // 队伍都没血了显示死亡界面
// 很显然目前这个很不完善 // 技能耐力消耗配置表
// 食物影响消耗的耐力
// 先传送玩家再设置角色存活否则同时设置会传送前显示角色实体 // 先传送玩家再设置角色存活否则同时设置会传送前显示角色实体
if player.StaminaInfo.DrownBackDelay > 20 && player.SceneLoadState == model.SceneEnterDone { if player.StaminaInfo.DrownBackDelay > 20 && player.SceneLoadState == model.SceneEnterDone {
@@ -457,26 +456,26 @@ func (g *GameManager) DrownBackHandler(player *model.Player) {
g.SetPlayerStamina(player, maxStamina/2) g.SetPlayerStamina(player, maxStamina/2)
// 如果玩家的位置比锚点距离近则优先使用玩家位置 // 如果玩家的位置比锚点距离近则优先使用玩家位置
pos := &model.Vector{ pos := &model.Vector{
X: player.Pos.X, X: player.SafePos.X,
Y: player.Pos.Y, Y: player.SafePos.Y,
Z: player.Pos.Z, Z: player.SafePos.Z,
} }
// 获取最近角色实体的锚点 // 获取最近角色实体的锚点
// TODO 阻塞优化 16ms我感觉有点慢 // TODO 阻塞优化 16ms我感觉有点慢
for _, entry := range gdc.CONF.ScenePointEntries { //for _, entry := range gdc.CONF.ScenePointEntries {
if entry.PointData == nil || entry.PointData.TranPos == nil { // if entry.PointData == nil || entry.PointData.TranPos == nil {
continue // continue
} // }
pointPos := &model.Vector{ // pointPos := &model.Vector{
X: entry.PointData.TranPos.X, // X: entry.PointData.TranPos.X,
Y: entry.PointData.TranPos.Y, // Y: entry.PointData.TranPos.Y,
Z: entry.PointData.TranPos.Z, // Z: entry.PointData.TranPos.Z,
} // }
// 该坐标距离小于之前的则赋值 // // 该坐标距离小于之前的则赋值
if player.StaminaInfo.ActiveAvatarPos.Distance(pointPos) < player.StaminaInfo.ActiveAvatarPos.Distance(pos) { // if player.SafePos.Distance(pointPos) < player.SafePos.Distance(pos) {
pos = pointPos // pos = pointPos
} // }
} //}
// 传送玩家至安全位置 // 传送玩家至安全位置
g.TeleportPlayer(player, uint32(constant.EnterReasonConst.Revival), player.SceneId, pos) g.TeleportPlayer(player, uint32(constant.EnterReasonConst.Revival), player.SceneId, pos)
} }

View File

@@ -42,6 +42,7 @@ type Player struct {
FlyCloakList []uint32 `bson:"flyCloakList"` // 风之翼列表 FlyCloakList []uint32 `bson:"flyCloakList"` // 风之翼列表
CostumeList []uint32 `bson:"costumeList"` // 角色衣装列表 CostumeList []uint32 `bson:"costumeList"` // 角色衣装列表
SceneId uint32 `bson:"sceneId"` // 场景 SceneId uint32 `bson:"sceneId"` // 场景
SafePos *Vector `bson:"safePos"` // 玩家在陆地时的坐标
Pos *Vector `bson:"pos"` // 玩家坐标 Pos *Vector `bson:"pos"` // 玩家坐标
Rot *Vector `bson:"rot"` // 玩家朝向 Rot *Vector `bson:"rot"` // 玩家朝向
ItemMap map[uint32]*Item `bson:"itemMap"` // 玩家统一大背包仓库 ItemMap map[uint32]*Item `bson:"itemMap"` // 玩家统一大背包仓库
@@ -81,7 +82,6 @@ func (p *Player) InitAll() {
p.GameObjectGuidMap = make(map[uint64]GameObject) p.GameObjectGuidMap = make(map[uint64]GameObject)
p.CoopApplyMap = make(map[uint32]int64) p.CoopApplyMap = make(map[uint32]int64)
p.StaminaInfo = new(StaminaInfo) p.StaminaInfo = new(StaminaInfo)
p.StaminaInfo.ActiveAvatarPos = new(Vector)
p.VehicleInfo = new(VehicleInfo) p.VehicleInfo = new(VehicleInfo)
p.VehicleInfo.LastCreateEntityIdMap = make(map[uint32]uint32) p.VehicleInfo.LastCreateEntityIdMap = make(map[uint32]uint32)
p.InitAllAvatar() p.InitAllAvatar()

View File

@@ -14,8 +14,7 @@ type StaminaInfo struct {
LastSkillId uint32 // 最后释放的技能Id LastSkillId uint32 // 最后释放的技能Id
LastSkillTime int64 // 最后释放技能的时间 LastSkillTime int64 // 最后释放技能的时间
LastSkillStartTime int64 // 最后执行开始技能耐力消耗的时间 LastSkillStartTime int64 // 最后执行开始技能耐力消耗的时间
DrownBackDelay int64 // 溺水返回安全点延时 DrownBackDelay uint8 // 溺水返回安全点延时
ActiveAvatarPos *Vector // 当前角色位置
} }
// SetStaminaCost 设置动作需要消耗的耐力 // SetStaminaCost 设置动作需要消耗的耐力

View File

@@ -1,7 +1,8 @@
package model package model
type VehicleInfo struct { type VehicleInfo struct {
InVehicleEntityId uint32 // 玩家所在载具的实体Id InVehicleEntityId uint32 // 玩家所在载具的实体Id
LastCreateTime int64 // 最后一次创建载具的时间 LastCreateTime int64 // 最后一次创建载具的时间
// TODO 玩家可以在其他世界创建载具 需要额外处理
LastCreateEntityIdMap map[uint32]uint32 // 最后一次创建载具的实体Id map[vehicleId]EntityId LastCreateEntityIdMap map[uint32]uint32 // 最后一次创建载具的实体Id map[vehicleId]EntityId
} }