Compare commits

...

42 Commits

Author SHA1 Message Date
lowercasebtw
e8d42e5033 Small changes 2025-11-23 20:28:15 -05:00
lowercasebtw
8764c2a251 Add midnightlib to required deps on neoforge 2025-11-23 20:19:10 -05:00
lowercasebtw
85126b5927 1.21.10/fix 2025-11-23 17:27:48 -05:00
lowercasebtw
a0f7125b89 1.21.10 2025-11-23 17:26:49 -05:00
lowercasebtw
1ad6c1f588 Mojmap + Stonecutter 2025-11-23 17:08:22 -05:00
Martin Prokoph
46f36864c2 port: Chase the Skies (1.21.6) 2025-06-19 16:30:56 +02:00
Martin Prokoph
92ba293322 Fix mixin apply crash 2024-12-12 14:50:20 +01:00
lowercasebtw
1d305e8f8b Update to 1.21.4 & New Features
Updated to 1.21.4, along with some new features & bumped version to 2.2.0
2024-12-06 18:17:42 -05:00
lowercasebtw
a6df4e73df Move some enabled checks 2024-12-06 18:12:43 -05:00
lowercasebtw
5119e0b3ba Update to 1.21.4 + New Features 2024-12-06 18:06:46 -05:00
Martin Prokoph
2a03dd78fb Architectury port
because why not
2024-07-07 22:26:59 +02:00
Martin Prokoph
d91ced885d Fix #16 2024-07-07 21:54:23 +02:00
Martin Prokoph
4e2fa07c15 Code cleanup 2024-07-07 21:07:51 +02:00
Martin Prokoph
e8c8fb7c57 Optimize blocking detection code 2024-07-07 21:06:41 +02:00
Martin Prokoph
0bbcf5251e Update to work on newer ViaVersion servers
- There will also not be any delay on those servers
2024-07-07 21:02:14 +02:00
lowercasebtw
bf4769bc4f Merge pull request #23 from lowercasebtw/main
Make the Mace Blockable
2024-06-13 13:19:41 -04:00
lowercasebtw
0f339fd7a5 Merge remote-tracking branch 'origin/main' 2024-06-13 13:18:03 -04:00
lowercasebtw
35987af8c7 Add Mace as a blockable weapon & cleanup canWeaponBlock method. 2024-06-13 13:17:47 -04:00
Martin Prokoph
b20b233595 Merge pull request #22 from lowercasebtw/main
Update to 1.21
2024-06-13 19:16:49 +02:00
lowercasebtw
7e2ef4d2d8 Update to 1.21 2024-06-13 13:07:05 -04:00
Martin Prokoph
95454d1c33 Improved way of rendering the blocking animation
- Now no longer depends on the integrated resourcepack
- Improved compatibility with resourcepacks and mods (closes #17)
- Big thanks to @lowercasebtw for contributing this part of the code
- Fixed #13
2024-06-10 15:39:43 +02:00
Martin Prokoph
68dade9453 Merge pull request #21 from Alexander317/main
Add ru_ru.json (Russian)
2024-06-10 15:32:54 +02:00
Alexander317
51cbfae757 Add ru_ru.json (Russian) 2024-06-10 10:47:10 +03:00
Martin Prokoph
bae992c8b1 Further improve unifiedPublishing 2024-06-09 16:04:56 +02:00
Martin Prokoph
5b0e385d39 Fix unifiedPublishing version name 2024-06-09 15:59:53 +02:00
Martin Prokoph
fb0c90c62a Add unifiedPublishing
Allows for easier uploading to Modrinth and CurseForge
2024-06-09 15:58:16 +02:00
Martin Prokoph
1c4389e30f Merge pull request #20 from lowercasebtw/main
Make pack format support versions 1.20.2+
2024-06-09 15:52:21 +02:00
lowercasebtw
013322f7ee Make pack format support versions 1.20.2+ 2024-06-09 09:51:33 -04:00
Martin Prokoph
1b39555f7e Merge pull request #19 from lowercasebtw/main
Update to 1.20.6, and update loom to 1.6.
2024-06-09 15:35:06 +02:00
lowercasebtw
909fc4f9b0 Update to 1.20.6 & Don't import all Item classes when it isn't needed 2024-06-09 09:31:40 -04:00
lowercasebtw
d8ade3e4e8 Update to 1.20.5, and update loom to 1.6. 2024-04-24 20:38:12 -04:00
Motschen
f482d2e700 Update build.gradle 2023-06-11 16:45:43 +02:00
Motschen
24a923ef16 SwordBlocking 1.3.1 - Update to 1.20 2023-06-11 16:32:33 +02:00
Martin Prokoph
c126a76a5e Merge pull request #12 from helpimnotdrowning/main
Gradle files bump to 1.20
2023-06-11 16:24:45 +02:00
helpimnotdrowning
75b980f36f Update to 1.20 2023-06-07 13:48:46 -05:00
Martin Prokoph
6cd237e087 Merge pull request #10 from unilock/feat/1.19.4
Update to 1.19.4
2023-05-24 14:39:24 +02:00
unilock
a66be9a7be Update to 1.19.4
Signed-off-by: unilock <unilock@fennet.rentals>
2023-03-27 09:22:14 -04:00
Motschen
ca198eeea3 SwordBlocking 1.2.0 - 1.19.3, Config, Axe blocking,
- Added configuration screen based on MidnightLib
- Made everything configurable
- Add option to hide offhand slot when it contains a shield
- Fix 3rd-person blocking
2023-01-28 19:41:02 +01:00
Motschen
c847b0f1d0 Merge pull request #4 from helpimnotdrowning/main
Port to 1.17 by helpimnotdrowning
2021-08-22 20:32:24 +02:00
helpimnotdrowning
82e910a5fa Bump mod verison 2021-07-06 18:49:10 -05:00
helpimnotdrowning@gmail.com
a7113cc4de Fix some weird stuff about lambdas, ty intellij context actions <3 2021-07-06 18:47:38 -05:00
helpimnotdrowning@gmail.com
d1a18cded6 Compile with Java 16 for 1.17 2021-07-06 18:44:08 -05:00
48 changed files with 1233 additions and 639 deletions

6
.editorconfig Normal file
View File

@@ -0,0 +1,6 @@
[*]
end_of_line = lf
[{*.json,*.toml}]
indent_style = tab
indent_size = 4

19
.gitignore vendored
View File

@@ -1,9 +1,13 @@
# gradle # gradle
.gradle/ .gradle/
build/
out/ out/
classes/ classes/
build/
# eclipse
*.launch
# idea # idea
@@ -20,6 +24,17 @@ bin/
.classpath .classpath
.project .project
# macos
*.DS_Store
# fabric # fabric
run/ run/
# java
hs_err_*.log
replay_*.log
*.hprof
*.jfr

View File

@@ -1,3 +1,3 @@
# Sword Blocking # Sword Blocking
A minecraft fabric clientside mod to restore sword blocking, you just need a shield in your offhand. A minecraft fabric clientside mod to restore sword blocking, you just need a shield in your offhand.
Works especially well if you want to use 1.16 on an 1.8 server which is running ViaVersion. Works especially well if you want to use 1.16 on an 1.8 server which is running ViaVersion.

View File

@@ -1,80 +0,0 @@
plugins {
id 'fabric-loom' version '0.5-SNAPSHOT'
id 'maven-publish'
}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
archivesBaseName = project.archives_base_name
version = project.mod_version
group = project.maven_group
minecraft {
}
repositories {
maven { url "https://jitpack.io" }
}
dependencies {
//to change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modCompile "net.fabricmc:fabric-loader:${project.loader_version}"
modCompile "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
}
processResources {
inputs.property "version", project.version
from(sourceSets.main.resources.srcDirs) {
include "fabric.mod.json"
expand "version": project.version
}
from(sourceSets.main.resources.srcDirs) {
exclude "fabric.mod.json"
}
}
// ensure that the encoding is set to UTF-8, no matter what the system default is
// this fixes some edge cases with special characters not displaying correctly
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
// if it is present.
// If you remove this task, sources will not be generated.
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = "sources"
from sourceSets.main.allSource
}
jar {
from "LICENSE"
}
// configure the maven publication
publishing {
publications {
mavenJava(MavenPublication) {
// add all the jars that should be included when publishing to maven
artifact(remapJar) {
builtBy remapJar
}
artifact(sourcesJar) {
builtBy remapSourcesJar
}
}
}
// select the repositories you want to publish to
repositories {
// uncomment to publish to the local maven
// mavenLocal()
}
}

