Skip to content

Commit

Permalink
Add alter() command and refactor to enable block to do all the block …
Browse files Browse the repository at this point in the history
…setting commands.
  • Loading branch information
r1chardj0n3s committed Jan 7, 2017
1 parent 0471e16 commit 3291d02
Show file tree
Hide file tree
Showing 9 changed files with 504 additions and 290 deletions.
28 changes: 24 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,23 @@ More complete docs TBD::
hand.forward(10)
# hand is now back at pos, and has the same facing

hand.water() # only if clear
hand.lava() # only if clear
hand.clear()
Putting Down Blocks
-------------------

Python Blocks and Hands may place blocks in the world. They both have the same
methos listed below, the only difference is that blocks have a "pos" first argument,
so for example, placing a ladder::

hand.ladder(8, 'ladder') # place a bunch of the block in a vertical line
block.ladder(pos.up(), 8, 'ladder') # place the ladder on top of this block

Note that it is possible to place a block in the same position as the Python Block
which will remove it from the game!

The block placement functions are::

hand.put('cobblestone') # the REFERENCE.txt file lists block names
hand.clear() # set to air - hand.put('air')
hand.line(5, 'stone')
hand.ladder(8, 'ladder') # place a bunch of the block in a vertical line
hand.wall(5, 3, 'planks') # depth, height
Expand Down Expand Up @@ -247,7 +259,10 @@ Block variations are handled through keyword arguments. All of the above block-
placing functions accept the following keywords::

# different plank types
hand.put('plank', type='acacia')
hand.put('planks', type='acacia')

# if you use an invalid keyword, it will fail
hand.put('planks', color='red')

# different stone slab types
hand.put('stone_slab', type='quartz', half='top')
Expand All @@ -269,6 +284,11 @@ placing functions accept the following keywords::
hand.put('oak_stairs', facing='left', # or right, back, and cardinals
half='top', shape='outer_right')

You may alter block variations after they've been put down::

hand.put('wool', color='red')
hand.alter(color='yellow') # any of the keywords above are acceptable

Roof styles include "hip", "gable" and "box-gable" (filled gable). To get a box gable
with overhang you could::

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public boolean has(String name) {
return this.args.containsKey(name);
}

