init
This commit is contained in:
13
game_server/game/avatar/avatar_manager.py
Normal file
13
game_server/game/avatar/avatar_manager.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import dataclasses
|
||||
from rail_proto.lib import AvatarSkillTree,EquipRelic
|
||||
|
||||
@dataclasses.dataclass
|
||||
class AvatarManager:
|
||||
avatar_id: int
|
||||
level: int
|
||||
exp: int
|
||||
promotion: int
|
||||
rank: int
|
||||
skills: list[AvatarSkillTree]
|
||||
equip_id: int = 0
|
||||
relic_list: dict[int,EquipRelic] = dataclasses.field(default_factory=dict)
|
||||
16
game_server/game/chat/command/__init__.py
Normal file
16
game_server/game/chat/command/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import importlib
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
folder = "game_server/game/chat/command"
|
||||
sys.path.append(os.path.dirname(folder))
|
||||
|
||||
for filename in os.listdir(folder):
|
||||
if filename.endswith(".py") and filename != "__init__.py":
|
||||
module_name = filename[:-3]
|
||||
module_path = f"game_server.game.chat.command.{module_name}"
|
||||
try:
|
||||
importlib.import_module(module_path)
|
||||
except Exception as e:
|
||||
print(f"Error importing module '{module_path}': {e}")
|
||||
60
game_server/game/chat/command/give.py
Normal file
60
game_server/game/chat/command/give.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from game_server.game.chat.decorators import Command
|
||||
from game_server.net.session import PlayerSession
|
||||
from game_server.resource import ResourceManager
|
||||
from game_server.resource.configdb.equipment_config import EquipmentConfig
|
||||
from game_server.resource.configdb.relic_config import RelicConfigData
|
||||
from game_server.resource.configdb.relic_main_affix_config import RelicMainAffixConfigData
|
||||
from game_server.resource.configdb.relic_sub_affix_config import RelicSubAffixConfigData
|
||||
from database.inventory.inventory_data import SubAffix
|
||||
|
||||
@Command(
|
||||
prefix="give",
|
||||
usage="/give",
|
||||
)
|
||||
async def execute(session:PlayerSession, item_id, param1=None, param2=None, param3=None, param4=None, param5=None):
|
||||
try:
|
||||
sync = False
|
||||
lightcones = ResourceManager.instance().find_by_index(EquipmentConfig,item_id)
|
||||
relics = ResourceManager.instance().find_by_index(RelicConfigData,item_id)
|
||||
|
||||
if lightcones:
|
||||
rank = 1
|
||||
if param1 and param1.startswith("r") and len(param1) == 2:
|
||||
rank_value = param1[1]
|
||||
if rank_value.isdigit() and 1 <= int(rank_value) <= 5:
|
||||
rank = int(rank_value)
|
||||
elif rank_value.isdigit() and int(rank_value) > 5:
|
||||
rank = 5
|
||||
item = session.player.add_lightcone(item_id, rank)
|
||||
if item:
|
||||
session.player.inventory_manager[item.unique_id] = item
|
||||
sync = True
|
||||
elif relics:
|
||||
main_stat = 0
|
||||
main_property = ""
|
||||
main_affix_group = ResourceManager.instance().find_all_by_index(RelicMainAffixConfigData, relics.MainAffixGroup)
|
||||
sub_affix_list = []
|
||||
|
||||
if param1 and param1.startswith("s") and len(param1) == 2 and param1[1].isdigit():
|
||||
main_affix = next((affix for affix in main_affix_group if affix.AffixID == int(param1[1])))
|
||||
if main_affix:
|
||||
main_stat = main_affix.AffixID
|
||||
main_property = main_affix.Property
|
||||
|
||||
for param in [param2, param3, param4, param5]:
|
||||
if param and len(param) >= 3 and ":" in param:
|
||||
parts = param.split(":")
|
||||
if len(parts) == 2 and all(part.isdigit() for part in parts):
|
||||
sub_affix_data = ResourceManager.instance().find_all_by_index(RelicSubAffixConfigData, relics.SubAffixGroup)
|
||||
for affix in sub_affix_data:
|
||||
if affix.AffixID == int(parts[0]) and affix.Property != main_property:
|
||||
sub_affix_list.append(SubAffix(id=int(parts[0]), count=int(parts[1]), step=int(parts[1]) * 2))
|
||||
item = session.player.add_relic(item_id,main_stat,sub_affix_list)
|
||||
if item:
|
||||
session.player.inventory_manager[item.unique_id] = item
|
||||
sync = True
|
||||
if sync:
|
||||
await session.notify(session.player.PlayerSyncProto())
|
||||
return "GIVE"
|
||||
except Exception as e:
|
||||
print(e)
|
||||
48
game_server/game/chat/command/giveall.py
Normal file
48
game_server/game/chat/command/giveall.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from game_server.game.chat.decorators import Command
|
||||
from game_server.net.session import PlayerSession
|
||||
from game_server.resource import ResourceManager
|
||||
from game_server.resource.configdb.avatar_config import AvatarConfig
|
||||
from game_server.resource.configdb.equipment_config import EquipmentConfig
|
||||
from game_server.resource.configdb.relic_config import RelicConfigData
|
||||
|
||||
@Command(
|
||||
prefix="giveall",
|
||||
usage="/giveall",
|
||||
)
|
||||
async def execute(session:PlayerSession, text):
|
||||
try:
|
||||
sync = False
|
||||
if text == "avatars":
|
||||
avatars = ResourceManager.instance().values(AvatarConfig)
|
||||
for avatar in avatars:
|
||||
if avatar.AvatarID == 1224 or avatar.AvatarID >= 7000:
|
||||
continue
|
||||
if session.player.avatar_mananger.get(avatar.AvatarID):
|
||||
continue
|
||||
data = session.player.add_avatar(avatar.AvatarID)
|
||||
if data:
|
||||
session.player.avatar_mananger[data.avatar_id] = data
|
||||
sync = True
|
||||
|
||||
if text == "lightcones":
|
||||
lightcones = ResourceManager.instance().values(EquipmentConfig)
|
||||
for lightcone in lightcones:
|
||||
item = session.player.add_lightcone(lightcone.EquipmentID)
|
||||
if item:
|
||||
session.player.inventory_manager[item.unique_id] = item
|
||||
sync = True
|
||||
|
||||
if text == "relics":
|
||||
relics = ResourceManager.instance().values(RelicConfigData)
|
||||
for relic in relics:
|
||||
item = session.player.add_relic(relic.ID)
|
||||
if item:
|
||||
session.player.inventory_manager[item.unique_id] = item
|
||||
sync = True
|
||||
|
||||
if sync:
|
||||
await session.notify(session.player.PlayerSyncProto())
|
||||
|
||||
return "GIVEALL"
|
||||
except Exception as e:
|
||||
print(e)
|
||||
53
game_server/game/chat/command_handler.py
Normal file
53
game_server/game/chat/command_handler.py
Normal file
@@ -0,0 +1,53 @@
|
||||
from utils.logger import Info
|
||||
from game_server.game.chat.decorators import command_registry
|
||||
from game_server.net.session import PlayerSession
|
||||
import game_server.game.chat.command # noqa: F401
|
||||
|
||||
|
||||
class CommandHandler:
|
||||
def load_commands(self):
|
||||
registered_commands = ", ".join(
|
||||
item.prefix for item in command_registry.values() if not item.is_alias
|
||||
)
|
||||
|
||||
Info(
|
||||
f"[BOOT] [CommandHandler] Registered {len(command_registry)} game commands => {registered_commands}"
|
||||
)
|
||||
|
||||
def parse_command(self, content: str):
|
||||
content = content.lstrip("/")
|
||||
parts = content.split(maxsplit=1)
|
||||
if len(parts) < 2:
|
||||
return parts[0], ""
|
||||
|
||||
return parts[0], parts[1]
|
||||
|
||||
def print_help(self):
|
||||
result = "Available commands:\n"
|
||||
for index, (_, func) in enumerate(command_registry.items()):
|
||||
result += f"{index+1}) {func.usage}\n\n"
|
||||
return result
|
||||
|
||||
async def handle_command(self, session: PlayerSession, content: str):
|
||||
if content == "/help":
|
||||
return self.print_help()
|
||||
|
||||
command_label, args = self.parse_command(content)
|
||||
command_func = command_registry.get(command_label)
|
||||
|
||||
if command_func is not None:
|
||||
func_args_cnt = command_func.__code__.co_argcount - 1
|
||||
args_list = args.split()[:func_args_cnt]
|
||||
|
||||
if args_list and args_list[0] == "help":
|
||||
return f"Usage: {command_func.usage}"
|
||||
|
||||
try:
|
||||
return await command_func(session, *args_list)
|
||||
except TypeError:
|
||||
return f"Usage: {command_func.usage}"
|
||||
|
||||
return None
|
||||
|
||||
|
||||
handler = CommandHandler()
|
||||
21
game_server/game/chat/decorators.py
Normal file
21
game_server/game/chat/decorators.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from typing import Dict, Type
|
||||
|
||||
|
||||
command_registry: Dict[str, Type] = {}
|
||||
|
||||
|
||||
def Command(prefix: str, usage: str, aliases: list = list()):
|
||||
def decorator(func):
|
||||
func.usage = usage
|
||||
func.prefix = prefix
|
||||
func.is_alias = False
|
||||
command_registry[prefix] = func
|
||||
|
||||
# Register alias if exist
|
||||
for alias in aliases:
|
||||
func.is_alias = True
|
||||
command_registry[alias] = func
|
||||
|
||||
return func
|
||||
|
||||
return decorator
|
||||
10
game_server/game/enums/avatar/relic_type.py
Normal file
10
game_server/game/enums/avatar/relic_type.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from enum import Enum
|
||||
|
||||
class RelicTypeEnum(Enum):
|
||||
Unknown = 0
|
||||
HEAD = 1
|
||||
HAND = 2
|
||||
BODY = 3
|
||||
FOOT = 4
|
||||
NECK = 5
|
||||
OBJECT = 6
|
||||
12
game_server/game/enums/scene/game_mode_type.py
Normal file
12
game_server/game/enums/scene/game_mode_type.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from enum import Enum
|
||||
|
||||
class GameModeTypeEnum(Enum):
|
||||
Unknown = 0
|
||||
Town = 1
|
||||
Maze = 2
|
||||
Train = 3
|
||||
Challenge = 4
|
||||
Rogue = 5
|
||||
Raid = 6
|
||||
AetherDivide = 7
|
||||
TrialActivity = 8
|
||||
57
game_server/game/items/relic_manager.py
Normal file
57
game_server/game/items/relic_manager.py
Normal file
@@ -0,0 +1,57 @@
|
||||
import random
|
||||
from pydantic import BaseModel
|
||||
from game_server.resource import ResourceManager
|
||||
from game_server.resource.configdb.relic_config import RelicConfigData
|
||||
from game_server.resource.configdb.relic_main_affix_config import RelicMainAffixConfigData
|
||||
from game_server.resource.configdb.relic_sub_affix_config import RelicSubAffixConfigData
|
||||
|
||||
|
||||
class SubAffix(BaseModel):
|
||||
id: int
|
||||
count: int
|
||||
step: int
|
||||
|
||||
class MainAffix(BaseModel):
|
||||
AffixID: int
|
||||
Property: str
|
||||
|
||||
class RelicManager(BaseModel):
|
||||
def GetRandomRelicMainAffix(self, itemid) -> MainAffix:
|
||||
config = ResourceManager.instance().find_by_index(RelicConfigData, itemid)
|
||||
if not config:
|
||||
return MainAffix(AffixID=0, Property=None)
|
||||
|
||||
affixes = [
|
||||
affix
|
||||
for affix in ResourceManager.instance().values(RelicMainAffixConfigData)
|
||||
if config.MainAffixGroup == affix.GroupID
|
||||
]
|
||||
|
||||
if not affixes:
|
||||
return MainAffix(AffixID=0, Property=None)
|
||||
|
||||
selected_affix = random.choice(affixes)
|
||||
return MainAffix(AffixID=selected_affix.AffixID, Property=selected_affix.Property)
|
||||
|
||||
def GetRandomRelicSubAffix(self, itemid: int, property: str, loop: int, affix_list: list[SubAffix] = []) -> list[SubAffix]:
|
||||
config = ResourceManager.instance().find_by_index(RelicConfigData, itemid)
|
||||
if not config:
|
||||
return []
|
||||
|
||||
affix_ids_in_list = {affix.id for affix in affix_list}
|
||||
affixes = [
|
||||
affix
|
||||
for affix in ResourceManager.instance().values(RelicSubAffixConfigData)
|
||||
if config.SubAffixGroup == affix.GroupID and affix.Property != property and affix.AffixID not in affix_ids_in_list
|
||||
]
|
||||
|
||||
selected_affixes = random.sample(affixes, 4 - len(affix_ids_in_list))
|
||||
|
||||
sub_affix_list = []
|
||||
for affix in selected_affixes:
|
||||
count = random.randint(1, loop)
|
||||
step = count * 2
|
||||
sub_affix_list.append(SubAffix(id=affix.AffixID, count=count, step=step))
|
||||
|
||||
return sub_affix_list
|
||||
|
||||
22
game_server/game/motion/motion_info.py
Normal file
22
game_server/game/motion/motion_info.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from pydantic import BaseModel
|
||||
from rail_proto.lib import MotionInfo,Vector
|
||||
|
||||
class Motion(BaseModel):
|
||||
x: float
|
||||
y: float
|
||||
z: float
|
||||
rotY: float
|
||||
|
||||
def ToProto(self) -> MotionInfo:
|
||||
return MotionInfo(
|
||||
pos=Vector(
|
||||
x=int(self.x*1000),
|
||||
y=int(self.y*1000),
|
||||
z=int(self.z*1000)
|
||||
),
|
||||
rot=Vector(
|
||||
x=0,
|
||||
y=int(self.rotY*1000),
|
||||
z=0
|
||||
)
|
||||
)
|
||||
171
game_server/game/player/player_manager.py
Normal file
171
game_server/game/player/player_manager.py
Normal file
@@ -0,0 +1,171 @@
|
||||
from pydantic import BaseModel
|
||||
from database.player.player_data import PlayerData,players_collection
|
||||
from database.avatar.avatar_data import AvatarData,get_all_avatars_by_uid,avatars_collection
|
||||
from database.lineup.lineup_data import LineupData,get_all_lineup_by_uid,lineups_collection
|
||||
from database.inventory.inventory_data import InventoryData,get_all_items_by_uid,items_collection
|
||||
from game_server.game.scene.scene_manager import SceneManager
|
||||
from typing import Optional
|
||||
from rail_proto.lib import (
|
||||
PlayerSyncScNotify,
|
||||
AvatarSync
|
||||
)
|
||||
from pymongo import UpdateOne
|
||||
from utils.logger import Error
|
||||
|
||||
|
||||
class PlayerManager(BaseModel):
|
||||
data : PlayerData = PlayerData()
|
||||
avatar_mananger: dict[int,AvatarData] = {}
|
||||
lineup_manager: dict[int,LineupData] = {}
|
||||
inventory_manager: dict[int,InventoryData] = {}
|
||||
scene_manager: SceneManager = None
|
||||
|
||||
def init_default(self):
|
||||
self.add_all_avatars()
|
||||
self.add_all_lineups()
|
||||
self.add_all_items()
|
||||
self.scene_manager = SceneManager(
|
||||
entry_id=self.data.entry_id
|
||||
)
|
||||
|
||||
def save_all(self):
|
||||
self.save_player_data_bulk()
|
||||
self.save_all_avatars_bulk()
|
||||
self.save_all_lineups_bulk()
|
||||
self.save_all_items_bulk()
|
||||
|
||||
def add_all_avatars(self):
|
||||
avatars = get_all_avatars_by_uid(uid=self.data.uid)
|
||||
if not avatars:
|
||||
avatar = AvatarData(
|
||||
uid=self.data.uid,
|
||||
avatar_id=self.data.cur_basic_type
|
||||
).add_avatar()
|
||||
self.avatar_mananger[self.data.cur_basic_type] = avatar
|
||||
|
||||
for avatar in avatars:
|
||||
self.avatar_mananger[avatar.avatar_id] = avatar
|
||||
|
||||
def add_all_lineups(self):
|
||||
lineups = get_all_lineup_by_uid(uid=self.data.uid)
|
||||
if not lineups:
|
||||
lineup = LineupData(
|
||||
uid=self.data.uid,
|
||||
index=0,
|
||||
name="",
|
||||
avatar_list=[self.data.cur_basic_type]
|
||||
).add_lineup()
|
||||
self.lineup_manager[lineup.index] = lineup
|
||||
for lineup in lineups:
|
||||
self.lineup_manager[lineup.index] = lineup
|
||||
|
||||
def add_all_items(self):
|
||||
items = get_all_items_by_uid(uid=self.data.uid)
|
||||
for item in items:
|
||||
self.inventory_manager[item.unique_id] = item
|
||||
|
||||
def add_avatar(self,avatar_id:int) -> Optional[AvatarData]:
|
||||
avatar = self.avatar_mananger.get(avatar_id)
|
||||
if avatar:
|
||||
return None
|
||||
|
||||
avatar = AvatarData(uid=self.data.uid,avatar_id=avatar_id).add_avatar()
|
||||
if avatar:
|
||||
return avatar
|
||||
return None
|
||||
|
||||
def add_lineup(self,avatar_ids: list[int],index=0,name=""):
|
||||
LineupData(
|
||||
uid=self.data.uid,
|
||||
index=index,
|
||||
name=name,
|
||||
avatar_list=avatar_ids
|
||||
).add_lineup()
|
||||
|
||||
def add_lightcone(self,lightcone_id: int, rank=1) -> Optional[InventoryData]:
|
||||
item = InventoryData(
|
||||
uid=self.data.uid,
|
||||
item_id=lightcone_id,
|
||||
rank=rank
|
||||
).add_lightcone()
|
||||
if item:
|
||||
return item
|
||||
return None
|
||||
|
||||
def add_relic(self,relic_id: int, main_affix=0, sub_affix=[]) -> Optional[InventoryData]:
|
||||
item = InventoryData(
|
||||
uid=self.data.uid,
|
||||
item_id=relic_id,
|
||||
main_affix=main_affix,
|
||||
sub_affix=sub_affix
|
||||
).add_relic()
|
||||
if item:
|
||||
return item
|
||||
return None
|
||||
|
||||
|
||||
def PlayerSyncProto(self) -> PlayerSyncScNotify:
|
||||
avatars = []
|
||||
for avatar_id,avatar in self.avatar_mananger.items():
|
||||
avatars.append(avatar.ToProto())
|
||||
|
||||
lightcones = []
|
||||
for unique_id,item in self.inventory_manager.items():
|
||||
if item.main_type == 1:
|
||||
lightcones.append(item.ToProto())
|
||||
|
||||
relics = []
|
||||
for unique_id,item in self.inventory_manager.items():
|
||||
if item.main_type == 2:
|
||||
relics.append(item.ToProto())
|
||||
return PlayerSyncScNotify(
|
||||
equipment_list=lightcones,
|
||||
relic_list=relics,
|
||||
avatar_sync=
|
||||
AvatarSync(
|
||||
avatar_list=avatars
|
||||
),
|
||||
basic_info=self.data.ToProto()
|
||||
)
|
||||
|
||||
def save_player_data_bulk(self):
|
||||
try:
|
||||
player_data = self.data.model_dump()
|
||||
player_data["uid"] = self.data.uid
|
||||
query = {"uid": self.data.uid}
|
||||
players_collection.update_one(query, {"$set": player_data}, upsert=True)
|
||||
except Exception as e:
|
||||
Error(f"Error save player data: {e}")
|
||||
|
||||
def save_all_avatars_bulk(self):
|
||||
operations = []
|
||||
for avatar in self.avatar_mananger.values():
|
||||
avatar_data = avatar.model_dump()
|
||||
avatar_data["uid"] = avatar.uid
|
||||
query = {"uid": avatar.uid, "avatar_id": avatar.avatar_id}
|
||||
operations.append(UpdateOne(query, {"$set": avatar_data}, upsert=True))
|
||||
|
||||
if operations:
|
||||
avatars_collection.bulk_write(operations)
|
||||
|
||||
def save_all_lineups_bulk(self):
|
||||
operations = []
|
||||
for lineup in self.lineup_manager.values():
|
||||
lineup_data = lineup.model_dump()
|
||||
lineup_data["uid"] = lineup.uid
|
||||
query = {"uid": lineup.uid, "index": lineup.index}
|
||||
operations.append(UpdateOne(query, {"$set": lineup_data}, upsert=True))
|
||||
|
||||
if operations:
|
||||
lineups_collection.bulk_write(operations)
|
||||
|
||||
def save_all_items_bulk(self):
|
||||
operations = []
|
||||
for item in self.inventory_manager.values():
|
||||
item_data = item.model_dump()
|
||||
item_data["uid"] = item.uid
|
||||
query = {"uid": item.uid, "unique_id": item.unique_id}
|
||||
operations.append(UpdateOne(query, {"$set": item_data}, upsert=True))
|
||||
|
||||
if operations:
|
||||
items_collection.bulk_write(operations)
|
||||
165
game_server/game/scene/scene_manager.py
Normal file
165
game_server/game/scene/scene_manager.py
Normal file
@@ -0,0 +1,165 @@
|
||||
from pydantic import BaseModel
|
||||
from game_server.game.enums.scene.game_mode_type import GameModeTypeEnum
|
||||
from game_server.resource import ResourceManager
|
||||
from game_server.resource.configdb.maze_plane import MazePlaneData
|
||||
from game_server.resource.configdb.map_entrance import MapEntranceData
|
||||
from game_server.game.motion.motion_info import Motion
|
||||
from rail_proto.lib import (
|
||||
SceneEntityGroupInfo,
|
||||
SceneInfo,
|
||||
SceneEntityInfo,
|
||||
SceneEntityGroupInfo,
|
||||
ScenePropInfo,
|
||||
SceneNpcInfo,
|
||||
SceneNpcMonsterInfo,
|
||||
SceneActorInfo,
|
||||
AvatarType
|
||||
)
|
||||
|
||||
class SceneManager(BaseModel):
|
||||
entry_id: int
|
||||
plane_id: int = 0
|
||||
floor_id: int = 0
|
||||
game_mode_type: int = 0
|
||||
world_id: int = 0
|
||||
teleport_id: int = 0
|
||||
entity_group_list: list[SceneEntityGroupInfo] = []
|
||||
entities: dict[int,SceneEntityInfo] = {}
|
||||
battle_monster: list[SceneEntityInfo] = []
|
||||
|
||||
def ToProto(self,session) -> SceneInfo:
|
||||
prop_entity_id = 10
|
||||
npc_entity_id = 10_000
|
||||
monster_entity_id = 20_000
|
||||
entrance = ResourceManager.instance().find_by_index(MapEntranceData, self.entry_id)
|
||||
maze_plane = ResourceManager.instance().find_by_index(MazePlaneData, entrance.PlaneID)
|
||||
floor_infos = entrance.floor_infos.get(self.entry_id)
|
||||
proto = SceneInfo(
|
||||
entry_id=self.entry_id,
|
||||
plane_id=entrance.PlaneID,
|
||||
floor_id=entrance.FloorID,
|
||||
)
|
||||
|
||||
proto.game_mode_type = GameModeTypeEnum[maze_plane.PlaneType].value
|
||||
if maze_plane.WorldID == 100:
|
||||
maze_plane.WorldID = 401
|
||||
proto.world_id = maze_plane.WorldID
|
||||
|
||||
loaded_npc = [13199,13321,1313,13227,13190,13191,13192,13141,13246,13407 ,13223,13152]
|
||||
loaded_group = []
|
||||
groups = []
|
||||
for group_id,group in floor_infos.groups.items():
|
||||
if group.LoadSide == "Client":
|
||||
continue
|
||||
# if group_id in loaded_group:
|
||||
# continue
|
||||
# if group_id > 150 and group_id < 200:
|
||||
# continue
|
||||
# if group_id > 300:
|
||||
# continue
|
||||
if group_id in groups:
|
||||
continue
|
||||
groups.append(group_id)
|
||||
group_info = SceneEntityGroupInfo(
|
||||
group_id=group_id
|
||||
)
|
||||
|
||||
for prop in group.PropList:
|
||||
prop_entity_id += 1
|
||||
prop_entity_info = SceneEntityInfo(
|
||||
inst_id=prop.ID,
|
||||
group_id=group_id,
|
||||
motion=Motion(
|
||||
x=prop.PosX,
|
||||
y=prop.PosY,
|
||||
z=prop.PosZ,
|
||||
rotY=prop.RotY
|
||||
).ToProto(),
|
||||
prop=ScenePropInfo(
|
||||
prop_id=prop.PropID,
|
||||
prop_state=8 if prop.MappingInfoID > 0 else (1 if prop.State == 0 else prop.State)
|
||||
),
|
||||
entity_id=prop_entity_id
|
||||
)
|
||||
group_info.entity_list.append(prop_entity_info)
|
||||
if self.teleport_id > 0 and self.teleport_id == prop.MappingInfoID:
|
||||
for anchor in group.AnchorList:
|
||||
if group.id == prop.AnchorGroupID and anchor.ID == prop.AnchorID:
|
||||
session.player.data.pos.x = int(anchor.PosX)
|
||||
session.player.data.pos.y = int(anchor.PosY)
|
||||
session.player.data.pos.z = int(anchor.PosZ)
|
||||
session.player.data.rot.y = int(anchor.RotY)
|
||||
|
||||
for npc in group.NPCList:
|
||||
if npc.NPCID in loaded_npc:
|
||||
continue
|
||||
loaded_npc.append(npc.NPCID)
|
||||
npc_entity_id += 1
|
||||
npc_entity_info = SceneEntityInfo(
|
||||
inst_id=npc.ID,
|
||||
group_id=group_id,
|
||||
entity_id=npc_entity_id,
|
||||
motion=Motion(
|
||||
x=npc.PosX,
|
||||
y=npc.PosY,
|
||||
z=npc.PosZ,
|
||||
rotY=npc.RotY
|
||||
).ToProto(),
|
||||
npc=SceneNpcInfo(
|
||||
npc_id=npc.NPCID
|
||||
)
|
||||
)
|
||||
group_info.entity_list.append(npc_entity_info)
|
||||
|
||||
for monster in group.MonsterList:
|
||||
monster_entity_id += 1
|
||||
monster_entity_info = SceneEntityInfo(
|
||||
inst_id=monster.ID,
|
||||
group_id=group_id,
|
||||
entity_id=monster_entity_id,
|
||||
motion=Motion(
|
||||
x=monster.PosX,
|
||||
y=monster.PosY,
|
||||
z=monster.PosZ,
|
||||
rotY=monster.RotY
|
||||
).ToProto(),
|
||||
npc_monster=SceneNpcMonsterInfo(
|
||||
monster_id=monster.NPCMonsterID,
|
||||
event_id=monster.EventID,
|
||||
world_level=6
|
||||
)
|
||||
)
|
||||
group_info.entity_list.append(monster_entity_info)
|
||||
session.player.scene_manager.entities[monster_entity_id] = monster_entity_info
|
||||
proto.entity_group_list.append(group_info)
|
||||
|
||||
player_pos = Motion(
|
||||
x=session.player.data.pos.x,
|
||||
y=session.player.data.pos.y,
|
||||
z=session.player.data.pos.z,
|
||||
rotY=session.player.data.rot.y
|
||||
).ToProto()
|
||||
player_group = SceneEntityGroupInfo(state=0,group_id=0)
|
||||
for avatar_id in session.player.lineup_manager.get(session.player.data.cur_lineup).avatar_list:
|
||||
player_entity = SceneEntityInfo(
|
||||
inst_id=0,
|
||||
entity_id=avatar_id << 20,
|
||||
motion=player_pos,
|
||||
actor=SceneActorInfo(
|
||||
avatar_type=AvatarType.AVATAR_FORMAL_TYPE.value,
|
||||
base_avatar_id=avatar_id,
|
||||
uid=session.player.data.uid,
|
||||
)
|
||||
)
|
||||
player_group.entity_list.append(player_entity)
|
||||
proto.entity_group_list.append(player_group)
|
||||
session.player.data.entry_id = self.entry_id
|
||||
session.player.data.plane_id = entrance.PlaneID
|
||||
session.player.data.floor_id = entrance.FloorID
|
||||
return proto
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user