def save(self): ''' Saves all waypoint information to the 'mcedit_waypoints.dat' file in the world directory ''' if DEBUG: current_frame = inspect.currentframe() outerframe = inspect.getouterframes(current_frame, 2)[1] print "Called by '" + str(outerframe[3]) + "()' in '" + str( outerframe[1].split("\\")[-1]) + "' at line " + str( outerframe[2]) del self.nbt_waypoints["Waypoints"] self.nbt_waypoints["Waypoints"] = nbt.TAG_List() for waypoint in self.waypoints.keys(): if waypoint.split()[0] == "Empty": continue way = nbt.TAG_Compound() way["Name"] = nbt.TAG_String(waypoint.split()[0]) way["Dimension"] = nbt.TAG_Int(self.waypoints[waypoint][5]) coords = nbt.TAG_List() coords.append(nbt.TAG_Float(self.waypoints[waypoint][0])) coords.append(nbt.TAG_Float(self.waypoints[waypoint][1])) coords.append(nbt.TAG_Float(self.waypoints[waypoint][2])) rot = nbt.TAG_List() rot.append(nbt.TAG_Float(self.waypoints[waypoint][3])) rot.append(nbt.TAG_Float(self.waypoints[waypoint][4])) way["Coordinates"] = coords way["Rotation"] = rot self.nbt_waypoints["Waypoints"].append(way) self.nbt_waypoints.save( os.path.join(self.worldDirectory, u"mcedit_waypoints.dat"))
def saveLastPosition(self, mainViewport, dimension): ''' Saves the final position of the camera viewport when the world is closed or MCEdit is exited :param mainViewport: The reference to viewport object :param dimension: The dimension the camera viewport is currently in :type dimension: int ''' log.info('Saving last position.') if "LastPosition" in self.nbt_waypoints: del self.nbt_waypoints["LastPosition"] topTag = nbt.TAG_Compound() topTag["Dimension"] = nbt.TAG_Int(dimension) pos = nbt.TAG_List() pos.append(nbt.TAG_Float(mainViewport.cameraPosition[0])) pos.append(nbt.TAG_Float(mainViewport.cameraPosition[1])) pos.append(nbt.TAG_Float(mainViewport.cameraPosition[2])) topTag["Coordinates"] = pos rot = nbt.TAG_List() rot.append(nbt.TAG_Float(mainViewport.yaw)) rot.append(nbt.TAG_Float(mainViewport.pitch)) topTag["Rotation"] = rot self.nbt_waypoints["LastPosition"] = topTag self.save()
def newPlayer(self): playerTag = nbt.TAG_Compound() playerTag['Air'] = nbt.TAG_Short(300) playerTag['AttackTime'] = nbt.TAG_Short(0) playerTag['DeathTime'] = nbt.TAG_Short(0) playerTag['Fire'] = nbt.TAG_Short(-20) playerTag['Health'] = nbt.TAG_Short(20) playerTag['HurtTime'] = nbt.TAG_Short(0) playerTag['Score'] = nbt.TAG_Int(0) playerTag['FallDistance'] = nbt.TAG_Float(0) playerTag['OnGround'] = nbt.TAG_Byte(0) playerTag["Inventory"] = nbt.TAG_List() playerTag['Motion'] = nbt.TAG_List([nbt.TAG_Double(0) for i in range(3)]) spawn = self.level.playerSpawnPosition() spawnX = spawn[0] spawnZ = spawn[2] blocks = [self.level.blockAt(spawnX, i, spawnZ) for i in range(self.level.Height)] i = self.level.Height done = False for index, b in enumerate(reversed(blocks)): if b != 0 and not done: i = index done = True spawnY = self.level.Height - i playerTag['Pos'] = nbt.TAG_List([nbt.TAG_Double([spawnX, spawnY, spawnZ][i]) for i in range(3)]) playerTag['Rotation'] = nbt.TAG_List([nbt.TAG_Float(0), nbt.TAG_Float(0)]) return playerTag
def convert(tag): out = None if (tag.type is parse.TAG_Byte): out = nbt.TAG_Byte(value=tag.data, name=tag.name) elif (tag.type is parse.TAG_Byte_Array): out = nbt.TAG_Byte_Array(value=fromstring(tag.data), name=tag.name) elif (tag.type is parse.TAG_Double): out = nbt.TAG_Double(value=tag.data, name=tag.name) elif (tag.type is parse.TAG_Float): out = nbt.TAG_Float(value=tag.data, name=tag.name) elif (tag.type is parse.TAG_Int): out = nbt.TAG_Int(value=tag.data, name=tag.name) elif (tag.type is parse.TAG_Int_Array): out = nbt.TAG_Int_Array(value=tag.data, name=tag.name) elif (tag.type is parse.TAG_Long): out = nbt.TAG_Long(value=tag.data, name=tag.name) elif (tag.type is parse.TAG_Short): out = nbt.TAG_Short(value=tag.data, name=tag.name) elif (tag.type is parse.TAG_String): out = nbt.TAG_String(value=tag.data, name=tag.name) # Recursives elif (tag.type is parse.TAG_Compound): out = nbt.TAG_Compound(name=tag.name) for item in tag.data: temp = convert(item) if (temp is not None): out[temp.name] = temp elif (tag.type is parse.TAG_List): out = nbt.TAG_List(name=tag.name) for item in tag.data[1]: temp = convert(dummyNBTyaml(tag.data[0], item)) if (temp is not None): out.append(temp) return out
def enchant_tags(item, level, debug=False): tags = nbt.TAG_List() for ench in enchant(item, level, debug): e = nbt.TAG_Compound() e['id'] = nbt.TAG_Short(ench['id']) e['lvl'] = nbt.TAG_Short(ench['lvl']) tags.append(e) return tags
def __init__(self, worldDir=None, editor=None): self.worldDirectory = worldDir self.waypoints = {} self.waypoint_names = [] self.editor = editor self.nbt_waypoints = nbt.TAG_Compound() self.nbt_waypoints["Waypoints"] = nbt.TAG_List() self.load()
def save(self): del self.nbt_waypoints["Waypoints"] self.nbt_waypoints["Waypoints"] = nbt.TAG_List() for waypoint in self.waypoints.keys(): way = nbt.TAG_Compound() way["Name"] = nbt.TAG_String(waypoint.split()[0]) way["Dimension"] = nbt.TAG_Int(self.waypoints[waypoint][5]) coords = nbt.TAG_List() coords.append(nbt.TAG_Float(self.waypoints[waypoint][0])) coords.append(nbt.TAG_Float(self.waypoints[waypoint][1])) coords.append(nbt.TAG_Float(self.waypoints[waypoint][2])) rot = nbt.TAG_List() rot.append(nbt.TAG_Float(self.waypoints[waypoint][3])) rot.append(nbt.TAG_Float(self.waypoints[waypoint][4])) way["Coordinates"] = coords way["Rotation"] = rot self.nbt_waypoints["Waypoints"].append(way) self.nbt_waypoints.save(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat"))
def loadrandbooktext(self): item = nbt.TAG_Compound() item['id'] = nbt.TAG_String('minecraft:written_book') # No books? Give a book and quill instead if len(self.booklist) == 0: item['id'] = nbt.TAG_String('minecraft:writable_book') return item # Open the book's text file bookfile = open(os.path.join(self.book_path, random.choice(self.booklist))) bookdata = bookfile.read().splitlines() bookfile.close() # Create NBT tag item['tag'] = nbt.TAG_Compound() # Prevent unusual characters from being used with filter item['tag']['author'] = nbt.TAG_String( filter( lambda x: x in self.valid_characters, bookdata.pop(0))) title = filter(lambda x: x in self.valid_characters,bookdata.pop(0)) item['tag']['title'] = nbt.TAG_String(title[:32]) item['tag']["pages"] = nbt.TAG_List() # Slice the pages at 50 and the page text at 256 to match minecraft # limits for p in bookdata[:50]: page = filter(lambda x: x in self.valid_characters, p) item['tag']["pages"].append(nbt.TAG_String(encodeJSONtext(page[:256]))) # Give the book an edition ed = topheavy_random(0, 9) item['tag']['display'] = nbt.TAG_Compound() item['tag']['display']['Lore'] = nbt.TAG_List() item['tag']['display']['Lore'].append( nbt.TAG_String( converttoordinal(ed+1) + ' Edition')) if (ed == 0): item['tag']['generation'] = nbt.TAG_Int(0) elif (ed == 1): item['tag']['generation'] = nbt.TAG_Int(1) else: item['tag']['generation'] = nbt.TAG_Int(2) return item
def loadrandbooktext(self): item = nbt.TAG_Compound() item['id'] = nbt.TAG_Short(387) # No books? Give a book and quill instead if len(self.booklist) == 0: item['id'] = nbt.TAG_Short(386) return item # Open the book's text file bookfile = open( os.path.join(self.book_path, random.choice(self.booklist))) bookdata = bookfile.read().splitlines() bookfile.close() # Create NBT tag item['tag'] = nbt.TAG_Compound() item['tag']['author'] = nbt.TAG_String( filter(lambda x: x in self.valid_characters, bookdata.pop(0))) # Prevent unusual characters from being used item['tag']['title'] = nbt.TAG_String( filter(lambda x: x in self.valid_characters, bookdata.pop(0))) item['tag']["pages"] = nbt.TAG_List() # Slice the pages at 50 and the page text at 256 to match minecraft # limits for p in bookdata[:50]: page = filter(lambda x: x in self.valid_characters, p) page = self.ConvertEscapeChars(page) # Escape quote charcaters page = page.replace('"', '\\"') item['tag']["pages"].append(nbt.TAG_String('"%s"' % (page[:256]))) # Give the book an edition ed = topheavy_random(0, 9) item['tag']['display'] = nbt.TAG_Compound() item['tag']['display']['Lore'] = nbt.TAG_List() item['tag']['display']['Lore'].append( nbt.TAG_String(self.ed_dict[ed] + ' Edition')) if (ed == 0): item['tag']['generation'] = nbt.TAG_Int(0) elif (ed == 1): item['tag']['generation'] = nbt.TAG_Int(1) else: item['tag']['generation'] = nbt.TAG_Int(2) return item
def saveLastPosition(self, mainViewport, dimension): if "LastPosition" in self.nbt_waypoints: del self.nbt_waypoints["LastPosition"] topTag = nbt.TAG_Compound() topTag["Dimension"] = nbt.TAG_Int(dimension) pos = nbt.TAG_List() pos.append(nbt.TAG_Float(mainViewport.cameraPosition[0])) pos.append(nbt.TAG_Float(mainViewport.cameraPosition[1])) pos.append(nbt.TAG_Float(mainViewport.cameraPosition[2])) topTag["Coordinates"] = pos rot = nbt.TAG_List() rot.append(nbt.TAG_Float(mainViewport.yaw)) rot.append(nbt.TAG_Float(mainViewport.pitch)) topTag["Rotation"] = rot self.nbt_waypoints["LastPosition"] = topTag self.save()
def add_painting(self, painting_file): src = os.path.join(self.painting_path, painting_file + '.dat') painting_file_hash = hashlib.md5(open(src, 'r').read()).digest() # Look up file in hashtable if painting_file_hash in self.maphash: mapid = self.maphash[painting_file_hash] else: # Initialize the map count if it doesn't exist. if 'map' not in self.idcounts: self.idcounts['map'] = nbt.TAG_Short(-1) # Increment and return id self.idcounts['map'].value += 1 mapid = self.idcounts['map'].value # Copy the map to the data dir dest = os.path.join(self.mapstore, 'map_%d.dat' % (mapid)) try: shutil.copy(src, dest) except: sys.exit('Error when placing painting in map directory.') self.maphash[painting_file_hash] = mapid # Update hashtable self.update_mapstore() # Create map item tag item = nbt.TAG_Compound() item['id'] = nbt.TAG_Short(358) item['Damage'] = nbt.TAG_Short(mapid) item['Count'] = nbt.TAG_Byte(1) # Fetch the lore text for this map lorefile = open( os.path.join( self.painting_path, painting_file + '.txt')) loredata = lorefile.read().splitlines() lorefile.close() # Create NBT tag valid_characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ " item['tag'] = nbt.TAG_Compound() item['tag']['display'] = nbt.TAG_Compound() item['tag']['display']['Name'] = nbt.TAG_String( filter( lambda x: x in valid_characters, loredata.pop(0))) item['tag']['display']['Lore'] = nbt.TAG_List() # Slice at 5 lines of 50 chars each for p in loredata[:5]: line = filter(lambda x: x in valid_characters, p) item['tag']['display']['Lore'].append(nbt.TAG_String(line[:50])) return item
def load(self): if self.editor.level is None: return if not os.path.exists(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat")): self.nbt_waypoints = nbt.TAG_Compound() self.nbt_waypoints["Waypoints"] = nbt.TAG_List() self.build() else: self.nbt_waypoints = nbt.load(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat")) self.build() if not (len(self.waypoints) > 0): self.waypoints["Empty"] = [0,0,0,0,0,0] if "LastPosition" in self.nbt_waypoints: self.editor.gotoLastWaypoint(self.nbt_waypoints["LastPosition"])
def save(self): ''' Saves all waypoint information to the 'mcedit_waypoints.dat' file in the world directory ''' del self.nbt_waypoints["Waypoints"] self.nbt_waypoints["Waypoints"] = nbt.TAG_List() for waypoint in self.waypoints.keys(): if waypoint.split()[0] == "Empty": continue way = nbt.TAG_Compound() way["Name"] = nbt.TAG_String(waypoint.split()[0]) way["Dimension"] = nbt.TAG_Int(self.waypoints[waypoint][5]) coords = nbt.TAG_List() coords.append(nbt.TAG_Float(self.waypoints[waypoint][0])) coords.append(nbt.TAG_Float(self.waypoints[waypoint][1])) coords.append(nbt.TAG_Float(self.waypoints[waypoint][2])) rot = nbt.TAG_List() rot.append(nbt.TAG_Float(self.waypoints[waypoint][3])) rot.append(nbt.TAG_Float(self.waypoints[waypoint][4])) way["Coordinates"] = coords way["Rotation"] = rot self.nbt_waypoints["Waypoints"].append(way) self.nbt_waypoints.save( os.path.join(self.worldDirectory, u"mcedit_waypoints.dat"))
def parse_nbt(node, params={}): """Recursivly build nbt datastructure from xml.""" if 'name' in node.attrib: name = node.attrib['name'] else: name = '' if node.text and node.text != '': text = replace_params(node.text, params) else: text = '' if node.tag == 'Compound': values = [] # list of other tags for child in node: values.append(parse_nbt(child, params)) return nbt.TAG_Compound(values, name) if node.tag == 'List': values = [] # list of other tags for child in node: values.append(parse_nbt(child, params)) return nbt.TAG_List(values, name) elif node.tag == 'String': return nbt.TAG_String(text, name) elif node.tag == 'Int': return nbt.TAG_Int(text, name) elif node.tag == 'Byte': return nbt.TAG_Byte(text, name) elif node.tag == 'Short': return nbt.TAG_Short(text, name) elif node.tag == 'Long': return nbt.TAG_Long(text, name) elif node.tag == 'Float': return nbt.TAG_Float(text, name) elif node.tag == 'Double': return nbt.TAG_Double(text, name) else: raise 'Unsupported'
def testModify(self): level = self.testCreate() # Most of the value types work as expected. Here, we replace the entire tag with a TAG_String level["About"]["Author"] = nbt.TAG_String("YARRR~!") # Because the tag type usually doesn't change, # we can replace the string tag's value instead of replacing the entire tag. level["About"]["Author"].value = "Stew Pickles" # Remove members of a TAG_Compound using del, similar to a python dict. del (level["About"]) # Replace all of the wood blocks with gold using a boolean index array blocks = level["Map"]["Blocks"].value blocks[blocks == 5] = 41 level["Entities"][0] = nbt.TAG_Compound([nbt.TAG_String("Creeper", "id"), nbt.TAG_List([nbt.TAG_Double(d) for d in (1, 1, 1)], "Pos")])
def buildItemTag(self,i): # If it's a binary NBT file, just load it if i.file != '': item_tag = tagsfromfile(i.file) # Set the slot and count if i.slot != None: item_tag['Slot'] = nbt.TAG_Byte(i.slot) item_tag['Count'] = nbt.TAG_Byte(i.count) return item_tag # Otherwise, we will build the compound item_tag = nbt.TAG_Compound() # Standard stuff item_tag['id'] = nbt.TAG_String(i.id) item_tag['Damage'] = nbt.TAG_Short(i.damage) # Enchantments if len(i.enchantments) > 0: item_tag['tag'] = nbt.TAG_Compound() if (i.flag == 'ENCH_BOOK'): item_tag['tag']['StoredEnchantments'] = nbt.TAG_List() elist = item_tag['tag']['StoredEnchantments'] else: item_tag['tag']['ench'] = nbt.TAG_List() elist = item_tag['tag']['ench'] for e in i.enchantments: e_tag = nbt.TAG_Compound() e_tag['id'] = nbt.TAG_Short(e['id']) e_tag['lvl'] = nbt.TAG_Short(e['lvl']) elist.append(e_tag) # Custom Potion Effects if i.p_effect != '': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() # Is this a 'basic' potion i.e. no custom effects list if (i.p_effect.replace(',','').replace('-','').isdigit()): item_tag['tag']['CustomPotionEffects'] = nbt.TAG_List() elist = item_tag['tag']['CustomPotionEffects'] for e in i.p_effect.split(','): id, amp, dur = e.split('-') e_tag = nbt.TAG_Compound() e_tag['Id'] = nbt.TAG_Byte(id) e_tag['Amplifier'] = nbt.TAG_Byte(amp) e_tag['Duration'] = nbt.TAG_Int(dur) # Flags for hiding potion particles if i.flag == 'HIDE_PARTICLES' or i.flag == 'HIDE_ALL': e_tag['ShowParticles'] = nbt.TAG_Byte(0) elist.append(e_tag) # If we have a flagparam, use it for the potion's colour if i.flagparam != '': item_tag['tag']['CustomPotionColor'] = nbt.TAG_Int(i.flagparam) else: item_tag['tag']['Potion'] = nbt.TAG_String(i.p_effect) # For basic potions there is no need for a custom name i.customname = '' # Flag for hiding additional text if i.flag == 'HIDE_EFFECTS' or i.flag == 'HIDE_ALL': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['HideFlags'] = nbt.TAG_Int(63) # 63 = Hide everything # Naming if i.customname != '': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['display'] = nbt.TAG_Compound() item_tag['tag']['display']['Name'] = nbt.TAG_String(i.customname) # Lore Text if i.lore != '' or i.flag == 'FORTUNE': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() try: item_tag['tag']['display'] except: item_tag['tag']['display'] = nbt.TAG_Compound() item_tag['tag']['display']['Lore'] = nbt.TAG_List() if i.flag == 'FORTUNE': item_tag['tag']['display'][ 'Name'] = nbt.TAG_String('Fortune Cookie') i.lore = random_line_from_file(cfg.file_fortunes, "...in bed") loredata = textwrap.wrap(self.ConvertEscapeChars(i.lore), 30) for loretext in loredata[:10]: item_tag['tag']['display']['Lore'].append( nbt.TAG_String(loretext)) else: loredata = i.lore.split(':') for loretext in loredata[:10]: item_tag['tag']['display']['Lore'].append( nbt.TAG_String(self.ConvertEscapeChars(loretext[:50]))) # Flag: Dyed item if (i.flag == 'DYED'): try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() try: item_tag['tag']['display'] except: item_tag['tag']['display'] = nbt.TAG_Compound() if i.flagparam == '': item_tag['tag']['display']['color'] = nbt.TAG_Int( random.randint( 0, 16777215)) else: item_tag['tag']['display']['color'] = nbt.TAG_Int(i.flagparam) # Flags: Random Book or Painting elif (i.flag == 'WRITTEN'): item_tag = self.loadrandbooktext() elif (i.flag == 'PAINT'): item_tag = self.loadrandpainting() # Flag: Paint banner or shield with dungeon flag design elif (i.flag == 'DUNGEON_FLAG'): try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['BlockEntityTag'] = nbt.TAG_Compound() item_tag['tag']['BlockEntityTag']['Base'] = nbt.TAG_Int(self.flag['Base']) item_tag['tag']['BlockEntityTag']['Patterns'] = nbt.TAG_List() for p in self.flag['Patterns']: q = nbt.TAG_Compound() q['Color'] = nbt.TAG_Int(p[0]) q['Pattern'] = nbt.TAG_String(p[1]) item_tag['tag']['BlockEntityTag']['Patterns'].append(q) # Set the damage to match the base colour. This is a special case for # banner items in chests if i.id == 'minecraft:banner': item_tag['Damage'] = nbt.TAG_Short(self.flag['Base']) # Flag: Give item mob entity tag (spawn eggs) elif (i.flag.startswith('ENTITYTAG:')): try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['EntityTag'] = nbt.TAG_Compound() # ENTITYTAG: is 10 characters, we want everything afterwards item_tag['tag']['EntityTag']['id'] = nbt.TAG_String(i.flag[10:]) # Flag: Give random recipie from recipes.txt elif (i.flag == 'RECIPE'): try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['Recipes'] = nbt.TAG_List() r = random_line_from_file(cfg.file_recipes, "minecraft:crafting_table") item_tag['tag']['Recipes'].append(nbt.TAG_String(r)) # Set the slot and count if i.slot != None: item_tag['Slot'] = nbt.TAG_Byte(i.slot) item_tag['Count'] = nbt.TAG_Byte(i.count) return item_tag
def buildItemTag(self, i): # If it's a binary NBT file, just load it if i.file != '': item_tag = nbt.load(i.file) # Set the slot and count if i.slot != None: item_tag['Slot'] = nbt.TAG_Byte(i.slot) item_tag['Count'] = nbt.TAG_Byte(i.count) return item_tag # Otherwise, we will build the compound item_tag = nbt.TAG_Compound() # Standard stuff item_tag['id'] = nbt.TAG_Short(i.id) item_tag['Damage'] = nbt.TAG_Short(i.damage) # Enchantments if len(i.enchantments) > 0: item_tag['tag'] = nbt.TAG_Compound() if (i.flag == 'ENCH_BOOK'): item_tag['tag']['StoredEnchantments'] = nbt.TAG_List() elist = item_tag['tag']['StoredEnchantments'] else: item_tag['tag']['ench'] = nbt.TAG_List() elist = item_tag['tag']['ench'] for e in i.enchantments: e_tag = nbt.TAG_Compound() e_tag['id'] = nbt.TAG_Short(e['id']) e_tag['lvl'] = nbt.TAG_Short(e['lvl']) elist.append(e_tag) # Custom Potion Effects if i.p_effect != '': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['CustomPotionEffects'] = nbt.TAG_List() elist = item_tag['tag']['CustomPotionEffects'] for e in i.p_effect.split(','): id, amp, dur = e.split('-') e_tag = nbt.TAG_Compound() e_tag['Id'] = nbt.TAG_Byte(id) e_tag['Amplifier'] = nbt.TAG_Byte(amp) e_tag['Duration'] = nbt.TAG_Int(dur) # Flags for hiding potion particles if i.flag == 'HIDE_PARTICLES' or i.flag == 'HIDE_ALL': e_tag['ShowParticles'] = nbt.TAG_Byte(0) elist.append(e_tag) # Flag for hiding additional text if i.flag == 'HIDE_EFFECTS' or i.flag == 'HIDE_ALL': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['HideFlags'] = nbt.TAG_Int( 63) # 63 = Hide everything # Naming if i.customname != '': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['display'] = nbt.TAG_Compound() item_tag['tag']['display']['Name'] = nbt.TAG_String(i.customname) # Lore Text if i.lore != '' or i.flag == 'FORTUNE': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() try: item_tag['tag']['display'] except: item_tag['tag']['display'] = nbt.TAG_Compound() item_tag['tag']['display']['Lore'] = nbt.TAG_List() if i.flag == 'FORTUNE': item_tag['tag']['display']['Name'] = nbt.TAG_String( 'Fortune Cookie') i.lore = self.loadrandfortune() loredata = textwrap.wrap(self.ConvertEscapeChars(i.lore), 30) for loretext in loredata[:10]: item_tag['tag']['display']['Lore'].append( nbt.TAG_String(loretext)) else: loredata = i.lore.split(':') for loretext in loredata[:10]: item_tag['tag']['display']['Lore'].append( nbt.TAG_String(self.ConvertEscapeChars(loretext[:50]))) # Dyed if (i.flag == 'DYED'): try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() try: item_tag['tag']['display'] except: item_tag['tag']['display'] = nbt.TAG_Compound() if i.flagparam == '': item_tag['tag']['display']['color'] = nbt.TAG_Int( random.randint(0, 16777215)) else: item_tag['tag']['display']['color'] = nbt.TAG_Int(i.flagparam) # special cases for written books and paintings if (i.flag == 'WRITTEN'): item_tag = self.loadrandbooktext() if (i.flag == 'PAINT'): item_tag = self.loadrandpainting() # Set the slot and count if i.slot != None: item_tag['Slot'] = nbt.TAG_Byte(i.slot) item_tag['Count'] = nbt.TAG_Byte(i.count) return item_tag
def testList(): tag = nbt.TAG_List() tag.append(nbt.TAG_Int(258)) del tag[0]
def testCreate(): "Create an indev level." # The root of an NBT file is always a TAG_Compound. level = nbt.TAG_Compound(name="MinecraftLevel") # Subtags of a TAG_Compound are automatically named when you use the [] operator. level["About"] = nbt.TAG_Compound() level["About"]["Author"] = nbt.TAG_String("codewarrior") level["About"]["CreatedOn"] = nbt.TAG_Long(time.time()) level["Environment"] = nbt.TAG_Compound() level["Environment"]["SkyBrightness"] = nbt.TAG_Byte(16) level["Environment"]["SurroundingWaterHeight"] = nbt.TAG_Short(32) level["Environment"]["FogColor"] = nbt.TAG_Int(0xcccccc) entity = nbt.TAG_Compound() entity["id"] = nbt.TAG_String("Creeper") entity["Pos"] = nbt.TAG_List([nbt.TAG_Float(d) for d in (32.5, 64.0, 33.3)]) level["Entities"] = nbt.TAG_List([entity]) # You can also create and name a tag before adding it to the compound. spawn = nbt.TAG_List((nbt.TAG_Short(100), nbt.TAG_Short(45), nbt.TAG_Short(55))) spawn.name = "Spawn" mapTag = nbt.TAG_Compound() mapTag.add(spawn) mapTag.name = "Map" level.add(mapTag) mapTag2 = nbt.TAG_Compound([spawn]) mapTag2.name = "Map" # I think it looks more familiar with [] syntax. l, w, h = 128, 128, 128 mapTag["Height"] = nbt.TAG_Short(h) # y dimension mapTag["Length"] = nbt.TAG_Short(l) # z dimension mapTag["Width"] = nbt.TAG_Short(w) # x dimension # Byte arrays are stored as numpy.uint8 arrays. mapTag["Blocks"] = nbt.TAG_Byte_Array() mapTag["Blocks"].value = numpy.zeros(l * w * h, dtype=numpy.uint8) # create lots of air! # The blocks array is indexed (y,z,x) for indev levels, so reshape the blocks mapTag["Blocks"].value.shape = (h, l, w) # Replace the bottom layer of the indev level with wood mapTag["Blocks"].value[0, :, :] = 5 # This is a great way to learn the power of numpy array slicing and indexing. mapTag["Data"] = nbt.TAG_Byte_Array() mapTag["Data"].value = numpy.zeros(l * w * h, dtype=numpy.uint8) # Save a few more tag types for completeness level["ShortArray"] = nbt.TAG_Short_Array(numpy.zeros((16, 16), dtype='uint16')) level["IntArray"] = nbt.TAG_Int_Array(numpy.zeros((16, 16), dtype='uint32')) level["Float"] = nbt.TAG_Float(0.3) return level
def placechests(self, level=0): # Place chests, create clue books and keys _directions = ( ('Wander {D} til ye find {L}, which be the next step in thy search.', 1), ('Walk as the crow flies {D} without rest until ye find {L}.', 1), ('Travel towards the {D} to {L}, then follow the next step.', 1), ('I hid the next step at {L}, {D} of here.', 1), ('Find {L} to the {D}, and be wary of zombies as ye travel.', 1), ('Now walk ye {D}, and do keep thy eyes peeled for {L}.', 1), ('To the {D} there do lie {L}. Thy next step be to find it.', 1), ('There do lie {L} to the {D}, and that is where ye must needs go next.', 1), ('Turn ye to the {D}, and march forrard \'til ye find {L}.', 1), ) # Iterate through the landmarks from the end back. # Generate a clue book and possible key as we go as extra chest loot. # At each location, randomly either make a chest and store items or # continue one. fromstep = 1 tostep = 1 pages = [] pages.append(self.dungeon_name) # If necessary, we create a key to lock the chests with if cfg.th_locked is True: keyname = self.keyName() print "Creating key: %s" % (keyname) chestkey = nbt.TAG_Compound() chestkey['Count'] = nbt.TAG_Byte(1) chestkey['id'] = nbt.TAG_String('minecraft:stick') # ID 280 chestkey['tag'] = nbt.TAG_Compound() chestkey['tag']['Unbreakable'] = nbt.TAG_Byte(1) chestkey['tag']['display'] = nbt.TAG_Compound() chestkey['tag']['display']['Name'] = nbt.TAG_String(keyname) chestkey['tag']['display']['Lore'] = nbt.TAG_List() chestkey['tag']['display']['Lore'].append( nbt.TAG_String('"Key found with treasure map"')) else: keyname = None # fromstep = step where we're placing the clue chest # tostep = step we are calculating clue for relative to tostep-1 # There are 1-based but the landmarks[] array is 0-based. # If we place an intermediate chest, fromstep is changed else stays as 1 self.pm.init(self.steps, label='Placing chests:') while tostep < self.steps: self.pm.update_left(self.steps - tostep) tostep += 1 if self.args.debug: print 'Processing step %d' % (tostep) if self.landmarks[tostep - 2].pos.z < self.landmarks[tostep - 1].pos.z: direction = 'South' elif self.landmarks[tostep - 2].pos.z > self.landmarks[tostep - 1].pos.z: direction = 'North' else: direction = '' if self.landmarks[tostep - 2].pos.x < self.landmarks[tostep - 1].pos.x: direction = '%sEast' % (direction) elif self.landmarks[tostep - 2].pos.x > self.landmarks[tostep - 1].pos.x: direction = '%sWest' % (direction) landmark_name = self.landmarks[tostep - 1].describe() p = weighted_choice(_directions).format(D=direction, L=landmark_name) if self.args.debug: print "%d: %d, %d, %d\n %s" % ( tostep - 1, self.landmarks[tostep - 1].pos.x, self.landmarks[tostep - 1].pos.y, self.landmarks[tostep - 1].pos.z, p) pages.append(p) if tostep == self.steps: break if random.randint(1, 100) > cfg.th_intermediate: if random.randint(1, 100) < cfg.th_bonus: if self.args.debug: print "Adding an intermediate treasure chest" self.landmarks[tostep - 1].addcluechest( tier=int(tostep / cfg.th_multiplier)) continue # save book and restart self.landmarks[tostep - 1].addchest(name=self.dungeon_name, tier=int(tostep / cfg.th_multiplier), locked=keyname) if self.args.debug: print 'Placed an intermediate chest at step %d!' % (tostep) print 'Location: %s' % (self.landmarks[tostep - 1].chestlocdesc()) pages.append('When ye reach this place, seek ye another clue %s.' % (self.landmarks[tostep - 1].chestlocdesc())) if cfg.th_locked is True: pages.append( 'But take ye heed -- tis only %s as can open the chest.' % (keyname)) cluebook_tag = nbt.TAG_Compound() cluebook_tag['title'] = nbt.TAG_String(self.dungeon_name) cluebook_tag['author'] = nbt.TAG_String(self.owner) cluebook_tag['pages'] = nbt.TAG_List() for p in pages: cluebook_tag['pages'].append(nbt.TAG_String('"%s"' % (p))) cluebook = nbt.TAG_Compound() cluebook['Count'] = nbt.TAG_Byte(1) cluebook['id'] = nbt.TAG_Short( 387) # change to String minecraft:written_book cluebook['Damage'] = nbt.TAG_Short(0) cluebook['tag'] = cluebook_tag # write clue for this stage if fromstep == 1: self.landmarks[fromstep - 1].addcluechest( name=self.dungeon_name, tier=0) self.landmarks[fromstep - 1].addcluechestitem_tag(cluebook) if cfg.th_locked is True: self.landmarks[fromstep - 1].addcluechestitem_tag(chestkey) else: self.landmarks[fromstep - 1].addchestitem_tag(cluebook) if self.args.debug: print 'Placed a clue chest at step %d!' % (fromstep) fromstep = tostep pages = [] pages.append(self.dungeon_name) # write treasure self.landmarks[tostep - 1].addchest(name=self.dungeon_name, tier=int(tostep / cfg.th_multiplier), locked=keyname) if self.args.debug: print 'Placed a treasure chest at step %d, tier %d!' % ( tostep, int(tostep / cfg.th_multiplier)) print 'Location: %s' % (self.landmarks[tostep - 1].chestlocdesc()) pages.append( 'Now that ye have reached thy destination, ye may find the treasure %s.' % (self.landmarks[tostep - 1].chestlocdesc())) if cfg.th_locked is True: pages.append( 'Take heed! For \'tis only %s that can open the chest that holds my treasure.' % (keyname)) cluebook_tag = nbt.TAG_Compound() cluebook_tag['title'] = nbt.TAG_String(self.dungeon_name) cluebook_tag['author'] = nbt.TAG_String(self.owner) cluebook_tag['pages'] = nbt.TAG_List() for p in pages: cluebook_tag['pages'].append(nbt.TAG_String('"%s"' % (p))) cluebook = nbt.TAG_Compound() cluebook['Count'] = nbt.TAG_Byte(1) cluebook['id'] = nbt.TAG_Short(387) cluebook['Damage'] = nbt.TAG_Short(0) cluebook['tag'] = cluebook_tag # write clue for this stage if fromstep == 1: self.landmarks[fromstep - 1].addcluechest(name=self.dungeon_name, tier=0) self.landmarks[fromstep - 1].addcluechestitem_tag(cluebook) if cfg.th_locked is True: self.landmarks[fromstep - 1].addcluechestitem_tag(chestkey) else: self.landmarks[fromstep - 1].addchestitem_tag(cluebook) if self.args.debug: print 'Placed a clue chest at step %d!' % (fromstep) self.pm.set_complete()