溺水传送优化 溺水安全点无果

This commit is contained in:
UnKownOwO
2022-12-20 18:13:12 +08:00
parent 391738e29a
commit 056ae5f8d8
9 changed files with 101 additions and 74 deletions

View File

@@ -1,6 +1,7 @@
package game
import (
"hk4e/gs/constant"
"hk4e/gs/model"
"hk4e/pkg/logger"
)
@@ -12,7 +13,7 @@ func (c *CommandManager) GMTeleportPlayer(userId, sceneId uint32, posX, posY, po
logger.Error("player is nil, uid: %v", userId)
return
}
GAME_MANAGER.TeleportPlayer(player, sceneId, &model.Vector{
GAME_MANAGER.TeleportPlayer(player, uint32(constant.EnterReasonConst.Gm), sceneId, &model.Vector{
X: posX,
Y: posY,
Z: posZ,

View File

@@ -38,7 +38,7 @@ func (r *RouteManager) doRoute(cmdId uint16, userId uint32, clientSeq uint32, pa
if player == nil {
logger.Error("player is nil, uid: %v", userId)
// 临时为了调试便捷搞的重连 生产环境请务必去除 不然新用户会一直重连不能进入
// GAME_MANAGER.ReconnectPlayer(userId)
GAME_MANAGER.ReconnectPlayer(userId)
return
}
player.ClientSeq = clientSeq

View File

@@ -113,21 +113,12 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
if sceneEntity.avatarEntity != nil {
// 玩家实体在移动
// 更新玩家的位置信息
switch motionInfo.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.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)
}
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)
// 处理耐力消耗
g.ImmediateStamina(player, motionInfo.State)

View File

@@ -1,10 +1,10 @@
package game
import (
"hk4e/gs/constant"
"strconv"
gdc "hk4e/gs/config"
"hk4e/gs/constant"
"hk4e/gs/model"
"hk4e/pkg/logger"
"hk4e/protocol/cmd"
@@ -32,7 +32,7 @@ func (g *GameManager) SceneTransToPointReq(player *model.Player, payloadMsg pb.M
Y: transPos.Y,
Z: transPos.Z,
}
g.TeleportPlayer(player, sceneId, pos)
g.TeleportPlayer(player, uint32(constant.EnterReasonConst.TransPoint), sceneId, pos)
sceneTransToPointRsp := &proto.SceneTransToPointRsp{
Retcode: 0,
@@ -60,13 +60,13 @@ func (g *GameManager) MarkMapReq(player *model.Player, payloadMsg pb.Message) {
Y: float64(posYInt),
Z: float64(req.Mark.Pos.Z),
}
g.TeleportPlayer(player, req.Mark.SceneId, pos)
g.TeleportPlayer(player, uint32(constant.EnterReasonConst.Gm), req.Mark.SceneId, pos)
}
}
}
// TeleportPlayer 传送玩家至地图上的某个位置
func (g *GameManager) TeleportPlayer(player *model.Player, sceneId uint32, pos *model.Vector) {
func (g *GameManager) TeleportPlayer(player *model.Player, enterReason uint32, sceneId uint32, pos *model.Vector) {
// 传送玩家
newSceneId := sceneId
oldSceneId := player.SceneId
@@ -105,7 +105,7 @@ func (g *GameManager) TeleportPlayer(player *model.Player, sceneId uint32, pos *
logger.Debug("player goto scene, scene: %v, pos: %v", player.SceneId, player.Pos)
enterType = proto.EnterType_ENTER_TYPE_GOTO
}
playerEnterSceneNotify := g.PacketPlayerEnterSceneNotifyTp(player, enterType, uint32(constant.EnterReasonConst.TransPoint), oldSceneId, oldPos)
playerEnterSceneNotify := g.PacketPlayerEnterSceneNotifyTp(player, enterType, enterReason, oldSceneId, oldPos)
g.SendMsg(cmd.PlayerEnterSceneNotify, player.PlayerID, player.ClientSeq, playerEnterSceneNotify)
}

View File

@@ -422,26 +422,54 @@ func (g *GameManager) DrownBackHandler(player *model.Player) {
if player.StaminaInfo.DrownBackTime == 0 {
return
}
if time.Now().UnixMilli() >= player.StaminaInfo.DrownBackTime {
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
scene := world.GetSceneById(player.SceneId)
activeAvatar := world.GetPlayerWorldAvatar(player, player.TeamConfig.GetActiveAvatarId())
avatarEntity := scene.GetEntity(activeAvatar.avatarEntityId)
if avatarEntity == nil {
logger.Error("avatar entity is nil, entityId: %v", activeAvatar.avatarEntityId)
return
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
scene := world.GetSceneById(player.SceneId)
activeAvatar := world.GetPlayerWorldAvatar(player, world.GetPlayerActiveAvatarId(player))
avatarEntity := scene.GetEntity(activeAvatar.avatarEntityId)
if avatarEntity == nil {
logger.Error("avatar entity is nil, entityId: %v", activeAvatar.avatarEntityId)
return
}
// 记录溺水安全点
// 溺水安全点可能需要读取附近锚点坐标
// 多次溺水后提示溺水的死亡信息
// 官服 游戏离线也会回到安全位置
// 很显然目前这个很不完善
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.StaminaInfo.DrownBackPos.X = player.Pos.X
player.StaminaInfo.DrownBackPos.Y = player.Pos.Y
player.StaminaInfo.DrownBackPos.Z = player.Pos.Z
}
// 临时
if player.StaminaInfo.DrownBackPos.X == 0 && player.StaminaInfo.DrownBackPos.Y == 0 && player.StaminaInfo.DrownBackPos.Z == 0 {
player.StaminaInfo.DrownBackPos.X = player.Pos.X
player.StaminaInfo.DrownBackPos.Y = player.Pos.Y
player.StaminaInfo.DrownBackPos.Z = player.Pos.Z
}
if player.StaminaInfo.DrownBackTime == 1 {
// 确保玩家已经完成加载场景
if player.SceneLoadState == model.SceneEnterDone {
// 设置角色存活
scene.SetEntityLifeState(avatarEntity, constant.LifeStateConst.LIFE_REVIVE, proto.PlayerDieType_PLAYER_DIE_TYPE_NONE)
// 重置溺水返回时间
player.StaminaInfo.DrownBackTime = 0
}
// TODO 目前存在的问题
// 传送会显示玩家实体后再传送 返回安全位置写的不是很好可能存在问题
// 官服 游戏离线也会回到安全位置
// 设置角色存活
scene.SetEntityLifeState(avatarEntity, constant.LifeStateConst.LIFE_ALIVE, proto.PlayerDieType_PLAYER_DIE_TYPE_NONE)
} else if time.Now().UnixMilli() >= player.StaminaInfo.DrownBackTime {
// 临时 防止一直淹死 尚未完善
g.SetPlayerStamina(player, 10000)
// 传送玩家至安全位置
g.TeleportPlayer(player, player.SceneId, player.Pos)
g.TeleportPlayer(player, uint32(constant.EnterReasonConst.Revival), player.SceneId, player.StaminaInfo.DrownBackPos)
// 置溺水返回时间
player.StaminaInfo.DrownBackTime = 0
// 置溺水返回时间为1
// 1代表加载完场景后再复活玩家
player.StaminaInfo.DrownBackTime = 1
// 重置动作状态否则可能会导致多次溺水
player.StaminaInfo.State = 0
}
@@ -456,7 +484,7 @@ func (g *GameManager) HandleDrown(player *model.Player, stamina uint32) {
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
scene := world.GetSceneById(player.SceneId)
activeAvatar := world.GetPlayerWorldAvatar(player, player.TeamConfig.GetActiveAvatarId())
activeAvatar := world.GetPlayerWorldAvatar(player, world.GetPlayerActiveAvatarId(player))
avatarEntity := scene.GetEntity(activeAvatar.avatarEntityId)
if avatarEntity == nil {
logger.Error("avatar entity is nil, entityId: %v", activeAvatar.avatarEntityId)

View File

@@ -634,11 +634,16 @@ func (s *Scene) SetEntityLifeState(entity *Entity, lifeState uint16, dieType pro
return
}
// 设置角色存活状态
avatar.LifeState = lifeState
if lifeState == constant.LifeStateConst.LIFE_REVIVE {
avatar.LifeState = constant.LifeStateConst.LIFE_ALIVE
// 设置血量
entity.fightProp[uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_HP)] = 110
GAME_MANAGER.EntityFightPropUpdateNotifyBroadcast(s, entity, uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_HP))
}
// PacketAvatarLifeStateChangeNotify
avatarLifeStateChangeNotify := &proto.AvatarLifeStateChangeNotify{
LifeState: uint32(avatar.LifeState),
LifeState: uint32(lifeState),
AttackTag: "",
DieType: dieType,
ServerBuffList: nil,
@@ -665,7 +670,7 @@ func (s *Scene) SetEntityLifeState(entity *Entity, lifeState uint16, dieType pro
AttackTag: "",
MoveReliableSeq: entity.lastMoveReliableSeq,
DieType: dieType,
LifeState: uint32(entity.lifeState),
LifeState: uint32(lifeState),
SourceEntityId: 0,
}
for _, p := range s.playerMap {