Compare commits

...
19 Commits
Author SHA1 Message Date
Lucas Vas 2bf4b80094 Merge pull request #3 from The-Uncreative-Bunch/feature/wand-crafting-test
Basic crafting recipe example
2025-09-15 22:01:04 -04:00
alphafetus 430c59aed4 feat: implement very simple crafting output slot
Note that this is likely full of bugs that we'll find later on, but this should be good enough to merge for now as a simple example.
2025-09-15 21:54:45 -04:00
alphafetus b888aa5a78 chore: remove unused imports 2025-09-09 17:47:35 -04:00
alphafetus 5331aa8f97 chore: remove unused method 2025-09-09 17:44:37 -04:00
alphafetus a558428b58 chore: remove player electrocution on block usage 2025-09-09 17:44:19 -04:00
alphafetus 632772b666 feat: implement basic crafting block
This block still needs a lot of polish and real crafting mechanics, but it serves as a relatively complex idea of how to create a crafting recipe type and a block/BlockEntity to go along with it.
2025-09-08 23:38:11 -04:00
alphafetus ad9c46c0b4 build: revert to Minecraft version 1.21.5 due to undocumented breaking changes 2025-09-06 13:25:46 -04:00
alphafetus c92563a672 build: remapped to Minecraft version 1.21.8
No breaking changes, minor version update.
2025-09-06 12:48:30 -04:00
alphafetus ce1bd9052f feat: build crafting type and block entity, pc change 2025-09-05 07:31:39 -04:00
alphafetus 6e224e1fdf feat: add custom magical crafting screen handler 2025-09-03 21:42:17 -04:00
alphafetus ce56bbe9da fix: add tag translation 2025-09-02 17:13:50 -04:00
abird356 5927760472 Merge pull request #2 from The-Uncreative-Bunch/feature/stick-items
Add Stick/Stick Recipies
2025-05-03 12:50:37 -04:00
abird356 e0518be96a update stick from bamboo item crafting recipe 2025-05-03 12:46:31 -04:00
abird356 21009bba52 Merge branch 'main' into feature/stick-items 2025-05-03 12:31:02 -04:00
Lucas Vas d34fb7d033 Merge pull request #1 from The-Uncreative-Bunch/feature/first-crafting-block
Create new example block
2025-05-01 20:52:14 -04:00
alphafetus 902576988a feat: give crafter an example event that calls down lightning 2025-04-20 15:03:25 -04:00
alphafetus 0975198a76 feat: replace instances of minecraft:stick in vanilla recipes with #magic_mod:sticks 2025-04-18 20:56:50 -04:00
alphafetus 75a38837a6 chore: update recipe for block and alter textures 2025-04-17 19:03:38 -04:00
alphafetus 6462e0f810 feat: create testing block
It's a mess.
2025-04-15 00:30:23 -04:00
135 changed files with 1734 additions and 11 deletions

No files matched your search

