From 3cd8a328180bbb11721a22beeb1bf1534e4a822e Mon Sep 17 00:00:00 2001 From: UnKownOwO <80520429@qq.com> Date: Mon, 28 Nov 2022 22:14:07 +0800 Subject: [PATCH] =?UTF-8?q?=E8=80=90=E5=8A=9B=E6=A8=A1=E5=9D=97=E5=88=9D?= =?UTF-8?q?=E6=AD=A5=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gs/constant/constant.go | 1 + gs/constant/stamina_cost.go | 49 ++++++++++++++ gs/game/command_controller.go | 8 +-- gs/game/command_gm.go | 12 +++- gs/game/route_manager.go | 1 + gs/game/tick_manager.go | 12 ++++ gs/game/user_combat.go | 4 ++ gs/game/user_stamina.go | 117 ++++++++++++++++++++++++++++++++++ gs/model/player.go | 2 + gs/model/stamina.go | 12 ++++ 10 files changed, 211 insertions(+), 7 deletions(-) create mode 100644 gs/constant/stamina_cost.go create mode 100644 gs/game/user_stamina.go create mode 100644 gs/model/stamina.go diff --git a/gs/constant/constant.go b/gs/constant/constant.go index e8c1ba61..63e860e8 100644 --- a/gs/constant/constant.go +++ b/gs/constant/constant.go @@ -18,4 +18,5 @@ func InitConstant() { InitPlayerPropertyConst() InitSceneTypeConst() InitEntityTypeConst() + InitStaminaCostConst() } diff --git a/gs/constant/stamina_cost.go b/gs/constant/stamina_cost.go new file mode 100644 index 00000000..49fdd7f6 --- /dev/null +++ b/gs/constant/stamina_cost.go @@ -0,0 +1,49 @@ +package constant + +var StaminaCostConst *StaminaCost + +type StaminaCost struct { + CLIMBING int32 + CLIMB_START int32 + CLIMB_JUMP int32 + DASH int32 + FIGHT int32 + FLY int32 + SKIFF_DASH int32 + SPRINT int32 + SWIM_DASH_START int32 + SWIM_DASH int32 + SWIMMING int32 + TALENT_DASH int32 + TALENT_DASH_START int32 + POWERED_FLY int32 + POWERED_SKIFF int32 + RUN int32 + SKIFF int32 + STANDBY int32 + WALK int32 +} + +func InitStaminaCostConst() { + StaminaCostConst = new(StaminaCost) + + StaminaCostConst.CLIMBING = -150 + StaminaCostConst.CLIMB_START = -500 + StaminaCostConst.CLIMB_JUMP = -2500 + StaminaCostConst.DASH = -360 + StaminaCostConst.FIGHT = 0 + StaminaCostConst.FLY = -60 + StaminaCostConst.SKIFF_DASH = -204 + StaminaCostConst.SPRINT = -1800 + StaminaCostConst.SWIM_DASH_START = -2000 + StaminaCostConst.SWIM_DASH = -204 + StaminaCostConst.SWIMMING = -80 + StaminaCostConst.TALENT_DASH = -300 + StaminaCostConst.TALENT_DASH_START = -1000 + StaminaCostConst.POWERED_FLY = 500 + StaminaCostConst.POWERED_SKIFF = 500 + StaminaCostConst.RUN = 500 + StaminaCostConst.SKIFF = 500 + StaminaCostConst.STANDBY = 500 + StaminaCostConst.WALK = 500 +} diff --git a/gs/game/command_controller.go b/gs/game/command_controller.go index 9d30eedf..174507e8 100644 --- a/gs/game/command_controller.go +++ b/gs/game/command_controller.go @@ -247,12 +247,8 @@ func (c *CommandManager) GiveCommand(cmd *CommandMessage) { c.GMAddUserAllAvatar(target.PlayerID) c.SendMessage(player, "已给予玩家 UID:%v, 所有角色。", target.PlayerID) case "all": - // 给予玩家所有物品 - c.GMAddUserAllItem(target.PlayerID, count) - // 给予玩家所有武器 - c.GMAddUserAllWeapon(target.PlayerID, count) - // 给予玩家所有角色 - c.GMAddUserAllAvatar(target.PlayerID) + // 给予玩家所有内容 + c.GMAddUserAllEvery(target.PlayerID, count, count) // TODO 武器额外获取数量 c.SendMessage(player, "已给予玩家 UID:%v, 所有内容。", target.PlayerID) } } diff --git a/gs/game/command_gm.go b/gs/game/command_gm.go index 08d8affa..5945e769 100644 --- a/gs/game/command_gm.go +++ b/gs/game/command_gm.go @@ -47,7 +47,7 @@ func (c *CommandManager) GMAddUserAvatar(userId, avatarId uint32) { } // 添加角色 c.gameManager.AddUserAvatar(userId, avatarId) - // todo 设置角色 等以后做到角色升级之类的再说 + // TODO 设置角色 等以后做到角色升级之类的再说 //avatar := player.AvatarMap[avatarId] } @@ -71,3 +71,13 @@ func (c *CommandManager) GMAddUserAllAvatar(userId uint32) { c.GMAddUserAvatar(userId, uint32(avatarId)) } } + +// GMAddUserAllEvery 给予玩家所有内容 +func (c *CommandManager) GMAddUserAllEvery(userId uint32, itemCount uint32, weaponCount uint32) { + // 给予玩家所有物品 + c.GMAddUserAllItem(userId, itemCount) + // 给予玩家所有武器 + c.GMAddUserAllWeapon(userId, itemCount) + // 给予玩家所有角色 + c.GMAddUserAllAvatar(userId) +} diff --git a/gs/game/route_manager.go b/gs/game/route_manager.go index 5c66e1ae..c28f3e01 100644 --- a/gs/game/route_manager.go +++ b/gs/game/route_manager.go @@ -38,6 +38,7 @@ func (r *RouteManager) doRoute(cmdId uint16, userId uint32, clientSeq uint32, pa player := r.gameManager.userManager.GetOnlineUser(userId) if player == nil { logger.LOG.Error("player is nil, uid: %v", userId) + r.gameManager.ReconnectPlayer(userId) return } player.ClientSeq = clientSeq diff --git a/gs/game/tick_manager.go b/gs/game/tick_manager.go index 71f91068..5bde2680 100644 --- a/gs/game/tick_manager.go +++ b/gs/game/tick_manager.go @@ -31,6 +31,9 @@ func (t *TickManager) OnGameServerTick() { t.tickCount++ now := time.Now().UnixMilli() t.onTick100MilliSecond(now) + if t.tickCount%2 == 0 { + t.onTick200MilliSecond(now) + } if t.tickCount%(10*1) == 0 { t.onTickSecond(now) } @@ -222,6 +225,15 @@ func (t *TickManager) onTickSecond(now int64) { } } +func (t *TickManager) onTick200MilliSecond(now int64) { + // 耐力消耗 + for _, world := range t.gameManager.worldManager.worldMap { + for _, player := range world.playerMap { + t.gameManager.StaminaHandler(player) + } + } +} + func (t *TickManager) onTick100MilliSecond(now int64) { // 伤害处理和转发 for _, world := range t.gameManager.worldManager.worldMap { diff --git a/gs/game/user_combat.go b/gs/game/user_combat.go index 7c7bcc1c..7409fc26 100644 --- a/gs/game/user_combat.go +++ b/gs/game/user_combat.go @@ -201,6 +201,10 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p sceneEntity.lastMoveReliableSeq = entityMoveInfo.ReliableSeq logger.LOG.Debug("entity move, id: %v, pos: %v, uid: %v", sceneEntity.id, sceneEntity.pos, player.PlayerID) } + + // 处理耐力消耗 + g.HandleStamina(player, motionInfo.State) + invokeHandler.addEntry(entry.ForwardType, entry) default: invokeHandler.addEntry(entry.ForwardType, entry) diff --git a/gs/game/user_stamina.go b/gs/game/user_stamina.go new file mode 100644 index 00000000..dc5053b8 --- /dev/null +++ b/gs/game/user_stamina.go @@ -0,0 +1,117 @@ +package game + +import ( + "hk4e/gs/constant" + "hk4e/gs/model" + "hk4e/pkg/logger" + "hk4e/protocol/cmd" + "hk4e/protocol/proto" +) + +// HandleStamina 处理即时耐力消耗 +func (g *GameManager) HandleStamina(player *model.Player, motionState proto.MotionState) { + logger.LOG.Debug("stamina handle, uid: %v, motionState: %v", player.PlayerID, motionState) + + // 记录玩家的此时状态 + player.StaminaInfo.CurState = motionState + player.StaminaInfo.CurPos = &model.Vector{ + X: player.Pos.X, + Y: player.Pos.Y, + Z: player.Pos.Z, + } + + // 根据玩家的状态消耗耐力 + switch motionState { + case proto.MotionState_MOTION_STATE_CLIMB: + g.UpdateStamina(player, constant.StaminaCostConst.CLIMB_START) + } +} + +// StaminaHandler 处理持续耐力消耗 +func (g *GameManager) StaminaHandler(player *model.Player) { + staminaInfo := player.StaminaInfo + isMoving := g.GetPlayerIsMoving(staminaInfo) + + // 玩家最大耐力 + maxStamina := player.PropertiesMap[constant.PlayerPropertyConst.PROP_MAX_STAMINA] + // 玩家现行耐力 + curStamina := player.PropertiesMap[constant.PlayerPropertyConst.PROP_CUR_PERSIST_STAMINA] + + // 确保玩家需要执行耐力消耗 + if isMoving || curStamina < maxStamina { + var staminaConst int32 + + switch staminaInfo.CurState { + case proto.MotionState_MOTION_STATE_CLIMB: + // 攀爬 + if isMoving { + staminaConst = constant.StaminaCostConst.CLIMBING + } + case proto.MotionState_MOTION_STATE_DASH: + // 短跑 + staminaConst = constant.StaminaCostConst.DASH + case proto.MotionState_MOTION_STATE_RUN: + // 跑步 + staminaConst = constant.StaminaCostConst.RUN + } + + // 更新玩家耐力 + g.UpdateStamina(player, staminaConst) + } + // 替换老数据 + staminaInfo.PrevState = staminaInfo.CurState + staminaInfo.PrevPos = staminaInfo.CurPos +} + +// GetPlayerIsMoving 玩家是否正在移动 +func (g *GameManager) GetPlayerIsMoving(staminaInfo *model.StaminaInfo) bool { + if staminaInfo.PrevPos == nil || staminaInfo.CurPos == nil { + return false + } + diffX := staminaInfo.CurPos.X - staminaInfo.PrevPos.X + diffY := staminaInfo.CurPos.Y - staminaInfo.PrevPos.Y + diffZ := staminaInfo.CurPos.Z - staminaInfo.PrevPos.Z + logger.LOG.Debug("get player is moving, diffX: %v, diffY: %v, diffZ: %v", diffX, diffY, diffZ) + return diffX > 0.3 || diffY > 0.2 || diffZ > 0.3 +} + +// UpdateStamina 更新耐力 当前耐力值 + 消耗的耐力值 +func (g *GameManager) UpdateStamina(player *model.Player, staminaCost int32) { + // 玩家最大耐力值 + maxStamina := int32(player.PropertiesMap[constant.PlayerPropertyConst.PROP_MAX_STAMINA]) + + // 玩家现行耐力值 + curStamina := int32(player.PropertiesMap[constant.PlayerPropertyConst.PROP_CUR_PERSIST_STAMINA]) + + // 即将更改为的耐力值 + stamina := curStamina + staminaCost + + // 确保耐力值不超出范围 + if stamina > maxStamina { + stamina = maxStamina + } else if stamina < 0 { + stamina = 0 + } + + g.SetStamina(player, uint32(stamina)) +} + +// SetStamina 设置玩家的耐力 +func (g *GameManager) SetStamina(player *model.Player, stamina uint32) { + prop := constant.PlayerPropertyConst.PROP_CUR_PERSIST_STAMINA + + // 设置玩家的耐力prop + player.PropertiesMap[prop] = stamina + + // PacketPlayerPropNotify + playerPropNotify := new(proto.PlayerPropNotify) + playerPropNotify.PropMap = make(map[uint32]*proto.PropValue) + playerPropNotify.PropMap[uint32(prop)] = &proto.PropValue{ + Type: uint32(prop), + Val: int64(player.PropertiesMap[prop]), + Value: &proto.PropValue_Ival{ + Ival: int64(player.PropertiesMap[prop]), + }, + } + g.SendMsg(cmd.PlayerPropNotify, player.PlayerID, player.ClientSeq, playerPropNotify) +} diff --git a/gs/model/player.go b/gs/model/player.go index 00216898..e22e16e8 100644 --- a/gs/model/player.go +++ b/gs/model/player.go @@ -64,6 +64,7 @@ type Player struct { Pause bool `bson:"-"` // 暂停状态 SceneLoadState int `bson:"-"` // 场景加载状态 CoopApplyMap map[uint32]int64 `bson:"-"` // 敲门申请的玩家uid及时间 + StaminaInfo *StaminaInfo `bson:"-"` // 耐力临时数据 ClientSeq uint32 `bson:"-"` } @@ -75,6 +76,7 @@ func (p *Player) GetNextGameObjectGuid() uint64 { func (p *Player) InitAll() { p.GameObjectGuidMap = make(map[uint64]GameObject) p.CoopApplyMap = make(map[uint32]int64) + p.StaminaInfo = new(StaminaInfo) p.InitAllAvatar() p.InitAllWeapon() p.InitAllItem() diff --git a/gs/model/stamina.go b/gs/model/stamina.go new file mode 100644 index 00000000..b3901626 --- /dev/null +++ b/gs/model/stamina.go @@ -0,0 +1,12 @@ +package model + +import ( + "hk4e/protocol/proto" +) + +type StaminaInfo struct { + PrevState proto.MotionState + PrevPos *Vector + CurState proto.MotionState + CurPos *Vector +}