mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-13 04:22:27 +08:00
Merge remote-tracking branch 'origin/main' into main
This commit is contained in:
@@ -18,4 +18,5 @@ func InitConstant() {
|
|||||||
InitPlayerPropertyConst()
|
InitPlayerPropertyConst()
|
||||||
InitSceneTypeConst()
|
InitSceneTypeConst()
|
||||||
InitEntityTypeConst()
|
InitEntityTypeConst()
|
||||||
|
InitStaminaCostConst()
|
||||||
}
|
}
|
||||||
|
|||||||
49
gs/constant/stamina_cost.go
Normal file
49
gs/constant/stamina_cost.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
@@ -247,12 +247,8 @@ func (c *CommandManager) GiveCommand(cmd *CommandMessage) {
|
|||||||
c.GMAddUserAllAvatar(target.PlayerID)
|
c.GMAddUserAllAvatar(target.PlayerID)
|
||||||
c.SendMessage(player, "已给予玩家 UID:%v, 所有角色。", target.PlayerID)
|
c.SendMessage(player, "已给予玩家 UID:%v, 所有角色。", target.PlayerID)
|
||||||
case "all":
|
case "all":
|
||||||
// 给予玩家所有物品
|
// 给予玩家所有内容
|
||||||
c.GMAddUserAllItem(target.PlayerID, count)
|
c.GMAddUserAllEvery(target.PlayerID, count, count) // TODO 武器额外获取数量
|
||||||
// 给予玩家所有武器
|
|
||||||
c.GMAddUserAllWeapon(target.PlayerID, count)
|
|
||||||
// 给予玩家所有角色
|
|
||||||
c.GMAddUserAllAvatar(target.PlayerID)
|
|
||||||
c.SendMessage(player, "已给予玩家 UID:%v, 所有内容。", target.PlayerID)
|
c.SendMessage(player, "已给予玩家 UID:%v, 所有内容。", target.PlayerID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ func (c *CommandManager) GMAddUserAvatar(userId, avatarId uint32) {
|
|||||||
}
|
}
|
||||||
// 添加角色
|
// 添加角色
|
||||||
c.gameManager.AddUserAvatar(userId, avatarId)
|
c.gameManager.AddUserAvatar(userId, avatarId)
|
||||||
// todo 设置角色 等以后做到角色升级之类的再说
|
// TODO 设置角色 等以后做到角色升级之类的再说
|
||||||
//avatar := player.AvatarMap[avatarId]
|
//avatar := player.AvatarMap[avatarId]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,3 +71,13 @@ func (c *CommandManager) GMAddUserAllAvatar(userId uint32) {
|
|||||||
c.GMAddUserAvatar(userId, uint32(avatarId))
|
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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ func (r *RouteManager) doRoute(cmdId uint16, userId uint32, clientSeq uint32, pa
|
|||||||
player := r.gameManager.userManager.GetOnlineUser(userId)
|
player := r.gameManager.userManager.GetOnlineUser(userId)
|
||||||
if player == nil {
|
if player == nil {
|
||||||
logger.LOG.Error("player is nil, uid: %v", userId)
|
logger.LOG.Error("player is nil, uid: %v", userId)
|
||||||
|
r.gameManager.ReconnectPlayer(userId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
player.ClientSeq = clientSeq
|
player.ClientSeq = clientSeq
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ func (t *TickManager) OnGameServerTick() {
|
|||||||
t.tickCount++
|
t.tickCount++
|
||||||
now := time.Now().UnixMilli()
|
now := time.Now().UnixMilli()
|
||||||
t.onTick100MilliSecond(now)
|
t.onTick100MilliSecond(now)
|
||||||
|
if t.tickCount%2 == 0 {
|
||||||
|
t.onTick200MilliSecond(now)
|
||||||
|
}
|
||||||
if t.tickCount%(10*1) == 0 {
|
if t.tickCount%(10*1) == 0 {
|
||||||
t.onTickSecond(now)
|
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) {
|
func (t *TickManager) onTick100MilliSecond(now int64) {
|
||||||
// 伤害处理和转发
|
// 伤害处理和转发
|
||||||
for _, world := range t.gameManager.worldManager.worldMap {
|
for _, world := range t.gameManager.worldManager.worldMap {
|
||||||
|
|||||||
@@ -201,6 +201,10 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
|||||||
sceneEntity.lastMoveReliableSeq = entityMoveInfo.ReliableSeq
|
sceneEntity.lastMoveReliableSeq = entityMoveInfo.ReliableSeq
|
||||||
logger.LOG.Debug("entity move, id: %v, pos: %v, uid: %v", sceneEntity.id, sceneEntity.pos, player.PlayerID)
|
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)
|
invokeHandler.addEntry(entry.ForwardType, entry)
|
||||||
default:
|
default:
|
||||||
invokeHandler.addEntry(entry.ForwardType, entry)
|
invokeHandler.addEntry(entry.ForwardType, entry)
|
||||||
|
|||||||
117
gs/game/user_stamina.go
Normal file
117
gs/game/user_stamina.go
Normal file
@@ -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)
|
||||||
|
}
|
||||||
@@ -64,6 +64,7 @@ type Player struct {
|
|||||||
Pause bool `bson:"-"` // 暂停状态
|
Pause bool `bson:"-"` // 暂停状态
|
||||||
SceneLoadState int `bson:"-"` // 场景加载状态
|
SceneLoadState int `bson:"-"` // 场景加载状态
|
||||||
CoopApplyMap map[uint32]int64 `bson:"-"` // 敲门申请的玩家uid及时间
|
CoopApplyMap map[uint32]int64 `bson:"-"` // 敲门申请的玩家uid及时间
|
||||||
|
StaminaInfo *StaminaInfo `bson:"-"` // 耐力临时数据
|
||||||
ClientSeq uint32 `bson:"-"`
|
ClientSeq uint32 `bson:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +76,7 @@ func (p *Player) GetNextGameObjectGuid() uint64 {
|
|||||||
func (p *Player) InitAll() {
|
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.InitAllAvatar()
|
p.InitAllAvatar()
|
||||||
p.InitAllWeapon()
|
p.InitAllWeapon()
|
||||||
p.InitAllItem()
|
p.InitAllItem()
|
||||||
|
|||||||
12
gs/model/stamina.go
Normal file
12
gs/model/stamina.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hk4e/protocol/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StaminaInfo struct {
|
||||||
|
PrevState proto.MotionState
|
||||||
|
PrevPos *Vector
|
||||||
|
CurState proto.MotionState
|
||||||
|
CurPos *Vector
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user