226
build.gradle.kts Normal file
View File

@@ -0,0 +1,226 @@
plugins {
alias(libs.plugins.kotlin.jvm)
alias(libs.plugins.loom)
alias(libs.plugins.publishing)
alias(libs.plugins.blossom)
alias(libs.plugins.ksp)
alias(libs.plugins.fletchingtable.fabric)
}
repositories {
maven("https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1") // DevAuth
maven("https://maven.parchmentmc.org") // Parchment
maven("https://maven.neoforged.net/releases") // NeoForge
maven("https://maven.bawnorton.com/releases") // MixinSquared
maven("https://maven.terraformersmc.com/") // Mod Menu
maven("https://api.modrinth.com/maven") // MidnightLib
}
class ModData {
val id = property("mod.id") as String
val name = property("mod.name") as String
val version = property("mod.version") as String
val group = property("mod.group") as String
val description = property("mod.description") as String
val source = property("mod.source") as String
val issues = property("mod.issues") as String
val license = property("mod.license") as String
val modrinth = property("mod.modrinth") as String
val curseforge = property("mod.curseforge") as String
val discord = property("mod.discord") as String
val minecraftVersion = property("mod.minecraft_version") as String
val minecraftVersionRange = property("mod.minecraft_version_range") as String
}
class Dependencies {
val fabricLoaderVersion = property("deps.fabric_loader_version") as String?
val midnightLibVersion = property("deps.midnightlib_version") as String?
val devAuthVersion = property("deps.devauth_version") as String?
val lombokVersion = property("deps.lombok_version") as String?
val mixinConstraintsVersion = property("deps.mixinconstraints_version") as String?
val mixinSquaredVersion = property("deps.mixinsquared_version") as String?
// Versioned
val neoForgeVersion = property("deps.neoforge_version") as String?
val fabricApiVersion = property("deps.fabric_api_version") as String?
}
class LoaderData {
val name = loom.platform.get().name.lowercase()
val isFabric = name == "fabric"
val isNeoForge = name == "neoforge"
}
val mod = ModData()
val deps = Dependencies()
val loader = LoaderData()
group = mod.group
base {
archivesName.set("${mod.id}-${mod.version}+${mod.minecraftVersion}-${loader.name}")
}
java {
val requiredJava = when {
stonecutter.eval(stonecutter.current.version, ">=1.20.6") -> JavaVersion.VERSION_21
stonecutter.eval(stonecutter.current.version, ">=1.18") -> JavaVersion.VERSION_17
stonecutter.eval(stonecutter.current.version, ">=1.17") -> JavaVersion.VERSION_16
else -> JavaVersion.VERSION_1_8
}
sourceCompatibility = requiredJava
targetCompatibility = requiredJava
}
stonecutter {
replacements.string {
direction = eval(current.version, ">=1.21.11")
replace("ResourceLocation", "Identifier")
}
}
val currentCommitHash: String by lazy {
Runtime.getRuntime()
.exec("git rev-parse --verify --short HEAD", null, rootDir)
.inputStream.bufferedReader().readText().trim()
}
blossom {
replaceToken("@MODID@", mod.id)
replaceToken("@VERSION@", mod.version)
replaceToken("@COMMIT@", currentCommitHash)
}
loom {
silentMojangMappingsLicense()
runConfigs.all {
ideConfigGenerated(stonecutter.current.isActive)
runDir = "../../run"
}
runConfigs.remove(runConfigs["server"]) // Removes server run configs
}
loom.runs {
afterEvaluate {
val mixinJarFile = configurations.runtimeClasspath.get().incoming.artifactView {
componentFilter {
it is ModuleComponentIdentifier && it.group == "net.fabricmc" && it.module == "sponge-mixin"
}
}.files.first()
configureEach {
vmArg("-javaagent:$mixinJarFile")
property("mixin.hotSwap", "true")
property("mixin.debug.export", "true") // Puts mixin outputs in /run/.mixin.out
property("devauth.enabled", "true")
property("devauth.account", "main")
}
}
}
fletchingTable {
mixins.create("main") {
mixin("default", "${mod.id}.mixins.json")
}
lang.create("main") {
patterns.add("assets/${mod.id}/lang/**")
}
}
dependencies {
minecraft("com.mojang:minecraft:${mod.minecraftVersion}")
@Suppress("UnstableApiUsage")
mappings(loom.layered {
officialMojangMappings()
// Parchment mappings (it adds parameter mappings & javadoc)
optionalProp("deps.parchment_version") {
parchment("org.parchmentmc.data:parchment-${mod.minecraftVersion}:$it@zip")
}
})
modImplementation("maven.modrinth:midnightlib:${deps.midnightLibVersion}+${mod.minecraftVersion}-${loader.name}")
compileOnly("org.projectlombok:lombok:${deps.lombokVersion}")
annotationProcessor("org.projectlombok:lombok:${deps.lombokVersion}")
modRuntimeOnly("me.djtheredstoner:DevAuth-${loader.name}:${deps.devAuthVersion}")
include(implementation("com.moulberry:mixinconstraints:${deps.mixinConstraintsVersion}")!!)!!
include(implementation(annotationProcessor("com.github.bawnorton.mixinsquared:mixinsquared-${loader.name}:${deps.mixinSquaredVersion}")!!)!!)
if (loader.isFabric) {
modImplementation("net.fabricmc:fabric-loader:${deps.fabricLoaderVersion}")!!
modImplementation("net.fabricmc.fabric-api:fabric-api:${deps.fabricApiVersion}")
optionalProp("deps.modmenu_version") { prop ->
modImplementation("com.terraformersmc:modmenu:$prop") {
exclude(group, "net.fabricmc.fabric-api")
}
}
} else if (loader.isNeoForge) {
"neoForge"("net.neoforged:neoforge:${deps.neoForgeVersion}")
}
}
publishMods {
}
tasks {
processResources {
val props = buildMap {
put("id", mod.id)
put("name", mod.name)
put("version", mod.version)
put("description", mod.description)
put("source", mod.source)
put("issues", mod.issues)
put("license", mod.license)
put("modrinth", mod.modrinth)
put("curseforge", mod.curseforge)
put("discord", mod.discord)
put("minecraft_version_range", mod.minecraftVersionRange)
if (loader.isFabric) {
put("fabric_api_version", deps.fabricApiVersion?.trim())
put("fabric_loader_version", deps.fabricLoaderVersion?.trim())
} else if (loader.isNeoForge) {
put("neoforge_version", deps.neoForgeVersion?.trim())
}
}
props.forEach(inputs::property)
filesMatching("**/lang/en_us.json") { // Defaults description to English translation
expand(props)
filteringCharset = "UTF-8"
}
if (loader.isFabric) {
filesMatching("fabric.mod.json") { expand(props) }
exclude(listOf("META-INF/neoforge.mods.toml"))
}
if (loader.isNeoForge) {
filesMatching("META-INF/neoforge.mods.toml") { expand(props) }
exclude(listOf("fabric.mod.json"))
}
}
// Builds the version into a shared folder in `build/libs/${mod version}/`
register<Copy>("buildAndCollect") {
group = "build"
from(remapJar.map { it.archiveFile }, remapSourcesJar.map { it.archiveFile })
into(rootProject.layout.buildDirectory.file("libs/${project.property("mod.version")}"))
dependsOn("build")
}
}
if (stonecutter.current.isActive) {
rootProject.tasks.register("buildActive") {
group = "project"
dependsOn(tasks.named("build"))
}
}
fun <T> optionalProp(property: String, block: (String) -> T?): T? =
findProperty(property)?.toString()?.takeUnless { it.isBlank() }?.let(block)

