From e3a2e0550e64e2f8abd60f85b7a1a3b1c17bdda0 Mon Sep 17 00:00:00 2001 From: flswld Date: Sun, 15 Jan 2023 05:30:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=96=E7=95=8C=E6=80=AA=E7=89=A9=E3=80=81NP?= =?UTF-8?q?C=E3=80=81=E8=A3=85=E7=BD=AE=E7=AD=89=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E8=AF=BB=E5=8F=96lua=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E7=94=9F=E6=88=90=EF=BC=8C=E5=AE=9E=E7=8E=B0AOI=E4=B9=9D?= =?UTF-8?q?=E5=AE=AB=E6=A0=BC=E5=8A=A8=E6=80=81=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gate/net/kcp_connect_manager.go | 6 +- gdconf/game_data_config.go | 103 ++- gdconf/game_data_config/csv/SceneData.csv | 913 +++++++++++++++++++ gdconf/game_data_config/csv/SceneTagData.csv | 251 +++++ gdconf/game_data_config_test.go | 71 ++ gdconf/scene_data.go | 30 + gdconf/scene_data_config.go | 256 ++++++ go.mod | 3 + go.sum | 2 + gs/game/game_manager.go | 12 +- gs/game/route_manager.go | 1 + gs/game/tick_manager.go | 42 - gs/game/user_common_handler.go | 6 + gs/game/user_fight_sync.go | 65 +- gs/game/user_scene.go | 116 ++- gs/game/video_player.go | 8 +- gs/game/world_manager.go | 262 ++++-- pkg/alg/aoi.go | 153 ++-- pkg/alg/aoi_grid.go | 42 +- pkg/alg/aoi_test.go | 10 +- 20 files changed, 2133 insertions(+), 219 deletions(-) create mode 100644 gdconf/game_data_config/csv/SceneData.csv create mode 100644 gdconf/game_data_config/csv/SceneTagData.csv create mode 100644 gdconf/scene_data.go create mode 100644 gdconf/scene_data_config.go diff --git a/gate/net/kcp_connect_manager.go b/gate/net/kcp_connect_manager.go index 69e5218e..692bee7e 100644 --- a/gate/net/kcp_connect_manager.go +++ b/gate/net/kcp_connect_manager.go @@ -24,6 +24,8 @@ import ( const ( PacketFreqLimit = 1000 PacketMaxLen = 343 * 1024 + ConnRecvTimeout = 30 + ConnSendTimeout = 10 ) type KcpConnectManager struct { @@ -246,7 +248,7 @@ func (k *KcpConnectManager) recvHandle(session *Session) { recvBuf := make([]byte, PacketMaxLen) dataBuf := make([]byte, 0, 1500) for { - _ = conn.SetReadDeadline(time.Now().Add(time.Second * 15)) + _ = conn.SetReadDeadline(time.Now().Add(time.Second * ConnRecvTimeout)) recvLen, err := conn.Read(recvBuf) if err != nil { logger.Error("exit recv loop, conn read err: %v, convId: %v", err, convId) @@ -296,7 +298,7 @@ func (k *KcpConnectManager) sendHandle(session *Session) { continue } bin := k.encodePayloadToBin(kcpMsg, session.xorKey) - _ = conn.SetWriteDeadline(time.Now().Add(time.Second * 5)) + _ = conn.SetWriteDeadline(time.Now().Add(time.Second * ConnSendTimeout)) _, err := conn.Write(bin) if err != nil { logger.Error("exit send loop, conn write err: %v, convId: %v", err, convId) diff --git a/gdconf/game_data_config.go b/gdconf/game_data_config.go index aba78a0d..78ee0f21 100644 --- a/gdconf/game_data_config.go +++ b/gdconf/game_data_config.go @@ -1,11 +1,15 @@ package gdconf import ( + "encoding/json" "fmt" "os" "strings" "hk4e/common/config" + "hk4e/pkg/logger" + + lua "github.com/yuin/gopher-lua" ) // 游戏数据配置表 @@ -16,6 +20,7 @@ type GameDataConfig struct { // 配置表路径前缀 csvPrefix string jsonPrefix string + luaPrefix string // 配置表数据 AvatarDataMap map[int32]*AvatarData // 角色 AvatarSkillDataMap map[int32]*AvatarSkillData // 角色技能 @@ -23,12 +28,14 @@ type GameDataConfig struct { DropGroupDataMap map[int32]*DropGroupData // 掉落组 GCGCharDataMap map[int32]*GCGCharData // 角色卡牌 GCGSkillDataMap map[int32]*GCGSkillData // 卡牌技能 + SceneDataMap map[int32]*SceneData // 场景 + SceneMap map[int32]*Scene // 场景详情 } func InitGameDataConfig() { CONF = new(GameDataConfig) - CONF.csvPrefix = "" CONF.loadAll() + logger.Info("load all game data config finish") } func (g *GameDataConfig) loadAll() { @@ -56,6 +63,14 @@ func (g *GameDataConfig) loadAll() { } g.jsonPrefix += "/" + g.luaPrefix = pathPrefix + "/lua" + dirInfo, err = os.Stat(g.luaPrefix) + if err != nil || !dirInfo.IsDir() { + info := fmt.Sprintf("open game data config lua dir error: %v", err) + panic(info) + } + g.luaPrefix += "/" + g.load() } @@ -66,6 +81,8 @@ func (g *GameDataConfig) load() { g.loadDropGroupData() // 掉落组 g.loadGCGCharData() // 角色卡牌 g.loadGCGSkillData() // 卡牌技能 + g.loadSceneData() // 场景 + g.loadScene() // 场景详情 } func (g *GameDataConfig) readCsvFileData(fileName string) []byte { @@ -83,3 +100,87 @@ func (g *GameDataConfig) readCsvFileData(fileName string) []byte { standardCsvData = append(standardCsvData, fileData[index3+(index2+1)+(index1+1):]...) return standardCsvData } + +func fixLuaState(luaStr string) *lua.LState { + fixLua := "" + fixLua += "GadgetState = {}" + fixLua += "EventType = {}" + fixLua += "RegionShape = {}" + fixLua += "VisionLevelType = {}" + luaLineList := strings.Split(luaStr, "\n") + luaStr = "" + for _, luaLine := range luaLineList { + line := strings.TrimSpace(luaLine) + if len(line) != 0 && line[0] == '[' && strings.Contains(line, "]") && strings.Contains(line, "=") { + luaStr += luaLine[strings.Index(luaLine, "=")+1:] + "\n" + } else { + luaStr += luaLine + "\n" + } + } + luaStr = fixLua + luaStr + luaState := lua.NewState() + err := luaState.DoString(luaStr) + if err != nil { + if !strings.Contains(err.Error(), "module") { + logger.Error("lua parse error: %v", err) + } + } + return luaState +} + +func parseLuaTableToObject[T any](luaState *lua.LState, tableName string, object T) bool { + luaValue := luaState.GetGlobal(tableName) + table, ok := luaValue.(*lua.LTable) + if !ok { + logger.Info("get lua table error, table name: %v, lua type: %v", tableName, luaValue.Type().String()) + return false + } + tableObject := convLuaValueToGo(table) + jsonData, err := json.Marshal(tableObject) + if err != nil { + logger.Error("build json error: %v", err) + return false + } + if string(jsonData) == "{}" { + return true + } + err = json.Unmarshal(jsonData, object) + if err != nil { + logger.Error("parse json error: %v", err) + return false + } + return true +} + +func convLuaValueToGo(lv lua.LValue) any { + switch v := lv.(type) { + case *lua.LNilType: + return nil + case lua.LBool: + return bool(v) + case lua.LString: + return string(v) + case lua.LNumber: + return float64(v) + case *lua.LTable: + maxn := v.MaxN() + if maxn == 0 { + // table + ret := make(map[string]any) + v.ForEach(func(key, value lua.LValue) { + keystr := fmt.Sprint(convLuaValueToGo(key)) + ret[keystr] = convLuaValueToGo(value) + }) + return ret + } else { + // array + ret := make([]any, 0, maxn) + for i := 1; i <= maxn; i++ { + ret = append(ret, convLuaValueToGo(v.RawGetInt(i))) + } + return ret + } + default: + return v + } +} diff --git a/gdconf/game_data_config/csv/SceneData.csv b/gdconf/game_data_config/csv/SceneData.csv new file mode 100644 index 00000000..e2080a5f --- /dev/null +++ b/gdconf/game_data_config/csv/SceneData.csv @@ -0,0 +1,913 @@ +SceneId,SceneType,,,,,,,,,,,,,,,,,, +int32,int32,,,,,,,,,,,,,,,,,, +ID,,,Ƿnavmesh,ռѰ·,NavmeshMode,LevelEntityConfig,entity,ָɫб,ָɫ,Ƿؿ,ScenePoint,ģʽ,Ƿ֧Զͼ,ǷɾԶͼ,سdzڵ,õس,Ƿblockbin,ǷSceneBin,ID +1001,2,,,,,,,,,0,,,,,,,,, +1002,1,,,,,,,,,0,,,,,,,,, +1003,1,,,,,,,,,0,,,,,,,,, +1004,3,,1,,,,,,,0,,,,,,,,, +1005,3,,,,,Level_Sneak,,10000005#10000007,1,0,,,,,,,,, +1006,2,,,,,,,,,1,,,,,,,,, +1008,3,,,,,,,,,0,,,,,,,,, +1009,3,,,,,,,,,0,,,,,,,,, +1011,2,,,,,,,,,0,,,,,,,,, +1013,3,,,,,Level_Sneak,,10000005#10000007,1,0,,,,,,,,, +1015,2,,,,,Level_Sneak,,10000005#10000007,1,1,,,,,,,,, +1016,2,,,,,,,,,1,,,,,,,,, +1017,2,,,,,,,,,1,,,,,,,,, +1018,3,,,,,,,,,0,,,,,,,,, +1019,2,,,,,Level_Dungeon,,,,0,,,,,,,,, +1023,3,,,,,,,,,0,,,,,,,,, +1024,2,,,,,,,,,1,,,,,,,,, +1030,1,,,,,Level_Sneak,,,1,0,,,,,,,,, +1031,2,,,,,,,,,1,,,,,,,,, +1032,2,,,,,LevelEntity_Quest_XiaoDungeon,,,,1,,,,,,,,, +1033,3,,,,,,,,,0,,,,,,,,, +1034,3,,,,,,,,,0,,,,,,,,, +1035,3,,,,,,,,,0,,,,,,,,, +1050,2,,,,,,,,,0,,,,,,,,, +1051,2,,,,,,,,,1,,,,,,,,, +1052,2,,,,,,,,,1,,,,,,,,, +1053,2,,,,,,,,,1,,,,,,,,, +1054,2,,,,,,,,,1,,,,,,,,, +1055,2,,,,,,,,,1,,,,,,,,, +1056,2,,,,,,,,,1,,,,,,,,, +1057,3,,1,,,,,,,0,,,,,,,,, +1058,2,,,,,,,,,1,,,,,,,,, +1059,2,,,,,,,,,1,,,,,,,,, +1060,3,,1,,,,,,,0,,,,,,,,, +1061,3,,1,,,,,,,0,,,,,,,,, +1062,2,,,,,,,,,1,,,,,,,,, +1063,3,,1,,,,,,,0,,,,,,,,, +1064,3,,1,,,,,,,1,,,,,,,,, +1065,2,,,,,,,,,1,,,,,,,,, +1066,3,,1,,,,,,,,,,,,,,,, +1068,3,,,,,Level_Bartender_Room,,10000005#10000007,1,1,,1,,,,,,, +1069,3,,,,,,,,,0,,,,,,,,, +1070,2,,,,,,,,,1,,,,,,,,, +1071,2,,,,,,,,,,,,,,,,,, +1072,3,,1,,,,,,,0,,,,,,,,, +1073,3,,1,,,,,,,0,,,,,,,,, +1074,3,,1,,,,,,,0,,,,,,,,, +1075,3,,1,,,,,,,0,,,,,,,,, +1077,3,,1,,,,,,,,,,,,,,,, +1078,3,,1,,,,,,,,,,,,,,,, +2001,4,,,,,,,,,1,,,,,,,,, +2002,4,,,,,,,,,1,,,,,,,,, +2003,4,,,,,,,,,1,,,,,,,,, +2004,4,,,,,,,,,1,,,,,,,,, +2005,4,,,,,,,,,1,,,,,,,,, +2201,5,,,,,,,,,1,,,,,,,,, +2202,5,,,,,,,,,1,,,,,,,,, +2203,5,,,,,,,,,1,,,,,,,,, +2204,5,,,,,,,,,1,,,,,,,,, +1,1,,,,,Level_BigWorld,,,,0,,,,,,,,, +2,1,,,,,Level_BigWorld,,,,0,,,,,,,,, +3,1,,,1,,Level_BigWorld,,,,1,15,,1,,,,,, +4,1,,,,,Level_BigWorld,,,,1,1,,1,1,,,1,, +5,1,,,,,Level_BigWorld,,,,1,1,,1,,,,,, +6,1,,,,,Level_BigWorld,,,,1,1,,1,,,,,, +7,1,,,,,Level_BigWorld,,,,1,2,,1,1,,,1,, +9,1,,,,1,Level_BigWorld,,,,1,33,,1,1,,,1,, +20000,2,,,,,,,,,0,,,,,,,,, +20005,2,,,,,,,,,1,,,,,,,,, +20006,2,,,,,,,,,0,,,,,,,,, +20007,2,,,,,,,,,0,,,,,,,,, +20008,2,,,,,,,,,1,,,,,,,,, +20009,2,,,,,,,,,1,,,,,,,,, +20010,2,,,,,,,,,1,,,,,,,,, +20011,2,,,,,,,,,1,,,,,,,,, +20012,2,,,,,,,,,0,,,,,,,,, +20013,2,,,,,,,,,0,,,,,,,,, +20014,2,,,,,,,,,0,,,,,,,,, +20015,2,,,,,,,,,0,,,,,,,,, +20016,2,,,,,,,,,1,,,,,,,,, +20017,2,,,,,Level_Dvalin_S01,1,10000005#10000007,1,1,,,,,,,,, +20018,2,,,,,Level_Dvalin_S04,1,,,1,,,,,,,,, +20019,2,,,,,,,,,1,,,,,,,,, +20020,2,,,,,Level_Dvalin_S00,1,10000005#10000007,1,1,,,,,,,,, +20022,2,,,,,,,,,1,,,,,,,,, +20023,2,,,,,,,,,1,,,,,,,,, +20024,2,,,,,,,,,1,,,,,,,,, +20025,2,,,,,Level_Dvalin_S04_Recycle,1,,,1,,,,,,,,, +20026,2,,,,,,,,,1,,,,,,,,, +20027,2,,,,,,,,,1,,,,,,,,, +20028,2,,,,,,,,,1,,,,,,,,, +20031,2,,,,,,,,,1,,,,,,,,, +20032,2,,,,,,,,,1,,,,,,,,, +20034,2,,,,,Level_Tartaglia,,,,1,,,,,,,,, +20035,2,,,,,,,,,1,,,,,,,,, +20036,2,,,,,,,,,1,,,,,,,,, +20037,2,,,,,,,,,1,,,,,,,,, +20101,2,,,,,Level_Tartaglia,,,,1,,,,,,,,, +20102,2,,,,,,,,,1,,,,,,,,, +20103,2,,,,,,,,,1,,,,,,,,, +20104,2,,,,,,,,,1,,,,,,,,, +20105,2,,,,,,,,,1,,,,,,,,, +20106,2,,,,,Level_Dahaka_CameraSetting,,,,1,,,,,,,,, +20107,2,,,,,Level_Dahaka_CameraSetting,,,,1,,,,,,,,, +20108,2,,,,,Level_Dahaka_CameraSetting,,,,1,,,,,,,,, +20109,2,,,,,Level_Dahaka_CameraSetting,,,,1,,,,,,,,, +20110,2,,,,,Level_Dahaka_CameraSetting,,,,1,,,,,,,,, +20111,2,,,,,,,,,1,,,,,,,,, +20112,2,,,,,Level_Monster_Shougun_Setting,,,,1,,,,,,,,, +20113,2,,,,,,,,,1,,,,,,,,, +20114,2,,,,,,,,,1,,,,,,,,, +20115,2,,,,,,,,,1,,,,,,,,, +20116,2,,,,,,,,,1,,,,,,,,, +20117,2,,,,,Level_Monster_Shougun_Tachi_Revive,,,,1,,,,,,,,, +20118,2,,,,,,,,,1,,,,,,,,, +20119,2,,,,,,,,,1,,,,,,,,, +20120,2,,,,,,,,,1,,,,,,,,, +20121,2,,,,,,,,,1,,,,,,,,, +20122,2,,,,,Level_Monster_Shougun_Mitakenarukami_AvatarRevive,,,,1,,,,,,,,, +20123,2,,,,,,,,,1,,,,,,,,, +20124,2,,,,,,,,,1,,,,,,,,, +20125,2,,,,,,,,,1,,,,,,,,, +20126,2,,,,,,,,,1,,,,,,,,, +20127,2,,,,,,,,,1,,,,,,,,, +20128,2,,,,,LevelEntity_Activity_V2_7_CYRogue_20128,,,,1,,,,,,,,, +20129,2,,,,,,,,,1,,,,,,,,, +20130,3,,,,,,,,,,,,,,,,,, +20131,2,,,,,,,,,1,,,,,,,,, +20132,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +20133,2,1,,,,,,,,1,,,,,9#27,,1,1, +20134,2,1,,,,Level_DreamDungeon_Mona,,,,1,,,,,9#29,,1,1, +20135,2,1,,,,,,,,1,,,,,9#11,,1,1, +20136,2,1,,,,Level_DreamDungeon_Mona,,,,1,,,,,,,1,1, +20137,2,1,,,,,,,,,,,,,9#15,,1,1, +20138,2,1,,,,,,,,,,,,,9#17,,1,1, +20139,2,1,,,,,,,,,,,,,9#19,,1,1, +20140,2,1,,,,,,,,1,,,,,9#13,,1,1, +20141,2,1,,,,,,,,1,,,,,,,1,1, +20142,2,1,,,,,,,,1,,,,,9#9,,1,1, +20143,2,1,,,,,,,,,,,,,,,1,1, +20144,2,1,,,,,,,,,,,,,,,1,1, +20145,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +20146,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +20147,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +20148,2,,,,,,,,,1,,,,,,,,, +20149,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +20150,2,,,,,,,,,1,,,,,,,,, +20151,2,,,,,,,,,1,,,,,,,,, +20152,2,,,,,Level_Monster_Nada_Setting,,,,0,,,,,,,,, +20153,2,,,,,Level_Monster_Nada_Setting,,,,1,,,,,,,,, +20154,2,,,,,Level_Monster_Nada_Setting,,,,1,,,,,,,,, +20155,2,,,,,Level_Monster_Nada_Setting,,,,1,,,,,,,,, +20156,2,,,,,Level_Monster_Nada_Setting,,,,1,,,,,,,,, +20157,2,,,,,,,,,1,,,,,,,,, +20158,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +20159,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +20160,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +20161,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +20162,2,,,,,,,,,1,,,,,,,,, +20163,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +20164,2,,,,,,,,,1,,,,,,,,, +20165,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +20168,2,,,,,Level_Monster_Nada_Setting,,,,1,,,,,,,,, +30001,2,,,,,,,,,0,,,,,,,,, +30100,2,,,,,,,,,1,,,,,,,,, +30101,2,,,,,,,,,1,,,,,,,,, +30102,2,,,,,,,,,1,,,,,,,,, +30103,2,,,,,,,,,1,,,,,,,,, +30104,2,,,,,,,,,1,,,,,,,,, +30200,2,,,,,,,,,1,,,,,,,,, +30201,2,,,,,,,,,1,,,,,,,,, +30202,2,,,,,,,,,1,,,,,,,,, +30203,2,,,,,,,,,1,,,,,,,,, +30204,2,,,,,,,,,1,,,,,,,,, +30300,2,,,,,,,,,1,,,,,,,,, +30301,2,,,,,,,,,1,,,,,,,,, +30302,2,,,,,,,,,1,,,,,,,,, +30303,2,,,,,,,,,1,,,,,,,,, +30304,2,,,,,,,,,1,,,,,,,,, +30400,2,,,,,,,,,1,,,,,,,,, +30401,2,,,,,,,,,1,,,,,,,,, +30402,2,,,,,,,,,1,,,,,,,,, +30403,2,,,,,,,,,1,,,,,,,,, +30404,2,,,,,,,,,1,,,,,,,,, +30500,2,,,,,,,,,1,,,,,,,,, +30501,2,,,,,,,,,1,,,,,,,,, +30502,2,,,,,,,,,1,,,,,,,,, +30503,2,,,,,,,,,1,,,,,,,,, +30504,2,,,,,,,,,1,,,,,,,,, +30600,2,,,,,,,,,1,,,,,,,,, +30601,2,,,,,,,,,1,,,,,,,,, +30602,2,,,,,,,,,1,,,,,,,,, +30603,2,,,,,,,,,1,,,,,,,,, +30604,2,,,,,,,,,1,,,,,,,,, +30700,2,,,,,,,,,1,,,,,,,,, +30701,2,,,,,,,,,1,,,,,,,,, +30702,2,,,,,,,,,1,,,,,,,,, +30703,2,,,,,,,,,1,,,,,,,,, +30704,2,,,,,,,,,1,,,,,,,,, +30800,2,,,,,,,,,1,,,,,,,,, +30801,2,,,,,,,,,1,,,,,,,,, +30802,2,,,,,,,,,1,,,,,,,,, +30803,2,,,,,,,,,1,,,,,,,,, +30804,2,,,,,,,,,1,,,,,,,,, +30900,2,,,,,,,,,1,,,,,,,,, +30901,2,,,,,,,,,1,,,,,,,,, +30902,2,,,,,,,,,1,,,,,,,,, +30903,2,,,,,,,,,1,,,,,,,,, +30904,2,,,,,,,,,1,,,,,,,,, +31000,2,,,,,,,,,1,,,,,,,,, +31001,2,,,,,,,,,1,,,,,,,,, +31002,2,,,,,,,,,1,,,,,,,,, +31003,2,,,,,,,,,1,,,,,,,,, +31004,2,,,,,,,,,1,,,,,,,,, +31100,2,,,,,,,,,1,,,,,,,,, +31101,2,,,,,,,,,1,,,,,,,,, +31102,2,,,,,,,,,1,,,,,,,,, +31103,2,,,,,,,,,1,,,,,,,,, +31104,2,,,,,,,,,1,,,,,,,,, +31200,2,,,,,,,,,1,,,,,,,,, +31201,2,,,,,,,,,1,,,,,,,,, +31202,2,,,,,,,,,1,,,,,,,,, +31203,2,,,,,,,,,1,,,,,,,,, +31204,2,,,,,,,,,1,,,,,,,,, +31300,2,,,,,,,,,1,,,,,,,,, +31301,2,,,,,,,,,1,,,,,,,,, +31302,2,,,,,,,,,1,,,,,,,,, +31303,2,,,,,,,,,1,,,,,,,,, +31304,2,,,,,,,,,1,,,,,,,,, +31400,2,,,,,,,,,1,,,,,,,,, +31401,2,,,,,,,,,1,,,,,,,,, +31402,2,,,,,,,,,1,,,,,,,,, +31403,2,,,,,,,,,1,,,,,,,,, +31404,2,,,,,,,,,1,,,,,,,,, +31500,2,,,,,,,,,1,,,,,,,,, +31501,2,,,,,,,,,1,,,,,,,,, +31502,2,,,,,,,,,1,,,,,,,,, +31503,2,,,,,,,,,1,,,,,,,,, +31504,2,,,,,,,,,1,,,,,,,,, +31600,2,,,,,,,,,1,,,,,,,,, +31601,2,,,,,,,,,1,,,,,,,,, +31602,2,,,,,,,,,1,,,,,,,,, +31603,2,,,,,,,,,1,,,,,,,,, +31604,2,,,,,,,,,1,,,,,,,,, +31700,2,,,,,,,,,1,,,,,,,,, +31701,2,,,,,,,,,1,,,,,,,,, +31702,2,,,,,,,,,1,,,,,,,,, +31703,2,,,,,,,,,1,,,,,,,,, +31704,2,,,,,,,,,1,,,,,,,,, +31800,2,,,,,,,,,1,,,,,,,,, +31801,2,,,,,,,,,1,,,,,,,,, +31802,2,,,,,,,,,1,,,,,,,,, +31803,2,,,,,,,,,1,,,,,,,,, +31804,2,,,,,,,,,1,,,,,,,,, +31900,2,,,,,,,,,1,,,,,,,,, +31901,2,,,,,,,,,1,,,,,,,,, +31902,2,,,,,,,,,1,,,,,,,,, +31903,2,,,,,,,,,1,,,,,,,,, +31904,2,,,,,,,,,1,,,,,,,,, +32000,2,,,,,,,,,1,,,,,,,,, +32001,2,,,,,,,,,1,,,,,,,,, +32002,2,,,,,,,,,1,,,,,,,,, +32003,2,,,,,,,,,1,,,,,,,,, +32004,2,,,,,,,,,1,,,,,,,,, +32100,2,,,,,,,,,1,,,,,,,,, +32101,2,,,,,,,,,1,,,,,,,,, +32102,2,,,,,,,,,1,,,,,,,,, +32103,2,,,,,,,,,1,,,,,,,,, +32104,2,,,,,,,,,1,,,,,,,,, +32200,2,,,,,,,,,1,,,,,,,,, +32201,2,,,,,,,,,1,,,,,,,,, +32202,2,,,,,,,,,1,,,,,,,,, +32203,2,,,,,,,,,1,,,,,,,,, +32204,2,,,,,,,,,1,,,,,,,,, +33100,2,,,,,,,,,1,,,,,,,,, +33101,2,,,,,,,,,1,,,,,,,,, +33102,2,,,,,,,,,1,,,,,,,,, +33103,2,,,,,,,,,1,,,,,,,,, +34100,2,,,,,,,,,1,,,,,,,,, +34101,2,,,,,,,,,1,,,,,,,,, +34102,2,,,,,,,,,1,,,,,,,,, +34103,2,,,,,,,,,1,,,,,,,,, +35100,2,,,,,,,,,1,,,,,,,,, +35101,2,,,,,,,,,1,,,,,,,,, +35102,2,,,,,,,,,1,,,,,,,,, +35103,2,,,,,,,,,1,,,,,,,,, +33401,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +33402,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +33403,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +33404,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +34401,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +34402,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +34403,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +34404,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +35401,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +35402,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +35403,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +35404,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +33700,2,,,,,,,,,1,,,,,,,,, +33701,2,,,,,,,,,1,,,,,,,,, +33702,2,,,,,,,,,1,,,,,,,,, +33703,2,,,,,,,,,1,,,,,,,,, +33704,2,,,,,,,,,1,,,,,,,,, +33705,2,,,,,,,,,1,,,,,,,,, +33706,2,,,,,,,,,1,,,,,,,,, +33707,2,,,,,,,,,1,,,,,,,,, +33708,2,,,,,,,,,1,,,,,,,,, +33709,2,,,,,,,,,1,,,,,,,,, +33710,2,,,,,,,,,1,,,,,,,,, +33711,2,,,,,,,,,1,,,,,,,,, +33712,2,,,,,,,,,1,,,,,,,,, +33713,2,,,,,,,,,1,,,,,,,,, +33714,2,,,,,,,,,1,,,,,,,,, +33715,2,,,,,,,,,1,,,,,,,,, +33716,2,,,,,,,,,1,,,,,,,,, +33717,2,,,,,,,,,1,,,,,,,,, +33718,2,,,,,,,,,1,,,,,,,,, +33719,2,,,,,,,,,1,,,,,,,,, +33720,2,,,,,,,,,1,,,,,,,,, +33721,2,,,,,,,,,1,,,,,,,,, +33722,2,,,,,,,,,1,,,,,,,,, +33723,2,,,,,,,,,1,,,,,,,,, +33724,2,,,,,,,,,1,,,,,,,,, +33725,2,,,,,,,,,1,,,,,,,,, +33726,2,,,,,,,,,1,,,,,,,,, +33727,2,,,,,,,,,1,,,,,,,,, +33728,2,,,,,,,,,1,,,,,,,,, +33729,2,,,,,,,,,1,,,,,,,,, +33730,2,,,,,,,,,1,,,,,,,,, +33731,2,,,,,,,,,1,,,,,,,,, +33732,2,,,,,,,,,1,,,,,,,,, +33733,2,,,,,,,,,1,,,,,,,,, +33734,2,,,,,,,,,1,,,,,,,,, +33735,2,,,,,,,,,1,,,,,,,,, +33736,2,,,,,,,,,1,,,,,,,,, +33737,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +33738,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +33739,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +33740,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +33741,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +33742,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +33743,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +33744,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +34700,2,,,,,,,,,1,,,,,,,,, +34701,2,,,,,,,,,1,,,,,,,,, +34702,2,,,,,,,,,1,,,,,,,,, +34703,2,,,,,,,,,1,,,,,,,,, +34704,2,,,,,,,,,1,,,,,,,,, +34705,2,,,,,,,,,1,,,,,,,,, +34706,2,,,,,,,,,1,,,,,,,,, +34707,2,,,,,,,,,1,,,,,,,,, +34708,2,,,,,,,,,1,,,,,,,,, +34709,2,,,,,,,,,1,,,,,,,,, +34710,2,,,,,,,,,1,,,,,,,,, +34711,2,,,,,,,,,1,,,,,,,,, +34712,2,,,,,,,,,1,,,,,,,,, +34713,2,,,,,,,,,1,,,,,,,,, +34714,2,,,,,,,,,1,,,,,,,,, +34715,2,,,,,,,,,1,,,,,,,,, +34716,2,,,,,,,,,1,,,,,,,,, +34717,2,,,,,,,,,1,,,,,,,,, +34718,2,,,,,,,,,1,,,,,,,,, +34719,2,,,,,,,,,1,,,,,,,,, +34720,2,,,,,,,,,1,,,,,,,,, +34721,2,,,,,,,,,1,,,,,,,,, +34722,2,,,,,,,,,1,,,,,,,,, +34723,2,,,,,,,,,1,,,,,,,,, +34724,2,,,,,,,,,1,,,,,,,,, +34725,2,,,,,,,,,1,,,,,,,,, +34726,2,,,,,,,,,1,,,,,,,,, +34727,2,,,,,,,,,1,,,,,,,,, +34728,2,,,,,,,,,1,,,,,,,,, +34729,2,,,,,,,,,1,,,,,,,,, +34730,2,,,,,,,,,1,,,,,,,,, +34731,2,,,,,,,,,1,,,,,,,,, +34732,2,,,,,,,,,1,,,,,,,,, +34733,2,,,,,,,,,1,,,,,,,,, +34734,2,,,,,,,,,1,,,,,,,,, +34735,2,,,,,,,,,1,,,,,,,,, +34736,2,,,,,,,,,1,,,,,,,,, +34737,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +34738,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +34739,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +34740,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +34741,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +34742,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +34743,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +34744,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +35700,2,,,,,,,,,1,,,,,,,,, +35701,2,,,,,,,,,1,,,,,,,,, +35702,2,,,,,,,,,1,,,,,,,,, +35703,2,,,,,,,,,1,,,,,,,,, +35704,2,,,,,,,,,1,,,,,,,,, +35705,2,,,,,,,,,1,,,,,,,,, +35706,2,,,,,,,,,1,,,,,,,,, +35707,2,,,,,,,,,1,,,,,,,,, +35708,2,,,,,,,,,1,,,,,,,,, +35709,2,,,,,,,,,1,,,,,,,,, +35710,2,,,,,,,,,1,,,,,,,,, +35711,2,,,,,,,,,1,,,,,,,,, +35712,2,,,,,,,,,1,,,,,,,,, +35713,2,,,,,,,,,1,,,,,,,,, +35714,2,,,,,,,,,1,,,,,,,,, +35715,2,,,,,,,,,1,,,,,,,,, +35716,2,,,,,,,,,1,,,,,,,,, +35717,2,,,,,,,,,1,,,,,,,,, +35718,2,,,,,,,,,1,,,,,,,,, +35719,2,,,,,,,,,1,,,,,,,,, +35720,2,,,,,,,,,1,,,,,,,,, +35721,2,,,,,,,,,1,,,,,,,,, +35722,2,,,,,,,,,1,,,,,,,,, +35723,2,,,,,,,,,1,,,,,,,,, +35724,2,,,,,,,,,1,,,,,,,,, +35725,2,,,,,,,,,1,,,,,,,,, +35726,2,,,,,,,,,1,,,,,,,,, +35727,2,,,,,,,,,1,,,,,,,,, +35728,2,,,,,,,,,1,,,,,,,,, +35729,2,,,,,,,,,1,,,,,,,,, +35730,2,,,,,,,,,1,,,,,,,,, +35731,2,,,,,,,,,1,,,,,,,,, +35732,2,,,,,,,,,1,,,,,,,,, +35733,2,,,,,,,,,1,,,,,,,,, +35734,2,,,,,,,,,1,,,,,,,,, +35735,2,,,,,,,,,1,,,,,,,,, +35736,2,,,,,,,,,1,,,,,,,,, +35737,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +35738,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +35739,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +35740,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +35741,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +35742,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +35743,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +35744,2,,,,,LevelEntity_ClearLocalGadgets,,,,1,,,,,,,,, +35800,2,,,,,Level_WindFlora_Dungeon,,,,1,,,,,,,,, +35801,2,,,,,,,,,1,,,,,,,,, +35802,2,,,,,,,,,1,,,,,,,,, +35803,2,,,,,,,,,1,,,,,,,,, +35804,2,,,,,,,,,1,,,,,,,,, +35805,2,,,,,,,,,1,,,,,,,,, +35806,2,,,,,,,,,1,,,,,,,,, +35807,2,,,,,,,,,1,,,,,,,,, +35808,2,,,,,,,,,1,,,,,,,,, +35809,2,,,,,,,,,1,,,,,,,,, +35810,2,,,,,,,,,1,,,,,,,,, +35811,2,,,,,,,,,1,,,,,,,,, +35812,2,,,,,,,,,1,,,,,,,,, +35813,2,,,,,,,,,1,,,,,,,,, +35814,2,,,,,,,,,1,,,,,,,,, +35815,2,,,,,,,,,1,,,,,,,,, +35816,2,,,,,,,,,1,,,,,,,,, +35817,2,,,,,,,,,1,,,,,,,,, +35818,2,,,,,,,,,1,,,,,,,,, +35820,2,,,,,,,,,,,,,,,,,, +35821,2,,,,,,,,,,,,,,,,,, +35822,2,,,,,,,,,,,,,,,,,, +35823,2,,,,,,,,,,,,,,,,,, +35824,2,,,,,,,,,,,,,,,,,, +35825,2,,,,,,,,,,,,,,,,,, +35826,2,,,,,,,,,,,,,,,,,, +35827,2,,,,,,,,,,,,,,,,,, +35828,2,,,,,,,,,,,,,,,,,, +35829,2,,,,,,,,,,,,,,,,,, +35830,2,,,,,,,,,,,,,,,,,, +35831,2,,,,,,,,,,,,,,,,,, +35840,2,,,,,,,,,,,,,,,,,, +35841,2,,,,,,,,,,,,,,,,,, +35842,2,,,,,,,,,,,,,,,,,, +35843,2,,,,,,,,,,,,,,,,,, +35844,2,,,,,,,,,,,,,,,,,, +35845,2,,,,,,,,,,,,,,,,,, +35846,2,,,,,,,,,1,,,,,,,,, +35847,2,,,,,,,,,1,,,,,,,,, +35848,2,,,,,,,,,1,,,,,,,,, +35849,2,,,,,,,,,1,,,,,,,,, +35850,2,,,,,,,,,1,,,,,,,,, +35851,2,,,,,,,,,1,,,,,,,,, +35852,2,,,,,Level_DreamDungeon_Mona,,,,1,,,,,,,,, +35853,2,,,,,Level_DreamDungeon_Mona,,,,1,,,,,,,,, +35860,2,,,,,,,,,1,,,,,,,,, +35861,2,,,,,,,,,1,,,,,,,,, +35862,2,,,,,,,,,1,,,,,,,,, +35863,2,,,,,,,,,1,,,,,,,,, +40001,2,,,,,,,,,0,,,,,,,,, +40002,2,,,,,,,,,0,,,,,,,,, +40003,2,,,,,,,,,0,,,,,,,,, +40004,2,,,,,,,,,1,,,,,,,,, +40005,2,,,,,,,,,0,,,,,,,,, +40006,2,,,,,,,,,0,,,,,,,,, +40007,2,,,,,,,,,0,,,,,,,,, +40008,2,,,,,,,,,0,,,,,,,,, +40009,2,,,,,,,,,0,,,,,,,,, +40010,2,,,,,,,,,1,,,,,,,,, +40012,2,,,,,,,,,1,,,,,,,,, +40013,2,,,,,,,,,1,,,,,,,,, +40014,2,,,,,,,,,1,,,,,,,,, +40015,2,,,,,,,,,1,,,,,,,,, +40016,2,,,,,,,,,1,,,,,,,,, +40017,2,,,,,,,,,0,,,,,,,,, +40018,2,,,,,,,,,0,,,,,,,,, +40019,2,,,,,,,,,1,,,,,,,,, +40020,2,,,,,,,,,1,,,,,,,,, +40021,2,,,,,,,,,0,,,,,,,,, +40022,2,,,,,,,,,1,,,,,,,,, +40023,2,,,,,,,,,1,,,,,,,,, +40024,2,,,,,,,,,1,,,,,,,,, +40025,2,,,,,,,,,1,,,,,,,,, +40026,2,,,,,,,,,1,,,,,,,,, +40027,2,,,,,,,,,1,,,,,,,,, +40028,2,,,,,,,,,1,,,,,,,,, +40029,2,,,,,,,,,1,,,,,,,,, +40030,2,,,,,,,,,1,,,,,,,,, +40031,2,,,,,,,,,1,,,,,,,,, +40032,2,,,,,,,,,1,,,,,,,,, +40033,2,,,,,,,,,1,,,,,,,,, +40034,2,,,,,,,,,1,,,,,,,,, +40035,2,,,,,,,,,1,,,,,,,,, +40036,2,,,,,,,,,1,,,,,,,,, +40037,2,,,,,,,,,1,,,,,,,,, +40038,2,,,,,,,,,1,,,,,,,,, +40039,2,,,,,,,,,1,,,,,,,,, +40040,2,,,,,,,,,1,,,,,,,,, +40041,2,,,,,,,,,1,,,,,,,,, +40042,2,,,,,,,,,1,,,,,,,,, +40043,2,,,,,,,,,1,,,,,,,,, +40044,2,,,,,,,,,1,,,,,,,,, +40045,2,,,,,,,,,1,,,,,,,,, +40046,2,,,,,,,,,1,,,,,,,,, +40047,2,,,,,,,,,1,,,,,,,,, +40048,2,,,,,,,,,1,,,,,,,,, +40049,2,,,,,,,,,1,,,,,,,,, +40050,2,,,,,,,,,1,,,,,,,,, +40051,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +40052,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +40053,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +40054,2,,,,,Level_Dungeon,,,,1,,,,,,,,, +40055,2,,,,,Level_EffigyChallenge,,,,1,,,,,,,,, +40056,2,,,,,Level_EffigyChallenge,,,,1,,,,,,,,, +40057,2,,,,,Level_EffigyChallenge,,,,1,,,,,,,,, +40058,2,,,,,Level_EffigyChallenge,,,,1,,,,,,,,, +40059,2,,,,,Level_EffigyChallenge,,,,1,,,,,,,,, +40060,2,,,,,Level_EffigyChallenge,,,,1,,,,,,,,, +40061,2,,,,,Level_EffigyChallenge,,,,1,,,,,,,,, +40062,2,,,,,Level_EffigyChallenge,,,,1,,,,,,,,, +40100,2,,,,,,,,,1,,,,,,,,, +40101,2,,,,,,,,,1,,,,,,,,, +40102,2,,,,,,,,,1,,,,,,,,, +40103,2,,,,,,,,,0,,,,,,,,, +40104,2,,,,,,,,,0,,,,,,,,, +40105,2,,,,,,,,,1,,,,,,,,, +40200,2,,,,,,,,,1,,,,,,,,, +40201,2,,,,,,,,,1,,,,,,,,, +40202,2,,,,,,,,,1,,,,,,,,, +40203,2,,,,,,,,,1,,,,,,,,, +40300,2,,,,,,,,,1,,,,,,,,, +40301,2,,,,,,,,,1,,,,,,,,, +40302,2,,,,,,,,,1,,,,,,,,, +40303,2,,,,,,,,,1,,,,,,,,, +40400,2,,,,,,,,,1,,,,,,,,, +40401,2,,,,,,,,,1,,,,,,,,, +40402,2,,,,,,,,,1,,,,,,,,, +40403,2,,,,,,,,,1,,,,,,,,, +40404,2,,,,,,,,,1,,,,,,,,, +40405,2,,,,,,,,,0,,,,,,,,, +40406,2,,,,,,,,,0,,,,,,,,, +40407,2,,,,,,,,,0,,,,,,,,, +40408,2,,,,,,,,,1,,,,,,,,, +40409,2,,,,,,,,,1,,,,,,,,, +40410,2,,,,,,,,,1,,,,,,,,, +40500,2,,,,,,,,,1,,,,,,,,, +40501,2,,,,,,,,,1,,,,,,,,, +40502,2,,,,,,,,,1,,,,,,,,, +40503,2,,,,,,,,,1,,,,,,,,, +40504,2,,,,,,,,,1,,,,,,,,, +40505,2,,,,,,,,,1,,,,,,,,, +40506,2,,,,,,,,,1,,,,,,,,, +40507,2,,,,,,,,,0,,,,,,,,, +40508,2,,,,,,,,,1,,,,,,,,, +40509,2,,,,,,,,,1,,,,,,,,, +40510,2,,,,,,,,,1,,,,,,,,, +40511,2,,,,,,,,,1,,,,,,,,, +40512,2,,,,,,,,,1,,,,,,,,, +40513,2,,,,,,,,,0,,,,,,,,, +40514,2,,,,,,,,,1,,,,,,,,, +40515,2,,,,,,,,,1,,,,,,,,, +40516,2,,,,,,,,,1,,,,,,,,, +40517,2,,,,,,,,,1,,,,,,,,, +40600,2,,,,,,,,,1,,,,,,,,, +40601,2,,,,,,,,,1,,,,,,,,, +40602,2,,,,,,,,,1,,,,,,,,, +40603,2,,,,,,,,,1,,,,,,,,, +40604,2,,,,,,,,,1,,,,,,,,, +40605,2,,,,,,,,,1,,,,,,,,, +40606,2,,,,,,,,,0,,,,,,,,, +40607,2,,,,,,,,,1,,,,,,,,, +40608,2,,,,,,,,,1,,,,,,,,, +40609,2,,,,,,,,,1,,,,,,,,, +40610,2,,,,,,,,,1,,,,,,,,, +40611,2,,,,,,,,,0,,,,,,,,, +40612,2,,,,,,,,,1,,,,,,,,, +40613,2,,,,,,,,,1,,,,,,,,, +40614,2,,,,,,,,,1,,,,,,,,, +40615,2,,,,,,,,,1,,,,,,,,, +40616,2,,,,,,,,,0,,,,,,,,, +40617,2,,,,,,,,,1,,,,,,,,, +40618,2,,,,,,,,,1,,,,,,,,, +40619,2,,,,,,,,,1,,,,,,,,, +40620,2,,,,,,,,,1,,,,,,,,, +40650,2,,,,,,,,,1,,,,,,,,, +40651,2,,,,,,,,,1,,,,,,,,, +40652,2,,,,,,,,,1,,,,,,,,, +40653,2,,,,,,,,,1,,,,,,,,, +40700,2,,,,,TestLevel_Element_Evn_Rock,,,,1,,,,,,,,, +40701,2,,,,,TestLevel_Element_Evn_Rock,,,,1,,,,,,,,, +40702,2,,,,,TestLevel_Element_Evn_Rock,,,,1,,,,,,,,, +40703,2,,,,,TestLevel_Element_Evn_Rock,,,,1,,,,,,,,, +40750,2,,,,,,,,,1,,,,,,,,, +40751,2,,,,,,,,,1,,,,,,,,, +40752,2,,,,,,,,,1,,,,,,,,, +40753,2,,,,,,,,,1,,,,,,,,, +40754,2,,,,,,,,,1,,,,,,,,, +40755,2,,,,,,,,,1,,,,,,,,, +40756,2,,,,,,,,,1,,,,,,,,, +40757,2,,,,,,,,,1,,,,,,,,, +40800,2,,,,,,,,,0,,,,,,,,, +40801,2,,,,,,,,,1,,,,,,,,, +40802,2,,,,,,,,,1,,,,,,,,, +40803,2,,,,,,,,,1,,,,,,,,, +40804,2,,,,,,,,,1,,,,,,,,, +40805,2,,,,,,,,,0,,,,,,,,, +40806,2,,,,,,,,,1,,,,,,,,, +40807,2,,,,,,,,,1,,,,,,,,, +40808,2,,,,,,,,,1,,,,,,,,, +40809,2,,,,,,,,,1,,,,,,,,, +40900,2,,,,,TestLevel_Element_Evn_Rock,,,,1,,,,,,,,, +40901,2,,,,,TestLevel_Element_Evn_Rock,,,,1,,,,,,,,, +40902,2,,,,,TestLevel_Element_Evn_Rock,,,,1,,,,,,,,, +40903,2,,,,,TestLevel_Element_Evn_Rock,,,,1,,,,,,,,, +40950,2,,,,,,,,,1,,,,,,,,, +40951,2,,,,,,,,,1,,,,,,,,, +40952,2,,,,,,,,,1,,,,,,,,, +40953,2,,,,,,,,,1,,,,,,,,, +41000,2,,,,,,,,,1,,,,,,,,, +41001,2,,,,,,,,,1,,,,,,,,, +41002,2,,,,,,,,,1,,,,,,,,, +41003,2,,,,,,,,,1,,,,,,,,, +41004,2,,,,,,,,,1,,,,,,,,, +41005,2,,,,,,,,,1,,,,,,,,, +41006,2,,,,,,,,,1,,,,,,,,, +41007,2,,,,,,,,,1,,,,,,,,, +41008,2,,,,,,,,,1,,,,,,,,, +41009,2,,,,,,,,,1,,,,,,,,, +41010,2,,,,,,,,,1,,,,,,,,, +41011,2,,,,,,,,,1,,,,,,,,, +41012,2,,,,,,,,,1,,,,,,,,, +41013,2,,,,,,,,,1,,,,,,,,, +41014,2,,,,,,,,,1,,,,,,,,, +41015,2,,,,,,,,,1,,,,,,,,, +41016,2,,,,,,,,,1,,,,,,,,, +41017,2,,,,,,,,,1,,,,,,,,, +41018,2,,,,,,,,,1,,,,,,,,, +41019,2,,,,,,,,,1,,,,,,,,, +41020,2,,,,,,,,,1,,,,,,,,, +41021,2,,,,,,,,,1,,,,,,,,, +41022,2,,,,,,,,,1,,,,,,,,, +41023,2,,,,,,,,,1,,,,,,,,, +41024,2,,,,,,,,,1,,,,,,,,, +41025,2,,,,,,,,,1,,,,,,,,, +41026,2,,,,,,,,,1,,,,,,,,, +41027,2,,,,,,,,,1,,,,,,,,, +41028,2,,,,,,,,,1,,,,,,,,, +41029,2,,,,,,,,,1,,,,,,,,, +41030,2,,,,,,,,,1,,,,,,,,, +41031,2,,,,,,,,,1,,,,,,,,, +41032,2,,,,,,,,,1,,,,,,,,, +41033,2,,,,,,,,,1,,,,,,,,, +41034,2,,,,,,,,,1,,,,,,,,, +41035,2,,,,,,,,,1,,,,,,,,, +41036,2,,,,,,,,,1,,,,,,,,, +41037,2,,,,,,,,,1,,,,,,,,, +41038,2,,,,,,,,,1,,,,,,,,, +41039,2,,,,,,,,,1,,,,,,,,, +41040,2,,,,,,,,,1,,,,,,,,, +41041,2,,,,,,,,,1,,,,,,,,, +41042,2,,,,,,,,,1,,,,,,,,, +41043,2,,,,,,,,,1,,,,,,,,, +41044,2,,,,,,,,,1,,,,,,,,, +41045,2,,,,,,,,,1,,,,,,,,, +41046,2,,,,,,,,,1,,,,,,,,, +41047,2,,,,,,,,,1,,,,,,,,, +41048,2,,,,,,,,,1,,,,,,,,, +41049,2,,,,,,,,,1,,,,,,,,, +41050,2,,,,,,,,,1,,,,,,,,, +41051,2,,,,,,,,,1,,,,,,,,, +41052,2,,,,,,,,,1,,,,,,,,, +41053,2,,,,,,,,,1,,,,,,,,, +41054,2,,,,,,,,,1,,,,,,,,, +41055,2,,,,,,,,,1,,,,,,,,, +41056,2,,,,,,,,,1,,,,,,,,, +41057,2,,,,,,,,,1,,,,,,,,, +41058,2,,,,,,,,,1,,,,,,,,, +42001,2,,,,,,,,,1,,,,,,,,, +42002,2,,,,,,,,,1,,,,,,,,, +42003,2,,,,,,,,,1,,,,,,,,, +42004,2,,,,,,,,,1,,,,,,,,, +42005,2,,,,,,,,,1,,,,,,,,, +42006,2,,,,,,,,,1,,,,,,,,, +42007,2,,,,,,,,,1,,,,,,,,, +42008,2,,,,,,,,,1,,,,,,,,, +42009,2,,,,,,,,,1,,,,,,,,, +42010,2,,,,,,,,,1,,,,,,,,, +42011,2,,,,,,,,,1,,,,,,,,, +42012,2,,,,,,,,,1,,,,,,,,, +42013,2,,,,,,,,,1,,,,,,,,, +42014,2,,,,,,,,,1,,,,,,,,, +43001,2,,,,,,,,,1,,,,,,,,, +43002,2,,,,,,,,,1,,,,,,,,, +43003,2,,,,,,,,,1,,,,,,,,, +43004,2,,,,,,,,,1,,,,,,,,, +43005,2,,,,,,,,,1,,,,,,,,, +43006,2,,,,,,,,,1,,,,,,,,, +43007,2,,,,,,,,,1,,,,,,,,, +43008,2,,,,,,,,,1,,,,,,,,, +43009,2,,,,,,,,,1,,,,,,,,, +43010,2,,,,,,,,,1,,,,,,,,, +43011,2,,,,,,,,,1,,,,,,,,, +43012,2,,,,,,,,,1,,,,,,,,, +43013,2,,,,,,,,,1,,,,,,,,, +44001,2,,,,,,,,,1,,,,,,,,, +44002,2,,,,,,,,,1,,,,,,,,, +44003,2,,,,,,,,,1,,,,,,,,, +44004,2,,,,,,,,,1,,,,,,,,, +44005,2,,,,,,,,,1,,,,,,,,, +44006,2,,,,,,,,,1,,,,,,,,, +44007,2,,,,,,,,,1,,,,,,,,, +44011,2,,,,,,,,,1,,,,,,,,, +44012,2,,,,,,,,,1,,,,,,,,, +44013,2,,,,,,,,,1,,,,,,,,, +45000,2,,,,,,,,,1,,,,,,,,, +45001,2,,,,,,,,,1,,,,,,,,, +45002,2,,,,,,,,,1,,,,,,,,, +45003,2,,,,,,,,,1,,,,,,,,, +45004,2,,,,,,,,,1,,,,,,,,, +45005,2,,,,,,,,,1,,,,,,,,, +45006,2,,,,,,,,,1,,,,,,,,, +45007,2,,,,,,,,,1,,,,,,,,, +45008,2,,,,,,,,,1,,,,,,,,, +45009,2,,,,,,,,,1,,,,,,,,, +45010,2,,,,,,,,,1,,,,,,,,, +45011,2,,,,,,,,,1,,,,,,,,, +45012,2,,,,,,,,,1,,,,,,,,, +45013,2,,,,,,,,,1,,,,,,,,, +45014,2,,,,,,,,,1,,,,,,,,, +45015,2,,,,,,,,,1,,,,,,,,, +45016,2,,,,,,,,,1,,,,,,,,, +45017,2,,,,,,,,,1,,,,,,,,, +45018,2,,,,,,,,,1,,,,,,,,, +45019,2,,,,,,,,,1,,,,,,,,, +45020,2,,,,,,,,,1,,,,,,,,, +45050,2,,,,,Level_UGC_Dungeon,,,,1,,,,,,,,, +45051,2,,,,,Level_UGC_Dungeon,,,,1,,,,,,,,, +45052,2,,,,,Level_UGC_Dungeon,,,,1,,,,,,,,, +45053,2,,,,,Level_UGC_Dungeon,,,,1,,,,,,,,, +45054,2,,,,,Level_UGC_Dungeon,,,,1,,,,,,,,, +45055,2,,,,,Level_UGC_Dungeon,,,,1,,,,,,,,, +45056,2,,,,,Level_UGC_Dungeon,,,,1,,,,,,,,, +45057,2,,,,,Level_UGC_Dungeon,,,,1,,,,,,,,, +45058,2,,,,,Level_UGC_Dungeon,,,,1,,,,,,,,, +45059,2,,,,,Level_UGC_Dungeon,,,,1,,,,,,,,, +46001,2,,,,,,,,,1,,,,,,,,, +46101,2,,,,,,,,,1,,,,,,,,, +46201,2,,,,,LevelEntity_Activity_V2_7_CYRogue_46201,,,,1,,,,,,,,, +46202,2,,,,,LevelEntity_Activity_V2_7_CYRogue_46202,,,,1,,,,,,,,, +46203,2,,,,,LevelEntity_Activity_V2_7_CYRogue_46203,,,,1,,,,,,,,, +46300,2,,,,,,,,,1,,,,,,,,, +46301,2,,,,,,,,,1,,,,,,,,, +46302,2,,,,,,,,,1,,,,,,,,, +46303,2,,,,,,,,,1,,,,,,,,, +46304,2,,,,,,,,,1,,,,,,,,, +46305,2,,,,,,,,,1,,,,,,,,, +46306,2,,,,,,,,,1,,,,,,,,, +47001,2,,,,,,,,,1,,,,,,,,, +47002,2,,,,,,,,,1,,,,,,,,, +47003,2,,,,,,,,,1,,,,,,,,, +47004,2,,,,,,,,,1,,,,,,,,, +47005,2,,,,,,,,,1,,,,,,,,, +47006,2,,,,,,,,,1,,,,,,,,, +47007,2,,,,,,,,,1,,,,,,,,, +47008,2,,,,,,,,,1,,,,,,,,, +47009,2,,,,,,,,,1,,,,,,,,, +47010,2,,,,,,,,,1,,,,,,,,, +47011,2,,,,,,,,,0,,,,,,,,, +47012,2,,,,,,,,,0,,,,,,,,, +47013,2,,,,,,,,,0,,,,,,,,, +47014,2,,,,,,,,,0,,,,,,,,, +47015,2,,,,,,,,,0,,,,,,,,, +47016,2,,,,,,,,,0,,,,,,,,, +47017,2,,,,,,,,,0,,,,,,,,, +47018,2,,,,,,,,,0,,,,,,,,, +47019,2,,,,,,,,,0,,,,,,,,, +47020,2,,,,,,,,,0,,,,,,,,, +47021,2,,,,,,,,,1,,,,,,,,, +47022,2,,,,,,,,,1,,,,,,,,, +47023,2,,,,,,,,,1,,,,,,,,, +47024,2,,,,,,,,,1,,,,,,,,, +47025,2,,,,,,,,,1,,,,,,,,, +47101,2,,,,,LevelEntity_Activity_V3_2_MushroomBeastBattle,,,,,,,,,,,,, +47102,2,,,,,LevelEntity_Activity_V3_2_MushroomBeastBattle,,,,,,,,,,,,, +47103,2,,,,,LevelEntity_Activity_V3_2_MushroomBeastBattle,,,,,,,,,,,,, +50002,2,,,,,TestLevel_Cold,,,,0,,,,,,,,, +50003,2,,,,,,,,,0,,,,,,,,, +50004,2,,,,,,,,,0,,,,,,,,, +50005,2,,,,,,,,,0,,,,,,,,, +50006,2,,,,,,,,,0,,,,,,,,, +50007,2,,,,,Level_ClimbTest1,,,,0,,,,,,,,, +50008,2,,,,,,,,,0,,,,,,,,, +50009,2,,,,,,,,,0,,,,,,,,, +50010,2,,,,,,,,,0,,,,,,,,, +50011,2,,,,,Level_Explode_Test,,,,0,,,,,,,,, +50012,2,,,,,Level_Swril_Test,,,,0,,,,,,,,, +50013,2,,,,,Level_Melt_Test,,,,0,,,,,,,,, +50014,2,,,,,,,,,0,,,,,,,,, +50015,2,,,,,,,,,0,,,,,,,,, +50016,2,,,,,,,,,0,,,,,,,,, +50017,2,,,,,,,,,0,,,,,,,,, +50018,2,,,,,,,,,0,,,,,,,,, +50019,2,,,,,TestLevel_Element_Evn_Rock,,,,0,,,,,,,,, +50020,1,,,,,,,,,0,,,,,,,,, +50021,2,,,,,,,,,0,,,,,,,,, +50022,2,,,,,,,,,0,,,,,,,,, +50023,2,,,,,,,,,0,,,,,,,,, +50024,2,,,,,LevelEntity_TowerBuff_ElementReactionHurt_Melt,,,,0,,,,,,,,, +50025,2,,,,,,,,,0,,,,,,,,, +50026,2,,,,,,,,,0,,,,,,,,, +50027,2,,,,,,,,,0,,,,,,,,, +50028,2,,,,,,,,,0,,,,,,,,, +50029,2,,,,,,,,,0,,,,,,,,, +50030,2,,,,,,,,,0,,,,,,,,, +50031,2,,,,,,,,,0,,,,,,,,, +50032,2,,,,,,,,,0,,,,,,,,, +50033,2,,,,,,,,,0,,,,,,,,, +50034,2,,,,,,,,,0,,,,,,,,, +50041,2,,,,,,,,,0,,,,,,,,, +50042,2,,,,,,,,,0,,,,,,,,, +50043,2,,,,,,,,,0,,,,,,,,, +50044,2,,,,,,,,,0,,,,,,,,, +50045,2,,,,,,,,,0,,,,,,,,, +50046,2,,,,,,,,,0,,,,,,,,, +50047,2,,,,,,,,,0,,,,,,,,, +50048,2,,,,,,,,,0,,,,,,,,, +50049,2,,,,,,,,,0,,,,,,,,, +50050,2,,,,,,,,,0,,,,,,,,, +50051,2,,,,,,,,,0,,,,,,,,, +50052,2,,,,,,,,,0,,,,,,,,, +50053,2,,,,,,,,,0,,,,,,,,, +50054,2,,,,,,,,,0,,,,,,,,, +50055,2,,,,,,,,,0,,,,,,,,, +50056,2,,,,,,,,,0,,,,,,,,, +50057,2,,,,,,,,,0,,,,,,,,, +50058,2,,,,,Level_Monster_Shougun_Setting,,,,0,,,,,,,,, +50059,2,,,,,Level_Monster_Shougun_Setting,,,,0,,,,,,,,, +50060,2,,,,,,,,,0,,,,,,,,, +50061,2,,,,,,,,,,,,,,,,,, +50062,2,,,,,,,,,0,,,,,,,,, +50063,2,,,,,,,,,0,,,,,,,,, +50064,2,,,,,,,,,0,,,,,,,,, +50065,2,,,,,,,,,0,,,,,,,,, +50066,2,,,,,,,,,0,,,,,,,,, +50067,2,,,,,,,,,0,,,,,,,,, +50068,2,,,,,,,,,,,,,,,,,, +50069,1,,,,,,,,,0,,,,,,,,, +50070,2,,,,,,,,,0,,,,,,,,, +50071,1,,,,,,,,,0,,,,,,,,, +50072,2,,,,,,,,,0,,,,,,,,, +50073,1,,,,,,,,,0,,,,,,,,, +50074,2,,,,,,,,,0,,,,,,,,, +50075,2,,,,,,,,,0,,,,,,,,, +50076,2,,,,,,,,,0,,,,,,,,, +50077,2,,,,,,,,,,,,,,,,,, +50078,2,1,,,,,,,,0,,,,,,,,, +50079,2,1,,,,Level_DreamDungeon_Mona,,,,0,,,,,,,,, +50080,2,1,,,,,,,,0,,,,,,,,, +50081,2,1,,,,Level_DreamDungeon_Mona,,,,0,,,,,,,,, +50082,2,1,,,,,,,,,,,,,,,,, +50083,2,1,,,,,,,,,,,,,,,,, +50084,2,1,,,,,,,,,,,,,,,,, +50085,2,1,,,,,,,,0,,,,,,,,, +50086,2,1,,,,,,,,0,,,,,,,,, +50087,2,1,,,,,,,,0,,,,,,,,, +50088,2,1,,,,,,,,,,,,,,,,, +50089,2,1,,,,,,,,,,,,,,,,, +50090,2,,,,,,,,,0,,,,,,,,, +50091,2,,,,,,,,,0,,,,,,,,, +50092,2,,,,,,,,,0,,,,,,,,, +50093,2,,,,,,,,,0,,,,,,,,, +50094,2,,,,,,,,,1,,,,,,,,, +50095,2,,,,,,,,,1,,,,,,,,, +50096,2,,,,,,,,,1,,,,,,,,, +50097,2,,,,,,,,,1,,,,,,,,, +50098,2,,,,,,,,,1,,,,,,,,, +50099,2,,,,,,,,,1,,,,,,,,, +51000,2,,,,,,,,,1,,,,,,,,, +51001,2,,,,,,,,,1,,,,,,,,, +51002,2,,,,,,,,,1,,,,,,,,, +51003,2,,,,,,,,,1,,,,,,,,, +51004,2,,,,,,,,,1,,,,,,,,, +51005,2,,,,,,,,,1,,,,,,,,, +51006,2,,,,,,,,,0,,,,,,,,, +51007,2,,,,,Level_BigWorld,,,,,,,,,,1,,,3 +51008,2,,,,,Level_CharAmusement_Dungeon,,,,,,,,,,,,, +51009,2,,,,,LevelEntity_Activity_V3_2_MushroomBeastBattle,,,,,,,,,,,,, diff --git a/gdconf/game_data_config/csv/SceneTagData.csv b/gdconf/game_data_config/csv/SceneTagData.csv new file mode 100644 index 00000000..2ff5fd40 --- /dev/null +++ b/gdconf/game_data_config/csv/SceneTagData.csv @@ -0,0 +1,251 @@ +SceneTagId,,,,,,,,,, +int32,,,,,,,,,, +ID,SceneTagName,ID,ĬǷЧ,Ƿloading,1,11,12,2,21,22 +101,Hdj,3,,,1,1001,,,, +102,JadeChamber,3,1,,2,10008,1,,, +103,JadeChamber,3,,,2,10009,1,,, +104,Hdj,3,,,4,2002,,5,1110311, +105,Fhj,3,,,4,2003,,5,39604, +106,SummerTime,4,,,4,2005,,5,4001103, +107,KlinSeal,3,1,,,,,,, +108,SummerTime_High,4,,,,,,,, +109,SummerTime_Low,4,,,,,,,, +111,Ruinup,3,,,,,,,, +112,QLFightPlatform,3,,,,,,,, +113,Lmboss_01,3,1,,,,,,, +114,FlowerZone_01,3,,,,,,,, +115,FlowerZone_02,3,,,,,,,, +116,Lmboss_02,3,,,,,,,, +117,LYDS_01,3,1,,,,,,, +118,LYDS_02,3,,,,,,,, +119,Zyj,3,,,,,,,, +120,AbyssalNight,5,,1,,,,,, +121,AbyssalIsle,5,,,,,,,, +122,AbyssalEvent,5,,,,,,,, +123,AbyssalEventNight,5,,,,,,,, +124,WinterCamp,3,,,1,2009,,,, +125,Hguan01,3,1,,,,,,, +126,Hguan02,3,,,,,,,, +127,Hguan03,3,,,,,,,, +128,RBQyg_01,3,,1,,,,,, +129,RBQyg_02,3,,1,,,,,, +130,RBQyg_03,3,,1,,,,,, +131,RBQyg_04,3,,1,,,,,, +133,RBQyg_Stage,3,,1,,,,,, +134,TongqueTemple_Old,3,1,,,,,,, +135,TongqueTemple_New,3,,,,,,,, +136,Aby_LightOFF,7,1,,,,,,, +137,AbyIsle_Const,7,1,,,,,,, +138,AbyIsle_LightOFF,7,1,,,,,,, +139,HZD01,3,1,,,,,,, +140,HZD02,3,,,,,,,, +141,CYJY_Phase1_ON,3,1,1,,,,,, +142,CYJY_Phase1_OFF,3,,1,,,,,, +143,CYJY_Phase2_ON,6,1,1,,,,,, +144,CYJY_Phase2_OFF,6,,1,,,,,, +145,CYJY_Phase3_ON,6,1,1,,,,,, +146,CYJY_Phase3_OFF,6,,1,,,,,, +147,Irodori,3,,,,,,,, +148,Aby_Event,7,1,,,,,,, +149,SHOPYamashiroKenta,3,,,,,,,, +150,CYJY_Phase4ON,6,,1,,,,,, +151,CYJY_Phase4OFF,6,,1,,,,,, +152,Vintage,3,,,,,,,, +153,Vintage_Md,3,,,,,,,, +154,FungusFighter,3,,,,,,,, +1001,Combine_Lyg,3,,,,,,,, +1002,Combine_Mdc,3,,,,,,,, +1003,Aby_LightOFF,5,,,,,,,, +1004,Aby_LightON,5,,,,,,,, +1005,AbyIsle_Const,5,,,,,,,, +1006,AbyIsle_LightON,5,,,,,,,, +1007,AbyIsle_LightOFF,5,,,,,,,, +1009,AbyIsle_NotEvent,5,,,,,,,, +1010,AbyIsle_NotEventLightOFF,5,,,,,,,, +1011,Combine_RBQyg,3,,1,,,,,, +1012,DI_WW01,9,1,,,,,,, +1013,DI_WW02,9,,,,,,,, +1014,DI_PP01,9,1,,,,,,, +1015,DI_PP02,9,,,,,,,, +1016,DI_PP03,9,,,,,,,, +1017,DI_SS01,9,1,,,,,,, +1018,DI_SS02,9,,,,,,,, +1019,DI_SS03,9,,,,,,,, +1020,DI_BD01,9,1,,,,,,, +1021,DI_BDLM,9,,1,,,,,, +1022,DI_BDRM,9,,1,,,,,, +1023,DI_BDLI,9,,1,,,,,, +1024,DI_BDRI,9,,1,,,,,, +1025,DI_BDLL,9,,1,,,,,, +1026,DI_BDRL,9,,1,,,,,, +1027,Combine_Irodori,3,,,,,,,, +1028,Aby_NotEvent,5,,,,,,,, +1029,Aby_NotEventLightOFF,5,,,,,,,, +1030,Combine_QldFight,3,,,,,,,, +1031,MichiaeMatsuri_WQ_Default5,5,1,,,,,,, +1032,MichiaeMatsuri_WQ_Default7,7,,1,,,,,, +1033,MichiaeMatsuri_WQ_SideA,7,,1,,,,,, +1034,MichiaeMatsuri_WQ_SideB,7,,1,,,,,, +1035,DreamIsland_All_WithoutAnyChange,9,,,,,,,, +1036,DreamIsland_-1_-1_BaseTerrain,9,,,,,,,, +1037,DreamIsland_0_-1_BaseTerrain,9,,,,,,,, +1038,DreamIsland_0_0_BaseTerrain,9,,,,,,,, +1039,DreamIsland_-1_0_BaseTerrain,9,,,,,,,, +1040,DreamIsland_-1_-1_BaseGrass,9,,,,,,,, +1041,DreamIsland_0_-1_BaseGrass,9,,,,,,,, +1042,DreamIsland_0_0_BaseGrass,9,,,,,,,, +1043,DreamIsland_-1_0_BaseGrass,9,,,,,,,, +1046,DI_Fischl01,20139,1,,,,,,, +1047,DI_Fischl02,20139,,,,,,,, +1048,DI_Xinyan01,20133,1,,,,,,, +1049,DI_Xinyan02,20133,,,,,,,, +1050,DI_Kazuha01,20142,1,1,,,,,, +1051,DI_Kazuha02,20142,1,1,,,,,, +1052,DI_Kazuha03,20142,,1,,,,,, +1053,DI_Kazuha04,20142,,1,,,,,, +1054,DI_Kazuha05,20142,,1,,,,,, +1055,DI_Kazuha06,20142,,1,,,,,, +1056,DI_Kazuha07,20142,,1,,,,,, +1057,DI_Kazuha08,20142,,1,,,,,, +1058,DI_Kazuha09,20142,,1,,,,,, +1059,DI_Kazuha10,20142,,1,,,,,, +1060,DI_SS04,9,,,,,,,, +1061,CYJY_Twins2_Block_ON,6,1,1,,,,,, +1062,CYJY_Twins2_Block_OFF,6,,1,,,,,, +1063,CYJY_Twins1_OFF,6,1,1,,,,,, +1064,CYJY_Twins1_ON,6,,1,,,,,, +1065,DI_Mona01,20136,1,1,,,,,, +1066,DI_Mona02,20136,,1,,,,,, +1067,DI_Mona03,20136,,1,,,,,, +1068,Combine_SHOPYamashiroKenta,3,,,,,,,, +1069,DI_Kazuha31,20140,1,1,,,,,, +1070,DI_Kazuha32,20140,,1,,,,,, +1071,DI_Kazuha33,20140,,1,,,,,, +1072,DI_Kazuha21,20135,1,1,,,,,, +1073,DI_Kazuha22,20135,1,1,,,,,, +1074,DI_Mona04,20136,,1,,,,,, +1075,DI_Mona05,20136,,1,,,,,, +1076,DI_SkiffWQ,9,,1,,,,,, +1077,DI_BDMM,9,,1,,,,,, +1078,DI_BDII,9,,1,,,,,, +1079,DI_BDIM,9,,1,,,,,, +1080,DI_BDMI,9,,1,,,,,, +1081,DI_BDYY,9,,1,,,,,, +1082,DI_BDMY,9,,1,,,,,, +1083,DI_BDYM,9,,1,,,,,, +1084,DI_BDIY,9,,1,,,,,, +1085,DI_BDYI,9,,1,,,,,, +1086,DI_Kazuha35,20140,,1,,,,,, +1087,BigTree01,20132,,1,,,,,, +1088,BigTree02,20132,,1,,,,,, +1089,BigTree03,20132,1,1,,,,,, +1090,BigTree04,20132,1,1,,,,,, +1091,XMSM_LSK_01,3,1,1,,,,,, +1092,XMSM_LSK_02,3,,1,,,,,, +1093,Vana_real,3,,,,,,,, +1094,Vana_dream,3,1,,,,,,, +1095,Vana_first,3,1,1,,,,,, +1096,Vana_festival,3,,1,,,,,, +1097,Onion_real,3,,,,,,,, +1098,Onion_dream,3,,,,,,,, +1099,Temple_before,3,1,1,,,,,, +1100,Temple_after,3,,1,,,,,, +1101,Forest_before,3,1,,,,,,, +1102,Forest_after,3,,,,,,,, +1103,Oasis_before,3,1,,,,,,, +1104,Oasis_after,3,,,,,,,, +1105,Final_before,3,1,,,,,,, +1106,Final_after,3,,,,,,,, +1107,Vintage_BaseGrass,3,,,,,,,, +1108,Final_BaseGrass,3,,,,,,,, +1109,Combine_Forest_after,3,,,,,,,, +1110,Mdg_real,3,1,,,,,,, +1111,Mdg_dream,3,,,,,,,, +1112,HuaShen01,3,,1,,,,,, +1114,HuaShen02,3,,1,,,,,, +1116,HuaShen03,3,,1,,,,,, +1117,Combine_HuaShen03,3,,,,,,,, +1118,VarunaCo_Af,3,,1,,,,,, +1119,VarunaDe_Af,3,,,,,,,, +1120,CaveForest_No,3,1,,,,,,, +1121,CaveForest_Dr,3,,,,,,,, +1122,WaterDR_Be,3,1,1,,,,,, +1123,WaterDR_Af,3,,1,,,,,, +1124,Oasis_BaseGrass,3,,,,,,,, +1125,VarunaCo_Be,3,1,1,,,,,, +1126,Vintage_BaseTerrain,3,,,,,,,, +1127,WaterPour_be,3,1,1,,,,,, +1128,WaterPour_af,3,,1,,,,,, +1129,DoorOpen_be,3,1,,,,,,, +1130,DoorOpen_af,3,,,,,,,, +1131,CupGrow_before,3,1,,,,,,, +1132,CupGrow_after,3,,,,,,,, +1133,Clear_before,3,1,,,,,,, +1134,Clear_after,3,,,,,,,, +1135,STemple_be,3,1,,,,,,, +1136,STemple_af,3,,,,,,,, +1137,XMSM_XST_01,3,1,,,,,,, +1138,XMSM_YHYD1_01,3,1,,,,,,, +1139,XMSM_YHYD1_02,3,,,,,,,, +1140,XMSM_YHYD2_01,3,1,,,,,,, +1141,XMSM_YHYD2_02,3,,,,,,,, +1142,Combine_Vintage,3,,,,,,,, +1143,Titan_before,3,1,1,,,,,, +1144,Titan_after,3,,1,,,,,, +1145,Combine_TitanO_after,3,,1,,,,,, +1146,VarunaDe_Be,3,1,,,,,,, +1147,BigTree04,20160,1,1,,,,,, +1148,BigTree04,20161,1,1,,,,,, +1149,CupGrow_0_2_BaseGrass,3,,,,,,,, +1150,BigTree01,46300,,1,,,,,, +1151,BigTree02,46300,,1,,,,,, +1152,BigTree03,46300,1,1,,,,,, +1153,BigTree04,46300,1,1,,,,,, +1154,BigTree01,46302,,1,,,,,, +1155,BigTree02,46302,,1,,,,,, +1156,BigTree03,46302,1,1,,,,,, +1157,BigTree04,46302,1,1,,,,,, +1158,BigTree01,46303,,1,,,,,, +1159,BigTree02,46303,,1,,,,,, +1160,BigTree03,46303,1,1,,,,,, +1161,BigTree04,46303,1,1,,,,,, +1162,TitanO_after,3,,1,,,,,, +1164,XMSM_CWLTop,3,,1,,,,,, +1165,CWL_Trans_01,3,1,,,,,,, +1166,CWL_Trans_02,3,,,,,,,, +1167,WorldTree01,20150,,1,,,,,, +1168,Xmsm_AfCs,3,1,1,,,,,, +1169,XMSM_CWLBlock,3,,,,,,,, +1170,XMSM_XST_02,3,,,,,,,, +1171,BigTree03,35860,1,1,,,,,, +1172,BigTree04,35860,1,1,,,,,, +1173,BigTree03,35861,1,1,,,,,, +1174,BigTree04,35861,1,1,,,,,, +1175,BigTree03,35862,1,1,,,,,, +1176,BigTree04,35862,1,1,,,,,, +1177,BigTree03,35863,1,1,,,,,, +1178,BigTree04,35863,1,1,,,,,, +1179,ScarBoss01,20154,1,1,,,,,, +1180,ScarBoss02,20154,,1,,,,,, +1181,ScarBoss01,20153,1,1,,,,,, +1182,ScarBoss02,20153,,1,,,,,, +1183,XMSM_YHYD1_03,3,,,,,,,, +1184,XMSM_YHYD2_03,3,,,,,,,, +1185,WorldTree01,20164,1,1,,,,,, +1186,Onion_after,20148,,1,,,,,, +1201,ScarBoss01,20168,1,1,,,,,, +1202,ScarBoss02,20168,,1,,,,,, +1203,CycleDungeon01,3,,1,,,,,, +1204,DreamClub01,3,,1,,,,,, +1205,Combine_FungusFighter,3,,,,,,,, +1209,JSG_State1,1075,1,1,,,,,, +1210,JSG_State2,1075,,1,,,,,, +1211,JSG_State3,1075,,1,,,,,, +1212,L_AkashaOpen,20162,1,,,,,,, +1213,L_AkashaOpen,1073,1,1,,,,,, +1214,L_AkashaClose,1073,,1,,,,,, +1215,BoatTurn,20158,,1,,,,,, +1216,Boat_BaseTerrain,20158,1,1,,,,,, +1217,Boat_BaseGrass,20158,1,1,,,,,, +1218,Combine_BoatTurn ,20158,1,1,,,,,, +1221,Combine_DreamClub01,3,,1,,,,,, diff --git a/gdconf/game_data_config_test.go b/gdconf/game_data_config_test.go index cfe6da0d..9c785647 100644 --- a/gdconf/game_data_config_test.go +++ b/gdconf/game_data_config_test.go @@ -1,6 +1,9 @@ package gdconf import ( + "image" + "image/color" + "image/jpeg" "os" "strings" "testing" @@ -96,3 +99,71 @@ func TestConvTxtToCsv(t *testing.T) { logger.Info("conv finish") time.Sleep(time.Second) } + +func TestSceneBlock(t *testing.T) { + config.InitConfig("./application.toml") + logger.InitLogger("test") + InitGameDataConfig() + scene, exist := CONF.SceneMap[3] + if !exist { + panic("scene 3 not exist") + } + logger.Info("scene info: %v", scene.SceneConfig) + for _, block := range scene.BlockMap { + block.BlockRange.Min.X *= -1.0 + block.BlockRange.Max.X *= -1.0 + block.BlockRange.Min.Z *= -1.0 + block.BlockRange.Max.Z *= -1.0 + } + minX := 0.0 + maxX := 0.0 + minZ := 0.0 + maxZ := 0.0 + for _, block := range scene.BlockMap { + if block.BlockRange.Min.X < minX { + minX = block.BlockRange.Min.X + } + if block.BlockRange.Max.X > maxX { + maxX = block.BlockRange.Max.X + } + if block.BlockRange.Min.Z < minZ { + minZ = block.BlockRange.Min.Z + } + if block.BlockRange.Max.Z > maxZ { + maxZ = block.BlockRange.Max.Z + } + } + logger.Info("minX: %v, maxX: %v, minZ: %v, maxZ: %v", minX, maxX, minZ, maxZ) + img := image.NewRGBA(image.Rect(0, 0, int(maxX-minX), int(maxZ-minZ))) + rectColor := uint8(0) + for _, block := range scene.BlockMap { + maxW := int(block.BlockRange.Min.X - minX) + maxH := int(block.BlockRange.Min.Z - minZ) + minW := int(block.BlockRange.Max.X - minX) + minH := int(block.BlockRange.Max.Z - minZ) + for w := minW; w <= maxW; w++ { + for h := minH; h <= maxH; h++ { + img.SetRGBA(w, h, color.RGBA{R: rectColor, G: rectColor, B: rectColor, A: 255}) + } + } + rectColor += 5 + if rectColor > 255 { + rectColor = 0 + } + } + file, err := os.Create("./block.jpg") + if err != nil { + return + } + defer func() { + _ = file.Close() + }() + err = jpeg.Encode(file, img, &jpeg.Options{ + Quality: 100, + }) + if err != nil { + return + } + logger.Info("test finish") + time.Sleep(time.Second) +} diff --git a/gdconf/scene_data.go b/gdconf/scene_data.go new file mode 100644 index 00000000..b1633efa --- /dev/null +++ b/gdconf/scene_data.go @@ -0,0 +1,30 @@ +package gdconf + +import ( + "fmt" + + "hk4e/pkg/logger" + + "github.com/jszwec/csvutil" +) + +type SceneData struct { + SceneId int32 `csv:"SceneId"` // ID + SceneType int32 `csv:"SceneType,omitempty"` // 类型 +} + +func (g *GameDataConfig) loadSceneData() { + g.SceneDataMap = make(map[int32]*SceneData) + data := g.readCsvFileData("SceneData.csv") + var sceneDataList []*SceneData + err := csvutil.Unmarshal(data, &sceneDataList) + if err != nil { + info := fmt.Sprintf("parse file error: %v", err) + panic(info) + } + for _, sceneData := range sceneDataList { + // list -> map + g.SceneDataMap[sceneData.SceneId] = sceneData + } + logger.Info("SceneData count: %v", len(g.SceneDataMap)) +} diff --git a/gdconf/scene_data_config.go b/gdconf/scene_data_config.go new file mode 100644 index 00000000..334c8db9 --- /dev/null +++ b/gdconf/scene_data_config.go @@ -0,0 +1,256 @@ +package gdconf + +import ( + "os" + "strconv" + + "hk4e/pkg/logger" +) + +type Scene struct { + Id int32 + SceneConfig *SceneConfig // 地图配置 + BlockMap map[int32]*Block // 所有的区块 +} + +type Vector struct { + X float64 `json:"x"` + Y float64 `json:"y"` + Z float64 `json:"z"` +} + +type SceneConfig struct { + BeginPos *Vector `json:"begin_pos"` + Size *Vector `json:"size"` + BornPos *Vector `json:"born_pos"` + BornRot *Vector `json:"born_rot"` + DieY float64 `json:"die_y"` + VisionAnchor *Vector `json:"vision_anchor"` +} + +type Block struct { + Id int32 + BlockRange *BlockRange // 区块范围坐标 + GroupMap map[int32]*Group // 所有的group +} + +type BlockRange struct { + Min *Vector `json:"min"` + Max *Vector `json:"max"` +} + +type Group struct { + Id int32 `json:"id"` + RefreshId int32 `json:"refresh_id"` + Area int32 `json:"area"` + Pos *Vector `json:"pos"` + IsReplaceable *Replaceable `json:"is_replaceable"` + MonsterList []*Monster `json:"monsters"` // 怪物 + NpcList []*Npc `json:"npcs"` // NPC + GadgetList []*Gadget `json:"gadgets"` // 装置 +} + +type Replaceable struct { + Value bool `json:"value"` + Version int32 `json:"version"` + NewBinOnly bool `json:"new_bin_only"` +} + +type Monster struct { + ConfigId int32 `json:"config_id"` + MonsterId int32 `json:"monster_id"` + Pos *Vector `json:"pos"` + Rot *Vector `json:"rot"` + Level int32 `json:"level"` + AreaId int32 `json:"area_id"` +} + +type Npc struct { + ConfigId int32 `json:"config_id"` + NpcId int32 `json:"npc_id"` + Pos *Vector `json:"pos"` + Rot *Vector `json:"rot"` + AreaId int32 `json:"area_id"` +} + +type Gadget struct { + ConfigId int32 `json:"config_id"` + GadgetId int32 `json:"gadget_id"` + Pos *Vector `json:"pos"` + Rot *Vector `json:"rot"` + Level int32 `json:"level"` + AreaId int32 `json:"area_id"` +} + +func (g *GameDataConfig) loadScene() { + g.SceneMap = make(map[int32]*Scene) + sceneLuaPrefix := g.luaPrefix + "scene/" + for _, sceneData := range g.SceneDataMap { + sceneId := sceneData.SceneId + sceneIdStr := strconv.Itoa(int(sceneId)) + mainLuaData, err := os.ReadFile(sceneLuaPrefix + sceneIdStr + "/scene" + sceneIdStr + ".lua") + if err != nil { + logger.Error("open file error: %v, sceneId: %v", err, sceneId) + continue + } + luaState := fixLuaState(string(mainLuaData)) + scene := new(Scene) + scene.Id = sceneId + // scene_config + scene.SceneConfig = new(SceneConfig) + ok := parseLuaTableToObject[*SceneConfig](luaState, "scene_config", scene.SceneConfig) + if !ok { + logger.Error("get scene_config object error, sceneId: %v", sceneId) + luaState.Close() + continue + } + scene.BlockMap = make(map[int32]*Block) + // blocks + blockIdList := make([]int32, 0) + ok = parseLuaTableToObject[*[]int32](luaState, "blocks", &blockIdList) + if !ok { + logger.Error("get blocks object error, sceneId: %v", sceneId) + luaState.Close() + continue + } + // block_rects + blockRectList := make([]*BlockRange, 0) + ok = parseLuaTableToObject[*[]*BlockRange](luaState, "block_rects", &blockRectList) + luaState.Close() + if !ok { + logger.Error("get block_rects object error, sceneId: %v", sceneId) + continue + } + for index, blockId := range blockIdList { + block := new(Block) + block.Id = blockId + if index >= len(blockRectList) { + continue + } + block.BlockRange = blockRectList[index] + blockIdStr := strconv.Itoa(int(block.Id)) + blockLuaData, err := os.ReadFile(sceneLuaPrefix + sceneIdStr + "/scene" + sceneIdStr + "_block" + blockIdStr + ".lua") + if err != nil { + logger.Error("open file error: %v, sceneId: %v, blockId: %v", err, sceneId, blockId) + continue + } + luaState = fixLuaState(string(blockLuaData)) + // groups + block.GroupMap = make(map[int32]*Group) + groupList := make([]*Group, 0) + ok = parseLuaTableToObject[*[]*Group](luaState, "groups", &groupList) + luaState.Close() + if !ok { + logger.Error("get groups object error, sceneId: %v, blockId: %v", sceneId, blockId) + continue + } + for _, group := range groupList { + groupId := group.Id + groupIdStr := strconv.Itoa(int(groupId)) + groupLuaData, err := os.ReadFile(sceneLuaPrefix + sceneIdStr + "/scene" + sceneIdStr + "_group" + groupIdStr + ".lua") + if err != nil { + logger.Error("open file error: %v, sceneId: %v, blockId: %v, groupId: %v", err, sceneId, blockId, groupId) + continue + } + luaState = fixLuaState(string(groupLuaData)) + // monsters + group.MonsterList = make([]*Monster, 0) + ok = parseLuaTableToObject[*[]*Monster](luaState, "monsters", &group.MonsterList) + if !ok { + logger.Error("get monsters object error, sceneId: %v, blockId: %v, groupId: %v", sceneId, blockId, groupId) + luaState.Close() + continue + } + // npcs + group.NpcList = make([]*Npc, 0) + ok = parseLuaTableToObject[*[]*Npc](luaState, "npcs", &group.NpcList) + if !ok { + logger.Error("get npcs object error, sceneId: %v, blockId: %v, groupId: %v", sceneId, blockId, groupId) + luaState.Close() + continue + } + // gadgets + group.GadgetList = make([]*Gadget, 0) + ok = parseLuaTableToObject[*[]*Gadget](luaState, "gadgets", &group.GadgetList) + luaState.Close() + if !ok { + logger.Error("get gadgets object error, sceneId: %v, blockId: %v, groupId: %v", sceneId, blockId, groupId) + continue + } + ok = true + for _, monster := range group.MonsterList { + if monster == nil { + ok = false + break + } + } + for _, npc := range group.NpcList { + if npc == nil { + ok = false + break + } + } + for _, gadget := range group.GadgetList { + if gadget == nil { + ok = false + break + } + } + if !ok { + logger.Error("entry is nil, sceneId: %v, blockId: %v, groupId: %v", sceneId, blockId, groupId) + continue + } + block.GroupMap[group.Id] = group + } + scene.BlockMap[block.Id] = block + } + g.SceneMap[sceneId] = scene + } + sceneCount := 0 + blockCount := 0 + groupCount := 0 + monsterCount := 0 + npcCount := 0 + gadgetCount := 0 + for _, scene := range g.SceneMap { + for _, block := range scene.BlockMap { + for _, group := range block.GroupMap { + monsterCount += len(group.MonsterList) + npcCount += len(group.NpcList) + gadgetCount += len(group.GadgetList) + groupCount++ + } + blockCount++ + } + sceneCount++ + } + logger.Info("Scene count: %v, Block count: %v, Group count: %v, Monster count: %v, Npc count: %v, Gadget count: %v", + sceneCount, blockCount, groupCount, monsterCount, npcCount, gadgetCount) +} + +func (g *GameDataConfig) GetSceneBlockConfig(sceneId int32, blockId int32) ([]*Monster, []*Npc, []*Gadget, bool) { + monsterList := make([]*Monster, 0) + npcList := make([]*Npc, 0) + gadgetList := make([]*Gadget, 0) + sceneConfig, exist := g.SceneMap[sceneId] + if !exist { + return nil, nil, nil, false + } + blockConfig, exist := sceneConfig.BlockMap[blockId] + if !exist { + return nil, nil, nil, false + } + for _, groupConfig := range blockConfig.GroupMap { + for _, monsterConfig := range groupConfig.MonsterList { + monsterList = append(monsterList, monsterConfig) + } + for _, npcConfig := range groupConfig.NpcList { + npcList = append(npcList, npcConfig) + } + + for _, gadgetConfig := range groupConfig.GadgetList { + gadgetList = append(gadgetList, gadgetConfig) + } + } + return monsterList, npcList, gadgetList, true +} diff --git a/go.mod b/go.mod index f48dc374..77de7909 100644 --- a/go.mod +++ b/go.mod @@ -56,6 +56,9 @@ require github.com/go-redis/redis/v8 v8.11.5 // midi require gitlab.com/gomidi/midi/v2 v2.0.25 +// lua +require github.com/yuin/gopher-lua v1.0.0 + require ( github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/go.sum b/go.sum index 3c77ae44..f552564a 100644 --- a/go.sum +++ b/go.sum @@ -147,6 +147,8 @@ github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lL github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/gopher-lua v1.0.0 h1:pQCf0LN67Kf7M5u7vRd40A8M1I8IMLrxlqngUJgZ0Ow= +github.com/yuin/gopher-lua v1.0.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= gitlab.com/gomidi/midi/v2 v2.0.25 h1:dkzVBqbaFHjyWwP71MrQNX7IeRUIDonddmHbPpO/Ucg= gitlab.com/gomidi/midi/v2 v2.0.25/go.mod h1:quTyMKSQ4Klevxu6gY4gy2USbeZra0fV5SalndmPfsY= go.mongodb.org/mongo-driver v1.8.3 h1:TDKlTkGDKm9kkJVUOAXDK5/fkqKHJVwYQSpoRfB43R4= diff --git a/gs/game/game_manager.go b/gs/game/game_manager.go index be72928d..7a1bda2d 100644 --- a/gs/game/game_manager.go +++ b/gs/game/game_manager.go @@ -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) } diff --git a/gs/game/route_manager.go b/gs/game/route_manager.go index 7a359d40..77558427 100644 --- a/gs/game/route_manager.go +++ b/gs/game/route_manager.go @@ -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) { diff --git a/gs/game/tick_manager.go b/gs/game/tick_manager.go index 1f208faa..e137d4c3 100644 --- a/gs/game/tick_manager.go +++ b/gs/game/tick_manager.go @@ -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 -} diff --git a/gs/game/user_common_handler.go b/gs/game/user_common_handler.go index 7994c188..8775de9e 100644 --- a/gs/game/user_common_handler.go +++ b/gs/game/user_common_handler.go @@ -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) +} diff --git a/gs/game/user_fight_sync.go b/gs/game/user_fight_sync.go index 55fc9f45..4f9f7346 100644 --- a/gs/game/user_fight_sync.go +++ b/gs/game/user_fight_sync.go @@ -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) diff --git a/gs/game/user_scene.go b/gs/game/user_scene.go index f9212320..3d511feb 100644 --- a/gs/game/user_scene.go +++ b/gs/game/user_scene.go @@ -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 +} diff --git a/gs/game/video_player.go b/gs/game/video_player.go index 1688a937..fb28dc3d 100644 --- a/gs/game/video_player.go +++ b/gs/game/video_player.go @@ -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) } } diff --git a/gs/game/world_manager.go b/gs/game/world_manager.go index d13ab679..68d8ce70 100644 --- a/gs/game/world_manager.go +++ b/gs/game/world_manager.go @@ -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 { diff --git a/pkg/alg/aoi.go b/pkg/alg/aoi.go index f93abb9e..f1754b33 100644 --- a/pkg/alg/aoi.go +++ b/pkg/alg/aoi.go @@ -1,6 +1,8 @@ package alg import ( + "math" + "hk4e/pkg/logger" ) @@ -19,48 +21,72 @@ type AoiManager struct { gridMap map[uint32]*Grid // 当前区域中都有哪些格子 key:gid value:格子对象 } -// NewAoiManager 初始化aoi区域 -func NewAoiManager(minX, maxX, numX, minY, maxY, numY, minZ, maxZ, numZ int16) (r *AoiManager) { +func NewAoiManager() (r *AoiManager) { r = new(AoiManager) - r.minX = minX - r.maxX = maxX - r.minY = minY - r.maxY = maxY - r.numX = numX - r.numY = numY - r.minZ = minZ - r.maxZ = maxZ - r.numZ = numZ r.gridMap = make(map[uint32]*Grid) - logger.Info("start init aoi area grid, num: %v", uint32(numX)*uint32(numY)*uint32(numZ)) + return r +} + +// SetAoiRange 设置aoi区域边界坐标 +func (a *AoiManager) SetAoiRange(minX, maxX, minY, maxY, minZ, maxZ int16) { + a.minX = minX + a.maxX = maxX + a.minY = minY + a.maxY = maxY + a.minZ = minZ + a.maxZ = maxZ +} + +// Init3DRectAoiManager 初始化3D矩形aoi区域 +func (a *AoiManager) Init3DRectAoiManager(numX, numY, numZ int16) { + a.numX = numX + a.numY = numY + a.numZ = numZ // 初始化aoi区域中所有的格子 - for x := int16(0); x < numX; x++ { - for y := int16(0); y < numY; y++ { - for z := int16(0); z < numZ; z++ { + for x := int16(0); x < a.numX; x++ { + for y := int16(0); y < a.numY; y++ { + for z := int16(0); z < a.numZ; z++ { // 利用格子坐标得到格子id gid从0开始按xzy的顺序增长 - gid := uint32(y)*(uint32(numX)*uint32(numZ)) + uint32(z)*uint32(numX) + uint32(x) + gid := uint32(y)*(uint32(a.numX)*uint32(a.numZ)) + uint32(z)*uint32(a.numX) + uint32(x) // 初始化一个格子放在aoi中的map里 key是当前格子的id grid := NewGrid( gid, - r.minX+x*r.GridXLen(), - r.minX+(x+1)*r.GridXLen(), - r.minY+y*r.GridYLen(), - r.minY+(y+1)*r.GridYLen(), - r.minZ+z*r.GridZLen(), - r.minZ+(z+1)*r.GridZLen(), + a.minX+x*a.GridXLen(), + a.minX+(x+1)*a.GridXLen(), + a.minY+y*a.GridYLen(), + a.minY+(y+1)*a.GridYLen(), + a.minZ+z*a.GridZLen(), + a.minZ+(z+1)*a.GridZLen(), ) - r.gridMap[gid] = grid + a.gridMap[gid] = grid } } } - logger.Info("init aoi area grid finish") - logger.Debug("AoiMgr: minX: %d, maxX: %d, numX: %d, minY: %d, maxY: %d, numY: %d, minZ: %d, maxZ: %d, numZ: %d\n", - r.minX, r.maxX, r.numX, r.minY, r.maxY, r.numY, r.minZ, r.maxZ, r.numZ) - for _, grid := range r.gridMap { - logger.Debug("Grid: gid: %d, minX: %d, maxX: %d, minY: %d, maxY: %d, minZ: %d, maxZ: %d, entityIdMap: %v", - grid.gid, grid.minX, grid.maxX, grid.minY, grid.maxY, grid.minZ, grid.maxZ, grid.entityIdMap) +} + +func (a *AoiManager) AoiInfoLog(debug bool) { + logger.Info("AoiMgr: minX: %d, maxX: %d, numX: %d, minY: %d, maxY: %d, numY: %d, minZ: %d, maxZ: %d, numZ: %d, num grid: %d\n", + a.minX, a.maxX, a.numX, a.minY, a.maxY, a.numY, a.minZ, a.maxZ, a.numZ, uint32(a.numX)*uint32(a.numY)*uint32(a.numZ)) + minGridObjectCount := math.MaxInt32 + maxGridObjectCount := 0 + for _, grid := range a.gridMap { + gridObjectCount := len(grid.objectMap) + if gridObjectCount > maxGridObjectCount { + maxGridObjectCount = gridObjectCount + } + if gridObjectCount < minGridObjectCount { + minGridObjectCount = gridObjectCount + } + if debug { + logger.Debug("Grid: gid: %d, minX: %d, maxX: %d, minY: %d, maxY: %d, minZ: %d, maxZ: %d, object count: %v", + grid.gid, grid.minX, grid.maxX, grid.minY, grid.maxY, grid.minZ, grid.maxZ, gridObjectCount) + for objectId, object := range grid.objectMap { + logger.Debug("objectId: %v, object: %v", objectId, object) + } + } } - return r + logger.Info("min grid object count: %v", minGridObjectCount) + logger.Info("max grid object count: %v", maxGridObjectCount) } // GridXLen 每个格子在x轴方向的长度 @@ -155,51 +181,72 @@ func (a *AoiManager) GetSurrGridListByGid(gid uint32) (gridList []*Grid) { gridList = append(gridList, a.gridMap[v+uint32(a.numX)*uint32(a.numZ)]) } } - return gridList + retGridList := make([]*Grid, 0) + for _, v := range gridList { + if v == nil { + continue + } + retGridList = append(retGridList, v) + } + return retGridList } -// GetEntityIdListByPos 通过坐标得到周边格子内的全部entityId -func (a *AoiManager) GetEntityIdListByPos(x, y, z float32) (entityIdList []uint32) { +// GetObjectListByPos 通过坐标得到周边格子内的全部object +func (a *AoiManager) GetObjectListByPos(x, y, z float32) map[int64]any { // 根据坐标得到当前坐标属于哪个格子id gid := a.GetGidByPos(x, y, z) // 根据格子id得到周边格子的信息 gridList := a.GetSurrGridListByGid(gid) - entityIdList = make([]uint32, 0) + objectList := make(map[int64]any) for _, v := range gridList { - tmp := v.GetEntityIdList() - entityIdList = append(entityIdList, tmp...) + tmp := v.GetObjectList() + for kk, vv := range tmp { + objectList[kk] = vv + } logger.Debug("Grid: gid: %d, tmp len: %v", v.gid, len(tmp)) } - return entityIdList + return objectList } -// GetEntityIdListByGid 通过gid获取当前格子的全部entityId -func (a *AoiManager) GetEntityIdListByGid(gid uint32) (entityIdList []uint32) { +// GetObjectListByGid 通过gid获取当前格子的全部object +func (a *AoiManager) GetObjectListByGid(gid uint32) map[int64]any { grid := a.gridMap[gid] - entityIdList = grid.GetEntityIdList() - return entityIdList + if grid == nil { + logger.Error("grid is nil, gid: %v", gid) + return nil + } + objectList := grid.GetObjectList() + return objectList } -// AddEntityIdToGrid 添加一个entityId到一个格子中 -func (a *AoiManager) AddEntityIdToGrid(entityId uint32, gid uint32) { +// AddObjectToGrid 添加一个object到一个格子中 +func (a *AoiManager) AddObjectToGrid(objectId int64, object any, gid uint32) { grid := a.gridMap[gid] - grid.AddEntityId(entityId) + if grid == nil { + logger.Error("grid is nil, gid: %v", gid) + return + } + grid.AddObject(objectId, object) } -// RemoveEntityIdFromGrid 移除一个格子中的entityId -func (a *AoiManager) RemoveEntityIdFromGrid(entityId uint32, gid uint32) { +// RemoveObjectFromGrid 移除一个格子中的object +func (a *AoiManager) RemoveObjectFromGrid(objectId int64, gid uint32) { grid := a.gridMap[gid] - grid.RemoveEntityId(entityId) + if grid == nil { + logger.Error("grid is nil, gid: %v", gid) + return + } + grid.RemoveObject(objectId) } -// AddEntityIdToGridByPos 通过坐标添加一个entityId到一个格子中 -func (a *AoiManager) AddEntityIdToGridByPos(entityId uint32, x, y, z float32) { +// AddObjectToGridByPos 通过坐标添加一个object到一个格子中 +func (a *AoiManager) AddObjectToGridByPos(objectId int64, object any, x, y, z float32) { gid := a.GetGidByPos(x, y, z) - a.AddEntityIdToGrid(entityId, gid) + a.AddObjectToGrid(objectId, object, gid) } -// RemoveEntityIdFromGridByPos 通过坐标把一个entityId从对应的格子中删除 -func (a *AoiManager) RemoveEntityIdFromGridByPos(entityId uint32, x, y, z float32) { +// RemoveObjectFromGridByPos 通过坐标把一个object从对应的格子中删除 +func (a *AoiManager) RemoveObjectFromGridByPos(objectId int64, x, y, z float32) { gid := a.GetGidByPos(x, y, z) - a.RemoveEntityIdFromGrid(entityId, gid) + a.RemoveObjectFromGrid(objectId, gid) } diff --git a/pkg/alg/aoi_grid.go b/pkg/alg/aoi_grid.go index 786ad75f..467adcab 100644 --- a/pkg/alg/aoi_grid.go +++ b/pkg/alg/aoi_grid.go @@ -8,13 +8,13 @@ import ( type Grid struct { gid uint32 // 格子id // 格子边界坐标 - minX int16 - maxX int16 - minY int16 - maxY int16 - minZ int16 - maxZ int16 - entityIdMap map[uint32]bool // k:entityId v:是否存在 + minX int16 + maxX int16 + minY int16 + maxY int16 + minZ int16 + maxZ int16 + objectMap map[int64]any // k:objectId v:对象 } // NewGrid 初始化格子 @@ -27,30 +27,26 @@ func NewGrid(gid uint32, minX, maxX, minY, maxY, minZ, maxZ int16) (r *Grid) { r.maxY = maxY r.minZ = minZ r.maxZ = maxZ - r.entityIdMap = make(map[uint32]bool) + r.objectMap = make(map[int64]any) return r } -// AddEntityId 向格子中添加一个实体id -func (g *Grid) AddEntityId(entityId uint32) { - g.entityIdMap[entityId] = true +// AddObject 向格子中添加一个对象 +func (g *Grid) AddObject(objectId int64, object any) { + g.objectMap[objectId] = object } -// RemoveEntityId 从格子中删除一个实体id -func (g *Grid) RemoveEntityId(entityId uint32) { - _, exist := g.entityIdMap[entityId] +// RemoveObject 从格子中删除一个对象 +func (g *Grid) RemoveObject(objectId int64) { + _, exist := g.objectMap[objectId] if exist { - delete(g.entityIdMap, entityId) + delete(g.objectMap, objectId) } else { - logger.Error("remove entity id but it not exist, entityId: %v", entityId) + logger.Error("remove object id but it not exist, objectId: %v", objectId) } } -// GetEntityIdList 获取格子中所有实体id -func (g *Grid) GetEntityIdList() (entityIdList []uint32) { - entityIdList = make([]uint32, 0) - for k := range g.entityIdMap { - entityIdList = append(entityIdList, k) - } - return entityIdList +// GetObjectList 获取格子中所有对象 +func (g *Grid) GetObjectList() map[int64]any { + return g.objectMap } diff --git a/pkg/alg/aoi_test.go b/pkg/alg/aoi_test.go index ce55a1ef..bc8dbf69 100644 --- a/pkg/alg/aoi_test.go +++ b/pkg/alg/aoi_test.go @@ -11,11 +11,13 @@ func TestAoiManagerGetSurrGridListByGid(t *testing.T) { filePath := "./application.toml" config.InitConfig(filePath) logger.InitLogger("") - aoiManager := NewAoiManager( - -150, 150, 3, - -150, 150, 3, - -150, 150, 3, + aoiManager := NewAoiManager() + aoiManager.SetAoiRange( + -150, 150, + -150, 150, + -150, 150, ) + aoiManager.Init3DRectAoiManager(3, 3, 3) for k := range aoiManager.gridMap { // 得到当前格子周边的九宫格 gridList := aoiManager.GetSurrGridListByGid(k)