mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 16:02:26 +08:00
优化代码
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
http_port = 8080
|
http_port = 8080
|
||||||
|
|
||||||
[hk4e]
|
[hk4e]
|
||||||
kcp_addr = "hk4e.flswld.com"
|
kcp_addr = "127.0.0.1"
|
||||||
kcp_port = 22103
|
kcp_port = 22103
|
||||||
login_sdk_url = "https://api.flswld.com/api/v1/auth/login"
|
login_sdk_url = "https://api.flswld.com/api/v1/auth/login"
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[hk4e]
|
[hk4e]
|
||||||
kcp_addr = "hk4e.flswld.com"
|
kcp_addr = "127.0.0.1"
|
||||||
kcp_port = 22103
|
kcp_port = 22103
|
||||||
|
|
||||||
[logger]
|
[logger]
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ type GameManager struct {
|
|||||||
userManager *UserManager
|
userManager *UserManager
|
||||||
// 世界管理器
|
// 世界管理器
|
||||||
worldManager *WorldManager
|
worldManager *WorldManager
|
||||||
// 游戏服务器tick
|
// 游戏服务器定时帧管理器
|
||||||
tickManager *TickManager
|
tickManager *TickManager
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,11 +41,7 @@ func NewGameManager(dao *dao.Dao, netMsgInput chan *cmd.NetMsg, netMsgOutput cha
|
|||||||
r.worldManager = NewWorldManager(r.snowflake)
|
r.worldManager = NewWorldManager(r.snowflake)
|
||||||
r.tickManager = NewTickManager(r)
|
r.tickManager = NewTickManager(r)
|
||||||
|
|
||||||
//r.worldManager.worldStatic.InitTerrain()
|
// 创建一个公共的开放世界的AI
|
||||||
//r.worldManager.worldStatic.Pathfinding()
|
|
||||||
//r.worldManager.worldStatic.ConvPathVectorListToAiMoveVectorList()
|
|
||||||
|
|
||||||
// 大世界的主人
|
|
||||||
r.OnRegOk(false, &proto.SetPlayerBornDataReq{AvatarId: 10000007, NickName: "大世界的主人"}, 1, 0)
|
r.OnRegOk(false, &proto.SetPlayerBornDataReq{AvatarId: 10000007, NickName: "大世界的主人"}, 1, 0)
|
||||||
bigWorldOwner := r.userManager.GetOnlineUser(1)
|
bigWorldOwner := r.userManager.GetOnlineUser(1)
|
||||||
bigWorldOwner.SceneLoadState = model.SceneEnterDone
|
bigWorldOwner.SceneLoadState = model.SceneEnterDone
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
|
// 本地事件队列管理器
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LoadLoginUserFromDbFinish = iota
|
LoadLoginUserFromDbFinish = iota
|
||||||
CheckUserExistOnRegFromDbFinish
|
CheckUserExistOnRegFromDbFinish
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
"hk4e/protocol/cmd"
|
"hk4e/protocol/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 接口路由管理器
|
||||||
|
|
||||||
type HandlerFunc func(player *model.Player, payloadMsg pb.Message)
|
type HandlerFunc func(player *model.Player, payloadMsg pb.Message)
|
||||||
|
|
||||||
type RouteManager struct {
|
type RouteManager struct {
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 游戏服务器定时帧管理器
|
||||||
|
|
||||||
type TickManager struct {
|
type TickManager struct {
|
||||||
ticker *time.Ticker
|
ticker *time.Ticker
|
||||||
tickCount uint64
|
tickCount uint64
|
||||||
@@ -77,7 +79,7 @@ func (t *TickManager) onTick10Minute(now int64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TickManager) onTickMinute(now int64) {
|
func (t *TickManager) onTickMinute(now int64) {
|
||||||
t.gameManager.ServerAnnounceNotify(100, "test123")
|
//t.gameManager.ServerAnnounceNotify(100, "test123")
|
||||||
for _, world := range t.gameManager.worldManager.worldMap {
|
for _, world := range t.gameManager.worldManager.worldMap {
|
||||||
for _, player := range world.playerMap {
|
for _, player := range world.playerMap {
|
||||||
// 随机物品
|
// 随机物品
|
||||||
@@ -149,6 +151,7 @@ func (t *TickManager) onTick5Second(now int64) {
|
|||||||
}
|
}
|
||||||
for _, player := range world.playerMap {
|
for _, player := range world.playerMap {
|
||||||
if world.multiplayer {
|
if world.multiplayer {
|
||||||
|
// 多人世界其他玩家的坐标位置广播
|
||||||
// PacketWorldPlayerLocationNotify
|
// PacketWorldPlayerLocationNotify
|
||||||
worldPlayerLocationNotify := new(proto.WorldPlayerLocationNotify)
|
worldPlayerLocationNotify := new(proto.WorldPlayerLocationNotify)
|
||||||
for _, worldPlayer := range world.playerMap {
|
for _, worldPlayer := range world.playerMap {
|
||||||
@@ -201,6 +204,7 @@ func (t *TickManager) onTick5Second(now int64) {
|
|||||||
func (t *TickManager) onTickSecond(now int64) {
|
func (t *TickManager) onTickSecond(now int64) {
|
||||||
for _, world := range t.gameManager.worldManager.worldMap {
|
for _, world := range t.gameManager.worldManager.worldMap {
|
||||||
for _, player := range world.playerMap {
|
for _, player := range world.playerMap {
|
||||||
|
// 世界里所有玩家的网络延迟广播
|
||||||
// PacketWorldPlayerRTTNotify
|
// PacketWorldPlayerRTTNotify
|
||||||
worldPlayerRTTNotify := new(proto.WorldPlayerRTTNotify)
|
worldPlayerRTTNotify := new(proto.WorldPlayerRTTNotify)
|
||||||
worldPlayerRTTNotify.PlayerRttList = make([]*proto.PlayerRTTInfo, 0)
|
worldPlayerRTTNotify.PlayerRttList = make([]*proto.PlayerRTTInfo, 0)
|
||||||
@@ -214,13 +218,15 @@ func (t *TickManager) onTickSecond(now int64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TickManager) onTick100MilliSecond(now int64) {
|
func (t *TickManager) onTick100MilliSecond(now int64) {
|
||||||
// AttackHandler
|
// 伤害处理和转发
|
||||||
for _, world := range t.gameManager.worldManager.worldMap {
|
for _, world := range t.gameManager.worldManager.worldMap {
|
||||||
for _, scene := range world.sceneMap {
|
for _, scene := range world.sceneMap {
|
||||||
scene.AttackHandler(t.gameManager)
|
scene.AttackHandler(t.gameManager)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 服务器控制的模拟AI移动
|
||||||
|
|
||||||
//bigWorldOwner := t.gameManager.userManager.GetOnlineUser(1)
|
//bigWorldOwner := t.gameManager.userManager.GetOnlineUser(1)
|
||||||
//bigWorld := t.gameManager.worldManager.GetBigWorld()
|
//bigWorld := t.gameManager.worldManager.GetBigWorld()
|
||||||
//bigWorldScene := bigWorld.GetSceneById(3)
|
//bigWorldScene := bigWorld.GetSceneById(3)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg pb.Message) {
|
func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg pb.Message) {
|
||||||
//logger.LOG.Debug("user combat invocations, uid: %v", player.PlayerID)
|
logger.LOG.Debug("user combat invocations, uid: %v", player.PlayerID)
|
||||||
req := payloadMsg.(*proto.CombatInvocationsNotify)
|
req := payloadMsg.(*proto.CombatInvocationsNotify)
|
||||||
world := g.worldManager.GetWorldByID(player.WorldId)
|
world := g.worldManager.GetWorldByID(player.WorldId)
|
||||||
if world == nil {
|
if world == nil {
|
||||||
@@ -18,7 +18,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
|||||||
scene := world.GetSceneById(player.SceneId)
|
scene := world.GetSceneById(player.SceneId)
|
||||||
invokeHandler := NewInvokeHandler[proto.CombatInvokeEntry]()
|
invokeHandler := NewInvokeHandler[proto.CombatInvokeEntry]()
|
||||||
for _, entry := range req.InvokeList {
|
for _, entry := range req.InvokeList {
|
||||||
//logger.LOG.Debug("AT: %v, FT: %v, UID: %v", entry.ArgumentType, entry.ForwardType, player.PlayerID)
|
logger.LOG.Debug("AT: %v, FT: %v, UID: %v", entry.ArgumentType, entry.ForwardType, player.PlayerID)
|
||||||
switch entry.ArgumentType {
|
switch entry.ArgumentType {
|
||||||
case proto.CombatTypeArgument_COMBAT_TYPE_ARGUMENT_EVT_BEING_HIT:
|
case proto.CombatTypeArgument_COMBAT_TYPE_ARGUMENT_EVT_BEING_HIT:
|
||||||
scene.AddAttack(&Attack{
|
scene.AddAttack(&Attack{
|
||||||
@@ -145,42 +145,42 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
|||||||
player.Rot.X = float64(motionInfo.Rot.X)
|
player.Rot.X = float64(motionInfo.Rot.X)
|
||||||
player.Rot.Y = float64(motionInfo.Rot.Y)
|
player.Rot.Y = float64(motionInfo.Rot.Y)
|
||||||
player.Rot.Z = float64(motionInfo.Rot.Z)
|
player.Rot.Z = float64(motionInfo.Rot.Z)
|
||||||
// TODO 采集大地图地形数据
|
//// TODO 采集大地图地形数据
|
||||||
if world.IsBigWorld() && scene.id == 3 && player.PlayerID != 1 {
|
//if world.IsBigWorld() && scene.id == 3 && player.PlayerID != 1 {
|
||||||
if motionInfo.State == proto.MotionState_MOTION_STATE_WALK ||
|
// if motionInfo.State == proto.MotionState_MOTION_STATE_WALK ||
|
||||||
motionInfo.State == proto.MotionState_MOTION_STATE_RUN ||
|
// motionInfo.State == proto.MotionState_MOTION_STATE_RUN ||
|
||||||
motionInfo.State == proto.MotionState_MOTION_STATE_DASH ||
|
// motionInfo.State == proto.MotionState_MOTION_STATE_DASH ||
|
||||||
motionInfo.State == proto.MotionState_MOTION_STATE_CLIMB {
|
// motionInfo.State == proto.MotionState_MOTION_STATE_CLIMB {
|
||||||
logger.LOG.Debug("set terr motionInfo: %v", motionInfo)
|
// logger.LOG.Debug("set terr motionInfo: %v", motionInfo)
|
||||||
exist := g.worldManager.worldStatic.GetTerrain(int16(motionInfo.Pos.X), int16(motionInfo.Pos.Y), int16(motionInfo.Pos.Z))
|
// exist := g.worldManager.worldStatic.GetTerrain(int16(motionInfo.Pos.X), int16(motionInfo.Pos.Y), int16(motionInfo.Pos.Z))
|
||||||
g.worldManager.worldStatic.SetTerrain(int16(motionInfo.Pos.X), int16(motionInfo.Pos.Y), int16(motionInfo.Pos.Z))
|
// g.worldManager.worldStatic.SetTerrain(int16(motionInfo.Pos.X), int16(motionInfo.Pos.Y), int16(motionInfo.Pos.Z))
|
||||||
if !exist {
|
// if !exist {
|
||||||
// TODO 薄荷标记
|
// // TODO 薄荷标记
|
||||||
// 只给附近aoi区域的玩家广播消息
|
// // 只给附近aoi区域的玩家广播消息
|
||||||
surrPlayerList := make([]*model.Player, 0)
|
// surrPlayerList := make([]*model.Player, 0)
|
||||||
entityIdList := world.aoiManager.GetEntityIdListByPos(float32(player.Pos.X), float32(player.Pos.Y), float32(player.Pos.Z))
|
// entityIdList := world.aoiManager.GetEntityIdListByPos(float32(player.Pos.X), float32(player.Pos.Y), float32(player.Pos.Z))
|
||||||
for _, entityId := range entityIdList {
|
// for _, entityId := range entityIdList {
|
||||||
entity := scene.GetEntity(entityId)
|
// entity := scene.GetEntity(entityId)
|
||||||
if entity == nil {
|
// if entity == nil {
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
if entity.avatarEntity != nil {
|
// if entity.avatarEntity != nil {
|
||||||
otherPlayer := g.userManager.GetOnlineUser(entity.avatarEntity.uid)
|
// otherPlayer := g.userManager.GetOnlineUser(entity.avatarEntity.uid)
|
||||||
surrPlayerList = append(surrPlayerList, otherPlayer)
|
// surrPlayerList = append(surrPlayerList, otherPlayer)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
pos := &model.Vector{
|
// pos := &model.Vector{
|
||||||
X: float64(int16(motionInfo.Pos.X)),
|
// X: float64(int16(motionInfo.Pos.X)),
|
||||||
Y: float64(int16(motionInfo.Pos.Y)),
|
// Y: float64(int16(motionInfo.Pos.Y)),
|
||||||
Z: float64(int16(motionInfo.Pos.Z)),
|
// Z: float64(int16(motionInfo.Pos.Z)),
|
||||||
}
|
// }
|
||||||
gadgetEntityId := scene.CreateEntityGadget(pos, 3003009)
|
// gadgetEntityId := scene.CreateEntityGadget(pos, 3003009)
|
||||||
for _, otherPlayer := range surrPlayerList {
|
// for _, otherPlayer := range surrPlayerList {
|
||||||
g.AddSceneEntityNotify(otherPlayer, proto.VisionType_VISION_TYPE_BORN, []uint32{gadgetEntityId}, false)
|
// g.AddSceneEntityNotify(otherPlayer, proto.VisionType_VISION_TYPE_BORN, []uint32{gadgetEntityId}, false)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
// 更新场景实体的位置信息
|
// 更新场景实体的位置信息
|
||||||
sceneEntity := scene.GetEntity(entityMoveInfo.EntityId)
|
sceneEntity := scene.GetEntity(entityMoveInfo.EntityId)
|
||||||
@@ -198,7 +198,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
|||||||
sceneEntity.moveState = uint16(motionInfo.State)
|
sceneEntity.moveState = uint16(motionInfo.State)
|
||||||
sceneEntity.lastMoveSceneTimeMs = entityMoveInfo.SceneTime
|
sceneEntity.lastMoveSceneTimeMs = entityMoveInfo.SceneTime
|
||||||
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)
|
||||||
}
|
}
|
||||||
invokeHandler.addEntry(entry.ForwardType, entry)
|
invokeHandler.addEntry(entry.ForwardType, entry)
|
||||||
default:
|
default:
|
||||||
@@ -246,7 +246,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameManager) AbilityInvocationsNotify(player *model.Player, payloadMsg pb.Message) {
|
func (g *GameManager) AbilityInvocationsNotify(player *model.Player, payloadMsg pb.Message) {
|
||||||
//logger.LOG.Debug("user ability invocations, uid: %v", player.PlayerID)
|
logger.LOG.Debug("user ability invocations, uid: %v", player.PlayerID)
|
||||||
req := payloadMsg.(*proto.AbilityInvocationsNotify)
|
req := payloadMsg.(*proto.AbilityInvocationsNotify)
|
||||||
world := g.worldManager.GetWorldByID(player.WorldId)
|
world := g.worldManager.GetWorldByID(player.WorldId)
|
||||||
if world == nil {
|
if world == nil {
|
||||||
@@ -255,7 +255,7 @@ func (g *GameManager) AbilityInvocationsNotify(player *model.Player, payloadMsg
|
|||||||
scene := world.GetSceneById(player.SceneId)
|
scene := world.GetSceneById(player.SceneId)
|
||||||
invokeHandler := NewInvokeHandler[proto.AbilityInvokeEntry]()
|
invokeHandler := NewInvokeHandler[proto.AbilityInvokeEntry]()
|
||||||
for _, entry := range req.Invokes {
|
for _, entry := range req.Invokes {
|
||||||
//logger.LOG.Debug("AT: %v, FT: %v, UID: %v", entry.ArgumentType, entry.ForwardType, player.PlayerID)
|
logger.LOG.Debug("AT: %v, FT: %v, UID: %v", entry.ArgumentType, entry.ForwardType, player.PlayerID)
|
||||||
invokeHandler.addEntry(entry.ForwardType, entry)
|
invokeHandler.addEntry(entry.ForwardType, entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,7 +299,7 @@ func (g *GameManager) AbilityInvocationsNotify(player *model.Player, payloadMsg
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameManager) ClientAbilityInitFinishNotify(player *model.Player, payloadMsg pb.Message) {
|
func (g *GameManager) ClientAbilityInitFinishNotify(player *model.Player, payloadMsg pb.Message) {
|
||||||
//logger.LOG.Debug("user client ability ok, uid: %v", player.PlayerID)
|
logger.LOG.Debug("user client ability ok, uid: %v", player.PlayerID)
|
||||||
req := payloadMsg.(*proto.ClientAbilityInitFinishNotify)
|
req := payloadMsg.(*proto.ClientAbilityInitFinishNotify)
|
||||||
world := g.worldManager.GetWorldByID(player.WorldId)
|
world := g.worldManager.GetWorldByID(player.WorldId)
|
||||||
if world == nil {
|
if world == nil {
|
||||||
@@ -308,7 +308,7 @@ func (g *GameManager) ClientAbilityInitFinishNotify(player *model.Player, payloa
|
|||||||
scene := world.GetSceneById(player.SceneId)
|
scene := world.GetSceneById(player.SceneId)
|
||||||
invokeHandler := NewInvokeHandler[proto.AbilityInvokeEntry]()
|
invokeHandler := NewInvokeHandler[proto.AbilityInvokeEntry]()
|
||||||
for _, entry := range req.Invokes {
|
for _, entry := range req.Invokes {
|
||||||
//logger.LOG.Debug("AT: %v, FT: %v, UID: %v", entry.ArgumentType, entry.ForwardType, player.PlayerID)
|
logger.LOG.Debug("AT: %v, FT: %v, UID: %v", entry.ArgumentType, entry.ForwardType, player.PlayerID)
|
||||||
invokeHandler.addEntry(entry.ForwardType, entry)
|
invokeHandler.addEntry(entry.ForwardType, entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -286,10 +286,10 @@ func (g *GameManager) DoGachaReq(player *model.Player, payloadMsg pb.Message) {
|
|||||||
xh := uint32(random.GetRandomInt32(0, 10))
|
xh := uint32(random.GetRandomInt32(0, 10))
|
||||||
|
|
||||||
gachaItem := new(proto.GachaItem)
|
gachaItem := new(proto.GachaItem)
|
||||||
gachaItem.TokenItemList = []*proto.ItemParam{{
|
gachaItem.GachaItem = &proto.ItemParam{
|
||||||
ItemId: itemId,
|
ItemId: itemId,
|
||||||
Count: 1,
|
Count: 1,
|
||||||
}}
|
}
|
||||||
// 星尘
|
// 星尘
|
||||||
if xc != 0 {
|
if xc != 0 {
|
||||||
g.AddUserItem(player.PlayerID, []*UserItem{{
|
g.AddUserItem(player.PlayerID, []*UserItem{{
|
||||||
@@ -317,7 +317,7 @@ func (g *GameManager) DoGachaReq(player *model.Player, payloadMsg pb.Message) {
|
|||||||
doGachaRsp.GachaItemList = append(doGachaRsp.GachaItemList, gachaItem)
|
doGachaRsp.GachaItemList = append(doGachaRsp.GachaItemList, gachaItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
//logger.LOG.Debug("doGachaRsp: %v", doGachaRsp.String())
|
logger.LOG.Debug("doGachaRsp: %v", doGachaRsp.String())
|
||||||
g.SendMsg(cmd.DoGachaRsp, player.PlayerID, player.ClientSeq, doGachaRsp)
|
g.SendMsg(cmd.DoGachaRsp, player.PlayerID, player.ClientSeq, doGachaRsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,17 +42,17 @@ func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq u
|
|||||||
world.AddPlayer(player, player.SceneId)
|
world.AddPlayer(player, player.SceneId)
|
||||||
player.WorldId = world.id
|
player.WorldId = world.id
|
||||||
|
|
||||||
// TODO 薄荷标记
|
//// TODO 薄荷标记
|
||||||
if world.IsBigWorld() {
|
//if world.IsBigWorld() {
|
||||||
bigWorld := world.GetSceneById(3)
|
// bigWorld := world.GetSceneById(3)
|
||||||
for pos := range g.worldManager.worldStatic.terrain {
|
// for pos := range g.worldManager.worldStatic.terrain {
|
||||||
bigWorld.CreateEntityGadget(&model.Vector{
|
// bigWorld.CreateEntityGadget(&model.Vector{
|
||||||
X: float64(pos.X),
|
// X: float64(pos.X),
|
||||||
Y: float64(pos.Y),
|
// Y: float64(pos.Y),
|
||||||
Z: float64(pos.Z),
|
// Z: float64(pos.Z),
|
||||||
}, 3003009)
|
// }, 3003009)
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
// PacketPlayerDataNotify
|
// PacketPlayerDataNotify
|
||||||
playerDataNotify := new(proto.PlayerDataNotify)
|
playerDataNotify := new(proto.PlayerDataNotify)
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ func (g *GameManager) PathfindingEnterSceneReq(player *model.Player, payloadMsg
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameManager) QueryPathReq(player *model.Player, payloadMsg pb.Message) {
|
func (g *GameManager) QueryPathReq(player *model.Player, payloadMsg pb.Message) {
|
||||||
//logger.LOG.Debug("user query path, uid: %v", player.PlayerID)
|
logger.LOG.Debug("user query path, uid: %v", player.PlayerID)
|
||||||
req := payloadMsg.(*proto.QueryPathReq)
|
req := payloadMsg.(*proto.QueryPathReq)
|
||||||
|
|
||||||
// PacketQueryPathRsp
|
// PacketQueryPathRsp
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/gob"
|
|
||||||
pb "google.golang.org/protobuf/proto"
|
pb "google.golang.org/protobuf/proto"
|
||||||
"hk4e/common/utils/alg"
|
"hk4e/common/utils/alg"
|
||||||
gdc "hk4e/gs/config"
|
|
||||||
"hk4e/gs/constant"
|
"hk4e/gs/constant"
|
||||||
"hk4e/gs/game/aoi"
|
"hk4e/gs/game/aoi"
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
@@ -14,160 +11,10 @@ import (
|
|||||||
"hk4e/protocol/proto"
|
"hk4e/protocol/proto"
|
||||||
"math"
|
"math"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 世界管理器
|
// 世界管理器
|
||||||
|
|
||||||
type MeshMapPos struct {
|
|
||||||
X int16
|
|
||||||
Y int16
|
|
||||||
Z int16
|
|
||||||
}
|
|
||||||
|
|
||||||
type WorldStatic struct {
|
|
||||||
// x y z -> if terrain exist
|
|
||||||
terrain map[MeshMapPos]bool
|
|
||||||
// x y z -> gather id
|
|
||||||
gather map[MeshMapPos]uint32
|
|
||||||
pathfindingStartPos MeshMapPos
|
|
||||||
pathfindingEndPos MeshMapPos
|
|
||||||
pathVectorList []MeshMapPos
|
|
||||||
aiMoveMeshSpeedParam int
|
|
||||||
aiMoveVectorList []*model.Vector
|
|
||||||
aiMoveCurrIndex int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewWorldStatic() (r *WorldStatic) {
|
|
||||||
r = new(WorldStatic)
|
|
||||||
r.terrain = make(map[MeshMapPos]bool)
|
|
||||||
r.gather = make(map[MeshMapPos]uint32)
|
|
||||||
r.InitGather()
|
|
||||||
r.pathfindingStartPos = MeshMapPos{
|
|
||||||
X: 2747,
|
|
||||||
Y: 194,
|
|
||||||
Z: -1719,
|
|
||||||
}
|
|
||||||
r.pathfindingEndPos = MeshMapPos{
|
|
||||||
X: 2588,
|
|
||||||
Y: 211,
|
|
||||||
Z: -1349,
|
|
||||||
}
|
|
||||||
r.pathVectorList = make([]MeshMapPos, 0)
|
|
||||||
r.aiMoveMeshSpeedParam = 3
|
|
||||||
r.aiMoveVectorList = make([]*model.Vector, 0)
|
|
||||||
r.aiMoveCurrIndex = 0
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WorldStatic) ConvWSTMapToPFMap() map[alg.MeshMapPos]bool {
|
|
||||||
return *(*map[alg.MeshMapPos]bool)(unsafe.Pointer(&w.terrain))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WorldStatic) ConvWSPosToPFPos(v MeshMapPos) alg.MeshMapPos {
|
|
||||||
return alg.MeshMapPos(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WorldStatic) ConvPFPVLToWSPVL(v []alg.MeshMapPos) []MeshMapPos {
|
|
||||||
return *(*[]MeshMapPos)(unsafe.Pointer(&v))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WorldStatic) Pathfinding() {
|
|
||||||
bfs := alg.NewBFS()
|
|
||||||
bfs.InitMap(
|
|
||||||
w.ConvWSTMapToPFMap(),
|
|
||||||
w.ConvWSPosToPFPos(w.pathfindingStartPos),
|
|
||||||
w.ConvWSPosToPFPos(w.pathfindingEndPos),
|
|
||||||
100,
|
|
||||||
)
|
|
||||||
pathVectorList := bfs.Pathfinding()
|
|
||||||
if pathVectorList == nil {
|
|
||||||
logger.LOG.Error("could not find path")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
logger.LOG.Debug("find path success, path: %v", pathVectorList)
|
|
||||||
w.pathVectorList = w.ConvPFPVLToWSPVL(pathVectorList)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WorldStatic) ConvPathVectorListToAiMoveVectorList() {
|
|
||||||
for index, currPathVector := range w.pathVectorList {
|
|
||||||
if index > 0 {
|
|
||||||
lastPathVector := w.pathVectorList[index-1]
|
|
||||||
for i := 0; i < w.aiMoveMeshSpeedParam; i++ {
|
|
||||||
w.aiMoveVectorList = append(w.aiMoveVectorList, &model.Vector{
|
|
||||||
X: float64(lastPathVector.X) + float64(currPathVector.X-lastPathVector.X)/float64(w.aiMoveMeshSpeedParam)*float64(i),
|
|
||||||
Y: float64(lastPathVector.Y) + float64(currPathVector.Y-lastPathVector.Y)/float64(w.aiMoveMeshSpeedParam)*float64(i),
|
|
||||||
Z: float64(lastPathVector.Z) + float64(currPathVector.Z-lastPathVector.Z)/float64(w.aiMoveMeshSpeedParam)*float64(i),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WorldStatic) InitTerrain() bool {
|
|
||||||
data := gdc.CONF.ReadWorldTerrain()
|
|
||||||
decoder := gob.NewDecoder(bytes.NewReader(data))
|
|
||||||
err := decoder.Decode(&w.terrain)
|
|
||||||
if err != nil {
|
|
||||||
logger.LOG.Error("unmarshal world terrain data error: %v", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WorldStatic) SaveTerrain() bool {
|
|
||||||
var buffer bytes.Buffer
|
|
||||||
encoder := gob.NewEncoder(&buffer)
|
|
||||||
err := encoder.Encode(w.terrain)
|
|
||||||
if err != nil {
|
|
||||||
logger.LOG.Error("marshal world terrain data error: %v", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
gdc.CONF.WriteWorldTerrain(buffer.Bytes())
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WorldStatic) GetTerrain(x int16, y int16, z int16) (exist bool) {
|
|
||||||
pos := MeshMapPos{
|
|
||||||
X: x,
|
|
||||||
Y: y,
|
|
||||||
Z: z,
|
|
||||||
}
|
|
||||||
exist = w.terrain[pos]
|
|
||||||
return exist
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WorldStatic) SetTerrain(x int16, y int16, z int16) {
|
|
||||||
pos := MeshMapPos{
|
|
||||||
X: x,
|
|
||||||
Y: y,
|
|
||||||
Z: z,
|
|
||||||
}
|
|
||||||
w.terrain[pos] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WorldStatic) InitGather() {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WorldStatic) GetGather(x int16, y int16, z int16) (gatherId uint32, exist bool) {
|
|
||||||
pos := MeshMapPos{
|
|
||||||
X: x,
|
|
||||||
Y: y,
|
|
||||||
Z: z,
|
|
||||||
}
|
|
||||||
gatherId, exist = w.gather[pos]
|
|
||||||
return gatherId, exist
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WorldStatic) SetGather(x int16, y int16, z int16, gatherId uint32) {
|
|
||||||
pos := MeshMapPos{
|
|
||||||
X: x,
|
|
||||||
Y: y,
|
|
||||||
Z: z,
|
|
||||||
}
|
|
||||||
w.gather[pos] = gatherId
|
|
||||||
}
|
|
||||||
|
|
||||||
type WorldManager struct {
|
type WorldManager struct {
|
||||||
worldMap map[uint32]*World
|
worldMap map[uint32]*World
|
||||||
snowflake *alg.SnowflakeWorker
|
snowflake *alg.SnowflakeWorker
|
||||||
@@ -180,6 +27,9 @@ func NewWorldManager(snowflake *alg.SnowflakeWorker) (r *WorldManager) {
|
|||||||
r.worldMap = make(map[uint32]*World)
|
r.worldMap = make(map[uint32]*World)
|
||||||
r.snowflake = snowflake
|
r.snowflake = snowflake
|
||||||
r.worldStatic = NewWorldStatic()
|
r.worldStatic = NewWorldStatic()
|
||||||
|
r.worldStatic.InitTerrain()
|
||||||
|
//r.worldStatic.Pathfinding()
|
||||||
|
//r.worldStatic.ConvPathVectorListToAiMoveVectorList()
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,6 +370,8 @@ func (s *Scene) GetEntity(entityId uint32) *Entity {
|
|||||||
return s.entityMap[entityId]
|
return s.entityMap[entityId]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 伤害处理和转发
|
||||||
|
|
||||||
func (s *Scene) AddAttack(attack *Attack) {
|
func (s *Scene) AddAttack(attack *Attack) {
|
||||||
s.attackQueue.EnQueue(attack)
|
s.attackQueue.EnQueue(attack)
|
||||||
}
|
}
|
||||||
@@ -544,7 +396,7 @@ func (s *Scene) AttackHandler(gameManager *GameManager) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
attackResult := hitInfo.AttackResult
|
attackResult := hitInfo.AttackResult
|
||||||
//logger.LOG.Debug("run attack handler, attackResult: %v", attackResult)
|
logger.LOG.Debug("run attack handler, attackResult: %v", attackResult)
|
||||||
target := s.entityMap[attackResult.DefenseId]
|
target := s.entityMap[attackResult.DefenseId]
|
||||||
if target == nil {
|
if target == nil {
|
||||||
logger.LOG.Error("could not found target, defense id: %v", attackResult.DefenseId)
|
logger.LOG.Error("could not found target, defense id: %v", attackResult.DefenseId)
|
||||||
|
|||||||
162
gs/game/world_static.go
Normal file
162
gs/game/world_static.go
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
package game
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/gob"
|
||||||
|
"hk4e/common/utils/alg"
|
||||||
|
gdc "hk4e/gs/config"
|
||||||
|
"hk4e/gs/model"
|
||||||
|
"hk4e/logger"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 世界的静态资源坐标点数据
|
||||||
|
|
||||||
|
type MeshMapPos struct {
|
||||||
|
X int16
|
||||||
|
Y int16
|
||||||
|
Z int16
|
||||||
|
}
|
||||||
|
|
||||||
|
type WorldStatic struct {
|
||||||
|
// x y z -> if terrain exist
|
||||||
|
terrain map[MeshMapPos]bool
|
||||||
|
// x y z -> gather id
|
||||||
|
gather map[MeshMapPos]uint32
|
||||||
|
pathfindingStartPos MeshMapPos
|
||||||
|
pathfindingEndPos MeshMapPos
|
||||||
|
pathVectorList []MeshMapPos
|
||||||
|
aiMoveMeshSpeedParam int
|
||||||
|
aiMoveVectorList []*model.Vector
|
||||||
|
aiMoveCurrIndex int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWorldStatic() (r *WorldStatic) {
|
||||||
|
r = new(WorldStatic)
|
||||||
|
r.terrain = make(map[MeshMapPos]bool)
|
||||||
|
r.gather = make(map[MeshMapPos]uint32)
|
||||||
|
r.InitGather()
|
||||||
|
r.pathfindingStartPos = MeshMapPos{
|
||||||
|
X: 2747,
|
||||||
|
Y: 194,
|
||||||
|
Z: -1719,
|
||||||
|
}
|
||||||
|
r.pathfindingEndPos = MeshMapPos{
|
||||||
|
X: 2588,
|
||||||
|
Y: 211,
|
||||||
|
Z: -1349,
|
||||||
|
}
|
||||||
|
r.pathVectorList = make([]MeshMapPos, 0)
|
||||||
|
r.aiMoveMeshSpeedParam = 3
|
||||||
|
r.aiMoveVectorList = make([]*model.Vector, 0)
|
||||||
|
r.aiMoveCurrIndex = 0
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorldStatic) InitTerrain() bool {
|
||||||
|
data := gdc.CONF.ReadWorldTerrain()
|
||||||
|
decoder := gob.NewDecoder(bytes.NewReader(data))
|
||||||
|
err := decoder.Decode(&w.terrain)
|
||||||
|
if err != nil {
|
||||||
|
logger.LOG.Error("unmarshal world terrain data error: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorldStatic) SaveTerrain() bool {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
encoder := gob.NewEncoder(&buffer)
|
||||||
|
err := encoder.Encode(w.terrain)
|
||||||
|
if err != nil {
|
||||||
|
logger.LOG.Error("marshal world terrain data error: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
gdc.CONF.WriteWorldTerrain(buffer.Bytes())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorldStatic) GetTerrain(x int16, y int16, z int16) (exist bool) {
|
||||||
|
pos := MeshMapPos{
|
||||||
|
X: x,
|
||||||
|
Y: y,
|
||||||
|
Z: z,
|
||||||
|
}
|
||||||
|
exist = w.terrain[pos]
|
||||||
|
return exist
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorldStatic) SetTerrain(x int16, y int16, z int16) {
|
||||||
|
pos := MeshMapPos{
|
||||||
|
X: x,
|
||||||
|
Y: y,
|
||||||
|
Z: z,
|
||||||
|
}
|
||||||
|
w.terrain[pos] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorldStatic) InitGather() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorldStatic) GetGather(x int16, y int16, z int16) (gatherId uint32, exist bool) {
|
||||||
|
pos := MeshMapPos{
|
||||||
|
X: x,
|
||||||
|
Y: y,
|
||||||
|
Z: z,
|
||||||
|
}
|
||||||
|
gatherId, exist = w.gather[pos]
|
||||||
|
return gatherId, exist
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorldStatic) SetGather(x int16, y int16, z int16, gatherId uint32) {
|
||||||
|
pos := MeshMapPos{
|
||||||
|
X: x,
|
||||||
|
Y: y,
|
||||||
|
Z: z,
|
||||||
|
}
|
||||||
|
w.gather[pos] = gatherId
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorldStatic) ConvWSTMapToPFMap() map[alg.MeshMapPos]bool {
|
||||||
|
return *(*map[alg.MeshMapPos]bool)(unsafe.Pointer(&w.terrain))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorldStatic) ConvWSPosToPFPos(v MeshMapPos) alg.MeshMapPos {
|
||||||
|
return alg.MeshMapPos(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorldStatic) ConvPFPVLToWSPVL(v []alg.MeshMapPos) []MeshMapPos {
|
||||||
|
return *(*[]MeshMapPos)(unsafe.Pointer(&v))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorldStatic) Pathfinding() {
|
||||||
|
bfs := alg.NewBFS()
|
||||||
|
bfs.InitMap(
|
||||||
|
w.ConvWSTMapToPFMap(),
|
||||||
|
w.ConvWSPosToPFPos(w.pathfindingStartPos),
|
||||||
|
w.ConvWSPosToPFPos(w.pathfindingEndPos),
|
||||||
|
100,
|
||||||
|
)
|
||||||
|
pathVectorList := bfs.Pathfinding()
|
||||||
|
if pathVectorList == nil {
|
||||||
|
logger.LOG.Error("could not find path")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logger.LOG.Debug("find path success, path: %v", pathVectorList)
|
||||||
|
w.pathVectorList = w.ConvPFPVLToWSPVL(pathVectorList)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WorldStatic) ConvPathVectorListToAiMoveVectorList() {
|
||||||
|
for index, currPathVector := range w.pathVectorList {
|
||||||
|
if index > 0 {
|
||||||
|
lastPathVector := w.pathVectorList[index-1]
|
||||||
|
for i := 0; i < w.aiMoveMeshSpeedParam; i++ {
|
||||||
|
w.aiMoveVectorList = append(w.aiMoveVectorList, &model.Vector{
|
||||||
|
X: float64(lastPathVector.X) + float64(currPathVector.X-lastPathVector.X)/float64(w.aiMoveMeshSpeedParam)*float64(i),
|
||||||
|
Y: float64(lastPathVector.Y) + float64(currPathVector.Y-lastPathVector.Y)/float64(w.aiMoveMeshSpeedParam)*float64(i),
|
||||||
|
Z: float64(lastPathVector.Z) + float64(currPathVector.Z-lastPathVector.Z)/float64(w.aiMoveMeshSpeedParam)*float64(i),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user