From 9dc864ff69ffca6db48aacedfc8fbf6c5c9f8732 Mon Sep 17 00:00:00 2001 From: UnKownOwO <80520429@qq.com> Date: Mon, 12 Dec 2022 23:20:42 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=87=BB=E8=80=90=E5=8A=9B=E6=B6=88?= =?UTF-8?q?=E8=80=97=E3=80=81=E6=8C=81=E7=BB=AD=E8=80=90=E5=8A=9B=E6=B6=88?= =?UTF-8?q?=E8=80=97=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gs/constant/stamina_cost.go | 9 +++ gs/game/user_fight_sync.go | 3 + gs/game/user_stamina.go | 123 ++++++++++++++++++++++++++---------- gs/model/avatar.go | 6 +- gs/model/stamina.go | 9 +++ 5 files changed, 116 insertions(+), 34 deletions(-) diff --git a/gs/constant/stamina_cost.go b/gs/constant/stamina_cost.go index 118e2d14..9ac3df97 100644 --- a/gs/constant/stamina_cost.go +++ b/gs/constant/stamina_cost.go @@ -21,6 +21,11 @@ type StaminaCost struct { SKIFF int32 // 游艇行驶 STANDBY int32 // 站立 WALK int32 // 走路 + // 战斗技能 + FIGHT_SWORD_ONE_HAND int32 // 单手剑 + FIGHT_POLE int32 // 长枪 + FIGHT_CATALYST int32 // 法器 + FIGHT_CLAYMORE_PER int32 // 双手剑 (每秒消耗) } func InitStaminaCostConst() { @@ -42,4 +47,8 @@ func InitStaminaCostConst() { StaminaCostConst.SKIFF = 500 StaminaCostConst.STANDBY = 500 StaminaCostConst.WALK = 500 + StaminaCostConst.FIGHT_SWORD_ONE_HAND = -2000 + StaminaCostConst.FIGHT_POLE = -2500 + StaminaCostConst.FIGHT_CATALYST = -5000 + StaminaCostConst.FIGHT_CLAYMORE_PER = -4000 } diff --git a/gs/game/user_fight_sync.go b/gs/game/user_fight_sync.go index d8882c5d..c5908a8e 100644 --- a/gs/game/user_fight_sync.go +++ b/gs/game/user_fight_sync.go @@ -279,6 +279,9 @@ func (g *GameManager) EvtDoSkillSuccNotify(player *model.Player, payloadMsg pb.M return } 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) { diff --git a/gs/game/user_stamina.go b/gs/game/user_stamina.go index ccc67b48..bddfb7e5 100644 --- a/gs/game/user_stamina.go +++ b/gs/game/user_stamina.go @@ -16,13 +16,14 @@ import ( func (g *GameManager) HandleAbilityStamina(player *model.Player, entry *proto.AbilityInvokeEntry) { switch entry.ArgumentType { case proto.AbilityInvokeArgument_ABILITY_INVOKE_ARGUMENT_MIXIN_COST_STAMINA: - // 大剑重击耐力消耗 + // 大剑重击 或 持续技能 耐力消耗 costStamina := new(proto.AbilityMixinCostStamina) err := pb.Unmarshal(entry.AbilityData, costStamina) if err != nil { logger.LOG.Error("unmarshal ability data err: %v", err) return } + // 处理持续耐力消耗 g.HandleSkillSustainStamina(player) 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 { return } - // 获取该技能对应的耐力消耗 - _ = avatarAbility.CostStamina - logger.LOG.Error("%v", avatarAbility.CostStamina) + // 重击对应的耐力消耗 + g.HandleChargedAttackStamina(player, worldAvatar, avatarAbility) default: break } @@ -146,37 +146,93 @@ func (g *GameManager) HandleStamina(player *model.Player, motionState proto.Moti // HandleSkillSustainStamina 处理技能持续时的耐力消耗 func (g *GameManager) HandleSkillSustainStamina(player *model.Player) { - skillId := player.StaminaInfo.LastSkillId - logger.LOG.Error("stamina skill sustain, skillId: %v", skillId) + staminaInfo := player.StaminaInfo + skillId := staminaInfo.LastSkillId + + // 读取技能配置表 avatarSkillConfig, ok := gdconf.CONF.AvatarSkillDataMap[int32(skillId)] if !ok { logger.LOG.Error("avatarSkillConfig error, skillId: %v", skillId) return } - // 距离上次执行过去的时间 - pastTime := time.Now().UnixMilli() - player.StaminaInfo.LastSkillTime - // 根据配置以及距离上次的时间计算消耗的耐力 - g.UpdateStamina(player, -(int32(pastTime/1000)*avatarSkillConfig.CostStamina)*100) + // 获取释放技能者的角色Id + world := WORLD_MANAGER.GetWorldByID(player.WorldId) + // 获取世界中的角色实体 + 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 处理技能开始时即时耐力消耗 -//func (g *GameManager) HandleSkillStartStamina(player *model.Player, skillId uint32) { -// logger.LOG.Error("stamina skill start, skillId: %v", skillId) -// avatarSkillConfig, ok := gdconf.CONF.AvatarSkillDataMap[int32(skillId)] -// if !ok { -// logger.LOG.Error("avatarSkillConfig error, skillId: %v", skillId) -// return -// } -// // 根据配置消耗耐力 -// g.UpdateStamina(player, -avatarSkillConfig.CostStamina*100) -// -// // 记录最后释放的技能 -// player.StaminaInfo.LastSkillId = skillId -// player.StaminaInfo.LastSkillTime = time.Now().UnixMilli() -//} +// HandleChargedAttackStamina 处理重击技能即时耐力消耗 +func (g *GameManager) HandleChargedAttackStamina(player *model.Player, worldAvatar *WorldAvatar, skillData *gdconf.AvatarSkillData) { + // 获取现行角色的配置表 + avatarDataConfig, ok := gdconf.CONF.AvatarDataMap[int32(worldAvatar.avatarId)] + if !ok { + logger.LOG.Error("avatarDataConfig error, avatarId: %v", worldAvatar.avatarId) + return + } + + // 需要消耗的耐力值 + var costStamina int32 + + // 如果为0代表使用默认值 + 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 处理持续耐力消耗 func (g *GameManager) StaminaHandler(player *model.Player) { @@ -188,8 +244,8 @@ func (g *GameManager) StaminaHandler(player *model.Player) { // 添加的耐力大于0为恢复 if staminaInfo.CostStamina > 0 { - // 耐力延迟1s(5 ticks)恢复 动作状态为加速将立刻恢复耐力 - if staminaInfo.RestoreDelay < 5 && (staminaInfo.State != proto.MotionState_MOTION_STATE_POWERED_FLY && staminaInfo.State != proto.MotionState_MOTION_STATE_SKIFF_POWERED_DASH) { + // 耐力延迟2s(10 ticks)恢复 动作状态为加速将立刻恢复耐力 + 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) staminaInfo.RestoreDelay++ return // 不恢复耐力 @@ -271,6 +327,11 @@ func (g *GameManager) UpdateStamina(player *model.Player, staminaCost int32) { stamina = 0 } + // 当前无变动不要频繁发包 + if curStamina == stamina { + return + } + g.SetStamina(player, uint32(stamina)) } @@ -280,10 +341,6 @@ func (g *GameManager) SetStamina(player *model.Player, stamina uint32) { // 设置玩家的耐力prop player.PropertiesMap[prop] = 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 playerPropNotify := new(proto.PlayerPropNotify) diff --git a/gs/model/avatar.go b/gs/model/avatar.go index 3fdb9c95..99cf76ef 100644 --- a/gs/model/avatar.go +++ b/gs/model/avatar.go @@ -47,7 +47,11 @@ func (p *Player) InitAllAvatar() { } 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[uint32(constant.FightPropertyConst.FIGHT_PROP_NONE)] = 0.0 diff --git a/gs/model/stamina.go b/gs/model/stamina.go index 3e80e3f1..91a481af 100644 --- a/gs/model/stamina.go +++ b/gs/model/stamina.go @@ -2,12 +2,21 @@ package model import ( "hk4e/protocol/proto" + "time" ) type StaminaInfo struct { State proto.MotionState // 动作状态 CostStamina int32 // 消耗或恢复的耐力 RestoreDelay uint8 // 恢复延迟 + LastCasterId uint32 // 最后释放技能者的Id LastSkillId uint32 // 最后释放的技能Id LastSkillTime int64 // 最后释放技能的时间 } + +// SetLastSkill 记录技能以便后续使用 +func (s *StaminaInfo) SetLastSkill(casterId uint32, skillId uint32) { + s.LastCasterId = casterId + s.LastSkillId = skillId + s.LastSkillTime = time.Now().UnixMilli() +}