class Block: type: str = None id: str = None elements: ArrayList = None values: ArrayList = None children: ArrayList = None def __init__(self): self.elements = ArrayList() self.values = ArrayList() self.children = ArrayList() def asBlock(self): return self def asValue(self): return None def isEmpty(self) -> bool: return self.elements.isEmpty() def addBlock(self, type: str, id: str): #-> Block: block = Block() block.type = type block.id = id self.elements.add(block) self.children.add(block) return block def getBlock(self, type: str, id: str): #-> Block: for block in self.children: if block.type == type and block.id == id: return block return None def getValue(self, key: str) -> Value: for value in self.values: if value.string[0] != '=' and value.getKey().strip() == key: return value return None def setValue(self, key: str, new_value: str) -> None: value = self.getValue(key) if not value: self.addValue(key, value) else: value.string = f"{key} = {new_value}" def addValue(self, key: str, new_value: str) -> Value: value = Value() value.string = f"{key} = {new_value}" self.elements.add(value) self.values.add(value) return value
def getRequiredSkills(self) -> None: skills = [] if self.skillRequired: for sk in self.skillRequired: # TODO: we need to get the perk from string from PerkFactory #str2 = (PerkFactory.getPerk(PerkFactory.Perks.FromString(str1))).name + " " + + this.skillRequired.get(str1); skills.append("%s %s" % (sk, self.skillRequired[sk])) return ArrayList(*skills)
def __init__(self): self.Imports = ArrayList() self.ItemMap = HashMap() self.GameSoundMap = HashMap() self.GameSoundList = ArrayList() self.ModelScriptMap = HashMap() self.VehicleMap = HashMap() self.VehicleTemplateMap = HashMap() self.RecipeMap = ArrayList() self.RecipesWithDotInName = HashMap() self.EvolvedRecipe = ArrayList() self.UniqueRecipeMap = ArrayList() self.FixingMap = HashMap()
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
def __init__(self, id: str): self.requireValidId(id) self.id = id self.mods = ArrayList() self.mapOrder = ArrayList()
# -*- coding: utf-8 -*- from zomboid.java import ArrayList s_activeMods = ArrayList() # shared s_loaded = None # set at bottom. 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)
def __init__(self): super().__init__() self.Source = ArrayList()
class ScriptModule: name: str = None value: str = None Imports: ArrayList = None # not really a arraylist. Stack() ItemMap: HashMap = None GameSoundMap: HashMap = None GameSoundList: ArrayList = None ModelScriptMap: HashMap = None VehicleMap: HashMap = None VehicleTemplateMap: HashMap = None RecipeMap: ArrayList = None RecipesWithDotInName: HashMap = None EvolvedRecipe: ArrayList = None UniqueRecipeMap: ArrayList = None FixingMap: HashMap = None disabled: bool = False def __init__(self): self.Imports = ArrayList() self.ItemMap = HashMap() self.GameSoundMap = HashMap() self.GameSoundList = ArrayList() self.ModelScriptMap = HashMap() self.VehicleMap = HashMap() self.VehicleTemplateMap = HashMap() self.RecipeMap = ArrayList() self.RecipesWithDotInName = HashMap() self.EvolvedRecipe = ArrayList() self.UniqueRecipeMap = ArrayList() self.FixingMap = HashMap() def Load(self, name: str, data: str) -> None: self.name = name self.value = data self.ParseScriptPP(self.value) self.ParseScript(self.value) self.value = "" def ParseScriptPP(self, data: str) -> None: tokens = ScriptParser.parseTokens(data) for token in tokens: self.CreateFromTokenPP(token) def ParseScript(self, data: str) -> None: tokens = ScriptParser.parseTokens(data) for token in tokens: self.CreateFromToken(token) def CreateFromTokenPP(self, data: str) -> None: data = data.strip() match = RE_HEADER.match(data) if not match: return key, name, data = match.groups() if key == "item": self.ItemMap[name] = Item() elif key == "model": if name in self.ModelScriptMap: self.ModelScriptMap[name].reset() else: self.ModelScriptMap[name] = ModelScript() elif key == "sound": if name in self.GameSoundMap: self.GameSoundMap[name].reset() else: self.GameSoundMap[name] = GameSoundScript() self.GameSoundList.add(self.GameSoundMap[name]) elif key == "vehicle": self.VehicleMap[name] = VehicleScript() elif key == "template": name = name.split() if len(name) == 2 and name[0] == 'vehicle': template = VehicleTemplate(self, name[1], data) self.VehicleTemplateMap[name[1]] = template def CreateFromToken(self, data: str) -> None: data = data.strip() match = RE_HEADER.match(data) if not match: return key, name, block_data = match.groups() this = None block_data = block_data.split(",") if key == "imports": self.Imports += [s.strip() for s in block_data if s.strip()] # todo: check for self importing elif key == "item": this = self.ItemMap[name] elif key == "recipe": this = Recipe() self.RecipeMap.add(this) if '.' in name: self.RecipesWithDotInName[name] = this elif key == "uniquerecipe": this = UniqueRecipe(name) self.UniqueRecipeMap.add(this) elif key == "evolvedrecipe": this = [r for r in self.EvolvedRecipeMap if r.name == name] if this: this = this[0] else: this = EvolvedRecipe(name) elif key == "fixing": this = Fixing() elif key == "multistagebuild": pass # TODO: MultiStageBuilding stuff #(new MultiStageBuilding()).getClass(); #MultiStageBuilding.Stage stage = new MultiStageBuilding.Stage(new MultiStageBuilding()); #stage.Load(str, arrayOfString2); #MultiStageBuilding.addStage(stage); elif key == "model": this = self.ModelScriptMap[name] block_data = data elif key == "sound": this = self.GameSoundMap[name] block_data = data elif key == "vehicle": this = self.VehicleMap[name] block_data = data if not this: return # Load the object this.module = self this.Load(name, block_data)
def __init__(self): self.elements = ArrayList() self.values = ArrayList() self.children = ArrayList()
class Recipe(BaseScriptObject): canBeDoneFromFloor: bool = False AnimNode: str = None Prop1: str = None Prop2: str = None TimeToMake: float = 0.0 Sound: str = None LuaTest: str = None LuaCreate: str = None LuaGrab: str = None NeedToBeLearn: bool = False # this field is actually needToBeLearn, but theres also a method by this exact name.... removeResultItem: bool = False skillRequired: HashMap = None heat: float = 0.0 NoBrokenItems: bool = False # this field is actually NoBrokenItems, but theres also a method by this exact name.... name: str = 'recipe' originalname: str = 'recipe' Result: Result = None Source: ArrayList = None nearItem: str = None def __init__(self): super().__init__() self.Source = ArrayList() def setCanBeDoneFromFloor(self, value: bool) -> None: self.canBeDoneFromFloor = value def isCanBeDoneFromFloor(self) -> bool: return self.canBeDoneFromFloor def FindIndexOf(self, item: str) -> int: return -1 def getSource(self) -> Source: return self.Source def getNumberOfNeededItems(self) -> int: count = 0 for source in self.Source: if source.items: count += source.count return count def getTimeToMake(self) -> float: return self.TimeToMake def getName(self) -> str: return self.name def getFullType(self) -> str: return f"{self.module}.{self.originalname}" def Load(self, name: str, data: list) -> None: self.name = name # TODO: Translator.getRecipeName self.originalname = name override = False for line in data: line = line.strip() if not line: continue match = re.match(r"([^:]+)\s*:\s*(.+)\s*", line, flags=re.DOTALL | re.M) if not match: self.DoSource(line) else: key, value = match.groups() #key = key.lower() # NOTE ALL THESE KEYS ARE ACTUALLY CASE_SENSITIVE!!!! value = value.strip() if key == "Override": override = value.lower() == 'true' elif key == "AnimNode": self.AnimNode = value elif key == "Prop1": self.Prop1 = value elif key == "Prop2": self.Prop2 = value elif key == "Time": self.TimeToMake = float(value) elif key == "Sound": self.Sound = value elif key == "Result": self.DoResult(value) elif key == "OnTest": self.LuaTest = value elif key == "OnCreate": self.LuaCreate = value elif key == "OnGrab": self.LuaGrab = value elif key.lower() == "needtobelearn": # case insensitive self.setNeedToBeLearn(value.lower() == 'true') elif key.lower() == "category": # case insensitive self.setCategory(value) elif key == "RemoveResultItem": self.removeResultItem = value.lower() == 'true' elif key == "CanBeDoneFromFloor": self.setCanBeDoneFromFloor(value.lower() == 'true') elif key == "NearItem": self.setNearItem(value) elif key == "SkillRequired": self.skillRequired = HashMap() skills = value.split(";") for sk in skills: if not sk: continue sk, val = sk.split("=", 1) self.skillRequired[sk] = int(val) elif key == "OnGiveXP": self.OnGiveXP = value elif key == "Obsolete": if value.lower() == "true": self.module.RecipeMap.remove(self) self.module.RecipesWithDotInName.remove(self) return elif key == "Heat": self.heat = float(value) elif key == "NoBrokenItems": self.NoBrokenItems = value.lower() == 'true' if override: recipe = self.module.getRecipe(name) if recipe and recipe != self: self.module.RecipeMap.remove(self) self.module.RecipesWithDotInName.remove(self) return def DoSource(self, data: str) -> None: source = Source() if '=' in data: data, count = data.split('=') data, count = data.strip(), float(count.strip()) source.count = count if data.startswith("keep"): data = data[5:] source.keep = True if ";" in data: data, count = data.split(';') source.use = float(count) if data.startswith("destroy"): data = data[8:] source.destroy = True if data == 'null': source.items.clear() elif '/' in data: for i in data.split('/'): source.items.add(i) else: source.items.add(data) if data: self.Source.add(source) def DoResult(self, data: str) -> None: result = Result() if '=' in data: data, count = data.split('=') data, count = data.strip(), int(count.strip()) result.count = count if ";" in data: data, count = data.split(';') data, count = data.strip(), int(count.strip()) result.drainableCount = count if '.' in data: result.module, result.type = data.split('.') else: result.type = data self.Result = result def getResult(self) -> Result: return self.Result def getSound(self) -> str: return self.Sound def getOriginalName(self) -> str: return self.originalname def setOriginalName(self, value: str) -> None: self.originalname = value def needToBeLearn(self) -> bool: return self.NeedToBeLearn def setNeedToBeLearn(self, value: bool) -> None: self.NeedToBeLearn = value def getCategory(self) -> str: return self.category def setCategory(self, value: str) -> None: self.category = value def getRequiredSkills(self) -> None: skills = [] if self.skillRequired: for sk in self.skillRequired: # TODO: we need to get the perk from string from PerkFactory #str2 = (PerkFactory.getPerk(PerkFactory.Perks.FromString(str1))).name + " " + + this.skillRequired.get(str1); skills.append("%s %s" % (sk, self.skillRequired[sk])) return ArrayList(*skills) def findSource(self, item: str) -> Source: for source in self.Source: if item in source.items: return source return None def isDestroy(self, item: str) -> Source: try: source = self.findSource(item) return source.destroy except AttributeError: # Todo: should raise a specific exception raise def isKeep(self, item: str) -> Source: try: source = self.findSource(item) return source.keep except AttributeError: # Todo: should raise a specific exception raise def getHeat(self) -> float: return self.heat def noBrokenItems(self) -> bool: return self.NoBrokenItems def getWaterAmountNeeded(self) -> int: source = self.findSource("Water") if not source: return 0 return source.count def getNearItem(self) -> str: return self.nearItem def setNearItem(self, value: str) -> None: self.nearItem = value def isRemoveResultItem(self) -> bool: return self.removeResultItem def setRemoveResultItem(self, value: bool) -> None: self.removeResultItem = value def getAnimNode(self) -> str: return self.AnimNode def setAnimNode(self, value: str) -> None: self.AnimNode = value def getProp1(self) -> str: return self.Prop1 def setProp1(self, value: str) -> None: self.Prop1 = value def getProp2(self) -> str: return self.Prop2 def setProp2(self, value: str) -> None: self.Prop2 = value
class Fixing(BaseScriptObject): Fixer = Fixer # just to match the java structure FixerSkill = FixerSkill # just to match the java structure name: str = None require: ArrayList = None fixers: LinkedList = None globalItem: Fixer = None conditionModifier: float = 1.0 def Load(self, name: str, data: list): self.name = name for line in data: line = line.strip() match = re.match(r"^\s*(\S+)\s*:\s*(.+?)\s*$", line) if not match: continue key, value = match.groups() if key == "Require": for item in value.split(';'): if not item: continue self.addRequiredItem(item.strip()) elif key == "Fixer": if ';' in value: linked = LinkedList() for entry in value.split(';'): if not item: continue item, count = entry.strip().split('=', 1) linked.add(Fixer(item, None, int(count))) if '=' in value.split(";")[0]: item, count = value.split(";")[0].split('=', 1) self.fixers.add(Fixer(item, linked, int(count))) else: self.fixers.add(Fixer(item, linked, 1)) elif '=' in value: item, count = value.split('=', 1) self.fixers.add(Fixer(item, None, int(count))) else: self.fixers.add(Fixer(value, None, 1)) elif key == "GlobalItem": if '=' in value: item, count = value.split('=', 1) self.globalItem = Fixer(item, None, int(count)) else: self.globalItem = Fixer(value, None, 1) elif key == "ConditionModifier": self.conditionModifier = float(value) def getName(self) -> str: return self.name def setName(self, name: str) -> None: self.name = name def addRequiredItem(self, item: str) -> None: if self.require is None: self.require = ArrayList() if item: self.require.add(item) def getFixers(self) -> LinkedList: return self.fixers def getGlobalItem(self) -> Fixer: return self.globalItem def setGlobalItem(self, item: Fixer) -> None: self.globalItem = item def getConditionModifier(self) -> float: return self.conditionModifier def setConditionModifier(self, value: float) -> None: self.conditionModifier = value def usedInFixer(self, item: InventoryItem, character: IsoGameCharacter) -> Fixer: raise NotImplementedError def haveGlobalItem(self, character: IsoGameCharacter) -> InventoryItem: raise NotImplementedError def haveThisFixer(self, character: IsoGameCharacter, fixer: Fixer, item: InventoryItem) -> InventoryItem: raise NotImplementedError def countUses(self, character: IsoGameCharacter, fixer: Fixer, item: InventoryItem) -> int: raise NotImplementedError
def __init__(self, name: str): self.name = name self.items = ArrayList()
def addRequiredItem(self, item: str) -> None: if self.require is None: self.require = ArrayList() if item: self.require.add(item)
def __init__(self): self.scriptsWithVehicles = ArrayList() self.scriptsWithVehicleTemplate = ArrayList()
def __init__(self): self.m_attachments = ArrayList()
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
def __init__(self): self.clips = ArrayList()
class UniqueRecipe(BaseScriptObject): name: str = None baseRecipe: str = None items: ArrayList = None hungerBonus: int = 0 hapinessBonus: int = 0 # not a typo. least not by me boredomBonus: int = 0 def __init__(self, name: str): self.name = name self.items = ArrayList() def Load(self, name, data: list) -> None: for line in data: line = line.strip() if not line: continue match = re.match(r"([^:]+)\s*:\s*(.+)\s*", line, flags=re.DOTALL | re.M) if not match: continue key, value = match.groups() if key == 'baseRecipe': self.baseRecipe = value elif key == 'Item': self.items.add(value) elif key == 'Hunger': self.hungerBonus = int(value) elif key == 'Hapiness': self.hapinessBonus = int(value) elif key == 'Boredom': self.boredomBonus = int(value) def getName(self) -> str: return self.name def setName(self, name: str) -> None: self.name = name def getBaseRecipe(self) -> str: return self.baseRecipe def setBaseRecipe(self, value: str) -> None: self.baseRecipe = value def getHungerBonus(self) -> int: return self.hungerBonus def setHungerBonus(self, value: int) -> None: self.hungerBonus = value def getHapinessBonus(self) -> int: return self.hapinessBonus def setHapinessBonus(self, value: int) -> None: self.hapinessBonus = value def getBoredomBonus(self) -> int: return self.boredomBonus def setBoredomBonus(self, value: int) -> None: self.boredomBonus = value
def __init__(self): self.items = ArrayList()