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

redstone #941

Closed
wants to merge 8 commits into from
Closed
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
4 changes: 4 additions & 0 deletions cmd/blockhash/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ func (b *hashBuilder) ftype(structName, s string, expr ast.Expr, directives map[
return "uint64(" + s + ")", 8
case "Block":
return "world.BlockHash(" + s + ")", 32
case "ButtonType":
return "uint64(" + s + ".Uint8())", 6
case "PressurePlateType":
return "uint64(" + s + ".Uint8())", 8
Comment on lines +238 to +241
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm not mistaken, you can reduce this to 2 for buttons and 3 for pressure plates

case "Attachment":
if _, ok := directives["facing_only"]; ok {
log.Println("Found directive: 'facing_only'")
Expand Down
3 changes: 3 additions & 0 deletions server/block/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ type Permutable interface {
Permutations() []customblock.Permutation
}

// unknownFace is a face that is used for certain block items. This should not be exposed in the API.
var unknownFace = cube.Face(len(cube.Faces()))

func calculateFace(user item.User, placePos cube.Pos) cube.Face {
userPos := user.Position()
pos := cube.PosFromVec3(userPos)
Expand Down
153 changes: 153 additions & 0 deletions server/block/button.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package block

import (
"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/item"
"github.com/df-mc/dragonfly/server/world"
"github.com/df-mc/dragonfly/server/world/sound"
"github.com/go-gl/mathgl/mgl64"
"math/rand"
"time"
)

// TODO: Activate on projectile hit

// Button is a non-solid block that can provide temporary redstone power.
type Button struct {
empty
transparent
sourceWaterDisplacer

// Type is the type of the button.
Type ButtonType
// Facing is the face of the block that the button is on.
Facing cube.Face
// Pressed is whether the button is pressed or not.
Pressed bool
}

// FuelInfo ...
func (b Button) FuelInfo() item.FuelInfo {
if b.Type == StoneButton() || b.Type == PolishedBlackstoneButton() {
return item.FuelInfo{}
}
return newFuelInfo(time.Second * 5)
Comment on lines +31 to +34
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be checking if type == Wood() if future types were to be added, although Wood currently takes a parameter...

}

// Source ...
func (b Button) Source() bool {
return true
}

// WeakPower ...
func (b Button) WeakPower(cube.Pos, cube.Face, *world.World, bool) int {
if b.Pressed {
return 15
}
return 0
}

// StrongPower ...
func (b Button) StrongPower(_ cube.Pos, face cube.Face, _ *world.World, _ bool) int {
if b.Pressed && b.Facing == face {
return 15
}
return 0
}

// ScheduledTick ...
func (b Button) ScheduledTick(pos cube.Pos, w *world.World, r *rand.Rand) {
if !b.Pressed {
return
}
b.Pressed = false
w.SetBlock(pos, b, nil)
w.PlaySound(pos.Vec3Centre(), sound.PowerOff{})
updateDirectionalRedstone(pos, w, b.Facing.Opposite())
}

// NeighbourUpdateTick ...
func (b Button) NeighbourUpdateTick(pos, _ cube.Pos, w *world.World) {
if !w.Block(pos.Side(b.Facing.Opposite())).Model().FaceSolid(pos.Side(b.Facing.Opposite()), b.Facing, w) {
w.SetBlock(pos, nil, nil)
dropItem(w, item.NewStack(b, 1), pos.Vec3Centre())
updateDirectionalRedstone(pos, w, b.Facing.Opposite())
}
}

// Activate ...
func (b Button) Activate(pos cube.Pos, _ cube.Face, w *world.World, _ item.User, _ *item.UseContext) bool {
return b.Click(pos, w)
}

// Click ...
func (b Button) Click(pos cube.Pos, w *world.World) bool {
if b.Pressed {
return true
}
b.Pressed = true
w.SetBlock(pos, b, nil)
w.PlaySound(pos.Vec3Centre(), sound.PowerOn{})
updateDirectionalRedstone(pos, w, b.Facing.Opposite())

delay := time.Millisecond * 1500
if b.Type == StoneButton() || b.Type == PolishedBlackstoneButton() {
delay = time.Millisecond * 1000
}
Comment on lines +93 to +96
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably better in ButtonType

w.ScheduleBlockUpdate(pos, delay)
return true
}

// UseOnBlock ...
func (b Button) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) bool {
pos, face, used := firstReplaceable(w, pos, face, b)
if !used {
return false
}
if !w.Block(pos.Side(face.Opposite())).Model().FaceSolid(pos.Side(face.Opposite()), face, w) {
return false
}

b.Facing = face
place(w, pos, b, user, ctx)
return placed(ctx)
}

// BreakInfo ...
func (b Button) BreakInfo() BreakInfo {
harvestTool := alwaysHarvestable
effectiveTool := axeEffective
if b.Type == StoneButton() || b.Type == PolishedBlackstoneButton() {
harvestTool = pickaxeHarvestable
effectiveTool = pickaxeEffective
}
return newBreakInfo(0.5, harvestTool, effectiveTool, oneOf(b)).withBreakHandler(func(pos cube.Pos, w *world.World, _ item.User) {
updateDirectionalRedstone(pos, w, b.Facing.Opposite())
})
}

// SideClosed ...
func (b Button) SideClosed(cube.Pos, cube.Pos, *world.World) bool {
return false
}

// EncodeItem ...
func (b Button) EncodeItem() (name string, meta int16) {
return "minecraft:" + b.Type.String() + "_button", 0
}

// EncodeBlock ...
func (b Button) EncodeBlock() (string, map[string]any) {
return "minecraft:" + b.Type.String() + "_button", map[string]any{"facing_direction": int32(b.Facing), "button_pressed_bit": b.Pressed}
}

// allButtons ...
func allButtons() (buttons []world.Block) {
for _, w := range ButtonTypes() {
for _, f := range cube.Faces() {
buttons = append(buttons, Button{Type: w, Facing: f})
buttons = append(buttons, Button{Type: w, Facing: f, Pressed: true})
}
}
return
}
69 changes: 69 additions & 0 deletions server/block/button_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package block

// ButtonType represents a type of button.
type ButtonType struct {
button

// Wood is the type of wood of the button.
wood WoodType
}

type button uint8

// WoodButton returns the wood button type.
func WoodButton(w WoodType) ButtonType {
return ButtonType{0, w}
}

// StoneButton returns the stone button type.
func StoneButton() ButtonType {
return ButtonType{button: 1}
}

// PolishedBlackstoneButton returns the polished blackstone button type.
func PolishedBlackstoneButton() ButtonType {
return ButtonType{button: 2}
}

// Uint8 ...
func (b ButtonType) Uint8() uint8 {
return b.wood.Uint8() | uint8(b.button)<<4
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not ideal. With the current order, as we get more wood variants, this will need to be updated, which might not be obvious to whoever is doing that.

}

// Name ...
func (b ButtonType) Name() string {
switch b.button {
case 0:
return b.wood.Name() + " Button"
case 1:
return "Stone Button"
case 2:
return "Polished Blackstone Button"
}
panic("unknown button type")
}

// String ...
func (b ButtonType) String() string {
switch b.button {
case 0:
if b.wood == OakWood() {
return "wooden"
}
return b.wood.String()
case 1:
return "stone"
case 2:
return "polished_blackstone"
}
panic("unknown button type")
}

// ButtonTypes ...
func ButtonTypes() []ButtonType {
types := []ButtonType{StoneButton(), PolishedBlackstoneButton()}
for _, w := range WoodTypes() {
types = append(types, WoodButton(w))
}
return types
}
55 changes: 55 additions & 0 deletions server/block/hash.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading