mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 15:52:27 +08:00
世界怪物、NPC、装置等场景实体读取lua配置生成,实现AOI九宫格动态加载
This commit is contained in:
@@ -95,7 +95,10 @@ func NewGameManager(dao *dao.Dao, messageQueue *mq.MessageQueue, gsId uint32, gs
|
||||
USER_MANAGER.SetRemoteUserOnlineState(BigWorldAiUid, true, mainGsAppid)
|
||||
if r.IsMainGs() {
|
||||
// TODO 测试
|
||||
for i := 1; i < 8; i++ {
|
||||
r.ai.Pos.X -= random.GetRandomFloat64(25.0, 35.0)
|
||||
r.ai.Pos.Y += 1.0
|
||||
r.ai.Pos.Z += random.GetRandomFloat64(25.0, 35.0)
|
||||
for i := 1; i < 3; i++ {
|
||||
uid := 1000000 + uint32(i)
|
||||
avatarId := uint32(0)
|
||||
for _, avatarData := range gdconf.CONF.AvatarDataMap {
|
||||
@@ -109,8 +112,9 @@ func NewGameManager(dao *dao.Dao, messageQueue *mq.MessageQueue, gsId uint32, gs
|
||||
AvatarTeamGuidList: []uint64{robot.AvatarMap[avatarId].Guid},
|
||||
CurAvatarGuid: robot.AvatarMap[avatarId].Guid,
|
||||
})
|
||||
robot.Pos.X += random.GetRandomFloat64(0.0, 1.0)
|
||||
robot.Pos.Z += random.GetRandomFloat64(0.0, 1.0)
|
||||
robot.Pos.X -= random.GetRandomFloat64(25.0, 35.0)
|
||||
robot.Pos.Y += 1.0
|
||||
robot.Pos.Z += random.GetRandomFloat64(25.0, 35.0)
|
||||
r.UserWorldAddPlayer(WORLD_MANAGER.GetAiWorld(), robot)
|
||||
}
|
||||
}
|
||||
@@ -170,7 +174,7 @@ func (g *GameManager) gameMainLoop() {
|
||||
logger.Error("error: %v", err)
|
||||
logger.Error("stack: %v", logger.Stack())
|
||||
motherfuckerPlayerInfo, _ := json.Marshal(SELF)
|
||||
logger.Error("the motherfucker player info: %v", motherfuckerPlayerInfo)
|
||||
logger.Error("the motherfucker player info: %v", string(motherfuckerPlayerInfo))
|
||||
if SELF != nil {
|
||||
GAME_MANAGER.DisconnectPlayer(SELF.PlayerID, kcp.EnetServerKick)
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ func (r *RouteManager) initRoute() {
|
||||
r.registerRouter(cmd.GCGAskDuelReq, GAME_MANAGER.GCGAskDuelReq)
|
||||
r.registerRouter(cmd.GCGInitFinishReq, GAME_MANAGER.GCGInitFinishReq)
|
||||
r.registerRouter(cmd.GCGOperationReq, GAME_MANAGER.GCGOperationReq)
|
||||
r.registerRouter(cmd.ObstacleModifyNotify, GAME_MANAGER.ObstacleModifyNotify)
|
||||
}
|
||||
|
||||
func (r *RouteManager) RouteHandle(netMsg *mq.NetMsg) {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"time"
|
||||
|
||||
"hk4e/common/constant"
|
||||
"hk4e/gs/model"
|
||||
"hk4e/pkg/logger"
|
||||
"hk4e/pkg/random"
|
||||
"hk4e/protocol/cmd"
|
||||
@@ -348,20 +347,6 @@ func (t *TickManager) onTickSecond(now int64) {
|
||||
player.SafePos.Z = player.Pos.Z
|
||||
}
|
||||
}
|
||||
// 刷怪
|
||||
if !WORLD_MANAGER.IsRobotWorld(world) && world.owner.SceneLoadState == model.SceneEnterDone {
|
||||
scene := world.GetSceneById(3)
|
||||
monsterEntityCount := 0
|
||||
for _, entity := range scene.entityMap {
|
||||
if entity.entityType == uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_MONSTER) {
|
||||
monsterEntityCount++
|
||||
}
|
||||
}
|
||||
if monsterEntityCount < 3 {
|
||||
monsterEntityId := t.createMonster(scene)
|
||||
GAME_MANAGER.AddSceneEntityNotify(world.owner, proto.VisionType_VISION_TYPE_BORN, []uint32{monsterEntityId}, true, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
// GCG游戏Tick
|
||||
for _, game := range GCG_MANAGER.gameMap {
|
||||
@@ -396,30 +381,3 @@ func (t *TickManager) onTick50MilliSecond(now int64) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TickManager) createMonster(scene *Scene) uint32 {
|
||||
pos := &model.Vector{
|
||||
X: 2747,
|
||||
Y: 194,
|
||||
Z: -1719,
|
||||
}
|
||||
fpm := map[uint32]float32{
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_HP): float32(72.91699),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_PHYSICAL_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_DEFENSE): float32(505.0),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_ATTACK): float32(45.679916),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_ICE_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_BASE_ATTACK): float32(45.679916),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_MAX_HP): float32(72.91699),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_FIRE_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_ELEC_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_WIND_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_ROCK_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_GRASS_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_WATER_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_BASE_HP): float32(72.91699),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_BASE_DEFENSE): float32(505.0),
|
||||
}
|
||||
entityId := scene.CreateEntityMonster(pos, 1, fpm)
|
||||
return entityId
|
||||
}
|
||||
|
||||
@@ -168,3 +168,9 @@ func (g *GameManager) ServerAppidBindNotify(userId uint32, fightAppId string, jo
|
||||
player.SceneLoadState = model.SceneNone
|
||||
g.SendMsg(cmd.PlayerEnterSceneNotify, userId, player.ClientSeq, g.PacketPlayerEnterSceneNotifyLogin(player, proto.EnterType_ENTER_TYPE_SELF))
|
||||
}
|
||||
|
||||
func (g *GameManager) ObstacleModifyNotify(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.Debug("user obstacle modify, uid: %v", player.PlayerID)
|
||||
ntf := payloadMsg.(*proto.ObstacleModifyNotify)
|
||||
logger.Debug("ObstacleModifyNotify: %v", ntf)
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
||||
logger.Error("could not found target, defense id: %v", attackResult.DefenseId)
|
||||
continue
|
||||
}
|
||||
attackResult.Damage *= 100
|
||||
attackResult.Damage *= 10
|
||||
damage := attackResult.Damage
|
||||
attackerId := attackResult.AttackerId
|
||||
_ = attackerId
|
||||
@@ -150,6 +150,9 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
||||
EntityId: target.id,
|
||||
}
|
||||
g.SendToWorldA(world, cmd.EntityFightPropUpdateNotify, player.ClientSeq, entityFightPropUpdateNotify)
|
||||
if currHp == 0 && target.avatarEntity == nil {
|
||||
scene.SetEntityLifeState(target, constant.LifeStateConst.LIFE_DEAD, proto.PlayerDieType_PLAYER_DIE_TYPE_GM)
|
||||
}
|
||||
combatData, err := pb.Marshal(hitInfo)
|
||||
if err != nil {
|
||||
logger.Error("create combat invocations entity hit info error: %v", err)
|
||||
@@ -185,6 +188,11 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
||||
}
|
||||
if sceneEntity.avatarEntity != nil {
|
||||
// 玩家实体在移动
|
||||
g.AoiPlayerMove(player, player.Pos, &model.Vector{
|
||||
X: float64(motionInfo.Pos.X),
|
||||
Y: float64(motionInfo.Pos.Y),
|
||||
Z: float64(motionInfo.Pos.Z),
|
||||
})
|
||||
// 更新玩家的位置信息
|
||||
player.Pos.X = float64(motionInfo.Pos.X)
|
||||
player.Pos.Y = float64(motionInfo.Pos.Y)
|
||||
@@ -244,6 +252,61 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GameManager) AoiPlayerMove(player *model.Player, oldPos *model.Vector, newPos *model.Vector) {
|
||||
aoiManager, exist := WORLD_MANAGER.sceneBlockAoiMap[player.SceneId]
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
scene := world.GetSceneById(player.SceneId)
|
||||
if exist {
|
||||
oldGid := aoiManager.GetGidByPos(float32(oldPos.X), 0.0, float32(oldPos.Z))
|
||||
newGid := aoiManager.GetGidByPos(float32(newPos.X), 0.0, float32(newPos.Z))
|
||||
if oldGid != newGid {
|
||||
// 跨越了格子
|
||||
oldGridList := aoiManager.GetSurrGridListByGid(oldGid)
|
||||
oldObjectMap := make(map[int64]any)
|
||||
for _, grid := range oldGridList {
|
||||
tmp := grid.GetObjectList()
|
||||
for k, v := range tmp {
|
||||
oldObjectMap[k] = v
|
||||
}
|
||||
}
|
||||
newGridList := aoiManager.GetSurrGridListByGid(newGid)
|
||||
newObjectMap := make(map[int64]any)
|
||||
for _, grid := range newGridList {
|
||||
tmp := grid.GetObjectList()
|
||||
for k, v := range tmp {
|
||||
newObjectMap[k] = v
|
||||
}
|
||||
}
|
||||
delEntityIdList := make([]uint32, 0)
|
||||
for oldObjectId := range oldObjectMap {
|
||||
_, exist := newObjectMap[oldObjectId]
|
||||
if exist {
|
||||
continue
|
||||
}
|
||||
entity := scene.GetEntityByObjectId(oldObjectId)
|
||||
if entity == nil {
|
||||
continue
|
||||
}
|
||||
scene.DestroyEntity(entity.id)
|
||||
delEntityIdList = append(delEntityIdList, entity.id)
|
||||
}
|
||||
addEntityIdList := make([]uint32, 0)
|
||||
for newObjectId, newObject := range newObjectMap {
|
||||
_, exist := oldObjectMap[newObjectId]
|
||||
if exist {
|
||||
continue
|
||||
}
|
||||
entityId := g.CreateConfigEntity(scene, newObjectId, newObject)
|
||||
addEntityIdList = append(addEntityIdList, entityId)
|
||||
}
|
||||
// 发送已消失格子里的实体消失通知
|
||||
g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_TYPE_MISS, delEntityIdList)
|
||||
// 发送新出现格子里的实体出现通知
|
||||
g.AddSceneEntityNotify(player, proto.VisionType_VISION_TYPE_MEET, addEntityIdList, false, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GameManager) AbilityInvocationsNotify(player *model.Player, payloadMsg pb.Message) {
|
||||
// logger.Debug("user ability invocations, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.AbilityInvocationsNotify)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"hk4e/common/constant"
|
||||
"hk4e/gdconf"
|
||||
gdc "hk4e/gs/config"
|
||||
"hk4e/gs/model"
|
||||
"hk4e/pkg/logger"
|
||||
@@ -225,9 +226,50 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
|
||||
player.SceneLoadState = model.SceneInitFinish
|
||||
}
|
||||
|
||||
func (g *GameManager) CreateConfigEntity(scene *Scene, objectId int64, entityConfig any) uint32 {
|
||||
switch entityConfig.(type) {
|
||||
case *gdconf.Monster:
|
||||
monster := entityConfig.(*gdconf.Monster)
|
||||
return scene.CreateEntityMonster(&model.Vector{
|
||||
X: monster.Pos.X,
|
||||
Y: monster.Pos.Y,
|
||||
Z: monster.Pos.Z,
|
||||
}, &model.Vector{
|
||||
X: monster.Rot.X,
|
||||
Y: monster.Rot.Y,
|
||||
Z: monster.Rot.Z,
|
||||
}, uint32(monster.MonsterId), uint8(monster.Level), g.GetTempFightPropMap(), uint32(monster.ConfigId), objectId)
|
||||
case *gdconf.Npc:
|
||||
npc := entityConfig.(*gdconf.Npc)
|
||||
return scene.CreateEntityNpc(&model.Vector{
|
||||
X: npc.Pos.X,
|
||||
Y: npc.Pos.Y,
|
||||
Z: npc.Pos.Z,
|
||||
}, &model.Vector{
|
||||
X: npc.Rot.X,
|
||||
Y: npc.Rot.Y,
|
||||
Z: npc.Rot.Z,
|
||||
}, uint32(npc.NpcId), 0, 0, 0, uint32(npc.ConfigId), objectId)
|
||||
case *gdconf.Gadget:
|
||||
gadget := entityConfig.(*gdconf.Gadget)
|
||||
return scene.CreateEntityGadgetNormal(&model.Vector{
|
||||
X: gadget.Pos.X,
|
||||
Y: gadget.Pos.Y,
|
||||
Z: gadget.Pos.Z,
|
||||
}, &model.Vector{
|
||||
X: gadget.Rot.X,
|
||||
Y: gadget.Rot.Y,
|
||||
Z: gadget.Rot.Z,
|
||||
}, uint32(gadget.GadgetId), uint32(gadget.ConfigId), objectId)
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Message) {
|
||||
logger.Debug("user enter scene done, uid: %v", player.PlayerID)
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
scene := world.GetSceneById(player.SceneId)
|
||||
|
||||
if world.multiplayer && world.IsPlayerFirstEnter(player) {
|
||||
guestPostEnterSceneNotify := &proto.GuestPostEnterSceneNotify{
|
||||
@@ -248,14 +290,19 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess
|
||||
activeAvatarEntityId := world.GetPlayerWorldAvatarEntityId(player, activeAvatarId)
|
||||
g.AddSceneEntityNotify(player, visionType, []uint32{activeAvatarEntityId}, true, false)
|
||||
|
||||
// 通过aoi获取场景中在自己周围格子里的全部实体id
|
||||
// entityIdList := world.aoiManager.GetEntityIdListByPos(float32(player.Pos.X), float32(player.Pos.Y), float32(player.Pos.Z))
|
||||
aoiManager, exist := WORLD_MANAGER.sceneBlockAoiMap[scene.id]
|
||||
if exist {
|
||||
objectList := aoiManager.GetObjectListByPos(float32(player.Pos.X), 0.0, float32(player.Pos.Z))
|
||||
for objectId, entityConfig := range objectList {
|
||||
g.CreateConfigEntity(scene, objectId, entityConfig)
|
||||
}
|
||||
}
|
||||
if player.SceneJump {
|
||||
visionType = proto.VisionType_VISION_TYPE_MEET
|
||||
} else {
|
||||
visionType = proto.VisionType_VISION_TYPE_TRANSPORT
|
||||
}
|
||||
entityIdList := world.GetSceneById(player.SceneId).GetEntityIdList()
|
||||
entityIdList := scene.GetEntityIdList()
|
||||
g.AddSceneEntityNotify(player, visionType, entityIdList, false, false)
|
||||
|
||||
sceneAreaWeatherNotify := &proto.SceneAreaWeatherNotify{
|
||||
@@ -297,6 +344,8 @@ func (g *GameManager) EnterWorldAreaReq(player *model.Player, payloadMsg pb.Mess
|
||||
logger.Debug("user enter world area, uid: %v", player.PlayerID)
|
||||
req := payloadMsg.(*proto.EnterWorldAreaReq)
|
||||
|
||||
logger.Debug("EnterWorldAreaReq: %v", req)
|
||||
|
||||
enterWorldAreaRsp := &proto.EnterWorldAreaRsp{
|
||||
AreaType: req.AreaType,
|
||||
AreaId: req.AreaId,
|
||||
@@ -658,7 +707,7 @@ func (g *GameManager) PacketSceneEntityInfoMonster(scene *Scene, entityId uint32
|
||||
LifeState: uint32(entity.lifeState),
|
||||
AnimatorParaList: make([]*proto.AnimatorParameterValueInfoPair, 0),
|
||||
Entity: &proto.SceneEntityInfo_Monster{
|
||||
Monster: g.PacketSceneMonsterInfo(),
|
||||
Monster: g.PacketSceneMonsterInfo(entity),
|
||||
},
|
||||
EntityClientData: new(proto.EntityClientData),
|
||||
EntityAuthorityInfo: &proto.EntityAuthorityInfo{
|
||||
@@ -767,11 +816,11 @@ func (g *GameManager) PacketSceneEntityInfoGadget(scene *Scene, entityId uint32)
|
||||
switch entity.gadgetEntity.gadgetType {
|
||||
case GADGET_TYPE_NORMAL:
|
||||
sceneEntityInfo.Entity = &proto.SceneEntityInfo_Gadget{
|
||||
Gadget: g.PacketSceneGadgetInfoNormal(entity.gadgetEntity.gadgetId),
|
||||
Gadget: g.PacketSceneGadgetInfoNormal(entity),
|
||||
}
|
||||
case GADGET_TYPE_GATHER:
|
||||
sceneEntityInfo.Entity = &proto.SceneEntityInfo_Gadget{
|
||||
Gadget: g.PacketSceneGadgetInfoGather(entity.gadgetEntity.gadgetGatherEntity),
|
||||
Gadget: g.PacketSceneGadgetInfoGather(entity),
|
||||
}
|
||||
case GADGET_TYPE_CLIENT:
|
||||
sceneEntityInfo.Entity = &proto.SceneEntityInfo_Gadget{
|
||||
@@ -821,14 +870,14 @@ func (g *GameManager) PacketSceneAvatarInfo(scene *Scene, player *model.Player,
|
||||
return sceneAvatarInfo
|
||||
}
|
||||
|
||||
func (g *GameManager) PacketSceneMonsterInfo() *proto.SceneMonsterInfo {
|
||||
func (g *GameManager) PacketSceneMonsterInfo(entity *Entity) *proto.SceneMonsterInfo {
|
||||
sceneMonsterInfo := &proto.SceneMonsterInfo{
|
||||
MonsterId: 20011301,
|
||||
MonsterId: entity.monsterEntity.monsterId,
|
||||
AuthorityPeerId: 1,
|
||||
BornType: proto.MonsterBornType_MONSTER_BORN_TYPE_DEFAULT,
|
||||
BlockId: 3001,
|
||||
TitleId: 3001,
|
||||
SpecialNameId: 40,
|
||||
// BlockId: 3001,
|
||||
// TitleId: 3001,
|
||||
// SpecialNameId: 40,
|
||||
}
|
||||
return sceneMonsterInfo
|
||||
}
|
||||
@@ -843,30 +892,30 @@ func (g *GameManager) PacketSceneNpcInfo(entity *NpcEntity) *proto.SceneNpcInfo
|
||||
return sceneNpcInfo
|
||||
}
|
||||
|
||||
func (g *GameManager) PacketSceneGadgetInfoNormal(gadgetId uint32) *proto.SceneGadgetInfo {
|
||||
func (g *GameManager) PacketSceneGadgetInfoNormal(entity *Entity) *proto.SceneGadgetInfo {
|
||||
sceneGadgetInfo := &proto.SceneGadgetInfo{
|
||||
GadgetId: gadgetId,
|
||||
GroupId: 133220271,
|
||||
ConfigId: 271003,
|
||||
GadgetState: 901,
|
||||
GadgetId: entity.gadgetEntity.gadgetId,
|
||||
GroupId: 0,
|
||||
ConfigId: entity.configId,
|
||||
GadgetState: 0,
|
||||
IsEnableInteract: true,
|
||||
AuthorityPeerId: 1,
|
||||
}
|
||||
return sceneGadgetInfo
|
||||
}
|
||||
|
||||
func (g *GameManager) PacketSceneGadgetInfoGather(gadgetGatherEntity *GadgetGatherEntity) *proto.SceneGadgetInfo {
|
||||
gather, ok := gdc.CONF.GatherDataMap[int32(gadgetGatherEntity.gatherId)]
|
||||
func (g *GameManager) PacketSceneGadgetInfoGather(entity *Entity) *proto.SceneGadgetInfo {
|
||||
gather, ok := gdc.CONF.GatherDataMap[int32(entity.gadgetEntity.gadgetGatherEntity.gatherId)]
|
||||
if !ok {
|
||||
logger.Error("gather data error, gatherId: %v", gadgetGatherEntity.gatherId)
|
||||
logger.Error("gather data error, gatherId: %v", entity.gadgetEntity.gadgetGatherEntity.gatherId)
|
||||
return new(proto.SceneGadgetInfo)
|
||||
}
|
||||
sceneGadgetInfo := &proto.SceneGadgetInfo{
|
||||
GadgetId: uint32(gather.GadgetId),
|
||||
// GroupId: 133003011,
|
||||
// ConfigId: 11001,
|
||||
GadgetId: entity.gadgetEntity.gadgetId,
|
||||
GroupId: 0,
|
||||
ConfigId: entity.configId,
|
||||
GadgetState: 0,
|
||||
IsEnableInteract: false,
|
||||
IsEnableInteract: true,
|
||||
AuthorityPeerId: 1,
|
||||
Content: &proto.SceneGadgetInfo_GatherGadget{
|
||||
GatherGadget: &proto.GatherGadgetInfo{
|
||||
@@ -920,3 +969,24 @@ func (g *GameManager) PacketDelTeamEntityNotify(scene *Scene, player *model.Play
|
||||
}
|
||||
return delTeamEntityNotify
|
||||
}
|
||||
|
||||
func (g *GameManager) GetTempFightPropMap() map[uint32]float32 {
|
||||
fpm := map[uint32]float32{
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_HP): float32(72.91699),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_PHYSICAL_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_DEFENSE): float32(505.0),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_ATTACK): float32(45.679916),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_ICE_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_BASE_ATTACK): float32(45.679916),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_MAX_HP): float32(72.91699),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_FIRE_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_ELEC_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_WIND_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_ROCK_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_GRASS_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_WATER_SUB_HURT): float32(0.1),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_BASE_HP): float32(72.91699),
|
||||
uint32(constant.FightPropertyConst.FIGHT_PROP_BASE_DEFENSE): float32(505.0),
|
||||
}
|
||||
return fpm
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"image"
|
||||
"image/color"
|
||||
"image/jpeg"
|
||||
"math"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
@@ -213,6 +214,8 @@ func LoadVideoPlayerFile() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var OBJECT_ID_COUNTER int64 = math.MaxUint32
|
||||
|
||||
func (g *GameManager) VideoPlayerUpdate(rgb bool) {
|
||||
err := LoadVideoPlayerFile()
|
||||
if err != nil {
|
||||
@@ -233,12 +236,13 @@ func (g *GameManager) VideoPlayerUpdate(rgb bool) {
|
||||
for w := 0; w < SCREEN_WIDTH; w++ {
|
||||
for h := 0; h < SCREEN_HEIGHT; h++ {
|
||||
// 创建像素点
|
||||
OBJECT_ID_COUNTER++
|
||||
if rgb {
|
||||
entityId := scene.CreateEntityGadgetNormal(&model.Vector{
|
||||
X: leftTopPos.X - float64(w)*SCREEN_DPI,
|
||||
Y: leftTopPos.Y - float64(h)*SCREEN_DPI,
|
||||
Z: leftTopPos.Z,
|
||||
}, uint32(FRAME_COLOR[w][h]))
|
||||
}, new(model.Vector), uint32(FRAME_COLOR[w][h]), 271003, OBJECT_ID_COUNTER)
|
||||
SCREEN_ENTITY_ID_LIST = append(SCREEN_ENTITY_ID_LIST, entityId)
|
||||
} else {
|
||||
if !FRAME[w][h] {
|
||||
@@ -246,7 +250,7 @@ func (g *GameManager) VideoPlayerUpdate(rgb bool) {
|
||||
X: leftTopPos.X - float64(w)*SCREEN_DPI,
|
||||
Y: leftTopPos.Y - float64(h)*SCREEN_DPI,
|
||||
Z: leftTopPos.Z,
|
||||
}, uint32(GADGET_ID))
|
||||
}, new(model.Vector), uint32(GADGET_ID), 271003, OBJECT_ID_COUNTER)
|
||||
SCREEN_ENTITY_ID_LIST = append(SCREEN_ENTITY_ID_LIST, entityId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"hk4e/common/constant"
|
||||
"hk4e/common/mq"
|
||||
"hk4e/gdconf"
|
||||
"hk4e/gs/model"
|
||||
"hk4e/pkg/alg"
|
||||
"hk4e/pkg/logger"
|
||||
@@ -16,15 +17,125 @@ import (
|
||||
// 世界管理器
|
||||
|
||||
type WorldManager struct {
|
||||
worldMap map[uint32]*World
|
||||
snowflake *alg.SnowflakeWorker
|
||||
aiWorld *World // 本服的Ai玩家世界
|
||||
worldMap map[uint32]*World
|
||||
snowflake *alg.SnowflakeWorker
|
||||
aiWorld *World // 本服的Ai玩家世界
|
||||
sceneBlockAoiMap map[uint32]*alg.AoiManager // 全局各场景地图的aoi管理器
|
||||
}
|
||||
|
||||
func NewWorldManager(snowflake *alg.SnowflakeWorker) (r *WorldManager) {
|
||||
r = new(WorldManager)
|
||||
r.worldMap = make(map[uint32]*World)
|
||||
r.snowflake = snowflake
|
||||
r.sceneBlockAoiMap = make(map[uint32]*alg.AoiManager)
|
||||
for _, sceneConfig := range gdconf.CONF.SceneMap {
|
||||
minX := int16(0)
|
||||
maxX := int16(0)
|
||||
minZ := int16(0)
|
||||
maxZ := int16(0)
|
||||
blockXLen := int16(0)
|
||||
blockYLen := int16(0)
|
||||
blockZLen := int16(0)
|
||||
ok := true
|
||||
for _, blockConfig := range sceneConfig.BlockMap {
|
||||
if int16(blockConfig.BlockRange.Min.X) < minX {
|
||||
minX = int16(blockConfig.BlockRange.Min.X)
|
||||
}
|
||||
if int16(blockConfig.BlockRange.Max.X) > maxX {
|
||||
maxX = int16(blockConfig.BlockRange.Max.X)
|
||||
}
|
||||
if int16(blockConfig.BlockRange.Min.Z) < minZ {
|
||||
minZ = int16(blockConfig.BlockRange.Min.Z)
|
||||
}
|
||||
if int16(blockConfig.BlockRange.Max.Z) > maxZ {
|
||||
maxZ = int16(blockConfig.BlockRange.Max.Z)
|
||||
}
|
||||
xLen := int16(blockConfig.BlockRange.Max.X - blockConfig.BlockRange.Min.X)
|
||||
yLen := int16(blockConfig.BlockRange.Max.Y - blockConfig.BlockRange.Min.Y)
|
||||
zLen := int16(blockConfig.BlockRange.Max.Z - blockConfig.BlockRange.Min.Z)
|
||||
if blockXLen == 0 {
|
||||
blockXLen = xLen
|
||||
} else {
|
||||
if blockXLen != xLen {
|
||||
ok = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if blockYLen == 0 {
|
||||
blockYLen = yLen
|
||||
} else {
|
||||
if blockYLen != yLen {
|
||||
ok = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if blockZLen == 0 {
|
||||
blockZLen = zLen
|
||||
} else {
|
||||
if blockZLen != zLen {
|
||||
ok = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
numX := int16(0)
|
||||
if blockXLen != 0 {
|
||||
if blockXLen > 32 {
|
||||
blockXLen = 32
|
||||
}
|
||||
numX = (maxX - minX) / blockXLen
|
||||
} else {
|
||||
numX = 1
|
||||
}
|
||||
if numX == 0 {
|
||||
numX = 1
|
||||
}
|
||||
numZ := int16(0)
|
||||
if blockZLen != 0 {
|
||||
if blockZLen > 32 {
|
||||
blockZLen = 32
|
||||
}
|
||||
numZ = (maxZ - minZ) / blockZLen
|
||||
} else {
|
||||
numZ = 1
|
||||
}
|
||||
if numZ == 0 {
|
||||
numZ = 1
|
||||
}
|
||||
aoiManager := alg.NewAoiManager()
|
||||
aoiManager.SetAoiRange(minX, maxX, -1.0, 1.0, minZ, maxZ)
|
||||
aoiManager.Init3DRectAoiManager(numX, 1, numZ)
|
||||
for _, blockConfig := range sceneConfig.BlockMap {
|
||||
for _, groupConfig := range blockConfig.GroupMap {
|
||||
for _, monsterConfig := range groupConfig.MonsterList {
|
||||
aoiManager.AddObjectToGridByPos(r.snowflake.GenId(), monsterConfig,
|
||||
float32(monsterConfig.Pos.X),
|
||||
float32(0.0),
|
||||
float32(monsterConfig.Pos.Z))
|
||||
}
|
||||
for _, npcConfig := range groupConfig.NpcList {
|
||||
aoiManager.AddObjectToGridByPos(r.snowflake.GenId(), npcConfig,
|
||||
float32(npcConfig.Pos.X),
|
||||
float32(0.0),
|
||||
float32(npcConfig.Pos.Z))
|
||||
}
|
||||
for _, gadgetConfig := range groupConfig.GadgetList {
|
||||
aoiManager.AddObjectToGridByPos(r.snowflake.GenId(), gadgetConfig,
|
||||
float32(gadgetConfig.Pos.X),
|
||||
float32(0.0),
|
||||
float32(gadgetConfig.Pos.Z))
|
||||
}
|
||||
}
|
||||
}
|
||||
if sceneConfig.Id == 3 {
|
||||
logger.Info("init scene aoi mgr, scene: %v", sceneConfig.Id)
|
||||
aoiManager.AoiInfoLog(false)
|
||||
}
|
||||
r.sceneBlockAoiMap[uint32(sceneConfig.Id)] = aoiManager
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -39,22 +150,15 @@ func (w *WorldManager) GetAllWorld() map[uint32]*World {
|
||||
func (w *WorldManager) CreateWorld(owner *model.Player) *World {
|
||||
worldId := uint32(w.snowflake.GenId())
|
||||
world := &World{
|
||||
id: worldId,
|
||||
owner: owner,
|
||||
playerMap: make(map[uint32]*model.Player),
|
||||
sceneMap: make(map[uint32]*Scene),
|
||||
entityIdCounter: 0,
|
||||
worldLevel: 0,
|
||||
multiplayer: false,
|
||||
mpLevelEntityId: 0,
|
||||
chatMsgList: make([]*proto.ChatInfo, 0),
|
||||
// // aoi划分
|
||||
// // TODO 为减少内存占用暂时去掉Y轴AOI格子划分 原来的Y轴格子数量为80
|
||||
// aoiManager: aoi.NewAoiManager(
|
||||
// -8000, 4000, 120,
|
||||
// -2000, 2000, 1,
|
||||
// -5500, 6500, 120,
|
||||
// ),
|
||||
id: worldId,
|
||||
owner: owner,
|
||||
playerMap: make(map[uint32]*model.Player),
|
||||
sceneMap: make(map[uint32]*Scene),
|
||||
entityIdCounter: 0,
|
||||
worldLevel: 0,
|
||||
multiplayer: false,
|
||||
mpLevelEntityId: 0,
|
||||
chatMsgList: make([]*proto.ChatInfo, 0),
|
||||
playerFirstEnterMap: make(map[uint32]int64),
|
||||
waitEnterPlayerMap: make(map[uint32]int64),
|
||||
multiplayerTeam: CreateMultiplayerTeam(),
|
||||
@@ -101,18 +205,17 @@ func (w *WorldManager) IsBigWorld(world *World) bool {
|
||||
// 世界数据结构
|
||||
|
||||
type World struct {
|
||||
id uint32
|
||||
owner *model.Player
|
||||
playerMap map[uint32]*model.Player
|
||||
sceneMap map[uint32]*Scene
|
||||
entityIdCounter uint32 // 世界的实体id生成计数器
|
||||
worldLevel uint8 // 世界等级
|
||||
multiplayer bool // 是否多人世界
|
||||
mpLevelEntityId uint32
|
||||
chatMsgList []*proto.ChatInfo // 世界聊天消息列表
|
||||
// aoiManager *aoi.AoiManager // 当前世界地图的aoi管理器
|
||||
playerFirstEnterMap map[uint32]int64 // 玩家第一次进入世界的时间 key:uid value:进入时间
|
||||
waitEnterPlayerMap map[uint32]int64 // 进入世界的玩家等待列表 key:uid value:开始时间
|
||||
id uint32
|
||||
owner *model.Player
|
||||
playerMap map[uint32]*model.Player
|
||||
sceneMap map[uint32]*Scene
|
||||
entityIdCounter uint32 // 世界的实体id生成计数器
|
||||
worldLevel uint8 // 世界等级
|
||||
multiplayer bool // 是否多人世界
|
||||
mpLevelEntityId uint32
|
||||
chatMsgList []*proto.ChatInfo // 世界聊天消息列表
|
||||
playerFirstEnterMap map[uint32]int64 // 玩家第一次进入世界的时间 key:uid value:进入时间
|
||||
waitEnterPlayerMap map[uint32]int64 // 进入世界的玩家等待列表 key:uid value:开始时间
|
||||
multiplayerTeam *MultiplayerTeam
|
||||
peerList []*model.Player // 玩家编号列表
|
||||
}
|
||||
@@ -534,13 +637,14 @@ func (w *World) PlayerEnter(player *model.Player) {
|
||||
|
||||
func (w *World) CreateScene(sceneId uint32) *Scene {
|
||||
scene := &Scene{
|
||||
id: sceneId,
|
||||
world: w,
|
||||
playerMap: make(map[uint32]*model.Player),
|
||||
entityMap: make(map[uint32]*Entity),
|
||||
gameTime: 18 * 60,
|
||||
createTime: time.Now().UnixMilli(),
|
||||
meeoIndex: 0,
|
||||
id: sceneId,
|
||||
world: w,
|
||||
playerMap: make(map[uint32]*model.Player),
|
||||
entityMap: make(map[uint32]*Entity),
|
||||
objectIdEntityMap: make(map[int64]*Entity),
|
||||
gameTime: 18 * 60,
|
||||
createTime: time.Now().UnixMilli(),
|
||||
meeoIndex: 0,
|
||||
}
|
||||
w.sceneMap[sceneId] = scene
|
||||
return scene
|
||||
@@ -557,13 +661,14 @@ func (w *World) GetSceneById(sceneId uint32) *Scene {
|
||||
// 场景数据结构
|
||||
|
||||
type Scene struct {
|
||||
id uint32
|
||||
world *World
|
||||
playerMap map[uint32]*model.Player
|
||||
entityMap map[uint32]*Entity
|
||||
gameTime uint32 // 游戏内提瓦特大陆的时间
|
||||
createTime int64
|
||||
meeoIndex uint32 // 客户端风元素染色同步协议的计数器
|
||||
id uint32
|
||||
world *World
|
||||
playerMap map[uint32]*model.Player
|
||||
entityMap map[uint32]*Entity
|
||||
objectIdEntityMap map[int64]*Entity
|
||||
gameTime uint32 // 游戏内提瓦特大陆的时间
|
||||
createTime int64
|
||||
meeoIndex uint32 // 客户端风元素染色同步协议的计数器
|
||||
}
|
||||
|
||||
func (s *Scene) GetAllPlayer() map[uint32]*model.Player {
|
||||
@@ -580,6 +685,7 @@ type AvatarEntity struct {
|
||||
}
|
||||
|
||||
type MonsterEntity struct {
|
||||
monsterId uint32
|
||||
}
|
||||
|
||||
type NpcEntity struct {
|
||||
@@ -643,6 +749,8 @@ type Entity struct {
|
||||
monsterEntity *MonsterEntity
|
||||
npcEntity *NpcEntity
|
||||
gadgetEntity *GadgetEntity
|
||||
configId uint32
|
||||
objectId int64
|
||||
}
|
||||
|
||||
type Attack struct {
|
||||
@@ -761,9 +869,6 @@ func (s *Scene) CreateEntityAvatar(player *model.Player, avatarId uint32) uint32
|
||||
},
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
// if avatarId == s.world.GetPlayerActiveAvatarId(player) {
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
// }
|
||||
MESSAGE_QUEUE.SendToFight(s.world.owner.FightAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeFight,
|
||||
EventId: mq.FightRoutineAddEntity,
|
||||
@@ -797,24 +902,32 @@ func (s *Scene) CreateEntityWeapon() uint32 {
|
||||
return entity.id
|
||||
}
|
||||
|
||||
func (s *Scene) CreateEntityMonster(pos *model.Vector, level uint8, fightProp map[uint32]float32) uint32 {
|
||||
func (s *Scene) CreateEntityMonster(pos, rot *model.Vector, monsterId uint32, level uint8, fightProp map[uint32]float32, configId uint32, objectId int64) uint32 {
|
||||
_, exist := s.objectIdEntityMap[objectId]
|
||||
if exist {
|
||||
return 0
|
||||
}
|
||||
entityId := s.world.GetNextWorldEntityId(constant.EntityIdTypeConst.MONSTER)
|
||||
entity := &Entity{
|
||||
id: entityId,
|
||||
scene: s,
|
||||
lifeState: constant.LifeStateConst.LIFE_ALIVE,
|
||||
pos: pos,
|
||||
rot: new(model.Vector),
|
||||
rot: rot,
|
||||
moveState: uint16(proto.MotionState_MOTION_STATE_NONE),
|
||||
lastMoveSceneTimeMs: 0,
|
||||
lastMoveReliableSeq: 0,
|
||||
fightProp: fightProp,
|
||||
entityType: uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_MONSTER),
|
||||
level: level,
|
||||
monsterEntity: &MonsterEntity{},
|
||||
monsterEntity: &MonsterEntity{
|
||||
monsterId: monsterId,
|
||||
},
|
||||
configId: configId,
|
||||
objectId: objectId,
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
s.objectIdEntityMap[objectId] = entity
|
||||
MESSAGE_QUEUE.SendToFight(s.world.owner.FightAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeFight,
|
||||
EventId: mq.FightRoutineAddEntity,
|
||||
@@ -827,7 +940,11 @@ func (s *Scene) CreateEntityMonster(pos *model.Vector, level uint8, fightProp ma
|
||||
return entity.id
|
||||
}
|
||||
|
||||
func (s *Scene) CreateEntityNpc(pos, rot *model.Vector, npcId, roomId, parentQuestId, blockId uint32) uint32 {
|
||||
func (s *Scene) CreateEntityNpc(pos, rot *model.Vector, npcId, roomId, parentQuestId, blockId, configId uint32, objectId int64) uint32 {
|
||||
_, exist := s.objectIdEntityMap[objectId]
|
||||
if exist {
|
||||
return 0
|
||||
}
|
||||
entityId := s.world.GetNextWorldEntityId(constant.EntityIdTypeConst.NPC)
|
||||
entity := &Entity{
|
||||
id: entityId,
|
||||
@@ -851,20 +968,26 @@ func (s *Scene) CreateEntityNpc(pos, rot *model.Vector, npcId, roomId, parentQue
|
||||
ParentQuestId: parentQuestId,
|
||||
BlockId: blockId,
|
||||
},
|
||||
configId: configId,
|
||||
objectId: objectId,
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
s.objectIdEntityMap[objectId] = entity
|
||||
return entity.id
|
||||
}
|
||||
|
||||
func (s *Scene) CreateEntityGadgetNormal(pos *model.Vector, gadgetId uint32) uint32 {
|
||||
func (s *Scene) CreateEntityGadgetNormal(pos, rot *model.Vector, gadgetId uint32, configId uint32, objectId int64) uint32 {
|
||||
_, exist := s.objectIdEntityMap[objectId]
|
||||
if exist {
|
||||
return 0
|
||||
}
|
||||
entityId := s.world.GetNextWorldEntityId(constant.EntityIdTypeConst.GADGET)
|
||||
entity := &Entity{
|
||||
id: entityId,
|
||||
scene: s,
|
||||
lifeState: constant.LifeStateConst.LIFE_ALIVE,
|
||||
pos: pos,
|
||||
rot: new(model.Vector),
|
||||
rot: rot,
|
||||
moveState: uint16(proto.MotionState_MOTION_STATE_NONE),
|
||||
lastMoveSceneTimeMs: 0,
|
||||
lastMoveReliableSeq: 0,
|
||||
@@ -879,20 +1002,26 @@ func (s *Scene) CreateEntityGadgetNormal(pos *model.Vector, gadgetId uint32) uin
|
||||
gadgetId: gadgetId,
|
||||
gadgetType: GADGET_TYPE_NORMAL,
|
||||
},
|
||||
configId: configId,
|
||||
objectId: objectId,
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
s.objectIdEntityMap[objectId] = entity
|
||||
return entity.id
|
||||
}
|
||||
|
||||
func (s *Scene) CreateEntityGadgetGather(pos *model.Vector, gatherId uint32) uint32 {
|
||||
func (s *Scene) CreateEntityGadgetGather(pos, rot *model.Vector, gadgetId uint32, gatherId uint32, configId uint32, objectId int64) uint32 {
|
||||
_, exist := s.objectIdEntityMap[objectId]
|
||||
if exist {
|
||||
return 0
|
||||
}
|
||||
entityId := s.world.GetNextWorldEntityId(constant.EntityIdTypeConst.GADGET)
|
||||
entity := &Entity{
|
||||
id: entityId,
|
||||
scene: s,
|
||||
lifeState: constant.LifeStateConst.LIFE_ALIVE,
|
||||
pos: pos,
|
||||
rot: new(model.Vector),
|
||||
rot: rot,
|
||||
moveState: uint16(proto.MotionState_MOTION_STATE_NONE),
|
||||
lastMoveSceneTimeMs: 0,
|
||||
lastMoveReliableSeq: 0,
|
||||
@@ -904,14 +1033,17 @@ func (s *Scene) CreateEntityGadgetGather(pos *model.Vector, gatherId uint32) uin
|
||||
entityType: uint32(proto.ProtEntityType_PROT_ENTITY_TYPE_GADGET),
|
||||
level: 0,
|
||||
gadgetEntity: &GadgetEntity{
|
||||
gadgetId: gadgetId,
|
||||
gadgetType: GADGET_TYPE_GATHER,
|
||||
gadgetGatherEntity: &GadgetGatherEntity{
|
||||
gatherId: gatherId,
|
||||
},
|
||||
},
|
||||
configId: configId,
|
||||
objectId: objectId,
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
s.objectIdEntityMap[objectId] = entity
|
||||
return entity.id
|
||||
}
|
||||
|
||||
@@ -945,7 +1077,6 @@ func (s *Scene) CreateEntityGadgetClient(pos, rot *model.Vector, entityId uint32
|
||||
},
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
}
|
||||
|
||||
func (s *Scene) CreateEntityGadgetVehicle(uid uint32, pos, rot *model.Vector, vehicleId uint32) uint32 {
|
||||
@@ -984,7 +1115,6 @@ func (s *Scene) CreateEntityGadgetVehicle(uid uint32, pos, rot *model.Vector, ve
|
||||
},
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
return entity.id
|
||||
}
|
||||
|
||||
@@ -993,8 +1123,8 @@ func (s *Scene) DestroyEntity(entityId uint32) {
|
||||
if entity == nil {
|
||||
return
|
||||
}
|
||||
// s.world.aoiManager.RemoveEntityIdFromGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
delete(s.entityMap, entityId)
|
||||
delete(s.entityMap, entity.id)
|
||||
delete(s.objectIdEntityMap, entity.objectId)
|
||||
MESSAGE_QUEUE.SendToFight(s.world.owner.FightAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeFight,
|
||||
EventId: mq.FightRoutineDelEntity,
|
||||
@@ -1009,6 +1139,10 @@ func (s *Scene) GetEntity(entityId uint32) *Entity {
|
||||
return s.entityMap[entityId]
|
||||
}
|
||||
|
||||
func (s *Scene) GetEntityByObjectId(objectId int64) *Entity {
|
||||
return s.objectIdEntityMap[objectId]
|
||||
}
|
||||
|
||||
func (s *Scene) GetEntityIdList() []uint32 {
|
||||
entityIdList := make([]uint32, 0)
|
||||
for k := range s.entityMap {
|
||||
|
||||
Reference in New Issue
Block a user