+7
View File
@@ -87,4 +87,11 @@ publishing {
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
}
// Configure Fabric Data Generation API
fabricApi {
configureDataGeneration() {
client = true
}
}
+4 -2
View File
@@ -6,7 +6,8 @@ org.gradle.parallel=true
# check these on https://fabricmc.net/develop
minecraft_version=1.21.5
yarn_mappings=1.21.5+build.1
loader_version=0.16.12
loader_version=0.17.2
loom_version=1.11-SNAPSHOT
# Mod Properties
mod_version=1.0.0
@@ -14,4 +15,5 @@ maven_group=com.uncreativebunch.magicmod
archives_base_name=magic_mod
# Dependencies
fabric_version=0.119.9+1.21.5
# Fabric API
fabric_version=0.128.2+1.21.5
Vendored Regular → Executable
View File
File mode changed.
+507
View File
@@ -8,6 +8,10 @@
"name": "magic-mod",
"version": "0.1.0",
"license": "ISC",
"dependencies": {
"tsc": "^2.0.4",
"tsx": "^4.19.3"
},
"devDependencies": {
"commitlint": "^19.8.0",
"husky": "^9.1.7"
@@ -281,6 +285,406 @@
"node": ">=v18"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz",
"integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==",
"cpu": [
"ppc64"
],
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz",
"integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==",
"cpu": [
"arm"
],
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz",
"integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz",
"integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz",
"integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz",
"integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz",
"integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz",
"integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz",
"integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==",
"cpu": [
"arm"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz",
"integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz",
"integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==",
"cpu": [
"ia32"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz",
"integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==",
"cpu": [
"loong64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz",
"integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==",
"cpu": [
"mips64el"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz",
"integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==",
"cpu": [
"ppc64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz",
"integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==",
"cpu": [
"riscv64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz",
"integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==",
"cpu": [
"s390x"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz",
"integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz",
"integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz",
"integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz",
"integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz",
"integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz",
"integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz",
"integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz",
"integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==",
"cpu": [
"ia32"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz",
"integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@types/conventional-commits-parser": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.1.tgz",
@@ -574,6 +978,46 @@
"is-arrayish": "^0.2.1"
}
},
"node_modules/esbuild": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz",
"integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.25.2",
"@esbuild/android-arm": "0.25.2",
"@esbuild/android-arm64": "0.25.2",
"@esbuild/android-x64": "0.25.2",
"@esbuild/darwin-arm64": "0.25.2",
"@esbuild/darwin-x64": "0.25.2",
"@esbuild/freebsd-arm64": "0.25.2",
"@esbuild/freebsd-x64": "0.25.2",
"@esbuild/linux-arm": "0.25.2",
"@esbuild/linux-arm64": "0.25.2",
"@esbuild/linux-ia32": "0.25.2",
"@esbuild/linux-loong64": "0.25.2",
"@esbuild/linux-mips64el": "0.25.2",
"@esbuild/linux-ppc64": "0.25.2",
"@esbuild/linux-riscv64": "0.25.2",
"@esbuild/linux-s390x": "0.25.2",
"@esbuild/linux-x64": "0.25.2",
"@esbuild/netbsd-arm64": "0.25.2",
"@esbuild/netbsd-x64": "0.25.2",
"@esbuild/openbsd-arm64": "0.25.2",
"@esbuild/openbsd-x64": "0.25.2",
"@esbuild/sunos-x64": "0.25.2",
"@esbuild/win32-arm64": "0.25.2",
"@esbuild/win32-ia32": "0.25.2",
"@esbuild/win32-x64": "0.25.2"
}
},
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -626,6 +1070,20 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -636,6 +1094,18 @@
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/get-tsconfig": {
"version": "4.10.0",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz",
"integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==",
"license": "MIT",
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
},
"funding": {
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
}
},
"node_modules/git-raw-commits": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz",
@@ -1065,6 +1535,15 @@
"node": ">=8"
}
},
"node_modules/resolve-pkg-maps": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
"license": "MIT",
"funding": {
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
}
},
"node_modules/semver": {
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
@@ -1143,6 +1622,34 @@
"dev": true,
"license": "MIT"
},
"node_modules/tsc": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/tsc/-/tsc-2.0.4.tgz",
"integrity": "sha512-fzoSieZI5KKJVBYGvwbVZs/J5za84f2lSTLPYf6AGiIf43tZ3GNrI1QzTLcjtyDDP4aLxd46RTZq1nQxe7+k5Q==",
"license": "MIT",
"bin": {
"tsc": "bin/tsc"
}
},
"node_modules/tsx": {
"version": "4.19.3",
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.3.tgz",
"integrity": "sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==",
"license": "MIT",
"dependencies": {
"esbuild": "~0.25.0",
"get-tsconfig": "^4.7.5"
},
"bin": {
"tsx": "dist/cli.mjs"
},
"engines": {
"node": ">=18.0.0"
},
"optionalDependencies": {
"fsevents": "~2.3.3"
}
},
"node_modules/typescript": {
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+4
View File
@@ -11,5 +11,9 @@
"devDependencies": {
"commitlint": "^19.8.0",
"husky": "^9.1.7"
},
"dependencies": {
"tsc": "^2.0.4",
"tsx": "^4.19.3"
}
}
@@ -1,10 +1,14 @@
package com.uncreativebunch.magicmod;
import com.uncreativebunch.magicmod.screen.MagicalCraftingScreen;
import com.uncreativebunch.magicmod.screen.ModScreenHandlers;
import net.fabricmc.api.ClientModInitializer;
import net.minecraft.client.gui.screen.ingame.HandledScreens;
public class MagicModClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
// This entrypoint is suitable for setting up client-specific logic, such as rendering.
HandledScreens.register(ModScreenHandlers.MAGICAL_CRAFTING_SCREEN_HANDLER, MagicalCraftingScreen::new);
}
}
@@ -0,0 +1,39 @@
package com.uncreativebunch.magicmod.screen;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
public class MagicalCraftingScreen extends HandledScreen<MagicalCraftingScreenHandler> {
private static final Identifier TEXTURE = Identifier.of("textures/gui/container/dispenser.png");
public MagicalCraftingScreen(MagicalCraftingScreenHandler handler, PlayerInventory inventory, Text title) {
super(handler, inventory, title);
}
@Override
protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) {
context.drawTexture(RenderLayer::getGuiTextured, TEXTURE,
this.x, (this.height - this.backgroundHeight) / 2,
0.0F, 0.0F,
this.backgroundWidth, this.backgroundHeight,
256, 256);
}
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
renderBackground(context, mouseX, mouseY, delta);
super.render(context, mouseX, mouseY, delta);
drawMouseoverTooltip(context, mouseX, mouseY);
}
@Override
protected void init() {
super.init();
// Centers the title
titleX = (backgroundWidth - textRenderer.getWidth(title)) / 2;
}
}
@@ -1,6 +1,12 @@
package com.uncreativebunch.magicmod;
import com.uncreativebunch.magicmod.block.ModBlocks;
import com.uncreativebunch.magicmod.block.entity.ModBlockEntityTypes;
import com.uncreativebunch.magicmod.item.ModItemGroups;
import com.uncreativebunch.magicmod.item.ModItems;
import com.uncreativebunch.magicmod.recipe.ModRecipeSerializers;
import com.uncreativebunch.magicmod.recipe.ModRecipeTypes;
import com.uncreativebunch.magicmod.screen.ModScreenHandlers;
import net.fabricmc.api.ModInitializer;
import org.slf4j.Logger;
@@ -24,7 +30,13 @@ public class MagicMod implements ModInitializer {
LOGGER.info("Hello Fabric world!");
LOGGER.info("Starting Magic Mod...");
ModBlocks.init();
ModItems.init();
ModItemGroups.init();
ModScreenHandlers.init();
ModRecipeSerializers.init();
ModRecipeTypes.init();
ModBlockEntityTypes.init();
LOGGER.info("Finished Magic Mod initialization!");
}
}
@@ -0,0 +1,86 @@
package com.uncreativebunch.magicmod.block;
import com.uncreativebunch.magicmod.MagicMod;
import com.uncreativebunch.magicmod.block.crafting.MagicalCrafterBlock;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier;
import java.util.function.Function;
public class ModBlocks {
//region Block Definitions
/** The magical crafting table block. */
public static final Block MAGICAL_CRAFTING_TABLE = register(
"magical_crafting_table",
MagicalCrafterBlock::new,
AbstractBlock.Settings
.create()
.sounds(BlockSoundGroup.AMETHYST_BLOCK),
true
);
//endregion
/**
* Used to statically initialize this class. Nothing needs to be in it for now.
*/
public static void init() {
MagicMod.LOGGER.info("Block initialization complete");
}
/**
* Registers a new {@link Block}.
* @param name The name of the {@link Block} to register.
* @param factory The block factory to use - typically Block::new
* @param settings The {@link AbstractBlock.Settings} to use for creation.
* @param shouldRegisterItem Determines if an item should be created with the block, for use in the inventory.
* @return The newly registered {@link Block}.
*/
public static Block register(
String name,
Function<AbstractBlock.Settings,Block> factory,
AbstractBlock.Settings settings,
boolean shouldRegisterItem) {
RegistryKey<Block> blockKey = keyOfBlock(name);
Block block = factory.apply(settings.registryKey(blockKey));
// We don't always want to create items for blocks - sometimes the block is in an "active" state,
// which we don't want to create an item instance for, just the block.
if (shouldRegisterItem) {
RegistryKey<Item> itemKey = keyOfItem(name);
BlockItem blockItem = new BlockItem(block, new Item.Settings().registryKey(itemKey));
Registry.register(Registries.ITEM, itemKey, blockItem);
}
// Return the block we want to register.
return Registry.register(Registries.BLOCK, blockKey, block);
}
/**
* Gets a {@link RegistryKey} for the specified block name.
* @param name The name of the {@link Block} to use.
* @return The {@link RegistryKey} for the specified {@link Block}.
*/
public static RegistryKey<Block> keyOfBlock(String name) {
return RegistryKey.of(RegistryKeys.BLOCK, Identifier.of(MagicMod.MOD_ID, name));
}
/**
* Gets a {@link RegistryKey} for the specified item name.
* @param name The name of the {@link Item} to use.
* @return The {@link RegistryKey} of the specified {@link Item}.
*/
public static RegistryKey<Item> keyOfItem(String name) {
return RegistryKey.of(RegistryKeys.ITEM, Identifier.of(MagicMod.MOD_ID, name));
}
}
@@ -0,0 +1,100 @@
package com.uncreativebunch.magicmod.block.crafting;
import com.mojang.serialization.MapCodec;
import com.uncreativebunch.magicmod.MagicMod;
import com.uncreativebunch.magicmod.block.entity.MagicalCrafterBlockEntity;
import com.uncreativebunch.magicmod.block.entity.ModBlockEntityTypes;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityTicker;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.enums.SlabType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.stat.Stats;
import net.minecraft.state.StateManager;
import net.minecraft.util.ActionResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class MagicalCrafterBlock extends BlockWithEntity {
private static final MapCodec<MagicalCrafterBlock> CODEC = null;
/**
* Creates a new MagicalCrafterBlock.
* @param settings The settings of the block.
*/
public MagicalCrafterBlock(AbstractBlock.Settings settings) {
super(settings);
this.setDefaultState(
this.stateManager.getDefaultState()
.with(SlabBlock.TYPE, SlabType.BOTTOM)
.with(SlabBlock.WATERLOGGED, false)
);
}
@Override
protected MapCodec<? extends BlockWithEntity> getCodec() {
return CODEC;
}
/**
* Occurs whenever this block is used.
* It opens a crafting window and summons lightning on the interacting player.
* @param state The current {@link BlockState} of this block.
* @param world The {@link World} that this block exists in.
* @param pos The {@link BlockPos} that this block is at.
* @param player The {@link PlayerEntity} that used this object.
* @param hit The {@link BlockHitResult} that contains information about this interaction.
* @return Whether the action passed, was canceled, or succeeded.
*/
@Override
protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) {
// The server is the game's sole source of truth. Even though some things are displayed
// on the client, these actions usually, with very few exceptions, are routed and triggered
// through the server first.
if (!world.isClient) {
MagicMod.LOGGER.info("Block was used at location {}", pos.toShortString());
NamedScreenHandlerFactory screenFactory = state.createScreenHandlerFactory(world, pos);
if (screenFactory != null) {
player.openHandledScreen(screenFactory);
player.incrementStat(Stats.INTERACT_WITH_CRAFTING_TABLE);
} else {
MagicMod.LOGGER.info("NamedScreenHandlerFactory returned from the BlockState is null.");
}
}
return ActionResult.SUCCESS;
}
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new MagicalCrafterBlockEntity(pos, state);
}
/**
* Adds properties to the block state. This crafting table is a slab, so it has a type and waterlogged property.
* @param builder The {@link StateManager.Builder} to add properties to.
*/
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
builder.add(SlabBlock.TYPE, SlabBlock.WATERLOGGED);
}
/**
* Creates a {@link BlockEntityTicker} that runs the specified "tick" function from the
* given {@link BlockEntityType}.
* @param world The {@link World} instance.
* @param state The {@link BlockState} of the block.
* @param type The {@link BlockEntityType} to run the tick function from.
* @return A new {@link BlockEntityTicker} that runs the specified tick function.
* @param <T> The {@link BlockEntity} to use.
*/
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
return validateTicker(type, ModBlockEntityTypes.MAGICAL_CRAFTING_TABLE, MagicalCrafterBlockEntity::tick);
}
}
@@ -0,0 +1,87 @@
package com.uncreativebunch.magicmod.block.entity;
import com.uncreativebunch.magicmod.inventory.InputInventory;
import com.uncreativebunch.magicmod.inventory.OutputInventory;
import com.uncreativebunch.magicmod.recipe.MagicShapedInput;
import com.uncreativebunch.magicmod.recipe.ModRecipeTypes;
import com.uncreativebunch.magicmod.recipe.MagicShapedRecipe;
import com.uncreativebunch.magicmod.screen.MagicalCraftingScreenHandler;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.recipe.RecipeEntry;
import net.minecraft.recipe.ServerRecipeManager;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.Optional;
public class MagicalCrafterBlockEntity extends BlockEntity implements NamedScreenHandlerFactory {
private final ServerRecipeManager.MatchGetter<MagicShapedInput, ? extends MagicShapedRecipe> recipeGetter;
/**
* The input inventory for crafting ingredients. It goes in the order core, material, and grip.
*/
private final InputInventory inputInventory = new InputInventory(3);
/**
* The output inventory for crafting ingredients.
*/
private final OutputInventory outputInventory = new OutputInventory(1);
public MagicalCrafterBlockEntity(BlockPos pos, BlockState state) {
super(ModBlockEntityTypes.MAGICAL_CRAFTING_TABLE, pos, state);
this.recipeGetter = ServerRecipeManager.createCachedMatchGetter(ModRecipeTypes.MAGIC_SHAPED);
}
/**
* Gets the input inventory for this block entity.
* @return A {@link InputInventory} that represents the input inventory.
*/
public InputInventory getInputInventory() { return inputInventory; }
/**
* Gets the output inventory for this block entity.
* @return An {@link OutputInventory} that represents the output slot.
*/
public OutputInventory getOutputInventory() { return outputInventory; }
/**
* The ticking logic. This will check if the block's inventory contains the correct items to craft
* a {@link MagicShapedRecipe}.
* @param world The {@link World} instance.
* @param pos The {@link BlockPos} positional data.
* @param state The {@link BlockState} of the block.
* @param blockEntity An instance of this type.
*/
public static void tick(World world, BlockPos pos, BlockState state, MagicalCrafterBlockEntity blockEntity) {
// Check if the recipe within the crafting inventory matches any recipes. Must happen on server side.
if (world instanceof ServerWorld serverWorld) {
Optional<? extends RecipeEntry<? extends MagicShapedRecipe>> matched = blockEntity.recipeGetter
.getFirstMatch(
new MagicShapedInput(blockEntity.inputInventory.getHeldStacks()),
serverWorld
);
if (matched.isPresent()) {
// Work with the RecipeEntry here
MagicShapedRecipe entry = matched.get().value();
blockEntity.outputInventory.heldStacks.set(0, entry.output());
}
}
}
@Override
public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
return new MagicalCraftingScreenHandler(syncId, playerInventory, inputInventory, outputInventory);
}
@Override
public Text getDisplayName() {
return Text.translatable(getCachedState().getBlock().getTranslationKey());
}
}
@@ -0,0 +1,22 @@
package com.uncreativebunch.magicmod.block.entity;
import com.uncreativebunch.magicmod.block.ModBlocks;
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
public class ModBlockEntityTypes {
public static final BlockEntityType<MagicalCrafterBlockEntity> MAGICAL_CRAFTING_TABLE = register(
"magical_crafting_table",
FabricBlockEntityTypeBuilder.create(MagicalCrafterBlockEntity::new, ModBlocks.MAGICAL_CRAFTING_TABLE).build()
);
public static <T extends BlockEntity> BlockEntityType<T> register(String id, BlockEntityType<T> type) {
return Registry.register(Registries.BLOCK_ENTITY_TYPE, id, type);
}
public static void init() {}
}
@@ -0,0 +1,18 @@
package com.uncreativebunch.magicmod.datagen;
import com.uncreativebunch.magicmod.MagicMod;
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
import net.minecraft.recipe.RecipeManager;
public class DataGenerator implements DataGeneratorEntrypoint {
@Override
public void onInitializeDataGenerator(FabricDataGenerator dataGenerator) {
FabricDataGenerator.Pack pack = dataGenerator.createPack();
MagicMod.LOGGER.info("Hello from the data generator!");
// Add providers to the pack here.
pack.addProvider(MagicRecipeProvider::new);
}
}
@@ -0,0 +1,44 @@
package com.uncreativebunch.magicmod.datagen;
import com.uncreativebunch.magicmod.recipe.MagicShapedRecipe;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.data.recipe.RecipeExporter;
import net.minecraft.data.recipe.RecipeGenerator;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.recipe.Ingredient;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.util.Identifier;
import java.util.concurrent.CompletableFuture;
public class MagicRecipeProvider extends FabricRecipeProvider {
public MagicRecipeProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
super(output, registriesFuture);
}
@Override
protected RecipeGenerator getRecipeGenerator(RegistryWrapper.WrapperLookup registryLookup, RecipeExporter exporter) {
return new RecipeGenerator(registryLookup, exporter) {
@Override
public void generate() {
RegistryWrapper.Impl<Item> itemLookup = registries.getOrThrow(RegistryKeys.ITEM);
// Recipes are added here. We only want to create MagicShapedRecipes here.
MagicShapedRecipe.Builder.build(
Ingredient.ofItem(Items.STICK),
Ingredient.ofItem(Items.STICK),
Ingredient.ofItem(Items.STICK),
Items.REDSTONE.getDefaultStack()
).offerTo(exporter, Identifier.of("magic_mod", "magic_testing_recipe"));
}
};
}
@Override
public String getName() {
return "MagicRecipeProvider";
}
}
@@ -0,0 +1,77 @@
package com.uncreativebunch.magicmod.inventory;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventories;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.collection.DefaultedList;
public interface ImplementedInventory extends Inventory {
DefaultedList<ItemStack> getItems();
static ImplementedInventory of(DefaultedList<ItemStack> items) {
return () -> items;
}
static ImplementedInventory ofSize(int size) {
return of(DefaultedList.ofSize(size, ItemStack.EMPTY));
}
@Override
default int size() {
return getItems().size();
}
@Override
default boolean isEmpty() {
for (int i = 0; i < size(); i++) {
ItemStack stack = getStack(i);
if (!stack.isEmpty()) {
return false;
}
}
return true;
}
@Override
default ItemStack getStack(int slot) {
return getItems().get(slot);
}
@Override
default ItemStack removeStack(int slot, int count) {
ItemStack result = Inventories.splitStack(getItems(), slot, count);
if (!result.isEmpty()) {
markDirty();
}
return result;
}
@Override
default ItemStack removeStack(int slot) {
return Inventories.removeStack(getItems(), slot);
}
@Override
default void setStack(int slot, ItemStack stack) {
getItems().set(slot, stack);
if (stack.getCount() > stack.getMaxCount()) {
stack.setCount(stack.getMaxCount());
}
}
@Override
default void clear() {
getItems().clear();
}
@Override
default void markDirty() {
// Doesn't need to be overridden in this case.
}
@Override
default boolean canPlayerUse(PlayerEntity player) {
return true;
}
}
@@ -0,0 +1,24 @@
package com.uncreativebunch.magicmod.inventory;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.ItemStack;
public class InputInventory extends SimpleInventory {
public InputInventory(int size) {
super(size);
}
@Override
public boolean canInsert(ItemStack stack) {
return true;
}
/**
* Executes basic crafting logic and decrements all input stacks.
*/
public void onCrafted() {
for (var stack : this) {
stack.decrement(1);
}
}
}
@@ -0,0 +1,25 @@
package com.uncreativebunch.magicmod.inventory;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.collection.DefaultedList;
public class OutputInventory extends SimpleInventory {
public OutputInventory(int size) {
super(size);
}
public OutputInventory(ItemStack... items) {
super(items);
}
@Override
public boolean canInsert(ItemStack stack) {
return false;
}
public boolean canAddStack(ItemStack stack) {
return super.canInsert(stack);
}
}
@@ -1,6 +1,7 @@
package com.uncreativebunch.magicmod.item;
import com.uncreativebunch.magicmod.MagicMod;
import com.uncreativebunch.magicmod.block.ModBlocks;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.minecraft.item.ItemGroup;
@@ -42,8 +43,6 @@ public class ModItemGroups {
* custom items.
*/
public static void init() {
ModItems.init();
Registry.register(Registries.ITEM_GROUP, MAGIC_GROUP_KEY, MAGIC_GROUP);
ItemGroupEvents.modifyEntriesEvent(MAGIC_GROUP_KEY)
.register(itemGroup -> {
@@ -58,8 +57,10 @@ public class ModItemGroups {
itemGroup.add(ModItems.OAK_STICK);
itemGroup.add(ModItems.PALE_OAK_STICK);
itemGroup.add(ModItems.SPRUCE_STICK);
itemGroup.add(ModItems.TESTING_POWDER);
itemGroup.add(ModItems.WARPED_STICK);
itemGroup.add(ModItems.TESTING_POWDER);
itemGroup.add(ModBlocks.MAGICAL_CRAFTING_TABLE.asItem());
});
MagicMod.LOGGER.info("Item group initialization complete");
@@ -21,7 +21,7 @@ public class ModItems {
new Item.Settings()
.food(ModFoodComponents.TESTING_POWDER_COMPONENT, ModConsumableComponents.TESTING_POWDER_NIGHTVIS)
);
public static final Item ACACIA_STICK = register(
"acacia_stick",
Item::new,
@@ -94,17 +94,18 @@ public class ModItems {
new Item.Settings()
);
public static RegistryKey<Item> keyOf(String id) {
return RegistryKey.of(RegistryKeys.ITEM, Identifier.of(MagicMod.MOD_ID, id));
}
public static Item register(String name, @NotNull Function<Item.Settings, Item> factory, Item.Settings settings) {
// Create the item's registry key (get it from the ITEM registry)
// Create the item with the specified settings and give it the correct registry key
// Register the item with the registry (use the key we found and associate it with the new item)
RegistryKey<Item> itemKey = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(MagicMod.MOD_ID, name));
RegistryKey<Item> itemKey = keyOf(name);
Item item = factory.apply(settings.registryKey(itemKey));
Registry.register(Registries.ITEM, itemKey, item);
return item;
return Registry.register(Registries.ITEM, itemKey, item);
}
/**
@@ -0,0 +1,23 @@
package com.uncreativebunch.magicmod.recipe;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.input.RecipeInput;
import java.util.List;
public record MagicShapedInput(List<ItemStack> stacks) implements RecipeInput {
@Override
public ItemStack getStackInSlot(int index) {
return stacks.get(index);
}
@Override
public int size() {
return stacks.size();
}
@Override
public boolean isEmpty() {
return RecipeInput.super.isEmpty();
}
}
@@ -0,0 +1,164 @@
package com.uncreativebunch.magicmod.recipe;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.uncreativebunch.magicmod.MagicMod;
import net.minecraft.data.recipe.RecipeExporter;
import net.minecraft.item.ItemStack;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.recipe.*;
import net.minecraft.recipe.book.RecipeBookCategory;
import net.minecraft.recipe.display.RecipeDisplay;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.util.Identifier;
import net.minecraft.world.World;
import java.util.List;
import java.util.Optional;
public record MagicShapedRecipe(Ingredient coreIngredient, Ingredient materialIngredient, Ingredient gripIngredient,
ItemStack output, Identifier id) implements Recipe<MagicShapedInput> {
@Override
public boolean matches(MagicShapedInput input, World world) {
if (input.stacks().size() < 2) return false;
return coreIngredient.test(input.stacks().getFirst())
&& materialIngredient.test(input.stacks().get(1))
&& gripIngredient.test(input.stacks().get(2));
}
@Override
public ItemStack craft(MagicShapedInput input, RegistryWrapper.WrapperLookup registries) {
return this.output.copy();
}
@Override
public boolean isIgnoredInRecipeBook() {
return Recipe.super.isIgnoredInRecipeBook();
}
@Override
public boolean showNotification() {
return Recipe.super.showNotification();
}
@Override
public String getGroup() {
return Recipe.super.getGroup();
}
@Override
public RecipeSerializer<? extends Recipe<MagicShapedInput>> getSerializer() {
return ModRecipeSerializers.MAGIC_SHAPED;
}
@Override
public RecipeType<? extends Recipe<MagicShapedInput>> getType() {
return ModRecipeTypes.MAGIC_SHAPED;
}
@Override
public List<RecipeDisplay> getDisplays() {
return Recipe.super.getDisplays();
}
@Override
public RecipeBookCategory getRecipeBookCategory() {
return null;
}
@Override
public IngredientPlacement getIngredientPlacement() {
List<Optional<Ingredient>> ingredients = List.of(
Optional.of(coreIngredient),
Optional.of(materialIngredient),
Optional.of(gripIngredient)
);
return IngredientPlacement.forMultipleSlots(ingredients);
}
// Type definition
public static class Type implements RecipeType<MagicShapedRecipe> {
private Type() { }
public static final Type INSTANCE = new Type();
public static final String ID = "magic_crafting";
}
// Serializer definition
public static class Serializer implements RecipeSerializer<MagicShapedRecipe> {
public static final Serializer INSTANCE = new Serializer();
private static final MapCodec<MagicShapedRecipe> CODEC = RecordCodecBuilder.mapCodec(
// This function essentially creates a way to deserialize from a JSON using the constructor's
// parameters, as defined above.
instance -> instance.group(
Ingredient.CODEC.fieldOf("coreIngredient").forGetter(MagicShapedRecipe::coreIngredient),
Ingredient.CODEC.fieldOf("materialIngredient").forGetter(MagicShapedRecipe::materialIngredient),
Ingredient.CODEC.fieldOf("gripIngredient").forGetter(MagicShapedRecipe::gripIngredient),
ItemStack.CODEC.fieldOf("output").forGetter(MagicShapedRecipe::output),
Identifier.CODEC.fieldOf("id").forGetter(MagicShapedRecipe::id)
).apply(instance, MagicShapedRecipe::new)
);
private static final PacketCodec<RegistryByteBuf, MagicShapedRecipe> PACKET_CODEC = PacketCodec.tuple(
Ingredient.PACKET_CODEC, MagicShapedRecipe::coreIngredient,
Ingredient.PACKET_CODEC, MagicShapedRecipe::materialIngredient,
Ingredient.PACKET_CODEC, MagicShapedRecipe::gripIngredient,
ItemStack.PACKET_CODEC, MagicShapedRecipe::output,
Identifier.PACKET_CODEC, MagicShapedRecipe::id,
MagicShapedRecipe::new
);
/**
* Gets the codec for this serializer. This determines how the recipe is parsed from JSON.
*
* @return The codec for this serializer.
*/
@Override
public MapCodec<MagicShapedRecipe> codec() {
return CODEC;
}
@Override
@Deprecated
public PacketCodec<RegistryByteBuf, MagicShapedRecipe> packetCodec() {
return PACKET_CODEC;
}
}
// Builder definition
public record Builder(Ingredient core, Ingredient material, Ingredient grip, ItemStack output) {
/**
* Creates a new {@link Builder}.
* @param core The core {@link Ingredient}.
* @param material The material {@link Ingredient}.
* @param grip The grip {@link Ingredient}.
* @param output The output {@link ItemStack}
* @return A new {@link Builder} that can be offered to a {@link RecipeExporter}.
*/
public static Builder build(
Ingredient core,
Ingredient material,
Ingredient grip,
ItemStack output
) {
return new Builder(core, material, grip, output);
}
/**
* Offers the contents of this builder to the given {@link RecipeExporter}.
* @param exporter The {@link RecipeExporter} to use.
* @param recipeId The {@link Identifier} of the recipe to create.
*/
public void offerTo(RecipeExporter exporter, Identifier recipeId) {
RegistryKey<Recipe<?>> key = RegistryKey.of(RegistryKeys.RECIPE, recipeId);
MagicShapedRecipe recipe = new MagicShapedRecipe(core, material, grip, output, recipeId);
exporter.accept(key, recipe, null);
MagicMod.LOGGER.info("Created recipe with id {}", recipeId.toString());
}
}
}
@@ -0,0 +1,28 @@
package com.uncreativebunch.magicmod.recipe;
import com.uncreativebunch.magicmod.MagicMod;
import net.minecraft.recipe.Recipe;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
public class ModRecipeSerializers {
public static RecipeSerializer<MagicShapedRecipe> MAGIC_SHAPED = register(
"magic_shaped",
MagicShapedRecipe.Serializer.INSTANCE
);
/**
* Registers a {@link RecipeSerializer} with Minecraft's internal registry.
* @param id The {@link net.minecraft.util.Identifier} of the serializer.
* @param type An instance of the {@link RecipeSerializer} to register.
* @return The registered instance of the {@link RecipeSerializer}.
* @param <T> The type of the {@link Recipe} that is serialized.
*/
public static <T extends Recipe<?>> RecipeSerializer<T> register(String id, RecipeSerializer<T> type) {
return Registry.register(Registries.RECIPE_SERIALIZER, Identifier.of(MagicMod.MOD_ID, id), type);
}
public static void init() {}
}
@@ -0,0 +1,19 @@
package com.uncreativebunch.magicmod.recipe;
import com.uncreativebunch.magicmod.MagicMod;
import net.minecraft.recipe.Recipe;
import net.minecraft.recipe.RecipeType;
import net.minecraft.recipe.input.RecipeInput;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
public class ModRecipeTypes {
public static final RecipeType<MagicShapedRecipe> MAGIC_SHAPED = register("magic_shaped", MagicShapedRecipe.Type.INSTANCE);
public static <T extends Recipe<?>> RecipeType<T> register(String id, RecipeType<T> type) {
return Registry.register(Registries.RECIPE_TYPE, Identifier.of(MagicMod.MOD_ID, id), type);
}
public static void init() {}
}
@@ -0,0 +1,42 @@
package com.uncreativebunch.magicmod.screen;
import com.uncreativebunch.magicmod.inventory.InputInventory;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.slot.Slot;
public class MagicResultSlot extends Slot {
/**
* The crafting input inventory. There is not a current need for custom logic, but this may come in the future.
*/
protected InputInventory inputInventory;
public MagicResultSlot(InputInventory inputInventory, Inventory outputInventory, int index, int x, int y) {
super(outputInventory, index, x, y);
this.inputInventory = inputInventory;
}
/**
* Runs when the player takes the item out of the slot.
* This slot will run the crafting logic of the {@link InputInventory}.
* @param player The player that took the item.
* @param stack The item that was taken.
*/
@Override
public void onTakeItem(PlayerEntity player, ItemStack stack) {
this.inputInventory.onCrafted();
super.onTakeItem(player, stack);
}
/**
* Returns false, as the result slot does not allow items to be inserted.
* @param stack The item to insert.
* @return False.
*/
@Override
public boolean canInsert(ItemStack stack) {
return false;
}
}
@@ -0,0 +1,115 @@
package com.uncreativebunch.magicmod.screen;
import com.uncreativebunch.magicmod.inventory.InputInventory;
import com.uncreativebunch.magicmod.inventory.OutputInventory;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.slot.Slot;
public class MagicalCraftingScreenHandler extends ScreenHandler {
private final InputInventory inputInventory;
private final OutputInventory outputInventory;
/**
* Client-side constructor.
* @param syncId The sync ID that's sent from the server.
* @param playerInventory The player's inventory.
*/
public MagicalCraftingScreenHandler(int syncId, PlayerInventory playerInventory) {
this(syncId, playerInventory, new InputInventory(3), new OutputInventory(1));
}
/**
* Server-side constructor. The server knows the player's inventory and so can provide it to the client.
* It handles creating the inventory slots and syncs all information from the server to the client.
* @param syncId The sync ID that's sent from the server.
* @param playerInventory The player's inventory.
* @param inputInventory The crafting inventory.
* @param outputInventory The output inventory.
*/
public MagicalCraftingScreenHandler(int syncId, PlayerInventory playerInventory, InputInventory inputInventory,
OutputInventory outputInventory) {
super(ModScreenHandlers.MAGICAL_CRAFTING_SCREEN_HANDLER, syncId);
this.inputInventory = inputInventory;
this.outputInventory = outputInventory;
// Ensure that the crafting inventory is the correct size.
checkSize(inputInventory, 3);
checkSize(outputInventory, 1);
// Ensure that the inventory's custom logic runs (if any)
inputInventory.onOpen(playerInventory.player);
outputInventory.onOpen(playerInventory.player);
// Place all inventory slots within the screen. This piece doesn't actually render the background of the slots,
// as this is handled by the client-side application (the Screen), but it does tell the screen where to render.
// We do assign locations - each slot is 18 units wide/tall.
int m, l;
for (l = 0; l < 3; l++) {
// Create the crafting slots. This is good for a 3x3 grid of crafting slots. It registers them to a
// specific inventory and location on the client's screen, relative to the screen's size and origin.
this.addSlot(new Slot(inputInventory, l, 62 + l * 18, 17));
}
// TODO I don't actually know where the output slot should be located. Get correct coords.
this.addSlot(new MagicResultSlot(inputInventory, outputInventory, 0, 80, 35));
// Add all player inventory slots. Start with the main inventory, then the hotbar.
for (m = 0; m < 3; m++) {
for (l = 0; l < 9; l++) {
this.addSlot(new Slot(playerInventory, l + m * 9 + 9, 8 + l * 18, 84 + m * 18));
}
}
for (m = 0; m < 9; m++) {
this.addSlot(new Slot(playerInventory, m, 8 + m * 18, 142));
}
}
/**
* Checks if the specified slot index is within the crafting inventory.
* @param slotIndex The slot index to check.
* @return True if the slot index is within the crafting inventory, false otherwise.
*/
protected boolean isCraftingInventorySlot(int slotIndex) {
return slotIndex < this.inputInventory.size();
}
@Override
public ItemStack quickMove(PlayerEntity player, int slotIndex) {
// If the slot is in the crafting inventory, move it to the player's inventory.
// Otherwise, don't move it at all.
ItemStack newStack = ItemStack.EMPTY;
Slot slot = this.slots.get(slotIndex);
if (slot.hasStack()) {
ItemStack stack = slot.getStack();
newStack = stack.copy();
if (isCraftingInventorySlot(slotIndex)) {
// Attempt to move the stack into the player's inventory.
if (!this.insertItem(stack, this.inputInventory.size() + this.outputInventory.size(), this.slots.size(), true)) {
return ItemStack.EMPTY;
}
} else {
// Don't move the stack.
return ItemStack.EMPTY;
}
// Check if the stack was moved. If moved entirely, empty the slot.
if (stack.isEmpty()) {
slot.setStack(ItemStack.EMPTY);
} else {
slot.markDirty();
}
}
return newStack;
}
@Override
public boolean canUse(PlayerEntity player) {
return inputInventory.canPlayerUse(player);
}
}
@@ -0,0 +1,21 @@
package com.uncreativebunch.magicmod.screen;
import com.uncreativebunch.magicmod.MagicMod;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.resource.featuretoggle.FeatureFlags;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerType;
public class ModScreenHandlers {
public static final ScreenHandlerType<MagicalCraftingScreenHandler> MAGICAL_CRAFTING_SCREEN_HANDLER =
register("magical_crafting", MagicalCraftingScreenHandler::new);
private static <T extends ScreenHandler> ScreenHandlerType<T> register(String id, ScreenHandlerType.Factory<T> factory) {
return Registry.register(Registries.SCREEN_HANDLER, id, new ScreenHandlerType<>(factory, FeatureFlags.VANILLA_FEATURES));
}
public static void init() {
MagicMod.LOGGER.info("Screen handlers initialized.");
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "magic_mod:block/magical_crafting_table"
}
}
}
@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "magic_mod:block/magical_crafting_table"
}
}
@@ -1,4 +1,5 @@
{
"item.magic_mod.magical_crafting_table": "Magic Crafter",
"item.magic_mod.testing_powder": "Testing Powder (edible)",
"item.magic_mod.acacia_stick": "Acacia Stick",
"item.magic_mod.bamboo_stick": "Bamboo Stick",
@@ -12,5 +13,7 @@
"item.magic_mod.pale_oak_stick": "Pale Oak Stick",
"item.magic_mod.spruce_stick": "Spruce Stick",
"item.magic_mod.warped_stick": "Warped Stick",
"magic_mod.magic_group": "Testing Mod Items"
"container.magical_crafting_table": "Magical Crafting",
"magic_mod.magic_group": "Testing Mod Items",
"tag.item.magic_mod.sticks": "Sticks"
}
@@ -0,0 +1,22 @@
{
"credit": "Made with Blockbench",
"texture_size": [32, 32],
"textures": {
"0": "magic_mod:block/magical_crafting_table",
"particle": "magic_mod:block/magical_crafting_table"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 8, 16],
"faces": {
"north": {"uv": [8, 0, 16, 4], "texture": "#0"},
"east": {"uv": [8, 4, 16, 8], "texture": "#0"},
"south": {"uv": [8, 8, 16, 12], "texture": "#0"},
"west": {"uv": [8, 12, 16, 16], "texture": "#0"},
"up": {"uv": [8, 8, 0, 0], "texture": "#0"},
"down": {"uv": [8, 8, 0, 16], "texture": "#0"}
}
}
]
}
@@ -0,0 +1,12 @@
{
"parent": "minecraft:block/cube",
"textures": {
"up": "minecraft:block/ancient_debris_top",
"down": "minecraft:block/bamboo_block",
"north": "minecraft:block/cobblestone",
"east": "minecraft:block/bedrock",
"south": "minecraft:block/birch_leaves",
"west": "minecraft:block/creaking_heart",
"particle": "minecraft:block/creaking_heart"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

@@ -0,0 +1,19 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "magic_mod:testing_powder"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_fence","key":{"#":"#magic_mod:sticks","W":"minecraft:acacia_planks"},"pattern":["W#W","W#W"],"result":{"count":3,"id":"minecraft:acacia_fence"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"redstone","group":"wooden_fence_gate","key":{"#":"#magic_mod:sticks","W":"minecraft:acacia_planks"},"pattern":["#W#","#W#"],"result":{"count":1,"id":"minecraft:acacia_fence_gate"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_sign","key":{"#":"minecraft:acacia_planks","X":"#magic_mod:sticks"},"pattern":["###","###"," X "],"result":{"count":3,"id":"minecraft:acacia_sign"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","key":{"#":"minecraft:redstone_torch","S":"#magic_mod:sticks","X":"minecraft:iron_ingot"},"pattern":["XSX","X#X","XSX"],"result":{"count":6,"id":"minecraft:activator_rail"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","key":{"/":"#magic_mod:sticks","_":"minecraft:smooth_stone_slab"},"pattern":["///"," / ","/_/"],"result":{"count":1,"id":"minecraft:armor_stand"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"minecraft:flint","Y":"minecraft:feather"},"pattern":["X","#","Y"],"result":{"count":4,"id":"minecraft:arrow"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_fence","key":{"#":"#magic_mod:sticks","W":"minecraft:bamboo_planks"},"pattern":["W#W","W#W"],"result":{"count":3,"id":"minecraft:bamboo_fence"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"redstone","group":"wooden_fence_gate","key":{"#":"#magic_mod:sticks","W":"minecraft:bamboo_planks"},"pattern":["#W#","#W#"],"result":{"count":1,"id":"minecraft:bamboo_fence_gate"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_sign","key":{"#":"minecraft:bamboo_planks","X":"#magic_mod:sticks"},"pattern":["###","###"," X "],"result":{"count":3,"id":"minecraft:bamboo_sign"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_fence","key":{"#":"#magic_mod:sticks","W":"minecraft:birch_planks"},"pattern":["W#W","W#W"],"result":{"count":3,"id":"minecraft:birch_fence"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"redstone","group":"wooden_fence_gate","key":{"#":"#magic_mod:sticks","W":"minecraft:birch_planks"},"pattern":["#W#","#W#"],"result":{"count":1,"id":"minecraft:birch_fence_gate"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_sign","key":{"#":"minecraft:birch_planks","X":"#magic_mod:sticks"},"pattern":["###","###"," X "],"result":{"count":3,"id":"minecraft:birch_sign"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"banner","key":{"#":"minecraft:black_wool","|":"#magic_mod:sticks"},"pattern":["###","###"," | "],"result":{"count":1,"id":"minecraft:black_banner"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"banner","key":{"#":"minecraft:blue_wool","|":"#magic_mod:sticks"},"pattern":["###","###"," | "],"result":{"count":1,"id":"minecraft:blue_banner"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"minecraft:string"},"pattern":[" #X","# X"," #X"],"result":{"count":1,"id":"minecraft:bow"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"banner","key":{"#":"minecraft:brown_wool","|":"#magic_mod:sticks"},"pattern":["###","###"," | "],"result":{"count":1,"id":"minecraft:brown_banner"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"minecraft:copper_ingot","I":"#magic_mod:sticks","X":"minecraft:feather"},"pattern":["X","#","I"],"result":{"count":1,"id":"minecraft:brush"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","key":{"C":"#minecraft:coals","L":"#minecraft:logs","S":"#magic_mod:sticks"},"pattern":[" S ","SCS","LLL"],"result":{"count":1,"id":"minecraft:campfire"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_fence","key":{"#":"#magic_mod:sticks","W":"minecraft:cherry_planks"},"pattern":["W#W","W#W"],"result":{"count":3,"id":"minecraft:cherry_fence"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"redstone","group":"wooden_fence_gate","key":{"#":"#magic_mod:sticks","W":"minecraft:cherry_planks"},"pattern":["#W#","#W#"],"result":{"count":1,"id":"minecraft:cherry_fence_gate"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_sign","key":{"#":"minecraft:cherry_planks","X":"#magic_mod:sticks"},"pattern":["###","###"," X "],"result":{"count":3,"id":"minecraft:cherry_sign"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_fence","key":{"#":"#magic_mod:sticks","W":"minecraft:crimson_planks"},"pattern":["W#W","W#W"],"result":{"count":3,"id":"minecraft:crimson_fence"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"redstone","group":"wooden_fence_gate","key":{"#":"#magic_mod:sticks","W":"minecraft:crimson_planks"},"pattern":["#W#","#W#"],"result":{"count":1,"id":"minecraft:crimson_fence_gate"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_sign","key":{"#":"minecraft:crimson_planks","X":"#magic_mod:sticks"},"pattern":["###","###"," X "],"result":{"count":3,"id":"minecraft:crimson_sign"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","$":"minecraft:tripwire_hook","&":"minecraft:iron_ingot","~":"minecraft:string"},"pattern":["#&#","~$~"," # "],"result":{"count":1,"id":"minecraft:crossbow"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"banner","key":{"#":"minecraft:cyan_wool","|":"#magic_mod:sticks"},"pattern":["###","###"," | "],"result":{"count":1,"id":"minecraft:cyan_banner"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_fence","key":{"#":"#magic_mod:sticks","W":"minecraft:dark_oak_planks"},"pattern":["W#W","W#W"],"result":{"count":3,"id":"minecraft:dark_oak_fence"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"redstone","group":"wooden_fence_gate","key":{"#":"#magic_mod:sticks","W":"minecraft:dark_oak_planks"},"pattern":["#W#","#W#"],"result":{"count":1,"id":"minecraft:dark_oak_fence_gate"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_sign","key":{"#":"minecraft:dark_oak_planks","X":"#magic_mod:sticks"},"pattern":["###","###"," X "],"result":{"count":3,"id":"minecraft:dark_oak_sign"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:diamond_tool_materials"},"pattern":["XX","X#"," #"],"result":{"count":1,"id":"minecraft:diamond_axe"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:diamond_tool_materials"},"pattern":["XX"," #"," #"],"result":{"count":1,"id":"minecraft:diamond_hoe"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:diamond_tool_materials"},"pattern":["XXX"," # "," # "],"result":{"count":1,"id":"minecraft:diamond_pickaxe"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:diamond_tool_materials"},"pattern":["X","#","#"],"result":{"count":1,"id":"minecraft:diamond_shovel"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:diamond_tool_materials"},"pattern":["X","X","#"],"result":{"count":1,"id":"minecraft:diamond_sword"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"minecraft:string"},"pattern":[" #"," #X","# X"],"result":{"count":1,"id":"minecraft:fishing_rod"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:gold_tool_materials"},"pattern":["XX","X#"," #"],"result":{"count":1,"id":"minecraft:golden_axe"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:gold_tool_materials"},"pattern":["XX"," #"," #"],"result":{"count":1,"id":"minecraft:golden_hoe"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:gold_tool_materials"},"pattern":["XXX"," # "," # "],"result":{"count":1,"id":"minecraft:golden_pickaxe"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:gold_tool_materials"},"pattern":["X","#","#"],"result":{"count":1,"id":"minecraft:golden_shovel"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:gold_tool_materials"},"pattern":["X","X","#"],"result":{"count":1,"id":"minecraft:golden_sword"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"banner","key":{"#":"minecraft:gray_wool","|":"#magic_mod:sticks"},"pattern":["###","###"," | "],"result":{"count":1,"id":"minecraft:gray_banner"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"banner","key":{"#":"minecraft:green_wool","|":"#magic_mod:sticks"},"pattern":["###","###"," | "],"result":{"count":1,"id":"minecraft:green_banner"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","key":{"#":"#minecraft:planks","-":"minecraft:stone_slab","I":"#magic_mod:sticks"},"pattern":["I-I","# #"],"result":{"count":1,"id":"minecraft:grindstone"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:iron_tool_materials"},"pattern":["XX","X#"," #"],"result":{"count":1,"id":"minecraft:iron_axe"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:iron_tool_materials"},"pattern":["XX"," #"," #"],"result":{"count":1,"id":"minecraft:iron_hoe"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:iron_tool_materials"},"pattern":["XXX"," # "," # "],"result":{"count":1,"id":"minecraft:iron_pickaxe"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:iron_tool_materials"},"pattern":["X","#","#"],"result":{"count":1,"id":"minecraft:iron_shovel"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"equipment","key":{"#":"#magic_mod:sticks","X":"#minecraft:iron_tool_materials"},"pattern":["X","X","#"],"result":{"count":1,"id":"minecraft:iron_sword"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","key":{"#":"#magic_mod:sticks","X":"minecraft:leather"},"pattern":["###","#X#","###"],"result":{"count":1,"id":"minecraft:item_frame"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_fence","key":{"#":"#magic_mod:sticks","W":"minecraft:jungle_planks"},"pattern":["W#W","W#W"],"result":{"count":3,"id":"minecraft:jungle_fence"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"redstone","group":"wooden_fence_gate","key":{"#":"#magic_mod:sticks","W":"minecraft:jungle_planks"},"pattern":["#W#","#W#"],"result":{"count":1,"id":"minecraft:jungle_fence_gate"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_sign","key":{"#":"minecraft:jungle_planks","X":"#magic_mod:sticks"},"pattern":["###","###"," X "],"result":{"count":3,"id":"minecraft:jungle_sign"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","key":{"#":"#magic_mod:sticks"},"pattern":["# #","###","# #"],"result":{"count":3,"id":"minecraft:ladder"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"redstone","key":{"#":"minecraft:cobblestone","X":"#magic_mod:sticks"},"pattern":["X","#"],"result":{"count":1,"id":"minecraft:lever"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"banner","key":{"#":"minecraft:light_blue_wool","|":"#magic_mod:sticks"},"pattern":["###","###"," | "],"result":{"count":1,"id":"minecraft:light_blue_banner"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"banner","key":{"#":"minecraft:light_gray_wool","|":"#magic_mod:sticks"},"pattern":["###","###"," | "],"result":{"count":1,"id":"minecraft:light_gray_banner"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"banner","key":{"#":"minecraft:lime_wool","|":"#magic_mod:sticks"},"pattern":["###","###"," | "],"result":{"count":1,"id":"minecraft:lime_banner"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"banner","key":{"#":"minecraft:magenta_wool","|":"#magic_mod:sticks"},"pattern":["###","###"," | "],"result":{"count":1,"id":"minecraft:magenta_banner"}}
@@ -0,0 +1,16 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"$%$",
"###"
],
"key": {
"#": "minecraft:obsidian",
"$": "minecraft:amethyst_shard",
"%": "minecraft:book"
},
"result": {
"id": "magic_mod:magical_crafting_table",
"count": 1
}
}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_fence","key":{"#":"#magic_mod:sticks","W":"minecraft:mangrove_planks"},"pattern":["W#W","W#W"],"result":{"count":3,"id":"minecraft:mangrove_fence"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"redstone","group":"wooden_fence_gate","key":{"#":"#magic_mod:sticks","W":"minecraft:mangrove_planks"},"pattern":["#W#","#W#"],"result":{"count":1,"id":"minecraft:mangrove_fence_gate"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_sign","key":{"#":"minecraft:mangrove_planks","X":"#magic_mod:sticks"},"pattern":["###","###"," X "],"result":{"count":3,"id":"minecraft:mangrove_sign"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_fence","key":{"#":"#magic_mod:sticks","W":"minecraft:oak_planks"},"pattern":["W#W","W#W"],"result":{"count":3,"id":"minecraft:oak_fence"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"redstone","group":"wooden_fence_gate","key":{"#":"#magic_mod:sticks","W":"minecraft:oak_planks"},"pattern":["#W#","#W#"],"result":{"count":1,"id":"minecraft:oak_fence_gate"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"wooden_sign","key":{"#":"minecraft:oak_planks","X":"#magic_mod:sticks"},"pattern":["###","###"," X "],"result":{"count":3,"id":"minecraft:oak_sign"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","group":"banner","key":{"#":"minecraft:orange_wool","|":"#magic_mod:sticks"},"pattern":["###","###"," | "],"result":{"count":1,"id":"minecraft:orange_banner"}}
@@ -0,0 +1 @@
{"type":"minecraft:crafting_shaped","category":"misc","key":{"#":"#magic_mod:sticks","X":"#minecraft:wool"},"pattern":["###","#X#","###"],"result":{"count":1,"id":"minecraft:painting"}}
Loaded 100 of 135 files, more files were not shown because too many files have changed in this diff. Show more