From 6c363aeecebf450c13ccfc6958a0382205e5c4d5 Mon Sep 17 00:00:00 2001 From: Maciej Benke Date: Sun, 27 May 2012 23:51:02 +0200 Subject: [PATCH] First commit --- .gitattributes | 49 ++++++++ .gitignore | 165 +++++++++++++++++++++++++++ skygrid.py | 304 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 518 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 skygrid.py diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a664be3 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,49 @@ +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain + +*.jpg binary +*.png binary +*.gif binary + +*.cs text=auto diff=csharp +*.vb text=auto +*.c text=auto +*.cpp text=auto +*.cxx text=auto +*.h text=auto +*.hxx text=auto +*.py text=auto +*.rb text=auto +*.java text=auto +*.html text=auto +*.htm text=auto +*.css text=auto +*.scss text=auto +*.sass text=auto +*.less text=auto +*.js text=auto +*.lisp text=auto +*.clj text=auto +*.sql text=auto +*.php text=auto +*.lua text=auto +*.m text=auto +*.asm text=auto +*.erl text=auto +*.fs text=auto +*.fsx text=auto +*.hs text=auto + +*.csproj text=auto merge=union +*.vbproj text=auto merge=union +*.fsproj text=auto merge=union +*.dbproj text=auto merge=union +*.sln text=auto eol=crlf merge=union diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa8811c --- /dev/null +++ b/.gitignore @@ -0,0 +1,165 @@ + +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/** +tmp/** +tmp/**/* +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +**/[Dd]ebug/ +**/[Rr]elease/ +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.vspscc +.builds +**/*.dotCover + +## TODO: If you have NuGet Package Restore enabled, uncomment this +#**/packages/ + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf + +# Visual Studio profiler +*.psess +*.vsp + +# ReSharper is a .NET coding add-in +_ReSharper* + +# Installshield output folder +[Ee]xpress + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish + +# Others +[Bb]in +[Oo]bj +sql +TestResults +*.Cache +ClientBin +stylecop.* +~$* +*.dbmdl +Generated_Code #added for RIA/Silverlight projects + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML + + + +############ +## Windows +############ + +# Windows image file caches +Thumbs.db + +# Folder config file +Desktop.ini + + +############# +## Python +############# + +*.py[co] + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg + +# Mac crap +.DS_Store diff --git a/skygrid.py b/skygrid.py new file mode 100644 index 0000000..786e240 --- /dev/null +++ b/skygrid.py @@ -0,0 +1,304 @@ +# SkyGrid Filter by SethBling +# Feel free to modify and reuse, but credit to SethBling would be nice. + +from pymclevel import MCSchematic +from pymclevel import TileEntity +from pymclevel import TAG_Compound +from pymclevel import TAG_Short +from pymclevel import TAG_Byte +from pymclevel import TAG_String +import random + +displayName = "SethBling's Sky Grid" +inputs = ( + ("Grid Length", (4, 1, 100)), + ("World Type", ("Overworld", + "Nether", + )), +) + +def perform(level, box, options): + gridlength = options["Grid Length"] + worldtype = options["World Type"] + + total = 0 + cump = {} + + if worldtype == "Overworld": + p = normalp() + elif worldtype == "Nether": + p = netherp() + + # generate the cumulative distribution + for key, value in p.iteritems(): + cump[key] = (total, total + value) + total += value + + for x in xrange(box.minx, box.maxx, gridlength): + for y in xrange(box.miny, box.maxy, gridlength): + for z in xrange(box.minz, box.maxz, gridlength): + blockid = pickblock(cump, total) + + if(blockid == 6 or blockid == 31 or blockid == 32 or blockid == 37 or + blockid == 38 or blockid == 39 or blockid == 40 or blockid == 83): + level.setBlockAt(x, y, z, 3) #dirt + if(y < box.maxy): + level.setBlockAt(x, y+1, z, blockid) + if(blockid == 83): #reeds + level.setBlockAt(x+1, y, z, 9) #still water + elif(blockid == 81): #cactus + level.setBlockAt(x, y, z, 12) #sand + if(y < box.maxy): + level.setBlockAt(x, y+1, z, blockid) + if(y > box.miny): + level.setBlockAt(x, y-1, z, 106) # vines + elif(blockid == 115): #netherwart + level.setBlockAt(x, y, z, 112) + if(y < box.maxy): + level.setBlockAt(x, y+1, z, blockid) + else: + level.setBlockAt(x, y, z, blockid) + + if(blockid == 54): + fillChestAt(level, x, y, z) + + if(blockid == 52): + setSpawnerAt(level, worldtype, x, y, z) + + if worldtype == "Overworld": + #generate end portal + dx = box.maxx - box.minx + dz = box.maxz - box.minz + + middlex = box.minx + int(dx / 2 / gridlength) * gridlength + middlez = box.minz + int(dz / 2 / gridlength) * gridlength + + y = box.miny + gridlength + + if y <= box.maxy and middlex+4 <= box.maxx and middlez+4 <= box.maxz: + # set portal blocks + level.setBlockAt(middlex+1, y, middlez, 120) + level.setBlockAt(middlex+2, y, middlez, 120) + level.setBlockAt(middlex+3, y, middlez, 120) + + level.setBlockAt(middlex, y, middlez+1, 120) + level.setBlockAt(middlex, y, middlez+2, 120) + level.setBlockAt(middlex, y, middlez+3, 120) + + level.setBlockAt(middlex+1, y, middlez+4, 120) + level.setBlockAt(middlex+2, y, middlez+4, 120) + level.setBlockAt(middlex+3, y, middlez+4, 120) + + level.setBlockAt(middlex+4, y, middlez+1, 120) + level.setBlockAt(middlex+4, y, middlez+2, 120) + level.setBlockAt(middlex+4, y, middlez+3, 120) + + # set damage values + level.setBlockDataAt(middlex+1, y, middlez, 1) + level.setBlockDataAt(middlex+2, y, middlez, 1) + level.setBlockDataAt(middlex+3, y, middlez, 1) + + level.setBlockDataAt(middlex, y, middlez+1, 1) + level.setBlockDataAt(middlex, y, middlez+2, 1) + level.setBlockDataAt(middlex, y, middlez+3, 1) + + level.setBlockDataAt(middlex+1, y, middlez+4, 1) + level.setBlockDataAt(middlex+2, y, middlez+4, 1) + level.setBlockDataAt(middlex+3, y, middlez+4, 1) + + level.setBlockDataAt(middlex+4, y, middlez+1, 1) + level.setBlockDataAt(middlex+4, y, middlez+2, 1) + level.setBlockDataAt(middlex+4, y, middlez+3, 1) + + + level.markDirtyBox(box) + +# returns an unnormalized probability distribution for blocks in the +# overworld +def normalp(): + p = {} + p[1] = 120 #stone + p[2] = 80 #grass + p[3] = 20 #dirt + p[9] = 10 #still water + p[11] = 5 #still lava + p[12] = 20 #sand + p[13] = 10 #gravel + p[14] = 10 #gold ore + p[15] = 20 #iron ore + p[16] = 40 #coal ore + p[17] = 100 #log + p[18] = 40 #leaves + p[20] = 1 #glass + p[21] = 5 #lapis ore + p[24] = 10 #sandstone + p[29] = 1 #sticky piston + p[30] = 10 #web + p[31] = 3 #shrub + p[32] = 3 #shrub + p[33] = 1 #piston + p[35] = 25 #wool + p[37] = 2 #yellow flower + p[38] = 2 #red flower + p[39] = 2 #brown mushroom + p[40] = 2 #red mushroom + p[46] = 2 #TNT + p[47] = 3 #bookshelves + p[48] = 5 #mossy cobblestone + p[49] = 5 #obsidian + p[52] = 1 #spawner + p[54] = 1 #chest + p[56] = 1 #diamond ore + p[73] = 8 #redstone ore + p[79] = 4 #ice + p[80] = 8 #snow + p[81] = 1 #cactus + p[82] = 20 #clay + p[83] = 15 #reeds + p[86] = 5 #pumpkin + p[103] = 5 #melon + p[110] = 15 #mycelium + + return p + +# returns an unnormalized probability distribution for blocks in the +# nether +def netherp(): + p = {} + p[11] = 50 #still lava + p[13] = 30 #gravel + p[52] = 2 #mob spawner + p[54] = 1 #chest + p[87] = 300 #netherack + p[88] = 100 #soulsand + p[89] = 50 #glowstone + p[112] = 30 #netherbrick + p[113] = 10 #nether fence + p[114] = 15 #nether stairs + p[115] = 30 #netherwart + + return p + +# picks a random block from a cumulative distribution +def pickblock(cump, size): + r = random.random() * size + + for key, value in cump.iteritems(): + low, high = value + if r >= low and r < high: + return key + +# creates a randomized mob spawner tile entity at a specified location +def setSpawnerAt(level, worldtype, x, y, z): + chunk = level.getChunk(x / 16, z / 16) + + if worldtype=="Overworld": + spawns = overworldSpawns() + elif worldtype=="Nether": + spawns = netherSpawns() + + spawnindex = randomInRange(0, len(spawns) - 1) + + spawner = TileEntity.Create("MobSpawner") + TileEntity.setpos(spawner, (x, y, z)) + spawner["Delay"] = TAG_Short(120) + spawner["EntityId"] = spawns[spawnindex] + + chunk.TileEntities.append(spawner) + +def overworldSpawns(): + return ["Creeper", + "Skeleton", + "Spider", + "CaveSpider", + "Zombie", + "Slime", + "Pig", + "Sheep", + "Cow", + "Chicken", + "Squid", + "Wolf", + "Enderman", + "Silverfish", + "Villager", + ] + +def netherSpawns(): + return ["PigZombie", + "Blaze", + "LavaSlime", + ] + +# fills a chest with random goodies +def fillChestAt(level, x, y, z): + chunk = level.getChunk(x / 16, z / 16) + + chest = TileEntity.Create("Chest") + TileEntity.setpos(chest, (x, y, z)) + + if(random.random() < 0.7): + chest["Items"].append(createItemInRange(256, 294)) #various weapons/random + + if(random.random() < 0.7): + chest["Items"].append(createItemInRange(298, 317)) #various armor + + if(random.random() < 0.7): + chest["Items"].append(createItemInRange(318, 350)) #various food/tools + + if(random.random() < 0.3): + chest["Items"].append(createItemWithRandomDamage(383, 50, 52)) # various spawn eggs + + if(random.random() < 0.9): + chest["Items"].append(createItemWithRandomDamage(383, 54, 62)) #various spawn eggs + + if(random.random() < 0.4): + chest["Items"].append(createItemWithRandomDamage(383, 90, 96)) #various spawn eggs + + if(random.random() < 0.1): + chest["Items"].append(createItemWithRandomDamage(383, 98, 98)) #ocelot spawn egg + + if(random.random() < 0.1): + chest["Items"].append(createItemWithRandomDamage(383, 120, 120)) #villager spawn egg + + if(random.random() < 0.7): + itemid = randomInRange(1, 5) + count = randomInRange(10, 64) + slot = randomInRange(0, 26) + blocks = createItem(itemid, count, 0, slot) + chest["Items"].append(blocks) + + sapling = createItemWithRandomDamage(6, 0, 3) + sapling["Slot"] = TAG_Byte(randomInRange(0, 26)) + chest["Items"].append(sapling) + + chunk.TileEntities.append(chest) + +# creates a random item in an item id range +def createItemInRange(minid, maxid, count=1): + itemid = randomInRange(minid, maxid) + slot = randomInRange(0, 26) + + return createItem(itemid, count, 0, slot) + +# creates an item with a randomized damage value +def createItemWithRandomDamage(itemid, mindmg, maxdmg, count=1): + dmg = randomInRange(mindmg, maxdmg) + slot = randomInRange(0, 26) + + return createItem(itemid, count, dmg, slot) + +# creates an item +def createItem(itemid, count=1, damage=0, slot=0): + item = TAG_Compound() + + item["id"] = TAG_Short(itemid) + item["Damage"] = TAG_Short(damage) + item["Count"] = TAG_Byte(count) + item["Slot"] = TAG_Byte(slot) + + return item + +# returns a random integer between minr and maxr, inclusive +def randomInRange(minr, maxr): + return int(random.random() * (maxr - minr + 1)) + minr