Skip to content

Commit

Permalink
implement more redstone components
Browse files Browse the repository at this point in the history
  • Loading branch information
xNatsuri committed Jan 7, 2025
1 parent 536b5d8 commit a07805f
Show file tree
Hide file tree
Showing 20 changed files with 1,012 additions and 1 deletion.
25 changes: 25 additions & 0 deletions server/block/hash.go

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

5 changes: 5 additions & 0 deletions server/block/lava.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ func (Lava) LightEmissionLevel() uint8 {
return 15
}

// PistonBreakable ...
func (Lava) PistonBreakable() bool {
return true
}

// NeighbourUpdateTick ...
func (l Lava) NeighbourUpdateTick(pos, _ cube.Pos, tx *world.Tx) {
if !l.Harden(pos, tx, nil) {
Expand Down
5 changes: 5 additions & 0 deletions server/block/melon.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ func (Melon) CompostChance() float64 {
return 0.65
}

// PistonBreakable ...
func (Melon) PistonBreakable() bool {
return true
}

// EncodeItem ...
func (Melon) EncodeItem() (name string, meta int16) {
return "minecraft:melon_block", 0
Expand Down
19 changes: 19 additions & 0 deletions server/block/model/diode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package model

import (
"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/world"
)

// Diode is a model used by redstone gates, such as repeaters and comparators.
type Diode struct{}

// BBox ...
func (Diode) BBox(cube.Pos, world.BlockSource) []cube.BBox {
return []cube.BBox{full.ExtendTowards(cube.FaceDown, 0.875)}
}

// FaceSolid ...
func (Diode) FaceSolid(cube.Pos, cube.Face, world.BlockSource) bool {
return false
}
71 changes: 71 additions & 0 deletions server/block/moving.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package block

import (
"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/internal/nbtconv"
"github.com/df-mc/dragonfly/server/world"
)

// Moving ...
type Moving struct {
empty
transparent

// Moving represents the block that is moving.
Moving world.Block
// Extra represents an extra block that is moving with the main block.
Extra world.Block
// Piston is the position of the piston that is moving the block.
Piston cube.Pos
// Expanding is true if the moving block is expanding, false if it is contracting.
Expanding bool
}

// EncodeBlock ...
func (Moving) EncodeBlock() (string, map[string]any) {
return "minecraft:moving_block", nil
}

// PistonImmovable ...
func (Moving) PistonImmovable() bool {
return true
}

// EncodeNBT ...
func (b Moving) EncodeNBT() map[string]any {
if b.Moving == nil {
b.Moving = Air{}
}
if b.Extra == nil {
b.Extra = Air{}
}
data := map[string]any{
"id": "MovingBlock",
"expanding": b.Expanding,
"movingBlock": nbtconv.WriteBlock(b.Moving),
"movingBlockExtra": nbtconv.WriteBlock(b.Extra),
"pistonPosX": int32(b.Piston.X()),
"pistonPosY": int32(b.Piston.Y()),
"pistonPosZ": int32(b.Piston.Z()),
}
if nbt, ok := b.Moving.(world.NBTer); ok {
data["movingEntity"] = nbt.EncodeNBT()
}
return data
}

// DecodeNBT ...
func (b Moving) DecodeNBT(m map[string]any) any {
b.Expanding = nbtconv.Bool(m, "expanding")
b.Moving = nbtconv.Block(m, "movingBlock")
b.Extra = nbtconv.Block(m, "movingBlockExtra")
b.Piston = cube.Pos{
int(nbtconv.Int32(m, "pistonPosX")),
int(nbtconv.Int32(m, "pistonPosY")),
int(nbtconv.Int32(m, "pistonPosZ")),
}
if nbt, ok := b.Moving.(world.NBTer); ok {
b.Moving = nbt.DecodeNBT(m["movingEntity"].(map[string]any)).(world.Block)
}
return b
}
105 changes: 105 additions & 0 deletions server/block/observer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
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/go-gl/mathgl/mgl64"
"math/rand/v2"
"time"
)

// Observer is a block that emits a redstone signal when the block or fluid it faces experiences a change.
type Observer struct {
solid

// Facing is the direction the observer is observing.
Facing cube.Face
// Powered is whether the observer is powered or not.
Powered bool
}

// RedstoneSource ...
func (Observer) RedstoneSource() bool {
return true
}

// RedstoneBlocking ...
func (Observer) RedstoneBlocking() bool {
return true
}

// WeakPower ...
func (o Observer) WeakPower(pos cube.Pos, face cube.Face, tx *world.Tx, accountForDust bool) int {
return o.StrongPower(pos, face, tx, accountForDust)
}

// StrongPower ...
func (o Observer) StrongPower(_ cube.Pos, face cube.Face, _ *world.Tx, _ bool) int {
if !o.Powered || face != o.Facing {
return 0
}
return 15
}

// ScheduledTick ...
func (o Observer) ScheduledTick(pos cube.Pos, tx *world.Tx, _ *rand.Rand) {
o.Powered = !o.Powered
if o.Powered {
tx.ScheduleBlockUpdate(pos, o, time.Millisecond*100)
}
tx.SetBlock(pos, o, nil)
updateDirectionalRedstone(pos, tx, o.Facing.Opposite())
}

// NeighbourUpdateTick ...
func (o Observer) NeighbourUpdateTick(pos, changedNeighbour cube.Pos, tx *world.Tx) {
if pos.Side(o.Facing) != changedNeighbour {
return
}
if o.Powered {
return
}
tx.ScheduleBlockUpdate(pos, o, time.Millisecond*100)
}

// UseOnBlock ...
func (o Observer) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, tx *world.Tx, user item.User, ctx *item.UseContext) bool {
pos, _, used := firstReplaceable(tx, pos, face, o)
if !used {
return false
}
o.Facing = calculateFace(user, pos, false)
if o.Facing.Axis() == cube.Y {
o.Facing = o.Facing.Opposite()
}

place(tx, pos, o, user, ctx)
return placed(ctx)
}

// BreakInfo ...
func (o Observer) BreakInfo() BreakInfo {
return newBreakInfo(3, pickaxeHarvestable, pickaxeEffective, oneOf(o)).withBreakHandler(func(pos cube.Pos, tx *world.Tx, _ item.User) {
updateDirectionalRedstone(pos, tx, o.Facing.Opposite())
})
}

// EncodeItem ...
func (o Observer) EncodeItem() (name string, meta int16) {
return "minecraft:observer", 0
}

// EncodeBlock ...
func (o Observer) EncodeBlock() (string, map[string]any) {
return "minecraft:observer", map[string]any{"minecraft:facing_direction": o.Facing.String(), "powered_bit": o.Powered}
}

// allObservers ...
func allObservers() (observers []world.Block) {
for _, f := range cube.Faces() {
observers = append(observers, Observer{Facing: f})
observers = append(observers, Observer{Facing: f, Powered: true})
}
return
}
5 changes: 5 additions & 0 deletions server/block/obsidian.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ type Obsidian struct {
Crying bool
}

// PistonImmovable ...
func (o Obsidian) PistonImmovable() bool {
return !o.Crying
}

// LightEmissionLevel ...
func (o Obsidian) LightEmissionLevel() uint8 {
if o.Crying {
Expand Down
Loading

0 comments on commit a07805f

Please sign in to comment.