class ActiveMods: #s_activeMods : ArrayList = ArrayList() # shared #s_loaded : ActiveMods = ActiveMods('loaded') # shared id: str = None mods: ArrayList = None def __init__(self, id: str): self.requireValidId(id) self.id = id self.mods = ArrayList() self.mapOrder = ArrayList() @classmethod def count(cls) -> int: return len(s_activeMods) @classmethod def getByIndex(cls, index: int): #->ActiveMods return s_activeMods[index] @classmethod def getById(cls, id: str): #->ActiveMods index = cls.indexOf(id) if index == -1: return cls.create(id) return s_activeMods[index] @classmethod def indexOf(cls, id: str) -> int: id = id.strip() cls.requireValidId(id) for index, mod in s_activeMods.as_list().enumerate(): if mod.id.lower() == id.lower(): return index return -1 @classmethod def create(cls, id: str): #->ActiveMods cls.requireValidId(id) if cls.indexOf(id) > -1: assert False, "illegal state" #TODO: proper exception? mod = ActiveMods(id) s_activeMods.add(mod) return mod @classmethod def requireValidId(cls, id: str) -> None: if not id: raise ValueError('id must be a valid string') @classmethod def setLoadedMods(cls, mods) -> None: # mods : ActiveMods) -> None: raise NotImplementedError @classmethod def requiresResetLua(cls, mods) -> bool: raise NotImplementedError @classmethod def renderUI(cls) -> None: raise NotImplementedError @classmethod def Reset(cls) -> None: raise s_loaded.clear() def clear(self) -> None: self.mods.clear() self.mapOrder.clear() def getMods(self) -> ArrayList: return self.mods def getMapOrder(self) -> ArrayList: return self.mapOrder def copyFrom(self, mods) -> None: # mods : ActiveMods) -> None: self.clear() self.mods.addAll(mods.mods) self.mapOrder.addAll(mods.mapOrder) def setModActive(self, id: str, active: bool) -> None: id = id.strip() if not id: return if not active: self.mods.remove(id) elif id not in self.mods: self.mods.add(id) def isModActive(self, id: str) -> bool: return id.strip() in self.mods def removeMod(self, id: str) -> None: raise NotImplementedError def removeMapOrder(self, id: str) -> None: raise NotImplementedError def checkMissingMods(self) -> None: raise NotImplementedError def checkMissingMaps(self) -> None: raise NotImplementedError
class ModelScript(BaseScriptObject): DEFAULT_SHADER_NAME : str = "basicEffect" fileName : str = None name : str = None scale : float = 1.0 meshName : str = None textureName : str = None shaderName : str = None bStatic : bool = None m_attachments : ArrayList = None invertX : bool = False loadedModel : Model = None def __init__(self): self.m_attachments = ArrayList() def Load(self, name : str, data : str) -> None: from ..manager import instance self.fileName = instance.currentFileName self.name = name block = ScriptParser.parse(data) block = block.children[0] for sub in block.children: if sub.type == 'attachment': self.LoadAttachment(sub) for value in block.values: key, value = value.string.split(' = ') key = key.lower() if key == 'mesh': self.meshName = value elif key == 'scale': self.scale = float(value) elif key == 'shader': self.shaderName = value elif key == 'static': self.bStatic = value.lower() == 'true' elif key == 'texture': self.textureName = value elif key == 'invertX': self.invertX = value.lower() == 'true' def LoadAttachment(self, block) -> ModelAttachment: attach = self.getAttachmentById(block.id) if not attach: attach = ModelAttachment(block.id) self.m_attachments.add(attach) for value in block.values: key, value = value.string.split(' = ') if key == 'bone': attach.setBone(value) elif key == 'offset': self.LoadVector3f(value, attach.offset) elif key == 'rotate': self.LoadVector3f(value, attach.offset) return attach def LoadVector3f(cls, data : str, vector : Vector3f) -> None: data = [float(x) for x in data.split()] # TODO: set the vector here def getName(self) -> str: return self.name def getFullType(self) -> str: return f"{self.module.name}.{self.name}" def getMeshName(self) -> str: return self.meshName def getTextureName(self) -> str: if not self.textureName: return self.meshName return self.textureName def getShaderName(self) -> str: if not self.shaderName: return 'basicEffect' return self.textureName def getFileName(self) -> str: return self.fileName def getAttachmentCount(self) -> int: return len(self.m_attachments) def getAttachment(self, index : int) -> ModelAttachment: return self.m_attachments[index] def getAttachmentById(self, id : str) -> ModelAttachment: for attach in self.m_attachments: if attach.id == id: return attach return None def addAttachment(self, attach : ModelAttachment) -> ModelAttachment: self.m_attachments.add(attach) return attach def removeAttachment(self, attach : ModelAttachment) -> ModelAttachment: if isinstance(attach, int): attach = self.m_attachments[attach] #TODO: beware exceptions self.m_attachments.remove(attach) return attach def addAttachmentAt(self, index : int, attach : ModelAttachment) -> ModelAttachment: self.m_attachments.add(index, attach) return attach def reset(self) -> None: self.name = None self.meshName = None self.textureName = None self.shaderName = None self.bStatic = False self.scale = 1.0