mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 14:22:26 +08:00
优化代码
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
http_port = 8080
|
||||
|
||||
[hk4e]
|
||||
kcp_addr = "hk4e.flswld.com"
|
||||
kcp_addr = "127.0.0.1"
|
||||
kcp_port = 22103
|
||||
login_sdk_url = "https://api.flswld.com/api/v1/auth/login"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[hk4e]
|
||||
kcp_addr = "hk4e.flswld.com"
|
||||
kcp_addr = "127.0.0.1"
|
||||
kcp_port = 22103
|
||||
|
||||
[logger]
|
||||
|
||||
@@ -25,7 +25,7 @@ type GameManager struct {
|
||||
userManager *UserManager
|
||||
// 世界管理器
|
||||
worldManager *WorldManager
|
||||
// 游戏服务器tick
|
||||
// 游戏服务器定时帧管理器
|
||||
tickManager *TickManager
|
||||
}
|
||||
|
||||
@@ -41,11 +41,7 @@ func NewGameManager(dao *dao.Dao, netMsgInput chan *cmd.NetMsg, netMsgOutput cha
|
||||
r.worldManager = NewWorldManager(r.snowflake)
|
||||
r.tickManager = NewTickManager(r)
|
||||
|
||||
//r.worldManager.worldStatic.InitTerrain()
|
||||
//r.worldManager.worldStatic.Pathfinding()
|
||||
//r.worldManager.worldStatic.ConvPathVectorListToAiMoveVectorList()
|
||||
|
||||
// 大世界的主人
|
||||
// 创建一个公共的开放世界的AI
|
||||
r.OnRegOk(false, &proto.SetPlayerBornDataReq{AvatarId: 10000007, NickName: "大世界的主人"}, 1, 0)
|
||||
bigWorldOwner := r.userManager.GetOnlineUser(1)
|
||||
bigWorldOwner.SceneLoadState = model.SceneEnterDone
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package game
|
||||
|
||||
// 本地事件队列管理器
|
||||
|
||||
const (
|
||||
LoadLoginUserFromDbFinish = iota
|
||||
CheckUserExistOnRegFromDbFinish
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"hk4e/protocol/cmd"
|
||||
)
|
||||
|
||||
// 接口路由管理器
|
||||
|
||||
type HandlerFunc func(player *model.Player, payloadMsg pb.Message)
|
||||
|
||||
type RouteManager struct {
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// 游戏服务器定时帧管理器
|
||||
|
||||
type TickManager struct {
|
||||
ticker *time.Ticker
|
||||
tickCount uint64
|
||||
@@ -77,7 +79,7 @@ func (t *TickManager) onTick10Minute(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 _, player := range world.playerMap {
|
||||
// 随机物品
|
||||
@@ -149,6 +151,7 @@ func (t *TickManager) onTick5Second(now int64) {
|
||||
}
|
||||
for _, player := range world.playerMap {
|
||||
if world.multiplayer {
|
||||
// 多人世界其他玩家的坐标位置广播
|
||||
// PacketWorldPlayerLocationNotify
|
||||
worldPlayerLocationNotify := new(proto.WorldPlayerLocationNotify)
|
||||
for _, worldPlayer := range world.playerMap {
|
||||
@@ -201,6 +204,7 @@ func (t *TickManager) onTick5Second(now int64) {
|
||||
func (t *TickManager) onTickSecond(now int64) {
|
||||
for _, world := range t.gameManager.worldManager.worldMap {
|
||||
for _, player := range world.playerMap {
|
||||
// 世界里所有玩家的网络延迟广播
|
||||
// PacketWorldPlayerRTTNotify
|
||||
worldPlayerRTTNotify := new(proto.WorldPlayerRTTNotify)
|
||||
worldPlayerRTTNotify.PlayerRttList = make([]*proto.PlayerRTTInfo, 0)
|
||||
@@ -214,13 +218,15 @@ func (t *TickManager) onTickSecond(now int64) {
|
||||
}
|
||||
|
||||
func (t *TickManager) onTick100MilliSecond(now int64) {
|
||||
// AttackHandler
|
||||
// 伤害处理和转发
|
||||
for _, world := range t.gameManager.worldManager.worldMap {
|
||||
for _, scene := range world.sceneMap {
|
||||
scene.AttackHandler(t.gameManager)
|
||||
}
|
||||
}
|
||||
|
||||
// 服务器控制的模拟AI移动
|
||||
|
||||
//bigWorldOwner := t.gameManager.userManager.GetOnlineUser(1)
|
||||
//bigWorld := t.gameManager.worldManager.GetBigWorld()
|
||||
//bigWorldScene := bigWorld.GetSceneById(3)
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
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)
|
||||
world := g.worldManager.GetWorldByID(player.WorldId)
|
||||
if world == nil {
|
||||
@@ -18,7 +18,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
||||
scene := world.GetSceneById(player.SceneId)
|
||||
invokeHandler := NewInvokeHandler[proto.CombatInvokeEntry]()
|
||||
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 {
|
||||
case proto.CombatTypeArgument_COMBAT_TYPE_ARGUMENT_EVT_BEING_HIT:
|
||||
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.Y = float64(motionInfo.Rot.Y)
|
||||
player.Rot.Z = float64(motionInfo.Rot.Z)
|
||||
// TODO 采集大地图地形数据
|
||||
if world.IsBigWorld() && scene.id == 3 && player.PlayerID != 1 {
|
||||
if motionInfo.State == proto.MotionState_MOTION_STATE_WALK ||
|
||||
motionInfo.State == proto.MotionState_MOTION_STATE_RUN ||
|
||||
motionInfo.State == proto.MotionState_MOTION_STATE_DASH ||
|
||||
motionInfo.State == proto.MotionState_MOTION_STATE_CLIMB {
|
||||
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))
|
||||
g.worldManager.worldStatic.SetTerrain(int16(motionInfo.Pos.X), int16(motionInfo.Pos.Y), int16(motionInfo.Pos.Z))
|
||||
if !exist {
|
||||
// TODO 薄荷标记
|
||||
// 只给附近aoi区域的玩家广播消息
|
||||
surrPlayerList := make([]*model.Player, 0)
|
||||
entityIdList := world.aoiManager.GetEntityIdListByPos(float32(player.Pos.X), float32(player.Pos.Y), float32(player.Pos.Z))
|
||||
for _, entityId := range entityIdList {
|
||||
entity := scene.GetEntity(entityId)
|
||||
if entity == nil {
|
||||
continue
|
||||
}
|
||||
if entity.avatarEntity != nil {
|
||||
otherPlayer := g.userManager.GetOnlineUser(entity.avatarEntity.uid)
|
||||
surrPlayerList = append(surrPlayerList, otherPlayer)
|
||||
}
|
||||
}
|
||||
pos := &model.Vector{
|
||||
X: float64(int16(motionInfo.Pos.X)),
|
||||
Y: float64(int16(motionInfo.Pos.Y)),
|
||||
Z: float64(int16(motionInfo.Pos.Z)),
|
||||
}
|
||||
gadgetEntityId := scene.CreateEntityGadget(pos, 3003009)
|
||||
for _, otherPlayer := range surrPlayerList {
|
||||
g.AddSceneEntityNotify(otherPlayer, proto.VisionType_VISION_TYPE_BORN, []uint32{gadgetEntityId}, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//// TODO 采集大地图地形数据
|
||||
//if world.IsBigWorld() && scene.id == 3 && player.PlayerID != 1 {
|
||||
// if motionInfo.State == proto.MotionState_MOTION_STATE_WALK ||
|
||||
// motionInfo.State == proto.MotionState_MOTION_STATE_RUN ||
|
||||
// motionInfo.State == proto.MotionState_MOTION_STATE_DASH ||
|
||||
// motionInfo.State == proto.MotionState_MOTION_STATE_CLIMB {
|
||||
// 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))
|
||||
// g.worldManager.worldStatic.SetTerrain(int16(motionInfo.Pos.X), int16(motionInfo.Pos.Y), int16(motionInfo.Pos.Z))
|
||||
// if !exist {
|
||||
// // TODO 薄荷标记
|
||||
// // 只给附近aoi区域的玩家广播消息
|
||||
// surrPlayerList := make([]*model.Player, 0)
|
||||
// entityIdList := world.aoiManager.GetEntityIdListByPos(float32(player.Pos.X), float32(player.Pos.Y), float32(player.Pos.Z))
|
||||
// for _, entityId := range entityIdList {
|
||||
// entity := scene.GetEntity(entityId)
|
||||
// if entity == nil {
|
||||
// continue
|
||||
// }
|
||||
// if entity.avatarEntity != nil {
|
||||
// otherPlayer := g.userManager.GetOnlineUser(entity.avatarEntity.uid)
|
||||
// surrPlayerList = append(surrPlayerList, otherPlayer)
|
||||
// }
|
||||
// }
|
||||
// pos := &model.Vector{
|
||||
// X: float64(int16(motionInfo.Pos.X)),
|
||||
// Y: float64(int16(motionInfo.Pos.Y)),
|
||||
// Z: float64(int16(motionInfo.Pos.Z)),
|
||||
// }
|
||||
// gadgetEntityId := scene.CreateEntityGadget(pos, 3003009)
|
||||
// for _, otherPlayer := range surrPlayerList {
|
||||
// g.AddSceneEntityNotify(otherPlayer, proto.VisionType_VISION_TYPE_BORN, []uint32{gadgetEntityId}, false)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
// 更新场景实体的位置信息
|
||||
sceneEntity := scene.GetEntity(entityMoveInfo.EntityId)
|
||||
@@ -198,7 +198,7 @@ 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)
|
||||
logger.LOG.Debug("entity move, id: %v, pos: %v, uid: %v", sceneEntity.id, sceneEntity.pos, player.PlayerID)
|
||||
}
|
||||
invokeHandler.addEntry(entry.ForwardType, entry)
|
||||
default:
|
||||
@@ -246,7 +246,7 @@ 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)
|
||||
logger.LOG.Debug("user ability invocations, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.AbilityInvocationsNotify)
|
||||
world := g.worldManager.GetWorldByID(player.WorldId)
|
||||
if world == nil {
|
||||
@@ -255,7 +255,7 @@ func (g *GameManager) AbilityInvocationsNotify(player *model.Player, payloadMsg
|
||||
scene := world.GetSceneById(player.SceneId)
|
||||
invokeHandler := NewInvokeHandler[proto.AbilityInvokeEntry]()
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ func (g *GameManager) AbilityInvocationsNotify(player *model.Player, payloadMsg
|
||||
}
|
||||
|
||||
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)
|
||||
world := g.worldManager.GetWorldByID(player.WorldId)
|
||||
if world == nil {
|
||||
@@ -308,7 +308,7 @@ func (g *GameManager) ClientAbilityInitFinishNotify(player *model.Player, payloa
|
||||
scene := world.GetSceneById(player.SceneId)
|
||||
invokeHandler := NewInvokeHandler[proto.AbilityInvokeEntry]()
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
@@ -286,10 +286,10 @@ func (g *GameManager) DoGachaReq(player *model.Player, payloadMsg pb.Message) {
|
||||
xh := uint32(random.GetRandomInt32(0, 10))
|
||||
|
||||
gachaItem := new(proto.GachaItem)
|
||||
gachaItem.TokenItemList = []*proto.ItemParam{{
|
||||
gachaItem.GachaItem = &proto.ItemParam{
|
||||
ItemId: itemId,
|
||||
Count: 1,
|
||||
}}
|
||||
}
|
||||
// 星尘
|
||||
if xc != 0 {
|
||||
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)
|
||||
}
|
||||
|
||||
//logger.LOG.Debug("doGachaRsp: %v", doGachaRsp.String())
|
||||
logger.LOG.Debug("doGachaRsp: %v", doGachaRsp.String())
|
||||
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)
|
||||
player.WorldId = world.id
|
||||
|
||||
// TODO 薄荷标记
|
||||
if world.IsBigWorld() {
|
||||
bigWorld := world.GetSceneById(3)
|
||||
for pos := range g.worldManager.worldStatic.terrain {
|
||||
bigWorld.CreateEntityGadget(&model.Vector{
|
||||
X: float64(pos.X),
|
||||
Y: float64(pos.Y),
|
||||
Z: float64(pos.Z),
|
||||
}, 3003009)
|
||||
}
|
||||
}
|
||||
//// TODO 薄荷标记
|
||||
//if world.IsBigWorld() {
|
||||
// bigWorld := world.GetSceneById(3)
|
||||
// for pos := range g.worldManager.worldStatic.terrain {
|
||||
// bigWorld.CreateEntityGadget(&model.Vector{
|
||||
// X: float64(pos.X),
|
||||
// Y: float64(pos.Y),
|
||||
// Z: float64(pos.Z),
|
||||
// }, 3003009)
|
||||
// }
|
||||
//}
|
||||
|
||||
// PacketPlayerDataNotify
|
||||
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) {
|
||||
//logger.LOG.Debug("user query path, uid: %v", player.PlayerID)
|
||||
logger.LOG.Debug("user query path, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.QueryPathReq)
|
||||
|
||||
// PacketQueryPathRsp
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
pb "google.golang.org/protobuf/proto"
|
||||
"hk4e/common/utils/alg"
|
||||
gdc "hk4e/gs/config"
|
||||
"hk4e/gs/constant"
|
||||
"hk4e/gs/game/aoi"
|
||||
"hk4e/gs/model"
|
||||
@@ -14,160 +11,10 @@ import (
|
||||
"hk4e/protocol/proto"
|
||||
"math"
|
||||
"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 {
|
||||
worldMap map[uint32]*World
|
||||
snowflake *alg.SnowflakeWorker
|
||||
@@ -180,6 +27,9 @@ func NewWorldManager(snowflake *alg.SnowflakeWorker) (r *WorldManager) {
|
||||
r.worldMap = make(map[uint32]*World)
|
||||
r.snowflake = snowflake
|
||||
r.worldStatic = NewWorldStatic()
|
||||
r.worldStatic.InitTerrain()
|
||||
//r.worldStatic.Pathfinding()
|
||||
//r.worldStatic.ConvPathVectorListToAiMoveVectorList()
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -520,6 +370,8 @@ func (s *Scene) GetEntity(entityId uint32) *Entity {
|
||||
return s.entityMap[entityId]
|
||||
}
|
||||
|
||||
// 伤害处理和转发
|
||||
|
||||
func (s *Scene) AddAttack(attack *Attack) {
|
||||
s.attackQueue.EnQueue(attack)
|
||||
}
|
||||
@@ -544,7 +396,7 @@ func (s *Scene) AttackHandler(gameManager *GameManager) {
|
||||
}
|
||||
|
||||
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]
|
||||
if target == nil {
|
||||
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