View File

@@ -1,17 +1,44 @@
# Done to increase the memory available to gradle. # Done to increase the memory available to Gradle.
org.gradle.jvmargs=-Xmx1G org.gradle.jvmargs=-Xmx4G
org.gradle.parallel=true
# Fabric Properties # IntelliJ IDEA is not yet fully compatible with configuration cache, see: https://github.com/FabricMC/fabric-loom/issues/1349
# check these on https://fabricmc.net/use org.gradle.configuration-cache=false
minecraft_version=1.16.4
yarn_mappings=1.16.4+build.7
loader_version=0.10.8
# Mod Properties # Mod properties
mod_version = 1.0.0 mod.name=SwordBlocking
maven_group = eu.midnightdust mod.id=swordblocking
archives_base_name = swordblocking mod.version=1.0
mod.group=eu.midnightdust.swordblocking
mod.description=Adds sword blocking to new versions, you just need a shield in your offhand (or ViaVersion)!
mod.source=https://github.com/TeamMidnightDust/SwordBlocking
mod.issues=https://github.com/TeamMidnightDust/SwordBlocking/issues
mod.license=MIT
mod.modrinth=https://modrinth.com/mod/sword-blocking
mod.curseforge=http://curseforge.com/minecraft/mc-mods/sword-blocking
mod.discord=https://discord.gg/jAGnWYHm3r
# Publishing
publish.modrinth=
publish.curseforge=
# Dependencies # Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api deps.fabric_loader_version=0.17.3
fabric_version=0.26.1+1.16 deps.midnightlib_version=1.9.1
deps.devauth_version=1.2.1
deps.lombok_version=1.18.42
deps.mixinconstraints_version=1.1.0
deps.mixinsquared_version=0.2.0
# Build Plugins
# in libs.versions.toml
# Minecraft properties
mod.mc_dep=[VERSIONED]
mod.mc_version=[VERSIONED]
# Versioned
deps.parchment_version=[VERSIONED]
deps.fabric_api_version=[VERSIONED]
deps.neoforge_version=[VERSIONED]

16
gradle/libs.versions.toml Normal file
View File

@@ -0,0 +1,16 @@
[versions]
kotlin-jvm = "2.2.0"
loom = "1.13-SNAPSHOT"
publishing = "0.8.4"
blossom = "1.3.2"
ksp = "2.2.0-2.0.2"
fletchingtable = "0.1.0-alpha.13"
[plugins]
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin-jvm" }
loom = { id = "dev.architectury.loom", version.ref = "loom" }
publishing = { id = "me.modmuss50.mod-publish-plugin", version.ref = "publishing" }
blossom = { id = "net.kyori.blossom", version.ref = "blossom" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
fletchingtable-fabric = { id = "dev.kikugie.fletching-table.fabric", version.ref = "fletchingtable" }
fletchingtable-neoforge = { id = "dev.kikugie.fletching-table.neoforge", version.ref = "fletchingtable" }

Binary file not shown.

View File

@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

295
gradlew vendored Normal file → Executable file
View File

@@ -1,7 +1,7 @@
#!/usr/bin/env sh #!/bin/sh
# #
# Copyright 2015 the original author or authors. # Copyright © 2015 the original authors.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@@ -17,78 +17,111 @@
# #
############################################################################## ##############################################################################
## #
## Gradle start up script for UN*X # Gradle start up script for POSIX generated by Gradle.
## #
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
############################################################################## ##############################################################################
# Attempt to set APP_HOME # Attempt to set APP_HOME
# Resolve links: $0 may be a link # Resolve links: $0 may be a link
PRG="$0" app_path=$0
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do # Need this for daisy-chained symlinks.
ls=`ls -ld "$PRG"` while
link=`expr "$ls" : '.*-> \(.*\)$'` APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
if expr "$link" : '/.*' > /dev/null; then [ -h "$app_path" ]
PRG="$link" do
else ls=$( ls -ld "$app_path" )
PRG=`dirname "$PRG"`"/$link" link=${ls#*' -> '}
fi case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle" # This is normally unused
APP_BASE_NAME=`basename "$0"` # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD=maximum
warn () { warn () {
echo "$*" echo "$*"
} } >&2
die () { die () {
echo echo
echo "$*" echo "$*"
echo echo
exit 1 exit 1
} } >&2
# OS specific support (must be 'true' or 'false'). # OS specific support (must be 'true' or 'false').
cygwin=false cygwin=false
msys=false msys=false
darwin=false darwin=false
nonstop=false nonstop=false
case "`uname`" in case "$( uname )" in #(
CYGWIN* ) CYGWIN* ) cygwin=true ;; #(
cygwin=true Darwin* ) darwin=true ;; #(
;; MSYS* | MINGW* ) msys=true ;; #(
Darwin* ) NONSTOP* ) nonstop=true ;;
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables # IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java" JAVACMD=$JAVA_HOME/jre/sh/java
else else
JAVACMD="$JAVA_HOME/bin/java" JAVACMD=$JAVA_HOME/bin/java
fi fi
if [ ! -x "$JAVACMD" ] ; then if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -97,92 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
else else
JAVACMD="java" JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
MAX_FD_LIMIT=`ulimit -H -n` case $MAX_FD in #(
if [ $? -eq 0 ] ; then max*)
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
MAX_FD="$MAX_FD_LIMIT" # shellcheck disable=SC2039,SC3045
fi MAX_FD=$( ulimit -H -n ) ||
ulimit -n $MAX_FD warn "Could not query maximum file descriptor limit"
if [ $? -ne 0 ] ; then esac
warn "Could not set maximum file descriptor limit: $MAX_FD" case $MAX_FD in #(
fi '' | soft) :;; #(
else *)
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
fi # shellcheck disable=SC2039,SC3045
fi ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac esac
fi fi
# Escape application args # Collect all arguments for the java command, stacking in reverse order:
save () { # * args from the command line
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done # * the main class name
echo " " # * -classpath
} # * -D...appname settings
APP_ARGS=$(save "$@") # * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules # For Cygwin or MSYS, switch paths to Windows format before running java
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong JAVACMD=$( cygpath --unix "$JAVACMD" )
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")" # Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@" exec "$JAVACMD" "$@"

