Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GSoC: change pollBlockHits and add example #18

Merged
merged 9 commits into from
Jun 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,5 @@ getTile() # return a tuple of integers (x, y, z), for the tile on which the pla
setTile(pos::Tuple{Real, Real, Real}) # move the player to the tile specified by the integer coordinates
getPos() # return a tuple of floats (x, y, z) with the player's position
setPos(pos::Tuple{Real, Real, Real}) # move the player to the specified coordinates

pollBlockHits() #Return an Array of hit events. ((x,y,z), faceId, entityId)
```
24 changes: 17 additions & 7 deletions example/safeFeet.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
# Walk over water and air by replacing it with Dimaond Blocks
# Usage:
# t = now()
# while (now() - t).value/1000 < time_period
# safeFeet()
# end

using PiCraft

function safeFeet()
x,y,z = player.getTile()
b = world.getBlock(x,y-1, z)
if b == PiCraft.AIR || b == PiCraft.WATER_STATIONARY || b == PiCraft.WATER_FLOWING
world.setBlock(x, y-1, z, PiCraft.DIAMOND_BLOCK, 1)
end
b = getTile() .+ (0, -1, 0) #Get the Block coordinates on which the player is standing
if getBlock(b) ∈ [PiCraft.AIR, PiCraft.WATER_STATIONARY, PiCraft.WATER_FLOWING, PiCraft.LAVA, PiCraft.LAVA_STATIONARY] #Check if the block is
setBlock(b, PiCraft.DIAMOND_BLOCK)
end
sleep(0.05) #Pause as to not spam the API, results in a smoother experience
end



# Challenge: Use a queue to remove blocks such that the maximum bridge length is 10.
# Your script should automatically remove blocks which had too far behind.
# Enter "\py bridge" for a demonstration
90 changes: 90 additions & 0 deletions example/skyscraperBasic.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Construct a skyscraper

using PiCraft

# Let's first define a few basic parameters for our building
p = getPos() .+ (0, -1, 0)
floors = 5
#length will go in the +ve x direction and width in the +ve z direction
length = 10
width = 15
height = 6

# We're first going to write code to construct a single floor relative to a point
# Then we will use a loop to create a skyscraper
# pseudocode:
# x = start_position
# for i in 1:floors
# buildFloor(x)
# increase x's height by floor's height
# end
# Build a ceiling for the top floor
#
# Now to build a floor
# 1) Make all the walls out of glass panes
# 2) Set the bottom level as floor
# 3) Get Pillars on the corners

function buildFloor(p)
# Set all walls to glass panes
setBlocks(p .+ (1, 0, 1), p .+ (1, height, width), PiCraft.GLASS_PANE)
setBlocks(p .+ (1, 0, 1), p .+ (length, height, 1), PiCraft.GLASS_PANE)
setBlocks(p .+ (1, height, width), p .+(length, 0, width), PiCraft.GLASS_PANE)
setBlocks(p .+ (length, height, width), p .+ (length, 0, 1), PiCraft.GLASS_PANE)

#Set entire floor to Stone Brick
setBlocks(p .+ (1, 0, 1), p .+ (length, 0, width), PiCraft.STONE_BRICK)

#Set 4 Pillars to the corners
setBlocks(p .+ (1, 0, 1), p .+ (1, height, 1), PiCraft.STONE_BRICK)
setBlocks(p .+ (1, 0, width), p .+ (1, height, width), PiCraft.STONE_BRICK)
setBlocks(p .+ (length, 0, 1), p .+ (length, height, 1), PiCraft.STONE_BRICK)
setBlocks(p .+ (length, 0 , width), p .+ (length, height, width), PiCraft.STONE_BRICK)
end

function makeSkyscraper()
for i in 1:floors
buildFloor(p .+ (0, height*i - height, 0))
end
setBlocks(p .+ (1, height*floors, 1), p .+ (length, height*floors, width), PiCraft.IRON_BLOCK) # Set Roof to Iron Block
end

# This building isn't particularly nice and has too much glass. Let's have another go.
# When we use programming to solve a problem there can be multiple solutions to the same
# problem.

# This time let's make the building first and then add windows later

function makeSkyscraper2()
# Make a filled cuboid of Blocks filling the entire building space
setBlocks(p .+ (1, 0, 1), p .+ (length, height*floors + 1, width),Block(251, 0))

# Hollow out the inside of the building
setBlocks(p .+ (2, 1, 2), p .+ (length - 1, height*floors, width - 1), PiCraft.AIR)

# Add wooden flooring
for i in 0:floors
setBlocks(p .+ (2, height*i, 2), p .+ (length - 1, height*i, width - 1), PiCraft.WOOD_PLANKS)
end
# Add window Panes, careful if you change the given building dimensions, the change in coordinates may result
# in unintended consequences.
for i in 0:(floors - 1)
setBlocks(p .+ (1, height*i + 2, floor.((width + 1)/2 - 2)),
p .+ (1, height*i + 4, floor.((width + 1)/2 + 2)), PiCraft.GLASS_PANE)
setBlocks(p .+ (1, height*i + 2, floor.((width + 1)/2 - 2)),
p .+ (1, height*i + 4, floor.((width + 1)/2 + 2)), PiCraft.GLASS_PANE)
end
end

# In our second iteration we made the building better, the code is easier to
# follow through and is less in comparison.
# Now, experiment around writing your own code architecturing your own designs.
# Check out the challenges listed below
# Challenges :
# 1) Make the building well lit with torches
# 2) Add a balcony to each floor.
# 3) A common ladder access for all floors.
# 4) Add randomness to your design
# Hint: for all blocks in building
# if block is cobblestone and rand() < 0.1
# set block to Mossy Cobblestone
22 changes: 22 additions & 0 deletions example/turnToGold.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Turn blocks to gold by hitting them
# Demonstration of pollBlockHits()
# the function pollBlockHits() returns an Array of hit Events
# A hit event is a tuple, say ((5, 4, 5), 2, 17)
# (5, 4, 5) are the coordinates to the block which was hit
# 2 is the face of the block which was hit
# 17 is the entityId of the Entity which was responsible for the hit

using PiCraft

clearEvents() # Clear all previous events
t = now() # Mark the current time

post("60 seconds to turn blocks to gold.")

while (now() - t).value/1000 < 60.0 # Continue the loop if 60 seconds has not elapsed
for hit in pollBlockHits()
setBlock(hit[1], Block(41)) # hit[1] are the coordinates to the Block which was hit
end
end

post("Time Over!")
12 changes: 7 additions & 5 deletions src/PiCraft.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ function setBlock(pos::Tuple{Real, Real, Real}, block::Block)
end

"Set an entire region to the specified block type"
function setBlocks(pos::Tuple{UnitRange{Int}, UnitRange{Int}, UnitRange{Int}}, block::Block)
PiCraft.mc_send("world.setBlocks($(pos[1][1]),$(pos[2][1]),$(pos[3][1]),$(pos[1][end]),$(pos[2][end]),$(pos[3][end]),$(block.id),$(block.data))", false)
function setBlocks(p1::Tuple{Real, Real, Real}, p2::Tuple{Real, Real, Real}, block::Block)
p1 = round.(Int, p1)
p2 = round.(Int, p2)
PiCraft.mc_send("world.setBlocks($(p1[1]),$(p1[2]),$(p1[3]),$(p2[1]),$(p2[2]),$(p2[3]),$(block.id),$(block.data))", false)
end

"Get the height of the world at the specified `x` and `z` coordinates."
Expand Down Expand Up @@ -133,20 +135,20 @@ end
pollBlockHits()

Returns an array of all the events which have occurred since the last time the function was called.
Each event is described with a tuple `(x, y, z, face, entityId)`. `x`, `y` and `z` are the coordinates of the block.
Each event is described with a tuple `((x, y, z), face, entityId)`. `x`, `y` and `z` are the coordinates of the block.
`face` is the block's face number which was hit and `entityId` identifies the player who hit the block using a sword.

"""
function pollBlockHits()
rawEvents = []
for s in PiCraft.mc_send("events.block.hits()", true)
for j in split(s, "|")
push!(rawEvents, parse(Int,j))
length(j) > 0 && push!(rawEvents, parse(Int,j))
end
end
Events = []
for i in 0:(Int(length(rawEvents)/5) - 1)
push!(Events, (rawEvents[1 + 5*i], rawEvents[2 + 5*i], rawEvents[3 + 5*i], rawEvents[4 + 5*i], rawEvents[5 + 5*i]))
push!(Events, ( (rawEvents[1 + 5*i], rawEvents[2 + 5*i], rawEvents[3 + 5*i]) , rawEvents[4 + 5*i], rawEvents[5 + 5*i]))
end
return Events
end
Expand Down