Jump to content

[1.7.10][1.8] Builders Helper mod: copy/paste/save structures in-game v2.7


Recommended Posts

Posted

Cheshire Cat Builder's Helper Mod :  v2.7

 

Project moved to CurseForge http://minecraft.curseforge.com/projects/builders-helper

See this link for all future updates.

 

Download v2.7 from: http://www.steveshipway.org/mc/builders-helper-2.7.zip ( 1.7.10, 1.8 ) (includes src)

 

Download v2.5 from: http://www.steveshipway.org/mc/builders-helper-2.5.zip ( 1.7.10, 1.8 ) (includes src)

Download v2.4from: http://www.steveshipway.org/mc/builders-helper-2.4.zip ( 1.7.10, 1.8 ) (includes src)

Download v2.3.2 from: http://www.steveshipway.org/mc/builders-helper-2.3.2.zip ( 1.7.10, 1.8 ) (includes src)

Download v2.3.1 from: http://www.steveshipway.org/mc/builders-helper-2.3.1.zip ( 1.7.10, 1.8 ) (includes src)

Download v2.2 from: http://www.steveshipway.org/mc/builders-helper-2.2.zip ( 1.7.10, 1.8 ) (includes src)

Download v1.0 from: http://www.steveshipway.org/mc/builders-helper-1.0.zip ( 1.7.10, 1.8 ) (includes src)

Download v2.1-beta1 from: http://www.steveshipway.org/mc/builders-helper-2.1-beta1.zip ( 1.7.10, 1.8 ) (includes src)

Download v2.0-beta1 from: http://www.steveshipway.org/mc/builders-helper-2.0-beta1.zip ( 1.8 ) (includes src)

Download v0.3 from: http://www.steveshipway.org/mc/builders-helper-0.3.zip ( 1.7.10, 1.8 ) (includes src)

Download v0.2 from: http://www.steveshipway.org/mc/builders-helper-0.2.zip ( 1.7.10 only )

 

Screenshots:

 

width=800 height=449http://www.steveshipway.org/mc/2015-01-06_21.40.15.png[/img]

Some of the example structures created with the supplied blueprints.

width=800 height=449http://www.steveshipway.org/mc/2015-01-06_21.41.33.png[/img]

The same plan can be built multiple times, at different locations and rotations, with a click of the mouse.

width=800 height=449http://www.steveshipway.org/mc/2015-01-06_21.42.06.png[/img]

The random tower has varying height, room contents, balconies, windowboxes...

 

 

 

This is a mod aimed at:

  • People who spend all their time in Creative mode
  • People who like the copy/paste features in external editors, but want to create in-game
  • People who don't want to spend another ten minutes creating yet another generic house as they build their city
  • People who want to share their structure with others without having to save and load an entire world
  • People who want an easy way to add auto-spawning structures in-game

The mod adds a new item -- a Wand -- and a few commands ( /wand, /blueprint ).  It allows the person holding the wand to create any of a number of predefined  structures (plans) at the click of a right-button; it also allows them to save an existing structure as a file (blueprint) that can be loaded back in as a plan and used again multiple times.  The resulting map does not need the mod to be loaded for it to work.

 

Plans may use 'soft' blocks, which only place in air or water, and can also include reference to other place, at translation or rotation.  There is also the option to use an element of randomness, so that it can generate varying structures from the same blueprint.  It also preserves Block Entity data and can handle blocks added by other mods.

 

Plans can specify Chests and Spawners using special random syntax, to include randomised loot and spawn potentials.  This may be configured using in-line NBT, external NBT files, or symbolically in the code.  You can also specify mobile entities, such as carts, armour stands, and mobs.

 

There are also 'Metablock' symbols, such as 'OLD_STONE' which will resolve to a different block based on current biome and/or random states.  So, a cottage will generate using different stone and wood if built in a desert as opposed to being built on a plain.

 

Blueprints can also copy and paste mobile entities, such as minecrafts, mobs, and armour stands.

 

Blueprints can contain IFBLOCK and IFBIOME tests to branch on various conditions.

 

Blueprints can use MOB to create entities, and you can copy entities.

 

The PICTURE directive can be used to create a custom map in a frame displaying the contents of an external image file.

 

Plans may be flagged as 'autogenerate' with a probability and a list of biomes, and they will be auto-generated as new chunks are generated.

 

There is support for MCEdit Schematics, and Ruins Templates.

 

Example blueprint:

