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

Implement support for custom blocks #512

Merged
merged 88 commits into from Dec 9, 2023
Merged

Conversation

JustTalDevelops
Copy link
Member

@JustTalDevelops JustTalDevelops commented May 22, 2022

Still needs code cleanup.

Below is an example of creating a custom skull block that can be rotated:

type CustomSkull struct {
	empty
	transparent

	Facing cube.Direction
}

func (skull CustomSkull) Name() string {
	return "Custom Skull"
}

func (skull CustomSkull) Category() category.Category {
	return category.Nature()
}

func (skull CustomSkull) Textures() map[string]image.Image {
	return map[string]image.Image{
		"skull": skull.Texture(),
	}
}

func (skull CustomSkull) Texture() image.Image {
	texture, err := os.OpenFile("skull.png", os.O_RDONLY, os.ModePerm)
	if err != nil {
		panic(err)
	}
	defer texture.Close()
	img, err := png.Decode(texture)
	if err != nil {
		panic(err)
	}
	return img
}

func (skull CustomSkull) Geometry() []byte {
	data, err := os.ReadFile("skull.geo.json")
	if err != nil {
		panic(err)
	}
	return data
}

func (skull CustomSkull) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) (used bool) {
	pos, _, used = firstReplaceable(w, pos, face, skull)
	if !used {
		return
	}

	skull.Facing = user.Rotation().Direction()
	place(w, pos, skull, user, ctx)
	return placed(ctx)
}

func (skull CustomSkull) EncodeItem() (name string, meta int16) {
	return "dragonfly:skull", 0
}

// EncodeBlock ...
func (skull CustomSkull) EncodeBlock() (string, map[string]any) {
	return "dragonfly:skull", map[string]any{"rotation": int32(skull.Facing)}
}

var skullHash = NextHash()

func (skull CustomSkull) Hash() uint64 {
	return skullHash | (uint64(skull.Facing) << 8)
}

func (skull CustomSkull) Properties() customblock.Properties {
	return customblock.Properties{
		CollisionBox: cube.Box(0.25, 0, 0.25, 0.75, 0.5, 0.75),
		SelectionBox: cube.Box(0.25, 0, 0.25, 0.75, 0.5, 0.75),
		Geometry:     "geometry.skull",
		Textures: map[string]customblock.Material{
			"*": customblock.NewMaterial("skull", customblock.OpaqueRenderMethod()),
		},
	}
}

func (skull CustomSkull) States() map[string][]any {
	return map[string][]any{
		"rotation": {int32(0), int32(1), int32(2), int32(3)},
	}
}

func (skull CustomSkull) Permutations() []customblock.Permutation {
	return []customblock.Permutation{
		{
			Condition: "query.block_state('rotation') == 1",
			Properties: customblock.Properties{
				Rotation: cube.Pos{0, 3, 0},
			},
		},
		{
			Condition: "query.block_state('rotation') == 2",
			Properties: customblock.Properties{
				Rotation: cube.Pos{0, 2, 0},
			},
		},
		{
			Condition: "query.block_state('rotation') == 3",
			Properties: customblock.Properties{
				Rotation: cube.Pos{0, 1, 0},
			},
		},
	}
}
for _, direction := range cube.Directions() {
	world.RegisterBlock(block.CustomSkull{Facing: direction})
}
world.RegisterItem(block.CustomSkull{})
creative.RegisterItem(item.NewStack(block.CustomSkull{}, 1))

// Custom blocks need to be registered before the server is created

srv := conf.New()

IssueHunt Summary

Referenced issues

This pull request has been submitted to:


@JustTalDevelops JustTalDevelops changed the title Custom blocks Implement support for custom blocks Jul 22, 2022
@JustTalDevelops JustTalDevelops marked this pull request as ready for review July 22, 2022 22:54
@JustTalDevelops
Copy link
Member Author

JustTalDevelops commented Jul 22, 2022

This is now fully functional - feel free to review this. (although, I'm not exactly done with code cleanup yet, will do that ASAP!)

@RoyalMCPE
Copy link
Contributor

It maybe worth exporting firstReplaceable and place so that the end user doesn't have to copy the logic to add vanilla placement to their blocks.

@JustTalDevelops
Copy link
Member Author

Yeah I do agree, I also think other fields such as transparent or empty could be exported, along with newBreakInfo, newSmeltInfo, etc.

server/world/block_state.go Outdated Show resolved Hide resolved
server/server.go Outdated Show resolved Hide resolved
server/server.go Outdated Show resolved Hide resolved
server/internal/blockinternal/components.go Outdated Show resolved Hide resolved
server/internal/blockinternal/components.go Outdated Show resolved Hide resolved
server/block/cube/axis.go Outdated Show resolved Hide resolved
@TwistedAsylumMC TwistedAsylumMC merged commit 3425d39 into master Dec 9, 2023
2 of 4 checks passed
@TwistedAsylumMC TwistedAsylumMC deleted the feature/custom-blocks branch December 9, 2023 16:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants