Updated 1.21 -> 1.21.3
This commit is contained in:
parent
4d166edc20
commit
ea2e64ac00
10
README.md
10
README.md
|
|
@ -53,3 +53,13 @@
|
|||
* `LP.KeepLeashNotDropTime` - 此规则决定,当拴绳关系创建时一段时间里,即是距离已经达到了断裂距离,也保持其不断裂 [默认值: 240ticks ,可设置范围[80, 1200]ticks]
|
||||
|
||||
* `LP.DisableMoveCheck` - 此规则启用将会禁止服务器对玩家进行速度过快修正 [默认值: True]
|
||||
|
||||
Please use a paste site for large blocks of code/logs, instead of dumping it in chat or taking a screenshot.
|
||||
|
||||
Here's a list of some paste sites and their size limits:
|
||||
https://gist.github.com/: [Free] [SignUp] 100MB
|
||||
https://paste.gemwire.uk/: [Free] 10MB
|
||||
https://paste.ee/: [Free] 1MB, [SignUp] 6MB
|
||||
https://pastebin.com/: [Free] 512KB, [SignUp] [Paid] 10MB
|
||||
https://hastebin.com/: [Free] 400KB
|
||||
https://gist.github.com/: [Free] [SignUp] 100MB
|
||||
|
|
@ -3,7 +3,7 @@ plugins {
|
|||
id 'eclipse'
|
||||
id 'idea'
|
||||
id 'maven-publish'
|
||||
id 'net.neoforged.gradle.userdev' version '7.0.145'
|
||||
id 'net.neoforged.gradle.userdev' version '7.0.165'
|
||||
}
|
||||
|
||||
tasks.named('wrapper', Wrapper).configure {
|
||||
|
|
@ -25,11 +25,10 @@ repositories {
|
|||
base {
|
||||
archivesName = mod_id
|
||||
}
|
||||
|
||||
// Mojang ships Java 21 to end users starting in 1.20.5, so mods should target Java 21.
|
||||
java.toolchain.languageVersion = JavaLanguageVersion.of(21)
|
||||
|
||||
//minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||
minecraft.accessTransformers.file file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||
//minecraft.accessTransformers.entry public net.minecraft.client.Minecraft textureManager # textureManager
|
||||
|
||||
// Default run configurations.
|
||||
|
|
@ -172,4 +171,4 @@ idea {
|
|||
downloadSources = true
|
||||
downloadJavadoc = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,14 @@
|
|||
org.gradle.jvmargs=-Xmx8G
|
||||
org.gradle.daemon=false
|
||||
org.gradle.debug=false
|
||||
org.gradle.parallel=true
|
||||
org.gradle.caching=true
|
||||
org.gradle.configuration-cache=false
|
||||
|
||||
#read more on this at https://github.com/neoforged/ModDevGradle?tab=readme-ov-file#better-minecraft-parameter-names--javadoc-parchment
|
||||
# you can also find the latest versions at: https://parchmentmc.org/docs/getting-started
|
||||
parchment_minecraft_version=1.21
|
||||
parchment_mappings_version=2024.07.28
|
||||
|
||||
#read more on this at https://github.com/neoforged/NeoGradle/blob/NG_7.0/README.md#apply-parchment-mappings
|
||||
# you can also find the latest versions at: https://parchmentmc.org/docs/getting-started
|
||||
|
|
@ -10,17 +18,19 @@ neogradle.subsystems.parchment.mappingsVersion=2024.07.28
|
|||
# Environment Properties
|
||||
# You can find the latest versions here: https://projects.neoforged.net/neoforged/neoforge
|
||||
# The Minecraft version must agree with the Neo version to get a valid artifact
|
||||
minecraft_version=1.21
|
||||
minecraft_version=1.21.3
|
||||
# The Minecraft version range can use any release version of Minecraft as bounds.
|
||||
# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly
|
||||
# as they do not follow standard versioning conventions.
|
||||
minecraft_version_range=[1.21,1.22)
|
||||
minecraft_version_range=[1.21.1,1.22)
|
||||
enable_accesstransformers=true
|
||||
# The Neo version must agree with the Minecraft version to get a valid artifact
|
||||
neo_version=21.0.157
|
||||
neo_version=21.3.0-beta
|
||||
# The Neo version range can use any version of Neo as bounds
|
||||
neo_version_range=[21.0.0-beta,)
|
||||
neo_version_range=[21.1.0,)
|
||||
# The loader version range can only use the major version of FML as bounds
|
||||
loader_version_range=[4,)
|
||||
neoform_version=1.21.3-20241023.131943
|
||||
|
||||
## Mod Properties
|
||||
|
||||
|
|
@ -32,7 +42,7 @@ mod_name=Leashed Player
|
|||
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||
mod_license=MIT
|
||||
# The mod version. See https://semver.org/
|
||||
mod_version=0.0.3.9.4
|
||||
mod_version=1.21.3 0.0.3.9.4
|
||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
||||
# This should match the base package used for the mod sources.
|
||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
|
|
|
|||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -1,6 +1,6 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.9-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
|
|||
2
gradlew
vendored
2
gradlew
vendored
|
|
@ -249,4 +249,4 @@ eval "set -- $(
|
|||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
exec "$JAVACMD" "$@"
|
||||
2
gradlew.bat
vendored
2
gradlew.bat
vendored
|
|
@ -91,4 +91,4 @@ exit /b %EXIT_CODE%
|
|||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
:omega
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// 1.21 2024-10-23T13:15:06.1102778 Item Models: leashedplayer
|
||||
// 1.21.3 2024-10-27T23:14:21.0486567 Item Models: leashedplayer
|
||||
5846df9d85726428905701120ef34c9324c20faf assets/leashedplayer/models/item/bow_lra_pulling_0.json
|
||||
845a7316b86e26f88c6932d4ef2656126503727a assets/leashedplayer/models/item/bow_lra_pulling_1.json
|
||||
5bd1f9f28b91005c587f1c38fb77cd19b59495e3 assets/leashedplayer/models/item/bow_lra_pulling_2.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-10-23T13:15:06.1082841 Registries
|
||||
6f79a674215db9f9d2820b1c7f052c60ce729fee data/leashedplayer/painting_variant/group_photo.json
|
||||
// 1.21.3 2024-10-27T23:14:21.047502 Registries
|
||||
84106976f4f71012fc5bd1784303a0d135623c77 data/leashedplayer/painting_variant/group_photo.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-10-23T13:15:06.1012494 Tags for minecraft:item mod id leashedplayer
|
||||
// 1.21.3 2024-10-27T23:14:21.0349914 Tags for minecraft:item mod id leashedplayer
|
||||
36c1cccc1dfa448620c4e9cbc4a7d73986ff9e47 data/minecraft/tags/item/arrows.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-10-23T14:43:16.8619078 Languages: en_us for mod: leashedplayer
|
||||
// 1.21.3 2024-10-27T23:14:21.0486567 Languages: en_us for mod: leashedplayer
|
||||
4dc2ca922a540c7133a4a6867dfcd8bfec5a1db4 assets/leashedplayer/lang/en_us.json
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
// 1.21 2024-10-23T13:15:06.1052755 Tags for minecraft:block mod id leashedplayer
|
||||
// 1.21.3 2024-10-27T23:14:21.0429914 Tags for minecraft:block mod id leashedplayer
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-10-23T13:15:06.1052755 Tags for minecraft:painting_variant mod id leashedplayer
|
||||
// 1.21.3 2024-10-27T23:14:21.0429914 Tags for minecraft:painting_variant mod id leashedplayer
|
||||
e081a053d7c2f2d3238cf38436185ef23d234505 data/minecraft/tags/painting_variant/placeable.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-10-23T13:15:06.1042677 Languages: lzh for mod: leashedplayer
|
||||
// 1.21.3 2024-10-27T23:14:21.0429914 Languages: lzh for mod: leashedplayer
|
||||
bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f assets/leashedplayer/lang/lzh.json
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
// 1.21 2024-10-23T13:15:06.1092763 Recipes
|
||||
1b45d1ad8dc73f1787c97777ad13d9771c9e0ad1 data/leashedplayer/advancement/recipes/misc/leash_rope_arrow.json
|
||||
974d74538b3e172946f2e169036b453b6eb6bc0a data/leashedplayer/recipe/leash_rope_arrow.json
|
||||
c0e05f359296d3e28573fa1b205ac44736376622 data/minecraft/advancement/recipes/misc/spectral_leash_rope_arrow_with_glowstone_dust.json
|
||||
131fcbef603bfde7204d8e1ad15e4544696926bf data/minecraft/advancement/recipes/misc/spectral_leash_rope_arrow_with_leash_rope_arrow.json
|
||||
bb5909aa91d878c8f0ef9999881cfe89532509dd data/minecraft/recipe/spectral_leash_rope_arrow_with_glowstone_dust.json
|
||||
a1381da885fbedec01243c78afbb0a50ca803ee4 data/minecraft/recipe/spectral_leash_rope_arrow_with_leash_rope_arrow.json
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-10-23T14:43:16.860909 Languages: zh_cn for mod: leashedplayer
|
||||
// 1.21.3 2024-10-27T23:14:21.047502 Languages: zh_cn for mod: leashedplayer
|
||||
35bc6c3001138c5306d1ee9d55ef3dfbfd417e08 assets/leashedplayer/lang/zh_cn.json
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// 1.21 2024-10-23T14:19:10.2054361 Advancements
|
||||
// 1.21.3 2024-10-27T23:14:21.0497079 Advancements
|
||||
4d97adba079f1966090a52443bb439319f550680 data/leashedplayer/advancement/advancement_leash_arrow.json
|
||||
f16184b81ea35a0fbd8f2c49b085a96c32818c69 data/leashedplayer/advancement/dog_running_player.json
|
||||
bce12ed339b3b0fded263ba039f7a4e6fcfb84ca data/leashedplayer/advancement/follow_arrow.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-10-23T14:43:16.8589078 Languages: zh_tw for mod: leashedplayer
|
||||
// 1.21.3 2024-10-27T23:14:21.0467812 Languages: zh_tw for mod: leashedplayer
|
||||
c6df14a1f53a3e892ebc6b396b552ff27f1a7580 assets/leashedplayer/lang/zh_tw.json
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
{
|
||||
"asset_id": "leashedplayer:group_photo",
|
||||
"author": {
|
||||
"translate": "painting.leashedplayer.group_photo.author"
|
||||
},
|
||||
"height": 3,
|
||||
"title": {
|
||||
"translate": "painting.leashedplayer.group_photo.title"
|
||||
},
|
||||
"width": 4
|
||||
}
|
||||
|
|
@ -2,12 +2,8 @@
|
|||
"type": "minecraft:crafting_shapeless",
|
||||
"category": "misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:lead"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:arrow"
|
||||
}
|
||||
"minecraft:lead",
|
||||
"minecraft:arrow"
|
||||
],
|
||||
"result": {
|
||||
"count": 1,
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"criteria": {
|
||||
"has_glowstone_dust": {
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"items": "minecraft:glowstone_dust"
|
||||
}
|
||||
]
|
||||
},
|
||||
"trigger": "minecraft:inventory_changed"
|
||||
},
|
||||
"has_lead": {
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"items": "minecraft:lead"
|
||||
}
|
||||
]
|
||||
},
|
||||
"trigger": "minecraft:inventory_changed"
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"conditions": {
|
||||
"recipe": "minecraft:spectral_leash_rope_arrow_with_glowstone_dust"
|
||||
},
|
||||
"trigger": "minecraft:recipe_unlocked"
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"has_the_recipe",
|
||||
"has_lead",
|
||||
"has_glowstone_dust"
|
||||
]
|
||||
],
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"minecraft:spectral_leash_rope_arrow_with_glowstone_dust"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"criteria": {
|
||||
"has_lead": {
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"items": "minecraft:lead"
|
||||
}
|
||||
]
|
||||
},
|
||||
"trigger": "minecraft:inventory_changed"
|
||||
},
|
||||
"has_spectral_arrow": {
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"items": "minecraft:spectral_arrow"
|
||||
}
|
||||
]
|
||||
},
|
||||
"trigger": "minecraft:inventory_changed"
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"conditions": {
|
||||
"recipe": "minecraft:spectral_leash_rope_arrow_with_leash_rope_arrow"
|
||||
},
|
||||
"trigger": "minecraft:recipe_unlocked"
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"has_the_recipe",
|
||||
"has_lead",
|
||||
"has_spectral_arrow"
|
||||
]
|
||||
],
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"minecraft:spectral_leash_rope_arrow_with_leash_rope_arrow"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"category": "misc",
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "leashedplayer:leash_rope_arrow"
|
||||
},
|
||||
"$": {
|
||||
"item": "minecraft:glowstone_dust"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
" $ ",
|
||||
"$#$",
|
||||
" $ "
|
||||
],
|
||||
"result": {
|
||||
"count": 1,
|
||||
"id": "leashedplayer:spectral_leash_rope_arrow"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"category": "misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:lead"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:spectral_arrow"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"count": 1,
|
||||
"id": "leashedplayer:spectral_leash_rope_arrow"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,14 @@
|
|||
package com.r3944realms.leashedplayer;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.r3944realms.leashedplayer.client.renders.LeashRendererUtil;
|
||||
import com.r3944realms.leashedplayer.client.renders.entities.LeashRopeArrowRenderer;
|
||||
import com.r3944realms.leashedplayer.client.renders.entities.SpectralLeashRopeArrowRenderer;
|
||||
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import com.r3944realms.leashedplayer.content.items.type.ILeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension;
|
||||
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
|
||||
import net.minecraft.client.renderer.item.ItemProperties;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
|
@ -15,28 +19,44 @@ import net.neoforged.bus.api.SubscribeEvent;
|
|||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
|
||||
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
|
||||
import net.neoforged.neoforge.client.event.RenderPlayerEvent;
|
||||
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD, modid = LeashedPlayer.MOD_ID)
|
||||
public class ClientEventHandler {
|
||||
@SubscribeEvent
|
||||
public static void onRegisterItemProperties(FMLClientSetupEvent event) {
|
||||
event.enqueueWork(() -> {
|
||||
ItemProperties.register(Items.CROSSBOW, ResourceLocation.withDefaultNamespace("leash_rope_arrow"),
|
||||
((pStack, pLevel, pEntity, pSeed) -> {
|
||||
ChargedProjectiles chargedProjectiles = pStack.get(DataComponents.CHARGED_PROJECTILES);
|
||||
return chargedProjectiles != null && (chargedProjectiles.contains(ModItemRegister.LEASH_ROPE_ARROW.get()) || chargedProjectiles.contains(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get())) ? 1.0F : 0.0F;
|
||||
}));
|
||||
ItemProperties.register(Items.BOW, ResourceLocation.withDefaultNamespace("leash_rope_arrow_pulling"),
|
||||
((pStack, pLevel, pEntity, pSeed) ->
|
||||
(pEntity != null && pEntity.isUsingItem() && pEntity.getUseItem() == pStack && ILeashRopeArrow.isLeashRopeArrow(pStack, pEntity)) ? 1.0F: 0.0F
|
||||
));
|
||||
});
|
||||
@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.GAME, modid = LeashedPlayer.MOD_ID)
|
||||
public static class Game {
|
||||
@SubscribeEvent
|
||||
public static void onPlayerRendererEventPre(RenderPlayerEvent.Pre event) {
|
||||
PlayerRenderState renderState = event.getRenderState();
|
||||
if(((IPlayerRenderStateExtension)renderState).getPlayerLeashState() != null) {
|
||||
LeashRendererUtil.renderLeash(event.getPoseStack(), event.getMultiBufferSource(), renderState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD, modid = LeashedPlayer.MOD_ID)
|
||||
public static class Mod {
|
||||
@SubscribeEvent
|
||||
public static void onRegisterItemProperties(FMLClientSetupEvent event) {
|
||||
event.enqueueWork(() -> {
|
||||
ItemProperties.register(Items.CROSSBOW, ResourceLocation.withDefaultNamespace("leash_rope_arrow"),
|
||||
((pStack, pLevel, pEntity, pSeed) -> {
|
||||
ChargedProjectiles chargedProjectiles = pStack.get(DataComponents.CHARGED_PROJECTILES);
|
||||
return chargedProjectiles != null && (chargedProjectiles.contains(ModItemRegister.LEASH_ROPE_ARROW.get()) || chargedProjectiles.contains(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get())) ? 1.0F : 0.0F;
|
||||
}));
|
||||
ItemProperties.register(Items.BOW, ResourceLocation.withDefaultNamespace("leash_rope_arrow_pulling"),
|
||||
((pStack, pLevel, pEntity, pSeed) ->
|
||||
(pEntity != null && pEntity.isUsingItem() && pEntity.getUseItem() == pStack && ILeashRopeArrow.isLeashRopeArrow(pStack, pEntity)) ? 1.0F: 0.0F
|
||||
));
|
||||
});
|
||||
|
||||
}
|
||||
@SubscribeEvent
|
||||
public static void RegisterRenderer(EntityRenderersEvent.RegisterRenderers event) {
|
||||
event.registerEntityRenderer(ModEntityRegister.LEASH_ROPE_ARROW.get(), LeashRopeArrowRenderer::new);
|
||||
event.registerEntityRenderer(ModEntityRegister.SPECTRAL_LEASH_ROPE_ARROW.get(), SpectralLeashRopeArrowRenderer::new);
|
||||
}
|
||||
}
|
||||
@SubscribeEvent
|
||||
public static void RegisterRenderer(EntityRenderersEvent.RegisterRenderers event) {
|
||||
event.registerEntityRenderer(ModEntityRegister.LEASH_ROPE_ARROW.get(), LeashRopeArrowRenderer::new);
|
||||
event.registerEntityRenderer(ModEntityRegister.SPECTRAL_LEASH_ROPE_ARROW.get(), SpectralLeashRopeArrowRenderer::new);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,367 @@
|
|||
package com.r3944realms.leashedplayer.client.renders;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.IPlayerRendererExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.player.AbstractClientPlayer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.entity.player.PlayerRenderer;
|
||||
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.vehicle.AbstractMinecart;
|
||||
import net.minecraft.world.entity.vehicle.NewMinecartBehavior;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LightLayer;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class LeashRendererUtil {
|
||||
/**
|
||||
* <h1>1. 角度与弧度转换</h1>
|
||||
* {@snippet lang=java :
|
||||
* double d0 = (double)(pEntity.getPreciseBodyRotation(pPartialTick) * (float)(Math.PI / 180.0)) + (Math.PI / 2);
|
||||
* }
|
||||
* <ul>
|
||||
* <li><code>pEntity.getPreciseBodyRotation(pPartialTick)</code> 返回实体的旋转角度(通常是以度为单位)。/li>
|
||||
* <li> <code>(Math.PI / 180.0)</code> 是将度数转换为弧度的乘数,因为大多数三角函数(如 <code>cos</code> 和 <code>sin</code>)都需要弧度值。</li>
|
||||
* <li><code>+ (Math.PI / 2)</code> 用于将结果平移90度(四分之一圆),可能是为了校正方向或设置起始方向。 </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* <h1> 2. 三角函数计算位移</h1>
|
||||
* {@snippet lang=java :
|
||||
* double d1 = Math.cos(d0) * vec31.z + Math.sin(d0) * vec31.x;
|
||||
* double d2 = Math.sin(d0) * vec31.z - Math.cos(d0) * vec31.x;
|
||||
* }
|
||||
* <ul>
|
||||
* <li><code>d1</code> 和 <code>d2</code> 是利用三角函数 <code>cos</code> 和 <code>sin</code> 计算出来的位移量,用于确定实体相对于其旋转的实际位置。</li>
|
||||
* <li><code>Math.cos(d0) * vec31.z</code> 和 <code>Math.sin(d0) * vec31.x</code> 分别计算沿 X 和 Z 轴的位移分量,这种计算通常用于旋转一个点或向量。</li>
|
||||
* <li>两个公式结合起来用于旋转平面内的一个点 <code>(vec31.x, vec31.z)</code>,从而得到旋转后的新坐标。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 3. 线性插值 (Lerp) </h1>
|
||||
* {@snippet lang=java :
|
||||
* double d3 = Mth.lerp(pPartialTick, pEntity.xo, pEntity.getX()) + d1;
|
||||
* double d4 = Mth.lerp(pPartialTick, pEntity.yo, pEntity.getY()) + vec31.y;
|
||||
* double d5 = Mth.lerp(pPartialTick, pEntity.zo, pEntity.getZ()) + d2;
|
||||
* }
|
||||
* <ul>
|
||||
* <li><code>Mth.lerp</code> 是线性插值函数,通常用于在两个值之间平滑过渡。</li>
|
||||
* <li><code>pEntity.xo</code>, <code>pEntity.yo</code>, <code>pEntity.zo</code> 是实体在上一个刻度(tick)中的位置,而 <code>pEntity.getX()</code>, <code>pEntity.getY()</code>, <code>pEntity.getZ()</code> 是当前刻度的位置。</li>
|
||||
* <li><code>pPartialTick</code> 介于 <code>0</code> 和 <code>1</code> 之间,用来平滑过渡,使得动画更加流畅。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 4. 向量差值 </h1>
|
||||
* {@snippet lang=java :
|
||||
* float f = (float)(vec3.x - d3);
|
||||
* float f1 = (float)(vec3.y - d4);
|
||||
* float f2 = (float)(vec3.z - d5);
|
||||
* }
|
||||
* <ul>
|
||||
* <li>计算两个点(<code>vec3</code> 和 <code>(d3, d4, d5)</code>)之间的差值,得到的 <code>f</code>,<code>f1</code>,<code>f2</code> 是向量差,用于后续的渲染计算。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 5. 逆平方根与比例因子 </h1>
|
||||
* {@snippet lang=java :
|
||||
* float f4 = Mth.invSqrt(f * f + f2 * f2) * 0.025F / 2.0F;
|
||||
* }
|
||||
* <ul>
|
||||
* <li><code>Mth.invSqrt</code> 计算的是逆平方根(通常用于归一化向量或调整比例)。</li>
|
||||
* <li><code>f * f + f2 * f2</code> 是计算向量 <code>(f, f2)</code> 的平方和,用于得到其长度的平方。</li>
|
||||
* <li>乘以 <code>0.025F / 2.0F</code> 用于缩放结果,使得线条在渲染时具有合适的比例。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 6. 循环绘制 </h1>
|
||||
* {@snippet lang=java :
|
||||
* for (int i1 = 0; i1 <= 24; i1++) {
|
||||
* addVertexPair(vertexconsumer, matrix4f, f, f1, f2, i, j, k, l, 0.025F, 0.025F, f5, f6, i1, false);
|
||||
* }
|
||||
* }
|
||||
* <ul>
|
||||
* <li>循环从 <code>0</code> 到 <code>24</code>,用于创建24个顶点对,形成一个链状结构(或绳索)的外观。</li>
|
||||
* <li>每个循环迭代都会更新顶点的位置、颜色、光照等属性,使得链状结构被绘制出来。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 总结 </h1>
|
||||
* 这些数学运算主要用于计算实体在三维空间中的位置和方向,以确保在渲染链状结构(如拴住的绳索)时,链条能够跟随实体的移动和旋转并正确显示。在图形编程中,这些计算非常常见,尤其是在处理旋转、插值和光照效果时。
|
||||
*/
|
||||
|
||||
public static void renderLeash(
|
||||
com.mojang.blaze3d.vertex.PoseStack poseStack,
|
||||
net.minecraft.client.renderer.MultiBufferSource bufferSource,
|
||||
PlayerRenderState playerRenderState
|
||||
) {
|
||||
float f = 0.025F;
|
||||
// 获得绳索持有者的位置
|
||||
PlayerLeashState leashState = ((IPlayerRenderStateExtension)playerRenderState).getPlayerLeashState();
|
||||
if (leashState == null)
|
||||
return;
|
||||
Vec3 Holder = leashState.pos;
|
||||
Vec3 o = leashState.o;
|
||||
// 计算实体的朝向角度(弧度)
|
||||
float partialTick = playerRenderState.partialTick;
|
||||
double entityRotationAngleRadians = (double)(leashState.getPreciseBodyRotation(partialTick) * (float) (Math.PI / 180.0)) + (Math.PI / 2);
|
||||
// 计算实体的绳索偏移,此处add偏移让渲染拴绳显示在玩家头部下(大约在脖子处
|
||||
Vec3 cameraEntityLeashOffset = new Vec3(0.0, playerRenderState.eyeHeight , playerRenderState.boundingBoxWidth * 0.4F).add(0, 0, -0.2);
|
||||
double leashOffsetX = Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.z + Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
|
||||
double leashOffsetZ = Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.z - Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
|
||||
// 计算实体当前的实际位置
|
||||
double entityPosX = Mth.lerp(partialTick, o.x, playerRenderState.x) + leashOffsetX;
|
||||
double entityPosY = Mth.lerp(partialTick, o.y, playerRenderState.y) + cameraEntityLeashOffset.y;
|
||||
double entityPosZ = Mth.lerp(partialTick, o.z, playerRenderState.z) + leashOffsetZ;
|
||||
|
||||
// 计算绳索的相对位置差
|
||||
float deltaX = (float)(Holder.x - entityPosX);
|
||||
float deltaY = (float)(Holder.y - entityPosY);
|
||||
float deltaZ = (float)(Holder.z - entityPosZ);
|
||||
// 计算比例因子,用于调节绳索的粗细
|
||||
float leashLengthRatio = Mth.invSqrt(deltaX * deltaX + deltaZ * deltaZ) * 0.025F / 2.0F;
|
||||
// 计算比例因子,用于调节绳索的粗细
|
||||
float leashXZScaleX = deltaZ * leashLengthRatio;
|
||||
float leashXZScaleZ = deltaX * leashLengthRatio;
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(leashState.offset);
|
||||
VertexConsumer vertexconsumer = bufferSource.getBuffer(RenderType.leash());
|
||||
Matrix4f matrix4f = poseStack.last().pose();
|
||||
|
||||
for (int i = 0; i <= 24; i++) {
|
||||
addVertexPair(
|
||||
vertexconsumer,
|
||||
matrix4f,
|
||||
deltaX,
|
||||
deltaY,
|
||||
deltaZ,
|
||||
leashState.startBlockLight,
|
||||
leashState.endBlockLight,
|
||||
leashState.startSkyLight,
|
||||
leashState.endSkyLight,
|
||||
0.025F,
|
||||
0.025F,
|
||||
leashXZScaleX,
|
||||
leashXZScaleZ,
|
||||
i,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
for (int j = 24; j >= 0; j--) {
|
||||
addVertexPair(
|
||||
vertexconsumer,
|
||||
matrix4f,
|
||||
deltaX,
|
||||
deltaY,
|
||||
deltaZ,
|
||||
leashState.startBlockLight,
|
||||
leashState.endBlockLight,
|
||||
leashState.startSkyLight,
|
||||
leashState.endSkyLight,
|
||||
0.025F,
|
||||
0.0F,
|
||||
leashXZScaleX,
|
||||
leashXZScaleZ,
|
||||
j,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
protected static void addVertexPair(
|
||||
VertexConsumer buffer,
|
||||
Matrix4f pose,
|
||||
float startX,
|
||||
float startY,
|
||||
float startZ,
|
||||
int entityBlockLight,
|
||||
int holderBlockLight,
|
||||
int entitySkyLight,
|
||||
int holderSkyLight,
|
||||
float yOffset,
|
||||
float dy,
|
||||
float dx,
|
||||
float dz,
|
||||
int index,
|
||||
boolean reverse
|
||||
) {
|
||||
float f = (float)index / 24.0F;
|
||||
int i = (int)Mth.lerp(f, (float)entityBlockLight, (float)holderBlockLight);
|
||||
int j = (int)Mth.lerp(f, (float)entitySkyLight, (float)holderSkyLight);
|
||||
int k = LightTexture.pack(i, j);
|
||||
float f1 = index % 2 == (reverse ? 1 : 0) ? 0.7F : 1.0F;
|
||||
float f2 = 0.5F * f1;
|
||||
float f3 = 0.4F * f1;
|
||||
float f4 = 0.3F * f1;
|
||||
float f5 = startX * f;
|
||||
float f6 = startY > 0.0F ? startY * f * f : startY - startY * (1.0F - f) * (1.0F - f);
|
||||
float f7 = startZ * f;
|
||||
buffer.addVertex(pose, f5 - dx, f6 + dy, f7 + dz).setColor(f2, f3, f4, 1.0F).setLight(k);
|
||||
buffer.addVertex(pose, f5 + dx, f6 + yOffset - dy, f7 - dz).setColor(f2, f3, f4, 1.0F).setLight(k);
|
||||
}
|
||||
public static <E extends net.minecraft.world.entity.Entity> void renderLeashForCamera(
|
||||
Camera camera,
|
||||
float partialTick,
|
||||
com.mojang.blaze3d.vertex.PoseStack poseStack,
|
||||
net.minecraft.client.renderer.MultiBufferSource bufferSource,
|
||||
E leashHolder,
|
||||
Vec3 holderOffset
|
||||
) {
|
||||
|
||||
poseStack.pushPose();
|
||||
|
||||
// 获得绳索持有者的位置
|
||||
Vec3 leashHolderPosition = leashHolder.getRopeHoldPosition(partialTick).add(holderOffset);
|
||||
|
||||
// 获取当前观察的实体
|
||||
Entity cameraEntity = camera.getEntity();
|
||||
|
||||
// 计算实体的朝向角度(弧度)
|
||||
double entityRotationAngleRadians = (double)(cameraEntity.getPreciseBodyRotation(partialTick) * (float) (Math.PI / 180.0)) + (Math.PI / 2);
|
||||
|
||||
// 计算实体的绳索偏移,此处add偏移让渲染拴绳显示在玩家头部下(大约在脖子处
|
||||
Vec3 cameraEntityLeashOffset = cameraEntity.getLeashOffset(partialTick).add(0, -0.2, -0.5);
|
||||
double leashOffsetX = Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.z + Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
|
||||
double leashOffsetZ = Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.z - Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
|
||||
|
||||
// 计算实体当前的实际位置
|
||||
double entityPosX = Mth.lerp(partialTick, cameraEntity.xo, cameraEntity.getX()) + leashOffsetX;
|
||||
double entityPosY = Mth.lerp(partialTick, cameraEntity.yo, cameraEntity.getY()) + cameraEntityLeashOffset.y;
|
||||
double entityPosZ = Mth.lerp(partialTick, cameraEntity.zo, cameraEntity.getZ()) + leashOffsetZ;
|
||||
|
||||
// 在当前变换矩阵上应用偏移
|
||||
poseStack.translate(leashOffsetX, cameraEntityLeashOffset.y , leashOffsetZ);
|
||||
|
||||
// 计算绳索的相对位置差
|
||||
float deltaX = (float)(leashHolderPosition.x - entityPosX);
|
||||
float deltaY = (float)(leashHolderPosition.y - entityPosY);
|
||||
float deltaZ = (float)(leashHolderPosition.z - entityPosZ);
|
||||
|
||||
// 获取顶点消费者,用于绘制绳索
|
||||
VertexConsumer vertexConsumer = bufferSource.getBuffer(RenderType.leash());
|
||||
Matrix4f matrix = poseStack.last().pose();
|
||||
|
||||
// 计算比例因子,用于调节绳索的粗细
|
||||
float leashLengthRatio = Mth.invSqrt(deltaX * deltaX + deltaZ * deltaZ) * 0.025F / 2.0F;
|
||||
float leashXZScaleX = deltaZ * leashLengthRatio;
|
||||
float leashXZScaleZ = deltaX * leashLengthRatio;
|
||||
|
||||
// 获取光照信息
|
||||
BlockPos cameraEntityBlockPos = BlockPos.containing(cameraEntity.getEyePosition(partialTick));
|
||||
BlockPos leashHolderBlockPos = BlockPos.containing(leashHolder.getEyePosition(partialTick));
|
||||
int cameraEntityBlockLightLevel = 15;
|
||||
int leashHolderBlockLightLevel = 0; //getBlockLightLevel(leashHolder, leashHolderBlockPos);
|
||||
int cameraEntitySkyLightLevel = cameraEntity.level().getBrightness(LightLayer.SKY, cameraEntityBlockPos);
|
||||
int leashHolderSkyLightLevel = cameraEntity.level().getBrightness(LightLayer.SKY, leashHolderBlockPos);
|
||||
|
||||
// 绘制绳索的上半部分
|
||||
for (int segment = 0; segment <= 24; segment++) {
|
||||
addVertexPair(vertexConsumer, matrix, deltaX, deltaY, deltaZ, cameraEntityBlockLightLevel, leashHolderBlockLightLevel, cameraEntitySkyLightLevel, leashHolderSkyLightLevel, 0.025F, 0.025F, leashXZScaleX, leashXZScaleZ, segment, false);
|
||||
}
|
||||
|
||||
// 绘制绳索的下半部分
|
||||
for (int segment = 24; segment >= 0; segment--) {
|
||||
addVertexPair(vertexConsumer, matrix, deltaX, deltaY, deltaZ, cameraEntityBlockLightLevel, leashHolderBlockLightLevel, cameraEntitySkyLightLevel, leashHolderSkyLightLevel, 0.025F, 0.0F, leashXZScaleX, leashXZScaleZ, segment, true);
|
||||
}
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
public static void levelRenderLeash(ClientLevel level, Camera pCamera, PoseStack poseStack, MultiBufferSource.BufferSource multibuffersource$buffersource) {
|
||||
for(Entity entity : level.entitiesForRendering()) {
|
||||
//对于玩家实体拴绳渲染(从第一人称视角)
|
||||
if (entity instanceof AbstractClientPlayer abstractClientPlayer) {
|
||||
if(!(pCamera.getEntity() instanceof AbstractClientPlayer)) continue;
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
PlayerRenderer playerRenderer = (PlayerRenderer) mc.getEntityRenderDispatcher().getRenderer(abstractClientPlayer);
|
||||
IPlayerRendererExtension playerRendererExtension = (IPlayerRendererExtension) playerRenderer;
|
||||
if (mc.options.getCameraType().isFirstPerson()) {
|
||||
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashDataFromEntityData();
|
||||
if(leashDataFromEntityData == null) continue;
|
||||
Either<UUID, BlockPos> delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo;
|
||||
if(delayedLeashInfo != null) {
|
||||
float partialTickTime = pCamera.getPartialTickTime();
|
||||
Vec3 position = pCamera.getPosition();
|
||||
double dX = Mth.lerp(partialTickTime, abstractClientPlayer.xOld, abstractClientPlayer.getX()) - position.x;
|
||||
double dY = Mth.lerp(partialTickTime, abstractClientPlayer.yOld, abstractClientPlayer.getY()) - position.y;
|
||||
double dZ = Mth.lerp(partialTickTime, abstractClientPlayer.zOld, abstractClientPlayer.getZ()) - position.z;
|
||||
Vec3 vec3 = getRenderOffset(entity, partialTickTime);
|
||||
double dX_ = dX + vec3.x();
|
||||
double dY_ = dY + vec3.y();
|
||||
double dZ_ = dZ + vec3.z();
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(dX_, dY_, dZ_);
|
||||
if (delayedLeashInfo.right().isPresent() && delayedLeashInfo.left().isEmpty()) {
|
||||
renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, LeashFenceKnotEntity.getOrCreateKnot(level, delayedLeashInfo.right().get()), Vec3.ZERO);
|
||||
} else if (delayedLeashInfo.right().isEmpty() && delayedLeashInfo.left().isPresent()) {
|
||||
Player playerByUUID = level.getPlayerByUUID(delayedLeashInfo.left().get());
|
||||
if (playerByUUID != null) {
|
||||
renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, playerByUUID, Vec3.ZERO);
|
||||
} else {
|
||||
double MaxLeashLength = ((ILivingEntityExtension) abstractClientPlayer).getLeashLength() * LeashedPlayer.M1() * LeashedPlayer.M2();
|
||||
List<Entity> entities = level.getEntities(
|
||||
null,
|
||||
new AABB(
|
||||
abstractClientPlayer.getX() - MaxLeashLength,
|
||||
abstractClientPlayer.getY() - MaxLeashLength,
|
||||
abstractClientPlayer.getZ() - MaxLeashLength,
|
||||
abstractClientPlayer.getX() + MaxLeashLength,
|
||||
abstractClientPlayer.getY() + MaxLeashLength,
|
||||
abstractClientPlayer.getZ() + MaxLeashLength
|
||||
)
|
||||
);
|
||||
Entity holder = null;
|
||||
for (Entity entity_ : entities) {
|
||||
if(entity_.getUUID().equals(delayedLeashInfo.left().get())) {
|
||||
holder = entity_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (holder != null) {
|
||||
if(holder instanceof LeashRopeArrow) {
|
||||
renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder, new Vec3(0.,-0.09, 0));//TODO: 待擴展Vec3吗?
|
||||
}
|
||||
else renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder, Vec3.ZERO);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static Vec3 getRenderOffset(Entity entity, float partialTickTime) {
|
||||
Vec3 ret = Vec3.ZERO;
|
||||
if(entity.isPassenger()
|
||||
&& entity.getVehicle() instanceof AbstractMinecart abstractminecart
|
||||
&& abstractminecart.getBehavior() instanceof NewMinecartBehavior newminecartbehavior
|
||||
&& newminecartbehavior.cartHasPosRotLerp()
|
||||
) {
|
||||
double d2 = Mth.lerp(partialTickTime, abstractminecart.xOld, abstractminecart.getX());
|
||||
double d0 = Mth.lerp(partialTickTime, abstractminecart.yOld, abstractminecart.getY());
|
||||
double d1 = Mth.lerp(partialTickTime, abstractminecart.zOld, abstractminecart.getZ());
|
||||
ret = newminecartbehavior.getCartLerpPosition(partialTickTime).subtract(new Vec3(d2, d0, d1));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.r3944realms.leashedplayer.client.renders;
|
||||
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class PlayerLeashState {
|
||||
public Vec3 o, pos, offset;
|
||||
public float yRotO, yRot;
|
||||
public int startBlockLight;
|
||||
public int endBlockLight;
|
||||
public int startSkyLight;
|
||||
public int endSkyLight;
|
||||
|
||||
public float getPreciseBodyRotation(float pPartialTick) {
|
||||
return Mth.lerp(pPartialTick, this.yRotO, this.yRot);
|
||||
}
|
||||
|
||||
|
||||
public PlayerLeashState() {
|
||||
this.offset = Vec3.ZERO;
|
||||
this.o = Vec3.ZERO;
|
||||
this.pos = Vec3.ZERO;
|
||||
this.yRot = 0.0f;
|
||||
this.yRotO = 0.0f;
|
||||
this.startBlockLight = 0;
|
||||
this.endBlockLight = 0;
|
||||
this.startSkyLight = 15;
|
||||
this.endSkyLight = 15;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,20 +4,27 @@ import com.r3944realms.leashedplayer.LeashedPlayer;
|
|||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import net.minecraft.client.renderer.entity.ArrowRenderer;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.client.renderer.entity.state.ArrowRenderState;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class LeashRopeArrowRenderer extends ArrowRenderer<LeashRopeArrow> {
|
||||
public class LeashRopeArrowRenderer extends ArrowRenderer<LeashRopeArrow, ArrowRenderState> {
|
||||
public static final ResourceLocation LEASH_ROPE_ARROW = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/entity/projectiles/leash_rope_arrow.png");
|
||||
public LeashRopeArrowRenderer(EntityRendererProvider.Context pContext) {
|
||||
super(pContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ResourceLocation getTextureLocation(@NotNull LeashRopeArrow pEntity) {
|
||||
public @NotNull ArrowRenderState createRenderState() {
|
||||
return new ArrowRenderState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull ResourceLocation getTextureLocation(@NotNull ArrowRenderState arrowRenderState) {
|
||||
return LEASH_ROPE_ARROW;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,20 +4,28 @@ import com.r3944realms.leashedplayer.LeashedPlayer;
|
|||
import com.r3944realms.leashedplayer.content.entities.SpectralLeashRopeArrow;
|
||||
import net.minecraft.client.renderer.entity.ArrowRenderer;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.client.renderer.entity.state.ArrowRenderState;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class SpectralLeashRopeArrowRenderer extends ArrowRenderer<SpectralLeashRopeArrow> {
|
||||
public class SpectralLeashRopeArrowRenderer extends ArrowRenderer<SpectralLeashRopeArrow, ArrowRenderState> {
|
||||
public static final ResourceLocation SPECTRAL_LEASH_ROPE_ARROW = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/entity/projectiles/spectral_leash_rope_arrow.png");
|
||||
|
||||
public SpectralLeashRopeArrowRenderer(EntityRendererProvider.Context pContext) {
|
||||
super(pContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ResourceLocation getTextureLocation(@NotNull SpectralLeashRopeArrow pEntity) {
|
||||
public @NotNull ArrowRenderState createRenderState() {
|
||||
return new ArrowRenderState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull ResourceLocation getTextureLocation(@NotNull ArrowRenderState arrowRenderState) {
|
||||
return SPECTRAL_LEASH_ROPE_ARROW;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package com.r3944realms.leashedplayer.content.entities;
|
|||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
|
|
@ -17,7 +19,7 @@ public class ModEntityRegister {
|
|||
.eyeHeight(0.13F)
|
||||
.clientTrackingRange(4)
|
||||
.updateInterval(20)
|
||||
.build("leash_rope_arrow")
|
||||
.build(ResourceKey.create(Registries.ENTITY_TYPE, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "leash_rope_arrow")))
|
||||
);
|
||||
public static final DeferredHolder<EntityType<?>, EntityType<SpectralLeashRopeArrow>> SPECTRAL_LEASH_ROPE_ARROW = ENTITY_TYPE.register(
|
||||
"spectral_leash_rope_arrow",
|
||||
|
|
@ -26,7 +28,7 @@ public class ModEntityRegister {
|
|||
.eyeHeight(0.13F)
|
||||
.clientTrackingRange(4)
|
||||
.updateInterval(20)
|
||||
.build("spectral_leash_rope_arrow")
|
||||
.build(ResourceKey.create(Registries.ENTITY_TYPE, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "spectral_leash_rope_arrow")))
|
||||
);
|
||||
// public static final DeferredHolder<EntityType<?>, EntityType<ChainTieEntity>> CHAIN_TIE = ENTITY_TYPE.register(
|
||||
// "chain_tie",
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public class SpectralLeashRopeArrow extends LeashRopeArrow {
|
|||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (this.level().isClientSide && !this.inGround) {
|
||||
if (this.level().isClientSide && !this.isInGround()) {
|
||||
this.level().addParticle(ParticleTypes.INSTANT_EFFECT, this.getX(), this.getY(), this.getZ(), 0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.r3944realms.leashedplayer.content.gamerules;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.flag.FeatureFlagSet;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
|
|
@ -25,7 +27,7 @@ public enum GameruleRegistry {
|
|||
if (gameruleDataTypes.get(gameruleName) != RuleDataType.BOOLEAN) {
|
||||
return false;
|
||||
}
|
||||
return level.getGameRules().getBoolean((GameRules.Key<GameRules.BooleanValue>) gamerules.get(gameruleName));
|
||||
return ((ServerLevel)level).getGameRules().getBoolean((GameRules.Key<GameRules.BooleanValue>) gamerules.get(gameruleName));
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Integer getGameruleIntValue(Level level, String gameruleName) {
|
||||
|
|
@ -35,7 +37,7 @@ public enum GameruleRegistry {
|
|||
if (gameruleDataTypes.get(gameruleName) != RuleDataType.INTEGER) {
|
||||
return 0;
|
||||
}
|
||||
return level.getGameRules().getInt((GameRules.Key<GameRules.IntegerValue>)gamerules.get(gameruleName));
|
||||
return ((ServerLevel)level).getGameRules().getInt((GameRules.Key<GameRules.IntegerValue>)gamerules.get(gameruleName));
|
||||
}
|
||||
|
||||
public void registerGamerule(String gameruleName, GameRules.Category category, boolean pDefault) {
|
||||
|
|
@ -53,7 +55,7 @@ public enum GameruleRegistry {
|
|||
gameruleDataTypes.put(gameruleName, RuleDataType.INTEGER);
|
||||
}
|
||||
public void registerGamerule(String gameruleName, GameRules.Category category, int pDefault, int pMin, int pMax, BiConsumer<MinecraftServer, GameRules.IntegerValue> pChangeListener) {
|
||||
gamerules.put(gameruleName, GameRules.register(gameruleName, category, GameRules.IntegerValue.create(pDefault, pMin, pMax, pChangeListener)));
|
||||
gamerules.put(gameruleName, GameRules.register(gameruleName, category, GameRules.IntegerValue.create(pDefault, pMin, pMax, FeatureFlagSet.of(), pChangeListener)));
|
||||
gameruleDataTypes.put(gameruleName, RuleDataType.INTEGER);
|
||||
}
|
||||
public void registerGamerule(String gameruleName, GameRules.Category category,float value) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.mojang.brigadier.arguments.FloatArgumentType;
|
|||
import com.mojang.brigadier.context.CommandContext;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.flag.FeatureFlagSet;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
|
@ -38,7 +39,8 @@ public class Gamerules {
|
|||
(FloatArgumentType::floatArg,
|
||||
pType -> new FloatValue(pType, pDefaultValue),
|
||||
pChangeListener,
|
||||
GameRules.GameRuleTypeVisitor::visit
|
||||
GameRules.GameRuleTypeVisitor::visit,
|
||||
FeatureFlagSet.of()
|
||||
);
|
||||
}
|
||||
public static GameRules.Type<FloatValue> create(
|
||||
|
|
@ -48,7 +50,8 @@ public class Gamerules {
|
|||
() -> FloatArgumentType.floatArg(pMin, pMax),
|
||||
pType -> new FloatValue(pType, pDefaultValue),
|
||||
pChangeListener,
|
||||
GameRules.GameRuleTypeVisitor::visit
|
||||
GameRules.GameRuleTypeVisitor::visit,
|
||||
FeatureFlagSet.of()
|
||||
);
|
||||
}
|
||||
public FloatValue(GameRules.Type<FloatValue> pType, float value) {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ import com.r3944realms.leashedplayer.content.items.type.LeashRopeArrowItem;
|
|||
import com.r3944realms.leashedplayer.content.items.type.SpectralLeashRopeArrowItem;
|
||||
import com.r3944realms.leashedplayer.content.items.type.TestItem;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
|
|
@ -24,8 +27,8 @@ public class ModItemRegister {
|
|||
() -> new SpectralLeashRopeArrowItem(new Item.Properties().stacksTo(16)));
|
||||
|
||||
public static final Supplier<Item> FABRIC = ModItemRegister.register("fabric",
|
||||
() -> new TestItem(new Item.Properties().stacksTo(1))
|
||||
);
|
||||
() -> new TestItem(new Item.Properties().stacksTo(1)
|
||||
.setId(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "fabric")))));
|
||||
|
||||
public static Supplier<Item> register(String name, Supplier<Item> supplier) {
|
||||
return register(name, supplier, true);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
package com.r3944realms.leashedplayer.content.items.type;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Position;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.projectile.AbstractArrow;
|
||||
import net.minecraft.world.entity.projectile.Projectile;
|
||||
|
|
@ -22,7 +26,7 @@ import java.util.List;
|
|||
public class LeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{
|
||||
public static final String descKey = "item.leash_rope_arrow.description";
|
||||
public LeashRopeArrowItem(Item.Properties pProperties) {
|
||||
super(pProperties);
|
||||
super(pProperties.setId(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "leash_rope_arrow")))) ;
|
||||
}
|
||||
|
||||
public @NotNull AbstractArrow createArrow(@NotNull Level pLevel, @NotNull ItemStack pAmmo, @NotNull LivingEntity pShooter, @Nullable ItemStack pWeapon) {
|
||||
|
|
@ -36,7 +40,7 @@ public class LeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{
|
|||
return arrow;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public @NotNull Component getDescription() {
|
||||
return Component.translatable(descKey).withStyle(ChatFormatting.GRAY);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
package com.r3944realms.leashedplayer.content.items.type;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
|
||||
import com.r3944realms.leashedplayer.content.entities.SpectralLeashRopeArrow;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Position;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.projectile.AbstractArrow;
|
||||
import net.minecraft.world.entity.projectile.Projectile;
|
||||
|
|
@ -23,7 +27,7 @@ import java.util.List;
|
|||
public class SpectralLeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{
|
||||
public static final String descKey = "item.spectral_leash_rope_arrow.description";
|
||||
public SpectralLeashRopeArrowItem(Properties pProperties) {
|
||||
super(pProperties);
|
||||
super(pProperties.setId(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "spectral_leash_rope_arrow"))));
|
||||
}
|
||||
public @NotNull AbstractArrow createArrow(@NotNull Level pLevel, @NotNull ItemStack pAmmo, @NotNull LivingEntity pShooter, @Nullable ItemStack pWeapon) {
|
||||
return new SpectralLeashRopeArrow(ModEntityRegister.SPECTRAL_LEASH_ROPE_ARROW.get(), pShooter, pLevel, pAmmo.copyWithCount(1), pWeapon);
|
||||
|
|
@ -36,7 +40,6 @@ public class SpectralLeashRopeArrowItem extends ArrowItem implements ILeashRopeA
|
|||
return arrow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Component getDescription() {
|
||||
return Component.translatable(descKey).withStyle(ChatFormatting.GRAY);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,9 @@ import com.r3944realms.leashedplayer.client.renders.gui.IFadingProcessBarRendere
|
|||
import com.r3944realms.leashedplayer.client.renders.gui.IProcessBarRenderer;
|
||||
import com.r3944realms.leashedplayer.client.renders.gui.TestProcessBarRenderer;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResultHolder;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
|
@ -21,7 +20,7 @@ public class TestItem extends Item {
|
|||
}
|
||||
|
||||
@Override
|
||||
public @NotNull InteractionResultHolder<ItemStack> use(@NotNull Level pLevel, @NotNull Player pPlayer, @NotNull InteractionHand pUsedHand) {
|
||||
public @NotNull InteractionResult use(@NotNull Level pLevel, @NotNull Player pPlayer, @NotNull InteractionHand pUsedHand) {
|
||||
if(!pLevel.isClientSide()){
|
||||
//some lo
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,22 @@
|
|||
package com.r3944realms.leashedplayer.content.paintings;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.datagen.provider.attributes.ModPaintingVariants;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.decoration.PaintingVariant;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ModPaintingsRegister {
|
||||
public static final DeferredRegister<PaintingVariant> PAINTING_VARIANT =
|
||||
DeferredRegister.create(Registries.PAINTING_VARIANT, LeashedPlayer.MOD_ID);
|
||||
public static final Supplier<PaintingVariant> GROUP_PHOTO = PAINTING_VARIANT.register("group_photo", () -> new PaintingVariant(1920, 1080, getAssetId("group_photo")));
|
||||
public static final Supplier<PaintingVariant> GROUP_PHOTO = PAINTING_VARIANT.register("group_photo", () -> new PaintingVariant(1920, 1080, getAssetId("group_photo"), Optional.of(Component.translatable(ModPaintingVariants.getPaintingVariantTitleKey(ModPaintingVariants.GROUP_PHOTO))), Optional.of(Component.translatable(ModPaintingVariants.getPaintingVariantAuthorKey(ModPaintingVariants.GROUP_PHOTO)))));
|
||||
|
||||
private static @NotNull ResourceLocation getAssetId( String paint_name) {
|
||||
return ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/painting/"+paint_name+".png");
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.r3944realms.leashedplayer.datagen.provider.*;
|
|||
import com.r3944realms.leashedplayer.utils.Enum.LanguageEnum;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||
|
|
@ -17,7 +18,6 @@ public class ModDataGeneratorHandler {
|
|||
@SubscribeEvent
|
||||
public static void genData(GatherDataEvent event) {
|
||||
CompletableFuture<HolderLookup.Provider> holderFolder = event.getLookupProvider();
|
||||
|
||||
ExistingFileHelper existingFileHelper = event.getExistingFileHelper();
|
||||
/*Language Provider ENGLISH CHINESE(SIM/TRA)*/
|
||||
addLanguage(event, LanguageEnum.English);
|
||||
|
|
@ -44,9 +44,10 @@ public class ModDataGeneratorHandler {
|
|||
);
|
||||
}
|
||||
private static void RecipeGenerator(GatherDataEvent event, CompletableFuture<HolderLookup.Provider> future) {
|
||||
PackOutput packOutput = event.getGenerator().getPackOutput();
|
||||
event.getGenerator().addProvider(
|
||||
event.includeServer(),
|
||||
(DataProvider.Factory<ModRecipeProvider>) pOutput -> new ModRecipeProvider(pOutput, future)
|
||||
new ModRecipeProvider.Runner(packOutput, future)
|
||||
);
|
||||
}
|
||||
private static void ModTagsProvider(GatherDataEvent event, CompletableFuture<HolderLookup.Provider> completableFuture, ExistingFileHelper helper) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ import net.minecraft.advancements.Advancement;
|
|||
import net.minecraft.advancements.AdvancementHolder;
|
||||
import net.minecraft.advancements.AdvancementType;
|
||||
import net.minecraft.advancements.critereon.*;
|
||||
import net.minecraft.core.HolderGetter;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
|
|
@ -26,6 +28,7 @@ public class ModAdvancementGenerator implements AdvancementProvider.AdvancementG
|
|||
private final ResourceLocation ADV_BG = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/gui/advancements/backgrounds/leashed_player.png");
|
||||
@Override
|
||||
public void generate(HolderLookup.@NotNull Provider registries, @NotNull Consumer<AdvancementHolder> saver, @NotNull ExistingFileHelper existingFileHelper) {
|
||||
HolderGetter<EntityType<?>> holdergetter = registries.lookupOrThrow(Registries.ENTITY_TYPE);
|
||||
AdvancementHolder hasLeashRopeItem = Advancement.Builder.advancement().display(
|
||||
Items.LEAD,
|
||||
Component.translatable(ModAdvancementKey.LEASH_START.getNameKey()),
|
||||
|
|
@ -74,7 +77,7 @@ public class ModAdvancementGenerator implements AdvancementProvider.AdvancementG
|
|||
true,
|
||||
true
|
||||
).addCriterion("leash_self", LeashPlayerTrigger.TriggerInstance.LeashPlayer(
|
||||
EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(EntityType.LEASH_KNOT))
|
||||
EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(holdergetter, EntityType.LEASH_KNOT))
|
||||
))
|
||||
.parent(hasLeashRopeItem).save(saver, ModAdvancementKey.LEASHED_SELF.getNameWithNameSpace());
|
||||
AdvancementHolder followLeashRopeArrow = Advancement.Builder.advancement().display(
|
||||
|
|
@ -87,7 +90,7 @@ public class ModAdvancementGenerator implements AdvancementProvider.AdvancementG
|
|||
false,
|
||||
true
|
||||
).addCriterion("leash_arrow", LeashPlayerTrigger.TriggerInstance.LeashPlayer(
|
||||
EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(ModEntityRegister.LEASH_ROPE_ARROW.get()))
|
||||
EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(holdergetter, ModEntityRegister.LEASH_ROPE_ARROW.get()))
|
||||
))
|
||||
.parent(hasLeashRopeArrow)
|
||||
.save(saver, ModAdvancementKey.FOLLOW_LEASH_ARROW.getNameWithNameSpace());
|
||||
|
|
@ -101,7 +104,7 @@ public class ModAdvancementGenerator implements AdvancementProvider.AdvancementG
|
|||
true,
|
||||
true
|
||||
).addCriterion("leash_by_wo_do", LeashPlayerTrigger.TriggerInstance.LeashPlayer(
|
||||
EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(EntityType.WOLF))
|
||||
EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(holdergetter, EntityType.WOLF))
|
||||
))
|
||||
.parent(hasLeashRopeArrow).save(saver, ModAdvancementKey.DOG_RUNNING_PLAYER.getNameWithNameSpace());
|
||||
|
||||
|
|
@ -116,7 +119,7 @@ public class ModAdvancementGenerator implements AdvancementProvider.AdvancementG
|
|||
true
|
||||
).addCriterion("leash_other_player",
|
||||
LeashPlayerTrigger.TriggerInstance.LeashPlayer(
|
||||
EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(EntityType.PLAYER))
|
||||
EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(holdergetter, EntityType.PLAYER))
|
||||
)
|
||||
)
|
||||
.parent(hasLeashRopeItem).save(saver, ModAdvancementKey.LEASHED_FRIEND.getNameWithNameSpace());
|
||||
|
|
|
|||
|
|
@ -1,34 +1,36 @@
|
|||
package com.r3944realms.leashedplayer.datagen.provider;
|
||||
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import net.minecraft.core.HolderGetter;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.recipes.*;
|
||||
import net.minecraft.data.recipes.packs.VanillaRecipeProvider;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Items;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ModRecipeProvider extends RecipeProvider {
|
||||
public ModRecipeProvider(PackOutput pOutput, CompletableFuture<HolderLookup.Provider> future) {
|
||||
super(pOutput, future);
|
||||
public ModRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) {
|
||||
super(registries, output);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void buildRecipes(@NotNull RecipeOutput pRecipeOutput) {
|
||||
|
||||
ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, ModItemRegister.LEASH_ROPE_ARROW.get(),1)
|
||||
protected void buildRecipes() {
|
||||
this.shapeless(RecipeCategory.MISC, ModItemRegister.LEASH_ROPE_ARROW.get(), 1)
|
||||
.requires(Items.LEAD)
|
||||
.requires(Items.ARROW)
|
||||
.unlockedBy("has_lead",has(Items.LEAD))
|
||||
.save(pRecipeOutput);
|
||||
ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get(),1)
|
||||
.save(this.output);
|
||||
this.shapeless(RecipeCategory.MISC, ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get(),1)
|
||||
.requires(Items.LEAD)
|
||||
.requires(Items.SPECTRAL_ARROW)
|
||||
.unlockedBy("has_lead",has(Items.LEAD))
|
||||
.unlockedBy("has_spectral_arrow",has(Items.SPECTRAL_ARROW))
|
||||
.save(pRecipeOutput, "spectral_leash_rope_arrow_with_leash_rope_arrow");
|
||||
ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get(),1)
|
||||
.save(this.output);
|
||||
this.shaped(RecipeCategory.MISC, ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get(),1)
|
||||
.pattern(" $ ")
|
||||
.pattern("$#$")
|
||||
.pattern(" $ ")
|
||||
|
|
@ -36,7 +38,24 @@ public class ModRecipeProvider extends RecipeProvider {
|
|||
.define('$', Items.GLOWSTONE_DUST)
|
||||
.unlockedBy("has_lead",has(Items.LEAD))
|
||||
.unlockedBy("has_glowstone_dust",has(Items.GLOWSTONE_DUST))
|
||||
.save(pRecipeOutput,"spectral_leash_rope_arrow_with_glowstone_dust");
|
||||
.save(this.output,"2");
|
||||
}
|
||||
public static class Runner extends RecipeProvider.Runner {
|
||||
|
||||
public Runner(PackOutput pPackOutput, CompletableFuture<HolderLookup.Provider> providerCompletableFuture) {
|
||||
super(pPackOutput, providerCompletableFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public RecipeProvider createRecipeProvider(HolderLookup.@NotNull Provider provider, @NotNull RecipeOutput output) {
|
||||
return new ModRecipeProvider(provider, output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return "LeashedPlayer Recipes";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@ package com.r3944realms.leashedplayer.datagen.provider.attributes;
|
|||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.data.worldgen.BootstrapContext;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.decoration.PaintingVariant;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class ModPaintingVariants {
|
||||
public static final ResourceKey<PaintingVariant> GROUP_PHOTO = create("group_photo");
|
||||
|
||||
|
|
@ -14,10 +17,10 @@ public class ModPaintingVariants {
|
|||
PaintingVariantBootstrap(pContext);
|
||||
}
|
||||
public static void PaintingVariantBootstrap(BootstrapContext<PaintingVariant> pContext) {
|
||||
ModPaintingVariants.register(pContext, ModPaintingVariants.GROUP_PHOTO, 4, 3);
|
||||
ModPaintingVariants.register(pContext, ModPaintingVariants.GROUP_PHOTO, 4, 3, Component.translatable(ModPaintingVariants.getPaintingVariantTitleKey(ModPaintingVariants.GROUP_PHOTO)), Component.translatable(ModPaintingVariants.getPaintingVariantAuthorKey(ModPaintingVariants.GROUP_PHOTO)));
|
||||
}
|
||||
private static void register(BootstrapContext<PaintingVariant> pContext, ResourceKey<PaintingVariant> pKey, int pWidth, int pHeight) {
|
||||
pContext.register(pKey, new PaintingVariant(pWidth, pHeight, pKey.location()));
|
||||
private static void register(BootstrapContext<PaintingVariant> pContext, ResourceKey<PaintingVariant> pKey, int pWidth, int pHeight, Component title, Component author) {
|
||||
pContext.register(pKey, new PaintingVariant(pWidth, pHeight, pKey.location(), Optional.of(title), Optional.of(author)));
|
||||
}
|
||||
private static ResourceKey<PaintingVariant> create(String pName) {
|
||||
return ResourceKey.create(Registries.PAINTING_VARIANT, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, pName));
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package com.r3944realms.leashedplayer.mixin.both;
|
||||
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
|
@ -12,6 +14,8 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||
public abstract class MixinEntity {
|
||||
@Shadow public abstract void igniteForSeconds(float pSeconds);
|
||||
|
||||
@Shadow public abstract Level level();
|
||||
|
||||
/**
|
||||
* 这里重定向,当实体类实现了{@link PlayerLeashable}接口时,<br/>
|
||||
* 阻止原版的{@link Leashable}中 的tickLeash方法调用,将其<br/>
|
||||
|
|
@ -21,11 +25,11 @@ public abstract class MixinEntity {
|
|||
*/
|
||||
@Redirect(
|
||||
method = "baseTick",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Leashable;tickLeash(Lnet/minecraft/world/entity/Entity;)V")
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Leashable;tickLeash(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/Entity;)V")
|
||||
)
|
||||
<E extends Entity & Leashable> void checkAndCancelIfTure(E entity) {
|
||||
if(!(entity instanceof PlayerLeashable)) {
|
||||
Leashable.tickLeash(entity);
|
||||
<E extends Entity & Leashable> void checkAndCancelIfTure(ServerLevel f, E entity) {
|
||||
if(!(entity instanceof PlayerLeashable) && level() instanceof ServerLevel serverLevel_) {
|
||||
Leashable.tickLeash(serverLevel_, entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
package com.r3944realms.leashedplayer.mixin.client;
|
||||
|
||||
import net.minecraft.client.player.AbstractClientPlayer;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(EntityRenderer.class)
|
||||
public abstract class MixinEntityRenderer {
|
||||
|
||||
@Redirect(
|
||||
method = {"renderLeash"},
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/entity/Entity;getLeashOffset(F)Lnet/minecraft/world/phys/Vec3;"
|
||||
)
|
||||
)
|
||||
private @NotNull Vec3 ret(Entity instance, float pPartialTick) {
|
||||
if(instance instanceof AbstractClientPlayer) {
|
||||
//为了使拴绳在在第三视角下位于玩家脖子处
|
||||
return instance.getLeashOffset(pPartialTick).add(0, -0.2, -0.2);//TODO:待擴展Vec3
|
||||
}
|
||||
return instance.getLeashOffset(pPartialTick);//非实现这个接口则不变
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.r3944realms.leashedplayer.mixin.client;
|
||||
|
||||
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
|
|
@ -34,6 +35,8 @@ import javax.annotation.Nullable;
|
|||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.r3944realms.leashedplayer.client.renders.LeashRendererUtil.levelRenderLeash;
|
||||
|
||||
@Mixin(LevelRenderer.class)
|
||||
public abstract class MixinLevelRenderer {
|
||||
@Shadow
|
||||
|
|
@ -49,82 +52,15 @@ public abstract class MixinLevelRenderer {
|
|||
|
||||
@Inject(
|
||||
method = {"renderLevel"},
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/renderer/RenderBuffers;bufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;",
|
||||
shift = At.Shift.AFTER
|
||||
)
|
||||
at = @At(value = "HEAD")
|
||||
)
|
||||
private void renderLevel(DeltaTracker pDeltaTracker, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pFrustumMatrix, Matrix4f pProjectionMatrix, CallbackInfo ci) {
|
||||
private void renderLevel(GraphicsResourceAllocator pGraphicsResourceAllocator, DeltaTracker pDeltaTracker, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pFrustumMatrix, Matrix4f pProjectionMatrix, CallbackInfo ci) {
|
||||
assert this.level != null;
|
||||
PoseStack poseStack = new PoseStack();
|
||||
MultiBufferSource.BufferSource multibuffersource$buffersource = this.renderBuffers.bufferSource();
|
||||
for(Entity entity : this.level.entitiesForRendering()) {
|
||||
//对于玩家实体拴绳渲染(从第一人称视角)
|
||||
if (entity instanceof AbstractClientPlayer abstractClientPlayer) {
|
||||
if(!(pCamera.getEntity() instanceof AbstractClientPlayer)) continue;
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
PlayerRenderer playerRenderer = (PlayerRenderer) mc.getEntityRenderDispatcher().getRenderer(abstractClientPlayer);
|
||||
IPlayerRendererExtension playerRendererExtension = (IPlayerRendererExtension) playerRenderer;
|
||||
if (mc.options.getCameraType().isFirstPerson()) {
|
||||
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashDataFromEntityData();
|
||||
if(leashDataFromEntityData == null) continue;
|
||||
Either<UUID, BlockPos> delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo;
|
||||
if(delayedLeashInfo != null) {
|
||||
float partialTickTime = pCamera.getPartialTickTime();
|
||||
Vec3 position = pCamera.getPosition();
|
||||
double dX = Mth.lerp(partialTickTime, abstractClientPlayer.xOld, abstractClientPlayer.getX()) - position.x;
|
||||
double dY = Mth.lerp(partialTickTime, abstractClientPlayer.yOld, abstractClientPlayer.getY()) - position.y;
|
||||
double dZ = Mth.lerp(partialTickTime, abstractClientPlayer.zOld, abstractClientPlayer.getZ()) - position.z;
|
||||
Vec3 vec3 = playerRenderer.getRenderOffset(abstractClientPlayer, partialTickTime);
|
||||
double dX_ = dX + vec3.x();
|
||||
double dY_ = dY + vec3.y();
|
||||
double dZ_ = dZ + vec3.z();
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(dX_, dY_, dZ_);
|
||||
ClientLevel level = mc.level;
|
||||
if (delayedLeashInfo.right().isPresent() && delayedLeashInfo.left().isEmpty()) {
|
||||
assert level != null;
|
||||
playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, LeashFenceKnotEntity.getOrCreateKnot(level, delayedLeashInfo.right().get()));
|
||||
} else if (delayedLeashInfo.right().isEmpty() && delayedLeashInfo.left().isPresent()) {
|
||||
assert level != null;
|
||||
|
||||
Player playerByUUID = level.getPlayerByUUID(delayedLeashInfo.left().get());
|
||||
if (playerByUUID != null) {
|
||||
playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, playerByUUID);
|
||||
} else {
|
||||
double MaxLeashLength = ((ILivingEntityExtension) abstractClientPlayer).getLeashLength() * LeashedPlayer.M1() * LeashedPlayer.M2();
|
||||
List<Entity> entities = level.getEntities(
|
||||
null,
|
||||
new AABB(
|
||||
abstractClientPlayer.getX() - MaxLeashLength,
|
||||
abstractClientPlayer.getY() - MaxLeashLength,
|
||||
abstractClientPlayer.getZ() - MaxLeashLength,
|
||||
abstractClientPlayer.getX() + MaxLeashLength,
|
||||
abstractClientPlayer.getY() + MaxLeashLength,
|
||||
abstractClientPlayer.getZ() + MaxLeashLength
|
||||
)
|
||||
);
|
||||
Entity holder = null;
|
||||
for (Entity entity_ : entities) {
|
||||
if(entity_.getUUID().equals(delayedLeashInfo.left().get())) {
|
||||
holder = entity_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (holder != null) {
|
||||
if(holder instanceof LeashRopeArrow) {
|
||||
playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder, new Vec3(0.,-0.09, 0));//TODO: 待擴展Vec3吗?
|
||||
}
|
||||
else playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
levelRenderLeash(level, pCamera, poseStack, multibuffersource$buffersource);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package com.r3944realms.leashedplayer.mixin.client;
|
||||
|
||||
import com.r3944realms.leashedplayer.client.renders.PlayerLeashState;
|
||||
import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
@SuppressWarnings({"AddedMixinMembersNamePattern"})
|
||||
@Mixin(PlayerRenderState.class)
|
||||
public class MixinPlayerRenderState implements IPlayerRenderStateExtension {
|
||||
@Unique
|
||||
@Nullable
|
||||
private PlayerLeashState playerLeashState;
|
||||
|
||||
@Override
|
||||
public @Nullable PlayerLeashState getPlayerLeashState() {
|
||||
return playerLeashState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayerLeashState(@Nullable PlayerLeashState playerRenderState) {
|
||||
this.playerLeashState = playerRenderState;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,8 +4,10 @@ import com.mojang.blaze3d.vertex.PoseStack;
|
|||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.client.renders.PlayerLeashState;
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.IPlayerRendererExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import net.minecraft.client.Camera;
|
||||
|
|
@ -18,6 +20,8 @@ import net.minecraft.client.renderer.RenderType;
|
|||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
|
||||
import net.minecraft.client.renderer.entity.player.PlayerRenderer;
|
||||
import net.minecraft.client.renderer.entity.state.EntityRenderState;
|
||||
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
|
@ -38,238 +42,66 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
|
||||
@Mixin(PlayerRenderer.class)
|
||||
public abstract class MixinPlayerRenderer extends LivingEntityRenderer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>> implements IPlayerRendererExtension {
|
||||
public MixinPlayerRenderer(EntityRendererProvider.Context pContext, PlayerModel<AbstractClientPlayer> pModel, float pShadowRadius) {
|
||||
public abstract class MixinPlayerRenderer extends LivingEntityRenderer<AbstractClientPlayer, PlayerRenderState, PlayerModel> implements IPlayerRendererExtension {
|
||||
public MixinPlayerRenderer(EntityRendererProvider.Context pContext, PlayerModel pModel, float pShadowRadius) {
|
||||
super(pContext, pModel, pShadowRadius);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
at = @At("HEAD"),
|
||||
method = "render(Lnet/minecraft/client/player/AbstractClientPlayer;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V"
|
||||
)
|
||||
private void renderMixin(AbstractClientPlayer pEntity, float pEntityYaw, float pPartialTicks, PoseStack pPoseStack, MultiBufferSource pBuffer, int pPackedLight, CallbackInfo ci) {
|
||||
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) pEntity).getLeashDataFromEntityData();
|
||||
if(leashDataFromEntityData == null) return;
|
||||
Either<UUID, BlockPos> delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo;
|
||||
if(delayedLeashInfo != null) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
ClientLevel level = mc.level;
|
||||
if (delayedLeashInfo.right().isPresent() && delayedLeashInfo.left().isEmpty()) {
|
||||
assert level != null;
|
||||
renderLeash(pEntity, pPartialTicks, pPoseStack, pBuffer, LeashFenceKnotEntity.getOrCreateKnot(level, delayedLeashInfo.right().get()));
|
||||
} else if (delayedLeashInfo.right().isEmpty() && delayedLeashInfo.left().isPresent()) {
|
||||
assert level != null;
|
||||
Player playerByUUID = level.getPlayerByUUID(delayedLeashInfo.left().get());
|
||||
if (playerByUUID != null) {
|
||||
renderLeash(pEntity, pPartialTicks, pPoseStack, pBuffer, playerByUUID);
|
||||
} else {
|
||||
double breakDistanceTime = (leashDataFromEntityData.leashHolder instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1();
|
||||
double MaxLeashLength = ((ILivingEntityExtension) pEntity).getLeashLength() * breakDistanceTime;
|
||||
List<Entity> entities = level.getEntities(
|
||||
null,
|
||||
new AABB(
|
||||
pEntity.getX() - MaxLeashLength,
|
||||
pEntity.getY() - MaxLeashLength,
|
||||
pEntity.getZ() - MaxLeashLength,
|
||||
pEntity.getX() + MaxLeashLength,
|
||||
pEntity.getY() + MaxLeashLength,
|
||||
pEntity.getZ() + MaxLeashLength
|
||||
)
|
||||
);
|
||||
Entity holder = null;
|
||||
for (Entity entity_ : entities) {
|
||||
if(entity_.getUUID().equals(delayedLeashInfo.left().get())) {
|
||||
holder = entity_;
|
||||
break;
|
||||
@Inject(method = {"extractRenderState(Lnet/minecraft/client/player/AbstractClientPlayer;Lnet/minecraft/client/renderer/entity/state/PlayerRenderState;F)V"}, at = @At("TAIL"))
|
||||
public void extractRenderState(AbstractClientPlayer abstractClientPlayer, PlayerRenderState playerRenderState, float partTicks, CallbackInfo ci) {
|
||||
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashDataFromEntityData();
|
||||
IPlayerRenderStateExtension iPlayerRenderStateExtension = (IPlayerRenderStateExtension) playerRenderState;
|
||||
if(leashDataFromEntityData != null) {
|
||||
Either<UUID, BlockPos> delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo;
|
||||
PlayerLeashState playerLeashState = new PlayerLeashState();
|
||||
if (delayedLeashInfo != null) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
ClientLevel level = mc.level;
|
||||
if (delayedLeashInfo.right().isPresent() && delayedLeashInfo.left().isEmpty()) {
|
||||
assert level != null;
|
||||
playerLeashState.pos = delayedLeashInfo.right().get().getCenter().add(0.0, abstractClientPlayer.getEyeHeight() *0.7, 0);
|
||||
} else if (delayedLeashInfo.right().isEmpty() && delayedLeashInfo.left().isPresent()) {
|
||||
assert level != null;
|
||||
Player playerByUUID = level.getPlayerByUUID(delayedLeashInfo.left().get());
|
||||
if (playerByUUID != null) {
|
||||
playerLeashState.pos = playerByUUID.position().add(0.0, abstractClientPlayer.getEyeHeight() *0.7, 0);
|
||||
} else {
|
||||
double breakDistanceTime = (leashDataFromEntityData.leashHolder instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1();
|
||||
double MaxLeashLength = ((ILivingEntityExtension) abstractClientPlayer).getLeashLength() * breakDistanceTime;
|
||||
List<Entity> entities = level.getEntities(
|
||||
null,
|
||||
new AABB(
|
||||
abstractClientPlayer.getX() - MaxLeashLength,
|
||||
abstractClientPlayer.getY() - MaxLeashLength,
|
||||
abstractClientPlayer.getZ() - MaxLeashLength,
|
||||
abstractClientPlayer.getX() + MaxLeashLength,
|
||||
abstractClientPlayer.getY() + MaxLeashLength,
|
||||
abstractClientPlayer.getZ() + MaxLeashLength
|
||||
)
|
||||
);
|
||||
Entity holder = null;
|
||||
for (Entity entity_ : entities) {
|
||||
if (entity_.getUUID().equals(delayedLeashInfo.left().get())) {
|
||||
holder = entity_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (holder != null) {
|
||||
if(holder instanceof LeashRopeArrow) {
|
||||
renderLeash(pEntity, pPartialTicks, pPoseStack, pBuffer, holder, new Vec3(0,0, 0));//TODO: 待擴展Vec3
|
||||
if (holder != null) {
|
||||
if (holder instanceof LeashRopeArrow) {
|
||||
playerLeashState.pos = holder.position().add(0.0, abstractClientPlayer.getEyeHeight() *0.7, 0);//TODO: 待擴展Vec3
|
||||
} else playerLeashState.pos = holder.position().add(0.0, abstractClientPlayer.getEyeHeight() *0.7, 0);
|
||||
}
|
||||
else renderLeash(pEntity, pPartialTicks, pPoseStack, pBuffer, holder);
|
||||
}
|
||||
}
|
||||
playerLeashState.o = new Vec3(abstractClientPlayer.xo, abstractClientPlayer.yo, abstractClientPlayer.zo);
|
||||
Entity leashHolder = leashDataFromEntityData.leashHolder;
|
||||
playerLeashState.yRotO = abstractClientPlayer.yRotO;
|
||||
playerLeashState.yRot = abstractClientPlayer.getYRot();
|
||||
iPlayerRenderStateExtension.setPlayerLeashState(playerLeashState);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <h1>1. 角度与弧度转换</h1>
|
||||
* {@snippet lang=java :
|
||||
* double d0 = (double)(pEntity.getPreciseBodyRotation(pPartialTick) * (float)(Math.PI / 180.0)) + (Math.PI / 2);
|
||||
* }
|
||||
* <ul>
|
||||
* <li><code>pEntity.getPreciseBodyRotation(pPartialTick)</code> 返回实体的旋转角度(通常是以度为单位)。/li>
|
||||
* <li> <code>(Math.PI / 180.0)</code> 是将度数转换为弧度的乘数,因为大多数三角函数(如 <code>cos</code> 和 <code>sin</code>)都需要弧度值。</li>
|
||||
* <li><code>+ (Math.PI / 2)</code> 用于将结果平移90度(四分之一圆),可能是为了校正方向或设置起始方向。 </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* <h1> 2. 三角函数计算位移</h1>
|
||||
* {@snippet lang=java :
|
||||
* double d1 = Math.cos(d0) * vec31.z + Math.sin(d0) * vec31.x;
|
||||
* double d2 = Math.sin(d0) * vec31.z - Math.cos(d0) * vec31.x;
|
||||
* }
|
||||
* <ul>
|
||||
* <li><code>d1</code> 和 <code>d2</code> 是利用三角函数 <code>cos</code> 和 <code>sin</code> 计算出来的位移量,用于确定实体相对于其旋转的实际位置。</li>
|
||||
* <li><code>Math.cos(d0) * vec31.z</code> 和 <code>Math.sin(d0) * vec31.x</code> 分别计算沿 X 和 Z 轴的位移分量,这种计算通常用于旋转一个点或向量。</li>
|
||||
* <li>两个公式结合起来用于旋转平面内的一个点 <code>(vec31.x, vec31.z)</code>,从而得到旋转后的新坐标。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 3. 线性插值 (Lerp) </h1>
|
||||
* {@snippet lang=java :
|
||||
* double d3 = Mth.lerp(pPartialTick, pEntity.xo, pEntity.getX()) + d1;
|
||||
* double d4 = Mth.lerp(pPartialTick, pEntity.yo, pEntity.getY()) + vec31.y;
|
||||
* double d5 = Mth.lerp(pPartialTick, pEntity.zo, pEntity.getZ()) + d2;
|
||||
* }
|
||||
* <ul>
|
||||
* <li><code>Mth.lerp</code> 是线性插值函数,通常用于在两个值之间平滑过渡。</li>
|
||||
* <li><code>pEntity.xo</code>, <code>pEntity.yo</code>, <code>pEntity.zo</code> 是实体在上一个刻度(tick)中的位置,而 <code>pEntity.getX()</code>, <code>pEntity.getY()</code>, <code>pEntity.getZ()</code> 是当前刻度的位置。</li>
|
||||
* <li><code>pPartialTick</code> 介于 <code>0</code> 和 <code>1</code> 之间,用来平滑过渡,使得动画更加流畅。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 4. 向量差值 </h1>
|
||||
* {@snippet lang=java :
|
||||
* float f = (float)(vec3.x - d3);
|
||||
* float f1 = (float)(vec3.y - d4);
|
||||
* float f2 = (float)(vec3.z - d5);
|
||||
* }
|
||||
* <ul>
|
||||
* <li>计算两个点(<code>vec3</code> 和 <code>(d3, d4, d5)</code>)之间的差值,得到的 <code>f</code>,<code>f1</code>,<code>f2</code> 是向量差,用于后续的渲染计算。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 5. 逆平方根与比例因子 </h1>
|
||||
* {@snippet lang=java :
|
||||
* float f4 = Mth.invSqrt(f * f + f2 * f2) * 0.025F / 2.0F;
|
||||
* }
|
||||
* <ul>
|
||||
* <li><code>Mth.invSqrt</code> 计算的是逆平方根(通常用于归一化向量或调整比例)。</li>
|
||||
* <li><code>f * f + f2 * f2</code> 是计算向量 <code>(f, f2)</code> 的平方和,用于得到其长度的平方。</li>
|
||||
* <li>乘以 <code>0.025F / 2.0F</code> 用于缩放结果,使得线条在渲染时具有合适的比例。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 6. 循环绘制 </h1>
|
||||
* {@snippet lang=java :
|
||||
* for (int i1 = 0; i1 <= 24; i1++) {
|
||||
* addVertexPair(vertexconsumer, matrix4f, f, f1, f2, i, j, k, l, 0.025F, 0.025F, f5, f6, i1, false);
|
||||
* }
|
||||
* }
|
||||
* <ul>
|
||||
* <li>循环从 <code>0</code> 到 <code>24</code>,用于创建24个顶点对,形成一个链状结构(或绳索)的外观。</li>
|
||||
* <li>每个循环迭代都会更新顶点的位置、颜色、光照等属性,使得链状结构被绘制出来。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 总结 </h1>
|
||||
* 这些数学运算主要用于计算实体在三维空间中的位置和方向,以确保在渲染链状结构(如拴住的绳索)时,链条能够跟随实体的移动和旋转并正确显示。在图形编程中,这些计算非常常见,尤其是在处理旋转、插值和光照效果时。
|
||||
*/
|
||||
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Unique
|
||||
public <E extends net.minecraft.world.entity.Entity> void renderLeashForCamera(
|
||||
Camera camera,
|
||||
float partialTick,
|
||||
com.mojang.blaze3d.vertex.PoseStack poseStack,
|
||||
net.minecraft.client.renderer.MultiBufferSource bufferSource,
|
||||
E leashHolder,
|
||||
Vec3 holderOffset
|
||||
) {
|
||||
|
||||
poseStack.pushPose();
|
||||
|
||||
// 获得绳索持有者的位置
|
||||
Vec3 leashHolderPosition = leashHolder.getRopeHoldPosition(partialTick).add(holderOffset);
|
||||
|
||||
// 获取当前观察的实体
|
||||
Entity cameraEntity = camera.getEntity();
|
||||
|
||||
// 计算实体的朝向角度(弧度)
|
||||
double entityRotationAngleRadians = (double)(cameraEntity.getPreciseBodyRotation(partialTick) * (float) (Math.PI / 180.0)) + (Math.PI / 2);
|
||||
|
||||
// 计算实体的绳索偏移,此处add偏移让渲染拴绳显示在玩家头部下(大约在脖子处
|
||||
Vec3 cameraEntityLeashOffset = cameraEntity.getLeashOffset(partialTick).add(0, -0.2, -0.5);
|
||||
double leashOffsetX = Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.z + Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
|
||||
double leashOffsetZ = Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.z - Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
|
||||
|
||||
// 计算实体当前的实际位置
|
||||
double entityPosX = Mth.lerp(partialTick, cameraEntity.xo, cameraEntity.getX()) + leashOffsetX;
|
||||
double entityPosY = Mth.lerp(partialTick, cameraEntity.yo, cameraEntity.getY()) + cameraEntityLeashOffset.y;
|
||||
double entityPosZ = Mth.lerp(partialTick, cameraEntity.zo, cameraEntity.getZ()) + leashOffsetZ;
|
||||
|
||||
// 在当前变换矩阵上应用偏移
|
||||
poseStack.translate(leashOffsetX, cameraEntityLeashOffset.y , leashOffsetZ);
|
||||
|
||||
// 计算绳索的相对位置差
|
||||
float deltaX = (float)(leashHolderPosition.x - entityPosX);
|
||||
float deltaY = (float)(leashHolderPosition.y - entityPosY);
|
||||
float deltaZ = (float)(leashHolderPosition.z - entityPosZ);
|
||||
|
||||
// 获取顶点消费者,用于绘制绳索
|
||||
VertexConsumer vertexConsumer = bufferSource.getBuffer(RenderType.leash());
|
||||
Matrix4f matrix = poseStack.last().pose();
|
||||
|
||||
// 计算比例因子,用于调节绳索的粗细
|
||||
float leashLengthRatio = Mth.invSqrt(deltaX * deltaX + deltaZ * deltaZ) * 0.025F / 2.0F;
|
||||
float leashXZScaleX = deltaZ * leashLengthRatio;
|
||||
float leashXZScaleZ = deltaX * leashLengthRatio;
|
||||
|
||||
// 获取光照信息
|
||||
BlockPos cameraEntityBlockPos = BlockPos.containing(cameraEntity.getEyePosition(partialTick));
|
||||
BlockPos leashHolderBlockPos = BlockPos.containing(leashHolder.getEyePosition(partialTick));
|
||||
int cameraEntityBlockLightLevel = this.getBlockLightLevel((AbstractClientPlayer) cameraEntity, cameraEntityBlockPos);
|
||||
int leashHolderBlockLightLevel = 0; //getBlockLightLevel(leashHolder, leashHolderBlockPos);
|
||||
int cameraEntitySkyLightLevel = cameraEntity.level().getBrightness(LightLayer.SKY, cameraEntityBlockPos);
|
||||
int leashHolderSkyLightLevel = cameraEntity.level().getBrightness(LightLayer.SKY, leashHolderBlockPos);
|
||||
|
||||
// 绘制绳索的上半部分
|
||||
for (int segment = 0; segment <= 24; segment++) {
|
||||
addVertexPair(vertexConsumer, matrix, deltaX, deltaY, deltaZ, cameraEntityBlockLightLevel, leashHolderBlockLightLevel, cameraEntitySkyLightLevel, leashHolderSkyLightLevel, 0.025F, 0.025F, leashXZScaleX, leashXZScaleZ, segment, false);
|
||||
} else {
|
||||
iPlayerRenderStateExtension.setPlayerLeashState(null);
|
||||
}
|
||||
|
||||
// 绘制绳索的下半部分
|
||||
for (int segment = 24; segment >= 0; segment--) {
|
||||
addVertexPair(vertexConsumer, matrix, deltaX, deltaY, deltaZ, cameraEntityBlockLightLevel, leashHolderBlockLightLevel, cameraEntitySkyLightLevel, leashHolderSkyLightLevel, 0.025F, 0.0F, leashXZScaleX, leashXZScaleZ, segment, true);
|
||||
}
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Unique
|
||||
protected <E extends Entity> void renderLeash(AbstractClientPlayer pEntity, float pPartialTick, PoseStack pPoseStack, MultiBufferSource pBufferSource, E pLeashHolder, Vec3 holderOffset) {
|
||||
pPoseStack.pushPose();
|
||||
Vec3 vec3 = pLeashHolder.getRopeHoldPosition(pPartialTick).add(holderOffset);
|
||||
double d0 = (double)(pEntity.getPreciseBodyRotation(pPartialTick) * (float) (Math.PI / 180.0)) + (Math.PI / 2);
|
||||
Vec3 vec31 = pEntity.getLeashOffset(pPartialTick).add(0, -0.2, -0.2);//TODO:待擴展Vec3);
|
||||
double d1 = Math.cos(d0) * vec31.z + Math.sin(d0) * vec31.x;
|
||||
double d2 = Math.sin(d0) * vec31.z - Math.cos(d0) * vec31.x;
|
||||
double d3 = Mth.lerp(pPartialTick, pEntity.xo, pEntity.getX()) + d1;
|
||||
double d4 = Mth.lerp(pPartialTick, pEntity.yo, pEntity.getY()) + vec31.y;
|
||||
double d5 = Mth.lerp(pPartialTick, pEntity.zo, pEntity.getZ()) + d2;
|
||||
pPoseStack.translate(d1, vec31.y, d2);
|
||||
float f = (float)(vec3.x - d3);
|
||||
float f1 = (float)(vec3.y - d4);
|
||||
float f2 = (float)(vec3.z - d5);
|
||||
float f3 = 0.025F;
|
||||
VertexConsumer vertexconsumer = pBufferSource.getBuffer(RenderType.leash());
|
||||
Matrix4f matrix4f = pPoseStack.last().pose();
|
||||
float f4 = Mth.invSqrt(f * f + f2 * f2) * 0.025F / 2.0F;
|
||||
float f5 = f2 * f4;
|
||||
float f6 = f * f4;
|
||||
BlockPos blockpos = BlockPos.containing(pEntity.getEyePosition(pPartialTick));
|
||||
BlockPos blockpos1 = BlockPos.containing(pLeashHolder.getEyePosition(pPartialTick));
|
||||
int i = this.getBlockLightLevel(pEntity, blockpos);
|
||||
int j = 0;
|
||||
int k = pEntity.level().getBrightness(LightLayer.SKY, blockpos);
|
||||
int l = pEntity.level().getBrightness(LightLayer.SKY, blockpos1);
|
||||
|
||||
for (int i1 = 0; i1 <= 24; i1++) {
|
||||
addVertexPair(vertexconsumer, matrix4f, f, f1, f2, i, j, k, l, 0.025F, 0.025F, f5, f6, i1, false);
|
||||
}
|
||||
|
||||
for (int j1 = 24; j1 >= 0; j1--) {
|
||||
addVertexPair(vertexconsumer, matrix4f, f, f1, f2, i, j, k, l, 0.025F, 0.0F, f5, f6, j1, true);
|
||||
}
|
||||
|
||||
pPoseStack.popPose();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,7 +7,9 @@ import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
|||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.RelativeMovement;
|
||||
import net.minecraft.world.entity.PositionMoveRotation;
|
||||
import net.minecraft.world.entity.Relative;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
|
@ -26,8 +28,8 @@ public class MixinServerGamePacketListenerImpl {
|
|||
public ServerPlayer player;
|
||||
@Unique
|
||||
private List<Entity> Pl$LeashPlayers = new ArrayList<>();
|
||||
@Inject(method = {"teleport(DDDFFLjava/util/Set;)V"}, at = {@At("HEAD")})
|
||||
private void teleportHead(double pX, double pY, double pZ, float pYaw, float pPitch, Set<RelativeMovement> pRelativeSet, CallbackInfo ci) {
|
||||
@Inject(method = {"teleport(Lnet/minecraft/world/entity/PositionMoveRotation;Ljava/util/Set;)V"}, at = {@At("HEAD")})
|
||||
private void teleportHead(PositionMoveRotation positionMoveRotation, Set<Relative> pRelativeSet, CallbackInfo ci) {
|
||||
try {
|
||||
//獲取Holder
|
||||
this.Pl$LeashPlayers = ((PlayerLeashable)this.player).getLeashHolder() != null ? Collections.emptyList() : Objects.requireNonNull(this.player.getServer()).getPlayerList().getPlayers().stream().filter(serverPlayer -> (serverPlayer instanceof PlayerLeashable) && ((PlayerLeashable)serverPlayer).getLeashHolder() == this.player && player != serverPlayer).collect(Collectors.toList());
|
||||
|
|
@ -35,17 +37,18 @@ public class MixinServerGamePacketListenerImpl {
|
|||
logger.error("Internal Error:",e);
|
||||
}
|
||||
}
|
||||
@Inject(method = {"teleport(DDDFFLjava/util/Set;)V"}, at = {@At("TAIL")})
|
||||
private void teleportTail(double pX, double pY, double pZ, float pYaw, float pPitch, Set<RelativeMovement> pRelativeSet, CallbackInfo ci) {
|
||||
@Inject(method = {"teleport(Lnet/minecraft/world/entity/PositionMoveRotation;Ljava/util/Set;)V"}, at = {@At("TAIL")})
|
||||
private void teleportTail(PositionMoveRotation moveRotation, Set<Relative> pRelativeSet, CallbackInfo ci) {
|
||||
if(GameruleRegistry.getGameruleBoolValue(this.player.serverLevel(), TeleportWithLeashedPlayers.ID)) {
|
||||
for (Entity Pl$LeashPlayer : this.Pl$LeashPlayers) {
|
||||
if(Pl$LeashPlayer instanceof ServerPlayer) {
|
||||
if(Pl$LeashPlayer instanceof PlayerLeashable playerLeashable) {
|
||||
playerLeashable.dropLeash(false,false);
|
||||
if(((ServerPlayer) playerLeashable).serverLevel() == this.player.serverLevel()) {
|
||||
((ServerPlayer) playerLeashable).connection.teleport(pX, pY, pZ, pYaw, pPitch, pRelativeSet);
|
||||
((ServerPlayer) playerLeashable).connection.teleport(moveRotation, pRelativeSet);
|
||||
} else {
|
||||
((ServerPlayer) playerLeashable).teleportTo(this.player.serverLevel(), pX, pY, pZ, pYaw, pPitch);
|
||||
Vec3 vec3 = moveRotation.deltaMovement();
|
||||
((ServerPlayer) playerLeashable).teleportTo(this.player.serverLevel(), vec3.x, vec3.y, vec3.z, pRelativeSet, moveRotation.yRot(), moveRotation.yRot(),false);
|
||||
((ServerPlayer) playerLeashable).stopRiding();
|
||||
}
|
||||
playerLeashable.setLeashedTo(this.player, true);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
package com.r3944realms.leashedplayer.modInterface;
|
||||
|
||||
import com.r3944realms.leashedplayer.client.renders.PlayerLeashState;
|
||||
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
|
||||
|
||||
public interface IPlayerRenderStateExtension {
|
||||
PlayerLeashState getPlayerLeashState();
|
||||
void setPlayerLeashState(PlayerLeashState playerRenderState);
|
||||
}
|
||||
|
|
@ -5,9 +5,9 @@ protected net.minecraft.client.renderer.entity.EntityRenderer renderLeash(Lnet/m
|
|||
#priavte ->protected
|
||||
protected net.minecraft.client.renderer.entity.EntityRenderer addVertexPair(Lcom/mojang/blaze3d/vertex/VertexConsumer;Lorg/joml/Matrix4f;FFFIIIIFFFFIZ)V # addVertexPair
|
||||
#这个方法原包为package-priavet 有时需要限制范围故修改
|
||||
public net.minecraft.world.level.GameRules$IntegerValue create(IIILjava/util/function/BiConsumer;)Lnet/minecraft/world/level/GameRules$Type; # create
|
||||
public net.minecraft.world.level.GameRules$IntegerValue create(IIILnet/minecraft/world/flag/FeatureFlagSet;Ljava/util/function/BiConsumer;)Lnet/minecraft/world/level/GameRules$Type; # create
|
||||
#因为'net.minecraft.world.level.GameRules.Type' 中<init>不为 public。无法从外部软件包访问
|
||||
public net.minecraft.world.level.GameRules$Type <init>(Ljava/util/function/Supplier;Ljava/util/function/Function;Ljava/util/function/BiConsumer;Lnet/minecraft/world/level/GameRules$VisitorCaller;)V # Type
|
||||
public net.minecraft.world.level.GameRules$Type <init>(Ljava/util/function/Supplier;Ljava/util/function/Function;Ljava/util/function/BiConsumer;Lnet/minecraft/world/level/GameRules$VisitorCaller;Lnet/minecraft/world/flag/FeatureFlagSet;)V # Type
|
||||
#因为'net.minecraft.world.level.GameRules.VisitorCaller' 在 'net.minecraft.world.level.GameRules' 中不为 public。无法从外部软件包访问
|
||||
public net.minecraft.world.level.GameRules$VisitorCaller #Interface
|
||||
#private -> public
|
||||
|
|
@ -18,4 +18,4 @@ protected net.minecraft.world.entity.projectile.AbstractArrow life # life
|
|||
public net.minecraft.world.effect.MobEffect <init>(Lnet/minecraft/world/effect/MobEffectCategory;I)V # MobEffect
|
||||
#private -> protected
|
||||
protected net.minecraft.world.entity.projectile.Projectile cachedOwner # cachedOwner
|
||||
protected net.minecraft.world.entity.projectile.Projectile ownerUUID # ownerUUID
|
||||
protected net.minecraft.world.entity.projectile.Projectile ownerUUID # ownerUUID
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@
|
|||
"server.MixinServerGamePacketListenerImpl"
|
||||
],
|
||||
"client": [
|
||||
"client.MixinEntityRenderer",
|
||||
"client.MixinLevelRenderer",
|
||||
"client.MixinPlayerRenderer"
|
||||
"client.MixinPlayerRenderer",
|
||||
"client.MixinPlayerRenderState"
|
||||
],
|
||||
"refmap": "whimsicality.refmap.json",
|
||||
"required": true,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user