# Blueprint for small cottage
private  PLAN _cottage
  AREA minecraft:air 0,1,0 7,5,4
  AREA minecraft:cobblestone 0,0,0 0,2,4
  BLOCK minecraft:spruce_stairs(2) 0,3,0
  BLOCK minecraft:cobblestone 0,3,1
  BLOCK minecraft:cobblestone 0,3,2
  BLOCK minecraft:cobblestone 0,3,3
  BLOCK minecraft:spruce_stairs(3) 0,3,4
  BLOCK minecraft:spruce_stairs(2) 0,4,1
  BLOCK minecraft:cobblestone 0,4,2
  BLOCK minecraft:spruce_stairs(3) 0,4,3
  BLOCK minecraft:wooden_slab(1) 0,5,2
  AREA minecraft:cobblestone 1,0,0 1,0,4
  BLOCK minecraft:cobblestone 1,1,0
  BLOCK minecraft:crafting_table 1,1,1
  BLOCK minecraft:bed(9) 1,1,3
  BLOCK minecraft:cobblestone 1,1,4
  BLOCK minecraft:cobblestone 1,2,0
  BLOCK minecraft:cobblestone 1,2,4
  BLOCK minecraft:spruce_stairs(2) 1,3,0
  BLOCK minecraft:torch(1) 1,3,2
  BLOCK minecraft:spruce_stairs(3) 1,3,4
  BLOCK minecraft:spruce_stairs(2) 1,4,1
  BLOCK minecraft:spruce_stairs(3) 1,4,3
  BLOCK minecraft:wooden_slab(1) 1,5,2
  AREA minecraft:cobblestone 2,0,0 2,0,4
  BLOCK minecraft:wooden_door(5) 2,1,0
  BLOCK minecraft:bed(1) 2,1,3
  BLOCK minecraft:cobblestone 2,1,4
  BLOCK minecraft:wooden_door( 2,2,0
  BLOCK minecraft:cobblestone 2,2,4
  BLOCK minecraft:spruce_stairs(2) 2,3,0
  BLOCK minecraft:spruce_stairs(3) 2,3,4
  BLOCK minecraft:spruce_stairs(2) 2,4,1
  BLOCK minecraft:spruce_stairs(3) 2,4,3
  BLOCK minecraft:wooden_slab(1) 2,5,2
  BLOCK minecraft:cobblestone 3,0,0
  BLOCK minecraft:cobblestone 3,0,1
  BLOCK minecraft:cobblestone 3,0,2
  BLOCK minecraft:cobblestone 3,0,3
  BLOCK minecraft:cobblestone 3,0,4
  BLOCK minecraft:cobblestone 3,1,0
  BLOCK minecraft:cobblestone 3,1,4
  BLOCK minecraft:cobblestone 3,2,0
  BLOCK minecraft:glass_pane 3,2,4
  BLOCK minecraft:spruce_stairs(2) 3,3,0
  BLOCK minecraft:spruce_stairs(3) 3,3,4
  BLOCK minecraft:spruce_stairs(2) 3,4,1
  BLOCK minecraft:spruce_stairs(3) 3,4,3
  BLOCK minecraft:wooden_slab(1) 3,5,2
  BLOCK minecraft:cobblestone 4,0,0
  BLOCK minecraft:cobblestone 4,0,1
  BLOCK minecraft:cobblestone 4,0,2
  BLOCK minecraft:cobblestone 4,0,3
  BLOCK minecraft:cobblestone 4,0,4
  BLOCK minecraft:cobblestone 4,1,0
  BLOCK minecraft:fence 4,1,2
  BLOCK minecraft:cobblestone 4,1,4
  BLOCK minecraft:glass_pane 4,2,0
  BLOCK minecraft:wooden_pressure_plate 4,2,2
  BLOCK minecraft:cobblestone 4,2,4
  BLOCK minecraft:spruce_stairs(2) 4,3,0
  BLOCK minecraft:spruce_stairs(3) 4,3,4
  BLOCK minecraft:spruce_stairs(2) 4,4,1
  BLOCK minecraft:spruce_stairs(3) 4,4,3
  BLOCK minecraft:wooden_slab(1) 4,5,2
  AREA minecraft:cobblestone 5,0,0 5,0,4
  BLOCK minecraft:cobblestone 5,1,0
  BLOCK minecraft:cobblestone 5,1,4
  BLOCK minecraft:cobblestone 5,2,0
  BLOCK minecraft:cobblestone 5,2,4
  BLOCK minecraft:spruce_stairs(2) 5,3,0
  BLOCK minecraft:torch(2) 5,3,2
  BLOCK minecraft:spruce_stairs(3) 5,3,4
  BLOCK minecraft:spruce_stairs(2) 5,4,1
  BLOCK minecraft:spruce_stairs(3) 5,4,3
  BLOCK minecraft:wooden_slab(1) 5,5,2
  AREA minecraft:cobblestone 6,0,0 6,2,4
  BLOCK minecraft:air 6,1,2
  BLOCK minecraft:spruce_stairs(2) 6,3,0
  BLOCK minecraft:cobblestone 6,3,1
  BLOCK minecraft:cobblestone 6,3,2
  BLOCK minecraft:cobblestone 6,3,3
  BLOCK minecraft:spruce_stairs(3) 6,3,4
  BLOCK minecraft:spruce_stairs(2) 6,4,1
  BLOCK minecraft:cobblestone 6,4,2
  BLOCK minecraft:spruce_stairs(3) 6,4,3
  BLOCK minecraft:cobblestone 6,5,2
  BLOCK minecraft:cobblestone 6,6,2
  BLOCK minecraft:cobblestone 7,0,2
  BLOCK minecraft:cobblestone 7,1,2
  BLOCK minecraft:stone_stairs(1) 7,2,2
END

PUBLIC PLAN cottage A simple small one room cottage
  # shift to make the door in front of us when created
  CALL _cottage -2 -1 1 0
END

 

Another example:

PUBLIC PLAN flower A tulip in a flowerpot
  BLOCK minecraft:flower_pot(4) 0,0,0 {Item:38,Data:4,id:"FlowerPot"}
END

 

 

The main thing to note is that, once the structures have been built, the mod is not required for the world to work (provided you have removed the Wand from the player inventory of course).

 

The mod comes with a number of example blueprints, demonstrating the various capabilities.  For example:

  • Glass dome -- works on land or underwater
  • Random tower -- random room contents and height
  • Cottage -- simple cottage
  • Well -- example of underground structure
  • Water -- uses 'soft' blocks to fill holes with water without affecting other blocks
  • Jeb Door -- standard Jeb door, with redstone etc
  • Lava trap -- example of trapped chest with opening floor
  • Bridge -- a simple 4-block wide bridge with a 30-block span
  • Tree -- a simple Oak tree
  • Water and Dry -- fill a hole with water, or dry up existing water
  • Topsoil -- add a layer of dirt and grass to any exposed rock
  • Tunnel -- drill a tunnell, with a rail track and torches, until the far side of the hill
  • Dungeon -- generate a random dungeon, with random rooms, monsters and treasure

More details and documentation are included with the mod in the download file.

 

Suggested uses:

  • Removing repetitive duplication work when building cities, forests and so on
  • Tutorials (eg, redstone) can provide a blueprint containing the example structures
  • Builders can share their work as individual re-useable structures
  • Use of random features giving small variations in a plan, to make more realistic worlds
  • Procedurally generate simple towers and castles

Note:

This is my first Minecraft Forge mod, and is being released to solicit feedback.  There are a number of rough edges and a couple of small bugs still to be addressed.  All constructive criticism and suggestions welcomed.

 

Posted

Here's the blueprint code for the random tower.  This is a good example of a recursive plan, with random elements.

 

I'm working on compiling a version of this mod to work with Minecraft 1.8 and the current Forge beta.

 

 

#
# Build a castle (actually, a tower)
# This has a standard base, then random rooms for a random height,
# then a standard roof.
#

private plan _tower_floor
    AREA minecraft:stone_slab(11)   2 -1 1  6 -1 6
    BLOCK minecraft:stone_slab(11)  1 -1 1
    BLOCK minecraft:stone_slab(11)  1 -1 2
    BLOCK minecraft:stone_slab(3)   1 -1 6
    BLOCK minecraft:stone_stairs(2) 1 -2 5
    BLOCK minecraft:stone_stairs(2) 1 -3 4
    BLOCK minecraft:stone_stairs(2) 1 -4 3
END

private plan _tower_walls
    AREA minecraft:cobblestone 0 -1 0   7 2 0
    AREA minecraft:cobblestone 0 -1 7   7 2 7
    AREA minecraft:cobblestone 0 -1 1   0 2 6
    AREA minecraft:cobblestone 7 -1 1   7 2 6
END

# Ground floor of the tower
private plan _tower_ground
    AREA minecraft:cobblestone 1 -1 1  6 -1 6
    CALL _tower_walls 0 0 0 0
    AREA minecraft:air 1 0 1  6 2 6
    BLOCK minecraft:wooden_door(3) 3 0 0
    BLOCK minecraft:wooden_door( 3 1 0
    BLOCK minecraft:wooden_door(3) 4 0 0
    BLOCK minecraft:wooden_door(9) 4 1 0
  BLOCK minecraft:torch(3) 4,2,1
  BLOCK minecraft:torch(4) 4,2,6
  BLOCK minecraft:torch(2) 6,2,4
  # torches over door
  BLOCK minecraft:torch(4) 3,2,-1
  BLOCK minecraft:torch(4) 4,2,-1
END

private plan _tower_roof
    # CALL _tower_floor 0 0 0 0
    AREA minecraft:stone_slab(11)   1 -1 1  6 -1 6
    BLOCK minecraft:trapdoor(     1 -1 2
    BLOCK minecraft:ladder(5)       1 -2 2
    BLOCK minecraft:cobblestone     0 -3 2
    BLOCK minecraft:ladder(5)       1 -3 2
    BLOCK minecraft:ladder(5)       1 -4 2
    BLOCK minecraft:stone_slab(3)   1 -4 3

    # Low walls and crenelations
    AREA minecraft:cobblestone 0 -1 0   7 1 0
    AREA minecraft:cobblestone 0 -1 7   7 1 7
    AREA minecraft:cobblestone 0 -1 1   0 1 6
    AREA minecraft:cobblestone 7 -1 1   7 1 6
    BLOCK minecraft:air        0  1 1
    BLOCK minecraft:air        0  1 3
    BLOCK minecraft:air        0  1 5
    BLOCK minecraft:air        7  1 2
    BLOCK minecraft:air        7  1 4
    BLOCK minecraft:air        7  1 6
    BLOCK minecraft:air        2  1 0
    BLOCK minecraft:air        4  1 0
    BLOCK minecraft:air        6  1 0
    BLOCK minecraft:air        1  1 7
    BLOCK minecraft:air        3  1 7
    BLOCK minecraft:air        5  1 7
    # Flagpole
    BLOCK minecraft:fence      5  0 5
    BLOCK minecraft:fence      5  1 5
    BLOCK minecraft:fence      5  2 5
    BLOCK minecraft:fence      5  3 5
# torches
    BLOCK minecraft:torch(0)   0  2 0
    BLOCK minecraft:torch(0)   0  2 7
    BLOCK minecraft:torch(0)   7  2 0
    BLOCK minecraft:torch(0)   7  2 7
END

private plan _tower_balcony
  # Balcony for window
  BLOCK minecraft:air 1 0 0
  BLOCK minecraft:air 1 1 0
  AREA  minecraft:stone_slab(11)   0 -1 2  2 -1 2
  AREA  minecraft:stone_stairs(7)  0 -1 1  2 -1 1
  AREA  minecraft:fence            0  0 2  2  0 2
  BLOCK minecraft:fence            0  0 1
  BLOCK minecraft:fence            2  0 1
  BLOCK minecraft:torch(3)         1  2 1
END
private plan _tower_windowledge
  BLOCK minecraft:stone_stairs(7) 1 0 1
  BLOCK minecraft:flower_pot(4)   1 1 1 {Item:38,Data:4,id:"FlowerPot"}
END
private plan _tower_window
  RANDOM 3
     CALL _tower_balcony     0 0 0  0
     CALL _tower_windowledge 0 0 0  0
     CALL _tower_windowledge 0 0 0  0
END
private plan _tower_half
  AREA minecraft:air       4 -1 1  6 -1 6
  AREA minecraft:fence     3  0 1  3  0 6
  BLOCK minecraft:torch(3) 3, 2,1
  BLOCK minecraft:torch(4) 3, 2,6
  CHANCE 20
     CALL _tower_window       1 0 7  0
  CHANCE 20
     CALL _tower_window       3 0 0  2
  CHANCE 10
     CALL _tower_windowledge  4 0 7  0
  CHANCE 10
     CALL _tower_windowledge  6 0 0  2
END
private plan _tower_library
  AREA minecraft:bookshelf  6 0 1  6 0 6
  AREA minecraft:bookshelf  6 2 1  6 2 6
  BLOCK minecraft:bookshelf 6 1 1
  BLOCK minecraft:bookshelf 6 1 3
  BLOCK minecraft:bookshelf 6 1 4
  BLOCK minecraft:bookshelf 6 1 6
  BLOCK minecraft:torch(3)  4,2,1
  BLOCK minecraft:torch(4)  4,2,6
  CHANCE 20
     CALL _tower_window  1 0 7  0
  CHANCE 20
     CALL _tower_window  4 0 7  0
  CHANCE 20
     CALL _tower_window  6 0 0  2
  CHANCE 20
     CALL _tower_window  3 0 0  2
END
private plan _tower_jail
# windows
    BLOCK minecraft:iron_bars 5 1 7
    BLOCK minecraft:iron_bars  5 1 0
    BLOCK minecraft:iron_bars  7 1 2
    BLOCK minecraft:iron_bars  7 1 5
# jail
    AREA minecraft:iron_bars        4 0 6    4 2 4 
    AREA minecraft:cobblestone      4 0 3   4 2 1
    BLOCK minecraft:stone_button(2) 3 1 3
    BLOCK minecraft:iron_door(0)    4 0 2
    BLOCK minecraft:iron_door(    4 1 2
  BLOCK minecraft:bed( 6,0,6
  BLOCK minecraft:bed(0) 6,0,5
  BLOCK minecraft:torch(3) 3,2,1
  BLOCK minecraft:torch(4) 3,2,6
END
private plan _tower_bedroom
  BLOCK minecraft:bed(11) 6,0,6
  BLOCK minecraft:bed(3) 5,0,6
  BLOCK minecraft:bookshelf 6 0 5
  BLOCK minecraft:torch(2) 6,2,4
  CHANCE 20
     CALL _tower_window  1 0 7  0
  CHANCE 20
     CALL _tower_window  4 0 7  0
  CHANCE 20
     CALL _tower_window  7 0 6  3
  CHANCE 20
     CALL _tower_window  7 0 3  3
  CHANCE 20
     CALL _tower_window  3 0 0  2
  CHANCE 10
     CALL _tower_windowledge  6 0 0  2
END
private plan _tower_diningrm
  BLOCK minecraft:fence 4,0,4
  BLOCK minecraft:wooden_pressure_plate 4,1,4
  BLOCK minecraft:fence 4,0,3
  BLOCK minecraft:wooden_pressure_plate 4,1,3
  BLOCK minecraft:torch(3) 4,2,1
  BLOCK minecraft:torch(4) 4,2,6
  BLOCK minecraft:torch(2) 6,2,4
  CHANCE 20
     CALL _tower_window  1 0 7  0
  CHANCE 20
     CALL _tower_window  4 0 7  0
  CHANCE 20
     CALL _tower_window  7 0 6  3
  CHANCE 20
     CALL _tower_window  7 0 3  3
  CHANCE 20
     CALL _tower_window  6 0 0  2
  CHANCE 20
     CALL _tower_window  3 0 0  2
END
private plan _tower_empty
  CHANCE 75
BLOCK minecraft:web     1 2 6
  CHANCE 75
BLOCK minecraft:web     6 2 6
  CHANCE 75
BLOCK minecraft:web     6 2 1
  CHANCE 15
     CALL _tower_balcony  1 0 7  0
  CHANCE 15
     CALL _tower_balcony  4 0 7  0
  CHANCE 15
     CALL _tower_balcony  7 0 6  3
  CHANCE 15
     CALL _tower_balcony  7 0 3  3
  CHANCE 15
     CALL _tower_balcony  6 0 0  2
  CHANCE 15
     CALL _tower_balcony  3 0 0  2
END
private plan _tower_open
  AREA minecraft:air 3 -1 3    4 -1 4
  AREA minecraft:fence 2 0 2  5 0 2
  AREA minecraft:fence 2 0 5  5 0 5
  AREA minecraft:fence 2 0 3  2 0 4
  AREA minecraft:fence 5 0 3  5 0 4
  BLOCK minecraft:torch(3) 4,2,1
  BLOCK minecraft:torch(4) 4,2,6
  BLOCK minecraft:torch(2) 6,2,4
  CHANCE 20
     CALL _tower_window  1 0 7  0
  CHANCE 20
     CALL _tower_window  4 0 7  0
  CHANCE 20
     CALL _tower_window  7 0 6  3
  CHANCE 20
     CALL _tower_window  7 0 3  3
  CHANCE 20
     CALL _tower_window  6 0 0  2
  CHANCE 20
     CALL _tower_window  3 0 0  2
END

# randomly select some contents for the room
private plan _tower_room_contents

    RANDOM 8
CALL _tower_diningrm 0 0 0  0
CALL _tower_library  0 0 0  0
CALL _tower_bedroom  0 0 0  0
CALL _tower_diningrm 0 0 0  0
CALL _tower_jail     0 0 0  0
CALL _tower_open     0 0 0  0
CALL _tower_empty    0 0 0  0
CALL _tower_half     0 0 0  0

END

private plan _tower_room
    CALL _tower_floor 0 0 0  0
    CALL _tower_walls 0 0 0  0

    BLOCK minecraft:glass_pane 2 1 7
    BLOCK minecraft:glass_pane 5 1 7
    BLOCK minecraft:glass_pane 2 1 0
    BLOCK minecraft:glass_pane 5 1 0
    BLOCK minecraft:glass_pane 7 1 2
    BLOCK minecraft:glass_pane 7 1 5
    BLOCK minecraft:glass_pane 0 1 2
    BLOCK minecraft:glass_pane 0 1 5

# pick a random contents for this room
    CALL _tower_room_contents 0 0 0  0

# above it can be either another room, or the roof
    RANDOM 3
        CALL _tower_room 0 4 0  0
        CALL _tower_room 0 4 0  0
        CALL _tower_roof 0 4 0  0

END

# Build the tower.  Start with the ground floor, 
# then build a room above and recurse.
# This may take several seconds to complete.
public plan tower  A randomly high tower
   CALL _tower_ground -4 0 1  0
   CALL _tower_room   -4 4 1  0
END

 

Posted

Finally managed to get it to compile, and work, under Minecraft 1.8.  Not as easy as I'd hoped by any means...  the new BlockState way of handling things is awkward, to say the least, not to mention the problematic way of specifying textures.

 

Anyway, will shortly post mod v0.3 with support for both Minecraft 1.7.10 and 1.8.0

 

Have also fixed the problem with torches/trapdoors/signs occasionally falling off the walls.

Posted

It might be possible to hook this into the world generation hooks, so that specified plans are randomly generated during world generation.  A plan could be enabled for autogeneration using an Option flag, with a probability and valid biomes in which it may appear; then, you'd be able to customise the autogenerated structures easily.  I'm not sure how simple this would be to do; it also changes the focus of the mod from being one used by a builder and then removed before playing, to being one intended to be permanently loaded.

 

It would also be necessary to have a module cfg file (separate from the blueprint files) to enable or disable such things are the wand crafting recipie, autogeneration, and so on.

  • 2 weeks later...
Posted

Version 1.0, for both Minecraft 1.7.10 and 1.8, is now released (link in the first posting).  This includes a large blueprint library, as well as the ability to auto-create blueprints in new chunks.

  • 3 weeks later...
Posted

Version 2.0 is now in beta, for Minecraft 1.8 only

 

This includes new directives to allow placing of Chests with randomised contents and Spawners with randomised and customised mobs; you can also specify metadata, chests, items, spawners and mob using NBT files instead of JSON.

 

There are a few more provided blueprints, as well.

 

The Blueprint Java package is now properly packaged up in a separate heirachy from the module so that it is portable and reuseable by other modules.  A number of instances of bad coding have been rewritten, and the module used BlockPos and NBTTagCompound objects internally.

Posted

In Minecraft 1.8, things are a lot easier because you can use the generic blockstate to give you an Enum for direction, which can be used to rotate.  As long as orientable userdefined blocks use the standard EnumDirection or EnumOrientation (which is highly likely) then it is possible to make a generic rotation function... of course, there will always be a few exceptions, which end up not rotating.

 

For 1.7, I handled rotation in the same way as the code example you linked to -- with a special rotate function that takes the DV and returns a rotated on for the specified block type, using many If statements.  Highly non-ideal, but all you can do, I think.  I wish that Mojang has standardised on a sngle way to specify orientation back at the beginning :(

 

Having an option in the module cfg file to customise <blockname>=<bitmask>,<dv>,<dv>,<dv>,<dv> or <blockname>=<statename>,<valuelist> to specify the n/s/e/w DV values might be the way to go for custom blocks with orientation.

Posted

Version 2.1 (beta1) is now available. 

 

This allows chests to be defined using this sort of syntax:

 

  CHEST 1 2 3  2  stick,0,5;50 minecraft:silk,6;90

 

This gives you a 50% chance of 0-5 sticks, and a 90% chance of 6 pieces of string.  You can also use NBT either inline or in external files to specifiy either an item or the entire chest.

 

Similarly, you can define spawners to have multiple weights and source by name or from external files:

 

  SPAWNER 1 2 3  Skeleton;10 Zombie;10 externalfile.nbt;20

 

Some examples are shipped with the module.

Posted

Version 2.2 is now released, with source for both 1.7.10 and 1.8

 

This adds the MOB directive, allowing blueprints to include minecarts, armour stands, zombies and so on; the /bp copy command will copy mobs in the region as well.

 

You can also specify blocks as MetaBlocks, such as OLD_STONE.  This will resolve to a different block depending on biome and randomness to give a more realistic look (thanks to the coders of mcDungeon for this idea!)

 

Pick up from http://www.steveshipway.org/mc/builders-helper-2.2.zip

Posted

Next enhancements --

 

1. an IFBIOME directive, to branch on certain biome matches (so you can have dcompletely different structures in different biomes form the same blueprint)

2. an IFBLOCK <x><y><z> <id> directive, to branch if the block at a certain relative position matches (so you can have a structure that continues until a condition is met, such as a tunnel ending on the other side of a hill, or a bridge pier ending at ground level.

 

eg.

 

PUBLIC PLAN village
CALL meta_cottage 0 0 0 0
IFBIOME Desert
  CALL 10 0 10 0 desert_well
  CALL 10 0 10 0 other_well
END

PUBLIC PLAN tunnel_section
IFBLOCK 10 0 0 minecraft:air
  NOOP
  CALL tunnel_section 10 0 0 0
CALL build_section 0 0 0 0
END

  • 2 weeks later...
Posted

Version 2.3.1 is now available, and implements the IFBIOME and IFBLOCK tests.  This now supports 1.7.10 and 1.8, and fixes the issues with metablocks not always working as well as the issues with log rotation in 1.8.

Posted

To copy a structure in-game:

  1. [*]Hold the Wand, or be in Creative mode

[*]Use the command:

/bp copy myname x1 y1 z1 x2 y2 z2

Replace myname with the name you want to store the new blueprint under. The coordinates are for opposite corners of the box to copy; so "1 2 3 4 5 6" will copy from block 1,2,3 to block 4,5,6 (a 3x3x3 cube). It will not copy Air blocks.

[*]You can now use

 /wand set myname 

to make the wand produce your newly copied blocks when you right-click at a location.

[*]Use

 /bp savemyname

to save your new blueprint to disk as

confg/bp/myname.cfg

. This will make it persist after game restarts.

[*]Note that the 'origin' as defined by a

 /bp copy 

may not be precisely where you want it to be. In this case, you can edit the new blueprint file to wrap the new plan in another plan that simply does an offset and/or rotation. See the cottage.cfg example blueprint for a demonstration of this.

To use the wand:

  1. [*]The wand is initially not set to do anything. You need to "enchant" it (I.E., associate it with an existing Blueprint).

[*]Use

/bp list 

to list the Public blueprints.

[*]Use

/wand set name

to set the wand to produce a specific blueprint. This works with public or private blueprints.

[*]Right-click (use) the wand on a block. You must be targetting a block; just clicking in the air does nothing. This will create the specified structure at this point.

[*]You may need to wait a few seconds for the structure to appear, depending on the complexity of the structure, or the speed of your server. A chat message will tell you when the build is completed (or if it failed for any reason).

Using Blueprints

  1. [*]A
blueprint is a file containing one or more plans, which contain sequences of instructions to create a structure. The directory of blueprints is called the portfolio.

  [*]A particular plan may call one or more other plans multiple times; in fact, this is a recommended way to define structures. The sub-plans can be marked 'private', which means their names do not normally display when listing plans.

[*]A plan may be marked as 'autocreate' with a probability and biome list. This is used by the autogenerator to randomly create this structure in the world as new chunks are defined.

[*]Blueprints can be created by the

/bp save

command, usually after running

/bp copy

to copy something in-world. However, it is usually more efficient to write or edit them by hand.

[*]The Blueprint language is structured similarly to the language Logo. It has basic testing and branching, and can use 'soft' blocks (which only place in Air) or 'meta' blocks (which have an element of randomness or dependence on biome). The language is detailed in the readme.cfg sample blueprint; there are also many other example blueprints provided to help you.

[*]Plans in one blueprint may call plans from another; however this is not generally recommended as you cannot be certain which order they will be evaluated in. It is best to keep all related plans in a single blueprint file. Also, it is Best Practice (though not required) to prefix private plans with an underscore, and have all plans in a blueprint with a common prefix -- for example, "hut", "_hut_roof", "_hut_window".

[*]Be careful with recursion. An infinitely-recurring plan will hang the server thread (this will be hopefully prevented in a future release)

 

I hope this helps! Documentation is slowly being written. I'm hoping that other module writers may pick up on the blueprint language as being a convenient way to define structures, and it could become a common language for exchanging structural definitions.

 

  • 2 weeks later...
Posted

Version 2.3.2 is now available.

 

This fixes some bugs, and adds the MSG and PICTURE directives.  You can now create maps displaying the pictures from external image files!

  • 4 weeks later...
Posted

Version 2.4 is available from http://www.steveshipway.org/mc/builders-helper-2.4.zip

 

Changes:

 

    You can select the area to copy using right-click on the wand, rather than having to type in the coordinates.

    It also adds support for Ruins Templates (from the Ruins mod); these are automatically converted to Blueprint format and made available.

    Additional blueprints added

    Corrections to Float and Soft code

    Support for ChestGenHooks

 

  • 3 weeks later...
  • 1 month later...
Posted

When you use /wand copy, instead of /bp copy, you click on the lower corners of the volume to be copied, and the height is automatically worked out by coming down until it hits a hard block.  The lower Y coordinate is the minimum of the two clicked corners.

 

So, if you click on [10,60,0] and [15,65,5]  then the volume copied will be [10-15,60-H,0-5] where H is the highest block in the [10-15,0-5] column - which may well be 100 if there is something up that high.  It works this way because you cannot click on an air block, and usually the top of your structure volume will have air in the corners.

 

If you want to copy a specific volume, you can use /bp copy to specify the exact corners.  The /wand copy command is intended to make things easier when copying an outside structure with nothing else above it.

 

The problem might occur if you have an overhanging cliff, or a tree, or something floating in the air 69 blocks above you.  Then you'll end up copying higher than you intended - though you could save with /bp save and subsequently edit the saved .bp file in a text editor and remove the offending block(s), before doing a /bp load to reload the blueprints.

 

 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Please post logs as described in the FAQ (https://forums.minecraftforge.net/topic/125488-rules-and-frequently-asked-questions-faq/), they will contain information that may help.  
    • I've been trying to find a solution for this for the past few days and cant seem to find it anywhere.   What i want to do is basically set my player's head pitch without the server noticing it. Basically client-side change.   Is there a way to do this? With mixins or anything else?   Thanks in advance.
    • Did you ever find a solution to this
    • I have followed a tutorial on how to generate ores for my mod though the data files have not been generated despite me running data in my IDE.  I have looked over and compared my code multiple times and the only differences are either with the IDs or with unnecessary code because of what my mod is (The mod is for the End so I don't need the Overworld or Nether ores), my folders are all in the right structure and no warnings are present when ran. I have been trying to figure this out for a few days now so help would be much appreciated.  The tutorial I was following.  My code -  public class ModBiomeModifiers { public static final ResourceKey<BiomeModifier> ADD_GAZITE_ORE = registerKey("add_gazite_ore"); public static final ResourceKey<BiomeModifier> TRANSCENDINE_GAZITE_ORE = registerKey("add_transcendine_ore"); public static void bootstrap(BootstrapContext<BiomeModifier> context) { var placedFeature = context.lookup(Registries.PLACED_FEATURE); var biomes = context.lookup(Registries.BIOME); context.register(ADD_GAZITE_ORE, new ForgeBiomeModifiers.AddFeaturesBiomeModifier( biomes.getOrThrow(BiomeTags.IS_END), HolderSet.direct(placedFeature.getOrThrow(ModPlacedFeatures.GAZITE_ORE_PLACED_KEY)), GenerationStep.Decoration.UNDERGROUND_ORES)); context.register(TRANSCENDINE_GAZITE_ORE, new ForgeBiomeModifiers.AddFeaturesBiomeModifier( biomes.getOrThrow(BiomeTags.IS_END), HolderSet.direct(placedFeature.getOrThrow(ModPlacedFeatures.TRANSCENDINE_ORE_PLACED_KEY)), GenerationStep.Decoration.UNDERGROUND_ORES)); } private static ResourceKey<BiomeModifier> registerKey(String name) { return ResourceKey.create(ForgeRegistries.Keys.BIOME_MODIFIERS, ResourceLocation.fromNamespaceAndPath(EchoingEnd.MOD_ID, name)); } } The tutorial's code -  public class ModBiomeModifiers { public static final ResourceKey<BiomeModifier> ADD_ALEXANDRITE_ORE = registerKey("add_alexandrite_ore"); public static final ResourceKey<BiomeModifier> ADD_NETHER_ALEXANDRITE_ORE = registerKey("add_nether_alexandrite_ore"); public static final ResourceKey<BiomeModifier> ADD_END_ALEXANDRITE_ORE = registerKey("add_end_alexandrite_ore"); public static void bootstrap(BootstrapContext<BiomeModifier> context) { var placedFeature = context.lookup(Registries.PLACED_FEATURE); var biomes = context.lookup(Registries.BIOME); context.register(ADD_ALEXANDRITE_ORE, new ForgeBiomeModifiers.AddFeaturesBiomeModifier( biomes.getOrThrow(BiomeTags.IS_OVERWORLD), HolderSet.direct(placedFeature.getOrThrow(ModPlacedFeatures.ALEXANDRITE_ORE_PLACED_KEY)), GenerationStep.Decoration.UNDERGROUND_ORES)); // Individual Biomes // context.register(ADD_ALEXANDRITE_ORE, new ForgeBiomeModifiers.AddFeaturesBiomeModifier( // HolderSet.direct(biomes.getOrThrow(Biomes.PLAINS), biomes.getOrThrow(Biomes.BAMBOO_JUNGLE)), // HolderSet.direct(placedFeature.getOrThrow(ModPlacedFeatures.ALEXANDRITE_ORE_PLACED_KEY)), // GenerationStep.Decoration.UNDERGROUND_ORES)); context.register(ADD_NETHER_ALEXANDRITE_ORE, new ForgeBiomeModifiers.AddFeaturesBiomeModifier( biomes.getOrThrow(BiomeTags.IS_NETHER), HolderSet.direct(placedFeature.getOrThrow(ModPlacedFeatures.NETHER_ALEXANDRITE_ORE_PLACED_KEY)), GenerationStep.Decoration.UNDERGROUND_ORES)); context.register(ADD_END_ALEXANDRITE_ORE, new ForgeBiomeModifiers.AddFeaturesBiomeModifier( biomes.getOrThrow(BiomeTags.IS_END), HolderSet.direct(placedFeature.getOrThrow(ModPlacedFeatures.END_ALEXANDRITE_ORE_PLACED_KEY)), GenerationStep.Decoration.UNDERGROUND_ORES)); } private static ResourceKey<BiomeModifier> registerKey(String name) { return ResourceKey.create(ForgeRegistries.Keys.BIOME_MODIFIERS, ResourceLocation.fromNamespaceAndPath(TutorialMod.MOD_ID, name)); } }   ModConfiguredFeatures:   My code -  public class ModConfiguredFeatures { public static final ResourceKey<ConfiguredFeature<?, ?>> GAZITE_ORE_KEY = registerKey("gazite_ore"); public static final ResourceKey<ConfiguredFeature<?, ?>> TRANSCENDINE_ORE_KEY = registerKey("transcendine_ore"); public static void bootstrap(BootstrapContext<ConfiguredFeature<?, ?>> context) { RuleTest endReplaceables = new BlockMatchTest(Blocks.END_STONE); register(context, GAZITE_ORE_KEY, Feature.ORE, new OreConfiguration(endReplaceables, ModBlocks.GAZITE_ORE.get().defaultBlockState(), 4)); register(context, TRANSCENDINE_ORE_KEY, Feature.ORE, new OreConfiguration(endReplaceables, ModBlocks.TRANSCENDINE_ORE.get().defaultBlockState(), 8)); List<OreConfiguration.TargetBlockState> EndOres = List.of( OreConfiguration.target(endReplaceables, ModBlocks.GAZITE_ORE.get().defaultBlockState()), OreConfiguration.target(endReplaceables, ModBlocks.TRANSCENDINE_ORE.get().defaultBlockState())); } public static ResourceKey<ConfiguredFeature<?, ?>> registerKey(String name) { return ResourceKey.create(Registries.CONFIGURED_FEATURE, ResourceLocation.fromNamespaceAndPath(EchoingEnd.MOD_ID, name)); } private static <FC extends FeatureConfiguration, F extends Feature<FC>> void register(BootstrapContext<ConfiguredFeature<?, ?>> context, ResourceKey<ConfiguredFeature<?, ?>> key, F feature, FC configuration) { context.register(key, new ConfiguredFeature<>(feature, configuration)); } }   The tutorial's code - public class ModConfiguredFeatures { public static final ResourceKey<ConfiguredFeature<?, ?>> OVERWORLD_ALEXANDRITE_ORE_KEY = registerKey("alexandrite_ore"); public static final ResourceKey<ConfiguredFeature<?, ?>> NETHER_ALEXANDRITE_ORE_KEY = registerKey("nether_alexandrite_ore"); public static final ResourceKey<ConfiguredFeature<?, ?>> END_ALEXANDRITE_ORE_KEY = registerKey("end_alexandrite_ore"); public static void bootstrap(BootstrapContext<ConfiguredFeature<?, ?>> context) { RuleTest stoneReplaceables = new TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES); RuleTest deepslateReplaceables = new TagMatchTest(BlockTags.DEEPSLATE_ORE_REPLACEABLES); RuleTest netherrackReplaceables = new BlockMatchTest(Blocks.NETHERRACK); RuleTest endReplaceables = new BlockMatchTest(Blocks.END_STONE); List<OreConfiguration.TargetBlockState> overworldAlexandriteOres = List.of( OreConfiguration.target(stoneReplaceables, ModBlocks.ALEXANDRITE_ORE.get().defaultBlockState()), OreConfiguration.target(deepslateReplaceables, ModBlocks.ALEXANDRITE_DEEPSLATE_ORE.get().defaultBlockState())); register(context, OVERWORLD_ALEXANDRITE_ORE_KEY, Feature.ORE, new OreConfiguration(overworldAlexandriteOres, 9)); register(context, NETHER_ALEXANDRITE_ORE_KEY, Feature.ORE, new OreConfiguration(netherrackReplaceables, ModBlocks.ALEXANDRITE_NETHER_ORE.get().defaultBlockState(), 9)); register(context, END_ALEXANDRITE_ORE_KEY, Feature.ORE, new OreConfiguration(endReplaceables, ModBlocks.ALEXANDRITE_END_ORE.get().defaultBlockState(), 9)); } public static ResourceKey<ConfiguredFeature<?, ?>> registerKey(String name) { return ResourceKey.create(Registries.CONFIGURED_FEATURE, ResourceLocation.fromNamespaceAndPath(TutorialMod.MOD_ID, name)); } private static <FC extends FeatureConfiguration, F extends Feature<FC>> void register(BootstrapContext<ConfiguredFeature<?, ?>> context, ResourceKey<ConfiguredFeature<?, ?>> key, F feature, FC configuration) { context.register(key, new ConfiguredFeature<>(feature, configuration)); } }   ModPlacedFeatures:   My code - public class ModPlacedFeatures { public static final ResourceKey<PlacedFeature> GAZITE_ORE_PLACED_KEY = registerKey("gazite_ore_placed"); public static final ResourceKey<PlacedFeature> TRANSCENDINE_ORE_PLACED_KEY = registerKey("transcendine_ore_placed"); public static void bootstrap(BootstrapContext<PlacedFeature> context) { var configuredFeatures = context.lookup(Registries.CONFIGURED_FEATURE); register(context, GAZITE_ORE_PLACED_KEY, configuredFeatures.getOrThrow(ModConfiguredFeatures.GAZITE_ORE_KEY), ModOrePlacement.commonOrePlacement(9, HeightRangePlacement.uniform(VerticalAnchor.absolute(-64), VerticalAnchor.absolute(71)))); register(context, TRANSCENDINE_ORE_PLACED_KEY, configuredFeatures.getOrThrow(ModConfiguredFeatures.GAZITE_ORE_KEY), ModOrePlacement.rareOrePlacement(6, HeightRangePlacement.uniform(VerticalAnchor.absolute(-32), VerticalAnchor.absolute(71)))); } private static ResourceKey<PlacedFeature> registerKey(String name) { return ResourceKey.create(Registries.PLACED_FEATURE, ResourceLocation.fromNamespaceAndPath(EchoingEnd.MOD_ID, name)); } private static void register(BootstrapContext<PlacedFeature> context, ResourceKey<PlacedFeature> key, Holder<ConfiguredFeature<?, ?>> configuration, List<PlacementModifier> modifiers) { context.register(key, new PlacedFeature(configuration, List.copyOf(modifiers))); } }   the tutorial's code -  public class ModPlacedFeatures { public static final ResourceKey<PlacedFeature> ALEXANDRITE_ORE_PLACED_KEY = registerKey("alexandrite_ore_placed"); public static final ResourceKey<PlacedFeature> NETHER_ALEXANDRITE_ORE_PLACED_KEY = registerKey("nether_alexandrite_ore_placed"); public static final ResourceKey<PlacedFeature> END_ALEXANDRITE_ORE_PLACED_KEY = registerKey("end_alexandrite_ore_placed"); public static void bootstrap(BootstrapContext<PlacedFeature> context) { var configuredFeatures = context.lookup(Registries.CONFIGURED_FEATURE); register(context, ALEXANDRITE_ORE_PLACED_KEY, configuredFeatures.getOrThrow(ModConfiguredFeatures.OVERWORLD_ALEXANDRITE_ORE_KEY), ModOrePlacement.commonOrePlacement(12, HeightRangePlacement.uniform(VerticalAnchor.absolute(-64), VerticalAnchor.absolute(80)))); register(context, NETHER_ALEXANDRITE_ORE_PLACED_KEY, configuredFeatures.getOrThrow(ModConfiguredFeatures.NETHER_ALEXANDRITE_ORE_KEY), ModOrePlacement.commonOrePlacement(12, HeightRangePlacement.uniform(VerticalAnchor.absolute(-64), VerticalAnchor.absolute(80)))); register(context, END_ALEXANDRITE_ORE_PLACED_KEY, configuredFeatures.getOrThrow(ModConfiguredFeatures.END_ALEXANDRITE_ORE_KEY), ModOrePlacement.commonOrePlacement(12, HeightRangePlacement.uniform(VerticalAnchor.absolute(-64), VerticalAnchor.absolute(80)))); } private static ResourceKey<PlacedFeature> registerKey(String name) { return ResourceKey.create(Registries.PLACED_FEATURE, ResourceLocation.fromNamespaceAndPath(TutorialMod.MOD_ID, name)); } private static void register(BootstrapContext<PlacedFeature> context, ResourceKey<PlacedFeature> key, Holder<ConfiguredFeature<?, ?>> configuration, List<PlacementModifier> modifiers) { context.register(key, new PlacedFeature(configuration, List.copyOf(modifiers))); } }   ModOrePlacement:   My code -  public class ModOrePlacement { public static List<PlacementModifier> orePlacement(PlacementModifier pCountPlacement, PlacementModifier pHeightRange) { return List.of(pCountPlacement, InSquarePlacement.spread(), pHeightRange, BiomeFilter.biome()); } public static List<PlacementModifier> commonOrePlacement(int pCount, PlacementModifier pHeightRange) { return orePlacement(CountPlacement.of(pCount), pHeightRange); } public static List<PlacementModifier> rareOrePlacement(int pChance, PlacementModifier pHeightRange) { return orePlacement(RarityFilter.onAverageOnceEvery(pChance), pHeightRange); } }   The tutorial's code -  public class ModOrePlacement { public static List<PlacementModifier> orePlacement(PlacementModifier pCountPlacement, PlacementModifier pHeightRange) { return List.of(pCountPlacement, InSquarePlacement.spread(), pHeightRange, BiomeFilter.biome()); } public static List<PlacementModifier> commonOrePlacement(int pCount, PlacementModifier pHeightRange) { return orePlacement(CountPlacement.of(pCount), pHeightRange); } public static List<PlacementModifier> rareOrePlacement(int pChance, PlacementModifier pHeightRange) { return orePlacement(RarityFilter.onAverageOnceEvery(pChance), pHeightRange); } }  
    • I'm creating a modpack, and i just discovered that if i try to connect to a server it gives the error: Internal Exception: io.netty.handler.codec.DecoderException: java.lang.negativearraysizeexception -1   The client log:  
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.