mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-09 03:52:27 +08:00
溺水传送优化 溺水安全点无果
This commit is contained in:
@@ -4,37 +4,37 @@ var EnterReasonConst *EnterReason
|
||||
|
||||
type EnterReason struct {
|
||||
None uint16
|
||||
Login uint16
|
||||
DungeonReplay uint16
|
||||
DungeonReviveOnWaypoint uint16
|
||||
DungeonEnter uint16
|
||||
DungeonQuit uint16
|
||||
Gm uint16
|
||||
QuestRollback uint16
|
||||
Revival uint16
|
||||
PersonalScene uint16
|
||||
TransPoint uint16
|
||||
ClientTransmit uint16
|
||||
ForceDragBack uint16
|
||||
TeamKick uint16
|
||||
TeamJoin uint16
|
||||
TeamBack uint16
|
||||
Muip uint16
|
||||
DungeonInviteAccept uint16
|
||||
Lua uint16
|
||||
ActivityLoadTerrain uint16
|
||||
HostFromSingleToMp uint16
|
||||
MpPlay uint16
|
||||
AnchorPoint uint16
|
||||
LuaSkipUi uint16
|
||||
ReloadTerrain uint16
|
||||
DraftTransfer uint16
|
||||
EnterHome uint16
|
||||
ExitHome uint16
|
||||
ChangeHomeModule uint16
|
||||
Gallery uint16
|
||||
HomeSceneJump uint16
|
||||
HideAndSeek uint16
|
||||
Login uint16 // 登录
|
||||
DungeonReplay uint16 // 秘境重新挑战
|
||||
DungeonReviveOnWaypoint uint16 // 秘境重生
|
||||
DungeonEnter uint16 // 秘境进入
|
||||
DungeonQuit uint16 // 秘境离开
|
||||
Gm uint16 // 管理员
|
||||
QuestRollback uint16 // 任务回滚
|
||||
Revival uint16 // 重生
|
||||
PersonalScene uint16 // 个人场景
|
||||
TransPoint uint16 // 传送点
|
||||
ClientTransmit uint16 // 客户端传送
|
||||
ForceDragBack uint16 // 强制后退
|
||||
TeamKick uint16 // 队伍踢出
|
||||
TeamJoin uint16 // 队伍加入
|
||||
TeamBack uint16 // 队伍返回
|
||||
Muip uint16 // ??
|
||||
DungeonInviteAccept uint16 // 秘境邀请接受
|
||||
Lua uint16 // 脚本
|
||||
ActivityLoadTerrain uint16 // 活动加载地形
|
||||
HostFromSingleToMp uint16 // 房主从单人到多人
|
||||
MpPlay uint16 // 多人游戏
|
||||
AnchorPoint uint16 // 迷你锚点
|
||||
LuaSkipUi uint16 // 脚本跳过UI
|
||||
ReloadTerrain uint16 // 重载地形
|
||||
DraftTransfer uint16 // 某个东西传送 ??
|
||||
EnterHome uint16 // 进入尘歌壶
|
||||
ExitHome uint16 // 离开尘歌壶
|
||||
ChangeHomeModule uint16 // 更改尘歌壶模块
|
||||
Gallery uint16 // ??
|
||||
HomeSceneJump uint16 // 尘歌壶场景跳转
|
||||
HideAndSeek uint16 // 隐藏和搜索 ??
|
||||
}
|
||||
|
||||
func InitEnterReasonConst() {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -81,6 +81,7 @@ func (p *Player) InitAll() {
|
||||
p.GameObjectGuidMap = make(map[uint64]GameObject)
|
||||
p.CoopApplyMap = make(map[uint32]int64)
|
||||
p.StaminaInfo = new(StaminaInfo)
|
||||
p.StaminaInfo.DrownBackPos = new(Vector)
|
||||
p.VehicleInfo = new(VehicleInfo)
|
||||
p.VehicleInfo.LastCreateEntityIdMap = make(map[uint32]uint32)
|
||||
p.InitAllAvatar()
|
||||
|
||||
@@ -15,6 +15,7 @@ type StaminaInfo struct {
|
||||
LastSkillTime int64 // 最后释放技能的时间
|
||||
LastSkillStartTime int64 // 最后执行开始技能耐力消耗的时间
|
||||
DrownBackTime int64 // 溺水返回安全点的时间
|
||||
DrownBackPos *Vector // 溺水返回的安全点坐标
|
||||
}
|
||||
|
||||
// SetStaminaCost 设置动作需要消耗的耐力
|
||||
|
||||
Reference in New Issue
Block a user