mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 16:02:26 +08:00
同一类型载具唯一 载具耐力初步
This commit is contained in:
@@ -9,18 +9,19 @@ type StaminaCost struct {
|
||||
CLIMB_JUMP int32 // 攀爬跳跃
|
||||
DASH int32 // 快速跑步
|
||||
FLY int32 // 滑翔
|
||||
SKIFF_DASH int32 // 浪船加速
|
||||
SPRINT int32 // 冲刺
|
||||
SWIM_DASH_START int32 // 快速游泳开始
|
||||
SWIM_DASH int32 // 快速游泳
|
||||
SWIMMING int32 // 缓慢游泳
|
||||
// 恢复耐力
|
||||
POWERED_FLY int32 // 滑翔加速(风圈等)
|
||||
POWERED_SKIFF int32 // 浪船加速(风圈等)
|
||||
RUN int32 // 正常跑步
|
||||
SKIFF int32 // 游艇行驶
|
||||
STANDBY int32 // 站立
|
||||
WALK int32 // 走路
|
||||
POWERED_FLY int32 // 滑翔加速(风圈等)
|
||||
RUN int32 // 正常跑步
|
||||
STANDBY int32 // 站立
|
||||
WALK int32 // 走路
|
||||
// 载具浪船
|
||||
SKIFF_DASH int32 // 浪船加速
|
||||
SKIFF_NORMAL int32 // 浪船正常移动 (回复耐力)
|
||||
POWERED_SKIFF int32 // 浪船加速(风圈等) (回复耐力)
|
||||
// 武器消耗默认值
|
||||
FIGHT_SWORD_ONE_HAND int32 // 单手剑
|
||||
FIGHT_POLE int32 // 长枪
|
||||
@@ -38,17 +39,17 @@ func InitStaminaCostConst() {
|
||||
StaminaCostConst.CLIMB_JUMP = -2500
|
||||
StaminaCostConst.DASH = -360
|
||||
StaminaCostConst.FLY = -60
|
||||
StaminaCostConst.SKIFF_DASH = -204
|
||||
StaminaCostConst.SPRINT = -1800
|
||||
StaminaCostConst.SWIM_DASH_START = -2000
|
||||
StaminaCostConst.SWIM_DASH = -204
|
||||
StaminaCostConst.SWIMMING = -400
|
||||
StaminaCostConst.POWERED_FLY = 500
|
||||
StaminaCostConst.POWERED_SKIFF = 500
|
||||
StaminaCostConst.RUN = 500
|
||||
StaminaCostConst.SKIFF = 500
|
||||
StaminaCostConst.STANDBY = 500
|
||||
StaminaCostConst.WALK = 500
|
||||
StaminaCostConst.SKIFF_DASH = -204
|
||||
StaminaCostConst.SKIFF_NORMAL = 500
|
||||
StaminaCostConst.POWERED_SKIFF = 500
|
||||
StaminaCostConst.FIGHT_SWORD_ONE_HAND = -2000
|
||||
StaminaCostConst.FIGHT_POLE = -2500
|
||||
StaminaCostConst.FIGHT_CATALYST = -5000
|
||||
|
||||
@@ -55,8 +55,14 @@ func (g *GameManager) HandleAbilityStamina(player *model.Player, entry *proto.Ab
|
||||
if avatarAbility == nil {
|
||||
return
|
||||
}
|
||||
// 重击对应的耐力消耗
|
||||
g.ChargedAttackStamina(player, worldAvatar, avatarAbility)
|
||||
// 距离技能开始过去的时间
|
||||
pastTime := time.Now().UnixMilli() - player.StaminaInfo.LastSkillTime
|
||||
// 法器角色轻击也会算触发重击消耗
|
||||
// 所以通过策略判断 必须距离技能开始过去100ms才算重击
|
||||
if player.StaminaInfo.LastSkillId == uint32(avatarAbility.AvatarSkillId) && pastTime > 100 {
|
||||
// 重击对应的耐力消耗
|
||||
g.ChargedAttackStamina(player, worldAvatar, avatarAbility)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
@@ -117,7 +123,7 @@ func (g *GameManager) ImmediateStamina(player *model.Player, motionState proto.M
|
||||
//logger.LOG.Debug("stamina handle, uid: %v, motionState: %v", player.PlayerID, motionState)
|
||||
|
||||
// 设置用于持续消耗或恢复耐力的值
|
||||
g.SetStaminaCost(player, motionState)
|
||||
staminaInfo.SetStaminaCost(motionState)
|
||||
|
||||
// 未改变状态不执行后面 有些仅在动作开始消耗耐力
|
||||
if motionState == staminaInfo.State {
|
||||
@@ -126,6 +132,7 @@ func (g *GameManager) ImmediateStamina(player *model.Player, motionState proto.M
|
||||
|
||||
// 记录玩家的动作状态
|
||||
staminaInfo.State = motionState
|
||||
logger.LOG.Error("state: %v", motionState.String())
|
||||
|
||||
// 根据玩家的状态立刻消耗耐力
|
||||
switch motionState {
|
||||
@@ -237,7 +244,6 @@ func (g *GameManager) SkillStartStamina(player *model.Player, casterId uint32, s
|
||||
|
||||
// 获取该技能开始时所需消耗的耐力
|
||||
costStamina := constant.StaminaCostConst.SKILL_START[skillId]
|
||||
logger.LOG.Debug("skill start stamina, skillId: %v, cost: %v", skillId, costStamina)
|
||||
|
||||
// 距离上次处理技能开始耐力消耗过去的时间
|
||||
pastTime := time.Now().UnixMilli() - staminaInfo.LastSkillTime
|
||||
@@ -248,8 +254,12 @@ func (g *GameManager) SkillStartStamina(player *model.Player, casterId uint32, s
|
||||
// 根据配置消耗耐力
|
||||
g.UpdateStamina(player, costStamina)
|
||||
|
||||
logger.LOG.Debug("skill start stamina, skillId: %v, cost: %v", skillId, costStamina)
|
||||
|
||||
// 记录最后释放的技能
|
||||
player.StaminaInfo.SetLastSkill(casterId, skillId)
|
||||
staminaInfo.LastCasterId = casterId
|
||||
staminaInfo.LastSkillId = skillId
|
||||
staminaInfo.LastSkillTime = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// SustainStaminaHandler 处理持续耐力消耗
|
||||
@@ -274,50 +284,6 @@ func (g *GameManager) SustainStaminaHandler(player *model.Player) {
|
||||
g.UpdateStamina(player, staminaInfo.CostStamina)
|
||||
}
|
||||
|
||||
// SetStaminaCost 设置动作需要消耗的耐力
|
||||
func (g *GameManager) SetStaminaCost(player *model.Player, state proto.MotionState) {
|
||||
staminaInfo := player.StaminaInfo
|
||||
|
||||
// 根据状态决定要修改的耐力
|
||||
// TODO 角色天赋 食物 会影响耐力消耗
|
||||
switch state {
|
||||
// 消耗耐力
|
||||
case proto.MotionState_MOTION_STATE_DASH:
|
||||
// 快速跑步
|
||||
staminaInfo.CostStamina = constant.StaminaCostConst.DASH
|
||||
case proto.MotionState_MOTION_STATE_FLY, proto.MotionState_MOTION_STATE_FLY_FAST, proto.MotionState_MOTION_STATE_FLY_SLOW:
|
||||
// 滑翔
|
||||
staminaInfo.CostStamina = constant.StaminaCostConst.FLY
|
||||
case proto.MotionState_MOTION_STATE_SWIM_DASH:
|
||||
// 快速游泳
|
||||
staminaInfo.CostStamina = constant.StaminaCostConst.SWIM_DASH
|
||||
case proto.MotionState_MOTION_STATE_SKIFF_DASH:
|
||||
// 浪船加速
|
||||
// TODO 玩家使用载具时需要用载具的协议发送prop
|
||||
staminaInfo.CostStamina = constant.StaminaCostConst.SKIFF_DASH
|
||||
// 恢复耐力
|
||||
case proto.MotionState_MOTION_STATE_DANGER_RUN, proto.MotionState_MOTION_STATE_RUN:
|
||||
// 正常跑步
|
||||
staminaInfo.CostStamina = constant.StaminaCostConst.RUN
|
||||
case 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:
|
||||
// 站立
|
||||
staminaInfo.CostStamina = constant.StaminaCostConst.STANDBY
|
||||
case proto.MotionState_MOTION_STATE_DANGER_WALK, proto.MotionState_MOTION_STATE_WALK:
|
||||
// 走路
|
||||
staminaInfo.CostStamina = constant.StaminaCostConst.WALK
|
||||
case proto.MotionState_MOTION_STATE_POWERED_FLY:
|
||||
// 滑翔加速 (风圈等)
|
||||
staminaInfo.CostStamina = constant.StaminaCostConst.POWERED_FLY
|
||||
case proto.MotionState_MOTION_STATE_SKIFF_POWERED_DASH:
|
||||
// 浪船加速 (风圈等)
|
||||
staminaInfo.CostStamina = constant.StaminaCostConst.POWERED_SKIFF
|
||||
// 缓慢动作将在客户端发送消息后消耗
|
||||
case proto.MotionState_MOTION_STATE_CLIMB, proto.MotionState_MOTION_STATE_SWIM_MOVE:
|
||||
// 缓慢攀爬 或 缓慢游泳
|
||||
staminaInfo.CostStamina = 0
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateStamina 更新耐力 当前耐力值 + 消耗的耐力值
|
||||
func (g *GameManager) UpdateStamina(player *model.Player, staminaCost int32) {
|
||||
// 耐力增加0是没有意义的
|
||||
@@ -330,10 +296,29 @@ func (g *GameManager) UpdateStamina(player *model.Player, staminaCost int32) {
|
||||
player.StaminaInfo.RestoreDelay = 0
|
||||
}
|
||||
|
||||
// 玩家最大耐力值
|
||||
maxStamina := int32(player.PropertiesMap[constant.PlayerPropertyConst.PROP_MAX_STAMINA])
|
||||
// 玩家现行耐力值
|
||||
curStamina := int32(player.PropertiesMap[constant.PlayerPropertyConst.PROP_CUR_PERSIST_STAMINA])
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
scene := world.GetSceneById(player.SceneId)
|
||||
|
||||
// 最大耐力值 现行耐力值
|
||||
var maxStamina, curStamina int32
|
||||
// 玩家是否处于载具中
|
||||
var isInVehicle bool
|
||||
|
||||
// 获取载具实体
|
||||
entity := g.GetSceneVehicleEntity(scene, player.VehicleInfo.InVehicleEntityId)
|
||||
// 判断玩家处于载具中
|
||||
if entity != nil && g.IsPlayerInVehicle(player, entity.gadgetEntity.gadgetVehicleEntity) {
|
||||
// 载具耐力
|
||||
// 因为载具的耐力需要换算
|
||||
// 这里先*100后面要用的时候再换算 为了确保精度
|
||||
maxStamina = int32(entity.gadgetEntity.gadgetVehicleEntity.maxStamina * 100)
|
||||
curStamina = int32(entity.gadgetEntity.gadgetVehicleEntity.curStamina * 100)
|
||||
isInVehicle = true
|
||||
} else {
|
||||
// 角色耐力
|
||||
maxStamina = int32(player.PropertiesMap[constant.PlayerPropertyConst.PROP_MAX_STAMINA])
|
||||
curStamina = int32(player.PropertiesMap[constant.PlayerPropertyConst.PROP_CUR_PERSIST_STAMINA])
|
||||
}
|
||||
|
||||
// 即将更改为的耐力值
|
||||
stamina := curStamina + staminaCost
|
||||
@@ -350,15 +335,35 @@ func (g *GameManager) UpdateStamina(player *model.Player, staminaCost int32) {
|
||||
return
|
||||
}
|
||||
|
||||
g.SetStamina(player, uint32(stamina))
|
||||
if isInVehicle {
|
||||
// 修改载具现行耐力
|
||||
g.SetVehicleStamina(player, entity.gadgetEntity.gadgetVehicleEntity, float32(stamina)/100)
|
||||
} else {
|
||||
// 修改玩家现行耐力
|
||||
g.SetPlayerStamina(player, uint32(stamina))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// SetStamina 设置玩家的耐力
|
||||
func (g *GameManager) SetStamina(player *model.Player, stamina uint32) {
|
||||
// SetVehicleStamina 设置载具的耐力
|
||||
func (g *GameManager) SetVehicleStamina(player *model.Player, gadgetVehicleEntity *GadgetVehicleEntity, stamina float32) {
|
||||
// 设置载具的耐力
|
||||
gadgetVehicleEntity.curStamina = stamina
|
||||
logger.LOG.Debug("vehicle stamina set, stamina: %v", stamina)
|
||||
|
||||
// PacketVehicleStaminaNotify
|
||||
vehicleStaminaNotify := new(proto.VehicleStaminaNotify)
|
||||
vehicleStaminaNotify.EntityId = player.VehicleInfo.InVehicleEntityId
|
||||
vehicleStaminaNotify.CurStamina = stamina
|
||||
g.SendMsg(cmd.VehicleStaminaNotify, player.PlayerID, player.ClientSeq, vehicleStaminaNotify)
|
||||
}
|
||||
|
||||
// SetPlayerStamina 设置玩家的耐力
|
||||
func (g *GameManager) SetPlayerStamina(player *model.Player, stamina uint32) {
|
||||
// 设置玩家的耐力
|
||||
prop := constant.PlayerPropertyConst.PROP_CUR_PERSIST_STAMINA
|
||||
// 设置玩家的耐力prop
|
||||
player.PropertiesMap[prop] = stamina
|
||||
//logger.LOG.Debug("player curr stamina: %v", stamina)
|
||||
logger.LOG.Debug("player stamina set, stamina: %v", stamina)
|
||||
|
||||
// PacketPlayerPropNotify
|
||||
playerPropNotify := new(proto.PlayerPropNotify)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"hk4e/pkg/logger"
|
||||
"hk4e/protocol/cmd"
|
||||
"hk4e/protocol/proto"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CreateVehicleReq 创建载具
|
||||
@@ -15,37 +16,20 @@ func (g *GameManager) CreateVehicleReq(player *model.Player, payloadMsg pb.Messa
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
scene := world.GetSceneById(player.SceneId)
|
||||
|
||||
// TODO req.ScenePointId 验证浪船锚点是否已解锁
|
||||
// 创建载具冷却时间
|
||||
createVehicleCd := int64(5000) // TODO 冷却时间读取配置表
|
||||
if time.Now().UnixMilli()-player.VehicleInfo.LastCreateTime < createVehicleCd {
|
||||
g.CommonRetError(cmd.VehicleInteractRsp, player, &proto.VehicleInteractRsp{}, proto.Retcode_RET_CREATE_VEHICLE_IN_CD)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO req.ScenePointId 验证浪船锚点是否已解锁 Retcode_RET_VEHICLE_POINT_NOT_UNLOCK
|
||||
|
||||
// TODO 验证将要创建的载具位置是否有效 Retcode_RET_CREATE_VEHICLE_POS_INVALID
|
||||
|
||||
// 清除已创建的载具
|
||||
for _, id := range scene.GetEntityIdList() {
|
||||
entity := scene.GetEntity(id)
|
||||
// 判断实体类型是否为载具
|
||||
if entity.entityType != uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_GADGET) || entity.gadgetEntity.gadgetType != GADGET_TYPE_VEHICLE {
|
||||
continue
|
||||
}
|
||||
// 确保载具Id为将要创建的 (每种载具允许存在1个)
|
||||
if entity.gadgetEntity.gadgetVehicleEntity.vehicleId != req.VehicleId {
|
||||
continue
|
||||
}
|
||||
// 该载具是否为此玩家的
|
||||
if entity.gadgetEntity.gadgetVehicleEntity.owner != player {
|
||||
continue
|
||||
}
|
||||
// 现行角色Guid
|
||||
avatar, ok := player.AvatarMap[player.TeamConfig.GetActiveAvatarId()]
|
||||
if !ok {
|
||||
logger.LOG.Error("avatar is nil, avatarId: %v", player.TeamConfig.GetActiveAvatarId())
|
||||
g.CommonRetError(cmd.CreateVehicleRsp, player, &proto.CreateVehicleRsp{})
|
||||
return
|
||||
}
|
||||
// 确保玩家正在载具中
|
||||
if g.IsPlayerInVehicle(player, entity.gadgetEntity.gadgetVehicleEntity) {
|
||||
// 离开载具
|
||||
g.ExitVehicle(player, entity, avatar.Guid)
|
||||
}
|
||||
// TODO 删除实体 需要杀死实体 暂时实体模块还没写这个
|
||||
// scene.DestroyEntity(entity.id)
|
||||
if player.VehicleInfo.LastCreateEntityId != 0 {
|
||||
g.DestroyVehicleEntity(player, scene, req.VehicleId, player.VehicleInfo.LastCreateEntityId)
|
||||
}
|
||||
|
||||
// 创建载具实体
|
||||
@@ -54,11 +38,16 @@ func (g *GameManager) CreateVehicleReq(player *model.Player, payloadMsg pb.Messa
|
||||
entityId := scene.CreateEntityGadgetVehicle(player.PlayerID, pos, rot, req.VehicleId)
|
||||
if entityId == 0 {
|
||||
logger.LOG.Error("vehicle entityId is 0, uid: %v", player.PlayerID)
|
||||
g.CommonRetError(cmd.CreateVehicleRsp, player, &proto.CreateVehicleRsp{})
|
||||
g.CommonRetError(cmd.VehicleInteractRsp, player, &proto.VehicleInteractRsp{})
|
||||
return
|
||||
}
|
||||
GAME_MANAGER.AddSceneEntityNotify(player, proto.VisionType_VISION_TYPE_BORN, []uint32{entityId}, true, false)
|
||||
|
||||
// 记录创建的载具信息
|
||||
player.VehicleInfo.LastCreateEntityId = entityId
|
||||
player.VehicleInfo.LastCreateTime = time.Now().UnixMilli()
|
||||
|
||||
// PacketCreateVehicleRsp
|
||||
createVehicleRsp := &proto.CreateVehicleRsp{
|
||||
VehicleId: req.VehicleId,
|
||||
EntityId: entityId,
|
||||
@@ -66,8 +55,24 @@ func (g *GameManager) CreateVehicleReq(player *model.Player, payloadMsg pb.Messa
|
||||
g.SendMsg(cmd.CreateVehicleRsp, player.PlayerID, player.ClientSeq, createVehicleRsp)
|
||||
}
|
||||
|
||||
// GetSceneVehicleEntity 获取场景内的载具实体
|
||||
func (g *GameManager) GetSceneVehicleEntity(scene *Scene, entityId uint32) *Entity {
|
||||
entity := scene.GetEntity(entityId)
|
||||
if entity == nil {
|
||||
return nil
|
||||
}
|
||||
// 确保实体类型是否为载具
|
||||
if entity.entityType == uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_GADGET) && entity.gadgetEntity.gadgetType == GADGET_TYPE_VEHICLE {
|
||||
return entity
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsPlayerInVehicle 判断玩家是否在载具中
|
||||
func (g *GameManager) IsPlayerInVehicle(player *model.Player, gadgetVehicleEntity *GadgetVehicleEntity) bool {
|
||||
if gadgetVehicleEntity == nil {
|
||||
return false
|
||||
}
|
||||
for _, p := range gadgetVehicleEntity.memberMap {
|
||||
if p == player {
|
||||
return true
|
||||
@@ -76,28 +81,61 @@ func (g *GameManager) IsPlayerInVehicle(player *model.Player, gadgetVehicleEntit
|
||||
return false
|
||||
}
|
||||
|
||||
// EnterVehicle 进入载具
|
||||
func (g *GameManager) EnterVehicle(player *model.Player, entity *Entity, avatarGuid uint64) {
|
||||
// 玩家是否已进入载具
|
||||
if g.IsPlayerInVehicle(player, entity.gadgetEntity.gadgetVehicleEntity) {
|
||||
logger.LOG.Error("vehicle has equal player, uid: %v", player.PlayerID)
|
||||
g.CommonRetError(cmd.VehicleInteractRsp, player, &proto.VehicleInteractRsp{})
|
||||
// DestroyVehicleEntity 删除载具实体
|
||||
func (g *GameManager) DestroyVehicleEntity(player *model.Player, scene *Scene, vehicleId uint32, entityId uint32) {
|
||||
entity := g.GetSceneVehicleEntity(scene, entityId)
|
||||
if entity == nil {
|
||||
return
|
||||
}
|
||||
// 找出载具空闲的位置
|
||||
pos := uint32(0)
|
||||
for entity.gadgetEntity.gadgetVehicleEntity.memberMap[pos] != nil {
|
||||
pos++
|
||||
// 确保载具Id为将要创建的 (每种载具允许存在1个)
|
||||
if entity.gadgetEntity.gadgetVehicleEntity.vehicleId != vehicleId {
|
||||
return
|
||||
}
|
||||
// 载具成员记录玩家
|
||||
entity.gadgetEntity.gadgetVehicleEntity.memberMap[pos] = player
|
||||
// 该载具是否为此玩家的
|
||||
if entity.gadgetEntity.gadgetVehicleEntity.owner != player {
|
||||
return
|
||||
}
|
||||
// 确保玩家正在载具中
|
||||
if g.IsPlayerInVehicle(player, entity.gadgetEntity.gadgetVehicleEntity) {
|
||||
// 离开载具
|
||||
g.ExitVehicle(player, entity, player.AvatarMap[player.TeamConfig.GetActiveAvatarId()].Guid)
|
||||
}
|
||||
// 删除已创建的载具
|
||||
scene.DestroyEntity(entity.id)
|
||||
g.RemoveSceneEntityNotifyBroadcast(scene, proto.VisionType_VISION_TYPE_MISS, []uint32{entity.id})
|
||||
}
|
||||
|
||||
// EnterVehicle 进入载具
|
||||
func (g *GameManager) EnterVehicle(player *model.Player, entity *Entity, avatarGuid uint64) {
|
||||
maxSlot := 1 // TODO 读取配置表
|
||||
// 判断载具是否已满
|
||||
if len(entity.gadgetEntity.gadgetVehicleEntity.memberMap) >= maxSlot {
|
||||
g.CommonRetError(cmd.VehicleInteractRsp, player, &proto.VehicleInteractRsp{}, proto.Retcode_RET_VEHICLE_SLOT_OCCUPIED)
|
||||
return
|
||||
}
|
||||
|
||||
// 找出载具空闲的位置
|
||||
var freePos uint32
|
||||
for i := uint32(0); i < uint32(maxSlot); i++ {
|
||||
p := entity.gadgetEntity.gadgetVehicleEntity.memberMap[i]
|
||||
// 玩家如果已进入载具重复记录不进行报错
|
||||
if p == player || p == nil {
|
||||
// 载具成员记录玩家
|
||||
entity.gadgetEntity.gadgetVehicleEntity.memberMap[i] = player
|
||||
freePos = i
|
||||
}
|
||||
}
|
||||
|
||||
// 记录玩家所在的载具信息
|
||||
player.VehicleInfo.InVehicleEntityId = entity.id
|
||||
|
||||
// PacketVehicleInteractRsp
|
||||
vehicleInteractRsp := &proto.VehicleInteractRsp{
|
||||
InteractType: proto.VehicleInteractType_VEHICLE_INTERACT_TYPE_IN,
|
||||
Member: &proto.VehicleMember{
|
||||
Uid: player.PlayerID,
|
||||
AvatarGuid: avatarGuid,
|
||||
Pos: pos, // 应该是多人坐船时的位置?
|
||||
Pos: freePos, // 应该是多人坐船时的位置?
|
||||
},
|
||||
EntityId: entity.id,
|
||||
}
|
||||
@@ -109,7 +147,7 @@ func (g *GameManager) ExitVehicle(player *model.Player, entity *Entity, avatarGu
|
||||
// 玩家是否进入载具
|
||||
if !g.IsPlayerInVehicle(player, entity.gadgetEntity.gadgetVehicleEntity) {
|
||||
logger.LOG.Error("vehicle not has player, uid: %v", player.PlayerID)
|
||||
g.SendMsg(cmd.VehicleInteractRsp, player.PlayerID, player.ClientSeq, &proto.VehicleInteractRsp{Retcode: int32(proto.Retcode_RET_NOT_IN_VEHICLE)})
|
||||
g.CommonRetError(cmd.VehicleInteractRsp, player, &proto.VehicleInteractRsp{}, proto.Retcode_RET_NOT_IN_VEHICLE)
|
||||
return
|
||||
}
|
||||
// 载具成员删除玩家
|
||||
@@ -120,7 +158,10 @@ func (g *GameManager) ExitVehicle(player *model.Player, entity *Entity, avatarGu
|
||||
delete(entity.gadgetEntity.gadgetVehicleEntity.memberMap, pos)
|
||||
}
|
||||
}
|
||||
// 清除记录的所在载具信息
|
||||
player.VehicleInfo.InVehicleEntityId = 0
|
||||
|
||||
// PacketVehicleInteractRsp
|
||||
vehicleInteractRsp := &proto.VehicleInteractRsp{
|
||||
InteractType: proto.VehicleInteractType_VEHICLE_INTERACT_TYPE_OUT,
|
||||
Member: &proto.VehicleMember{
|
||||
@@ -137,34 +178,31 @@ func (g *GameManager) ExitVehicle(player *model.Player, entity *Entity, avatarGu
|
||||
func (g *GameManager) VehicleInteractReq(player *model.Player, payloadMsg pb.Message) {
|
||||
req := payloadMsg.(*proto.VehicleInteractReq)
|
||||
|
||||
// 获取载具实体
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
entity := world.GetSceneById(player.SceneId).GetEntity(req.EntityId)
|
||||
scene := world.GetSceneById(player.SceneId)
|
||||
|
||||
// 获取载具实体
|
||||
entity := g.GetSceneVehicleEntity(scene, req.EntityId)
|
||||
if entity == nil {
|
||||
logger.LOG.Error("vehicle entity is nil, entityId: %v", req.EntityId)
|
||||
g.CommonRetError(cmd.VehicleInteractRsp, player, &proto.VehicleInteractRsp{})
|
||||
g.CommonRetError(cmd.VehicleInteractRsp, player, &proto.VehicleInteractRsp{}, proto.Retcode_RET_ENTITY_NOT_EXIST)
|
||||
return
|
||||
}
|
||||
// 判断实体类型是否为载具
|
||||
if entity.entityType != uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_GADGET) || entity.gadgetEntity.gadgetType != GADGET_TYPE_VEHICLE {
|
||||
logger.LOG.Error("vehicle entity error, entityType: %v", entity.entityType)
|
||||
g.SendMsg(cmd.VehicleInteractRsp, player.PlayerID, player.ClientSeq, &proto.VehicleInteractRsp{Retcode: int32(proto.Retcode_RET_GADGET_NOT_VEHICLE)})
|
||||
return
|
||||
}
|
||||
// 现行角色Guid
|
||||
avatar, ok := player.AvatarMap[player.TeamConfig.GetActiveAvatarId()]
|
||||
if !ok {
|
||||
logger.LOG.Error("avatar is nil, avatarId: %v", player.TeamConfig.GetActiveAvatarId())
|
||||
g.CommonRetError(cmd.VehicleInteractRsp, player, &proto.VehicleInteractRsp{})
|
||||
g.CommonRetError(cmd.VehicleInteractRsp, player, &proto.VehicleInteractRsp{}, proto.Retcode_RET_GADGET_NOT_VEHICLE)
|
||||
return
|
||||
}
|
||||
|
||||
avatarGuid := player.AvatarMap[player.TeamConfig.GetActiveAvatarId()].Guid
|
||||
|
||||
switch req.InteractType {
|
||||
case proto.VehicleInteractType_VEHICLE_INTERACT_TYPE_IN:
|
||||
// 进入载具
|
||||
g.EnterVehicle(player, entity, avatar.Guid)
|
||||
g.EnterVehicle(player, entity, avatarGuid)
|
||||
case proto.VehicleInteractType_VEHICLE_INTERACT_TYPE_OUT:
|
||||
// 离开载具
|
||||
g.ExitVehicle(player, entity, avatar.Guid)
|
||||
g.ExitVehicle(player, entity, avatarGuid)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,6 +540,7 @@ type GadgetGatherEntity struct {
|
||||
type GadgetVehicleEntity struct {
|
||||
vehicleId uint32
|
||||
owner *model.Player
|
||||
maxStamina float32
|
||||
curStamina float32
|
||||
memberMap map[uint32]*model.Player // uint32 = pos
|
||||
}
|
||||
@@ -752,7 +753,8 @@ func (s *Scene) CreateEntityGadgetVehicle(uid uint32, pos, rot *model.Vector, ve
|
||||
gadgetVehicleEntity: &GadgetVehicleEntity{
|
||||
vehicleId: vehicleId,
|
||||
owner: player,
|
||||
curStamina: 240, // TODO 应该也能在配置表找到
|
||||
maxStamina: 240, // TODO 应该也能在配置表找到
|
||||
curStamina: 240, // TODO 与maxStamina一致
|
||||
memberMap: make(map[uint32]*model.Player),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -65,6 +65,7 @@ type Player struct {
|
||||
SceneLoadState int `bson:"-" msgpack:"-"` // 场景加载状态
|
||||
CoopApplyMap map[uint32]int64 `bson:"-" msgpack:"-"` // 敲门申请的玩家uid及时间
|
||||
StaminaInfo *StaminaInfo `bson:"-" msgpack:"-"` // 耐力临时数据
|
||||
VehicleInfo *VehicleInfo `bson:"-" msgpack:"-"` // 载具临时数据
|
||||
ClientSeq uint32 `bson:"-" msgpack:"-"` // 客户端发包请求的序号
|
||||
CombatInvokeHandler *InvokeHandler[proto.CombatInvokeEntry] `bson:"-" msgpack:"-"` // combat转发器
|
||||
AbilityInvokeHandler *InvokeHandler[proto.AbilityInvokeEntry] `bson:"-" msgpack:"-"` // ability转发器
|
||||
@@ -79,6 +80,7 @@ func (p *Player) InitAll() {
|
||||
p.GameObjectGuidMap = make(map[uint64]GameObject)
|
||||
p.CoopApplyMap = make(map[uint32]int64)
|
||||
p.StaminaInfo = new(StaminaInfo)
|
||||
p.VehicleInfo = new(VehicleInfo)
|
||||
p.InitAllAvatar()
|
||||
p.InitAllWeapon()
|
||||
p.InitAllItem()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"hk4e/gs/constant"
|
||||
"hk4e/protocol/proto"
|
||||
"time"
|
||||
)
|
||||
|
||||
type StaminaInfo struct {
|
||||
@@ -14,9 +14,46 @@ type StaminaInfo struct {
|
||||
LastSkillTime int64 // 最后释放技能的时间
|
||||
}
|
||||
|
||||
// SetLastSkill 记录技能以便后续使用
|
||||
func (s *StaminaInfo) SetLastSkill(casterId uint32, skillId uint32) {
|
||||
s.LastCasterId = casterId
|
||||
s.LastSkillId = skillId
|
||||
s.LastSkillTime = time.Now().UnixMilli()
|
||||
// SetStaminaCost 设置动作需要消耗的耐力
|
||||
func (s *StaminaInfo) SetStaminaCost(state proto.MotionState) {
|
||||
// 根据状态决定要修改的耐力
|
||||
// TODO 角色天赋 食物 会影响耐力消耗
|
||||
switch state {
|
||||
// 消耗耐力
|
||||
case proto.MotionState_MOTION_STATE_DASH:
|
||||
// 快速跑步
|
||||
s.CostStamina = constant.StaminaCostConst.DASH
|
||||
case proto.MotionState_MOTION_STATE_FLY, proto.MotionState_MOTION_STATE_FLY_FAST, proto.MotionState_MOTION_STATE_FLY_SLOW:
|
||||
// 滑翔
|
||||
s.CostStamina = constant.StaminaCostConst.FLY
|
||||
case proto.MotionState_MOTION_STATE_SWIM_DASH:
|
||||
// 快速游泳
|
||||
s.CostStamina = constant.StaminaCostConst.SWIM_DASH
|
||||
case proto.MotionState_MOTION_STATE_SKIFF_DASH:
|
||||
// 浪船加速
|
||||
s.CostStamina = constant.StaminaCostConst.SKIFF_DASH
|
||||
// 恢复耐力
|
||||
case proto.MotionState_MOTION_STATE_DANGER_RUN, proto.MotionState_MOTION_STATE_RUN:
|
||||
// 正常跑步
|
||||
s.CostStamina = constant.StaminaCostConst.RUN
|
||||
case 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:
|
||||
// 站立
|
||||
s.CostStamina = constant.StaminaCostConst.STANDBY
|
||||
case proto.MotionState_MOTION_STATE_DANGER_WALK, proto.MotionState_MOTION_STATE_WALK:
|
||||
// 走路
|
||||
s.CostStamina = constant.StaminaCostConst.WALK
|
||||
case proto.MotionState_MOTION_STATE_SKIFF_BOARDING, proto.MotionState_MOTION_STATE_SKIFF_NORMAL:
|
||||
// 浪船正常移动或停下
|
||||
s.CostStamina = constant.StaminaCostConst.SKIFF_NORMAL
|
||||
case proto.MotionState_MOTION_STATE_POWERED_FLY:
|
||||
// 滑翔加速 (风圈等)
|
||||
s.CostStamina = constant.StaminaCostConst.POWERED_FLY
|
||||
case proto.MotionState_MOTION_STATE_SKIFF_POWERED_DASH:
|
||||
// 浪船加速 (风圈等)
|
||||
s.CostStamina = constant.StaminaCostConst.POWERED_SKIFF
|
||||
// 缓慢动作将在客户端发送消息后消耗
|
||||
case proto.MotionState_MOTION_STATE_CLIMB, proto.MotionState_MOTION_STATE_SWIM_MOVE:
|
||||
// 缓慢攀爬 或 缓慢游泳
|
||||
s.CostStamina = 0
|
||||
}
|
||||
}
|
||||
|
||||
7
gs/model/vehicle.go
Normal file
7
gs/model/vehicle.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package model
|
||||
|
||||
type VehicleInfo struct {
|
||||
InVehicleEntityId uint32 // 玩家所在载具的实体Id
|
||||
LastCreateTime int64 // 最后一次创建载具的时间
|
||||
LastCreateEntityId uint32 // 最后一次创建载具的实体Id
|
||||
}
|
||||
Reference in New Issue
Block a user