192
gradlew.bat vendored
View File

@@ -1,100 +1,92 @@
@rem @rem
@rem Copyright 2015 the original author or authors. @rem Copyright 2015 the original author or authors.
@rem @rem
@rem Licensed under the Apache License, Version 2.0 (the "License"); @rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License. @rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at @rem You may obtain a copy of the License at
@rem @rem
@rem https://www.apache.org/licenses/LICENSE-2.0 @rem https://www.apache.org/licenses/LICENSE-2.0
@rem @rem
@rem Unless required by applicable law or agreed to in writing, software @rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS, @rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem Gradle startup script for Windows
@rem @rem
@rem ########################################################################## @rem ##########################################################################
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0 @rem This is normally unused
set APP_HOME=%DIRNAME% set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 @rem Find java.exe
if "%ERRORLEVEL%" == "0" goto init if defined JAVA_HOME goto findJavaFromJavaHome
echo. set JAVA_EXE=java.exe
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. %JAVA_EXE% -version >NUL 2>&1
echo. if %ERRORLEVEL% equ 0 goto execute
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
goto fail echo.
echo Please set the JAVA_HOME variable in your environment to match the
:findJavaFromJavaHome echo location of your Java installation.
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe goto fail
if exist "%JAVA_EXE%" goto init :findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
echo. set JAVA_EXE=%JAVA_HOME%/bin/java.exe
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo. if exist "%JAVA_EXE%" goto execute
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
goto fail echo.
echo Please set the JAVA_HOME variable in your environment to match the
:init echo location of your Java installation.
@rem Get command-line arguments, handling Windows variants
goto fail
if not "%OS%" == "Windows_NT" goto win9xME_args
:execute
:win9xME_args @rem Setup the command line
@rem Slurp the command line arguments.
set CMD_LINE_ARGS= set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set _SKIP=2
:win9xME_args_slurp @rem Execute Gradle
if "x%~1" == "x" goto execute "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
set CMD_LINE_ARGS=%* :end
@rem End local scope for the variables with windows NT shell
:execute if %ERRORLEVEL% equ 0 goto mainEnd
@rem Setup the command line
:fail
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
@rem Execute Gradle set EXIT_CODE=%ERRORLEVEL%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
:end exit /b %EXIT_CODE%
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of :omega
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -1,10 +0,0 @@
pluginManagement {
repositories {
jcenter()
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
gradlePluginPortal()
}
}

40
settings.gradle.kts Normal file
View File

@@ -0,0 +1,40 @@
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
maven("https://maven.fabricmc.net")
maven("https://maven.architectury.dev")
maven("https://maven.kikugie.dev/snapshots")
maven("https://maven.kikugie.dev/releases")
maven("https://repo.polyfrost.cc/releases")
}
}
plugins {
id("dev.kikugie.stonecutter") version "0.7.10"
}
stonecutter {
kotlinController = true
centralScript = "build.gradle.kts"
create(rootProject) {
fun mc(mcVersion: String, loaders: Iterable<String>) {
for (loader in loaders) {
version("$mcVersion-$loader", mcVersion)
}
}
mc("1.21.8", listOf("fabric", "neoforge"))
mc("1.21.10", listOf("fabric", "neoforge"))
vcsVersion = "1.21.8-fabric"
}
}
dependencyResolutionManagement {
versionCatalogs {
create("libs")
}
}
rootProject.name = "SwordBlocking"

View File

@@ -1,21 +1,66 @@
package eu.midnightdust.swordblocking; package eu.midnightdust.swordblocking;
import eu.midnightdust.swordblocking.config.SwordBlockingConfig;
import net.minecraft.core.component.DataComponents;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ShieldItem;
//? fabric {
import dev.kikugie.fletching_table.annotation.fabric.Entrypoint;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.object.builder.v1.client.model.FabricModelPredicateProviderRegistry; //?} else {
import net.minecraft.item.Items; /*import net.neoforged.api.distmarker.Dist;
import net.minecraft.item.SwordItem; import net.neoforged.fml.common.Mod;
import net.minecraft.util.Identifier; *///?}
import net.minecraft.util.registry.Registry;
public class SwordBlockingClient implements ClientModInitializer { //? fabric
@Entrypoint
//? neoforge
/*@Mod(value = SwordBlockingClient.MOD_ID, dist = Dist.CLIENT)*/
public final class SwordBlockingClient
//? fabric
implements ClientModInitializer
{
public static final String MOD_ID = "@MODID@";
// TODO/NOTE: I know this can be condensed more but i'm tired so will recheck later
public static boolean canEntityBlock(ItemStack mainHandStack, ItemStack offHandStack) {
return SwordBlockingConfig.enabled && canShieldSwordBlock(mainHandStack, offHandStack);
}
// TODO/NOTE: I know this can be condensed more but i'm tired so will recheck later
public static boolean canShieldSwordBlock(ItemStack mainHandStack, ItemStack offHandStack) {
if (SwordBlockingConfig.enabled && (offHandStack.getItem() instanceof ShieldItem || mainHandStack.getItem() instanceof ShieldItem)) {
final Item weaponItem = offHandStack.getItem() instanceof ShieldItem ? mainHandStack.getItem() : offHandStack.getItem();
return weaponItem.components().has(DataComponents.DAMAGE);
} else {
return false;
}
}
// TODO/NOTE: I know this can be condensed more but i'm tired so will recheck later
public static boolean shouldHideShield(ItemStack mainHandStack, ItemStack offHandStack, ItemStack stack) {
if (SwordBlockingConfig.enabled && stack.getItem() instanceof ShieldItem) {
return (SwordBlockingConfig.alwaysHideShield && SwordBlockingConfig.hideShield) ||
(SwordBlockingConfig.hideShield && SwordBlockingClient.canShieldSwordBlock(mainHandStack, offHandStack));
} else {
return false;
}
}
private void initialize() {
SwordBlockingConfig.init(MOD_ID, SwordBlockingConfig.class);
}
//? neoforge {
/*public SwordBlockingClient() {
initialize();
}
*///?} else {
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
Registry.ITEM.forEach((item) -> { initialize();
if(item instanceof SwordItem) {
FabricModelPredicateProviderRegistry.register(item, new Identifier("blocking"), (stack, world, entity) ->
entity != null && entity.getOffHandStack().getItem().equals(Items.SHIELD) && entity.isUsingItem() ? 1.0F : 0.0F);
}
});
} }
} //?}
}

