mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 14:22:26 +08:00
重击体力消耗
This commit is contained in:
@@ -9,10 +9,11 @@ import (
|
||||
// 角色技能配置表
|
||||
|
||||
type AvatarSkillData struct {
|
||||
AvatarSkillId int32 `csv:"AvatarSkillId"` // ID
|
||||
CostStamina int32 `csv:"CostStamina,omitempty"` // 消耗体力
|
||||
CostElemType int32 `csv:"CostElemType,omitempty"` // 消耗能量类型
|
||||
CostElemVal int32 `csv:"CostElemVal,omitempty"` // 消耗能量值
|
||||
AvatarSkillId int32 `csv:"AvatarSkillId"` // ID
|
||||
AbilityName string `csv:"AbilityName,omitempty"` // Ability名称
|
||||
CostStamina int32 `csv:"CostStamina,omitempty"` // 消耗体力
|
||||
CostElemType int32 `csv:"CostElemType,omitempty"` // 消耗能量类型
|
||||
CostElemVal int32 `csv:"CostElemVal,omitempty"` // 消耗能量值
|
||||
}
|
||||
|
||||
func (g *GameDataConfig) loadAvatarSkillData() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
AvatarSkillId,,,,,CostStamina,CostElemType,CostElemVal,,,,,,,,,,,,,,,,,,,,
|
||||
int32,,,,,int32,int32,int32,,,,,,,,,,,,,,,,,,,,
|
||||
AvatarSkillId,AbilityName,,,,CostStamina,CostElemType,CostElemVal,,,,,,,,,,,,,,,,,,,,
|
||||
int32,string,,,,int32,int32,int32,,,,,,,,,,,,,,,,,,,,
|
||||
ID,Ability名称,是远程,技能CD,无视冷却缩减属性,消耗体力,消耗能量类型,消耗能量值,可累积次数,TriggerID,索敌范围,索敌公式权重1,索敌公式权重2,索敌公式权重3,索敌公式权重4,是默认镜头,支持按钮拖动,是否显示箭头,是否监控状态,默认锁定,图标名称,升级技能组ID,技能能量键值,消耗能量最小值,CanDoSkill为false强制可用,处理冷却所属技能槽,是否存档,shareCDID
|
||||
10001,,,0,,1,,,1,0,CircleLockEnemyR5H6HC,1,1,0.3,0,1,,,,,,0,,,,,,
|
||||
10002,,,0,,1,,,1,0,CircleLockEnemyR5H6HC,1,1,0.3,0,1,,,,,,0,,,,,,
|
||||
@@ -270,7 +270,7 @@ ID,Ability
|
||||
10655,,,15,,0,4,60,1,5,CircleLockEnemyR8H6HC,1,1,0.3,0,1,,,,,,6539,,,,,,
|
||||
10656,Avatar_Shinobu_Constellation6_Limbo_Trigger,,60,1,0,,,1,0,CircleLockEnemyR5H6HC,1,1,0.3,0,1,,,,,,0,,,,,1,
|
||||
10657,Avatar_Shinobu_Constellation6_Limbo_Trigger,,60,1,0,,,1,0,CircleLockEnemyR5H6HC,1,1,0.3,0,1,,,,,,0,,,,,1,
|
||||
10661,Avatar_Ayato_ExtraAttack,,0,,0,,,1,0,CircleLockEnemyR5H6HC,1,1,0.3,0,1,,,,,,6631,,,,,,
|
||||
10661,Avatar_Ayato_ExtraAttack,,0,,6000,,,1,0,CircleLockEnemyR5H6HC,1,1,0.3,0,1,,,,,,6631,,,,,,
|
||||
10662,,,12,,0,,,1,2,CircleLockEnemyR8H6HC,1,1,0.3,0,1,,,,,,6632,,,,,,
|
||||
10663,Avatar_Ayato_KendoPose_Click,,0,,0,,,1,0,CircleLockEnemyR10H6HC,1,1,0.3,0,1,,,,,,0,,,,,,
|
||||
10665,,,20,,0,2,80,1,5,CircleLockEnemyR5H6HC,1,1,0.3,0,1,,,,,,6639,,,,,,
|
||||
|
||||
|
@@ -3,6 +3,7 @@ package game
|
||||
import (
|
||||
"hk4e/gs/model"
|
||||
"hk4e/pkg/logger"
|
||||
"hk4e/pkg/object"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -43,8 +44,8 @@ func (l *LocalEventManager) LocalEventHandle(localEvent *LocalEvent) {
|
||||
case RunUserCopyAndSave:
|
||||
startTime := time.Now().UnixNano()
|
||||
// 拷贝一份数据避免并发访问
|
||||
insertPlayerList := make([]model.Player, 0, len(USER_MANAGER.playerMap))
|
||||
updatePlayerList := make([]model.Player, 0, len(USER_MANAGER.playerMap))
|
||||
insertPlayerList := make([]*model.Player, 0)
|
||||
updatePlayerList := make([]*model.Player, 0)
|
||||
for uid, player := range USER_MANAGER.playerMap {
|
||||
if uid < 100000000 {
|
||||
continue
|
||||
@@ -53,26 +54,36 @@ func (l *LocalEventManager) LocalEventHandle(localEvent *LocalEvent) {
|
||||
case model.DbNone:
|
||||
break
|
||||
case model.DbInsert:
|
||||
insertPlayerList = append(insertPlayerList, *player)
|
||||
playerCopy := new(model.Player)
|
||||
err := object.FastDeepCopy(playerCopy, player)
|
||||
if err != nil {
|
||||
logger.LOG.Error("deep copy player error: %v", err)
|
||||
continue
|
||||
}
|
||||
insertPlayerList = append(insertPlayerList, playerCopy)
|
||||
USER_MANAGER.playerMap[uid].DbState = model.DbNormal
|
||||
case model.DbDelete:
|
||||
updatePlayerList = append(updatePlayerList, *player)
|
||||
playerCopy := new(model.Player)
|
||||
err := object.FastDeepCopy(playerCopy, player)
|
||||
if err != nil {
|
||||
logger.LOG.Error("deep copy player error: %v", err)
|
||||
continue
|
||||
}
|
||||
updatePlayerList = append(updatePlayerList, playerCopy)
|
||||
delete(USER_MANAGER.playerMap, uid)
|
||||
case model.DbNormal:
|
||||
updatePlayerList = append(updatePlayerList, *player)
|
||||
playerCopy := new(model.Player)
|
||||
err := object.FastDeepCopy(playerCopy, player)
|
||||
if err != nil {
|
||||
logger.LOG.Error("deep copy player error: %v", err)
|
||||
continue
|
||||
}
|
||||
updatePlayerList = append(updatePlayerList, playerCopy)
|
||||
}
|
||||
}
|
||||
insertPlayerPointerList := make([]*model.Player, 0, len(insertPlayerList))
|
||||
updatePlayerPointerList := make([]*model.Player, 0, len(updatePlayerList))
|
||||
for _, player := range insertPlayerList {
|
||||
insertPlayerPointerList = append(insertPlayerPointerList, &player)
|
||||
}
|
||||
for _, player := range updatePlayerList {
|
||||
updatePlayerPointerList = append(updatePlayerPointerList, &player)
|
||||
}
|
||||
USER_MANAGER.saveUserChan <- &SaveUserData{
|
||||
insertPlayerList: insertPlayerPointerList,
|
||||
updatePlayerList: updatePlayerPointerList,
|
||||
insertPlayerList: insertPlayerList,
|
||||
updatePlayerList: updatePlayerList,
|
||||
}
|
||||
endTime := time.Now().UnixNano()
|
||||
costTime := endTime - startTime
|
||||
|
||||
@@ -10,8 +10,12 @@ import (
|
||||
pb "google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
var cmdProtoMap *cmd.CmdProtoMap = nil
|
||||
|
||||
func DoForward[IET model.InvokeEntryType](player *model.Player, req pb.Message, copyFieldList []string, forwardField string, invokeHandler *model.InvokeHandler[IET]) {
|
||||
cmdProtoMap := cmd.NewCmdProtoMap()
|
||||
if cmdProtoMap == nil {
|
||||
cmdProtoMap = cmd.NewCmdProtoMap()
|
||||
}
|
||||
cmdId := cmdProtoMap.GetCmdIdByProtoObj(req)
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
if invokeHandler.AllLen() == 0 && invokeHandler.AllExceptCurLen() == 0 && invokeHandler.HostLen() == 0 {
|
||||
@@ -53,6 +57,9 @@ func (g *GameManager) UnionCmdNotify(player *model.Player, payloadMsg pb.Message
|
||||
//logger.LOG.Debug("user send union cmd, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.UnionCmdNotify)
|
||||
_ = req
|
||||
if player.SceneLoadState != model.SceneEnterDone {
|
||||
return
|
||||
}
|
||||
DoForward[proto.CombatInvokeEntry](player, &proto.CombatInvocationsNotify{}, []string{}, "InvokeList", player.CombatInvokeHandler)
|
||||
DoForward[proto.AbilityInvokeEntry](player, &proto.AbilityInvocationsNotify{}, []string{}, "Invokes", player.AbilityInvokeHandler)
|
||||
player.CombatInvokeHandler.Clear()
|
||||
@@ -62,6 +69,9 @@ func (g *GameManager) UnionCmdNotify(player *model.Player, payloadMsg pb.Message
|
||||
func (g *GameManager) MassiveEntityElementOpBatchNotify(player *model.Player, payloadMsg pb.Message) {
|
||||
//logger.LOG.Debug("user meeo sync, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.MassiveEntityElementOpBatchNotify)
|
||||
if player.SceneLoadState != model.SceneEnterDone {
|
||||
return
|
||||
}
|
||||
ntf := req
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
if world == nil {
|
||||
@@ -80,12 +90,8 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
||||
return
|
||||
}
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
if world == nil {
|
||||
return
|
||||
}
|
||||
scene := world.GetSceneById(player.SceneId)
|
||||
for _, entry := range req.InvokeList {
|
||||
//logger.LOG.Debug("AT: %v, FT: %v, UID: %v", entry.ArgumentType, entry.ForwardType, player.PlayerID)
|
||||
switch entry.ArgumentType {
|
||||
case proto.CombatTypeArgument_COMBAT_TYPE_ARGUMENT_EVT_BEING_HIT:
|
||||
player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry)
|
||||
@@ -93,7 +99,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
||||
entityMoveInfo := new(proto.EntityMoveInfo)
|
||||
err := pb.Unmarshal(entry.CombatData, entityMoveInfo)
|
||||
if err != nil {
|
||||
logger.LOG.Error("parse combat invocations entity move info error: %v", err)
|
||||
logger.LOG.Error("parse EntityMoveInfo error: %v", err)
|
||||
continue
|
||||
}
|
||||
motionInfo := entityMoveInfo.MotionInfo
|
||||
@@ -129,7 +135,6 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
||||
sceneEntity.moveState = uint16(motionInfo.State)
|
||||
sceneEntity.lastMoveSceneTimeMs = entityMoveInfo.SceneTime
|
||||
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)
|
||||
@@ -141,7 +146,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
||||
if err != nil {
|
||||
logger.LOG.Error("parse EvtAnimatorStateChangedInfo error: %v", err)
|
||||
}
|
||||
logger.LOG.Debug("%v", evtAnimatorStateChangedInfo)
|
||||
logger.LOG.Debug("EvtAnimatorStateChangedInfo: %v", entry, player.PlayerID)
|
||||
player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry)
|
||||
default:
|
||||
player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry)
|
||||
@@ -152,13 +157,39 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
||||
func (g *GameManager) AbilityInvocationsNotify(player *model.Player, payloadMsg pb.Message) {
|
||||
//logger.LOG.Debug("user ability invocations, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.AbilityInvocationsNotify)
|
||||
if player.SceneLoadState != model.SceneEnterDone {
|
||||
return
|
||||
}
|
||||
|
||||
for _, entry := range req.Invokes {
|
||||
//logger.LOG.Debug("AT: %v, FT: %v, UID: %v", entry.ArgumentType, entry.ForwardType, player.PlayerID)
|
||||
//logger.LOG.Debug("AbilityInvocationsNotify: %v", entry, player.PlayerID)
|
||||
|
||||
// 处理能力调用
|
||||
g.HandleAbilityInvoke(player, entry)
|
||||
//switch entry.ArgumentType {
|
||||
//case proto.AbilityInvokeArgument_ABILITY_INVOKE_ARGUMENT_META_MODIFIER_CHANGE:
|
||||
// world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
// worldAvatar := world.GetWorldAvatarByEntityId(entry.EntityId)
|
||||
// if worldAvatar != nil {
|
||||
// for _, ability := range worldAvatar.abilityList {
|
||||
// if ability.InstancedAbilityId == entry.Head.InstancedAbilityId {
|
||||
// logger.LOG.Error("A: %v", ability)
|
||||
// }
|
||||
// }
|
||||
// for _, modifier := range worldAvatar.modifierList {
|
||||
// if modifier.InstancedAbilityId == entry.Head.InstancedAbilityId {
|
||||
// logger.LOG.Error("B: %v", modifier)
|
||||
// }
|
||||
// }
|
||||
// for _, modifier := range worldAvatar.modifierList {
|
||||
// if modifier.InstancedModifierId == entry.Head.InstancedModifierId {
|
||||
// logger.LOG.Error("C: %v", modifier)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//case proto.AbilityInvokeArgument_ABILITY_INVOKE_ARGUMENT_NONE:
|
||||
//}
|
||||
|
||||
// 处理耐力消耗
|
||||
g.HandleAbilityStamina(player, entry)
|
||||
player.AbilityInvokeHandler.AddEntry(entry.ForwardType, entry)
|
||||
}
|
||||
}
|
||||
@@ -166,13 +197,12 @@ func (g *GameManager) AbilityInvocationsNotify(player *model.Player, payloadMsg
|
||||
func (g *GameManager) ClientAbilityInitFinishNotify(player *model.Player, payloadMsg pb.Message) {
|
||||
//logger.LOG.Debug("user client ability init finish, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.ClientAbilityInitFinishNotify)
|
||||
if player.SceneLoadState != model.SceneEnterDone {
|
||||
return
|
||||
}
|
||||
invokeHandler := model.NewInvokeHandler[proto.AbilityInvokeEntry]()
|
||||
for _, entry := range req.Invokes {
|
||||
//logger.LOG.Debug("AT: %v, FT: %v, UID: %v", entry.ArgumentType, entry.ForwardType, player.PlayerID)
|
||||
|
||||
// 处理能力调用
|
||||
g.HandleAbilityInvoke(player, entry)
|
||||
|
||||
logger.LOG.Debug("ClientAbilityInitFinishNotify: %v", entry, player.PlayerID)
|
||||
invokeHandler.AddEntry(entry.ForwardType, entry)
|
||||
}
|
||||
DoForward[proto.AbilityInvokeEntry](player, &proto.ClientAbilityInitFinishNotify{}, []string{"EntityId"}, "Invokes", invokeHandler)
|
||||
@@ -181,8 +211,13 @@ func (g *GameManager) ClientAbilityInitFinishNotify(player *model.Player, payloa
|
||||
func (g *GameManager) ClientAbilityChangeNotify(player *model.Player, payloadMsg pb.Message) {
|
||||
//logger.LOG.Debug("user client ability change, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.ClientAbilityChangeNotify)
|
||||
if player.SceneLoadState != model.SceneEnterDone {
|
||||
return
|
||||
}
|
||||
invokeHandler := model.NewInvokeHandler[proto.AbilityInvokeEntry]()
|
||||
for _, entry := range req.Invokes {
|
||||
logger.LOG.Debug("ClientAbilityChangeNotify: %v", entry, player.PlayerID)
|
||||
|
||||
invokeHandler.AddEntry(entry.ForwardType, entry)
|
||||
}
|
||||
DoForward[proto.AbilityInvokeEntry](player, req, []string{"EntityId", "IsInitHash"}, "Invokes", invokeHandler)
|
||||
@@ -240,15 +275,18 @@ func (g *GameManager) ClientAbilityChangeNotify(player *model.Player, payloadMsg
|
||||
func (g *GameManager) EvtDoSkillSuccNotify(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.LOG.Debug("user event do skill success, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.EvtDoSkillSuccNotify)
|
||||
if player.SceneLoadState != model.SceneEnterDone {
|
||||
return
|
||||
}
|
||||
logger.LOG.Debug("EvtDoSkillSuccNotify: %v", req)
|
||||
|
||||
// 处理技能开始时的耐力消耗
|
||||
g.HandleSkillStartStamina(player, req.SkillId)
|
||||
}
|
||||
|
||||
func (g *GameManager) EvtAvatarEnterFocusNotify(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.LOG.Debug("user avatar enter focus, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.EvtAvatarEnterFocusNotify)
|
||||
if player.SceneLoadState != model.SceneEnterDone {
|
||||
return
|
||||
}
|
||||
logger.LOG.Debug("EvtAvatarEnterFocusNotify: %v", req)
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
g.SendToWorldA(world, cmd.EvtAvatarEnterFocusNotify, player.ClientSeq, req)
|
||||
@@ -257,6 +295,9 @@ func (g *GameManager) EvtAvatarEnterFocusNotify(player *model.Player, payloadMsg
|
||||
func (g *GameManager) EvtAvatarUpdateFocusNotify(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.LOG.Debug("user avatar update focus, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.EvtAvatarUpdateFocusNotify)
|
||||
if player.SceneLoadState != model.SceneEnterDone {
|
||||
return
|
||||
}
|
||||
logger.LOG.Debug("EvtAvatarUpdateFocusNotify: %v", req)
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
g.SendToWorldA(world, cmd.EvtAvatarUpdateFocusNotify, player.ClientSeq, req)
|
||||
@@ -265,6 +306,9 @@ func (g *GameManager) EvtAvatarUpdateFocusNotify(player *model.Player, payloadMs
|
||||
func (g *GameManager) EvtAvatarExitFocusNotify(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.LOG.Debug("user avatar exit focus, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.EvtAvatarExitFocusNotify)
|
||||
if player.SceneLoadState != model.SceneEnterDone {
|
||||
return
|
||||
}
|
||||
logger.LOG.Debug("EvtAvatarExitFocusNotify: %v", req)
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
g.SendToWorldA(world, cmd.EvtAvatarExitFocusNotify, player.ClientSeq, req)
|
||||
@@ -273,6 +317,9 @@ func (g *GameManager) EvtAvatarExitFocusNotify(player *model.Player, payloadMsg
|
||||
func (g *GameManager) EvtEntityRenderersChangedNotify(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.LOG.Debug("user entity render change, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.EvtEntityRenderersChangedNotify)
|
||||
if player.SceneLoadState != model.SceneEnterDone {
|
||||
return
|
||||
}
|
||||
logger.LOG.Debug("EvtEntityRenderersChangedNotify: %v", req)
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
g.SendToWorldA(world, cmd.EvtEntityRenderersChangedNotify, player.ClientSeq, req)
|
||||
@@ -281,6 +328,9 @@ func (g *GameManager) EvtEntityRenderersChangedNotify(player *model.Player, payl
|
||||
func (g *GameManager) EvtCreateGadgetNotify(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.LOG.Debug("user create gadget, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.EvtCreateGadgetNotify)
|
||||
if player.SceneLoadState != model.SceneEnterDone {
|
||||
return
|
||||
}
|
||||
logger.LOG.Debug("EvtCreateGadgetNotify: %v", req)
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
scene := world.GetSceneById(player.SceneId)
|
||||
@@ -299,6 +349,9 @@ func (g *GameManager) EvtCreateGadgetNotify(player *model.Player, payloadMsg pb.
|
||||
func (g *GameManager) EvtDestroyGadgetNotify(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.LOG.Debug("user destroy gadget, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.EvtDestroyGadgetNotify)
|
||||
if player.SceneLoadState != model.SceneEnterDone {
|
||||
return
|
||||
}
|
||||
logger.LOG.Debug("EvtDestroyGadgetNotify: %v", req)
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
scene := world.GetSceneById(player.SceneId)
|
||||
|
||||
@@ -5,30 +5,60 @@ import (
|
||||
"hk4e/gdconf"
|
||||
"hk4e/gs/constant"
|
||||
"hk4e/gs/model"
|
||||
"hk4e/pkg/endec"
|
||||
"hk4e/pkg/logger"
|
||||
"hk4e/protocol/cmd"
|
||||
"hk4e/protocol/proto"
|
||||
"time"
|
||||
)
|
||||
|
||||
// HandleAbilityInvoke 处理能力调用
|
||||
func (g *GameManager) HandleAbilityInvoke(player *model.Player, entry *proto.AbilityInvokeEntry) {
|
||||
//logger.LOG.Debug("ability invoke handle, entry: %v", entry.ArgumentType)
|
||||
|
||||
// HandleAbilityStamina 处理来自ability的耐力消耗
|
||||
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
|
||||
//}
|
||||
|
||||
// 处理技能持续时的耐力消耗
|
||||
// 大剑重击耐力消耗
|
||||
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:
|
||||
// 普通角色重击耐力消耗
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
// 获取世界中的角色实体
|
||||
worldAvatar := world.GetWorldAvatarByEntityId(entry.EntityId)
|
||||
if worldAvatar == nil {
|
||||
return
|
||||
}
|
||||
// 查找是不是属于该角色实体的ability id
|
||||
abilityNameHashCode := uint32(0)
|
||||
for _, ability := range worldAvatar.abilityList {
|
||||
if ability.InstancedAbilityId == entry.Head.InstancedAbilityId {
|
||||
logger.LOG.Error("%v", ability)
|
||||
abilityNameHashCode = ability.AbilityName.GetHash()
|
||||
}
|
||||
}
|
||||
if abilityNameHashCode == 0 {
|
||||
return
|
||||
}
|
||||
// 根据ability name查找到对应的技能表里的技能配置
|
||||
var avatarAbility *gdconf.AvatarSkillData = nil
|
||||
for _, avatarSkillData := range gdconf.CONF.AvatarSkillDataMap {
|
||||
hashCode := endec.Hk4eAbilityHashCode(avatarSkillData.AbilityName)
|
||||
if uint32(hashCode) == abilityNameHashCode {
|
||||
avatarAbility = avatarSkillData
|
||||
}
|
||||
}
|
||||
if avatarAbility == nil {
|
||||
return
|
||||
}
|
||||
// 获取该技能对应的耐力消耗
|
||||
_ = avatarAbility.CostStamina
|
||||
logger.LOG.Error("%v", avatarAbility.CostStamina)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,21 +162,21 @@ func (g *GameManager) HandleSkillSustainStamina(player *model.Player) {
|
||||
player.StaminaInfo.LastSkillTime = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 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()
|
||||
}
|
||||
//// 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()
|
||||
//}
|
||||
|
||||
// StaminaHandler 处理持续耐力消耗
|
||||
func (g *GameManager) StaminaHandler(player *model.Player) {
|
||||
|
||||
@@ -169,10 +169,17 @@ func (w *World) AddPlayer(player *model.Player, sceneId uint32) {
|
||||
activeAvatarId := player.TeamConfig.GetActiveAvatarId()
|
||||
w.SetPlayerLocalTeam(player, []uint32{activeAvatarId})
|
||||
}
|
||||
for _, worldPlayer := range w.playerMap {
|
||||
w.SetPlayerAvatarIndex(worldPlayer, 0)
|
||||
}
|
||||
w.UpdateMultiplayerTeam()
|
||||
for _, worldPlayer := range w.playerMap {
|
||||
list := w.GetPlayerWorldAvatarList(worldPlayer)
|
||||
maxIndex := len(list) - 1
|
||||
index := int(worldPlayer.TeamConfig.CurrAvatarIndex)
|
||||
if index > maxIndex {
|
||||
w.SetPlayerAvatarIndex(worldPlayer, 0)
|
||||
} else {
|
||||
w.SetPlayerAvatarIndex(worldPlayer, index)
|
||||
}
|
||||
}
|
||||
scene := w.GetSceneById(sceneId)
|
||||
scene.AddPlayer(player)
|
||||
w.InitPlayerTeamEntityId(player)
|
||||
|
||||
@@ -22,7 +22,7 @@ type GameObject interface {
|
||||
}
|
||||
|
||||
type Player struct {
|
||||
// 离线数据
|
||||
// 离线数据 请尽量不要定义接口等复杂数据结构
|
||||
ID primitive.ObjectID `bson:"_id,omitempty"`
|
||||
PlayerID uint32 `bson:"playerID"` // 玩家uid
|
||||
NickName string `bson:"nickname"` // 玩家昵称
|
||||
@@ -52,22 +52,22 @@ type Player struct {
|
||||
MainCharAvatarId uint32 `bson:"mainCharAvatarId"` // 主角id
|
||||
ChatMsgMap map[uint32][]*ChatMsg `bson:"chatMsgMap"` // 聊天信息
|
||||
IsGM uint8 `bson:"isGM"` // 管理员权限等级
|
||||
// 在线数据
|
||||
EnterSceneToken uint32 `bson:"-"` // 玩家的世界进入令牌
|
||||
DbState int `bson:"-"` // 数据库存档状态
|
||||
WorldId uint32 `bson:"-"` // 所在的世界id
|
||||
GameObjectGuidCounter uint64 `bson:"-"` // 游戏对象guid计数器
|
||||
ClientTime uint32 `bson:"-"` // 玩家客户端的本地时钟
|
||||
ClientRTT uint32 `bson:"-"` // 玩家客户端往返时延
|
||||
GameObjectGuidMap map[uint64]GameObject `bson:"-"` // 游戏对象guid映射表
|
||||
Online bool `bson:"-"` // 在线状态
|
||||
Pause bool `bson:"-"` // 暂停状态
|
||||
SceneLoadState int `bson:"-"` // 场景加载状态
|
||||
CoopApplyMap map[uint32]int64 `bson:"-"` // 敲门申请的玩家uid及时间
|
||||
StaminaInfo *StaminaInfo `bson:"-"` // 耐力临时数据
|
||||
ClientSeq uint32 `bson:"-"` // 客户端发包请求的序号
|
||||
CombatInvokeHandler *InvokeHandler[proto.CombatInvokeEntry] `bson:"-"`
|
||||
AbilityInvokeHandler *InvokeHandler[proto.AbilityInvokeEntry] `bson:"-"`
|
||||
// 在线数据 请随意 记得加忽略字段的tag
|
||||
EnterSceneToken uint32 `bson:"-" msgpack:"-"` // 玩家的世界进入令牌
|
||||
DbState int `bson:"-" msgpack:"-"` // 数据库存档状态
|
||||
WorldId uint32 `bson:"-" msgpack:"-"` // 所在的世界id
|
||||
GameObjectGuidCounter uint64 `bson:"-" msgpack:"-"` // 游戏对象guid计数器
|
||||
ClientTime uint32 `bson:"-" msgpack:"-"` // 玩家客户端的本地时钟
|
||||
ClientRTT uint32 `bson:"-" msgpack:"-"` // 玩家客户端往返时延
|
||||
GameObjectGuidMap map[uint64]GameObject `bson:"-" msgpack:"-"` // 游戏对象guid映射表
|
||||
Online bool `bson:"-" msgpack:"-"` // 在线状态
|
||||
Pause bool `bson:"-" msgpack:"-"` // 暂停状态
|
||||
SceneLoadState int `bson:"-" msgpack:"-"` // 场景加载状态
|
||||
CoopApplyMap map[uint32]int64 `bson:"-" msgpack:"-"` // 敲门申请的玩家uid及时间
|
||||
StaminaInfo *StaminaInfo `bson:"-" msgpack:"-"` // 耐力临时数据
|
||||
ClientSeq uint32 `bson:"-" msgpack:"-"` // 客户端发包请求的序号
|
||||
CombatInvokeHandler *InvokeHandler[proto.CombatInvokeEntry] `bson:"-" msgpack:"-"` // combat转发器
|
||||
AbilityInvokeHandler *InvokeHandler[proto.AbilityInvokeEntry] `bson:"-" msgpack:"-"` // ability转发器
|
||||
}
|
||||
|
||||
func (p *Player) GetNextGameObjectGuid() uint64 {
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
)
|
||||
|
||||
type Team struct {
|
||||
Name string `bson:"name"`
|
||||
AvatarIdList [4]uint32 `bson:"avatarIdList"`
|
||||
Name string `bson:"name"`
|
||||
AvatarIdList []uint32 `bson:"avatarIdList"`
|
||||
}
|
||||
|
||||
func (t *Team) GetAvatarIdList() []uint32 {
|
||||
@@ -22,7 +22,7 @@ func (t *Team) GetAvatarIdList() []uint32 {
|
||||
}
|
||||
|
||||
func (t *Team) SetAvatarIdList(avatarIdList []uint32) {
|
||||
t.AvatarIdList = [4]uint32{0, 0, 0, 0}
|
||||
t.AvatarIdList = make([]uint32, 4)
|
||||
for index := range t.AvatarIdList {
|
||||
if index >= len(avatarIdList) {
|
||||
break
|
||||
@@ -42,10 +42,10 @@ type TeamInfo struct {
|
||||
func NewTeamInfo() (r *TeamInfo) {
|
||||
r = &TeamInfo{
|
||||
TeamList: []*Team{
|
||||
{Name: "冒险", AvatarIdList: [4]uint32{0, 0, 0, 0}},
|
||||
{Name: "委托", AvatarIdList: [4]uint32{0, 0, 0, 0}},
|
||||
{Name: "秘境", AvatarIdList: [4]uint32{0, 0, 0, 0}},
|
||||
{Name: "联机", AvatarIdList: [4]uint32{0, 0, 0, 0}},
|
||||
{Name: "冒险", AvatarIdList: make([]uint32, 4)},
|
||||
{Name: "委托", AvatarIdList: make([]uint32, 4)},
|
||||
{Name: "秘境", AvatarIdList: make([]uint32, 4)},
|
||||
{Name: "联机", AvatarIdList: make([]uint32, 4)},
|
||||
},
|
||||
CurrTeamIndex: 0,
|
||||
CurrAvatarIndex: 0,
|
||||
|
||||
@@ -27,3 +27,10 @@ func TestAesCFB(t *testing.T) {
|
||||
dec, _ := AesCFBDecrypt(enc, key, key[0:16])
|
||||
fmt.Printf("dec: %v\n", dec)
|
||||
}
|
||||
|
||||
func TestHk4eAbilityHashCode(t *testing.T) {
|
||||
hashCode := Hk4eAbilityHashCode("Avatar_Ayato_ExtraAttack")
|
||||
fmt.Printf("Avatar_Ayato_ExtraAttack hashCode: %v\n", hashCode)
|
||||
hashCode = Hk4eAbilityHashCode("Avatar_Ayato_ExtraAttack_CreateBullet")
|
||||
fmt.Printf("Avatar_Ayato_ExtraAttack_CreateBullet hashCode: %v\n", hashCode)
|
||||
}
|
||||
|
||||
@@ -4,14 +4,32 @@ import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"github.com/vmihailenco/msgpack/v5"
|
||||
)
|
||||
|
||||
func DeepCopy(src, dest any) error {
|
||||
func DeepCopy(dst, src any) error {
|
||||
var buf bytes.Buffer
|
||||
if err := gob.NewEncoder(&buf).Encode(src); err != nil {
|
||||
err := gob.NewEncoder(&buf).Encode(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dest)
|
||||
err = gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func FastDeepCopy(dst, src any) error {
|
||||
data, err := msgpack.Marshal(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = msgpack.Unmarshal(data, dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ConvBoolToInt64(v bool) int64 {
|
||||
|
||||
Reference in New Issue
Block a user