def Load(): print 'Reading loot tables...' global _maxtier while (cfg.parser.has_section('tier%d' % (_maxtier + 1))): _maxtier += 1 tiername = 'tier%d' % (_maxtier) # print 'Reading loot table for:',tiername loots = cfg.parser.items(tiername) _master_loot[tiername] = {} thistable = _master_loot[tiername] num = 0 for line in loots: try: chance, minmax, enchant = [ x.strip() for x in line[1].split(',') ] minimum = minmax.split('-')[0] maximum = minmax.split('-')[-1] except: print 'WARNING: Cannot parse loot table entry around line:' print ' {}: {} (skipping...)'.format(line[0], line[1]) continue ilist = [] for i in line[0].split(','): thisitem = items.byName(i.strip()) if thisitem is None: print 'ERROR: Tried to reference loot that does not exist.' sys.exit() ilist.append(items.byName(i.strip())) thistable[num] = dict([('item', ilist), ('chance', int(chance)), ('min', int(minimum)), ('max', int(maximum)), ('ench', enchant)]) num += 1
def stringToLoot(self, inloot): if inloot == None: return None loot = inloot.lower().split(',') i = random.choice(loot[0].split('/')) item = items.byName(i) if item == None: sys.exit('%s not found' % i) if len(loot) < 2: count = 1 else: count = int(loot[1]) if len(loot) < 3: enchantments = [] if item.name.startswith('magic_'): ench_level = 0 if len(item.ench) > 0: for e in item.ench.split(','): k = int(e.split('-')[0]) v = int(e.split('-')[-1]) enchantments.append(dict({'id': k, 'lvl': v})) else: enchantments = list(loottable.enchant(item.name, int(loot[2]))) return loottable.Loot(0, count, item.value, item.data, enchantments, item.p_effect, item.customname, item.flag, item.flagparam, item.lore, item.file)
def stringToLoot(self,inloot): if inloot == None: return None loot = inloot.lower().split(',') i = random.choice(loot[0].split('/')) item = items.byName(i) if item == None: sys.exit('%s not found'% i) if len(loot) < 2: count = 1 else: count = int(loot[1]) if len(loot) < 3: enchantments = [] if item.name.startswith('magic_'): ench_level = 0 if len(item.ench) > 0: for e in item.ench.split(','): k = int(e.split('-')[0]) v = int(e.split('-')[-1]) enchantments.append(dict({'id': k, 'lvl': v})) else: enchantments = list(loottable.enchant(item.name, int(loot[2]))) return loottable.Loot(0, count, item.value, item.data, enchantments, item.p_effect, item.customname, item.flag, item.flagparam, item.lore, item.file)
def Load (): print 'Reading loot tables...' global _maxtier while (cfg.parser.has_section('tier%d'%(_maxtier+1))): _maxtier += 1 tiername = 'tier%d'%(_maxtier) #print 'Reading loot table for:',tiername loots = cfg.parser.items(tiername) _master_loot[tiername] = {} thistable = _master_loot[tiername] num = 0 for line in loots: chance, minmax, enchant = [x.strip() for x in line[1].split(',')] minimum = minmax.split('-')[0] maximum = minmax.split('-')[-1] ilist = [] for i in line[0].split(','): ilist.append(items.byName(i.strip())) thistable[num] = dict([ ('item', ilist), ('chance', int(chance)), ('min', int(minimum)), ('max', int(maximum)), ('ench', enchant) ]) num += 1
def Load(): print "Reading loot tables..." global _maxtier while cfg.parser.has_section("tier%d" % (_maxtier + 1)): _maxtier += 1 tiername = "tier%d" % (_maxtier) # print 'Reading loot table for:',tiername loots = cfg.parser.items(tiername) _master_loot[tiername] = {} thistable = _master_loot[tiername] num = 0 for line in loots: chance, minmax, enchant = [x.strip() for x in line[1].split(",")] minimum = minmax.split("-")[0] maximum = minmax.split("-")[-1] ilist = [] for i in line[0].split(","): ilist.append(items.byName(i.strip())) thistable[num] = dict( [ ("item", ilist), ("chance", int(chance)), ("min", int(minimum)), ("max", int(maximum)), ("ench", enchant), ] ) num += 1
def buildFrameItemTag(self, i, ench=(), customname=''): item = items.byName(i) if customname == '': customname = item.customname thisloot = loottable.Loot(None, 1, item.value, item.data, ench, item.p_effect, customname, item.flag, item.flagparam, item.lore, item.file) return self.buildItemTag(thisloot)
def Load(): print 'Reading loot tables...' global _maxtier while (cfg.parser.has_section('tier%d' % (_maxtier + 1))): _maxtier += 1 tiername = 'tier%d' % (_maxtier) # print 'Reading loot table for:',tiername loots = cfg.parser.items(tiername) _master_loot[tiername] = {} thistable = _master_loot[tiername] num = 0 for line in loots: try: chance, minmax, enchant = [x.strip() for x in line[1].split(',')] minimum = minmax.split('-')[0] maximum = minmax.split('-')[-1] except: print 'WARNING: Cannot parse loot table entry around line:' print ' {}: {} (skipping...)'.format( line[0], line[1] ) continue ilist = [] for i in line[0].split(','): thisitem = items.byName(i.strip()) if thisitem is None: print 'ERROR: Tried to reference loot that does not exist.' sys.exit() ilist.append(items.byName(i.strip())) thistable[num] = dict([ ('item', ilist), ('chance', int(chance)), ('min', int(minimum)), ('max', int(maximum)), ('ench', enchant) ]) num += 1
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_String(items.byName('map').id) 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 display tags 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])) item['tag']['display']['MapColor'] = nbt.TAG_Int(self.paintingcolor) return item
def buildFrameItemTag(self,i,ench=(),customname=''): item = items.byName(i) if customname == '': customname = item.customname thisloot = loottable.Loot( None, 1, item.value, item.data, ench, item.p_effect, customname, item.flag, item.flagparam, item.lore, item.file) return self.buildItemTag(thisloot)
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_String(items.byName('map').id) 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 display tags 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])) item['tag']['display']['MapColor'] = nbt.TAG_Int(self.paintingcolor) return item
def generate_map(self, dungeon, level): '''Generate a new map, save it to disk, flush the cache, and return a map item NBT with the appropriate map ID.''' dungeon_key = '%s,%s' % (dungeon.position.x, dungeon.position.z) if dungeon_key not in self.mapcache['used']: self.mapcache['used'][dungeon_key] = set([]) # Find a map id. Look in the available list for old mcdungeon maps # that can be reused. If not, bump up the idcount and use that. if len(self.mapcache['available']) == 0: # Initialize the map count if it doesn't exist. if 'map' not in self.idcounts: self.idcounts['map'] = nbt.TAG_Short(-1) self.idcounts['map'].value += 1 mapid = self.idcounts['map'].value self.mapcache['used'][dungeon_key].add(mapid) else: mapid = self.mapcache['available'].pop() self.mapcache['used'][dungeon_key].add(mapid) filename = os.path.join(self.mapstore, 'map_%d.dat' % (mapid)) # Setup the defaults. # Offset will be way off somewhere were players are unlikely to go # to avoid the maps from being overwritten. Nothing else really # matters. tags = nbt.TAG_Compound() tags['data'] = nbt.TAG_Compound() tags['data']['scale'] = nbt.TAG_Byte(0) tags['data']['xCenter'] = nbt.TAG_Int(-12500000) tags['data']['zCenter'] = nbt.TAG_Int(-12500000) tags['data']['height'] = nbt.TAG_Short(128) tags['data']['width'] = nbt.TAG_Short(128) tags['data']['dimension'] = nbt.TAG_Byte(0) tags['data']['colors'] = nbt.TAG_Byte_Array(zeros(16384, uint8)) # Generate the map. blocks = dungeon.blocks colors = tags['data']['colors'].value y = level * dungeon.room_height - 3 # Scale the map. We only scale up, not down since scaling # looks terrible. max_dungeon = max(dungeon.xsize * dungeon.room_size, dungeon.zsize * dungeon.room_size) max_dungeon = max(128, max_dungeon) # If the size is less than 8, try to center it. xoffset = 0 zoffset = 0 if dungeon.xsize * dungeon.room_size < 128: xoffset = (128 - dungeon.xsize * dungeon.room_size) / 2 if dungeon.zsize * dungeon.room_size < 128: zoffset = (128 - dungeon.zsize * dungeon.room_size) / 2 # Draw pixels on the map corresponding to blocks just above # floor level. Color chests and spawners. Hide things that should be # hidden. for x in xrange(128): for z in xrange(128): block = Vec(x * max_dungeon / 128 - xoffset, y, z * max_dungeon / 128 - zoffset) if block in blocks: mat = blocks[block].material if mat == materials.StonePressurePlate: colors[x + z * 128] = 10 elif blocks[block].hide is True: colors[x + z * 128] = 0 elif blocks[block].blank is True: colors[x + z * 128] = 0 elif mat == materials.Air: colors[x + z * 128] = 10 elif mat == materials.Spawner: colors[x + z * 128] = 48 elif (mat == materials.Chest or mat == materials.TrappedChest): colors[x + z * 128] = 42 else: colors[x + z * 128] = 54 else: colors[x + z * 128] = 0 # Draw the level number in the corner digits = [[0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0], [0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1], [1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0], [1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1], [1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1], [0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0], [1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1]] sx = 120 if level < 10: sx = 124 sz = 123 for d in str(level): for x in xrange(3): for z in xrange(5): if digits[int(d)][x + z * 3] == 1: colors[x + sx + (z + sz) * 128] = 16 sx += 4 # Save the map file, cache, and idcount.dat tags.save(filename) self.update_mapstore() # Return a map item item = nbt.TAG_Compound() item['id'] = nbt.TAG_String(items.byName('map').id) item['Damage'] = nbt.TAG_Short(mapid) item['Count'] = nbt.TAG_Byte(1) item['tag'] = nbt.TAG_Compound() item['tag']['display'] = nbt.TAG_Compound() name = dungeon.dungeon_name + ' Lv {l}' item['tag']['display']['Name'] = nbt.TAG_String(name.format(l=level)) item['tag']['display']['MapColor'] = nbt.TAG_Int(self.mapcolor) print item['tag']['display']['Name'].value return item
def generate_map(self, dungeon, level): '''Generate a new map, save it to disk, flush the cache, and return a map item NBT with the appropriate map ID.''' dungeon_key = '%s,%s' % (dungeon.position.x, dungeon.position.z) if dungeon_key not in self.mapcache['used']: self.mapcache['used'][dungeon_key] = set([]) # Find a map id. Look in the available list for old mcdungeon maps # that can be reused. If not, bump up the idcount and use that. if len(self.mapcache['available']) == 0: # Initialize the map count if it doesn't exist. if 'map' not in self.idcounts: self.idcounts['map'] = nbt.TAG_Short(-1) self.idcounts['map'].value += 1 mapid = self.idcounts['map'].value self.mapcache['used'][dungeon_key].add(mapid) else: mapid = self.mapcache['available'].pop() self.mapcache['used'][dungeon_key].add(mapid) filename = os.path.join(self.mapstore, 'map_%d.dat' % (mapid)) # Setup the defaults. # Offset will be way off somewhere were players are unlikely to go # to avoid the maps from being overwritten. Nothing else really # matters. tags = nbt.TAG_Compound() tags['data'] = nbt.TAG_Compound() tags['data']['scale'] = nbt.TAG_Byte(0) tags['data']['xCenter'] = nbt.TAG_Int(-12500000) tags['data']['zCenter'] = nbt.TAG_Int(-12500000) tags['data']['height'] = nbt.TAG_Short(128) tags['data']['width'] = nbt.TAG_Short(128) tags['data']['dimension'] = nbt.TAG_Byte(0) tags['data']['colors'] = nbt.TAG_Byte_Array(zeros(16384, uint8)) # Generate the map. blocks = dungeon.blocks colors = tags['data']['colors'].value y = level * dungeon.room_height - 3 # Scale the map. We only scale up, not down since scaling # looks terrible. max_dungeon = max(dungeon.xsize * dungeon.room_size, dungeon.zsize * dungeon.room_size) max_dungeon = max(128, max_dungeon) # If the size is less than 8, try to center it. xoffset = 0 zoffset = 0 if dungeon.xsize * dungeon.room_size < 128: xoffset = (128 - dungeon.xsize * dungeon.room_size) / 2 if dungeon.zsize * dungeon.room_size < 128: zoffset = (128 - dungeon.zsize * dungeon.room_size) / 2 # Draw pixels on the map corresponding to blocks just above # floor level. Color chests and spawners. Hide things that should be # hidden. for x in xrange(128): for z in xrange(128): block = Vec(x * max_dungeon / 128 - xoffset, y, z * max_dungeon / 128 - zoffset) if block in blocks: mat = blocks[block].material if mat == materials.StonePressurePlate: colors[x + z * 128] = 10 elif blocks[block].hide is True: colors[x + z * 128] = 0 elif blocks[block].blank is True: colors[x + z * 128] = 0 elif mat == materials.Air: colors[x + z * 128] = 10 elif mat == materials.Spawner: colors[x + z * 128] = 48 elif (mat == materials.Chest or mat == materials.TrappedChest): colors[x + z * 128] = 42 else: colors[x + z * 128] = 54 else: colors[x + z * 128] = 0 # Draw the level number in the corner digits = [ [0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0], [0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1], [1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0], [1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1], [1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1], [0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0], [1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1] ] sx = 120 if level < 10: sx = 124 sz = 123 for d in str(level): for x in xrange(3): for z in xrange(5): if digits[int(d)][x + z * 3] == 1: colors[x + sx + (z + sz) * 128] = 16 sx += 4 # Save the map file, cache, and idcount.dat tags.save(filename) self.update_mapstore() # Return a map item item = nbt.TAG_Compound() item['id'] = nbt.TAG_String(items.byName('map').id) item['Damage'] = nbt.TAG_Short(mapid) item['Count'] = nbt.TAG_Byte(1) item['tag'] = nbt.TAG_Compound() item['tag']['display'] = nbt.TAG_Compound() name = dungeon.dungeon_name + ' Lv {l}' item['tag']['display']['Name'] = nbt.TAG_String(name.format(l=level)) print item['tag']['display']['Name'].value return item
def updateData(self): self.val = items.byName(self.name).value self.data = items.byName(self.name).data
def render(self): o = self.parent.loc.trans(2,0,2) sb = self.parent.parent.setblock roomtype = random.choice(('study', 'sepulchure')) if roomtype == 'study': wmat = materials._wall fmat = materials._floor cmat = materials._ceiling else: wmat = materials.meta_mossystonebrick fmat = materials.meta_mossystonebrick cmat = materials._ceiling # Reform the room. # Air space for p in iterate_cube(o.trans(1,1,1), o.trans(10,3,10)): sb(p, materials.Air) # Walls for p in iterate_four_walls(o, o.trans(11,0,11),-4): sb(p, wmat) # Ceiling for p in iterate_cube(o, o.trans(11,0,11)): sb(p, cmat) # Floor for p in iterate_cube(o.trans(0,4,0), o.trans(11,4,11)): sb(p, fmat) # Pick random contents. Right now there are two possibilities. if roomtype == 'study': # A secret study # Book cases for p in iterate_four_walls(o.trans(1,1,1), o.trans(10,1,10),-2): sb(p, materials.Bookshelf) for p in (Vec(1,1,3), Vec(1,1,8), Vec(3,1,1), Vec(3,1,10), Vec(8,1,1), Vec(8,1,10), Vec(10,1,3), Vec(10,1,8)): for q in iterate_cube(o+p, o+p.down(2)): sb(q, materials.Air) # Torches for p in (Vec(2,3,2), Vec(2,3,9), Vec(9,3,2), Vec(9,3,9)): sb(o+p, materials.Fence) sb(o+p.up(1), materials.Torch, 5) # Desk mats = [ materials.Air, # 0 materials.WoodPlanks, # 1 materials.Chest, # 2 materials.CraftingTable,# 3 materials.WallSign, # 4 materials.WoodenStairs # 5 ] template = [ [3,1,1,2], [0,4,5,4] ] oo = o.trans(5,3,4) for x in xrange(2): for z in xrange(4): p = oo.trans(x,0,z) sb(p, mats[template[x][z]]) self.parent.parent.blocks[o+Vec(6,3,5)].data = 2 self.parent.parent.blocks[o+Vec(6,3,6)].data = 0 self.parent.parent.blocks[o+Vec(6,3,7)].data = 3 sb(o.trans(5,2,5), materials.Torch) self.parent.parent.addchest(o.trans(5,3,7)) else: # a small sepulchure # Torches for p in (Vec(2,3,2), Vec(2,3,9), Vec(9,3,2), Vec(9,3,9)): sb(o+p, materials.Fence) sb(o+p.up(1), materials.Torch, 5) # Sarcophagus for p in iterate_cube(o.trans(3,3,4), o.trans(8,3,6)): sb(p, materials.EndStone) sb(o+Vec(3,3,4), materials.SandstoneSlab) sb(o+Vec(3,3,6), materials.SandstoneSlab) sb(o+Vec(8,3,4), materials.SandstoneSlab) sb(o+Vec(8,3,6), materials.SandstoneSlab) sb(o+Vec(4,2,5), materials.StoneBrick) sb(o+Vec(5,2,5), materials.StoneBrickSlab) sb(o+Vec(6,2,5), materials.StoneBrickSlab) sb(o+Vec(7,2,5), materials.StoneBrickStairs, 0) # Loot for the sarcophagus. loota = [] lootb = [] bone = items.byName('bone') for slot in xrange(11,15,1): loota.append(loottable.Loot(slot,1,bone.value,bone.data,'')) lootb.append(loottable.Loot(slot,1,bone.value,bone.data,'')) for slot in xrange(18,27,1): loota.append(loottable.Loot(slot,1,bone.value,bone.data,'')) for slot in xrange(0,9,1): lootb.append(loottable.Loot(slot,1,bone.value,bone.data,'')) # Random stuff to be buried with. Like Crypt, but not as good. lootc = [(items.byName('iron ingot'), 5), (items.byName('book'), 10), (items.byName('bow'), 10), (items.byName('diamond'), 5), (items.byName('gold ingot'), 5), (items.byName('bowl'), 10), (items.byName('feather'), 10), (items.byName('golden apple'), 5), (items.byName('paper'), 10), (items.byName('arrow'), 10), (items.byName('clock'), 10), (items.byName('compass'), 10), (items.byName('gold nugget'), 10), (items.byName('ghast tear'), 1), (items.byName('glass bottle'), 10)] i = weighted_choice(lootc) loota[7].id = i.value loota[7].data = i.data sb(o+Vec(5,3,5), materials.Chest) self.parent.parent.addchest(o+Vec(5,3,5), loot=loota) i = weighted_choice(lootc) lootb[7].id = i.value lootb[7].data = i.data sb(o+Vec(6,3,5), materials.Chest) self.parent.parent.addchest(o+Vec(6,3,5), loot=lootb) # Vines for p in iterate_cube(o, o.trans(11,3,11)): if random.randint(1,100) <= 20: self.parent.parent.vines(p, grow=True) # Hallway # Find the direction, room, and connecting room. # room = this room # d = direction out of this room # offset = offset of the hallways # oroom = connecting room # od = direction out of the connecting room # length = legth of the opposite hall # hall positions to grid direction dirs = {3: Vec(-1,0,0), 1: Vec(1,0,0), 2: Vec(0,0,1), 0: Vec(0,0,-1)} room = self.parent d = 0 for x in xrange(4): if room.halls[x]._name != 'blank': d = x offset = room.halls[d].offset oroom = self.parent.parent.rooms[room.pos+dirs[d]] od = (d+2)%4 length = oroom.hallLength[od]-2 # Figure our out deltas. There are 8 possibilities based on direction # and offset. Offset will basically mirror across width. # dw = delta width # dl = delta length # spos = start pos for the mechanism # d = 0 (West) if d == 0: dw = Vec(1,0,0) dl = Vec(0,0,-1) spos = o.trans(offset,0,0) # d = 1 (South) elif d == 1: dw = Vec(0,0,1) dl = Vec(1,0,0) spos = o.trans(11,0,offset) # d = 2 (East) elif d == 2: dw = Vec(1,0,0) dl = Vec(0,0,1) spos = o.trans(offset,0,11) # d = 3 (North) else: dw = Vec(0,0,1) dl = Vec(-1,0,0) spos = o.trans(0,0,offset) if offset >= 7: dw = dw*-1 if (d == 0 or d == 2): spos = spos.trans(-2,0,0) elif (d == 1 or d == 3): spos = spos.trans(0,0,-2) # Position the start block for the mechanism spos = spos + dl*length - dw if self.parent.parent.args.debug: print print 'room:', room.pos print 'dir:', d print 'offset:', offset print 'dl:', dl print 'dw:', dw print mats = [ [materials.Air,0], # 0 (ignore these) [materials.Air,0], # 1 [materials.Bookshelf,0], # 2 [materials.Stone,0], # 3 [materials._wall,0], # 4 [materials.RedStoneWire,0], # 5 [materials.StickyPiston,3], # 6 - toggle piston [materials.RedStoneTorchOn,2],# 7 [materials._ceiling, 0], # 8 [materials.StickyPiston, 4],# 9 - pusher piston [materials.RedStoneRepeaterOff, 3],# 10 - piston repeater [materials.RedStoneRepeaterOff, 7],# 11 - toggle repeater [materials.Torch, 0], # 12 [materials._secret_door, 0],# 13 [materials._floor, 0], # 14 [materials._subfloor, 0] # 15 ] if roomtype == 'sepulchure': mats[2] = [materials.meta_mossystonebrick, 0] template = [ [[ 8, 8, 8, 8, 8], [ 8, 8, 8, 8, 8], [ 8, 8, 8, 8, 8], [ 8, 8, 8, 8, 8], [ 8, 8, 8, 8, 8]], [[ 1, 1, 1,12, 4], [ 2, 4, 4, 4, 4], [ 2, 1, 1, 1, 4], [ 2, 1, 1, 1, 4], [ 2, 1, 1, 1, 4]], [[ 1, 7, 1 ,1,13], [ 2, 4, 6, 1, 4], [ 2,11, 9, 9, 4], [ 2, 5,10,10, 4], [ 2, 5, 5, 5, 4]], [[ 1, 1, 1, 1,13], [ 2, 4, 6, 1, 4], [ 2, 3, 9, 9, 4], [ 2, 3, 3, 3, 4], [ 2, 3, 3, 3, 4]], [[14,14,14,14,14], [14,14,14,14,14], [14,14,14,14,14], [14,14,14,14,14], [14,14,14,14,14]], [[15,15,15,15,15], [15,15,15,15,15], [15,15,15,15,15], [15,15,15,15,15], [15,15,15,15,15]], ] bdata = 3 # Data adjustments for directions. There are 8, but the defaults are # for East, low offset. # West if d == 0: bdata = 4 if offset >= 7: mats[6][1] = 2 mats[7][1] = 1 mats[9][1] = 5 mats[10][1] = 1 mats[11][1] = 5 else: mats[6][1] = 2 # South if d == 1: bdata = 1 if offset >= 7: mats[6][1] = 5 mats[7][1] = 3 mats[9][1] = 3 mats[10][1] = 2 mats[11][1] = 6 else: mats[6][1] = 5 mats[7][1] = 4 mats[9][1] = 2 mats[10][1] = 0 mats[11][1] = 4 # East, flipped if (d == 2 and offset >= 7): # flip the pusher piston mats[7][1] = 1 mats[9][1] = 5 mats[10][1] = 1 mats[11][1] = 5 # North if d == 3: bdata = 2 if offset >= 7: mats[6][1] = 4 mats[7][1] = 3 mats[9][1] = 3 mats[10][1] = 2 mats[11][1] = 6 else: mats[6][1] = 4 mats[7][1] = 4 mats[9][1] = 2 mats[10][1] = 0 mats[11][1] = 4 # Draw the mechanism for y in xrange(6): for w in xrange(5): for l in xrange(5): p = spos+dl*l+dw*w+Vec(0,1,0)*y sb(p, mats[template[y][w][l]][0], mats[template[y][w][l]][1]) # The button. p = spos+dl*3+dw*4+Vec(0,1,0)*2 blocks = self.parent.parent.blocks while blocks[p+dl].material != materials.Air: sb(p.up(1), materials.Air) sb(p, materials.RedStoneWire) sb(p.down(1), materials.Stone) p = p + dl sb(p+dl, materials.StoneButton, bdata) # Clear out extra space inside the room p = spos.down(1) for q in iterate_cube(p, p-dl*2+Vec(0,2,0)): sb(q, materials.Air) # Clear out any doors or extra torches in this room for p in iterate_cube(o, o.trans(11,4,11)): if p in self.parent.parent.doors: del(self.parent.parent.doors[p]) if p in self.parent.parent.torches: del(self.parent.parent.torches[p]) # Clear doors and torches from the entry way p = spos+dl*4 for q in iterate_cube(p.trans(-1,0,-1), p.trans(1,4,1)): if q in self.parent.parent.doors: del(self.parent.parent.doors[q]) if q in self.parent.parent.torches: del(self.parent.parent.torches[q]) # Kill the canvas to prevent spawners and chests from appearing self.parent.canvas = ( Vec(0,0,0), Vec(0,0,0), Vec(0,0,0)) # Cobwebs webs = {} for p in iterate_cube(o, o.trans(11,3,11)): count = 0 perc = 80 - (p.y - o.y) * (70/5) if (p not in blocks or blocks[p].material != materials.Air): continue for q in (Vec(1,0,0), Vec(-1,0,0), Vec(0,1,0), Vec(0,-1,0), Vec(0,0,1), Vec(0,0,-1)): if (p+q in blocks and blocks[p+q].material != materials.Air and random.randint(1,100) <= perc): count += 1 if count >= 3: webs[p] = True for p, q in webs.items(): sb(p, materials.Cobweb)