View File

@@ -0,0 +1,26 @@
package eu.midnightdust.swordblocking.config;
import eu.midnightdust.lib.config.MidnightConfig;
public class SwordBlockingConfig extends MidnightConfig {
@Entry
public static boolean enabled = true;
@Entry
public static boolean hideShield = true;
@Entry
public static boolean alwaysHideShield = true;
@Entry
public static boolean hideOffhandSlot = false;
@Entry
public static boolean disableUseEquipAnimation = false;
@Entry
public static boolean lockBlockingArmPosition = false;
@Entry
public static boolean blockHitAnimation = false;
}

View File

@@ -0,0 +1,16 @@
package eu.midnightdust.swordblocking.ducks;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.item.ItemStack;
public interface ArmedItemStackData {
ItemStack swordblocking$getItemHeldByArm(HumanoidArm humanoidArm);
ItemStack swordblocking$getOffHandItem();
void swordblocking$setOffHandItem(ItemStack stack);
ItemStack swordblocking$getMainHandItem();
void swordblocking$setMainHandItem(ItemStack stack);
}

View File

@@ -1,32 +0,0 @@
package eu.midnightdust.swordblocking.mixin;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.entity.PlayerEntityRenderer;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ShieldItem;
import net.minecraft.util.Hand;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PlayerEntityRenderer.class)
public abstract class MixinPlayerEntityRenderer {
@Inject(at = @At("HEAD"), method = "getArmPose", cancellable = true)
@Environment(EnvType.CLIENT)
private static void getArmPose(AbstractClientPlayerEntity abstractClientPlayerEntity, Hand hand, CallbackInfoReturnable<BipedEntityModel.ArmPose> cir) {
ItemStack itemStack = abstractClientPlayerEntity.getStackInHand(hand);
ItemStack itemStack2 = abstractClientPlayerEntity.getOffHandStack();
if (itemStack2.getItem() instanceof ShieldItem && abstractClientPlayerEntity.isUsingItem()) {
cir.setReturnValue(BipedEntityModel.ArmPose.BLOCK);
}
if (itemStack.getItem() instanceof ShieldItem) {
cir.setReturnValue(BipedEntityModel.ArmPose.EMPTY);
}
}
}

View File

@@ -0,0 +1,60 @@
package eu.midnightdust.swordblocking.mixins;
import eu.midnightdust.swordblocking.ducks.ArmedItemStackData;
import net.minecraft.client.renderer.entity.state.ArmedEntityRenderState;
import net.minecraft.client.renderer.item.ItemModelResolver;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ArmedEntityRenderState.class)
public abstract class MixinArmedEntityRenderState implements ArmedItemStackData {
@Unique
private ItemStack swordblocking$offHandStack = ItemStack.EMPTY;
@Unique
private ItemStack swordblocking$mainHandStack = ItemStack.EMPTY;
@Inject(method = "extractArmedEntityRenderState", at = @At("TAIL"))
private static void swordBlocking$storeRequiredData(LivingEntity livingEntity, ArmedEntityRenderState armedEntityRenderState, ItemModelResolver itemModelResolver, CallbackInfo ci) {
ArmedItemStackData armedItemStackData = (ArmedItemStackData) armedEntityRenderState;
armedItemStackData.swordblocking$setOffHandItem(livingEntity.getOffhandItem());
armedItemStackData.swordblocking$setMainHandItem(livingEntity.getMainHandItem());
}
@Override
public ItemStack swordblocking$getItemHeldByArm(HumanoidArm arm) {
if (arm == HumanoidArm.LEFT) {
return swordblocking$offHandStack;
} else if (arm == HumanoidArm.RIGHT) {
return swordblocking$mainHandStack;
} else {
throw new UnsupportedOperationException();
}
}
@Override
public ItemStack swordblocking$getOffHandItem() {
return this.swordblocking$offHandStack;
}
@Override
public void swordblocking$setOffHandItem(ItemStack stack) {
this.swordblocking$offHandStack = stack;
}
@Override
public ItemStack swordblocking$getMainHandItem() {
return this.swordblocking$mainHandStack;
}
@Override
public void swordblocking$setMainHandItem(ItemStack stack) {
this.swordblocking$mainHandStack = stack;
}
}

View File

@@ -0,0 +1,21 @@
package eu.midnightdust.swordblocking.mixins;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import eu.midnightdust.swordblocking.config.SwordBlockingConfig;
import net.minecraft.client.gui.Gui;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ShieldItem;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(Gui.class)
public abstract class MixinGui {
@ModifyExpressionValue(method = "renderItemHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;getOffhandItem()Lnet/minecraft/world/item/ItemStack;"))
public ItemStack swordBlocking$hideOffHandSlot(ItemStack original) {
if (SwordBlockingConfig.enabled && SwordBlockingConfig.hideOffhandSlot && original.getItem() instanceof ShieldItem) {
return ItemStack.EMPTY;
} else {
return original;
}
}
}

View File

@@ -0,0 +1,48 @@
package eu.midnightdust.swordblocking.mixins;
import eu.midnightdust.swordblocking.SwordBlockingClient;
import eu.midnightdust.swordblocking.config.SwordBlockingConfig;
import eu.midnightdust.swordblocking.ducks.ArmedItemStackData;
import net.minecraft.client.model.HumanoidModel;
import net.minecraft.client.renderer.entity.state.HumanoidRenderState;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ShieldItem;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(HumanoidModel.class)
public abstract class MixinHumanoidModel {
@Shadow
protected abstract void poseLeftArm(HumanoidRenderState renderState, HumanoidModel.ArmPose pose);
@Shadow
protected abstract void poseRightArm(HumanoidRenderState renderState, HumanoidModel.ArmPose pose);
@Inject(method = "setupAnim(Lnet/minecraft/client/renderer/entity/state/HumanoidRenderState;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/model/HumanoidModel;setupAttackAnimation(Lnet/minecraft/client/renderer/entity/state/HumanoidRenderState;F)V", shift = At.Shift.BEFORE))
private void swordBlocking$setBlockingAngles(HumanoidRenderState renderState, CallbackInfo ci) {
final ArmedItemStackData armedItemStackData = (ArmedItemStackData) renderState;
final ItemStack offHandStack = armedItemStackData.swordblocking$getOffHandItem();
final ItemStack mainHandStack = armedItemStackData.swordblocking$getMainHandItem();
if (renderState.isUsingItem && SwordBlockingClient.canEntityBlock(mainHandStack, offHandStack)) {
if (offHandStack.getItem() instanceof ShieldItem) {
this.poseRightArm(renderState, HumanoidModel.ArmPose.BLOCK);
} else {
this.poseLeftArm(renderState, HumanoidModel.ArmPose.BLOCK);
}
}
}
@Redirect(method = "poseBlockingArm", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Mth;clamp(FFF)F"))
private float swordBlocking$lockArmPosition(float value, float min, float max) {
if (SwordBlockingConfig.enabled && SwordBlockingConfig.lockBlockingArmPosition) {
return 0F;
} else {
return value;
}
}
}