private PyObject get(String name) {
public PyObject get(String name) {
PyObject value = this.args.get(name);
if(value == null) {
throw Py.TypeError(String.format("Missing argument to %s(): %s",
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/net/mechanicalcat/pycode/script/BaseMethods.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,20 @@
package net.mechanicalcat.pycode.script;

import net.minecraft.block.Block;
import net.minecraft.block.BlockBed;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.state.IBlockState;
import net.minecraft.command.CommandException;
import net.minecraft.command.server.CommandAchievement;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemDoor;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

Expand All @@ -46,6 +52,31 @@ protected BaseMethods(World world, EntityPlayer player) {
this.player = player;
}

protected void put(BlockPos pos, IBlockState block_state, EnumFacing facing) {
Block block = block_state.getBlock();

FMLLog.info("Putting %s at %s", block_state, pos);

// handle special cases
if (block instanceof BlockDoor) {
ItemDoor.placeDoor(this.world, pos, facing, block, true);
} else if (block instanceof BlockBed) {
BlockPos headpos = pos.offset(facing);
if (this.world.getBlockState(pos.down()).isSideSolid(this.world, pos.down(), EnumFacing.UP) &&
this.world.getBlockState(headpos.down()).isSideSolid(this.world, headpos.down(), EnumFacing.UP)) {
block_state = block_state
.withProperty(BlockBed.OCCUPIED, false).withProperty(BlockBed.FACING, facing)
.withProperty(BlockBed.PART, BlockBed.EnumPartType.FOOT);
if (this.world.setBlockState(pos, block_state, 11)) {
block_state = block_state.withProperty(BlockBed.PART, BlockBed.EnumPartType.HEAD);
this.world.setBlockState(headpos, block_state, 11);
}
}
} else {
this.world.setBlockState(pos, block_state);
}
}

public void achievement(String... args) throws CommandException {
CommandAchievement achiev = new CommandAchievement();
WorldServer ws = (WorldServer)this.world;
Expand Down
108 changes: 108 additions & 0 deletions src/main/java/net/mechanicalcat/pycode/script/BlockMethods.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import net.mechanicalcat.pycode.entities.EntityEnum;
import net.mechanicalcat.pycode.tileentity.PyCodeBlockTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityFireworkRocket;
import net.minecraft.entity.player.EntityPlayer;
Expand All @@ -39,11 +40,13 @@
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.fml.common.registry.GameData;
import org.python.core.Py;
import org.python.core.PyObject;

import java.util.List;
Expand Down Expand Up @@ -100,4 +103,109 @@ public void spawn(String entityName) throws EntityNameError {
if (this.world.isRemote) return;
entityType.spawn(this.world, this.block.getPos().add(0.5, 1.0, 0.5));
}

// this is just a little crazypants
private String[] s(String ... strings) {
return strings;
}

public void put(PyObject[] args, String[] kws) {
if (this.world == null || this.world.isRemote) return;
ArgParser r = new ArgParser("put", s("pos", "blockname"), PyRegistry.BLOCK_VARIATIONS);
r.parse(args, kws);
MyBlockPos mpos = (MyBlockPos)r.get("pos").__tojava__(MyBlockPos.class);
BlockPos pos = mpos.blockPos;
EnumFacing facing = EnumFacing.NORTH;
IBlockState state = PyRegistry.getBlockVariant(r, pos, facing, (WorldServer)this.world);
this.put(pos, state, facing);
}

public void alter(PyObject[] args, String[] kws) {
if (this.world == null || this.world.isRemote) return;
ArgParser r = new ArgParser("put", s("pos"), PyRegistry.BLOCK_VARIATIONS);
r.parse(args, kws);
MyBlockPos mpos = (MyBlockPos)r.get("pos").__tojava__(MyBlockPos.class);
BlockPos pos = mpos.blockPos;
IBlockState state = this.world.getBlockState(pos);
EnumFacing facing = PyRegistry.getBlockFacing(state);
IBlockState modified = PyRegistry.modifyBlockStateFromSpec(state, r, facing);
if (state != modified) {
this.world.setBlockState(pos, modified);
}
}

public void clear(MyBlockPos pos) {
this.clear(pos.blockPos);
}
public void clear(BlockPos pos) {
if (this.world == null || this.world.isRemote) return;
Block b = this.world.getBlockState(pos).getBlock();
if (!this.world.isAirBlock(pos)) {
this.world.setBlockState(pos, Blocks.AIR.getDefaultState());
}
}

public void line(PyObject[] args, String[] kws) {
ArgParser r = new ArgParser("line", s("pos", "distance", "blockname"),
PyRegistry.BLOCK_VARIATIONS);
r.parse(args, kws);
MyBlockPos mpos = (MyBlockPos)r.get("pos").__tojava__(MyBlockPos.class);
ShapeGen.line(r, this.world, mpos.blockPos, EnumFacing.NORTH);
}

public void ladder(PyObject[] args, String[] kws) {
if (this.world == null || this.world.isRemote) return;
ArgParser r = new ArgParser("line", s("pos", "height", "blockname"),
PyRegistry.BLOCK_VARIATIONS);
r.parse(args, kws);
MyBlockPos mpos = (MyBlockPos)r.get("pos").__tojava__(MyBlockPos.class);
ShapeGen.ladder(r, this.world, mpos.blockPos, EnumFacing.NORTH);
}

public void floor(PyObject[] args, String[] kws) {
if (this.world == null || this.world.isRemote) return;
ArgParser r = new ArgParser("line", s("pos", "width", "depth", "blockname"),
PyRegistry.BLOCK_VARIATIONS);
r.parse(args, kws);
MyBlockPos mpos = (MyBlockPos)r.get("pos").__tojava__(MyBlockPos.class);
ShapeGen.floor(r, this.world, mpos.blockPos, EnumFacing.NORTH);
}

public void wall(PyObject[] args, String[] kws) {
if (this.world == null || this.world.isRemote) return;
ArgParser r = new ArgParser("line", s("pos", "depth", "height", "blockname"),
PyRegistry.BLOCK_VARIATIONS);
r.parse(args, kws);
MyBlockPos mpos = (MyBlockPos)r.get("pos").__tojava__(MyBlockPos.class);
ShapeGen.wall(r, this.world, mpos.blockPos, EnumFacing.NORTH);
}

public void cube(PyObject[] args, String[] kws) {
if (this.world == null || this.world.isRemote) return;
ArgParser r = new ArgParser("line", s("pos", "width", "depth", "height", "blockname"),
PyRegistry.BLOCK_VARIATIONS);
r.parse(args, kws);
MyBlockPos mpos = (MyBlockPos)r.get("pos").__tojava__(MyBlockPos.class);
ShapeGen.cube(r, this.world, mpos.blockPos, EnumFacing.NORTH);
}

public void circle(PyObject[] args, String[] kws) {
if (this.world == null || this.world.isRemote) return;
ArgParser r = new ArgParser("line", s("pos", "radius", "blockname"),
// TODO PyRegistry.BLOCK_VARIATIONS
s("color", "facing", "type", "half", "shape", "fill"));
r.parse(args, kws);
MyBlockPos mpos = (MyBlockPos)r.get("pos").__tojava__(MyBlockPos.class);
ShapeGen.circle(r, this.world, mpos.blockPos, EnumFacing.NORTH);
}

public void roof(PyObject[] args, String[] kws) throws BlockTypeError {
if (this.world == null || this.world.isRemote) return;
ArgParser r = new ArgParser("roof", s("pos", "width", "depth", "blockname"),
// TODO PyRegistry.BLOCK_VARIATIONS
s("style", "color", "facing", "type", "half", "shape"));
r.parse(args, kws);
MyBlockPos mpos = (MyBlockPos)r.get("pos").__tojava__(MyBlockPos.class);
RoofGen.roof(r, this.world, mpos.blockPos, EnumFacing.NORTH);
}
}
Loading

0 comments on commit 3291d02

Please sign in to comment.