重击耐力消耗、持续耐力消耗完善

This commit is contained in:
UnKownOwO
2022-12-12 23:20:42 +08:00
parent 3e9e375e19
commit 9dc864ff69
5 changed files with 116 additions and 34 deletions

View File

@@ -21,6 +21,11 @@ type StaminaCost struct {
SKIFF int32 // 游艇行驶 SKIFF int32 // 游艇行驶
STANDBY int32 // 站立 STANDBY int32 // 站立
WALK int32 // 走路 WALK int32 // 走路
// 战斗技能
FIGHT_SWORD_ONE_HAND int32 // 单手剑
FIGHT_POLE int32 // 长枪
FIGHT_CATALYST int32 // 法器
FIGHT_CLAYMORE_PER int32 // 双手剑 (每秒消耗)
} }
func InitStaminaCostConst() { func InitStaminaCostConst() {
@@ -42,4 +47,8 @@ func InitStaminaCostConst() {
StaminaCostConst.SKIFF = 500 StaminaCostConst.SKIFF = 500
StaminaCostConst.STANDBY = 500 StaminaCostConst.STANDBY = 500
StaminaCostConst.WALK = 500 StaminaCostConst.WALK = 500
StaminaCostConst.FIGHT_SWORD_ONE_HAND = -2000
StaminaCostConst.FIGHT_POLE = -2500
StaminaCostConst.FIGHT_CATALYST = -5000
StaminaCostConst.FIGHT_CLAYMORE_PER = -4000
} }

View File

@@ -279,6 +279,9 @@ func (g *GameManager) EvtDoSkillSuccNotify(player *model.Player, payloadMsg pb.M
return return
} }
logger.LOG.Debug("EvtDoSkillSuccNotify: %v", req) logger.LOG.Debug("EvtDoSkillSuccNotify: %v", req)
// 记录耐力消耗的技能id 技能持续消耗需要这个获取到技能id
player.StaminaInfo.SetLastSkill(req.CasterId, req.SkillId)
} }
func (g *GameManager) EvtAvatarEnterFocusNotify(player *model.Player, payloadMsg pb.Message) { func (g *GameManager) EvtAvatarEnterFocusNotify(player *model.Player, payloadMsg pb.Message) {

View File

@@ -16,13 +16,14 @@ import (
func (g *GameManager) HandleAbilityStamina(player *model.Player, entry *proto.AbilityInvokeEntry) { func (g *GameManager) HandleAbilityStamina(player *model.Player, entry *proto.AbilityInvokeEntry) {
switch entry.ArgumentType { switch entry.ArgumentType {
case proto.AbilityInvokeArgument_ABILITY_INVOKE_ARGUMENT_MIXIN_COST_STAMINA: case proto.AbilityInvokeArgument_ABILITY_INVOKE_ARGUMENT_MIXIN_COST_STAMINA:
// 大剑重击耐力消耗 // 大剑重击 或 持续技能 耐力消耗
costStamina := new(proto.AbilityMixinCostStamina) costStamina := new(proto.AbilityMixinCostStamina)
err := pb.Unmarshal(entry.AbilityData, costStamina) err := pb.Unmarshal(entry.AbilityData, costStamina)
if err != nil { if err != nil {
logger.LOG.Error("unmarshal ability data err: %v", err) logger.LOG.Error("unmarshal ability data err: %v", err)
return return
} }
// 处理持续耐力消耗
g.HandleSkillSustainStamina(player) g.HandleSkillSustainStamina(player)
case proto.AbilityInvokeArgument_ABILITY_INVOKE_ARGUMENT_META_MODIFIER_CHANGE: case proto.AbilityInvokeArgument_ABILITY_INVOKE_ARGUMENT_META_MODIFIER_CHANGE:
// 普通角色重击耐力消耗 // 普通角色重击耐力消耗
@@ -54,9 +55,8 @@ func (g *GameManager) HandleAbilityStamina(player *model.Player, entry *proto.Ab
if avatarAbility == nil { if avatarAbility == nil {
return return
} }
// 获取该技能对应的耐力消耗 // 重击对应的耐力消耗
_ = avatarAbility.CostStamina g.HandleChargedAttackStamina(player, worldAvatar, avatarAbility)
logger.LOG.Error("%v", avatarAbility.CostStamina)
default: default:
break break
} }
@@ -146,37 +146,93 @@ func (g *GameManager) HandleStamina(player *model.Player, motionState proto.Moti
// HandleSkillSustainStamina 处理技能持续时的耐力消耗 // HandleSkillSustainStamina 处理技能持续时的耐力消耗
func (g *GameManager) HandleSkillSustainStamina(player *model.Player) { func (g *GameManager) HandleSkillSustainStamina(player *model.Player) {
skillId := player.StaminaInfo.LastSkillId staminaInfo := player.StaminaInfo
logger.LOG.Error("stamina skill sustain, skillId: %v", skillId) skillId := staminaInfo.LastSkillId
// 读取技能配置表
avatarSkillConfig, ok := gdconf.CONF.AvatarSkillDataMap[int32(skillId)] avatarSkillConfig, ok := gdconf.CONF.AvatarSkillDataMap[int32(skillId)]
if !ok { if !ok {
logger.LOG.Error("avatarSkillConfig error, skillId: %v", skillId) logger.LOG.Error("avatarSkillConfig error, skillId: %v", skillId)
return return
} }
// 距离上次执行过去的时间 // 获取释放技能者的角色Id
pastTime := time.Now().UnixMilli() - player.StaminaInfo.LastSkillTime world := WORLD_MANAGER.GetWorldByID(player.WorldId)
// 根据配置以及距离上次的时间计算消耗的耐力 // 获取世界中的角色实体
g.UpdateStamina(player, -(int32(pastTime/1000)*avatarSkillConfig.CostStamina)*100) worldAvatar := world.GetWorldAvatarByEntityId(staminaInfo.LastCasterId)
if worldAvatar == nil {
return
}
// 获取现行角色的配置表
avatarDataConfig, ok := gdconf.CONF.AvatarDataMap[int32(worldAvatar.avatarId)]
if !ok {
logger.LOG.Error("avatarDataConfig error, avatarId: %v", worldAvatar.avatarId)
return
}
// 记录最后释放技能时间 // 需要消耗的耐力值
player.StaminaInfo.LastSkillTime = time.Now().UnixMilli() var costStamina int32
// 如果为0代表使用默认值
if avatarSkillConfig.CostStamina == 0 {
// 大剑持续耐力消耗默认值
if avatarDataConfig.WeaponType == constant.WeaponTypeConst.WEAPON_CLAYMORE {
costStamina = constant.StaminaCostConst.FIGHT_CLAYMORE_PER
}
} else {
costStamina = -(avatarSkillConfig.CostStamina * 100)
}
// 距离上次执行过去的时间
pastTime := time.Now().UnixMilli() - staminaInfo.LastSkillTime
// 根据配置以及距离上次的时间计算消耗的耐力
costStamina = int32(float64(pastTime) / 1000 * float64(costStamina))
logger.LOG.Debug("stamina skill sustain, skillId: %v, cost: %v", skillId, costStamina)
// 根据配置以及距离上次的时间计算消耗的耐力
g.UpdateStamina(player, costStamina)
// 记录最后释放的技能
player.StaminaInfo.SetLastSkill(staminaInfo.LastCasterId, staminaInfo.LastSkillId)
} }
//// HandleSkillStartStamina 处理技能开始时即时耐力消耗 // HandleChargedAttackStamina 处理重击技能即时耐力消耗
//func (g *GameManager) HandleSkillStartStamina(player *model.Player, skillId uint32) { func (g *GameManager) HandleChargedAttackStamina(player *model.Player, worldAvatar *WorldAvatar, skillData *gdconf.AvatarSkillData) {
// logger.LOG.Error("stamina skill start, skillId: %v", skillId) // 获取现行角色的配置表
// avatarSkillConfig, ok := gdconf.CONF.AvatarSkillDataMap[int32(skillId)] avatarDataConfig, ok := gdconf.CONF.AvatarDataMap[int32(worldAvatar.avatarId)]
// if !ok { if !ok {
// logger.LOG.Error("avatarSkillConfig error, skillId: %v", skillId) logger.LOG.Error("avatarDataConfig error, avatarId: %v", worldAvatar.avatarId)
// return return
// } }
// // 根据配置消耗耐力
// g.UpdateStamina(player, -avatarSkillConfig.CostStamina*100) // 需要消耗的耐力值
// var costStamina int32
// // 记录最后释放的技能
// player.StaminaInfo.LastSkillId = skillId // 如果为0代表使用默认值
// player.StaminaInfo.LastSkillTime = time.Now().UnixMilli() if skillData.CostStamina == 0 {
//} // 使用武器对应默认耐力消耗
// 双手剑为持续耐力消耗不在这里处理
switch avatarDataConfig.WeaponType {
case constant.WeaponTypeConst.WEAPON_SWORD_ONE_HAND:
// 单手剑
costStamina = constant.StaminaCostConst.FIGHT_SWORD_ONE_HAND
case constant.WeaponTypeConst.WEAPON_POLE:
// 长枪
costStamina = constant.StaminaCostConst.FIGHT_POLE
case constant.WeaponTypeConst.WEAPON_CATALYST:
// 法器
costStamina = constant.StaminaCostConst.FIGHT_CATALYST
}
} else {
costStamina = -(skillData.CostStamina * 100)
}
logger.LOG.Debug("charged attack stamina, skillId: %v, cost: %v", skillData.AvatarSkillId, costStamina)
// 根据配置消耗耐力
g.UpdateStamina(player, costStamina)
// 记录最后释放的技能
player.StaminaInfo.SetLastSkill(worldAvatar.avatarEntityId, uint32(skillData.AvatarSkillId))
}
// StaminaHandler 处理持续耐力消耗 // StaminaHandler 处理持续耐力消耗
func (g *GameManager) StaminaHandler(player *model.Player) { func (g *GameManager) StaminaHandler(player *model.Player) {
@@ -188,8 +244,8 @@ func (g *GameManager) StaminaHandler(player *model.Player) {
// 添加的耐力大于0为恢复 // 添加的耐力大于0为恢复
if staminaInfo.CostStamina > 0 { if staminaInfo.CostStamina > 0 {
// 耐力延迟1s(5 ticks)恢复 动作状态为加速将立刻恢复耐力 // 耐力延迟2s(10 ticks)恢复 动作状态为加速将立刻恢复耐力
if staminaInfo.RestoreDelay < 5 && (staminaInfo.State != proto.MotionState_MOTION_STATE_POWERED_FLY && staminaInfo.State != proto.MotionState_MOTION_STATE_SKIFF_POWERED_DASH) { if staminaInfo.RestoreDelay < 10 && (staminaInfo.State != proto.MotionState_MOTION_STATE_POWERED_FLY && staminaInfo.State != proto.MotionState_MOTION_STATE_SKIFF_POWERED_DASH) {
//logger.LOG.Debug("stamina delay add, restoreDelay: %v", staminaInfo.RestoreDelay) //logger.LOG.Debug("stamina delay add, restoreDelay: %v", staminaInfo.RestoreDelay)
staminaInfo.RestoreDelay++ staminaInfo.RestoreDelay++
return // 不恢复耐力 return // 不恢复耐力
@@ -271,6 +327,11 @@ func (g *GameManager) UpdateStamina(player *model.Player, staminaCost int32) {
stamina = 0 stamina = 0
} }
// 当前无变动不要频繁发包
if curStamina == stamina {
return
}
g.SetStamina(player, uint32(stamina)) g.SetStamina(player, uint32(stamina))
} }
@@ -280,10 +341,6 @@ func (g *GameManager) SetStamina(player *model.Player, stamina uint32) {
// 设置玩家的耐力prop // 设置玩家的耐力prop
player.PropertiesMap[prop] = stamina player.PropertiesMap[prop] = stamina
//logger.LOG.Debug("player curr stamina: %v", stamina) //logger.LOG.Debug("player curr stamina: %v", stamina)
// 当前无变动不要频繁发包
if player.PropertiesMap[constant.PlayerPropertyConst.PROP_MAX_STAMINA] == player.PropertiesMap[constant.PlayerPropertyConst.PROP_CUR_PERSIST_STAMINA] {
return
}
// PacketPlayerPropNotify // PacketPlayerPropNotify
playerPropNotify := new(proto.PlayerPropNotify) playerPropNotify := new(proto.PlayerPropNotify)

View File

@@ -47,7 +47,11 @@ func (p *Player) InitAllAvatar() {
} }
func (p *Player) InitAvatar(avatar *Avatar) { func (p *Player) InitAvatar(avatar *Avatar) {
avatarDataConfig := gdc.CONF.AvatarDataMap[int32(avatar.AvatarId)] avatarDataConfig, ok := gdc.CONF.AvatarDataMap[int32(avatar.AvatarId)]
if !ok {
logger.LOG.Error("avatarDataConfig error, avatarId: %v", avatar.AvatarId)
return
}
// 角色战斗属性 // 角色战斗属性
avatar.FightPropMap = make(map[uint32]float32) avatar.FightPropMap = make(map[uint32]float32)
avatar.FightPropMap[uint32(constant.FightPropertyConst.FIGHT_PROP_NONE)] = 0.0 avatar.FightPropMap[uint32(constant.FightPropertyConst.FIGHT_PROP_NONE)] = 0.0

View File

@@ -2,12 +2,21 @@ package model
import ( import (
"hk4e/protocol/proto" "hk4e/protocol/proto"
"time"
) )
type StaminaInfo struct { type StaminaInfo struct {
State proto.MotionState // 动作状态 State proto.MotionState // 动作状态
CostStamina int32 // 消耗或恢复的耐力 CostStamina int32 // 消耗或恢复的耐力
RestoreDelay uint8 // 恢复延迟 RestoreDelay uint8 // 恢复延迟
LastCasterId uint32 // 最后释放技能者的Id
LastSkillId uint32 // 最后释放的技能Id LastSkillId uint32 // 最后释放的技能Id
LastSkillTime int64 // 最后释放技能的时间 LastSkillTime int64 // 最后释放技能的时间
} }
// SetLastSkill 记录技能以便后续使用
func (s *StaminaInfo) SetLastSkill(casterId uint32, skillId uint32) {
s.LastCasterId = casterId
s.LastSkillId = skillId
s.LastSkillTime = time.Now().UnixMilli()
}