View File

@@ -0,0 +1,35 @@
package eu.midnightdust.swordblocking.mixins;
import com.llamalad7.mixinextras.sugar.Local;
import eu.midnightdust.swordblocking.SwordBlockingClient;
import eu.midnightdust.swordblocking.config.SwordBlockingConfig;
import eu.midnightdust.swordblocking.ducks.ArmedItemStackData;
import net.minecraft.client.model.ArmedModel;
import net.minecraft.client.model.EntityModel;
import net.minecraft.client.renderer.entity.layers.ItemInHandLayer;
import net.minecraft.client.renderer.entity.state.ArmedEntityRenderState;
import net.minecraft.client.renderer.item.ItemStackRenderState;
import net.minecraft.world.entity.HumanoidArm;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ItemInHandLayer.class)
public abstract class MixinItemInHandLayer<S extends ArmedEntityRenderState, M extends EntityModel<S> & ArmedModel> {
@Redirect(
//? >=1.21.10 {
method = "submitArmWithItem",
//? } else {
/*method = "renderArmWithItem",
*///? }
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/item/ItemStackRenderState;isEmpty()Z")
)
private boolean swordBlocking$hideShield(ItemStackRenderState instance, @Local(argsOnly = true) S renderState, @Local(argsOnly = true) HumanoidArm arm) {
if (SwordBlockingConfig.enabled) {
final ArmedItemStackData armedItemStackData = (ArmedItemStackData) renderState;
return SwordBlockingClient.shouldHideShield(armedItemStackData.swordblocking$getMainHandItem(), armedItemStackData.swordblocking$getOffHandItem(), armedItemStackData.swordblocking$getItemHeldByArm(arm));
}
return instance.isEmpty();
}
}

View File

@@ -0,0 +1,116 @@
package eu.midnightdust.swordblocking.mixins;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.blaze3d.vertex.PoseStack;
import eu.midnightdust.swordblocking.SwordBlockingClient;
import eu.midnightdust.swordblocking.config.SwordBlockingConfig;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.ItemInHandRenderer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ItemUseAnimation;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
//? >=1.21.10 {
import net.minecraft.client.renderer.SubmitNodeCollector;
//? } else {
/*import net.minecraft.client.renderer.MultiBufferSource;
*///? }
@Mixin(ItemInHandRenderer.class)
public abstract class MixinItemInHandRenderer {
@Shadow
@Final
private Minecraft minecraft;
@Shadow
protected abstract void applyItemArmAttackTransform(PoseStack poseStack, HumanoidArm hand, float swingProgress);
@WrapMethod(method = "renderItem")
public void swordBlocking$hideShield(
LivingEntity entity,
ItemStack stack,
ItemDisplayContext displayContext,
PoseStack poseStack,
//? >=1.21.10 {
SubmitNodeCollector bufferSource,
//? } else {
/*MultiBufferSource bufferSource,
*///? }
int packedLight,
Operation<Void> original
) {
if (!SwordBlockingClient.shouldHideShield(entity.getMainHandItem(), entity.getOffhandItem(), stack)) {
original.call(entity, stack, displayContext, poseStack, bufferSource, packedLight);
}
}
@Redirect(method = "renderArmWithItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/AbstractClientPlayer;getUsedItemHand()Lnet/minecraft/world/InteractionHand;", ordinal = 1))
private InteractionHand swordBlocking$changeActiveHand(AbstractClientPlayer instance) {
final InteractionHand activeHand = instance.getUsedItemHand();
if (SwordBlockingClient.canEntityBlock(instance.getMainHandItem(), instance.getOffhandItem())) {
return swordBlocking$getBlockingHand(activeHand);
} else {
return activeHand;
}
}
@Redirect(method = "renderArmWithItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;getUseAnimation()Lnet/minecraft/world/item/ItemUseAnimation;"))
private ItemUseAnimation swordBlocking$changeItemAction(ItemStack stack, @Local(argsOnly = true) AbstractClientPlayer player, @Local(argsOnly = true) InteractionHand interactionHand) {
final ItemUseAnimation defaultUseAction = stack.getUseAnimation();
if (SwordBlockingClient.canEntityBlock(player.getMainHandItem(), player.getOffhandItem())) {
return swordBlocking$getBlockingHand(player.getUsedItemHand()) == interactionHand ? ItemUseAnimation.BLOCK : defaultUseAction;
} else {
return defaultUseAction;
}
}
@Inject(method = "renderArmWithItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ItemInHandRenderer;applyItemArmTransform(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/world/entity/HumanoidArm;F)V", ordinal = 3, shift = At.Shift.AFTER))
private void swordBlocking$applySwingOffset(
AbstractClientPlayer player,
float partialTicks,
float pitch,
InteractionHand hand,
float swingProgress,
ItemStack stack,
float equippedProgress,
PoseStack poseStack,
//? >=1.21.10 {
SubmitNodeCollector bufferSource,
//? } else {
/*MultiBufferSource bufferSource,
*///? }
int combinedLight,
CallbackInfo ci,
@Local HumanoidArm arm
) {
if (SwordBlockingConfig.enabled && SwordBlockingConfig.blockHitAnimation) {
this.applyItemArmAttackTransform(poseStack, arm, swingProgress);
}
}
@WrapMethod(method = "itemUsed")
private void swordBlocking$disableEquipAnimation(InteractionHand hand, Operation<Void> original) {
if (!SwordBlockingConfig.disableUseEquipAnimation || this.minecraft.player == null || !this.minecraft.player.isUsingItem()) {
original.call(hand);
}
}
@Unique
private InteractionHand swordBlocking$getBlockingHand(InteractionHand interactionHand) {
return interactionHand == InteractionHand.MAIN_HAND ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
}
}

View File

