# coding=utf-8 import copy from BlueFoxSystem import BlueFoxServerSystem from LocalCoord import FixPosition, OriginCoord, RotCoord, RotAxes, BlockFaceRot from ..OtherTools import Mount from ..ToolsConfig import * blockBlocks = {} blockEntityDataComp = serverCompFactory.CreateBlockEntityData(LevelId) def GetLoadedBlockBlockByPosDim(posDim): # type:(Tuple[int,int,int,int]) -> BlockBlock """ 通过维度坐标获取已经加载的方块块 """ return blockBlocks.get(posDim) def GetLoadedBlockBlock(): # type:() -> List[BlockBlock] """ 获取所有已加载的方块块 """ return list(set(blockBlocks.values())) @Mount(BlueFoxServerSystem) class BlockBlock(object): """ 方块块,用于解决模型体积过大导致的模型消失的问题 blockList = { (0, 0, 0): {'name': 'rtdd:carrotandbeef', 'aux': 0} (相对坐标位置): {'name': 方块ID, 'aux': 方块AUX} } """ blueFoxSystem = BlueFoxServerSystem if 0 else None blockList = {} @classmethod def getInstance(cls, posDim): instance = blockBlocks.get(posDim) if instance: return instance data = blockEntityDataComp.GetBlockEntityData(posDim[3], posDim[:3]) if data and data['isCenter']: posDims = [tuple(_) for _ in data['posDims']] return cls(tuple(data['centerPosDim']), data['aux'], posDims) blockData = serverCompFactory.CreateBlockInfo(LevelId).GetBlockNew(posDim[:3], posDim[3]) return cls(posDim, blockData['aux']) def __init__(self, posDim, aux, posDims=None): # type:(Tuple,int,List[Tuple]) -> None self.blockPosDims = posDims # 方块块控制坐标 self.centerPosDim = posDim # 控制中心 self.aux = aux if self.blockPosDims is None: self.blockPosDims = self.CreatePosDims(posDim, aux) self.CreateBlocks() self.dataComp = blockEntityDataComp.GetBlockEntityData(self.centerPosDim[3], self.centerPosDim[:3]) self.dataComp['posDims'] = self.blockPosDims self.dataComp['aux'] = self.aux for posDim in self.blockPosDims: blockBlocks[posDim] = self def ReplaceBlocks(self, newBlockList, otherData=None, drop=0): """ 替换方块,新方块依然具有方块实体的要求 """ oldData = { 'posDims': self.blockPosDims, 'aux': self.aux } if otherData is None: otherData = {} oldData.update(otherData) self.DestroyBlocks(drop) self.CreateBlocks(newBlockList) def DestroyFunction(self): """ 销毁处理逻辑不清除方块 """ for posDim in self.blockPosDims: del blockBlocks[posDim] def Destroy(self, drop=0): """ 销毁方块块 :param drop:是否掉落核心方块 """ self.DestroyFunction() self.DestroyBlocks(drop) def DestroyBlocks(self, drop=0): """ 销毁方块块所控制的方块 """ blockComp = serverCompFactory.CreateBlockInfo(LevelId) posDim = copy.copy(self.blockPosDims) posDim.remove(self.centerPosDim) for posDim in posDim: blockComp.SetBlockNew( posDim[:3], blockDict={'name': 'minecraft:air'}, dimensionId=posDim[3] ) blockComp.SetBlockNew( self.centerPosDim[:3], blockDict={'name': 'minecraft:air'}, dimensionId=self.centerPosDim[3], oldBlockHandling=1 if drop else 0 ) def CreateBlocks(self, blockList=None): """ 放置方块块所控制的方块 """ if blockList is None: blockList = self.blockList blockComp = serverCompFactory.CreateBlockInfo(LevelId) for pos in self.blockList: blockInfo = blockList[pos] posDim = self.CalculatePosDimFromOffset(pos, self.centerPosDim, self.aux) blockComp.SetBlockNew(posDim[:3], blockDict=blockInfo, dimensionId=posDim[3]) dataComp = blockEntityDataComp.GetBlockEntityData(posDim[3], posDim[:3]) dataComp['isCenter'] = True if not cmp(pos, (0, 0, 0)) else False dataComp['centerPosDim'] = self.centerPosDim self.dataComp = serverCompFactory.CreateBlockEntityData(LevelId).GetBlockEntityData( self.centerPosDim[3], self.centerPosDim[:3] ) def IsSelf(self, posDim): """ 判断一个维度坐标是否为本方块块 """ for posDimSelf in self.blockPosDims: if not cmp(posDimSelf, posDim): return True return False @classmethod def CreatePosDims(cls, posDim, aux): # type:(Tuple,int) -> List[Tuple] """ 创建方块块控制坐标 """ return [cls.CalculatePosDimFromOffset(pos, posDim, aux) for pos in cls.blockList] @classmethod def CalculatePosDimFromOffset(cls, offset, posDim, aux): """计算偏移坐标维度""" originCoord = OriginCoord(posDim) _, __, ___ = FixPosition(originCoord.AbsPos( RotCoord(BlockFaceRot[aux], RotAxes.Y).CalculatePos(offset) )) return _, __, ___, posDim[3] @classmethod def Able(cls, posDim, aux): """ 判断是否可以生成块 """ blockComp = serverCompFactory.CreateBlockInfo(LevelId) for posDim in cls.CreatePosDims(posDim, aux): block = blockComp.GetBlockNew(posDim[:3], posDim[3]) if block is None or (block and block['name'] != 'minecraft:air'): return False return True