mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-03-01 00:35:36 +08:00
溺水传送优化 溺水安全点无果
This commit is contained in:
@@ -4,37 +4,37 @@ var EnterReasonConst *EnterReason
|
|||||||
|
|
||||||
type EnterReason struct {
|
type EnterReason struct {
|
||||||
None uint16
|
None uint16
|
||||||
Login uint16
|
Login uint16 // 登录
|
||||||
DungeonReplay uint16
|
DungeonReplay uint16 // 秘境重新挑战
|
||||||
DungeonReviveOnWaypoint uint16
|
DungeonReviveOnWaypoint uint16 // 秘境重生
|
||||||
DungeonEnter uint16
|
DungeonEnter uint16 // 秘境进入
|
||||||
DungeonQuit uint16
|
DungeonQuit uint16 // 秘境离开
|
||||||
Gm uint16
|
Gm uint16 // 管理员
|
||||||
QuestRollback uint16
|
QuestRollback uint16 // 任务回滚
|
||||||
Revival uint16
|
Revival uint16 // 重生
|
||||||
PersonalScene uint16
|
PersonalScene uint16 // 个人场景
|
||||||
TransPoint uint16
|
TransPoint uint16 // 传送点
|
||||||
ClientTransmit uint16
|
ClientTransmit uint16 // 客户端传送
|
||||||
ForceDragBack uint16
|
ForceDragBack uint16 // 强制后退
|
||||||
TeamKick uint16
|
TeamKick uint16 // 队伍踢出
|
||||||
TeamJoin uint16
|
TeamJoin uint16 // 队伍加入
|
||||||
TeamBack uint16
|
TeamBack uint16 // 队伍返回
|
||||||
Muip uint16
|
Muip uint16 // ??
|
||||||
DungeonInviteAccept uint16
|
DungeonInviteAccept uint16 // 秘境邀请接受
|
||||||
Lua uint16
|
Lua uint16 // 脚本
|
||||||
ActivityLoadTerrain uint16
|
ActivityLoadTerrain uint16 // 活动加载地形
|
||||||
HostFromSingleToMp uint16
|
HostFromSingleToMp uint16 // 房主从单人到多人
|
||||||
MpPlay uint16
|
MpPlay uint16 // 多人游戏
|
||||||
AnchorPoint uint16
|
AnchorPoint uint16 // 迷你锚点
|
||||||
LuaSkipUi uint16
|
LuaSkipUi uint16 // 脚本跳过UI
|
||||||
ReloadTerrain uint16
|
ReloadTerrain uint16 // 重载地形
|
||||||
DraftTransfer uint16
|
DraftTransfer uint16 // 某个东西传送 ??
|
||||||
EnterHome uint16
|
EnterHome uint16 // 进入尘歌壶
|
||||||
ExitHome uint16
|
ExitHome uint16 // 离开尘歌壶
|
||||||
ChangeHomeModule uint16
|
ChangeHomeModule uint16 // 更改尘歌壶模块
|
||||||
Gallery uint16
|
Gallery uint16 // ??
|
||||||
HomeSceneJump uint16
|
HomeSceneJump uint16 // 尘歌壶场景跳转
|
||||||
HideAndSeek uint16
|
HideAndSeek uint16 // 隐藏和搜索 ??
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitEnterReasonConst() {
|
func InitEnterReasonConst() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"hk4e/gs/constant"
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/logger"
|
"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)
|
logger.Error("player is nil, uid: %v", userId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
GAME_MANAGER.TeleportPlayer(player, sceneId, &model.Vector{
|
GAME_MANAGER.TeleportPlayer(player, uint32(constant.EnterReasonConst.Gm), sceneId, &model.Vector{
|
||||||
X: posX,
|
X: posX,
|
||||||
Y: posY,
|
Y: posY,
|
||||||
Z: posZ,
|
Z: posZ,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func (r *RouteManager) doRoute(cmdId uint16, userId uint32, clientSeq uint32, pa
|
|||||||
if player == nil {
|
if player == nil {
|
||||||
logger.Error("player is nil, uid: %v", userId)
|
logger.Error("player is nil, uid: %v", userId)
|
||||||
// 临时为了调试便捷搞的重连 生产环境请务必去除 不然新用户会一直重连不能进入
|
// 临时为了调试便捷搞的重连 生产环境请务必去除 不然新用户会一直重连不能进入
|
||||||
// GAME_MANAGER.ReconnectPlayer(userId)
|
GAME_MANAGER.ReconnectPlayer(userId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
player.ClientSeq = clientSeq
|
player.ClientSeq = clientSeq
|
||||||
|
|||||||
@@ -113,21 +113,12 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
|||||||
if sceneEntity.avatarEntity != nil {
|
if sceneEntity.avatarEntity != nil {
|
||||||
// 玩家实体在移动
|
// 玩家实体在移动
|
||||||
// 更新玩家的位置信息
|
// 更新玩家的位置信息
|
||||||
|
player.Pos.X = float64(motionInfo.Pos.X)
|
||||||
switch motionInfo.State {
|
player.Pos.Y = float64(motionInfo.Pos.Y)
|
||||||
case proto.MotionState_MOTION_STATE_DANGER_RUN, proto.MotionState_MOTION_STATE_RUN,
|
player.Pos.Z = float64(motionInfo.Pos.Z)
|
||||||
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.Rot.X = float64(motionInfo.Rot.X)
|
||||||
proto.MotionState_MOTION_STATE_DANGER_WALK, proto.MotionState_MOTION_STATE_WALK,
|
player.Rot.Y = float64(motionInfo.Rot.Y)
|
||||||
proto.MotionState_MOTION_STATE_DASH:
|
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)
|
g.ImmediateStamina(player, motionInfo.State)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"hk4e/gs/constant"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
gdc "hk4e/gs/config"
|
gdc "hk4e/gs/config"
|
||||||
"hk4e/gs/constant"
|
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/protocol/cmd"
|
"hk4e/protocol/cmd"
|
||||||
@@ -32,7 +32,7 @@ func (g *GameManager) SceneTransToPointReq(player *model.Player, payloadMsg pb.M
|
|||||||
Y: transPos.Y,
|
Y: transPos.Y,
|
||||||
Z: transPos.Z,
|
Z: transPos.Z,
|
||||||
}
|
}
|
||||||
g.TeleportPlayer(player, sceneId, pos)
|
g.TeleportPlayer(player, uint32(constant.EnterReasonConst.TransPoint), sceneId, pos)
|
||||||
|
|
||||||
sceneTransToPointRsp := &proto.SceneTransToPointRsp{
|
sceneTransToPointRsp := &proto.SceneTransToPointRsp{
|
||||||
Retcode: 0,
|
Retcode: 0,
|
||||||
@@ -60,13 +60,13 @@ func (g *GameManager) MarkMapReq(player *model.Player, payloadMsg pb.Message) {
|
|||||||
Y: float64(posYInt),
|
Y: float64(posYInt),
|
||||||
Z: float64(req.Mark.Pos.Z),
|
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 传送玩家至地图上的某个位置
|
// 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
|
newSceneId := sceneId
|
||||||
oldSceneId := player.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)
|
logger.Debug("player goto scene, scene: %v, pos: %v", player.SceneId, player.Pos)
|
||||||
enterType = proto.EnterType_ENTER_TYPE_GOTO
|
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)
|
g.SendMsg(cmd.PlayerEnterSceneNotify, player.PlayerID, player.ClientSeq, playerEnterSceneNotify)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -422,26 +422,54 @@ func (g *GameManager) DrownBackHandler(player *model.Player) {
|
|||||||
if player.StaminaInfo.DrownBackTime == 0 {
|
if player.StaminaInfo.DrownBackTime == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if time.Now().UnixMilli() >= player.StaminaInfo.DrownBackTime {
|
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
scene := world.GetSceneById(player.SceneId)
|
||||||
scene := world.GetSceneById(player.SceneId)
|
activeAvatar := world.GetPlayerWorldAvatar(player, world.GetPlayerActiveAvatarId(player))
|
||||||
activeAvatar := world.GetPlayerWorldAvatar(player, player.TeamConfig.GetActiveAvatarId())
|
avatarEntity := scene.GetEntity(activeAvatar.avatarEntityId)
|
||||||
avatarEntity := scene.GetEntity(activeAvatar.avatarEntityId)
|
if avatarEntity == nil {
|
||||||
if avatarEntity == nil {
|
logger.Error("avatar entity is nil, entityId: %v", activeAvatar.avatarEntityId)
|
||||||
logger.Error("avatar entity is nil, entityId: %v", activeAvatar.avatarEntityId)
|
return
|
||||||
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 目前存在的问题
|
} else if time.Now().UnixMilli() >= player.StaminaInfo.DrownBackTime {
|
||||||
// 传送会显示玩家实体后再传送 返回安全位置写的不是很好可能存在问题
|
// 临时 防止一直淹死 尚未完善
|
||||||
// 官服 游戏离线也会回到安全位置
|
g.SetPlayerStamina(player, 10000)
|
||||||
|
|
||||||
// 设置角色存活
|
|
||||||
scene.SetEntityLifeState(avatarEntity, constant.LifeStateConst.LIFE_ALIVE, proto.PlayerDieType_PLAYER_DIE_TYPE_NONE)
|
|
||||||
// 传送玩家至安全位置
|
// 传送玩家至安全位置
|
||||||
g.TeleportPlayer(player, player.SceneId, player.Pos)
|
g.TeleportPlayer(player, uint32(constant.EnterReasonConst.Revival), player.SceneId, player.StaminaInfo.DrownBackPos)
|
||||||
|
|
||||||
// 重置溺水返回时间
|
// 设置溺水返回时间为1
|
||||||
player.StaminaInfo.DrownBackTime = 0
|
// 1代表加载完场景后再复活玩家
|
||||||
|
player.StaminaInfo.DrownBackTime = 1
|
||||||
// 重置动作状态否则可能会导致多次溺水
|
// 重置动作状态否则可能会导致多次溺水
|
||||||
player.StaminaInfo.State = 0
|
player.StaminaInfo.State = 0
|
||||||
}
|
}
|
||||||
@@ -456,7 +484,7 @@ func (g *GameManager) HandleDrown(player *model.Player, stamina uint32) {
|
|||||||
|
|
||||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||||
scene := world.GetSceneById(player.SceneId)
|
scene := world.GetSceneById(player.SceneId)
|
||||||
activeAvatar := world.GetPlayerWorldAvatar(player, player.TeamConfig.GetActiveAvatarId())
|
activeAvatar := world.GetPlayerWorldAvatar(player, world.GetPlayerActiveAvatarId(player))
|
||||||
avatarEntity := scene.GetEntity(activeAvatar.avatarEntityId)
|
avatarEntity := scene.GetEntity(activeAvatar.avatarEntityId)
|
||||||
if avatarEntity == nil {
|
if avatarEntity == nil {
|
||||||
logger.Error("avatar entity is nil, entityId: %v", activeAvatar.avatarEntityId)
|
logger.Error("avatar entity is nil, entityId: %v", activeAvatar.avatarEntityId)
|
||||||
|
|||||||
@@ -634,11 +634,16 @@ func (s *Scene) SetEntityLifeState(entity *Entity, lifeState uint16, dieType pro
|
|||||||
return
|
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
|
// PacketAvatarLifeStateChangeNotify
|
||||||
avatarLifeStateChangeNotify := &proto.AvatarLifeStateChangeNotify{
|
avatarLifeStateChangeNotify := &proto.AvatarLifeStateChangeNotify{
|
||||||
LifeState: uint32(avatar.LifeState),
|
LifeState: uint32(lifeState),
|
||||||
AttackTag: "",
|
AttackTag: "",
|
||||||
DieType: dieType,
|
DieType: dieType,
|
||||||
ServerBuffList: nil,
|
ServerBuffList: nil,
|
||||||
@@ -665,7 +670,7 @@ func (s *Scene) SetEntityLifeState(entity *Entity, lifeState uint16, dieType pro
|
|||||||
AttackTag: "",
|
AttackTag: "",
|
||||||
MoveReliableSeq: entity.lastMoveReliableSeq,
|
MoveReliableSeq: entity.lastMoveReliableSeq,
|
||||||
DieType: dieType,
|
DieType: dieType,
|
||||||
LifeState: uint32(entity.lifeState),
|
LifeState: uint32(lifeState),
|
||||||
SourceEntityId: 0,
|
SourceEntityId: 0,
|
||||||
}
|
}
|
||||||
for _, p := range s.playerMap {
|
for _, p := range s.playerMap {
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ 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.DrownBackPos = 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()
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ type StaminaInfo struct {
|
|||||||
LastSkillTime int64 // 最后释放技能的时间
|
LastSkillTime int64 // 最后释放技能的时间
|
||||||
LastSkillStartTime int64 // 最后执行开始技能耐力消耗的时间
|
LastSkillStartTime int64 // 最后执行开始技能耐力消耗的时间
|
||||||
DrownBackTime int64 // 溺水返回安全点的时间
|
DrownBackTime int64 // 溺水返回安全点的时间
|
||||||
|
DrownBackPos *Vector // 溺水返回的安全点坐标
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetStaminaCost 设置动作需要消耗的耐力
|
// SetStaminaCost 设置动作需要消耗的耐力
|
||||||
|
|||||||
Reference in New Issue
Block a user