@@ -0,0 +1,70 @@
package eu.midnightdust.swordblocking.mixins;
import eu.midnightdust.swordblocking.SwordBlockingClient;
import eu.midnightdust.swordblocking.config.SwordBlockingConfig;
import net.minecraft.client.model.HumanoidModel;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ShieldItem;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
//? >=1.21.10 {
import net.minecraft.client.renderer.entity.player.AvatarRenderer;
import net.minecraft.world.entity.Avatar;
//? } else {
/*import net.minecraft.client.renderer.entity.player.PlayerRenderer;
import net.minecraft.world.entity.player.Player;
*///? }
//? fabric {
import net.fabricmc.api.Environment;
import net.fabricmc.api.EnvType;
//?}
@Mixin(
//? >=1.21.10 {
AvatarRenderer.class
//? } else {
/*PlayerRenderer.class
*///? }
)
public abstract class MixinPlayerRenderer {
//? fabric
@Environment(EnvType.CLIENT)
@Inject(
//? >=1.21.10 {
method = "getArmPose(Lnet/minecraft/world/entity/Avatar;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/InteractionHand;)Lnet/minecraft/client/model/HumanoidModel$ArmPose;",
//? } else {
/*method = "getArmPose(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/InteractionHand;)Lnet/minecraft/client/model/HumanoidModel$ArmPose;",
*///? }
at = @At(value = "RETURN"),
cancellable = true
)
private static void swordBlocking$getArmPose(
//? >=1.21.10 {
Avatar player,
//? } else {
/*Player player,
*///? }
ItemStack stack,
InteractionHand hand,
CallbackInfoReturnable<HumanoidModel.ArmPose> cir
) {
if (SwordBlockingConfig.enabled) {
final ItemStack handStack = player.getItemInHand(hand);
final ItemStack offStack = player.getItemInHand(hand.equals(InteractionHand.MAIN_HAND) ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND);
if (!SwordBlockingConfig.alwaysHideShield && (handStack.getItem() instanceof ShieldItem) && !SwordBlockingClient.canShieldSwordBlock(player.getMainHandItem(), player.getOffhandItem())) {
return;
}
if (offStack.getItem() instanceof ShieldItem && SwordBlockingClient.canEntityBlock(player.getMainHandItem(), player.getOffhandItem())) {
cir.setReturnValue(HumanoidModel.ArmPose.BLOCK);
} else if (handStack.getItem() instanceof ShieldItem && SwordBlockingConfig.hideShield && (cir.getReturnValue() == HumanoidModel.ArmPose.ITEM || cir.getReturnValue() == HumanoidModel.ArmPose.BLOCK)) {
cir.setReturnValue(HumanoidModel.ArmPose.EMPTY);
}
}
}
}

View File

@@ -0,0 +1,37 @@
modLoader = "javafml"
loaderVersion = "[1,)"
license = "${license}"
issueTrackerURL = "${issues}"
[[mods]]
modId = "${id}"
version = "${version}"
displayName = "${name}"
description = "${description}"
logoFile = "assets/${id}/icon.png"
authors = ["Motschen", "TeamMidnightDust", "lowercasebtw"]
displayURL = "${modrinth}"
[[mixins]]
config = "${id}.mixins.json"
[[dependencies.${id}]]
modId = "neoforge"
mandatory = true
versionRange = "[${neoforge_version},)"
ordering = "NONE"
side = "CLIENT"
[[dependencies.${id}]]
modId = "minecraft"
mandatory = true
versionRange = "${minecraft_version_range}"
ordering = "NONE"
side = "CLIENT"
[[dependencies.${id}]]
modId = "midnightlib"
mandatory = true
versionRange = ""
ordering = "AFTER"
side = "CLIENT"

View File

@@ -1,15 +0,0 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "minecraft:item/diamond_sword"
},
"overrides": [
{
"predicate": {
"blocking": 1
},
"model": "minecraft:item/diamond_sword_blocking"
}
]
}

View File

@@ -1,6 +0,0 @@
{
"parent": "minecraft:item/handheld_blocking",
"textures": {
"layer0": "minecraft:item/diamond_sword"
}
}

View File

@@ -1,15 +0,0 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "minecraft:item/golden_sword"
},
"overrides": [
{
"predicate": {
"blocking": 1
},
"model": "minecraft:item/golden_sword_blocking"
}
]
}

View File

@@ -1,6 +0,0 @@
{
"parent": "minecraft:item/handheld_blocking",
"textures": {
"layer0": "minecraft:item/golden_sword"
}
}

View File

@@ -1,16 +0,0 @@
{
"credit": "https://github.com/FoundationGames/Parry/blob/master/src/main/resources/assets/minecraft/models/item/handheld_parry.json",
"parent": "item/handheld",
"display": {
"firstperson_righthand": {
"rotation": [ 171, 13, 165 ],
"translation": [ -2.8, -0.2, -5 ],
"scale": [ 1, 1, 1 ]
},
"firstperson_lefthand": {
"rotation": [ 171, 13, 75 ],
"translation": [ -2.8, -0.2, -5 ],
"scale": [ 1, 1, 1 ]
}
}
}

View File

@@ -1,15 +0,0 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "minecraft:item/iron_sword"
},
"overrides": [
{
"predicate": {
"blocking": 1
},
"model": "minecraft:item/iron_sword_blocking"
}
]
}

View File

@@ -1,6 +0,0 @@
{
"parent": "minecraft:item/handheld_blocking",
"textures": {
"layer0": "minecraft:item/iron_sword"
}
}

View File

@@ -1,15 +0,0 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "minecraft:item/netherite_sword"
},
"overrides": [
{
"predicate": {
"blocking": 1
},
"model": "minecraft:item/netherite_sword_blocking"
}
]
}

View File

@@ -1,6 +0,0 @@
{
"parent": "minecraft:item/handheld_blocking",
"textures": {
"layer0": "minecraft:item/netherite_sword"
}
}

View File

@@ -1,52 +0,0 @@
{
"parent": "builtin/entity",
"gui_light": "front",
"textures": {
"particle": "block/dark_oak_planks"
},
"display": {
"thirdperson_righthand": {
"rotation": [ 0, 90, 0 ],
"translation": [ 10, 6, -4 ],
"scale": [ 0, 0, 0 ]
},
"thirdperson_lefthand": {
"rotation": [ 0, 90, 0 ],
"translation": [ 10, 6, 12 ],
"scale": [ 0, 0, 0 ]
},
"firstperson_righthand": {
"rotation": [ 0, 180, 5 ],
"translation": [ -10, 2, -10 ],
"scale": [ 0, 0, 0 ]
},
"firstperson_lefthand": {
"rotation": [ 0, 180, 5 ],
"translation": [ 10, 0, -10 ],
"scale": [ 0, 0, 0 ]
},
"gui": {
"rotation": [ 15, -25, -5 ],
"translation": [ 2, 3, 0 ],
"scale": [ 0.65, 0.65, 0.65 ]
},
"fixed": {
"rotation": [ 0, 180, 0 ],
"translation": [ -2, 4, -5],
"scale":[ 0.5, 0.5, 0.5]
},
"ground": {
"rotation": [ 0, 0, 0 ],
"translation": [ 4, 4, 2],
"scale":[ 0.25, 0.25, 0.25]
}
},
"overrides": [
{
"predicate": {
"blocking": 1
},
"model": "item/shield_blocking"
}
]
}

View File

@@ -1,34 +0,0 @@
{
"parent": "builtin/entity",
"gui_light": "front",
"textures": {
"particle": "block/dark_oak_planks"
},
"display": {
"thirdperson_righthand": {
"rotation": [ 45, 135, 0 ],
"translation": [ 3.51, 11, -2 ],
"scale": [ 0, 0, 0 ]
},
"thirdperson_lefthand": {
"rotation": [ 45, 135, 0 ],
"translation": [ 13.51, 3, 5 ],
"scale": [ 0, 0, 0 ]
},
"firstperson_righthand": {
"rotation": [ 0, 180, -5 ],
"translation": [ -15, 5, -11 ],
"scale": [ 0, 0, 0 ]
},
"firstperson_lefthand": {
"rotation": [ 0, 180, -5 ],
"translation": [ 5, 5, -11 ],
"scale": [ 0, 0, 0 ]
},
"gui": {
"rotation": [ 15, -25, -5 ],
"translation": [ 2, 3, 0 ],
"scale": [ 0.65, 0.65, 0.65 ]
}
}
}

View File

@@ -1,15 +0,0 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "minecraft:item/stone_sword"
},
"overrides": [
{
"predicate": {
"blocking": 1
},
"model": "minecraft:item/stone_sword_blocking"
}
]
}

View File

@@ -1,6 +0,0 @@
{
"parent": "minecraft:item/handheld_blocking",
"textures": {
"layer0": "minecraft:item/stone_sword"
}
}

View File

@@ -1,15 +0,0 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "minecraft:item/wooden_sword"
},
"overrides": [
{
"predicate": {
"blocking": 1
},
"model": "minecraft:item/wooden_sword_blocking"
}
]
}

View File

@@ -1,6 +0,0 @@
{
"parent": "minecraft:item/handheld_blocking",
"textures": {
"layer0": "minecraft:item/wooden_sword"
}
}

View File

@@ -0,0 +1,11 @@
{
"swordblocking.midnightconfig.title": "Sword Blocking Config",
"swordblocking.midnightconfig.enabled": "Enabled",
"swordblocking.midnightconfig.hideShield": "Hide Shield",
"swordblocking.midnightconfig.alwaysHideShield": "Always Hide Shield",
"swordblocking.midnightconfig.hideOffhandSlot": "Hide Offhand Slot",
"swordblocking.midnightconfig.hideOffhandSlot.tooltip": "Hides the offhand slot when a shield is in the offhand.",
"swordblocking.midnightconfig.disableUseEquipAnimation": "Remove the equip animation when blocking.",
"swordblocking.midnightconfig.lockBlockingArmPosition": "Disable arm moving when blocking.",
"swordblocking.midnightconfig.blockHitAnimation": "Enable block hitting animation."
}

View File

@@ -0,0 +1,11 @@
{
"swordblocking.midnightconfig.title": "Конфигурация Sword Blocking",
"swordblocking.midnightconfig.enabled": "Включено",
"swordblocking.midnightconfig.hideShield": "Спрятать щит",
"swordblocking.midnightconfig.alwaysHideShield": "Всегда прятать щит",
"swordblocking.midnightconfig.hideOffhandSlot": "Скрывать слот второй руки",
"swordblocking.midnightconfig.hideOffhandSlot.tooltip": "Скрывает слот второй руки, если в ней находится щит.",
"swordblocking.midnightconfig.disableUseEquipAnimation": "Удалять анимацию оснащения при блокировании.",
"swordblocking.midnightconfig.lockBlockingArmPosition": "Отключить движение руки при блокировании.",
"swordblocking.midnightconfig.blockHitAnimation": "Включить анимацию удара по блоку."
}

View File

@@ -1,35 +1,35 @@
{ {
"schemaVersion": 1, "schemaVersion": 1,
"id": "swordblocking", "id": "${id}",
"version": "${version}", "version": "${version}",
"name": "${name}",
"name": "Sword Blocking", "description": "${description}",
"description": "Adds sword blocking back to 1.16, you just need a shield in your offhand!", "authors": [
"authors": [ "Motschen",
"Motschen", "TeamMidnightDust",
"TeamMidnightDust" "lowercasebtw"
], ],
"contact": { "contact": {
"homepage": "https://www.midnightdust.eu/", "sources": "${source}",
"sources": "https://github.com/TeamMidnightDust/SwordBlocking", "issues": "${issues}"
"issues": "https://github.com/TeamMidnightDust/SwordBlocking/issues" },
}, "license": "${license}",
"icon": "assets/${id}/icon.png",
"license": "MIT", "environment": "client",
"icon": "assets/swordblocking/icon.png", "depends": {
"fabricloader": ">=${fabric_loader_version}",
"environment": "client", "minecraft": "${minecraft_version_range}",
"entrypoints": { "fabric-api": "*",
"client": [ "midnightlib": "*"
"eu.midnightdust.swordblocking.SwordBlockingClient" },
] "custom": {
}, "modmenu": {
"links": {
"mixins": [ "modmenu.discord": "${discord}",
"swordblocking.mixins.json" "modmenu.modrinth": "${modrinth}",
], "modmenu.curseforge": "${curseforge}"
},
"depends": { "update_checker": true
"fabric": "*" }
} }
} }

View File

@@ -1,11 +1,19 @@
{ {
"required": true, "required": true,
"package": "eu.midnightdust.swordblocking.mixin", "package": "eu.midnightdust.swordblocking.mixins",
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_17",
"client": [ "client": [
"MixinPlayerEntityRenderer" "MixinGui",
], "MixinArmedEntityRenderState",
"injectors": { "MixinHumanoidModel",
"defaultRequire": 1 "MixinItemInHandLayer",
} "MixinItemInHandRenderer",
"MixinPlayerRenderer"
],
"injectors": {
"defaultRequire": 1
},
"mixinextras": {
"minVersion": "0.5.0"
}
} }

25
stonecutter.gradle.kts Normal file
View File

@@ -0,0 +1,25 @@
import dev.kikugie.stonecutter.data.tree.struct.ProjectNode
plugins {
id("dev.kikugie.stonecutter")
alias(libs.plugins.publishing)
}
stonecutter active "1.21.10-fabric" /* [SC] DO NOT EDIT */
stonecutter tasks {
val ordering = Comparator
.comparing<ProjectNode, _> { stonecutter.parse(it.metadata.version) }
.thenComparingInt { if (it.metadata.project.endsWith("fabric")) 1 else 0 }
order("publishMods", ordering)
}
stonecutter parameters {
val loader = node.project.property("loom.platform")
constants["fabric"] = loader == "fabric"
constants["neoforge"] = loader == "neoforge"
}
tasks.named("publishMods") {
group = "build"
}

View File

@@ -0,0 +1,8 @@
loom.platform=fabric
deps.parchment_version=2025.10.12
deps.fabric_api_version=0.138.3+1.21.10
deps.modmenu_version=16.0.0-rc.1
mod.minecraft_version=1.21.10
mod.minecraft_version_range=>=1.21.9 <=1.21.10

View File

@@ -0,0 +1,7 @@
loom.platform=neoforge
deps.parchment_version=2025.10.12
deps.neoforge_version=21.10.55-beta
mod.minecraft_version=1.21.10
mod.minecraft_version_range=[1.21.9, 1.21.10]

View File

@@ -0,0 +1,8 @@
loom.platform=fabric
deps.parchment_version=2025.09.14
deps.fabric_api_version=0.136.1+1.21.8
deps.modmenu_version=15.0.0
mod.minecraft_version=1.21.8
mod.minecraft_version_range=>=1.21.6 <=1.21.8

View File

@@ -0,0 +1,7 @@
loom.platform=neoforge
deps.parchment_version=2025.09.14
deps.neoforge_version=21.8.51
mod.minecraft_version=1.21.8
mod.minecraft_version_range=[1.21.6, 1.21.7, 1.21.8]