Compare commits

...

48 Commits

Author SHA1 Message Date
Tschipp
de388366ca Updated Version 2025-12-31 09:57:34 +01:00
Tschipp
b66040bf03 Fixed wrong Packet ID for Carry Data Sync on Forge, Proper handling of carried player dying 2025-12-29 23:27:04 +01:00
Tschipp
47910dbf61 Added possibility for scripts to override certain pickup checks. Closes #853 2025-12-29 23:23:28 +01:00
Tschipp
f147e801cc Updated to 1.21.11 2025-12-27 23:25:58 +01:00
Tschipp
20a40c1487
Update issue templates 2025-12-27 23:00:46 +01:00
Tschipp
08bc465d82 Fixed bugs, updated Blacklist 2025-12-26 15:56:13 +01:00
Tschipp
3352c497e2 Merge branch 'CatsSomeCat-1.21.8' into 1.21.9 2025-12-25 16:30:41 +01:00
Tschipp
f58829ea21 Merge branch '1.21.8' of github.com:CatsSomeCat/CarryOn into CatsSomeCat-1.21.8
# Conflicts:
#	Common/src/main/java/tschipp/carryon/common/carry/PlacementHandler.java
#	Fabric/src/main/java/tschipp/carryon/CarryOnFabricMod.java
#	Fabric/src/main/java/tschipp/carryon/events/CommonEvents.java
#	gradle.properties
2025-12-25 16:29:06 +01:00
Tschipp
550940b4ab Fixed Sync Issue after Respawning #850 #845 #843 2025-12-25 14:19:05 +01:00
Tschipp
4ca8a885da Cleaned up fork code, restored carry transformations 2025-12-24 22:29:30 +01:00
Tschipp
326880d40b Merge branch 'Hanro50-1.21.9' into 1.21.9 2025-12-23 11:53:20 +01:00
Tschipp
d4e0b29a06 Merge branch '1.21.9' of github.com:Hanro50/CarryOn into Hanro50-1.21.9
# Conflicts:
#	Common/src/main/java/tschipp/carryon/CarryOnCommon.java
#	Common/src/main/java/tschipp/carryon/CarryOnCommonClient.java
#	Common/src/main/java/tschipp/carryon/client/keybinds/ConflictFreeKeyMapping.java
#	Common/src/main/java/tschipp/carryon/client/render/CarriedObjectRender.java
#	Common/src/main/java/tschipp/carryon/mixin/AvatarRenderStateMixin.java
#	Common/src/main/java/tschipp/carryon/mixin/HumanoidModelMixin.java
#	Common/src/main/resources/carryon.mixins.json
#	Fabric/build.gradle
#	build.gradle
#	gradle.properties
2025-12-23 11:51:53 +01:00
Tschipp
8d8e0dad82 Initial work on 1.21.9 2025-11-23 20:40:31 +01:00
Hanro50
e1e122ae9b Fixed crash with mannequin 2025-10-25 09:53:14 +02:00
Hanro50
69eb806228 code cleanup 2025-10-25 09:05:48 +02:00
Hanro50
08b2a41043 Fixed 3rd person rendering 2025-10-24 22:27:31 +02:00
Hanro50
6f0c20077a Update CommonEvents.java 2025-10-22 19:42:01 +02:00
Hanro50
21f09b2526 Update CommonEvents.java 2025-10-22 19:37:26 +02:00
Hanro50
9a484df16e Fixed bugs related to picking up players
- Fixed slowness getting stuck when the other player dismounted with shift
- Fixed bug where player couldn't press shift to dismount
- Fixed being unable to place other player back down
2025-10-16 07:50:31 +02:00
Hanro50
e79e52cf65 Update PickupHandler.java 2025-10-15 22:03:53 +02:00
Hanro50
d35cb4ed72 Bug fixes
- Ports fabric disconnect fix to neoforge
- Fixes console error when trying to pickup non owned tamable mobs.
2025-10-15 22:03:28 +02:00
Hanro50
5cf2e87fe8 Update CarryOnFabricMod.java 2025-10-15 21:52:23 +02:00
Hanro50
ef8362e728 Update CarryOnFabricMod.java 2025-10-15 21:51:52 +02:00
Hanro50
e3be9c84da Revert "confusing "and" and for an "or""
This reverts commit efdd3277cc.
2025-10-15 21:18:32 +02:00
Hanro50
efdd3277cc confusing "and" and for an "or" 2025-10-15 19:23:41 +02:00
Hanro50
776d079be0 forge fix 2025-10-15 09:47:48 +02:00
Hanro50
9d6ffc37ca Fixes kick on death on neoforge 2025-10-15 09:11:08 +02:00
Hanro50
af25f681be fixes the kick on respawn bug 2025-10-15 08:27:25 +02:00
Hanro50
98247bceb2 Update ClientEvents.java 2025-10-15 08:18:23 +02:00
Hanro50
41b518942d Update CarryOnRenderType.java 2025-10-15 08:16:00 +02:00
Hanro50
32db7222b7 Swear I did fix this 2025-10-15 08:07:18 +02:00
Hanro50
eadfba05e8 some mild work on porting to 1.21.9 2025-10-15 07:51:47 +02:00
ElysianCat
00c0c89858 Bump to 2.7.1: fix slot selection and AttachmentType crash
- Fixed slot selection conflict with Sounds mod that caused rapid sound spam.
- Resolved crash-on-death bug triggered by AttachmentType handling.
- Improved Carry On slot change logic for stability and compatibility.
- Updated project version from 2.7.0 → 2.7.1.
2025-09-23 23:50:26 +03:30
ElysianCat
59ecfa81e5 Merge branch 'fix/crash-on-death-1.21.8' into 1.21.8 2025-09-23 23:45:10 +03:30
ElysianCat
c4346a4c00 Refactor CarryOn functionality to improve slot selection logic. Ensure that inventory slot changes are only allowed when not carrying an item. 2025-09-23 23:43:03 +03:30
ElysianCat
3fddd1112b Add ClientboundSyncCarryDataPacket for syncing carry data and enhance carry handling on player death
- Introduced ClientboundSyncCarryDataPacket to manage carry data synchronization between server and client.
- Updated PlacementHandler to handle carry data transfer during player death scenarios, considering keepInventory game rule.
- Refactored carry data handling in CommonEvents to ensure proper transfer and clearing of carry data on player respawn.
- Registered the new packet in CarryOnCommon for clientbound communication.
2025-09-23 23:32:49 +03:30
Tschipp
ece3ed7ff2 Updated to 1.21.8. Changed Data Storage to use Attachments or Capabilities. 2025-09-01 10:18:25 +02:00
Tschipp
162fc1051d Updated to 1.21.7 2025-08-25 10:49:14 +02:00
Tschipp
e7bf9a4dee Updated to 1.21.6 2025-08-16 22:02:28 +02:00
Tschipp
7f6e41e36a Blacklisted expanded Storage 2025-07-26 09:20:45 +02:00
Texaliuz
d9d25ab598 Translation into Argentine Spanish (es_ar) for CarryOn
Hello, I would appreciate if you could add the translation to my language (es_ar) for version 1.21.1 please and thank you.
2025-07-26 00:44:24 +02:00
inceon
9b2103137f Added uk_ua.json for Ukrainian localization 2025-07-26 00:44:14 +02:00
Bayi
7fc80adfe0 Add lang **hu_hu** 2025-07-26 00:44:02 +02:00
Tschipp
c662995320 Updated Version Numbers 2025-07-26 00:39:54 +02:00
Tschipp
0dec5bb175 Fixed various Bugs 2025-07-26 00:39:32 +02:00
Tschipp
1194370405 Updated Configs 2025-07-26 00:37:35 +02:00
Tschipp
45a2b32c97 Fixed Player Carrying, closes #774 2025-07-22 23:48:52 +02:00
Tschipp
d1227d3d87 Updated to 1.21.5 2025-07-08 10:51:36 +02:00
109 changed files with 1688 additions and 1369 deletions

View File

@ -0,0 +1,22 @@
---
name: Blacklist Request
about: Have a block / entity that shouldn't be picked up by Carry On? Report it here.
title: "[Blacklist]"
labels: Blacklist
assignees: ''
---
**Describe the problem**
What block / entity is causing issues? What problems occur with placement / pickup?
**ID's to Blacklist**
List of block identifiers (namespace:name) to blacklist. You can find identifiers by activating F3 and moving your crosshair over the block
-
-
...
**Game Information (please complete the following information):**
- Minecraft Version:
- Mod Loader:
- Carry On Version:

28
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,28 @@
---
name: Bug report
about: Create a report about a crash or otherwise buggy behavior
title: "[Bug]"
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1.
2.
...
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Game Information (please complete the following information):**
- Minecraft Version:
- Mod Loader:
- Carry On Version:
**Additional context, logs**
Add any other context about the problem here. Also include logs if available

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for Carry On
title: "[Feature Request]"
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

3
.gitignore vendored
View File

@ -22,3 +22,6 @@ build
eclipse eclipse
run run
runs runs
# vscode
.vscode/*

View File

@ -1,58 +1,51 @@
plugins { plugins {
id 'idea' id 'multiloader-common'
id 'java' id 'net.neoforged.moddev'
id 'maven-publish'
id 'org.spongepowered.gradle.vanilla' version '0.2.1-SNAPSHOT'
}
base {
archivesName = "${mod_id}-common-${minecraft_version}"
}
minecraft {
version(minecraft_version)
if(file("src/main/resources/${mod_id}.accesswidener").exists()){
accessWideners(file("src/main/resources/${mod_id}.accesswidener"))
}
} }
repositories { repositories {
maven {
name = "Shedaniel"
url "https://maven.shedaniel.me/"
}
maven { url 'https://jitpack.io' } maven { url 'https://jitpack.io' }
} }
neoForge {
neoFormVersion = neo_form_version
// Automatically enable AccessTransformers if the file exists
def at = file('src/main/resources/META-INF/accesstransformer.cfg')
if (at.exists()) {
accessTransformers.from(at.absolutePath)
}
parchment {
minecraftVersion = parchment_game_version
mappingsVersion = parchment_version
}
}
dependencies { dependencies {
compileOnly group:'org.spongepowered', name:'mixin', version:'0.8.5' compileOnly group: 'org.spongepowered', name: 'mixin', version: '0.8.5'
implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1' // fabric and neoforge both bundle mixinextras, so it is safe to use it in common
implementation("io.github.llamalad7:mixinextras-common:${mixinextras_version}") implementation("io.github.llamalad7:mixinextras-common:${mixinextras_version}")
annotationProcessor("io.github.llamalad7:mixinextras-common:${mixinextras_version}") annotationProcessor("io.github.llamalad7:mixinextras-common:${mixinextras_version}")
compileOnly("me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}") compileOnly("me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}")
} }
processResources { configurations {
commonJava {
def buildProps = project.properties.clone() canBeResolved = false
canBeConsumed = true
filesMatching(['pack.mcmeta']) { }
commonResources {
expand buildProps canBeResolved = false
canBeConsumed = true
} }
} }
publishing { artifacts {
publications { commonJava sourceSets.main.java.sourceDirectories.singleFile
mavenJava(MavenPublication) { commonResources sourceSets.main.resources.sourceDirectories.singleFile
groupId project.group
artifactId base.archivesName .get()
version project.version
from components.java
}
}
repositories {
maven {
url "file://" + System.getenv("local_maven")
}
}
} }

View File

@ -26,10 +26,7 @@ import net.minecraft.core.HolderLookup;
import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistryAccess;
import net.minecraft.core.RegistrySetBuilder; import net.minecraft.core.RegistrySetBuilder;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
@ -40,6 +37,7 @@ import tschipp.carryon.common.carry.CarryOnDataManager;
import tschipp.carryon.common.carry.PlacementHandler; import tschipp.carryon.common.carry.PlacementHandler;
import tschipp.carryon.common.command.CommandCarryOn; import tschipp.carryon.common.command.CommandCarryOn;
import tschipp.carryon.config.ConfigLoader; import tschipp.carryon.config.ConfigLoader;
import tschipp.carryon.networking.clientbound.ClientboundStartRidingOtherPlayerPacket;
import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket; import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket;
import tschipp.carryon.networking.clientbound.ClientboundSyncScriptsPacket; import tschipp.carryon.networking.clientbound.ClientboundSyncScriptsPacket;
import tschipp.carryon.networking.serverbound.ServerboundCarryKeyPressedPacket; import tschipp.carryon.networking.serverbound.ServerboundCarryKeyPressedPacket;
@ -83,6 +81,14 @@ public class CarryOnCommon
ClientboundSyncScriptsPacket::handle, ClientboundSyncScriptsPacket::handle,
args args
); );
Services.PLATFORM.registerClientboundPacket(
ClientboundStartRidingOtherPlayerPacket.TYPE,
ClientboundStartRidingOtherPlayerPacket.class,
ClientboundStartRidingOtherPlayerPacket.CODEC,
ClientboundStartRidingOtherPlayerPacket::handle,
args
);
} }
public static void registerConfig() public static void registerConfig()
@ -102,20 +108,19 @@ public class CarryOnCommon
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
if(carry.isCarrying()) if(carry.isCarrying())
{ {
// Dumb Fix to sync Carry Data after a respawn with KeepInventory, because we can't sync in the first tick.
if(player.tickCount == 1)
CarryOnDataManager.setCarryData(player, carry);
if(carry.getActiveScript().isPresent()) if(carry.getActiveScript().isPresent())
{ {
String cmd = carry.getActiveScript().get().scriptEffects().commandLoop(); String cmd = carry.getActiveScript().get().scriptEffects().commandLoop();
if(!cmd.isEmpty()) if(!cmd.isEmpty())
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd); player.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
} }
if (!Constants.COMMON_CONFIG.settings.slownessInCreative && player.isCreative())
return;
player.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 1, potionLevel(carry, player.level()), false, false));
Inventory inv = player.getInventory(); Inventory inv = player.getInventory();
inv.selected = carry.getSelected(); inv.setSelectedSlot(carry.getSelected());
} }
} }
@ -149,7 +154,7 @@ public class CarryOnCommon
public static void onPlayerAttacked(Player player) public static void onPlayerAttacked(Player player)
{ {
if (Constants.COMMON_CONFIG.settings.dropCarriedWhenHit && !player.level().isClientSide) if (Constants.COMMON_CONFIG.settings.dropCarriedWhenHit && !player.level().isClientSide())
{ {
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (carry.isCarrying()) if (carry.isCarrying())
@ -160,8 +165,18 @@ public class CarryOnCommon
} }
} }
public static void onRiderDisconnected(Player rider)
{
if(rider.getVehicle() instanceof ServerPlayer vehicle) {
CarryOnData data = CarryOnDataManager.getCarryData(vehicle);
if(data.isCarrying(CarryType.PLAYER)) {
PlacementHandler.placeCarried(vehicle);
}
}
}
private static int potionLevel(CarryOnData carry, Level level)
public static int potionLevel(CarryOnData carry, Level level)
{ {
if(carry.isCarrying(CarryType.PLAYER)) if(carry.isCarrying(CarryType.PLAYER))
return 1; return 1;

View File

@ -34,11 +34,11 @@ public class CarryOnCommonClient
Player player = mc.player; Player player = mc.player;
if(player != null) { if(player != null) {
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
if ((CarryOnKeybinds.carryKey.isUnbound() ? player.isShiftKeyDown() : (CarryOnKeybinds.carryKey.isDown() || checkMouse())) && !carry.isKeyPressed()) { if ((CarryOnKeybinds.carryKey.isUnbound() ? player.isShiftKeyDown() : (CarryOnKeybinds.carryKey.isDown())) && !carry.isKeyPressed()) {
CarryOnKeybinds.onCarryKey(true); CarryOnKeybinds.onCarryKey(true);
carry.setKeyPressed(true); carry.setKeyPressed(true);
CarryOnDataManager.setCarryData(player, carry); CarryOnDataManager.setCarryData(player, carry);
} else if (!(CarryOnKeybinds.carryKey.isUnbound() ? player.isShiftKeyDown() : (CarryOnKeybinds.carryKey.isDown() || checkMouse()) ) && carry.isKeyPressed()) { } else if (!(CarryOnKeybinds.carryKey.isUnbound() ? player.isShiftKeyDown() : (CarryOnKeybinds.carryKey.isDown() ) ) && carry.isKeyPressed()) {
CarryOnKeybinds.onCarryKey(false); CarryOnKeybinds.onCarryKey(false);
carry.setKeyPressed(false); carry.setKeyPressed(false);
CarryOnDataManager.setCarryData(player, carry); CarryOnDataManager.setCarryData(player, carry);
@ -46,20 +46,16 @@ public class CarryOnCommonClient
} }
} }
private static boolean checkMouse()
{
Minecraft mc = Minecraft.getInstance();
return (CarryOnKeybinds.carryKey.matchesMouse(0) && mc.mouseHandler.isLeftPressed()) || (CarryOnKeybinds.carryKey.matchesMouse(1) && mc.mouseHandler.isRightPressed()) || (CarryOnKeybinds.carryKey.matchesMouse(3) && mc.mouseHandler.isMiddlePressed());
}
public static void onCarryClientTick() public static void onCarryClientTick() {
{
Player player = Minecraft.getInstance().player; Player player = Minecraft.getInstance().player;
if(player != null) { if (player != null) {
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
if(carry.isCarrying()) if (carry.isCarrying()) {
{ int wantedSlot = carry.getSelected();
player.getInventory().selected = carry.getSelected(); if (player.getInventory().getSelectedSlot() != wantedSlot) {
player.getInventory().setSelectedSlot(wantedSlot);
}
} }
} }
} }
@ -68,4 +64,4 @@ public class CarryOnCommonClient
{ {
return Minecraft.getInstance().player; return Minecraft.getInstance().player;
} }
} }

View File

@ -20,7 +20,7 @@
package tschipp.carryon; package tschipp.carryon;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import tschipp.carryon.common.config.CarryConfig; import tschipp.carryon.common.config.CarryConfig;
@ -34,8 +34,10 @@ public class Constants {
public static final CarryConfig.Common COMMON_CONFIG = new CarryConfig.Common(); public static final CarryConfig.Common COMMON_CONFIG = new CarryConfig.Common();
public static final CarryConfig.Client CLIENT_CONFIG = new CarryConfig.Client(); public static final CarryConfig.Client CLIENT_CONFIG = new CarryConfig.Client();
public static final ResourceLocation PACKET_ID_KEY_PRESSED = ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "key_pressed"); public static final Identifier PACKET_ID_KEY_PRESSED = Identifier.fromNamespaceAndPath(Constants.MOD_ID, "key_pressed");
public static final ResourceLocation PACKET_ID_START_RIDING = ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "start_riding"); public static final Identifier PACKET_ID_START_RIDING = Identifier.fromNamespaceAndPath(Constants.MOD_ID, "start_riding");
public static final ResourceLocation PACKET_ID_SYNC_SCRIPTS = ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "sync_scripts"); public static final Identifier PACKET_ID_SYNC_SCRIPTS = Identifier.fromNamespaceAndPath(Constants.MOD_ID, "sync_scripts");
public static final Identifier PACKET_ID_START_RIDING_OTHER = Identifier.fromNamespaceAndPath(Constants.MOD_ID, "start_riding_other");
public static final Identifier PACKET_ID_SYNC_CARRY_ON_DATA = Identifier.fromNamespaceAndPath(Constants.MOD_ID, "sync_carry_data");
} }

View File

@ -22,6 +22,8 @@ package tschipp.carryon.client.keybinds;
import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.client.KeyMapping; import net.minecraft.client.KeyMapping;
import net.minecraft.client.KeyMapping.Category;
import net.minecraft.resources.Identifier;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.networking.serverbound.ServerboundCarryKeyPressedPacket; import tschipp.carryon.networking.serverbound.ServerboundCarryKeyPressedPacket;
import tschipp.carryon.platform.Services; import tschipp.carryon.platform.Services;
@ -34,10 +36,9 @@ public class CarryOnKeybinds
public static void registerKeybinds(Consumer<KeyMapping> registrar) public static void registerKeybinds(Consumer<KeyMapping> registrar)
{ {
if(Services.PLATFORM.isModLoaded("amecsapi")) Category category = Category.register(Identifier.fromNamespaceAndPath(Constants.MOD_ID,"key.carry.category"));
carryKey = new ConflictFreeKeyMapping("key.carry.desc", InputConstants.KEY_LSHIFT, "key.carry.category");
else carryKey = new KeyMapping("key.carry.desc", InputConstants.KEY_LSHIFT, category);
carryKey = new ConflictFreeKeyMapping("key.carry.desc", Services.PLATFORM.getPlatformName().equals("Forge") ? InputConstants.KEY_LSHIFT : InputConstants.UNKNOWN.getValue(), "key.carry.category");
registrar.accept(carryKey); registrar.accept(carryKey);
} }

View File

@ -1,43 +0,0 @@
/*
* GNU Lesser General Public License v3
* Copyright (C) 2024 Tschipp
* mrtschipp@gmail.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package tschipp.carryon.client.keybinds;
import com.mojang.blaze3d.platform.InputConstants.Type;
import net.minecraft.client.KeyMapping;
public class ConflictFreeKeyMapping extends KeyMapping
{
public ConflictFreeKeyMapping(String $$0, int $$1, String $$2)
{
super($$0, $$1, $$2);
}
public ConflictFreeKeyMapping(String $$0, Type $$1, int $$2, String $$3)
{
super($$0, $$1, $$2, $$3);
}
@Override
public boolean same(KeyMapping $$0)
{
return false;
}
}

View File

@ -23,7 +23,6 @@ package tschipp.carryon.client.modeloverride;
import com.mojang.brigadier.StringReader; import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.datafixers.util.Either; import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult; import com.mojang.serialization.DataResult;
import net.minecraft.commands.arguments.blocks.BlockStateParser; import net.minecraft.commands.arguments.blocks.BlockStateParser;
import net.minecraft.commands.arguments.blocks.BlockStateParser.BlockResult; import net.minecraft.commands.arguments.blocks.BlockStateParser.BlockResult;
@ -40,22 +39,13 @@ import tschipp.carryon.common.scripting.Matchables.NBTCondition;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Map; import java.util.Map;
public class ModelOverride public class ModelOverride {
{
//public static Codec<ModelOverride> CODEC = Codec.STRING.comapFlatMap(ModelOverride::of, override -> override.raw);
private String raw;
private BlockResult parsedBlock; private BlockResult parsedBlock;
private Type type;
private Either<ItemResult, BlockResult> parsedRHS;
private Either<ItemStack, BlockState> renderObject; private Either<ItemStack, BlockState> renderObject;
private ModelOverride(String raw, BlockResult parsedBlock, Type type, Either<ItemResult, BlockResult> parsedRHS) private ModelOverride(String raw, BlockResult parsedBlock, Type type, Either<ItemResult, BlockResult> parsedRHS)
{ {
this.raw = raw;
this.parsedBlock = parsedBlock; this.parsedBlock = parsedBlock;
this.type = type;
this.parsedRHS = parsedRHS;
parsedRHS.ifLeft(res -> { parsedRHS.ifLeft(res -> {
ItemStack stack = new ItemStack(res.item()); ItemStack stack = new ItemStack(res.item());

View File

@ -20,67 +20,42 @@
package tschipp.carryon.client.render; package tschipp.carryon.client.render;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.ByteBufferBuilder;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.math.Axis;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.SubmitNodeCollector;
import net.minecraft.client.renderer.MultiBufferSource.BufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.EntityRenderDispatcher; import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.client.renderer.entity.state.EntityRenderState;
import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.client.renderer.item.ItemStackRenderState;
import net.minecraft.client.renderer.rendertype.RenderTypes;
import net.minecraft.client.renderer.state.CameraRenderState;
import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.HumanoidArm; import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import org.joml.Matrix4f;
import tschipp.carryon.Constants;
import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnData.CarryType; import tschipp.carryon.common.carry.CarryOnData.CarryType;
import tschipp.carryon.common.carry.CarryOnDataManager; import tschipp.carryon.common.carry.CarryOnDataManager;
import tschipp.carryon.common.scripting.CarryOnScript;
import tschipp.carryon.common.scripting.CarryOnScript.ScriptRender; import tschipp.carryon.common.scripting.CarryOnScript.ScriptRender;
import tschipp.carryon.platform.Services; import tschipp.carryon.platform.Services;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.SequencedMap;
public class CarriedObjectRender public class CarriedObjectRender
{ {
public static boolean draw(Player player, PoseStack matrix, int light, float partialTicks,SubmitNodeCollector nodeCollector, boolean firstPerson)
private static SequencedMap<RenderType, ByteBufferBuilder> builders = new LinkedHashMap<>(Map.of(
RenderType.glint(), new ByteBufferBuilder(RenderType.glint().bufferSize()),
RenderType.armorEntityGlint(), new ByteBufferBuilder(RenderType.armorEntityGlint().bufferSize()),
RenderType.glintTranslucent(), new ByteBufferBuilder(RenderType.glintTranslucent().bufferSize()),
RenderType.entityGlint(), new ByteBufferBuilder(RenderType.entityGlint().bufferSize())
//RenderType.entityGlintDirect(), new ByteBufferBuilder(RenderType.entityGlintDirect().bufferSize())
));
public static boolean drawFirstPerson(Player player, MultiBufferSource buffer, PoseStack matrix, int light, float partialTicks)
{ {
if(Services.PLATFORM.isModLoaded("firstperson") || Services.PLATFORM.isModLoaded("firstpersonmod")) if(Services.PLATFORM.isModLoaded("firstperson") || Services.PLATFORM.isModLoaded("firstpersonmod") || player == null)
return false; return false;
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
try { try {
if (carry.isCarrying(CarryType.BLOCK)) if (carry.isCarrying(CarryType.BLOCK))
drawFirstPersonBlock(player, buffer, matrix, light, CarryRenderHelper.getRenderState(player)); drawBlock(player, matrix, light, CarryRenderHelper.getRenderState(player), nodeCollector, firstPerson, partialTicks);
else if (carry.isCarrying(CarryType.ENTITY)) else if (carry.isCarrying(CarryType.ENTITY))
drawFirstPersonEntity(player, buffer, matrix, light, partialTicks); drawEntity(player, matrix, light, partialTicks, nodeCollector, firstPerson);
} }
catch (Exception e) catch (Exception e)
{ {
@ -100,193 +75,59 @@ public class CarriedObjectRender
return carry.isCarrying(); return carry.isCarrying();
} }
private static void drawFirstPersonBlock(Player player, MultiBufferSource buffer, PoseStack matrix, int light, BlockState state) private static void drawBlock(Player player, PoseStack matrix, int light, BlockState state, SubmitNodeCollector nodeCollector, boolean firstPerson, float partialTicks)
{ {
matrix.pushPose();
matrix.scale(2.5f, 2.5f, 2.5f);
matrix.translate(0, -0.5, -1);
RenderSystem.enableBlend();
RenderSystem.disableCull();
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
ItemStackRenderState renderState = new ItemStackRenderState(); ItemStackRenderState renderState = new ItemStackRenderState();
var layer = renderState.newLayer();
layer.setRenderType(RenderTypes.glint());
if (Constants.CLIENT_CONFIG.facePlayer != CarryRenderHelper.isChest(state.getBlock())) { matrix.pushPose();
matrix.mulPose(Axis.YP.rotationDegrees(180));
matrix.mulPose(Axis.XN.rotationDegrees(8));
} else {
matrix.mulPose(Axis.XP.rotationDegrees(8));
}
if(carry.getActiveScript().isPresent()) PoseStack renderPose = CarryRenderHelper.setupBlockTransformations(player, matrix, carry, firstPerson);
CarryRenderHelper.performScriptTransformation(matrix, carry.getActiveScript().get());
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_BLOCKS);
ItemStack renderStack = CarryRenderHelper.getRenderItemStack(player); ItemStack renderStack = CarryRenderHelper.getRenderItemStack(player);
Minecraft.getInstance().getItemModelResolver().updateForTopItem(renderState, renderStack, ItemDisplayContext.NONE, false, player.level(), null, 0); Minecraft.getInstance().getItemModelResolver().updateForTopItem(renderState, renderStack, ItemDisplayContext.NONE, player.level(), null, 0);
renderState.render(matrix, buffer, light, OverlayTexture.NO_OVERLAY); renderState.submit(renderPose, nodeCollector, light, OverlayTexture.NO_OVERLAY, 0);
RenderSystem.enableCull();
RenderSystem.disableBlend();
matrix.popPose(); matrix.popPose();
} }
private static void drawFirstPersonEntity(Player player, MultiBufferSource buffer, PoseStack matrix, int light, float partialTicks) { private static void drawEntity(Player player, PoseStack matrix, int light, float partialTicks,SubmitNodeCollector nodeCollector, boolean firstPerson) {
EntityRenderDispatcher manager = Minecraft.getInstance().getEntityRenderDispatcher(); EntityRenderDispatcher manager = Minecraft.getInstance().getEntityRenderDispatcher();
Entity entity = CarryRenderHelper.getRenderEntity(player); Entity entity = CarryRenderHelper.getRenderEntity(player);
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (entity != null) if (entity == null)
{ return;
Vec3 playerpos = CarryRenderHelper.getExactPos(player, partialTicks);
entity.setPos(playerpos.x, playerpos.y, playerpos.z); Vec3 playerpos = CarryRenderHelper.getExactPos(player, partialTicks);
entity.xRotO = 0.0f;
entity.yRotO = 0.0f;
entity.setYHeadRot(0.0f);
float height = entity.getBbHeight(); entity.setPos(playerpos.x, playerpos.y, playerpos.z);
float width = entity.getBbWidth(); entity.xRotO = 0.0f;
entity.yRotO = 0.0f;
entity.setYHeadRot(0.0f);
matrix.pushPose(); matrix.pushPose();
matrix.scale(0.8f, 0.8f, 0.8f);
matrix.mulPose(Axis.YP.rotationDegrees(180));
matrix.translate(0.0, -height - .1, width + 0.1);
manager.setRenderShadow(false); CarryRenderHelper.setupEntityTransformations(player, matrix, carry, firstPerson);
Optional<CarryOnScript> res = carry.getActiveScript(); if (entity instanceof LivingEntity)
if(res.isPresent()) ((LivingEntity) entity).hurtTime = 0;
{
CarryOnScript script = res.get();
CarryRenderHelper.performScriptTransformation(matrix, script);
}
if (entity instanceof LivingEntity) try {
((LivingEntity) entity).hurtTime = 0; EntityRenderState renderState = manager.extractEntity(entity, 0);
renderState.shadowPieces.clear();
renderState.lightCoords = light;
manager.submit(renderState, new CameraRenderState(), 0, 0, 0, matrix, nodeCollector);
}
catch (Exception ignored)
{
}
try { matrix.popPose();
manager.render(entity, 0, 0, 0, 0f, matrix, buffer, light); if(!firstPerson)
}
catch (Exception e)
{
}
manager.setRenderShadow(true);
matrix.popPose(); matrix.popPose();
}
}
// RenderSystem.disableAlphaTest();
}
/**
* Draws the third person view of entities and blocks
* @param partialticks
* @param mat
*/
public static void drawThirdPerson(float partialticks, Matrix4f mat) {
Minecraft mc = Minecraft.getInstance();
Level level = mc.level;
int light = 0;
int perspective = CarryRenderHelper.getPerspective();
EntityRenderDispatcher manager = mc.getEntityRenderDispatcher();
PoseStack matrix = new PoseStack();
matrix.mulPose(mat);
RenderSystem.enableBlend();
RenderSystem.disableCull();
RenderSystem.disableDepthTest();
BufferSource buffer = MultiBufferSource.immediateWithBuffers(builders, builders.get(RenderType.glint()));
ItemStackRenderState renderState = new ItemStackRenderState();
for (Player player : level.players())
{
try {
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (perspective == 0 && player == mc.player && !(Services.PLATFORM.isModLoaded("firstperson") || Services.PLATFORM.isModLoaded("firstpersonmod") || Services.PLATFORM.isModLoaded("realcamera")))
continue;
light = manager.getPackedLightCoords(player, partialticks);
if (carry.isCarrying(CarryType.BLOCK)) {
BlockState state = CarryRenderHelper.getRenderState(player);
CarryRenderHelper.applyBlockTransformations(player, partialticks, matrix, state.getBlock());
ItemStack renderItemStack = CarryRenderHelper.getRenderItemStack(player);
mc.getItemModelResolver().updateForTopItem(renderState, renderItemStack, ItemDisplayContext.NONE, false, level, null, 0);
Optional<CarryOnScript> res = carry.getActiveScript();
if (res.isPresent()) {
CarryOnScript script = res.get();
CarryRenderHelper.performScriptTransformation(matrix, script);
}
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_BLOCKS);
RenderSystem.enableCull();
PoseStack.Pose p = matrix.last();
PoseStack copy = new PoseStack();
copy.mulPose(p.pose());
matrix.popPose();
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
renderState.render(copy, buffer, light, OverlayTexture.NO_OVERLAY);
matrix.popPose();
} else if (carry.isCarrying(CarryType.ENTITY)) {
Entity entity = CarryRenderHelper.getRenderEntity(player);
if (entity != null) {
CarryRenderHelper.applyEntityTransformations(player, partialticks, matrix, entity);
manager.setRenderShadow(false);
Optional<CarryOnScript> res = carry.getActiveScript();
if (res.isPresent()) {
CarryOnScript script = res.get();
CarryRenderHelper.performScriptTransformation(matrix, script);
}
if (entity instanceof LivingEntity le)
le.hurtTime = 0;
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
manager.render(entity, 0, 0, 0, 0f, matrix, buffer, light);
matrix.popPose();
manager.setRenderShadow(true);
matrix.popPose();
}
}
}
catch (Exception e)
{
}
}
buffer.endLastBatch();
buffer.endBatch(RenderType.entitySolid(TextureAtlas.LOCATION_BLOCKS));
buffer.endBatch(RenderType.entityCutout(TextureAtlas.LOCATION_BLOCKS));
buffer.endBatch(RenderType.entityCutoutNoCull(TextureAtlas.LOCATION_BLOCKS));
buffer.endBatch(RenderType.entitySmoothCutout(TextureAtlas.LOCATION_BLOCKS));
RenderSystem.enableDepthTest();
RenderSystem.enableCull();
RenderSystem.disableBlend();
}
} }

View File

@ -23,26 +23,20 @@ package tschipp.carryon.client.render;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis; import com.mojang.math.Axis;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.item.ItemStackRenderState;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.util.Mth; import net.minecraft.util.ProblemReporter;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Pose; import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.ChestBlock;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.TagValueInput;
import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import org.joml.Quaternionf; import org.joml.Quaternionf;
@ -80,91 +74,60 @@ public class CarryRenderHelper
return Axis.YP.rotationDegrees(getExactBodyRotationDegrees(entity, partialticks)); return Axis.YP.rotationDegrees(getExactBodyRotationDegrees(entity, partialticks));
} }
public static void applyGeneralTransformations(Player player, float partialticks, PoseStack matrix) public static void applyGeneralTransformations(Player player, PoseStack matrix)
{ {
int perspective = CarryRenderHelper.getPerspective();
Quaternionf playerrot = CarryRenderHelper.getExactBodyRotation(player, partialticks);
Vec3 playerpos = CarryRenderHelper.getExactPos(player, partialticks);
Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition();
Vec3 offset = playerpos.subtract(cameraPos);
Pose pose = player.getPose(); Pose pose = player.getPose();
matrix.pushPose();
matrix.translate(offset.x, offset.y, offset.z);
if (perspective == 2)
playerrot.mul(Axis.YP.rotationDegrees(180));
matrix.mulPose(playerrot);
matrix.pushPose(); matrix.pushPose();
matrix.scale(0.6f, 0.6f, 0.6f); matrix.scale(0.6f, 0.6f, 0.6f);
if (perspective == 2) matrix.translate(0, 0, -1.35);
matrix.translate(0, 0, -1.35);
if (doSneakCheck(player)) if (doSneakCheck(player))
{ {
matrix.translate(0, -0.4, 0); matrix.translate(0, -0.4, 0);
} }
if (pose == Pose.SWIMMING) if (pose == Pose.SWIMMING || pose == Pose.FALL_FLYING)
{ {
float f = player.getSwimAmount(partialticks); matrix.translate(0, 0, 2.5);
float f3 = player.isInWater() ? -90.0F - player.xRotO : -90.0F; matrix.mulPose(Axis.XP.rotationDegrees(90));
float f4 = Mth.lerp(f, 0.0F, f3);
if (perspective == 2)
{
matrix.translate(0, 0, 1.35);
matrix.mulPose(Axis.XP.rotationDegrees(f4));
}
else
matrix.mulPose(Axis.XN.rotationDegrees(f4));
matrix.translate(0, -1.5, -1.848);
if (perspective == 2)
matrix.translate(0, 0, 2.38);
} }
if (pose == Pose.FALL_FLYING) matrix.translate(0, -0.5, 0.65);
{
float f1 = player.getFallFlyingTicks() + partialticks;
float f2 = Mth.clamp(f1 * f1 / 100.0F, 0.0F, 1.0F);
if (!player.isAutoSpinAttack())
{
if (perspective == 2)
matrix.translate(0, 0, 1.35);
if (perspective == 2)
matrix.mulPose(Axis.XP.rotationDegrees(f2 * (-90.0F - player.xRotO)));
else
matrix.mulPose(Axis.XN.rotationDegrees(f2 * (-90.0F - player.xRotO)));
}
Vec3 viewVector = player.getViewVector(partialticks);
Vec3 deltaMovement = player.getDeltaMovement();
double d0 = deltaMovement.horizontalDistanceSqr();
double d1 = deltaMovement.horizontalDistanceSqr();
if (d0 > 0.0D && d1 > 0.0D)
{
double d2 = (deltaMovement.x * viewVector.x + deltaMovement.z * viewVector.z) / (Math.sqrt(d0) * Math.sqrt(d1));
double d3 = deltaMovement.x * viewVector.z - deltaMovement.z * viewVector.x;
matrix.mulPose(Axis.YP.rotation((float) (Math.signum(d3) * Math.acos(d2))));
}
if (perspective != 2)
matrix.translate(0, 0, -1.35);
matrix.translate(0, -0.2, 0);
}
matrix.translate(0, 1.6, 0.65);
} }
public static void applyBlockTransformations(Player player, float partialticks, PoseStack matrix, Block block) public static PoseStack setupBlockTransformations(Player player, PoseStack matrix, CarryOnData carry, boolean firstPerson) {
{ if (firstPerson) {
int perspective = CarryRenderHelper.getPerspective(); matrix.scale(2.5f, 2.5f, 2.5f);
matrix.translate(0, -0.5, -1);
applyGeneralTransformations(player, partialticks, matrix); if (Constants.CLIENT_CONFIG.facePlayer != CarryRenderHelper.isChest(carry.getBlock().getBlock())) {
matrix.mulPose(Axis.YP.rotationDegrees(180));
matrix.mulPose(Axis.XN.rotationDegrees(8));
} else {
matrix.mulPose(Axis.XP.rotationDegrees(8));
}
carry.getActiveScript().ifPresent(script -> CarryRenderHelper.performScriptTransformation(matrix, script));
return matrix;
} else {
CarryRenderHelper.applyBlockTransformations(player, matrix, carry.getBlock().getBlock());
carry.getActiveScript().ifPresent(script -> CarryRenderHelper.performScriptTransformation(matrix, script));
PoseStack.Pose p = matrix.last();
PoseStack copy = new PoseStack();
copy.mulPose(p.pose());
matrix.popPose();
return copy;
}
}
public static void applyBlockTransformations(Player player, PoseStack matrix, Block block)
{
matrix.mulPose(Axis.ZN.rotationDegrees(180));
applyGeneralTransformations(player, matrix);
if (Constants.CLIENT_CONFIG.facePlayer != CarryRenderHelper.isChest(block)) if (Constants.CLIENT_CONFIG.facePlayer != CarryRenderHelper.isChest(block))
{ {
@ -173,61 +136,72 @@ public class CarryRenderHelper
// matrix.translate(0, 0, -0.4); // matrix.translate(0, 0, -0.4);
matrix.mulPose(Axis.YP.rotationDegrees(180)); matrix.mulPose(Axis.YP.rotationDegrees(180));
} }
// if(perspective == 1)
// {
// matrix.pushPose();
// //matrix.mulPose(Axis.YP.rotationDegrees(180));
// matrix.popPose();
// }
//else if ((ModList.get().isLoaded("realrender") || ModList.get().isLoaded("rfpr")) && perspective == 0)
// matrix.translate(0, 0, 0.4);
//matrix.mulPose(Axis.YP.rotationDegrees(180));
float height = getRenderHeight(player); float height = getRenderHeight(player);
float offset = (height - 1f) / 1.2f; float offset = (height - 1f) / 1.2f;
matrix.translate(0, -offset, 0); matrix.translate(0, -offset, 0);
} }
public static void applyEntityTransformations(Player player, float partialticks, PoseStack matrix, Entity entity) public static void setupEntityTransformations(Player player, PoseStack matrix, CarryOnData carry, boolean firstPerson) {
Entity entity = carry.getEntity(player.level());
float height = entity.getBbHeight();
float width = entity.getBbWidth();
if(firstPerson) {
matrix.mulPose(Axis.YP.rotationDegrees(180));
matrix.scale(0.8f, 0.8f, 0.8f);
matrix.translate(0.0, -height - .2, width * 1.3 + 0.1);
carry.getActiveScript().ifPresent(script -> CarryRenderHelper.performScriptTransformation(matrix, script));
if(Constants.CLIENT_CONFIG.rotateEntitiesSideways)
matrix.mulPose(Axis.YP.rotationDegrees(90));
}
else {
applyEntityTransformations(player, matrix, entity);
carry.getActiveScript().ifPresent(script -> CarryRenderHelper.performScriptTransformation(matrix, script));
}
}
public static void applyEntityTransformations(Player player, PoseStack matrix, Entity entity)
{ {
int perspective = CarryRenderHelper.getPerspective();
Pose pose = player.getPose(); Pose pose = player.getPose();
applyGeneralTransformations(player, partialticks, matrix); applyGeneralTransformations(player, matrix);
if (perspective == 2) matrix.mulPose(Axis.XP.rotationDegrees(180));
matrix.translate(0, -1.6, 0.65);
else matrix.translate(0, -3.1, -0.65);
matrix.translate(0, -1.6, -0.65);
matrix.scale(1.666f, 1.666f, 1.666f); matrix.scale(1.666f, 1.666f, 1.666f);
float height = entity.getBbHeight(); float height = entity.getBbHeight();
float width = entity.getBbWidth(); float width = entity.getBbWidth();
float multiplier = height * width; float multiplier = Math.min(9.9f, height * width) ;
entity.yo = 0.0f; entity.yo = 0.0f;
entity.yRotO = 0.0f; entity.yRotO = 0.0f;
entity.setYHeadRot(0.0f); entity.setYHeadRot(0.0f);
entity.xo = 0.0f; entity.xo = 0.0f;
entity.xRotO = 0.0f; entity.xRotO = 0.0f;
if (perspective == 2)
matrix.mulPose(Axis.YP.rotationDegrees(180));
matrix.scale((10 - multiplier) * 0.08f, (10 - multiplier) * 0.08f, (10 - multiplier) * 0.08f); matrix.scale((10 - multiplier) * 0.08f, (10 - multiplier) * 0.08f, (10 - multiplier) * 0.08f);
matrix.translate(0.0, height / 2 + -(height / 2) + 1, width - 0.1 < 0.7 ? width - 0.1 + (0.7 - (width - 0.1)) : width - 0.1); matrix.translate(0.0, height / 2 + -(height / 4) + 1, width - 0.1 < 0.7 ? width - 0.1 + (0.7 - (width - 0.1)) : width - 0.1);
if(doSneakCheck(player))
matrix.translate(0, -0.4, 0);
if (pose == Pose.SWIMMING || pose == Pose.FALL_FLYING) if (pose == Pose.SWIMMING || pose == Pose.FALL_FLYING)
{ {
matrix.mulPose(Axis.XN.rotationDegrees(90)); matrix.mulPose(Axis.XN.rotationDegrees(180));
matrix.translate(0, -0.2 * height, 0); matrix.translate(0, 0.2 * height - 2, -0.5);
if (pose == Pose.FALL_FLYING)
matrix.translate(0, 0, 0.2);
} }
if(Constants.CLIENT_CONFIG.rotateEntitiesSideways)
matrix.mulPose(Axis.YP.rotationDegrees(90));
} }
@ -374,8 +348,10 @@ public class CarryRenderHelper
if(render.renderNameEntity().isPresent()) if(render.renderNameEntity().isPresent())
entity = BuiltInRegistries.ENTITY_TYPE.get(render.renderNameEntity().get()).get().value().create(player.level(), EntitySpawnReason.EVENT); entity = BuiltInRegistries.ENTITY_TYPE.get(render.renderNameEntity().get()).get().value().create(player.level(), EntitySpawnReason.EVENT);
if(render.renderNBT().isPresent()) if(render.renderNBT().isPresent()) {
entity.load(render.renderNBT().get()); ValueInput input = TagValueInput.create(new ProblemReporter.ScopedCollector(Constants.LOG), player.registryAccess(), render.renderNBT().get());
entity.load(input);
}
} }
return entity; return entity;
@ -403,7 +379,10 @@ public class CarryRenderHelper
else if(carry.isCarrying(CarryType.ENTITY)) else if(carry.isCarrying(CarryType.ENTITY))
{ {
Entity entity = getRenderEntity(player); Entity entity = getRenderEntity(player);
return entity.getBbWidth(); float w = entity.getBbWidth();
if (Constants.CLIENT_CONFIG.rotateEntitiesSideways)
return w - (w*w) * 0.35f;
return w * 0.9f;
} }
else else
return 1f; return 1f;
@ -461,7 +440,7 @@ public class CarryRenderHelper
public static boolean isChest(Block block) public static boolean isChest(Block block)
{ {
return block == Blocks.CHEST || block == Blocks.ENDER_CHEST || block == Blocks.TRAPPED_CHEST; return block == Blocks.CHEST || block == Blocks.ENDER_CHEST || block == Blocks.TRAPPED_CHEST || block instanceof ChestBlock;
} }
} }

View File

@ -0,0 +1,22 @@
package tschipp.carryon.client.render;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.player.PlayerModel;
import net.minecraft.client.renderer.SubmitNodeCollector;
import net.minecraft.client.renderer.entity.RenderLayerParent;
import net.minecraft.client.renderer.entity.layers.RenderLayer;
import net.minecraft.client.renderer.entity.state.AvatarRenderState;
public class CarryingItemRenderLayer<M extends PlayerModel> extends RenderLayer<AvatarRenderState, M> {
public CarryingItemRenderLayer(RenderLayerParent<AvatarRenderState, M> renderer) {
super(renderer);
}
@Override
public void submit(PoseStack poseStack, SubmitNodeCollector nodeCollector, int packedLight,
AvatarRenderState renderState, float yRot, float xRot) {
if (renderState instanceof ICarryOnRenderState carryOnRenderState){
CarriedObjectRender.draw(carryOnRenderState.getPlayer(), poseStack, packedLight, Minecraft.getInstance().getDeltaTracker().getGameTimeDeltaPartialTick(true), nodeCollector,false);
}
}
}

View File

@ -1,5 +1,6 @@
package tschipp.carryon.client.render; package tschipp.carryon.client.render;
import net.minecraft.world.entity.player.Player;
import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.common.carry.CarryOnData;
public interface ICarryOnRenderState { public interface ICarryOnRenderState {
@ -12,4 +13,8 @@ public interface ICarryOnRenderState {
void setRenderWidth(float val); void setRenderWidth(float val);
Player getPlayer();
void setPlayer(Player player);
} }

View File

@ -20,6 +20,7 @@
package tschipp.carryon.common.carry; package tschipp.carryon.common.carry;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult; import com.mojang.serialization.DataResult;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
@ -28,20 +29,29 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.entity.AreaEffectCloud; import net.minecraft.world.entity.AreaEffectCloud;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.storage.TagValueInput;
import net.minecraft.world.level.storage.TagValueOutput;
import net.minecraft.world.level.storage.ValueInput;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.common.scripting.CarryOnScript; import tschipp.carryon.common.scripting.CarryOnScript;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
public class CarryOnData { public class CarryOnData {
@ -50,18 +60,40 @@ public class CarryOnData {
private boolean keyPressed = false; private boolean keyPressed = false;
private CarryOnScript activeScript; private CarryOnScript activeScript;
private int selectedSlot = 0; private int selectedSlot = 0;
private static final ProblemReporter problemReporter = new ProblemReporter.ScopedCollector(Constants.LOG);
public static final Codec<CarryOnData> CODEC = CompoundTag.CODEC.flatXmap(
tag -> {
try {
return DataResult.success(new CarryOnData(tag));
} catch (Exception e) {
return DataResult.error(e::getMessage);
}
},
carry -> {
try {
return DataResult.success(carry.getNbt());
} catch (Exception e) {
return DataResult.error(e::getMessage);
}
}
);
public static final StreamCodec<RegistryFriendlyByteBuf, CarryOnData> STREAM_CODEC = ByteBufCodecs.fromCodecWithRegistries(CODEC);
public static final String SERIALIZATION_KEY = "CarryOnData";
public CarryOnData(CompoundTag data) public CarryOnData(CompoundTag data)
{ {
if(data.contains("type")) if(data.contains("type"))
this.type = CarryType.valueOf(data.getString("type")); this.type = CarryType.valueOf(data.getStringOr("type", "INVALID"));
else else
this.type = CarryType.INVALID; this.type = CarryType.INVALID;
this.nbt = data; this.nbt = data;
if(data.contains("keyPressed")) this.keyPressed = data.getBooleanOr("keyPressed", false);
this.keyPressed = data.getBoolean("keyPressed");
if(data.contains("activeScript")) if(data.contains("activeScript"))
{ {
@ -69,11 +101,15 @@ public class CarryOnData {
this.activeScript = res.getOrThrow((s) -> {throw new RuntimeException("Failed to decode activeScript during CarryOnData serialization: " + s);}); this.activeScript = res.getOrThrow((s) -> {throw new RuntimeException("Failed to decode activeScript during CarryOnData serialization: " + s);});
} }
if(data.contains("selected")) this.selectedSlot = data.getIntOr("selected", 0);
this.selectedSlot = data.getInt("selected");
} }
public CarryType getType()
{
return this.type;
}
public CompoundTag getNbt() public CompoundTag getNbt()
{ {
nbt.putString("type", type.toString()); nbt.putString("type", type.toString());
@ -91,9 +127,9 @@ public class CarryOnData {
public CompoundTag getContentNbt() public CompoundTag getContentNbt()
{ {
if(type == CarryType.BLOCK && nbt.contains("block")) if(type == CarryType.BLOCK && nbt.contains("block"))
return nbt.getCompound("block"); return nbt.getCompoundOrEmpty("block");
else if(type == CarryType.ENTITY && nbt.contains("entity")) else if(type == CarryType.ENTITY && nbt.contains("entity"))
return nbt.getCompound("entity"); return nbt.getCompoundOrEmpty("entity");
return null; return null;
} }
@ -109,7 +145,9 @@ public class CarryOnData {
if(tile != null) if(tile != null)
{ {
CompoundTag tileData = tile.saveWithId(tile.getLevel().registryAccess()); TagValueOutput output = TagValueOutput.createWithContext(problemReporter, player.registryAccess());
tile.saveWithId(output);
Tag tileData = output.buildResult();
nbt.put("tile", tileData); nbt.put("tile", tileData);
} }
} }
@ -119,7 +157,7 @@ public class CarryOnData {
if(this.type != CarryType.BLOCK) if(this.type != CarryType.BLOCK)
throw new IllegalStateException("Called getBlock on data that contained " + this.type); throw new IllegalStateException("Called getBlock on data that contained " + this.type);
return NbtUtils.readBlockState(BuiltInRegistries.BLOCK, nbt.getCompound("block")); return NbtUtils.readBlockState(BuiltInRegistries.BLOCK, nbt.getCompoundOrEmpty("block"));
} }
@Nullable @Nullable
@ -131,14 +169,15 @@ public class CarryOnData {
if(!nbt.contains("tile")) if(!nbt.contains("tile"))
return null; return null;
return BlockEntity.loadStatic(pos, this.getBlock(), nbt.getCompound("tile"), lookup); return BlockEntity.loadStatic(pos, this.getBlock(), nbt.getCompoundOrEmpty("tile"), lookup);
} }
public void setEntity(Entity entity) public void setEntity(Entity entity)
{ {
this.type = CarryType.ENTITY; this.type = CarryType.ENTITY;
CompoundTag entityData = new CompoundTag(); TagValueOutput output = TagValueOutput.createWithContext(new ProblemReporter.ScopedCollector(Constants.LOG), entity.registryAccess());
entity.save(entityData); entity.save(output);
Tag entityData = output.buildResult();
nbt.put("entity", entityData); nbt.put("entity", entityData);
} }
@ -147,7 +186,8 @@ public class CarryOnData {
if(this.type != CarryType.ENTITY) if(this.type != CarryType.ENTITY)
throw new IllegalStateException("Called getEntity on data that contained " + this.type); throw new IllegalStateException("Called getEntity on data that contained " + this.type);
var optionalEntity = EntityType.create(nbt.getCompound("entity"), level, EntitySpawnReason.BUCKET); ValueInput in = TagValueInput.create(problemReporter, level.registryAccess(), nbt.getCompoundOrEmpty("entity"));
var optionalEntity = EntityType.create(in, level, EntitySpawnReason.BUCKET);
if(optionalEntity.isPresent()) if(optionalEntity.isPresent())
return optionalEntity.get(); return optionalEntity.get();
@ -168,8 +208,20 @@ public class CarryOnData {
this.activeScript = script; this.activeScript = script;
} }
public void setCarryingPlayer() { public void setCarryingPlayer(Player player)
{
this.type = CarryType.PLAYER; this.type = CarryType.PLAYER;
nbt.putString("player", player.getStringUUID().toString());
}
public Player getCarryingPlayer(Level level)
{
if(this.type != CarryType.PLAYER)
throw new IllegalStateException("Called getCarryingPlayer on data that contained " + this.type);
if(!nbt.contains("player"))
return null;
UUID uuid = UUID.fromString(nbt.getString("player").get());
return level.getServer().getPlayerList().getPlayer(uuid);
} }
public boolean isCarrying() public boolean isCarrying()
@ -210,11 +262,14 @@ public class CarryOnData {
public int getTick() public int getTick()
{ {
if(!this.nbt.contains("tick")) return this.nbt.getIntOr("tick", -1);
return -1;
return this.nbt.getInt("tick");
} }
public void setTick(int tick) {
this.nbt.putInt("tick", tick);
}
public enum CarryType { public enum CarryType {
BLOCK, BLOCK,
ENTITY, ENTITY,

View File

@ -20,29 +20,21 @@
package tschipp.carryon.common.carry; package tschipp.carryon.common.carry;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import tschipp.carryon.platform.Services;
public class CarryOnDataManager { public class CarryOnDataManager {
public static CarryOnData getCarryData(Player player) public static CarryOnData getCarryData(Player player)
{ {
return ((ICarrying)player).getCarryOnData(); return Services.PLATFORM.getCarryData(player);
} }
public static void setCarryData(Player player, CarryOnData data) public static void setCarryData(Player player, CarryOnData data)
{ {
((ICarrying)player).setCarryOnData(data); data.setSelected(player.getInventory().getSelectedSlot());
} data.setTick(player.tickCount);
Services.PLATFORM.setCarryData(player, data);
public interface ICarrying {
void setCarryOnData(CarryOnData data);
CarryOnData getCarryOnData();
} }
} }

View File

@ -25,26 +25,30 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.AgeableMob; import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity; import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.*;
import net.minecraft.world.entity.Entity.RemovalReason; import net.minecraft.world.entity.Entity.RemovalReason;
import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.entity.TamableAnimal;
import net.minecraft.world.entity.animal.Animal; import net.minecraft.world.entity.animal.Animal;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.GameType; import net.minecraft.world.level.GameType;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.DoorBlock;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.storage.TagValueOutput;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import tschipp.carryon.CarryOnCommon;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.common.config.ListHandler; import tschipp.carryon.common.config.ListHandler;
import tschipp.carryon.common.pickupcondition.PickupCondition; import tschipp.carryon.common.pickupcondition.PickupCondition;
import tschipp.carryon.common.pickupcondition.PickupConditionHandler; import tschipp.carryon.common.pickupcondition.PickupConditionHandler;
import tschipp.carryon.common.scripting.CarryOnScript; import tschipp.carryon.common.scripting.CarryOnScript;
import tschipp.carryon.common.scripting.ScriptManager; import tschipp.carryon.common.scripting.ScriptManager;
import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket; import tschipp.carryon.networking.clientbound.ClientboundStartRidingOtherPlayerPacket;
import tschipp.carryon.platform.Services; import tschipp.carryon.platform.Services;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -92,16 +96,26 @@ public class PickupHandler {
BlockEntity blockEntity = level.getBlockEntity(pos); BlockEntity blockEntity = level.getBlockEntity(pos);
BlockState state = level.getBlockState(pos); BlockState state = level.getBlockState(pos);
CompoundTag nbt = null; CompoundTag nbt = null;
if(blockEntity != null) if(blockEntity != null) {
nbt = blockEntity.saveWithId(level.registryAccess()); TagValueOutput output = TagValueOutput.createWithContext(new ProblemReporter.ScopedCollector(Constants.LOG), level.registryAccess());
blockEntity.saveWithId(output);
nbt = output.buildResult();
}
Optional<CarryOnScript> result = ScriptManager.inspectBlock(state, level, pos, nbt);
boolean overrideChecks = result.map(CarryOnScript::overrideChecks).orElse(false);
if(!ListHandler.isPermitted(state.getBlock())) if(!ListHandler.isPermitted(state.getBlock()))
return false; return false;
if(state.getDestroySpeed(level, pos) == -1 && !player.isCreative() && !Constants.COMMON_CONFIG.settings.pickupUnbreakableBlocks) // Reject pickup of Double blocks, if they use the vanilla property
if(hasPropertyType(state, DoorBlock.HALF))
return false; return false;
if(blockEntity == null && !Constants.COMMON_CONFIG.settings.pickupAllBlocks) if(!overrideChecks && (state.getDestroySpeed(level, pos) == -1 && !player.isCreative() && !Constants.COMMON_CONFIG.settings.pickupUnbreakableBlocks))
return false;
if(!overrideChecks && (blockEntity == null && !Constants.COMMON_CONFIG.settings.pickupAllBlocks))
return false; return false;
//Check if TE is locked //Check if TE is locked
@ -122,7 +136,6 @@ public class PickupHandler {
if(!doPickup) if(!doPickup)
return false; return false;
Optional<CarryOnScript> result = ScriptManager.inspectBlock(state, level, pos, nbt);
if(result.isPresent()) if(result.isPresent())
{ {
CarryOnScript script = result.get(); CarryOnScript script = result.get();
@ -133,7 +146,7 @@ public class PickupHandler {
String cmd = script.scriptEffects().commandInit(); String cmd = script.scriptEffects().commandInit();
if(!cmd.isEmpty()) if(!cmd.isEmpty())
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd); player.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
} }
carry.setBlock(state, blockEntity, player, pos); carry.setBlock(state, blockEntity, player, pos);
@ -144,6 +157,8 @@ public class PickupHandler {
CarryOnDataManager.setCarryData(player, carry); CarryOnDataManager.setCarryData(player, carry);
level.playSound(null, pos, state.getSoundType().getHitSound(), SoundSource.BLOCKS, 1.0f, 0.5f); level.playSound(null, pos, state.getSoundType().getHitSound(), SoundSource.BLOCKS, 1.0f, 0.5f);
player.swing(InteractionHand.MAIN_HAND, true); player.swing(InteractionHand.MAIN_HAND, true);
if (!player.isCreative() || Constants.COMMON_CONFIG.settings.slownessInCreative)
player.addEffect(new MobEffectInstance(MobEffects.SLOWNESS, 100000000, CarryOnCommon.potionLevel(carry, player.level()), false, false));
return true; return true;
} }
@ -162,23 +177,29 @@ public class PickupHandler {
if (entity instanceof TamableAnimal tame) if (entity instanceof TamableAnimal tame)
{ {
UUID owner = tame.getOwnerUUID(); EntityReference<LivingEntity> ref = tame.getOwnerReference();
UUID playerID = player.getGameProfile().getId(); if (ref != null) {
if (owner != null && !owner.equals(playerID)) UUID owner = ref.getUUID();
return false; UUID playerID = player.getGameProfile().id();
if (!owner.equals(playerID))
return false;
}
} }
Optional<CarryOnScript> result = ScriptManager.inspectEntity(entity);
boolean overrideChecks = result.map(CarryOnScript::overrideChecks).orElse(false);
if(!ListHandler.isPermitted(entity)) if(!ListHandler.isPermitted(entity))
{ {
//We can pick up baby animals even if the grown up animal is blacklisted. //We can pick up baby animals even if the grown up animal is blacklisted.
if(!(entity instanceof AgeableMob ageableMob && Constants.COMMON_CONFIG.settings.allowBabies && (ageableMob.getAge() < 0 || ageableMob.isBaby()))) if(!overrideChecks && (!(entity instanceof AgeableMob ageableMob && Constants.COMMON_CONFIG.settings.allowBabies && (ageableMob.getAge() < 0 || ageableMob.isBaby()))))
return false; return false;
} }
//Non-Creative only guards //Non-Creative only guards
if(!player.isCreative()) if(!player.isCreative())
{ {
if(!Constants.COMMON_CONFIG.settings.pickupHostileMobs && entity.getType().getCategory() == MobCategory.MONSTER) if(!overrideChecks && (!Constants.COMMON_CONFIG.settings.pickupHostileMobs && entity.getType().getCategory() == MobCategory.MONSTER))
return false; return false;
if(Constants.COMMON_CONFIG.settings.maxEntityHeight < entity.getBbHeight() || Constants.COMMON_CONFIG.settings.maxEntityWidth < entity.getBbWidth()) if(Constants.COMMON_CONFIG.settings.maxEntityHeight < entity.getBbHeight() || Constants.COMMON_CONFIG.settings.maxEntityWidth < entity.getBbWidth())
@ -192,13 +213,12 @@ public class PickupHandler {
return false; return false;
} }
boolean doPickup = pickupCallback == null ? true : pickupCallback.apply(entity); boolean doPickup = pickupCallback == null || pickupCallback.apply(entity);
if(!doPickup) if(!doPickup)
return false; return false;
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
Optional<CarryOnScript> result = ScriptManager.inspectEntity(entity);
if(result.isPresent()) if(result.isPresent())
{ {
CarryOnScript script = result.get(); CarryOnScript script = result.get();
@ -221,15 +241,17 @@ public class PickupHandler {
if (result.isPresent()) { if (result.isPresent()) {
String cmd = result.get().scriptEffects().commandInit(); String cmd = result.get().scriptEffects().commandInit();
if (!cmd.isEmpty()) if (!cmd.isEmpty())
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd); player.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
} }
otherPlayer.startRiding(player); otherPlayer.startRiding(player, true, false);
Services.PLATFORM.sendPacketToPlayer(Constants.PACKET_ID_START_RIDING, new ClientboundStartRidingPacket(otherPlayer.getId(), true), player); Services.PLATFORM.sendPacketToAllPlayers(Constants.PACKET_ID_START_RIDING_OTHER, new ClientboundStartRidingOtherPlayerPacket(player.getId(), otherPlayer.getId(), true), player.level());
carry.setCarryingPlayer(); carry.setCarryingPlayer(otherPlayer);
player.swing(InteractionHand.MAIN_HAND, true); player.swing(InteractionHand.MAIN_HAND, true);
player.level().playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC.value(), SoundSource.AMBIENT, 1.0f, 0.5f); player.level().playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC.value(), SoundSource.AMBIENT, 1.0f, 0.5f);
CarryOnDataManager.setCarryData(player, carry); CarryOnDataManager.setCarryData(player, carry);
if (!player.isCreative() || Constants.COMMON_CONFIG.settings.slownessInCreative)
player.addEffect(new MobEffectInstance(MobEffects.SLOWNESS, 100000000, CarryOnCommon.potionLevel(carry, player.level()), false, false));
return true; return true;
} }
@ -244,7 +266,7 @@ public class PickupHandler {
{ {
String cmd = result.get().scriptEffects().commandInit(); String cmd = result.get().scriptEffects().commandInit();
if(!cmd.isEmpty()) if(!cmd.isEmpty())
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd); player.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
} }
carry.setEntity(entity); carry.setEntity(entity);
@ -253,7 +275,17 @@ public class PickupHandler {
player.level().playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC.value(), SoundSource.AMBIENT, 1.0f, 0.5f); player.level().playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC.value(), SoundSource.AMBIENT, 1.0f, 0.5f);
CarryOnDataManager.setCarryData(player, carry); CarryOnDataManager.setCarryData(player, carry);
player.swing(InteractionHand.MAIN_HAND, true); player.swing(InteractionHand.MAIN_HAND, true);
if (!player.isCreative() || Constants.COMMON_CONFIG.settings.slownessInCreative)
player.addEffect(new MobEffectInstance(MobEffects.SLOWNESS, 100000000, CarryOnCommon.potionLevel(carry, player.level()), false, false));
return true; return true;
} }
private static <T extends Comparable<T>> boolean hasPropertyType(BlockState state, Property<T> prop) {
for (var p : state.getProperties()) {
if(p.getValueClass().equals(prop.getValueClass()))
return true;
}
return false;
}
} }

View File

@ -22,23 +22,23 @@ package tschipp.carryon.common.carry;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.animal.horse.Horse; import net.minecraft.world.entity.animal.equine.Horse;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.gamerules.GameRules;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.CollisionContext;
@ -46,6 +46,8 @@ import tschipp.carryon.Constants;
import tschipp.carryon.common.carry.CarryOnData.CarryType; import tschipp.carryon.common.carry.CarryOnData.CarryType;
import tschipp.carryon.common.config.ListHandler; import tschipp.carryon.common.config.ListHandler;
import tschipp.carryon.common.scripting.CarryOnScript.ScriptEffects; import tschipp.carryon.common.scripting.CarryOnScript.ScriptEffects;
import tschipp.carryon.networking.clientbound.ClientboundStartRidingOtherPlayerPacket;
import tschipp.carryon.platform.Services;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@ -90,11 +92,14 @@ public class PlacementHandler
if (!doPlace) if (!doPlace)
return false; return false;
if(level.isOutsideBuildHeight(pos))
return false;
if (carry.getActiveScript().isPresent()) { if (carry.getActiveScript().isPresent()) {
ScriptEffects effects = carry.getActiveScript().get().scriptEffects(); ScriptEffects effects = carry.getActiveScript().get().scriptEffects();
String cmd = effects.commandPlace(); String cmd = effects.commandPlace();
if (!cmd.isEmpty()) if (!cmd.isEmpty())
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd); player.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
} }
level.setBlockAndUpdate(pos, state); level.setBlockAndUpdate(pos, state);
@ -109,6 +114,7 @@ public class PlacementHandler
player.playSound(state.getSoundType().getPlaceSound(), 1.0f, 0.5f); player.playSound(state.getSoundType().getPlaceSound(), 1.0f, 0.5f);
level.playSound(null, pos, state.getSoundType().getPlaceSound(), SoundSource.BLOCKS, 1.0f, 0.5f); level.playSound(null, pos, state.getSoundType().getPlaceSound(), SoundSource.BLOCKS, 1.0f, 0.5f);
player.swing(InteractionHand.MAIN_HAND, true); player.swing(InteractionHand.MAIN_HAND, true);
player.removeEffect(MobEffects.SLOWNESS);
return true; return true;
} }
@ -171,14 +177,14 @@ public class PlacementHandler
Vec3 placementPos = Vec3.atBottomCenterOf(pos); Vec3 placementPos = Vec3.atBottomCenterOf(pos);
if (carry.isCarrying(CarryType.PLAYER)) { if (carry.isCarrying(CarryType.PLAYER)) {
Entity otherPlayer = player.getFirstPassenger(); Entity otherPlayer = carry.getCarryingPlayer(level);
player.ejectPassengers(); player.ejectPassengers();
Services.PLATFORM.sendPacketToAllPlayers(Constants.PACKET_ID_START_RIDING_OTHER, new ClientboundStartRidingOtherPlayerPacket(player.getId(), otherPlayer.getId(), false), player.level());
carry.clear(); carry.clear();
CarryOnDataManager.setCarryData(player, carry); CarryOnDataManager.setCarryData(player, carry);
if (otherPlayer == null) otherPlayer.teleportTo(placementPos.x, placementPos.y, placementPos.z);
return true;
otherPlayer.teleportTo(placementPos.x, placementPos.y, placementPos.z);
player.swing(InteractionHand.MAIN_HAND, true); player.swing(InteractionHand.MAIN_HAND, true);
player.removeEffect(MobEffects.SLOWNESS);
return true; return true;
} }
@ -193,7 +199,7 @@ public class PlacementHandler
ScriptEffects effects = carry.getActiveScript().get().scriptEffects(); ScriptEffects effects = carry.getActiveScript().get().scriptEffects();
String cmd = effects.commandPlace(); String cmd = effects.commandPlace();
if (!cmd.isEmpty()) if (!cmd.isEmpty())
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd); player.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
} }
level.addFreshEntity(entity); level.addFreshEntity(entity);
@ -203,6 +209,7 @@ public class PlacementHandler
player.swing(InteractionHand.MAIN_HAND, true); player.swing(InteractionHand.MAIN_HAND, true);
carry.clear(); carry.clear();
CarryOnDataManager.setCarryData(player, carry); CarryOnDataManager.setCarryData(player, carry);
player.removeEffect(MobEffects.SLOWNESS);
return true; return true;
} }
@ -222,6 +229,8 @@ public class PlacementHandler
else else
entityHeld = player.getFirstPassenger(); entityHeld = player.getFirstPassenger();
if(entityHeld == null)
return;
double sizeHeldEntity = entityHeld.getBbHeight() * entityHeld.getBbWidth(); double sizeHeldEntity = entityHeld.getBbHeight() * entityHeld.getBbWidth();
double distance = entityClicked.blockPosition().distSqr(player.blockPosition()); double distance = entityClicked.blockPosition().distSqr(player.blockPosition());
@ -248,26 +257,27 @@ public class PlacementHandler
level.addFreshEntity(entityHeld); level.addFreshEntity(entityHeld);
entityHeld.teleportTo(tempX, tempY, tempZ); entityHeld.teleportTo(tempX, tempY, tempZ);
} }
entityHeld.startRiding(topEntity, false); entityHeld.startRiding(topEntity, false,false);
} else { } else {
if (carry.isCarrying(CarryType.ENTITY)) { if (carry.isCarrying(CarryType.ENTITY)) {
entityHeld.setPos(entityClicked.getX(), entityClicked.getY(), entityClicked.getZ()); entityHeld.setPos(entityClicked.getX(), entityClicked.getY(), entityClicked.getZ());
level.addFreshEntity(entityHeld); level.addFreshEntity(entityHeld);
} }
entityHeld.startRiding(topEntity, false); entityHeld.startRiding(topEntity, false,false);
} }
if (carry.getActiveScript().isPresent()) { if (carry.getActiveScript().isPresent()) {
ScriptEffects effects = carry.getActiveScript().get().scriptEffects(); ScriptEffects effects = carry.getActiveScript().get().scriptEffects();
String cmd = effects.commandPlace(); String cmd = effects.commandPlace();
if (!cmd.isEmpty()) if (!cmd.isEmpty())
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd); player.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
} }
player.swing(InteractionHand.MAIN_HAND, true); player.swing(InteractionHand.MAIN_HAND, true);
carry.clear(); carry.clear();
CarryOnDataManager.setCarryData(player, carry); CarryOnDataManager.setCarryData(player, carry);
level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.HORSE_SADDLE, SoundSource.PLAYERS, 0.5F, 1.5F); level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.HORSE_SADDLE, SoundSource.PLAYERS, 0.5F, 1.5F);
player.removeEffect(MobEffects.SLOWNESS);
} else { } else {
level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.LAVA_POP, SoundSource.PLAYERS, 0.5F, 0.5F); level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.LAVA_POP, SoundSource.PLAYERS, 0.5F, 0.5F);
} }
@ -280,10 +290,10 @@ public class PlacementHandler
public static void placeCarriedOnDeath(ServerPlayer oldPlayer, ServerPlayer newPlayer, boolean died) public static void placeCarriedOnDeath(ServerPlayer oldPlayer, ServerPlayer newPlayer, boolean died)
{ {
CarryOnData carry = CarryOnDataManager.getCarryData(oldPlayer); CarryOnData carry = CarryOnDataManager.getCarryData(oldPlayer);
if (((ServerLevel) oldPlayer.level()).getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || !died) { if (oldPlayer.level().getGameRules().get(GameRules.KEEP_INVENTORY) || !died) {
if (!carry.isCarrying(CarryType.PLAYER)) { if (!carry.isCarrying(CarryType.PLAYER)) {
CarryOnDataManager.setCarryData(newPlayer, carry); CarryOnDataManager.setCarryData(newPlayer, carry);
newPlayer.getInventory().selected = oldPlayer.getInventory().selected; newPlayer.getInventory().setSelectedSlot(oldPlayer.getInventory().getSelectedSlot());
return; return;
} }
} }
@ -311,6 +321,7 @@ public class PlacementHandler
} }
carry.clear(); carry.clear();
CarryOnDataManager.setCarryData(player, carry); CarryOnDataManager.setCarryData(player, carry);
player.removeEffect(MobEffects.SLOWNESS);
} }
private static BlockPos getDeathPlacementPos(BlockState state, ServerPlayer player) private static BlockPos getDeathPlacementPos(BlockState state, ServerPlayer player)

View File

@ -28,6 +28,8 @@ import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.EntityArgument; import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.permissions.Permission;
import net.minecraft.server.permissions.PermissionLevel;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
@ -54,11 +56,11 @@ public class CommandCarryOn
.then(Commands.literal("clear").executes(cmd -> handleClear(cmd.getSource(), Collections.singleton(cmd.getSource().getPlayerOrException())))) .then(Commands.literal("clear").executes(cmd -> handleClear(cmd.getSource(), Collections.singleton(cmd.getSource().getPlayerOrException()))))
.then(Commands.literal("clear").then(Commands.argument("target", EntityArgument.players()).requires(src -> src.hasPermission(2)).executes(cmd -> handleClear(cmd.getSource(), EntityArgument.getPlayers(cmd, "target"))))) .then(Commands.literal("clear").then(Commands.argument("target", EntityArgument.players()).requires(src -> src.permissions().hasPermission(new Permission.HasCommandLevel(PermissionLevel.GAMEMASTERS))).executes(cmd -> handleClear(cmd.getSource(), EntityArgument.getPlayers(cmd, "target")))))
.then(Commands.literal("place").requires(src -> src.hasPermission(2)).executes(cmd -> handlePlace(cmd.getSource(), Collections.singleton(cmd.getSource().getPlayerOrException())))) .then(Commands.literal("place").requires(src -> src.permissions().hasPermission(new Permission.HasCommandLevel(PermissionLevel.GAMEMASTERS))).executes(cmd -> handlePlace(cmd.getSource(), Collections.singleton(cmd.getSource().getPlayerOrException()))))
.then(Commands.literal("place").then(Commands.argument("target", EntityArgument.players()).requires(src -> src.hasPermission(2)).executes(cmd -> handlePlace(cmd.getSource(), EntityArgument.getPlayers(cmd, "target"))))) .then(Commands.literal("place").then(Commands.argument("target", EntityArgument.players()).requires(src -> src.permissions().hasPermission(new Permission.HasCommandLevel(PermissionLevel.GAMEMASTERS))).executes(cmd -> handlePlace(cmd.getSource(), EntityArgument.getPlayers(cmd, "target")))))
; ;

View File

@ -285,7 +285,7 @@ public class CarryConfig
"modern_industrialization:fluid_pipe", "modern_industrialization:fluid_pipe",
"modern_industrialization:*_fluid_pipe", "modern_industrialization:*_fluid_pipe",
"yigd:*", "domum_ornamentum:*", "connectiblechains:*", "yigd:*", "domum_ornamentum:*", "connectiblechains:*",
"cobblemon:*", "snowrealmagic:*" "cobblemon:*", "snowrealmagic:*", "forbidden_arcanus:black_hole", "domum_ornamentum:*", "sgjourney:*", "copycats:*", "expandedstorage:*", "replication:*"
}; };
@Property( @Property(
@ -302,7 +302,7 @@ public class CarryConfig
"animania:hamster", "animania:ferret*", "animania:hedgehog*", "animania:cart", "animania:hamster", "animania:ferret*", "animania:hedgehog*", "animania:cart",
"animania:wagon", "mynko:*", "pixelmon:*", "mocreatures:*", "quark:totem", "vehicle:*", "animania:wagon", "mynko:*", "pixelmon:*", "mocreatures:*", "quark:totem", "vehicle:*",
"securitycraft:*", "taterzens:npc", "easy_npc:*", "bodiesbodies:dead_body", "littletiles:*", "securitycraft:*", "taterzens:npc", "easy_npc:*", "bodiesbodies:dead_body", "littletiles:*",
"connectiblechains:*", "cobblemon:*", "create:*" "connectiblechains:*", "cobblemon:*", "create:*", "swem:*", "toms_mobs:*"
}; };
@Property( @Property(
@ -311,7 +311,8 @@ public class CarryConfig
validationRegex = "(#?[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]*(?:\\*|[a-zA-Z0-9_]*)(?:\\*|[a-zA-Z0-9_]*)?)" validationRegex = "(#?[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]*(?:\\*|[a-zA-Z0-9_]*)(?:\\*|[a-zA-Z0-9_]*)?)"
) )
public String[] forbiddenStacking = { public String[] forbiddenStacking = {
"minecraft:horse" "minecraft:horse",
"minecraft:ender_dragon"
}; };
} }
@ -351,6 +352,12 @@ public class CarryConfig
) )
public boolean facePlayer = false; public boolean facePlayer = false;
@Property(
type = PropertyType.BOOLEAN,
description = "If Entities should be rotated sideways when carried"
)
public boolean rotateEntitiesSideways = false;
@Property( @Property(
type = PropertyType.BOOLEAN, type = PropertyType.BOOLEAN,
description = "Arms should render on sides when carrying. Set to false if you experience issues with mods that replace the player model (like MoBends, etc)" description = "Arms should render on sides when carrying. Set to false if you experience issues with mods that replace the player model (like MoBends, etc)"

View File

@ -22,7 +22,7 @@ package tschipp.carryon.common.config;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
@ -119,8 +119,8 @@ public class ListHandler {
ALLOWED_TILES_TAGS.clear(); ALLOWED_TILES_TAGS.clear();
PROPERTY_EXCEPTION_CLASSES.clear(); PROPERTY_EXCEPTION_CLASSES.clear();
Map<ResourceLocation, TagKey<Block>> blocktags = BuiltInRegistries.BLOCK.listTagIds().collect(Collectors.toMap(t -> t.location(), t -> t)); Map<Identifier, TagKey<Block>> blocktags = BuiltInRegistries.BLOCK.listTagIds().collect(Collectors.toMap(t -> t.location(), t -> t));
Map<ResourceLocation, TagKey<EntityType<?>>> entitytags = BuiltInRegistries.ENTITY_TYPE.listTagIds().collect(Collectors.toMap(t -> t.location(), t -> t)); Map<Identifier, TagKey<EntityType<?>>> entitytags = BuiltInRegistries.ENTITY_TYPE.listTagIds().collect(Collectors.toMap(t -> t.location(), t -> t));
List<String> forbidden = new ArrayList<>(List.of(Constants.COMMON_CONFIG.blacklist.forbiddenTiles)); List<String> forbidden = new ArrayList<>(List.of(Constants.COMMON_CONFIG.blacklist.forbiddenTiles));
forbidden.add("#carryon:block_blacklist"); forbidden.add("#carryon:block_blacklist");
@ -152,7 +152,7 @@ public class ListHandler {
continue; continue;
String name = propString.substring(0, propString.indexOf("[")); String name = propString.substring(0, propString.indexOf("["));
String props = propString.substring(propString.indexOf("[") + 1, propString.indexOf("]")); String props = propString.substring(propString.indexOf("[") + 1, propString.indexOf("]"));
Block blk = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(name)).get().value(); Block blk = BuiltInRegistries.BLOCK.get(Identifier.parse(name)).get().value();
for(String propName : props.split(",")) { for(String propName : props.split(",")) {
for (Property<?> prop : blk.defaultBlockState().getProperties()) { for (Property<?> prop : blk.defaultBlockState().getProperties()) {
if (prop.getName().equals(propName)) if (prop.getName().equals(propName))
@ -162,16 +162,16 @@ public class ListHandler {
} }
} }
private static <T> void addTag(String tag, Map<ResourceLocation, TagKey<T>> tagMap, List<TagKey<T>> tags) { private static <T> void addTag(String tag, Map<Identifier, TagKey<T>> tagMap, List<TagKey<T>> tags) {
String sub = tag.substring(1); String sub = tag.substring(1);
TagKey<T> t = tagMap.get(ResourceLocation.parse(sub)); TagKey<T> t = tagMap.get(Identifier.parse(sub));
if (t != null) if (t != null)
tags.add(t); tags.add(t);
} }
private static <T> void addWithWildcards(List<String> entries, Set<String> toAddTo, Registry<T> registry, Map<ResourceLocation, TagKey<T>> tags, List<TagKey<T>> toAddTags) { private static <T> void addWithWildcards(List<String> entries, Set<String> toAddTo, Registry<T> registry, Map<Identifier, TagKey<T>> tags, List<TagKey<T>> toAddTags) {
ResourceLocation[] keys = registry.keySet().toArray(new ResourceLocation[0]); Identifier[] keys = registry.keySet().toArray(new Identifier[0]);
for (int i = 0; i < entries.size(); i++) for (int i = 0; i < entries.size(); i++)
{ {
String curr = entries.get(i); String curr = entries.get(i);
@ -181,7 +181,7 @@ public class ListHandler {
{ {
String[] filter = curr.replace("*", ",").split(","); String[] filter = curr.replace("*", ",").split(",");
for (ResourceLocation key : keys) for (Identifier key : keys)
{ {
if (containsAll(key.toString(), filter)) if (containsAll(key.toString(), filter))

View File

@ -39,12 +39,13 @@ public record CarryOnScript(
ScriptObject scriptObject, ScriptObject scriptObject,
ScriptConditions scriptConditions, ScriptConditions scriptConditions,
ScriptRender scriptRender, ScriptRender scriptRender,
ScriptEffects scriptEffects) ScriptEffects scriptEffects,
boolean overrideChecks)
{ {
public boolean isValid() public boolean isValid()
{ {
return (isBlock() ^ isEntity()) && (scriptConditions != ScriptConditions.EMPTY || scriptRender != ScriptRender.EMPTY || scriptEffects != ScriptEffects.EMPTY); return (isBlock() ^ isEntity()) && (scriptConditions != ScriptConditions.EMPTY || scriptRender != ScriptRender.EMPTY || scriptEffects != ScriptEffects.EMPTY || overrideChecks);
} }
public boolean isBlock() public boolean isBlock()
@ -63,7 +64,8 @@ public record CarryOnScript(
ScriptObject.CODEC.fieldOf("object").forGetter(CarryOnScript::scriptObject), ScriptObject.CODEC.fieldOf("object").forGetter(CarryOnScript::scriptObject),
ScriptConditions.CODEC.optionalFieldOf("conditions", ScriptConditions.EMPTY).forGetter(CarryOnScript::scriptConditions), ScriptConditions.CODEC.optionalFieldOf("conditions", ScriptConditions.EMPTY).forGetter(CarryOnScript::scriptConditions),
ScriptRender.CODEC.optionalFieldOf("render", ScriptRender.EMPTY).forGetter(CarryOnScript::scriptRender), ScriptRender.CODEC.optionalFieldOf("render", ScriptRender.EMPTY).forGetter(CarryOnScript::scriptRender),
ScriptEffects.CODEC.optionalFieldOf("effects", ScriptEffects.EMPTY).forGetter(CarryOnScript::scriptEffects) ScriptEffects.CODEC.optionalFieldOf("effects", ScriptEffects.EMPTY).forGetter(CarryOnScript::scriptEffects),
Codec.BOOL.optionalFieldOf("override_checks", false).forGetter(CarryOnScript::overrideChecks)
).apply(instance, CarryOnScript::new) ).apply(instance, CarryOnScript::new)
); );

View File

@ -22,23 +22,23 @@ package tschipp.carryon.common.scripting;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.advancements.Advancement;
import net.minecraft.advancements.AdvancementHolder; import net.minecraft.advancements.AdvancementHolder;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.NbtUtils;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.server.ServerAdvancementManager; import net.minecraft.server.ServerAdvancementManager;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraft.world.scores.Objective; import net.minecraft.world.scores.Objective;
import net.minecraft.world.scores.Score;
import net.minecraft.world.scores.Scoreboard; import net.minecraft.world.scores.Scoreboard;
import tschipp.carryon.platform.Services; import tschipp.carryon.platform.Services;
import java.util.*; import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
public final class Matchables public final class Matchables
{ {
@ -127,8 +127,8 @@ public final class Matchables
@Override @Override
public boolean matches(ServerPlayer player) public boolean matches(ServerPlayer player)
{ {
ServerAdvancementManager manager = player.server.getAdvancements(); ServerAdvancementManager manager = player.level().getServer().getAdvancements();
AdvancementHolder adv = manager.get(ResourceLocation.parse(advancement.isEmpty() ? "" : advancement)); AdvancementHolder adv = manager.get(Identifier.parse(advancement.isEmpty() ? "" : advancement));
boolean achievement = adv == null ? true : player.getAdvancements().getOrStartProgress(adv).isDone(); boolean achievement = adv == null ? true : player.getAdvancements().getOrStartProgress(adv).isDone();
return achievement; return achievement;
@ -167,7 +167,7 @@ public final class Matchables
if (cond == null || cond.isEmpty()) if (cond == null || cond.isEmpty())
return true; return true;
Scoreboard score = player.getScoreboard(); Scoreboard score = player.level().getScoreboard();
String numb; String numb;
String scorename; String scorename;
int iE = cond.indexOf("="); int iE = cond.indexOf("=");

View File

@ -23,11 +23,13 @@ package tschipp.carryon.common.scripting;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.TagValueOutput;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.common.scripting.CarryOnScript.ScriptObject.ScriptObjectBlock; import tschipp.carryon.common.scripting.CarryOnScript.ScriptObject.ScriptObjectBlock;
import tschipp.carryon.common.scripting.CarryOnScript.ScriptObject.ScriptObjectEntity; import tschipp.carryon.common.scripting.CarryOnScript.ScriptObject.ScriptObjectEntity;
@ -67,8 +69,9 @@ public class ScriptManager
float height = entity.getBbHeight(); float height = entity.getBbHeight();
float width = entity.getBbWidth(); float width = entity.getBbWidth();
float health = entity instanceof LivingEntity ? ((LivingEntity) entity).getHealth() : 0.0f; float health = entity instanceof LivingEntity ? ((LivingEntity) entity).getHealth() : 0.0f;
CompoundTag tag = new CompoundTag(); TagValueOutput output = TagValueOutput.createWithContext(new ProblemReporter.ScopedCollector(Constants.LOG), entity.registryAccess());
entity.save(tag); entity.save(output);
CompoundTag tag = output.buildResult();
for (CarryOnScript script : SCRIPTS) for (CarryOnScript script : SCRIPTS)
{ {

View File

@ -20,28 +20,21 @@
package tschipp.carryon.common.scripting; package tschipp.carryon.common.scripting;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult; import com.mojang.serialization.DataResult;
import com.mojang.serialization.JsonOps;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.resources.FileToIdConverter; import net.minecraft.resources.FileToIdConverter;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener;
import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.util.profiling.ProfilerFiller;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.networking.clientbound.ClientboundSyncScriptsPacket; import tschipp.carryon.networking.clientbound.ClientboundSyncScriptsPacket;
import tschipp.carryon.platform.Services; import tschipp.carryon.platform.Services;
import java.util.Collections;
import java.util.Map; import java.util.Map;
public class ScriptReloadListener extends SimpleJsonResourceReloadListener<CarryOnScript> public class ScriptReloadListener extends SimpleJsonResourceReloadListener<CarryOnScript>
@ -52,7 +45,7 @@ public class ScriptReloadListener extends SimpleJsonResourceReloadListener<Carry
} }
@Override @Override
protected void apply(Map<ResourceLocation, CarryOnScript> scripts, @NotNull ResourceManager resourceManager, @NotNull ProfilerFiller profilerFiller) protected void apply(Map<Identifier, CarryOnScript> scripts, @NotNull ResourceManager resourceManager, @NotNull ProfilerFiller profilerFiller)
{ {
ScriptManager.SCRIPTS.clear(); ScriptManager.SCRIPTS.clear();

View File

@ -4,13 +4,11 @@ import me.shedaniel.clothconfig2.api.ConfigBuilder;
import me.shedaniel.clothconfig2.api.ConfigCategory; import me.shedaniel.clothconfig2.api.ConfigCategory;
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder; import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
import me.shedaniel.clothconfig2.impl.builders.SubCategoryBuilder; import me.shedaniel.clothconfig2.impl.builders.SubCategoryBuilder;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import tschipp.carryon.config.AnnotationData; import tschipp.carryon.config.AnnotationData;
import tschipp.carryon.config.BuiltCategory; import tschipp.carryon.config.BuiltCategory;
import tschipp.carryon.config.BuiltConfig; import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.ConfigLoader;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.List; import java.util.List;
@ -22,7 +20,7 @@ public record ClothConfigCompat(BuiltConfig client, BuiltConfig common, Runnable
public static Screen getConfigScreen(BuiltConfig client, BuiltConfig common, Screen parentScreen, Runnable onSave) { public static Screen getConfigScreen(BuiltConfig client, BuiltConfig common, Screen parentScreen, Runnable onSave) {
ConfigBuilder builder = ConfigBuilder.create() ConfigBuilder builder = ConfigBuilder.create()
.setParentScreen(parentScreen) .setParentScreen(parentScreen)
.setTitle(Component.translatable("key.carry.category")); .setTitle(Component.translatable("key.category.carryon.key.carry.category"));
buildConfigType(client, builder, "Client Config"); buildConfigType(client, builder, "Client Config");
buildConfigType(common, builder, "Common Config"); buildConfigType(common, builder, "Common Config");

View File

@ -0,0 +1,29 @@
package tschipp.carryon.mixin;
import net.minecraft.client.entity.ClientAvatarEntity;
import net.minecraft.client.model.player.PlayerModel;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.EntityRendererProvider.Context;
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
import net.minecraft.client.renderer.entity.player.AvatarRenderer;
import net.minecraft.client.renderer.entity.state.AvatarRenderState;
import net.minecraft.world.entity.Avatar;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import tschipp.carryon.client.render.CarryingItemRenderLayer;
@Mixin(AvatarRenderer.class)
public abstract class AvatarRendererMixin<AvatarlikeEntity extends Avatar & ClientAvatarEntity> extends LivingEntityRenderer<AvatarlikeEntity, AvatarRenderState, PlayerModel> {
public AvatarRendererMixin(Context context, PlayerModel model, float shadowRadius) {
super(context, model, shadowRadius);
}
@Inject(method = "<init>(Lnet/minecraft/client/renderer/entity/EntityRendererProvider$Context;Z)V", at = @At("RETURN"))
public void init(EntityRendererProvider.Context context, boolean slim, CallbackInfo info) {
//Player
this.addLayer(new CarryingItemRenderLayer<>(this));
}
}

View File

@ -20,6 +20,7 @@
package tschipp.carryon.mixin; package tschipp.carryon.mixin;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@ -47,6 +48,13 @@ public abstract class EntityMixin
@Shadow @Shadow
public boolean hasPassenger(Entity pEntity) {throw new IllegalStateException("EntityMixin application failed");} public boolean hasPassenger(Entity pEntity) {throw new IllegalStateException("EntityMixin application failed");}
@ModifyExpressionValue(method = "startRiding(Lnet/minecraft/world/entity/Entity;ZZ)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EntityType;canSerialize()Z"))
private boolean onStartRidingCheck(boolean original, Entity entity, boolean force) {
if (force && entity instanceof Player) return true;
return original;
}
@Shadow public abstract void onPassengerTurned(Entity $$0); @Shadow public abstract void onPassengerTurned(Entity $$0);
@Inject(method = "positionRider(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/entity/Entity$MoveFunction;)V", at = @At("HEAD"), cancellable = true) @Inject(method = "positionRider(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/entity/Entity$MoveFunction;)V", at = @At("HEAD"), cancellable = true)
@ -85,7 +93,7 @@ public abstract class EntityMixin
@Inject(method = "onPassengerTurned(Lnet/minecraft/world/entity/Entity;)V", at = @At("HEAD")) @Inject(method = "onPassengerTurned(Lnet/minecraft/world/entity/Entity;)V", at = @At("HEAD"))
private void onPassengerTurned(Entity toUpdate, CallbackInfo ci) private void onPassengerTurned(Entity toUpdate, CallbackInfo ci)
{ {
if((Object)this instanceof Player thisPlayer && toUpdate instanceof Player otherPlayer) if((Object)this instanceof Player thisPlayer && toUpdate instanceof Player)
{ {
CarryOnData carry = CarryOnDataManager.getCarryData(thisPlayer); CarryOnData carry = CarryOnDataManager.getCarryData(thisPlayer);
if(carry.isCarrying(CarryType.PLAYER)) { if(carry.isCarrying(CarryType.PLAYER)) {

View File

@ -23,13 +23,14 @@ public class EntityRendererMixin {
shift = At.Shift.AFTER shift = At.Shift.AFTER
), method = "createRenderState(Lnet/minecraft/world/entity/Entity;F)Lnet/minecraft/client/renderer/entity/state/EntityRenderState;") ), method = "createRenderState(Lnet/minecraft/world/entity/Entity;F)Lnet/minecraft/client/renderer/entity/state/EntityRenderState;")
private void onCreateRenderState(Entity entity, float $$1, CallbackInfoReturnable<EntityRenderState> cir, @Local(ordinal = 0) EntityRenderState state) { private void onCreateRenderState(Entity entity, float $$1, CallbackInfoReturnable<EntityRenderState> cir, @Local(ordinal = 0) EntityRenderState state) {
if (entity instanceof Player player) { if (entity instanceof Player player) {
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
ICarryOnRenderState carryOnRenderState = (ICarryOnRenderState) state; ICarryOnRenderState carryOnRenderState = (ICarryOnRenderState) state;
carryOnRenderState.setCarryOnData(carry); carryOnRenderState.setCarryOnData(carry);
carryOnRenderState.setRenderWidth(CarryRenderHelper.getRenderWidth(player)); carryOnRenderState.setRenderWidth(CarryRenderHelper.getRenderWidth(player));
carryOnRenderState.setPlayer(player);
} }
} }
} }

View File

@ -23,7 +23,6 @@ package tschipp.carryon.mixin;
import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.HumanoidModel;
import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.renderer.entity.state.HumanoidRenderState; import net.minecraft.client.renderer.entity.state.HumanoidRenderState;
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@ -51,7 +50,7 @@ public class HumanoidModelMixin {
if(state instanceof ICarryOnRenderState carryOnRenderState && Constants.CLIENT_CONFIG.renderArms) if(state instanceof ICarryOnRenderState carryOnRenderState && Constants.CLIENT_CONFIG.renderArms)
{ {
CarryOnData carry = carryOnRenderState.getCarryOnData(); CarryOnData carry = carryOnRenderState.getCarryOnData();
if(carry.isCarrying() && !state.isVisuallySwimming && !state.isFallFlying) if(carry != null && carry.isCarrying() && !state.isVisuallySwimming && !state.isFallFlying)
{ {
boolean sneaking = state.isCrouching; boolean sneaking = state.isCrouching;

View File

@ -32,8 +32,8 @@ import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnDataManager; import tschipp.carryon.common.carry.CarryOnDataManager;
@Mixin(Inventory.class) @Mixin(Inventory.class)
@ -76,10 +76,11 @@ public class InventoryMixin
info.cancel(); info.cancel();
} }
@Inject(method = "setSelectedHotbarSlot(I)V", at = @At("HEAD"), cancellable = true) @Inject(method = "setSelectedSlot(I)V", at = @At("HEAD"), cancellable = true)
private void onSwapPaint(int $$0, CallbackInfo info) private void onSwapPaint(int slot, CallbackInfo info)
{ {
if(CarryOnDataManager.getCarryData(player).isCarrying()) CarryOnData data = CarryOnDataManager.getCarryData(player);
if(data.isCarrying() && data.getSelected() != slot)
info.cancel(); info.cancel();
} }
} }

View File

@ -25,15 +25,27 @@ import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import tschipp.carryon.common.carry.CarryOnDataManager; import tschipp.carryon.common.carry.CarryOnDataManager;
@Mixin(Minecraft.class) @Mixin(Minecraft.class)
public class MinecraftMixin public class MinecraftMixin {
{
@WrapWithCondition(method = "handleKeybinds()V", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/player/Inventory;selected:I", ordinal = 0, opcode = 181)) //Opcode for PUTFIELD @WrapWithCondition(
private boolean allowSlotSelection(Inventory inv,int slot) method = "handleKeybinds()V",
{ at = @At(
return !CarryOnDataManager.getCarryData(inv.player).isCarrying(); value = "INVOKE",
} target = "Lnet/minecraft/world/entity/player/Inventory;setSelectedSlot(I)V",
ordinal = 0
)
)
private boolean allowSlotSelection(Inventory inv, int slot) {
boolean carrying = CarryOnDataManager.getCarryData(inv.player).isCarrying();
// Allow if not carrying
if (!carrying) return true;
// Block only if trying to switch away
return inv.getSelectedSlot() == slot;
}
} }

View File

@ -20,76 +20,49 @@
package tschipp.carryon.mixin; package tschipp.carryon.mixin;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.Entity;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.storage.ValueInput;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnData.CarryType;
import tschipp.carryon.common.carry.CarryOnDataManager; import tschipp.carryon.common.carry.CarryOnDataManager;
import java.util.Optional;
@Mixin(Player.class) @Mixin(Player.class)
public abstract class PlayerMixin extends LivingEntity implements CarryOnDataManager.ICarrying { public abstract class PlayerMixin extends LivingEntity {
@Unique
private static final EntityDataAccessor<CompoundTag> CARRY_DATA_KEY = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG);
@Override
public void setCarryOnData(CarryOnData data)
{
data.setSelected(this.getInventory().selected);
CompoundTag nbt = data.getNbt();
nbt.putInt("tick", tickCount);
this.getEntityData().set(CARRY_DATA_KEY, nbt);
}
@Override
public CarryOnData getCarryOnData()
{
CompoundTag data = this.getEntityData().get(CARRY_DATA_KEY);
return new CarryOnData(data.copy());
}
@Shadow
public abstract Inventory getInventory();
private PlayerMixin(EntityType<? extends LivingEntity> type, Level level) { private PlayerMixin(EntityType<? extends LivingEntity> type, Level level) {
super(type, level); super(type, level);
} }
//We leave this in here to ensure cross-compatibility if world are upgraded from <1.21.8. Should be removed in the future.
@Inject(method = "defineSynchedData(Lnet/minecraft/network/syncher/SynchedEntityData$Builder;)V", at = @At("RETURN")) @Inject(method = "readAdditionalSaveData(Lnet/minecraft/world/level/storage/ValueInput;)V", at = @At("RETURN"))
private void onDefineSynchedData(SynchedEntityData.Builder builder, CallbackInfo ci) { private void onReadAdditionalSaveData(ValueInput input, CallbackInfo ci)
builder.define(CARRY_DATA_KEY, new CompoundTag()); {
Optional<CarryOnData> res = input.read("CarryOnData", CarryOnData.CODEC);
res.ifPresent(data -> CarryOnDataManager.setCarryData((Player)((Object)this), data));
} }
@Inject(method = "addAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("RETURN")) @Override
private void onAddAdditionalSaveData(CompoundTag tag, CallbackInfo info) public void stopRiding() {
{ Entity entity = this.getVehicle();
CarryOnData carry = CarryOnDataManager.getCarryData((Player)(Object)this); if (entity instanceof Player && entity.getPassengers().size() < 2){
tag.put("CarryOnData", carry.getNbt()); CarryOnData carry = CarryOnDataManager.getCarryData((Player) entity);
} if (carry.getType() == CarryType.PLAYER){
carry.clear();
@Inject(method = "readAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("RETURN")) ((Player) entity).removeEffect(MobEffects.SLOWNESS);
private void onReadAdditionalSaveData(CompoundTag tag, CallbackInfo info) }
{
if (tag.contains("CarryOnData")) {
CarryOnData data = new CarryOnData(tag.getCompound("CarryOnData"));
setCarryOnData(data);
} }
super.stopRiding();
} }
} }

View File

@ -1,12 +1,13 @@
package tschipp.carryon.mixin; package tschipp.carryon.mixin;
import net.minecraft.client.renderer.entity.state.PlayerRenderState; import net.minecraft.client.renderer.entity.state.HumanoidRenderState;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
import tschipp.carryon.client.render.ICarryOnRenderState; import tschipp.carryon.client.render.ICarryOnRenderState;
import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.common.carry.CarryOnData;
@Mixin(PlayerRenderState.class) @Mixin(HumanoidRenderState.class)
public class PlayerRenderStateMixin implements ICarryOnRenderState { public class PlayerRenderStateMixin implements ICarryOnRenderState {
@Unique @Unique
@ -15,6 +16,10 @@ public class PlayerRenderStateMixin implements ICarryOnRenderState {
@Unique @Unique
public float renderWidth = 0f; public float renderWidth = 0f;
@Unique
public Player player = null;
@Unique @Unique
@Override @Override
public CarryOnData getCarryOnData() { public CarryOnData getCarryOnData() {
@ -38,4 +43,14 @@ public class PlayerRenderStateMixin implements ICarryOnRenderState {
public void setRenderWidth(float val) { public void setRenderWidth(float val) {
renderWidth = val; renderWidth = val;
} }
@Override
public Player getPlayer() {
return player;
}
@Override
public void setPlayer(Player player) {
this.player = player;
}
} }

View File

@ -20,12 +20,7 @@
package tschipp.carryon.networking; package tschipp.carryon.networking;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
public interface PacketBase extends CustomPacketPayload { public interface PacketBase extends CustomPacketPayload {

View File

@ -0,0 +1,59 @@
/*
* GNU Lesser General Public License v3
* Copyright (C) 2024 Tschipp
* mrtschipp@gmail.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package tschipp.carryon.networking.clientbound;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import tschipp.carryon.Constants;
import tschipp.carryon.networking.PacketBase;
public record ClientboundStartRidingOtherPlayerPacket(int mount, int rider, boolean ride) implements PacketBase
{
public static final StreamCodec<RegistryFriendlyByteBuf, ClientboundStartRidingOtherPlayerPacket> CODEC = StreamCodec.composite(
ByteBufCodecs.INT, ClientboundStartRidingOtherPlayerPacket::mount,
ByteBufCodecs.INT, ClientboundStartRidingOtherPlayerPacket::rider,
ByteBufCodecs.BOOL, ClientboundStartRidingOtherPlayerPacket::ride,
ClientboundStartRidingOtherPlayerPacket::new
);
public static final Type<ClientboundStartRidingOtherPlayerPacket> TYPE = new Type<>(Constants.PACKET_ID_START_RIDING_OTHER);
@Override
public void handle(Player player)
{
Entity mount = player.level().getEntity(this.mount);
Entity rider = player.level().getEntity(this.rider);
if(mount != null && rider != null)
if(ride)
rider.startRiding(mount, true,true);
else
rider.stopRiding();
}
@Override
public Type<ClientboundStartRidingOtherPlayerPacket> type() {
return TYPE;
}
}

View File

@ -20,12 +20,10 @@
package tschipp.carryon.networking.clientbound; package tschipp.carryon.networking.clientbound;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;

View File

@ -1,6 +0,0 @@
package tschipp.carryon.networking.clientbound;
import tschipp.carryon.common.carry.CarryOnData;
public record ClientboundSyncCarryDataPacket(CarryOnData data) {
}

View File

@ -22,16 +22,12 @@ package tschipp.carryon.networking.clientbound;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult; import com.mojang.serialization.DataResult;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.common.scripting.CarryOnScript; import tschipp.carryon.common.scripting.CarryOnScript;

View File

@ -20,20 +20,15 @@
package tschipp.carryon.networking.serverbound; package tschipp.carryon.networking.serverbound;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnDataManager; import tschipp.carryon.common.carry.CarryOnDataManager;
import tschipp.carryon.networking.PacketBase; import tschipp.carryon.networking.PacketBase;
import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket;
import tschipp.carryon.networking.clientbound.ClientboundSyncScriptsPacket;
public record ServerboundCarryKeyPressedPacket(boolean pressed) implements PacketBase public record ServerboundCarryKeyPressedPacket(boolean pressed) implements PacketBase
{ {

View File

@ -20,19 +20,18 @@
package tschipp.carryon.platform.services; package tschipp.carryon.platform.services;
import net.minecraft.core.HolderLookup;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.config.BuiltConfig; import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.networking.PacketBase; import tschipp.carryon.networking.PacketBase;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Function;
public interface IPlatformHelper { public interface IPlatformHelper {
@ -64,7 +63,17 @@ public interface IPlatformHelper {
<T extends PacketBase, B extends FriendlyByteBuf> void registerClientboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args); <T extends PacketBase, B extends FriendlyByteBuf> void registerClientboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args);
void sendPacketToServer(ResourceLocation id, PacketBase packet); void sendPacketToServer(Identifier id, PacketBase packet);
void sendPacketToPlayer(Identifier id, PacketBase packet, ServerPlayer player);
default void sendPacketToAllPlayers(Identifier id, PacketBase packet, ServerLevel level) {
for(ServerPlayer p : level.players())
sendPacketToPlayer(id, packet, p);
}
CarryOnData getCarryData(Player player);
void setCarryData(Player player, CarryOnData data);
void sendPacketToPlayer(ResourceLocation id, PacketBase packet, ServerPlayer player);
} }

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "Benutzerdefinierte Bedingungen für Entitäten", "carryon.category.custompickupconditions.custompickupconditionsentities": "Benutzerdefinierte Bedingungen für Entitäten",
"key.carry.desc": "Carry", "key.carry.desc": "Carry",
"key.carry.category": "Carry On" "key.category.carryon.key.carry.category": "Carry On"
} }

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "suoᴉʇᴉpuoƆ dnʞɔᴉԀ ʎʇᴉʇuƎ ɯoʇsnƆ", "carryon.category.custompickupconditions.custompickupconditionsentities": "suoᴉʇᴉpuoƆ dnʞɔᴉԀ ʎʇᴉʇuƎ ɯoʇsnƆ",
"key.carry.desc": "ʎɹɹɐƆ", "key.carry.desc": "ʎɹɹɐƆ",
"key.carry.category": "uO ʎɹɹɐƆ" "key.category.carryon.key.carry.category": "uO ʎɹɹɐƆ"
} }

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "Custom Entity Pickup Conditions", "carryon.category.custompickupconditions.custompickupconditionsentities": "Custom Entity Pickup Conditions",
"key.carry.desc": "Carry", "key.carry.desc": "Carry",
"key.carry.category": "Carry On" "key.category.carryon.key.carry.category": "Carry On"
} }

View File

@ -0,0 +1,16 @@
{
"carryon.category.settings": "Configuraciones",
"carryon.category.blacklist": "Lista Negra",
"carryon.category.modeloverrides": "Reemplazos de Modelos (Avanzado)",
"carryon.category.custompickupconditions": "Condiciones Personalizadas de Recogida (Avanzado)",
"carryon.category.whitelist": "Lista Blanca",
"carryon.general.modeloverrides.modeloverrides": "Reemplazos de Modelos",
"carryon.general.blacklist.forbiddenentities": "Entidades que el jugador no puede levantar",
"carryon.general.blacklist.forbiddentiles": "Bloques que el jugador no puede levantar",
"carryon.category.custompickupconditions.custompickupconditionsblocks": "Condiciones Personalizadas de Recogida de Bloques",
"carryon.category.custompickupconditions.custompickupconditionsentities": "Condiciones Personalizadas de Recogida de Entidades",
"key.carry.desc": "Cargar",
"key.category.carryon.key.carry.category": "Carry On"
}

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "Condiciones Personalizadas para Recoger Entidades", "carryon.category.custompickupconditions.custompickupconditionsentities": "Condiciones Personalizadas para Recoger Entidades",
"key.carry.desc": "Recoger", "key.carry.desc": "Recoger",
"key.carry.category": "Carry On" "key.category.carryon.key.carry.category": "Carry On"
} }

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "Customizar condiciones para recoger entidades", "carryon.category.custompickupconditions.custompickupconditionsentities": "Customizar condiciones para recoger entidades",
"key.carry.desc": "Agarrar", "key.carry.desc": "Agarrar",
"key.carry.category": "Carry On" "key.category.carryon.key.carry.category": "Carry On"
} }

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "Conditions de ramassage d'entités personalisés", "carryon.category.custompickupconditions.custompickupconditionsentities": "Conditions de ramassage d'entités personalisés",
"key.carry.desc": "Saisir", "key.carry.desc": "Saisir",
"key.carry.category": "Carry On" "key.category.carryon.key.carry.category": "Carry On"
} }

View File

@ -0,0 +1,16 @@
{
"carryon.category.settings": "Beállítások",
"carryon.category.blacklist": "Feketelista",
"carryon.category.modeloverrides": "Model felülírások (Fejlett)",
"carryon.category.custompickupconditions": "Egyedi felvételi feltételek (Fejlett)",
"carryon.category.whitelist": "Fehérlista",
"carryon.general.modeloverrides.modeloverrides": "Model felülírások",
"carryon.general.blacklist.forbiddenentities": "Entitások amiket a játékos nem vehet fel",
"carryon.general.blacklist.forbiddentiles": "Blokkok amiket a játékos nem vehet fel",
"carryon.category.custompickupconditions.custompickupconditionsblocks": "Egyedi blokk felvételi feltételek",
"carryon.category.custompickupconditions.custompickupconditionsentities": "Egyedi entitás felvételi feltételek",
"key.carry.desc": "Cipelés",
"key.category.carryon.key.carry.category": "Carry On"
}

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "Condizioni di prelievo entità personalizzate", "carryon.category.custompickupconditions.custompickupconditionsentities": "Condizioni di prelievo entità personalizzate",
"key.carry.desc": "Afferra", "key.carry.desc": "Afferra",
"key.carry.category": "Carry On Mod" "key.category.carryon.key.carry.category": "Carry On Mod"
} }

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "カスタムエンティティ持ち上げ条件", "carryon.category.custompickupconditions.custompickupconditionsentities": "カスタムエンティティ持ち上げ条件",
"key.carry.desc": "Carry", "key.carry.desc": "Carry",
"key.carry.category": "Carry On" "key.category.carryon.key.carry.category": "Carry On"
} }

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "맞춤형 개체 들기 조건", "carryon.category.custompickupconditions.custompickupconditionsentities": "맞춤형 개체 들기 조건",
"key.carry.desc": "들고 나르기", "key.carry.desc": "들고 나르기",
"key.carry.category": "Carry On" "key.category.carryon.key.carry.category": "Carry On"
} }

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "Пользовательские условия поднятия сущности", "carryon.category.custompickupconditions.custompickupconditionsentities": "Пользовательские условия поднятия сущности",
"key.carry.desc": "Поднять", "key.carry.desc": "Поднять",
"key.carry.category": "Carry On" "key.category.carryon.key.carry.category": "Carry On"
} }

View File

@ -13,5 +13,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "Özel Varlık Alma Durumları", "carryon.category.custompickupconditions.custompickupconditionsentities": "Özel Varlık Alma Durumları",
"key.carry.desc": "Taşı", "key.carry.desc": "Taşı",
"key.carry.category": "Carry On" "key.category.carryon.key.carry.category": "Carry On"
} }

View File

@ -0,0 +1,16 @@
{
"carryon.category.settings": "Налаштування",
"carryon.category.blacklist": "Чорний список",
"carryon.category.modeloverrides": "Перевизначення моделей (Розширені)",
"carryon.category.custompickupconditions": "Користувацькі умови підбору (Розширені)",
"carryon.category.whitelist": "Білий список",
"carryon.general.modeloverrides.modeloverrides": "Перевизначення моделей",
"carryon.general.blacklist.forbiddenentities": "Сутності, які гравець не може підібрати",
"carryon.general.blacklist.forbiddentiles": "Блоки, які гравець не може підібрати",
"carryon.category.custompickupconditions.custompickupconditionsblocks": "Користувацькі умови підбору блоків",
"carryon.category.custompickupconditions.custompickupconditionsentities": "Користувацькі умови підбору сутностей",
"key.carry.desc": "Нести",
"key.category.carryon.key.carry.category": "Carry On"
}

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "自定义抱起实体条件", "carryon.category.custompickupconditions.custompickupconditionsentities": "自定义抱起实体条件",
"key.carry.desc": "抱起", "key.carry.desc": "抱起",
"key.carry.category": "搬运" "key.category.carryon.key.carry.category": "搬运"
} }

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "自訂實體拾取條件", "carryon.category.custompickupconditions.custompickupconditionsentities": "自訂實體拾取條件",
"key.carry.desc": "攜帶", "key.carry.desc": "攜帶",
"key.carry.category": "Carry On" "key.category.carryon.key.carry.category": "Carry On"
} }

View File

@ -9,10 +9,11 @@
"PlayerMixin" "PlayerMixin"
], ],
"client": [ "client": [
"AvatarRendererMixin",
"EntityRendererMixin",
"HumanoidModelMixin", "HumanoidModelMixin",
"MinecraftMixin", "MinecraftMixin",
"PlayerRenderStateMixin", "PlayerRenderStateMixin"
"EntityRendererMixin"
], ],
"server": [ "server": [
], ],
@ -20,5 +21,5 @@
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1
}, },
"refmap": "${refmap_target}refmap.json" "refmap": "${mod_id}.refmap.json"
} }

View File

@ -1,35 +1,24 @@
plugins { plugins {
id 'java' id 'multiloader-loader'
id 'maven-publish' id 'fabric-loom' version "${loom_version}"
id 'idea'
id 'fabric-loom' version '1.8-SNAPSHOT'
}
base {
archivesName = "${mod_id}-fabric-${minecraft_version}"
}
/*
apply from: 'https://raw.githubusercontent.com/MinecraftModDevelopment/Gradle-Collection/22e7d543a18cd30675277fbfa3669e3d9e206010/generic/secrets.gradle'
if (project.hasProperty('secretFile')) {
loadSecrets(new File((String) findProperty('secretFile')))
}
*/
if (System.getenv('BUILD_NUMBER') != null) {
version += "." + System.getenv('BUILD_NUMBER')
} }
repositories { repositories {
maven { maven {
url "https://maven.siphalor.de/" name = "Shedaniel"
name "Siphalor's Maven" url "https://maven.shedaniel.me/"
} }
maven { url "https://maven.terraformersmc.com/releases/" } maven { url 'https://jitpack.io' }
maven {
name = "Terraformers"
url = "https://maven.terraformersmc.com/"
}
} }
dependencies { dependencies {
minecraft "com.mojang:minecraft:${minecraft_version}" minecraft "com.mojang:minecraft:${minecraft_version}"
mappings loom.layered() { mappings loom.layered() {
@ -39,19 +28,17 @@ dependencies {
modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}" modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}"
implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1' implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1'
implementation project(":Common")
//modRuntimeOnly "de.siphalor:amecsapi-1.20:1.5.6+mc1.20.2"
modApi("me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}") { modApi("me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}") {
exclude(group: "net.fabricmc.fabric-api") exclude(group: "net.fabricmc.fabric-api")
} }
modApi "com.terraformersmc:modmenu:13.0.0-beta.1" modApi "com.terraformersmc:modmenu:17.0.0-beta.1"
} }
loom { loom {
if (project(":Common").file("src/main/resources/${mod_id}.accesswidener").exists()) { def aw = project(':Common').file("src/main/resources/${mod_id}.accesswidener")
accessWidenerPath.set(project(":Common").file("src/main/resources/${mod_id}.accesswidener")) if (aw.exists()) {
accessWidenerPath.set(aw)
} }
mixin { mixin {
defaultRefmapName.set("${mod_id}.refmap.json") defaultRefmapName.set("${mod_id}.refmap.json")
@ -71,31 +58,3 @@ loom {
} }
} }
} }
tasks.withType(JavaCompile).configureEach {
source(project(":Common").sourceSets.main.allSource)
}
tasks.withType(Javadoc).configureEach {
source(project(":Common").sourceSets.main.allJava)
}
tasks.named("sourcesJar", Jar) {
from(project(":Common").sourceSets.main.allSource)
}
processResources {
from project(":Common").sourceSets.main.resources
}
publishing {
publications {
mavenJava(MavenPublication) {
artifactId base.archivesName.get()
from components.java
}
}
repositories {
maven {
url "file://" + System.getenv("local_maven")
}
}
}

View File

@ -23,20 +23,13 @@ package tschipp.carryon;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.core.RegistryAccess;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import tschipp.carryon.client.keybinds.CarryOnKeybinds; import tschipp.carryon.client.keybinds.CarryOnKeybinds;
import tschipp.carryon.events.ClientEvents; import tschipp.carryon.events.ClientEvents;
import tschipp.carryon.networking.PacketBase; import tschipp.carryon.networking.PacketBase;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Function;
public class CarryOnFabricClientMod implements ClientModInitializer public class CarryOnFabricClientMod implements ClientModInitializer
{ {

View File

@ -21,13 +21,36 @@
package tschipp.carryon; package tschipp.carryon;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.attachment.v1.AttachmentRegistry;
import net.fabricmc.fabric.api.attachment.v1.AttachmentType;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerPlayer;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.config.fabric.ConfigLoaderImpl; import tschipp.carryon.config.fabric.ConfigLoaderImpl;
import tschipp.carryon.events.CommonEvents; import tschipp.carryon.events.CommonEvents;
import java.io.IOException; import java.io.IOException;
public class CarryOnFabricMod implements ModInitializer { public class CarryOnFabricMod implements ModInitializer {
public static final AttachmentType<CarryOnData> CARRY_ON_DATA_ATTACHMENT_TYPE = AttachmentRegistry.create(
Identifier.fromNamespaceAndPath(Constants.MOD_ID, "carry_on_data"),
builder -> builder
.initializer(() -> new CarryOnData(new CompoundTag()))
.persistent(CarryOnData.CODEC)
.syncWith(CarryOnData.STREAM_CODEC, (t, p) ->{
ServerPlayer player = (ServerPlayer) t;
// the isAlive check avoids us syncing attachment data about dead players. Which causes a disconnect
// player.tickCount > 0 avoids us syncing attachment data about players the instant they spawn.
// Which also causes a disconnect as the player entity may not be synced yet.
return p.connection != null && player.isAlive() && !p.isRemoved() && player.tickCount > 0;
})
);
@Override @Override
public void onInitialize() { public void onInitialize() {

View File

@ -20,7 +20,6 @@
package tschipp.carryon.compat; package tschipp.carryon.compat;
import net.fabricmc.fabric.api.event.Event;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
@ -39,6 +38,7 @@ public class ArchitecturyCompat {
private static Method PLACE_BLOCK; private static Method PLACE_BLOCK;
private static Method IS_FALSE; private static Method IS_FALSE;
@SuppressWarnings("unchecked")
private static void setup( ) { private static void setup( ) {
try { try {
Class BlockEvent = Class.forName("dev.architectury.event.events.common.BlockEvent"); Class BlockEvent = Class.forName("dev.architectury.event.events.common.BlockEvent");

View File

@ -23,8 +23,6 @@ package tschipp.carryon.config.fabric;
import com.google.gson.*; import com.google.gson.*;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import tschipp.carryon.Constants;
import tschipp.carryon.common.config.CarryConfig;
import tschipp.carryon.common.config.ListHandler; import tschipp.carryon.common.config.ListHandler;
import tschipp.carryon.config.*; import tschipp.carryon.config.*;
@ -32,7 +30,10 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.*; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class ConfigLoaderImpl { public class ConfigLoaderImpl {
@ -149,6 +150,7 @@ public class ConfigLoaderImpl {
builder.add(category.category, categoryJson); builder.add(category.category, categoryJson);
} }
@SuppressWarnings("unchecked")
private static void buildProperty(JsonObject builder, PropertyData data) throws IllegalAccessException { private static void buildProperty(JsonObject builder, PropertyData data) throws IllegalAccessException {
AnnotationData annotationData = data.getData(); AnnotationData annotationData = data.getData();
builder.addProperty("//"+data.getId(), annotationData.description()); builder.addProperty("//"+data.getId(), annotationData.description());

View File

@ -20,11 +20,8 @@
package tschipp.carryon.events; package tschipp.carryon.events;
import com.mojang.blaze3d.vertex.PoseStack;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
import tschipp.carryon.CarryOnCommonClient; import tschipp.carryon.CarryOnCommonClient;
import tschipp.carryon.client.render.CarriedObjectRender;
public class ClientEvents { public class ClientEvents {
@ -34,10 +31,6 @@ public class ClientEvents {
CarryOnCommonClient.checkForKeybinds(); CarryOnCommonClient.checkForKeybinds();
CarryOnCommonClient.onCarryClientTick(); CarryOnCommonClient.onCarryClientTick();
}); });
WorldRenderEvents.LAST.register(event -> {
CarriedObjectRender.drawThirdPerson(event.tickCounter().getGameTimeDeltaPartialTick(true), new PoseStack().last().pose());
});
} }
} }

View File

@ -21,11 +21,13 @@
package tschipp.carryon.events; package tschipp.carryon.events;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents; import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.event.player.*; import net.fabricmc.fabric.api.event.player.*;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -54,7 +56,7 @@ public class CommonEvents {
UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> { UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> {
if(world.isClientSide) if(world.isClientSide())
return InteractionResult.PASS; return InteractionResult.PASS;
BlockPos pos = hitResult.getBlockPos(); BlockPos pos = hitResult.getBlockPos();
@ -95,7 +97,7 @@ public class CommonEvents {
UseEntityCallback.EVENT.register((player, level, hand, entity, hitResult) -> { UseEntityCallback.EVENT.register((player, level, hand, entity, hitResult) -> {
if(level.isClientSide) if(level.isClientSide())
return InteractionResult.PASS; return InteractionResult.PASS;
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
@ -131,12 +133,10 @@ public class CommonEvents {
CarryOnCommon.onCarryTick(player); CarryOnCommon.onCarryTick(player);
}); });
ServerPlayerEvents.COPY_FROM.register(((oldPlayer, newPlayer, alive) -> { ServerPlayerEvents.COPY_FROM.register(((oldPlayer, newPlayer, alive) -> {
PlacementHandler.placeCarriedOnDeath(oldPlayer, newPlayer, !alive); PlacementHandler.placeCarriedOnDeath(oldPlayer, newPlayer, !alive);
})); }));
PlayerBlockBreakEvents.BEFORE.register(((world, player, pos, state, blockEntity) -> { PlayerBlockBreakEvents.BEFORE.register(((world, player, pos, state, blockEntity) -> {
if(!CarryOnCommon.onTryBreakBlock(player)) if(!CarryOnCommon.onTryBreakBlock(player))
return false; return false;
@ -155,7 +155,23 @@ public class CommonEvents {
return InteractionResult.PASS; return InteractionResult.PASS;
})); }));
//TODO: drop carried when attacked ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
CarryOnCommon.onRiderDisconnected(handler.getPlayer());
});
ServerLivingEntityEvents.ALLOW_DEATH.register((entity, damageSource, damageAmount) -> {
if(entity instanceof ServerPlayer sp) {
CarryOnCommon.onRiderDisconnected(sp);
}
return true;
});
ServerLivingEntityEvents.ALLOW_DAMAGE.register((entity, source, amount) -> {
if(entity instanceof ServerPlayer sp) {
CarryOnCommon.onPlayerAttacked(sp);
}
return true;
});
} }
} }

View File

@ -21,31 +21,24 @@
package tschipp.carryon.mixin; package tschipp.carryon.mixin;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.ItemInHandRenderer; import net.minecraft.client.renderer.ItemInHandRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.SubmitNodeCollector;
import net.minecraft.client.renderer.RenderBuffers;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import tschipp.carryon.client.render.CarriedObjectRender; import tschipp.carryon.client.render.CarriedObjectRender;
import tschipp.carryon.client.render.CarryRenderHelper;
import tschipp.carryon.platform.Services;
@Mixin(ItemInHandRenderer.class) @Mixin(ItemInHandRenderer.class)
public class ItemInHandRendererMixin public class ItemInHandRendererMixin
{ {
@Inject(at = @At(value = "HEAD"), method = "renderArmWithItem(Lnet/minecraft/client/player/AbstractClientPlayer;FFLnet/minecraft/world/InteractionHand;FLnet/minecraft/world/item/ItemStack;FLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", cancellable = true) @Inject(at = @At(value = "HEAD"), method = "renderArmWithItem(Lnet/minecraft/client/player/AbstractClientPlayer;FFLnet/minecraft/world/InteractionHand;FLnet/minecraft/world/item/ItemStack;FLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;I)V", cancellable = true)
private void onRenderHand(AbstractClientPlayer player, float partialTicks, float pitch, InteractionHand hand, float pSwingProgress, ItemStack pStack, float pEquippedProgress, PoseStack poseStack, MultiBufferSource buffer, int light, CallbackInfo ci) private void renderArmWithItem(AbstractClientPlayer player, float partialTick, float pitch, InteractionHand hand, float swingProgress, ItemStack item, float equippedProgress, PoseStack poseStack, SubmitNodeCollector nodeCollector, int packedLight, CallbackInfo ci)
{ {
if(CarryRenderHelper.getPerspective() == 0 && CarriedObjectRender.drawFirstPerson(player, buffer, poseStack, light, partialTicks)) if(CarriedObjectRender.draw(player, poseStack, packedLight, partialTick,nodeCollector,true))
ci.cancel(); ci.cancel();
} }

View File

@ -34,9 +34,10 @@ import tschipp.carryon.common.carry.CarryOnDataManager;
@Mixin(Screen.class) @Mixin(Screen.class)
public class ScreenMixin public class ScreenMixin
{ {
@Inject(at = @At(value = "TAIL"), method = "init(Lnet/minecraft/client/Minecraft;II)V") @Inject(at = @At(value = "TAIL"), method = "init(II)V")
private void onInit(Minecraft mc, int i, int j, CallbackInfo ci) private void onInit(int width, int height, CallbackInfo ci)
{ {
Minecraft mc = Minecraft.getInstance();
Player player = mc.player; Player player = mc.player;
if((Object)this instanceof AbstractContainerScreen && player != null) if((Object)this instanceof AbstractContainerScreen && player != null)
{ {

View File

@ -20,28 +20,25 @@
package tschipp.carryon.platform; package tschipp.carryon.platform;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking.PlayPayloadHandler;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.codec.StreamDecoder;
import net.minecraft.network.codec.StreamMemberEncoder;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import tschipp.carryon.CarryOnFabricClientMod; import tschipp.carryon.CarryOnFabricClientMod;
import tschipp.carryon.CarryOnFabricMod;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.config.BuiltConfig; import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.fabric.ConfigLoaderImpl; import tschipp.carryon.config.fabric.ConfigLoaderImpl;
import tschipp.carryon.networking.PacketBase; import tschipp.carryon.networking.PacketBase;
import tschipp.carryon.platform.services.IPlatformHelper; import tschipp.carryon.platform.services.IPlatformHelper;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Function;
public class FabricPlatformHelper implements IPlatformHelper { public class FabricPlatformHelper implements IPlatformHelper {
@ -67,6 +64,7 @@ public class FabricPlatformHelper implements IPlatformHelper {
ConfigLoaderImpl.registerConfig(cfg); ConfigLoaderImpl.registerConfig(cfg);
} }
@SuppressWarnings("unchecked")
@Override @Override
public <T extends PacketBase, B extends FriendlyByteBuf> void registerServerboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args) public <T extends PacketBase, B extends FriendlyByteBuf> void registerServerboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args)
{ {
@ -79,6 +77,7 @@ public class FabricPlatformHelper implements IPlatformHelper {
}); });
} }
@SuppressWarnings("unchecked")
@Override @Override
public <T extends PacketBase, B extends FriendlyByteBuf> void registerClientboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args) public <T extends PacketBase, B extends FriendlyByteBuf> void registerClientboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args)
{ {
@ -91,14 +90,25 @@ public class FabricPlatformHelper implements IPlatformHelper {
} }
@Override @Override
public void sendPacketToServer(ResourceLocation id, PacketBase packet) public void sendPacketToServer(Identifier id, PacketBase packet)
{ {
CarryOnFabricClientMod.sendPacketToServer(packet); CarryOnFabricClientMod.sendPacketToServer(packet);
} }
@Override @Override
public void sendPacketToPlayer(ResourceLocation id, PacketBase packet, ServerPlayer player) public void sendPacketToPlayer(Identifier id, PacketBase packet, ServerPlayer player)
{ {
ServerPlayNetworking.send(player, packet); ServerPlayNetworking.send(player, packet);
} }
@Override
public CarryOnData getCarryData(Player player) {
CarryOnData data = player.getAttachedOrCreate(CarryOnFabricMod.CARRY_ON_DATA_ATTACHMENT_TYPE);
return data.clone();
}
@Override
public void setCarryData(Player player, CarryOnData data) {
player.setAttached(CarryOnFabricMod.CARRY_ON_DATA_ATTACHMENT_TYPE, data);
}
} }

View File

@ -21,15 +21,15 @@
package tschipp.carryon.scripting; package tschipp.carryon.scripting;
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.common.scripting.ScriptReloadListener; import tschipp.carryon.common.scripting.ScriptReloadListener;
public class IdentifiableScriptReloadListener extends ScriptReloadListener implements IdentifiableResourceReloadListener public class IdentifiableScriptReloadListener extends ScriptReloadListener implements IdentifiableResourceReloadListener
{ {
@Override @Override
public ResourceLocation getFabricId() public Identifier getFabricId()
{ {
return ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "carryon_scripts"); return Identifier.fromNamespaceAndPath(Constants.MOD_ID, "carryon_scripts");
} }
} }

View File

@ -36,8 +36,8 @@
"depends": { "depends": {
"fabricloader": ">=${fabric_loader_version}", "fabricloader": ">=${fabric_loader_version}",
"fabric-api": "*", "fabric-api": "*",
"minecraft": "${minecraft_version}", "minecraft": "${minecraft_version_range_fabric}",
"java": ">=21" "java": ">=${java_version}"
} }
} }

View File

@ -1,26 +1,10 @@
plugins { plugins {
id 'idea' id 'multiloader-loader'
id 'java' id 'net.minecraftforge.gradle' version '[6.0.46,6.2)'
id 'maven-publish'
id 'net.minecraftforge.gradle' version '[6.0.24,6.2)'
id 'org.spongepowered.mixin' version '0.7-SNAPSHOT' id 'org.spongepowered.mixin' version '0.7-SNAPSHOT'
id 'org.parchmentmc.librarian.forgegradle' version '1.+' id 'org.parchmentmc.librarian.forgegradle' version '1.+'
} }
/*
apply from: 'https://raw.githubusercontent.com/MinecraftModDevelopment/Gradle-Collection/22e7d543a18cd30675277fbfa3669e3d9e206010/generic/secrets.gradle'
if (project.hasProperty('secretFile')) {
loadSecrets(new File((String) findProperty('secretFile')))
}
*/
if (System.getenv('BUILD_NUMBER') != null) {
version += "." + System.getenv('BUILD_NUMBER')
}
base { base {
archivesName = "${mod_id}-forge-${minecraft_version}" archivesName = "${mod_id}-forge-${minecraft_version}"
} }
@ -32,16 +16,25 @@ mixin {
config "${mod_id}.forge.mixins.json" config "${mod_id}.forge.mixins.json"
} }
tasks.named('jar', Jar).configure {
manifest {
attributes([
"MixinConfigs" : "${mod_id}.mixins.json,${mod_id}.forge.mixins.json"
])
}
}
jarJar.enable() jarJar.enable()
build.dependsOn tasks.jarJar build.dependsOn tasks.jarJar
minecraft { minecraft {
mappings channel: 'official', version: "1.21.4" mappings channel: 'parchment', version: parchment_mappings
copyIdeResources = true copyIdeResources = true
reobf = false reobf = false
if (file('src/main/resources/META-INF/accesstransformer.cfg').exists()) { def at = file('src/main/resources/META-INF/accesstransformer.cfg')
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') if (at.exists()) {
accessTransformer = at
} }
runs { runs {
@ -51,6 +44,7 @@ minecraft {
taskName 'Client' taskName 'Client'
property 'mixin.env.remapRefMap', 'true' property 'mixin.env.remapRefMap', 'true'
property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg" property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg"
property 'eventbus.api.strictRuntimeChecks', 'true'
args "-mixin.config=${mod_id}.mixins.json", "-mixin.config=${mod_id}.forge.mixins.json" args "-mixin.config=${mod_id}.mixins.json", "-mixin.config=${mod_id}.forge.mixins.json"
mods { mods {
modClientRun { modClientRun {
@ -66,6 +60,7 @@ minecraft {
taskName 'Server' taskName 'Server'
property 'mixin.env.remapRefMap', 'true' property 'mixin.env.remapRefMap', 'true'
property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg" property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg"
property 'eventbus.api.strictRuntimeChecks', 'true'
args "-mixin.config=${mod_id}.mixins.json", "-mixin.config=${mod_id}.forge.mixins.json" args "-mixin.config=${mod_id}.mixins.json", "-mixin.config=${mod_id}.forge.mixins.json"
mods { mods {
modServerRun { modServerRun {
@ -82,6 +77,7 @@ minecraft {
taskName 'Data' taskName 'Data'
property 'mixin.env.remapRefMap', 'true' property 'mixin.env.remapRefMap', 'true'
property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg" property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg"
property 'eventbus.api.strictRuntimeChecks', 'true'
args "-mixin.config=${mod_id}.mixins.json", "-mixin.config=${mod_id}.forge.mixins.json" args "-mixin.config=${mod_id}.mixins.json", "-mixin.config=${mod_id}.forge.mixins.json"
mods { mods {
modDataRun { modDataRun {
@ -96,17 +92,25 @@ minecraft {
sourceSets.main.resources.srcDir 'src/generated/resources' sourceSets.main.resources.srcDir 'src/generated/resources'
repositories { repositories {
maven {
name = "Shedaniel"
url "https://maven.shedaniel.me/"
}
maven { url 'https://jitpack.io' }
flatDir { flatDir {
dirs 'libs' dirs 'libs'
} }
maven { url 'https://jitpack.io' }
} }
dependencies { dependencies {
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
compileOnly project(":Common") compileOnly project(":Common")
annotationProcessor 'org.spongepowered:mixin:0.8.5-SNAPSHOT:processor' annotationProcessor 'org.spongepowered:mixin:0.8.5-SNAPSHOT:processor'
annotationProcessor 'net.minecraftforge:eventbus-validator:7.0-beta.7'
// Hack fix for now, force jopt-simple to be exactly 5.0.4 because Mojang ships that version, but some transitive dependencies request 6.0+ // Hack fix for now, force jopt-simple to be exactly 5.0.4 because Mojang ships that version, but some transitive dependencies request 6.0+
implementation('net.sf.jopt-simple:jopt-simple:5.0.4') { version { strictly '5.0.4' } } implementation('net.sf.jopt-simple:jopt-simple:5.0.4') { version { strictly '5.0.4' } }
@ -117,7 +121,7 @@ dependencies {
//implementation fg.deobf("net.darkhax.gamestages:GameStages-Forge-1.19.2:11.0.2") //implementation fg.deobf("net.darkhax.gamestages:GameStages-Forge-1.19.2:11.0.2")
implementation(fg.deobf("me.shedaniel.cloth:cloth-config-forge:${cloth_config_version}")) compileOnly(fg.deobf("me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}"))
fileTree("libs").matching { fileTree("libs").matching {
include "*.jar" include "*.jar"
@ -132,47 +136,14 @@ dependencies {
} }
tasks.withType(JavaCompile).configureEach {
source(project(":Common").sourceSets.main.allSource)
}
tasks.withType(Javadoc).configureEach {
source(project(":Common").sourceSets.main.allJava)
}
tasks.named("sourcesJar", Jar) {
from(project(":Common").sourceSets.main.allSource)
}
processResources {
from project(":Common").sourceSets.main.resources
}
tasks.named('jar', Jar).configure {
manifest {
attributes([
"MixinConfigs" : "${mod_id}.mixins.json,${mod_id}.forge.mixins.json"
])
}
}
publishing { publishing {
publications { publications {
mavenJava(MavenPublication) { mavenJava(MavenPublication) {
artifactId base.archivesName.get()
from components.java
fg.component(it) fg.component(it)
} }
} }
repositories {
maven {
url "file://" + System.getenv("local_maven")
}
}
} }
// Merge the resources and classes into the same directory.
// This is done because java expects modules to be in a single directory.
// And if we have it in multiple we have to do performance intensive hacks like having the UnionFileSystem
// This will eventually be migrated to ForgeGradle so modders don't need to manually do it. But that is later.
sourceSets.each { sourceSets.each {
def dir = layout.buildDirectory.dir("sourcesSets/$it.name") def dir = layout.buildDirectory.dir("sourcesSets/$it.name")
it.output.resourcesDir = dir it.output.resourcesDir = dir

View File

@ -20,7 +20,8 @@
package tschipp.carryon; package tschipp.carryon;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
@ -28,6 +29,8 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.network.ChannelBuilder; import net.minecraftforge.network.ChannelBuilder;
import net.minecraftforge.network.SimpleChannel; import net.minecraftforge.network.SimpleChannel;
import tschipp.carryon.config.forge.ConfigLoaderImpl; import tschipp.carryon.config.forge.ConfigLoaderImpl;
import tschipp.carryon.networking.ClientboundSyncCarryDataPacket;
import tschipp.carryon.platform.Services;
@Mod(Constants.MOD_ID) @Mod(Constants.MOD_ID)
@EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) @EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
@ -43,17 +46,23 @@ public class CarryOnForge {
// Use Forge to bootstrap the Common mod. // Use Forge to bootstrap the Common mod.
CarryOnCommon.registerConfig(); CarryOnCommon.registerConfig();
context.getModEventBus().addListener(this::setup);
ConfigLoaderImpl.initialize(context); ConfigLoaderImpl.initialize(context);
} }
private void setup(final FMLCommonSetupEvent event) @SubscribeEvent
public static void setup(final FMLCommonSetupEvent event)
{ {
network = ChannelBuilder.named(ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "carryonpackets")).simpleChannel(); network = ChannelBuilder.named(Identifier.fromNamespaceAndPath(Constants.MOD_ID, "carryonpackets")).simpleChannel();
CarryOnCommon.registerServerPackets(); CarryOnCommon.registerServerPackets();
CarryOnCommon.registerClientPackets(); CarryOnCommon.registerClientPackets();
Services.PLATFORM.registerClientboundPacket(
ClientboundSyncCarryDataPacket.TYPE,
ClientboundSyncCarryDataPacket.class,
ClientboundSyncCarryDataPacket.CODEC,
ClientboundSyncCarryDataPacket::handle
);
} }
} }

View File

@ -0,0 +1,23 @@
package tschipp.carryon.carry;
import net.minecraft.nbt.CompoundTag;
import tschipp.carryon.common.carry.CarryOnData;
public class CarryOnDataCapability implements ICarryOnDataCapability {
private CarryOnData data;
public CarryOnDataCapability() {
this.data = new CarryOnData(new CompoundTag());
}
@Override
public CarryOnData getCarryData() {
return data;
}
@Override
public void setCarryData(CarryOnData data) {
this.data = data;
}
}

View File

@ -0,0 +1,38 @@
package tschipp.carryon.carry;
import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.capabilities.CapabilityToken;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.LazyOptional;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import tschipp.carryon.common.carry.CarryOnData;
public class CarryOnDataCapabilityProvider implements ICapabilitySerializable<CompoundTag> {
public static final Capability<ICarryOnDataCapability> CARRY_ON_DATA_CAPABILITY = CapabilityManager.get(new CapabilityToken<ICarryOnDataCapability>() {});
private final CarryOnDataCapability impl = new CarryOnDataCapability();
private final LazyOptional<ICarryOnDataCapability> opt = LazyOptional.of(() -> impl);
@Override
public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
return cap == CARRY_ON_DATA_CAPABILITY ? opt.cast() : LazyOptional.empty();
}
@Override
public CompoundTag serializeNBT(HolderLookup.Provider registryAccess) {
return (CompoundTag) CarryOnData.CODEC.encodeStart(NbtOps.INSTANCE, impl.getCarryData()).getOrThrow();
}
@Override
public void deserializeNBT(HolderLookup.Provider registryAccess, CompoundTag nbt) {
CarryOnData data = CarryOnData.CODEC.parse(NbtOps.INSTANCE, nbt).getOrThrow();
impl.setCarryData(data);
}
}

View File

@ -0,0 +1,13 @@
package tschipp.carryon.carry;
import net.minecraftforge.common.capabilities.AutoRegisterCapability;
import tschipp.carryon.common.carry.CarryOnData;
@AutoRegisterCapability
public interface ICarryOnDataCapability {
CarryOnData getCarryData();
void setCarryData(CarryOnData data);
}

View File

@ -1,17 +0,0 @@
package tschipp.carryon.compat;
import net.minecraft.client.gui.screens.Screen;
import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.forge.ConfigLoaderImpl;
public class ClothConfigCompatForge {
public static Screen createScreen(BuiltConfig client, BuiltConfig common, Screen screen) {
return ClothConfigCompat.getConfigScreen(client, common, screen, () -> {
ConfigLoaderImpl.saveConfig(client); ConfigLoaderImpl.saveConfig(common);});
}
}

View File

@ -22,34 +22,27 @@ package tschipp.carryon.config.forge;
import com.electronwill.nightconfig.core.AbstractConfig; import com.electronwill.nightconfig.core.AbstractConfig;
import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig;
import net.minecraft.client.Minecraft;
import net.minecraft.server.MinecraftServer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.common.util.LogicalSidedProvider; import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.config.IConfigSpec; import net.minecraftforge.fml.config.IConfigSpec;
import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.event.config.ModConfigEvent; import net.minecraftforge.fml.event.config.ModConfigEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.loading.FMLServiceProvider; import tschipp.carryon.Constants;
import net.minecraftforge.server.ServerLifecycleHooks; import tschipp.carryon.config.AnnotationData;
import tschipp.carryon.config.*; import tschipp.carryon.config.BuiltCategory;
import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.PropertyData;
import java.util.*; import java.util.*;
@Mod.EventBusSubscriber(modid = Constants.MOD_ID)
public class ConfigLoaderImpl { public class ConfigLoaderImpl {
public static final Map<ForgeConfigSpec, BuiltConfig> CONFIGS = new HashMap<>(); public static final Map<ForgeConfigSpec, BuiltConfig> CONFIGS = new HashMap<>();
public static void initialize(FMLJavaModLoadingContext context) { public static void initialize(FMLJavaModLoadingContext context) {
IEventBus bus = context.getModEventBus();
bus.addListener(ConfigLoaderImpl::onConfigLoad);
bus.addListener(ConfigLoaderImpl::onConfigReload);
ConfigLoaderImpl.CONFIGS.forEach((spec, config) -> { ConfigLoaderImpl.CONFIGS.forEach((spec, config) -> {
if(config.fileName.contains("client")) if(config.fileName.contains("client"))
context.registerConfig(ModConfig.Type.CLIENT, spec, config.fileName+".toml"); context.registerConfig(ModConfig.Type.CLIENT, spec, config.fileName+".toml");
@ -58,10 +51,12 @@ public class ConfigLoaderImpl {
}); });
} }
@SubscribeEvent
public static void onConfigLoad(ModConfigEvent.Loading loading) { public static void onConfigLoad(ModConfigEvent.Loading loading) {
loadConfig(loading.getConfig().getSpec()); loadConfig(loading.getConfig().getSpec());
} }
@SubscribeEvent
public static void onConfigReload(ModConfigEvent.Reloading loading) { public static void onConfigReload(ModConfigEvent.Reloading loading) {
loadConfig(loading.getConfig().getSpec()); loadConfig(loading.getConfig().getSpec());
} }
@ -119,6 +114,7 @@ public class ConfigLoaderImpl {
builder.pop(); builder.pop();
} }
@SuppressWarnings("unchecked")
private static void buildProperty(ForgeConfigSpec.Builder builder, PropertyData data) throws IllegalAccessException { private static void buildProperty(ForgeConfigSpec.Builder builder, PropertyData data) throws IllegalAccessException {
AnnotationData annotationData = data.getData(); AnnotationData annotationData = data.getData();
builder.comment(annotationData.description()); builder.comment(annotationData.description());

View File

@ -23,15 +23,13 @@ package tschipp.carryon.events;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.SubmitNodeCollector;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.RenderHandEvent; import net.minecraftforge.client.event.RenderHandEvent;
import net.minecraftforge.client.event.ScreenEvent; import net.minecraftforge.client.event.ScreenEvent;
import net.minecraftforge.event.TickEvent.ClientTickEvent; import net.minecraftforge.event.TickEvent.ClientTickEvent;
import net.minecraftforge.event.TickEvent.Phase; import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import tschipp.carryon.CarryOnCommonClient; import tschipp.carryon.CarryOnCommonClient;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
@ -44,49 +42,37 @@ import tschipp.carryon.common.carry.CarryOnDataManager;
public class ClientEvents { public class ClientEvents {
@SubscribeEvent @SubscribeEvent
public static void renderHand(RenderHandEvent event) public static boolean renderHand(RenderHandEvent event)
{ {
Player player = Minecraft.getInstance().player; Player player = Minecraft.getInstance().player;
MultiBufferSource buffer = event.getMultiBufferSource();
PoseStack matrix = event.getPoseStack(); PoseStack matrix = event.getPoseStack();
int light = event.getPackedLight(); int light = event.getPackedLight();
float partialTicks = event.getPartialTick(); float partialTicks = event.getPartialTick();
SubmitNodeCollector nodes =event.getNodeCollector();
if(CarriedObjectRender.drawFirstPerson(player, buffer, matrix, light, partialTicks) && CarryRenderHelper.getPerspective() == 0) //If true, cancels event
event.setCanceled(true); return CarriedObjectRender.draw(player, matrix, light, partialTicks,nodes,true) && CarryRenderHelper.getPerspective() == 0;
} }
/*
@SubscribeEvent
public static void onRenderLevel(Render event)
{
if(event.getStage() == Stage.AFTER_PARTICLES)
CarriedObjectRender.drawThirdPerson(Minecraft.getInstance().getTimer().getGameTimeDeltaPartialTick(true), event.getPoseStack());
}
*/
@SubscribeEvent @SubscribeEvent
public static void onGuiInit(ScreenEvent.Init.Pre event) public static boolean onGuiInit(ScreenEvent.Init.Pre event)
{ {
if (event.getScreen() != null) boolean inventory = event.getScreen() instanceof AbstractContainerScreen;
{ Minecraft mc = Minecraft.getInstance();
boolean inventory = event.getScreen() instanceof AbstractContainerScreen; Player player = mc.player;
Minecraft mc = Minecraft.getInstance();
Player player = mc.player;
if (player != null && inventory) if (player != null && inventory)
{ {
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (carry.isCarrying()) if (carry.isCarrying())
{ {
mc.player.closeContainer(); mc.player.closeContainer();
mc.screen = null; mc.screen = null;
mc.mouseHandler.grabMouse(); mc.mouseHandler.grabMouse();
event.setCanceled(true); return true;
} }
} }
} return false;
} }
@SubscribeEvent @SubscribeEvent
public static void onClientTick(ClientTickEvent.Post event) public static void onClientTick(ClientTickEvent.Post event)

View File

@ -21,6 +21,7 @@
package tschipp.carryon.events; package tschipp.carryon.events;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@ -29,30 +30,28 @@ import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.BlockSnapshot; import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.event.AddReloadListenerEvent; import net.minecraftforge.common.util.Result;
import net.minecraftforge.event.OnDatapackSyncEvent; import net.minecraftforge.event.*;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.TagsUpdatedEvent;
import net.minecraftforge.event.TickEvent.Phase;
import net.minecraftforge.event.TickEvent.ServerTickEvent; import net.minecraftforge.event.TickEvent.ServerTickEvent;
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
import net.minecraftforge.event.entity.living.LivingAttackEvent; import net.minecraftforge.event.entity.living.LivingAttackEvent;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.living.MobSpawnEvent.FinalizeSpawn; import net.minecraftforge.event.entity.living.MobSpawnEvent.FinalizeSpawn;
import net.minecraftforge.event.entity.player.AttackEntityEvent; import net.minecraftforge.event.entity.player.AttackEntityEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.entity.player.PlayerEvent.BreakSpeed; import net.minecraftforge.event.entity.player.PlayerEvent.BreakSpeed;
import net.minecraftforge.event.entity.player.PlayerEvent.Clone; import net.minecraftforge.event.entity.player.PlayerEvent.Clone;
import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.level.BlockEvent; import net.minecraftforge.event.level.BlockEvent;
import net.minecraftforge.event.level.BlockEvent.BreakEvent; import net.minecraftforge.event.level.BlockEvent.BreakEvent;
import net.minecraftforge.event.level.BlockEvent.EntityPlaceEvent; import net.minecraftforge.event.level.BlockEvent.EntityPlaceEvent;
import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.eventbus.api.listener.Priority;
import net.minecraftforge.eventbus.api.Event.Result; import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import tschipp.carryon.CarryOnCommon; import tschipp.carryon.CarryOnCommon;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.carry.CarryOnDataCapabilityProvider;
import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnData.CarryType; import tschipp.carryon.common.carry.CarryOnData.CarryType;
import tschipp.carryon.common.carry.CarryOnDataManager; import tschipp.carryon.common.carry.CarryOnDataManager;
@ -60,31 +59,29 @@ import tschipp.carryon.common.carry.PickupHandler;
import tschipp.carryon.common.carry.PlacementHandler; import tschipp.carryon.common.carry.PlacementHandler;
import tschipp.carryon.common.scripting.ScriptReloadListener; import tschipp.carryon.common.scripting.ScriptReloadListener;
import tschipp.carryon.config.ConfigLoader; import tschipp.carryon.config.ConfigLoader;
import tschipp.carryon.networking.ClientboundSyncCarryDataPacket;
import tschipp.carryon.platform.Services;
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Constants.MOD_ID) @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Constants.MOD_ID)
public class CommonEvents public class CommonEvents
{ {
@SubscribeEvent(priority = EventPriority.HIGH) @SubscribeEvent(priority = Priority.HIGH)
public static void onBlockClick(PlayerInteractEvent.RightClickBlock event) public static boolean onBlockClick(PlayerInteractEvent.RightClickBlock event)
{ {
if (event.isCanceled())
return;
Player player = event.getEntity(); Player player = event.getEntity();
Level level = event.getLevel(); Level level = event.getLevel();
BlockPos pos = event.getPos(); BlockPos pos = event.getPos();
if (level.isClientSide) if (level.isClientSide())
return; return false;
boolean success = false; boolean success = false;
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (!carry.isCarrying()) { if (!carry.isCarrying()) {
if (PickupHandler.tryPickUpBlock((ServerPlayer) player, pos, level, (pState, pPos) -> { if (PickupHandler.tryPickUpBlock((ServerPlayer) player, pos, level, (pState, pPos) -> {
BlockEvent.BreakEvent breakEvent = new BreakEvent(level, pPos, pState, player); BlockEvent.BreakEvent breakEvent = new BreakEvent(level, pPos, pState, player, Result.DEFAULT);
MinecraftForge.EVENT_BUS.post(breakEvent); return !BreakEvent.BUS.post(breakEvent);
return !breakEvent.isCanceled();
})) { })) {
success = true; success = true;
} }
@ -93,15 +90,13 @@ public class CommonEvents
PlacementHandler.tryPlaceBlock((ServerPlayer) player, pos, event.getFace(), (pos2, state) -> { PlacementHandler.tryPlaceBlock((ServerPlayer) player, pos, event.getFace(), (pos2, state) -> {
BlockSnapshot snapshot = BlockSnapshot.create(level.dimension(), level, pos2); BlockSnapshot snapshot = BlockSnapshot.create(level.dimension(), level, pos2);
EntityPlaceEvent event1 = new EntityPlaceEvent(snapshot, level.getBlockState(pos), player); EntityPlaceEvent event1 = new EntityPlaceEvent(snapshot, level.getBlockState(pos), player);
MinecraftForge.EVENT_BUS.post(event1); return !EntityPlaceEvent.BUS.post(event1);
return !event1.isCanceled();
}); });
} else { } else {
PlacementHandler.tryPlaceEntity((ServerPlayer) player, pos, event.getFace(), (pPos, toPlace) -> { PlacementHandler.tryPlaceEntity((ServerPlayer) player, pos, event.getFace(), (pPos, toPlace) -> {
if (toPlace instanceof Mob mob) { if (toPlace instanceof Mob mob) {
FinalizeSpawn checkSpawn = new FinalizeSpawn(mob, (ServerLevelAccessor) level, pPos.x, pPos.y, pPos.z, level.getCurrentDifficultyAt(new BlockPos((int) pPos.x, (int) pPos.y, (int) pPos.z)), EntitySpawnReason.EVENT, null, null, null); FinalizeSpawn checkSpawn = new FinalizeSpawn(mob, (ServerLevelAccessor) level, pPos.x, pPos.y, pPos.z, ((ServerLevelAccessor) level).getCurrentDifficultyAt(new BlockPos((int) pPos.x, (int) pPos.y, (int) pPos.z)), EntitySpawnReason.EVENT, null, null, null);
MinecraftForge.EVENT_BUS.post(checkSpawn); return !FinalizeSpawn.BUS.post(checkSpawn);
return event.getResult() != Result.DENY;
} }
return true; return true;
}); });
@ -110,40 +105,38 @@ public class CommonEvents
} }
if (success) { if (success) {
event.setUseBlock(Event.Result.DENY); event.setUseBlock(Result.DENY);
event.setUseItem(Event.Result.DENY); event.setUseItem(Result.DENY);
event.setCancellationResult(InteractionResult.SUCCESS); event.setCancellationResult(InteractionResult.SUCCESS);
event.setCanceled(true); return true;
} }
return false;
} }
@SubscribeEvent(priority = EventPriority.HIGH) @SubscribeEvent(priority = Priority.HIGH)
public static void onEntityRightClick(PlayerInteractEvent.EntityInteract event) public static boolean onEntityRightClick(PlayerInteractEvent.EntityInteract event)
{ {
if (event.isCanceled())
return;
Player player = event.getEntity(); Player player = event.getEntity();
Level level = event.getLevel(); Level level = event.getLevel();
Entity target = event.getTarget(); Entity target = event.getTarget();
if (level.isClientSide) if (level.isClientSide())
return; return false;
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (!carry.isCarrying()) { if (!carry.isCarrying()) {
if (PickupHandler.tryPickupEntity((ServerPlayer) player, target, (toPickup) -> { if (PickupHandler.tryPickupEntity((ServerPlayer) player, target, (toPickup) -> {
EntityPickupEvent pickupEvent = new EntityPickupEvent((ServerPlayer) player, toPickup); EntityPickupEvent pickupEvent = new EntityPickupEvent((ServerPlayer) player, toPickup);
MinecraftForge.EVENT_BUS.post(pickupEvent); return !EntityPickupEvent.BUS.post(pickupEvent);
return !pickupEvent.isCanceled();
})) { })) {
event.setCancellationResult(InteractionResult.SUCCESS); event.setCancellationResult(InteractionResult.SUCCESS);
event.setCanceled(true); return true;
return;
} }
} else if (carry.isCarrying(CarryType.ENTITY) || carry.isCarrying(CarryType.PLAYER)) { } else if (carry.isCarrying(CarryType.ENTITY) || carry.isCarrying(CarryType.PLAYER)) {
PlacementHandler.tryStackEntity((ServerPlayer) player, target); PlacementHandler.tryStackEntity((ServerPlayer) player, target);
} }
return false;
} }
@SubscribeEvent @SubscribeEvent
@ -178,15 +171,23 @@ public class CommonEvents
@SubscribeEvent @SubscribeEvent
public static void onServerTick(ServerTickEvent.Post event) public static void onServerTick(ServerTickEvent.Post event)
{ {
for (ServerPlayer player : event.getServer().getPlayerList().getPlayers()) for (ServerPlayer player : event.server().getPlayerList().getPlayers())
CarryOnCommon.onCarryTick(player); CarryOnCommon.onCarryTick(player);
} }
@SubscribeEvent @SubscribeEvent
public static void onClone(Clone event) public static void onClone(Clone event)
{ {
if (!event.getOriginal().level().isClientSide) if (!event.getOriginal().level().isClientSide()) {
PlacementHandler.placeCarriedOnDeath((ServerPlayer) event.getOriginal(), (ServerPlayer) event.getEntity(), event.isWasDeath()); Player newPlayer = event.getEntity();
Player oldPlayer = event.getOriginal();
oldPlayer.reviveCaps();
PlacementHandler.placeCarriedOnDeath((ServerPlayer) oldPlayer, (ServerPlayer) newPlayer, event.isWasDeath());
oldPlayer.invalidateCaps();
}
} }
@SubscribeEvent @SubscribeEvent
@ -197,19 +198,16 @@ public class CommonEvents
} }
@SubscribeEvent @SubscribeEvent
public static void attackEntity(AttackEntityEvent event) public static boolean attackEntity(AttackEntityEvent event)
{ {
if(!CarryOnCommon.onAttackedByPlayer(event.getEntity())) return !CarryOnCommon.onAttackedByPlayer(event.getEntity());
event.setCanceled(true); }
}
@SubscribeEvent @SubscribeEvent
public static void onBreakBlock(BreakEvent event) public static boolean onBreakBlock(BreakEvent event)
{ {
if (!CarryOnCommon.onTryBreakBlock(event.getPlayer())) { return !CarryOnCommon.onTryBreakBlock(event.getPlayer());
event.setCanceled(true); }
}
}
@SubscribeEvent @SubscribeEvent
public static void playerAttack(LivingAttackEvent event) public static void playerAttack(LivingAttackEvent event)
@ -218,4 +216,38 @@ public class CommonEvents
CarryOnCommon.onPlayerAttacked(player); CarryOnCommon.onPlayerAttacked(player);
} }
@SubscribeEvent
public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) {
if(event.getEntity() instanceof ServerPlayer player)
CarryOnCommon.onRiderDisconnected(player);
}
@SubscribeEvent
public static void onAttachCapabilities(AttachCapabilitiesEvent.Entities event) {
if (event.getObject() instanceof Player) {
event.addCapability(Identifier.fromNamespaceAndPath(Constants.MOD_ID, "carry_on_data"), new CarryOnDataCapabilityProvider());
}
}
@SubscribeEvent
public static void onStartTracking(PlayerEvent.StartTracking event) {
if(event.getEntity() instanceof ServerPlayer sp && event.getTarget() instanceof ServerPlayer target) {
Services.PLATFORM.sendPacketToPlayer(Constants.PACKET_ID_SYNC_CARRY_ON_DATA, new ClientboundSyncCarryDataPacket(sp.getId(), CarryOnDataManager.getCarryData(sp)), target);
}
}
@SubscribeEvent
public static void onJoinWorld(EntityJoinLevelEvent event) {
if (event.getEntity() instanceof ServerPlayer sp) {
Services.PLATFORM.sendPacketToPlayer(Constants.PACKET_ID_SYNC_CARRY_ON_DATA, new ClientboundSyncCarryDataPacket(sp.getId(), CarryOnDataManager.getCarryData(sp)), sp);
}
}
@SubscribeEvent
public static void onPlayerDie(LivingDeathEvent event) {
if(event.getEntity() instanceof ServerPlayer sp) {
CarryOnCommon.onRiderDisconnected(sp);
}
}
} }

View File

@ -22,17 +22,11 @@ package tschipp.carryon.events;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraftforge.eventbus.api.Cancelable; import net.minecraftforge.eventbus.api.bus.CancellableEventBus;
import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.eventbus.api.event.RecordEvent;
import net.minecraftforge.eventbus.api.event.characteristic.Cancellable;
@Cancelable public record EntityPickupEvent(ServerPlayer player, Entity target) implements Cancellable, RecordEvent {
public class EntityPickupEvent extends Event {
public final ServerPlayer player; public static final CancellableEventBus<EntityPickupEvent> BUS = CancellableEventBus.create(EntityPickupEvent.class);
public final Entity target;
public EntityPickupEvent(ServerPlayer player, Entity target) {
this.player = player;
this.target = target;
}
} }

View File

@ -19,16 +19,13 @@
*/ */
package tschipp.carryon.events; package tschipp.carryon.events;
import net.minecraftforge.eventbus.api.listener.Priority;
import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.InterModComms; import net.minecraftforge.fml.InterModComms;
import net.minecraftforge.fml.InterModComms.IMCMessage; import net.minecraftforge.fml.InterModComms.IMCMessage;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent; import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.client.modeloverride.ModelOverrideHandler;
import tschipp.carryon.common.config.ListHandler; import tschipp.carryon.common.config.ListHandler;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -36,7 +33,7 @@ import java.util.stream.Stream;
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, modid = Constants.MOD_ID) @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, modid = Constants.MOD_ID)
public class ModBusEvents { public class ModBusEvents {
@SubscribeEvent(priority = EventPriority.LOW) @SubscribeEvent(priority = Priority.LOW)
public static void serverLoad(InterModProcessEvent event) public static void serverLoad(InterModProcessEvent event)
{ {
Stream<IMCMessage> messages = InterModComms.getMessages(Constants.MOD_ID); Stream<IMCMessage> messages = InterModComms.getMessages(Constants.MOD_ID);

View File

@ -21,17 +21,13 @@
package tschipp.carryon.events; package tschipp.carryon.events;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.ConfigScreenHandler;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent; import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus; import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.client.keybinds.CarryOnKeybinds; import tschipp.carryon.client.keybinds.CarryOnKeybinds;
import tschipp.carryon.compat.ClothConfigCompatForge;
import tschipp.carryon.config.BuiltConfig; import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.forge.ConfigLoaderImpl; import tschipp.carryon.config.forge.ConfigLoaderImpl;
import tschipp.carryon.platform.Services; import tschipp.carryon.platform.Services;
@ -39,20 +35,15 @@ import tschipp.carryon.platform.Services;
@Mod.EventBusSubscriber(bus = Bus.MOD, modid = Constants.MOD_ID, value=Dist.CLIENT) @Mod.EventBusSubscriber(bus = Bus.MOD, modid = Constants.MOD_ID, value=Dist.CLIENT)
public class ModClientEvents public class ModClientEvents
{ {
@SubscribeEvent static{
public static void registerKeybinds(RegisterKeyMappingsEvent event) RegisterKeyMappingsEvent.BUS.addListener((e)->CarryOnKeybinds.registerKeybinds(e::register));
{
CarryOnKeybinds.registerKeybinds(event::register);
} }
@SubscribeEvent @SubscribeEvent
public static void clientSetup(FMLClientSetupEvent event) public static void clientSetup(FMLClientSetupEvent event)
{ {
if(Services.PLATFORM.isModLoaded("cloth_config")) { if(Services.PLATFORM.isModLoaded("cloth_config")) {
ConfigLoaderImpl.CONFIGS.values().toArray(new BuiltConfig[0]);
BuiltConfig[] configs = ConfigLoaderImpl.CONFIGS.values().toArray(new BuiltConfig[0]);
ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, () -> new ConfigScreenHandler.ConfigScreenFactory((mc, prevScreen) -> ClothConfigCompatForge.createScreen(configs[1], configs[0], prevScreen)));
} }
} }
} }

View File

@ -1,47 +0,0 @@
/*
* GNU Lesser General Public License v3
* Copyright (C) 2024 Tschipp
* mrtschipp@gmail.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package tschipp.carryon.mixin;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Camera;
import net.minecraft.client.particle.ParticleEngine;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.culling.Frustum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import tschipp.carryon.client.render.CarriedObjectRender;
@Mixin(ParticleEngine.class)
public class ParticleEngineMixin
{
//I am injecting into a lambda, lord help me
@Inject(method = "render(Lnet/minecraft/client/Camera;FLnet/minecraft/client/renderer/MultiBufferSource$BufferSource;Lnet/minecraft/client/renderer/culling/Frustum;)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch()V",
shift = At.Shift.AFTER))
private void onRenderLevel(Camera p_107340_, float partialTick, MultiBufferSource.BufferSource p_377798_, Frustum frustum, CallbackInfo ci)
{
CarriedObjectRender.drawThirdPerson(partialTick, new PoseStack().last().pose());
}
}

View File

@ -0,0 +1,35 @@
package tschipp.carryon.networking;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import tschipp.carryon.Constants;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnDataManager;
public record ClientboundSyncCarryDataPacket(int iden, CarryOnData data) implements PacketBase {
public static final StreamCodec<RegistryFriendlyByteBuf, ClientboundSyncCarryDataPacket> CODEC = StreamCodec.composite(
ByteBufCodecs.INT, ClientboundSyncCarryDataPacket::iden,
CarryOnData.STREAM_CODEC, ClientboundSyncCarryDataPacket::data,
ClientboundSyncCarryDataPacket::new
);
public static final CustomPacketPayload.Type<ClientboundSyncCarryDataPacket> TYPE = new Type<>(Constants.PACKET_ID_SYNC_CARRY_ON_DATA);
@Override
public void handle(Player player) {
Entity e = player.level().getEntity(this.iden);
if(e instanceof Player p) {
CarryOnDataManager.setCarryData(p, data);
}
}
@Override
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
}

View File

@ -21,26 +21,29 @@
package tschipp.carryon.platform; package tschipp.carryon.platform;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraftforge.event.network.CustomPayloadEvent; import net.minecraftforge.event.network.CustomPayloadEvent;
import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PacketDistributor;
import tschipp.carryon.CarryOnCommonClient; import tschipp.carryon.CarryOnCommonClient;
import tschipp.carryon.CarryOnForge; import tschipp.carryon.CarryOnForge;
import tschipp.carryon.Constants;
import tschipp.carryon.carry.CarryOnDataCapability;
import tschipp.carryon.carry.CarryOnDataCapabilityProvider;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.config.BuiltConfig; import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.forge.ConfigLoaderImpl; import tschipp.carryon.config.forge.ConfigLoaderImpl;
import tschipp.carryon.networking.ClientboundSyncCarryDataPacket;
import tschipp.carryon.networking.PacketBase; import tschipp.carryon.networking.PacketBase;
import tschipp.carryon.platform.services.IPlatformHelper; import tschipp.carryon.platform.services.IPlatformHelper;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Function;
public class ForgePlatformHelper implements IPlatformHelper { public class ForgePlatformHelper implements IPlatformHelper {
@ -67,6 +70,7 @@ public class ForgePlatformHelper implements IPlatformHelper {
ConfigLoaderImpl.registerConfig(cfg); ConfigLoaderImpl.registerConfig(cfg);
} }
@SuppressWarnings("unchecked")
@Override @Override
public <T extends PacketBase, B extends FriendlyByteBuf> void registerServerboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args) public <T extends PacketBase, B extends FriendlyByteBuf> void registerServerboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args)
{ {
@ -83,6 +87,7 @@ public class ForgePlatformHelper implements IPlatformHelper {
CarryOnForge.network.messageBuilder(clazz).codec((StreamCodec<FriendlyByteBuf, T>) codec).consumerMainThread(serverHandler).add(); CarryOnForge.network.messageBuilder(clazz).codec((StreamCodec<FriendlyByteBuf, T>) codec).consumerMainThread(serverHandler).add();
} }
@SuppressWarnings("unchecked")
@Override @Override
public <T extends PacketBase, B extends FriendlyByteBuf> void registerClientboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args) public <T extends PacketBase, B extends FriendlyByteBuf> void registerClientboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args)
{ {
@ -101,14 +106,29 @@ public class ForgePlatformHelper implements IPlatformHelper {
@Override @Override
public void sendPacketToServer(ResourceLocation id, PacketBase packet) public void sendPacketToServer(Identifier id, PacketBase packet)
{ {
CarryOnForge.network.send(packet, PacketDistributor.SERVER.noArg()); CarryOnForge.network.send(packet, PacketDistributor.SERVER.noArg());
} }
@Override @Override
public void sendPacketToPlayer(ResourceLocation id, PacketBase packet, ServerPlayer player) public void sendPacketToPlayer(Identifier id, PacketBase packet, ServerPlayer player)
{ {
CarryOnForge.network.send(packet, PacketDistributor.PLAYER.with(player)); CarryOnForge.network.send(packet, PacketDistributor.PLAYER.with(player));
} }
@Override
public CarryOnData getCarryData(Player player) {
var cap = player.getCapability(CarryOnDataCapabilityProvider.CARRY_ON_DATA_CAPABILITY).orElse(new CarryOnDataCapability());
return cap.getCarryData();
}
@Override
public void setCarryData(Player player, CarryOnData data) {
var cap = player.getCapability(CarryOnDataCapabilityProvider.CARRY_ON_DATA_CAPABILITY).orElse(new CarryOnDataCapability());
cap.setCarryData(data);
if(!player.level().isClientSide()) {
sendPacketToAllPlayers(Constants.PACKET_ID_SYNC_CARRY_ON_DATA, new ClientboundSyncCarryDataPacket(player.getId(), data), (ServerLevel) player.level());
}
}
} }

View File

@ -19,7 +19,7 @@ issueTrackerURL="https://github.com/Tschipp/CarryOn/issues"
# Does this dependency have to exist - if not, ordering below must be specified # Does this dependency have to exist - if not, ordering below must be specified
mandatory=true #mandatory mandatory=true #mandatory
# The version range of the dependency # The version range of the dependency
versionRange="${forge_version_range}" #mandatory versionRange="${forge_loader_version_range}" #mandatory
# An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory
ordering="NONE" ordering="NONE"
# Side this dependency is applied on - BOTH, CLIENT or SERVER # Side this dependency is applied on - BOTH, CLIENT or SERVER

View File

@ -6,12 +6,10 @@
"mixins": [ "mixins": [
], ],
"client": [ "client": [
"ParticleEngineMixin"
], ],
"server": [ "server": [
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1
}, }
"refmap": "${refmap_target}refmap.json"
} }

View File

@ -1,120 +1,174 @@
plugins { plugins {
id 'idea' id 'multiloader-loader'
id 'maven-publish' id 'net.neoforged.moddev'
id 'net.neoforged.gradle.userdev' version '7.0.168'
id 'java-library'
} }
repositories {
if (System.getenv('BUILD_NUMBER') != null) { maven {
version += "." + System.getenv('BUILD_NUMBER') name = "Shedaniel"
} url "https://maven.shedaniel.me/"
base {
archivesName = "${mod_id}-neoforge-${minecraft_version}"
}
//jarJar.enable()
//archivesBaseName = "${mod_id}-neoforge-${minecraft_version}"
/*
mixin {
add sourceSets.main, "${mod_id}.refmap.json"
config "${mod_id}.mixins.json"
config "${mod_id}.forge.mixins.json"
}
*/
if (file('src/main/resources/META-INF/accesstransformer.cfg').exists()) {
minecraft.accessTransformers.file file('src/main/resources/META-INF/accesstransformer.cfg')
}
runs {
// applies to all the run configs below
configureEach {
systemProperty 'forge.logging.markers', 'REGISTRIES'
systemProperty 'forge.logging.console.level', 'debug'
modSource project.sourceSets.main
} }
client { maven { url 'https://jitpack.io' }
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces. }
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
neoForge {
version = neoforge_version
// Automatically enable neoforge AccessTransformers if the file exists
def at = project(':Common').file('src/main/resources/META-INF/accesstransformer.cfg')
if (at.exists()) {
accessTransformers.from(at.absolutePath)
} }
parchment {
server { minecraftVersion = parchment_game_version
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id mappingsVersion = parchment_version
programArgument '--nogui'
} }
runs {
// This run config launches GameTestServer and runs all registered gametests, then exits. configureEach {
// By default, the server will crash when no gametests are provided. systemProperty('neoforge.enabledGameTestNamespaces', mod_id)
// The gametest system is also enabled by default for other run configs under the /test command. ideName = "NeoForge ${it.name.capitalize()} (${project.path})" // Unify the run config names with fabric
gameTestServer { }
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id client {
client()
}
data {
clientData()
}
server {
server()
}
} }
mods {
"${mod_id}" {
sourceSet sourceSets.main
}
}
}
/*
data {
// example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it
// workingDirectory project.file('run-data')
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. dependencies {
programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() compileOnly "me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}"
}*/
} }
sourceSets.main.resources { srcDir 'src/generated/resources' } sourceSets.main.resources { srcDir 'src/generated/resources' }
configurations { //plugins {
runtimeClasspath.extendsFrom localRuntime // id 'idea'
} // id 'maven-publish'
// id 'net.neoforged.gradle.userdev' version '7.0.168'
// id 'java-library'
tasks.named("test").configure { //}
enabled = false //
} //
//if (System.getenv('BUILD_NUMBER') != null) {
dependencies { // version += "." + System.getenv('BUILD_NUMBER')
implementation "net.neoforged:neoforge:${neoforge_version}" //}
compileOnly project(":Common") //
//base {
api "me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}" // archivesName = "${mod_id}-neoforge-${minecraft_version}"
//implementation fg.deobf("net.darkhax.gamestages:GameStages-Forge-1.19.2:11.0.2") //}
//implementation fg.deobf("net.darkhax.bookshelf:Bookshelf-Forge-1.19.3:17.0.2") //
} ////jarJar.enable()
//
// NeoGradle compiles the game, but we don't want to add our common code to the game's code ////archivesBaseName = "${mod_id}-neoforge-${minecraft_version}"
Spec<Task> notNeoTask = { Task it -> !it.name.startsWith("neo") } as Spec<Task> //
///*
tasks.withType(JavaCompile).matching(notNeoTask).configureEach { //mixin {
source(project(":Common").sourceSets.main.allSource) // add sourceSets.main, "${mod_id}.refmap.json"
} //
// config "${mod_id}.mixins.json"
tasks.withType(Javadoc).matching(notNeoTask).configureEach { // config "${mod_id}.forge.mixins.json"
source(project(":Common").sourceSets.main.allJava) //}
} //*/
//
tasks.named("sourcesJar", Jar) { //if (file('src/main/resources/META-INF/accesstransformer.cfg').exists()) {
from(project(":Common").sourceSets.main.allSource) // minecraft.accessTransformers.file file('src/main/resources/META-INF/accesstransformer.cfg')
} //}
//
tasks.withType(ProcessResources).matching(notNeoTask).configureEach { //runs {
from project(":Common").sourceSets.main.resources // // applies to all the run configs below
} // configureEach {
// systemProperty 'forge.logging.markers', 'REGISTRIES'
publishing { // systemProperty 'forge.logging.console.level', 'debug'
publications { // modSource project.sourceSets.main
mavenJava(MavenPublication) { // }
artifactId base.archivesName.get() //
from components.java // client {
} // // Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
} // systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
repositories { // }
maven { //
url "file://" + System.getenv("local_maven") // server {
} // systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
} // programArgument '--nogui'
} // }
//
// // This run config launches GameTestServer and runs all registered gametests, then exits.
// // By default, the server will crash when no gametests are provided.
// // The gametest system is also enabled by default for other run configs under the /test command.
// gameTestServer {
// systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
// }
//
// /*
// data {
// // example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it
// // workingDirectory project.file('run-data')
//
// // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
// programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
// }*/
//}
//
//sourceSets.main.resources { srcDir 'src/generated/resources' }
//
//configurations {
// runtimeClasspath.extendsFrom localRuntime
//}
//
//
//tasks.named("test").configure {
// enabled = false
//}
//
//dependencies {
// implementation "net.neoforged:neoforge:${neoforge_version}"
// compileOnly project(":Common")
//
// api "me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}"
// //implementation fg.deobf("net.darkhax.gamestages:GameStages-Forge-1.19.2:11.0.2")
// //implementation fg.deobf("net.darkhax.bookshelf:Bookshelf-Forge-1.19.3:17.0.2")
//}
//
//// NeoGradle compiles the game, but we don't want to add our common code to the game's code
//Spec<Task> notNeoTask = { Task it -> !it.name.startsWith("neo") } as Spec<Task>
//
//tasks.withType(JavaCompile).matching(notNeoTask).configureEach {
// source(project(":Common").sourceSets.main.allSource)
//}
//
//tasks.withType(Javadoc).matching(notNeoTask).configureEach {
// source(project(":Common").sourceSets.main.allJava)
//}
//
//tasks.named("sourcesJar", Jar) {
// from(project(":Common").sourceSets.main.allSource)
//}
//
//tasks.withType(ProcessResources).matching(notNeoTask).configureEach {
// from project(":Common").sourceSets.main.resources
//}
//
//publishing {
// publications {
// mavenJava(MavenPublication) {
// artifactId base.archivesName.get()
// from components.java
// }
// }
// repositories {
// maven {
// url "file://" + System.getenv("local_maven")
// }
// }
//}

View File

@ -20,20 +20,34 @@
package tschipp.carryon; package tschipp.carryon;
import net.neoforged.bus.api.IEventBus; import net.minecraft.nbt.CompoundTag;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.ModContainer; import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.Mod; import net.neoforged.fml.common.Mod;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.client.gui.ConfigurationScreen; import net.neoforged.neoforge.attachment.AttachmentType;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
import net.neoforged.neoforge.network.registration.PayloadRegistrar; import net.neoforged.neoforge.network.registration.PayloadRegistrar;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
import tschipp.carryon.carry.CarryOnDataSyncHandler;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.config.neoforge.ConfigLoaderImpl; import tschipp.carryon.config.neoforge.ConfigLoaderImpl;
import java.util.function.Supplier;
@Mod(Constants.MOD_ID) @Mod(Constants.MOD_ID)
public class CarryOnNeoForge { public class CarryOnNeoForge {
private static final DeferredRegister<AttachmentType<?>> ATTACHMENT_TYPES = DeferredRegister.create(NeoForgeRegistries.ATTACHMENT_TYPES, Constants.MOD_ID);
public static final Supplier<AttachmentType<CarryOnData>> CARRY_ON_DATA_ATTACHMENT = ATTACHMENT_TYPES.register(
"carry_on_data",
() -> AttachmentType.builder(() -> new CarryOnData(new CompoundTag()))
.sync(new CarryOnDataSyncHandler())
.serialize(CarryOnData.CODEC.fieldOf(CarryOnData.SERIALIZATION_KEY))
.build()
);
public CarryOnNeoForge(ModContainer container) { public CarryOnNeoForge(ModContainer container) {
// This method is invoked by the Forge mod loader when it is ready // This method is invoked by the Forge mod loader when it is ready
@ -45,6 +59,8 @@ public class CarryOnNeoForge {
container.getEventBus().addListener(this::registerPackets); container.getEventBus().addListener(this::registerPackets);
ConfigLoaderImpl.initialize(container); ConfigLoaderImpl.initialize(container);
ATTACHMENT_TYPES.register(container.getEventBus());
} }
private void setup(final FMLCommonSetupEvent event) private void setup(final FMLCommonSetupEvent event)
@ -57,6 +73,8 @@ public class CarryOnNeoForge {
CarryOnCommon.registerServerPackets(registrar); CarryOnCommon.registerServerPackets(registrar);
CarryOnCommon.registerClientPackets(registrar); CarryOnCommon.registerClientPackets(registrar);
} }
} }

View File

@ -4,9 +4,11 @@ import net.neoforged.api.distmarker.Dist;
import net.neoforged.fml.ModContainer; import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.Mod; import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.gui.IConfigScreenFactory; import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
import net.neoforged.neoforge.client.network.ClientPacketDistributor;
import tschipp.carryon.compat.ClothConfigCompatNeo; import tschipp.carryon.compat.ClothConfigCompatNeo;
import tschipp.carryon.config.BuiltConfig; import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.neoforge.ConfigLoaderImpl; import tschipp.carryon.config.neoforge.ConfigLoaderImpl;
import tschipp.carryon.networking.PacketBase;
import tschipp.carryon.platform.Services; import tschipp.carryon.platform.Services;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -24,4 +26,8 @@ public class CarryOnNeoForgeClient {
} }
} }
public static void sendPacketToServer(PacketBase packet) {
ClientPacketDistributor.sendToServer(packet);
}
} }

View File

@ -0,0 +1,31 @@
package tschipp.carryon.carry;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.neoforge.attachment.AttachmentSyncHandler;
import net.neoforged.neoforge.attachment.IAttachmentHolder;
import org.jetbrains.annotations.Nullable;
import tschipp.carryon.common.carry.CarryOnData;
public class CarryOnDataSyncHandler implements AttachmentSyncHandler<CarryOnData> {
@Override
public void write(RegistryFriendlyByteBuf registryFriendlyByteBuf, CarryOnData carryOnData, boolean b) {
CarryOnData.STREAM_CODEC.encode(registryFriendlyByteBuf, carryOnData);
}
@Override
public @Nullable CarryOnData read(IAttachmentHolder iAttachmentHolder, RegistryFriendlyByteBuf registryFriendlyByteBuf, @Nullable CarryOnData carryOnData) {
return CarryOnData.STREAM_CODEC.decode(registryFriendlyByteBuf);
}
@Override
public boolean sendToPlayer(IAttachmentHolder holder, ServerPlayer to) {
ServerPlayer player = (ServerPlayer) holder;
// the isAlive check avoids us syncing attachment data about dead players. Which causes a disconnect
// player.tickCount <= 0 avoids us syncing attachment data about players the instant they spawn.
// Which also causes a disconnect as the player entity may not be synced yet.
if (to.connection == null || !player.isAlive() || player.tickCount <= 0 || player.isRemoved())
return false;
return AttachmentSyncHandler.super.sendToPlayer(holder, to);
}
}

View File

@ -1,18 +1,11 @@
package tschipp.carryon.compat; package tschipp.carryon.compat;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.neoforged.fml.ModContainer; import net.neoforged.fml.ModContainer;
import net.neoforged.neoforge.client.gui.IConfigScreenFactory; import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
import tschipp.carryon.config.AnnotationData;
import tschipp.carryon.config.BuiltCategory;
import tschipp.carryon.config.BuiltConfig; import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.neoforge.ConfigLoaderImpl; import tschipp.carryon.config.neoforge.ConfigLoaderImpl;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Optional;
public record ClothConfigCompatNeo(BuiltConfig client, BuiltConfig common) implements IConfigScreenFactory { public record ClothConfigCompatNeo(BuiltConfig client, BuiltConfig common) implements IConfigScreenFactory {

View File

@ -22,27 +22,21 @@ package tschipp.carryon.config.neoforge;
import com.electronwill.nightconfig.core.AbstractConfig; import com.electronwill.nightconfig.core.AbstractConfig;
import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig;
import net.minecraft.client.Minecraft;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.ModContainer; import net.neoforged.fml.ModContainer;
import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.config.IConfigSpec;
import net.neoforged.fml.config.ModConfig; import net.neoforged.fml.config.ModConfig;
import net.neoforged.fml.event.config.ModConfigEvent; import net.neoforged.fml.event.config.ModConfigEvent;
import net.neoforged.neoforge.common.ModConfigSpec; import net.neoforged.neoforge.common.ModConfigSpec;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.server.ServerLifecycleHooks;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.config.*; import tschipp.carryon.config.AnnotationData;
import tschipp.carryon.config.BuiltCategory;
import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.PropertyData;
import java.util.*; import java.util.*;
import java.util.function.Consumer;
@EventBusSubscriber(modid = Constants.MOD_ID, bus = EventBusSubscriber.Bus.MOD) @EventBusSubscriber(modid = Constants.MOD_ID)
public class ConfigLoaderImpl { public class ConfigLoaderImpl {
public static final Map<ModConfigSpec, BuiltConfig> CONFIGS = new LinkedHashMap<>(); public static final Map<ModConfigSpec, BuiltConfig> CONFIGS = new LinkedHashMap<>();
@ -120,6 +114,7 @@ public class ConfigLoaderImpl {
builder.pop(); builder.pop();
} }
@SuppressWarnings("unchecked")
private static void buildProperty(ModConfigSpec.Builder builder, PropertyData data) throws IllegalAccessException { private static void buildProperty(ModConfigSpec.Builder builder, PropertyData data) throws IllegalAccessException {
AnnotationData annotationData = data.getData(); AnnotationData annotationData = data.getData();
builder.comment(annotationData.description()); builder.comment(annotationData.description());

View File

@ -23,16 +23,13 @@ package tschipp.carryon.events;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.SubmitNodeCollector;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.ClientTickEvent;
import net.neoforged.neoforge.client.event.RenderHandEvent; import net.neoforged.neoforge.client.event.RenderHandEvent;
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
import net.neoforged.neoforge.client.event.ScreenEvent; import net.neoforged.neoforge.client.event.ScreenEvent;
import tschipp.carryon.CarryOnCommonClient; import tschipp.carryon.CarryOnCommonClient;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
@ -41,32 +38,22 @@ import tschipp.carryon.client.render.CarryRenderHelper;
import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnDataManager; import tschipp.carryon.common.carry.CarryOnDataManager;
@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, modid = Constants.MOD_ID, value = Dist.CLIENT) @EventBusSubscriber(modid = Constants.MOD_ID, value = Dist.CLIENT)
public class ClientEvents { public class ClientEvents {
@OnlyIn(Dist.CLIENT)
@SubscribeEvent @SubscribeEvent
public static void renderHand(RenderHandEvent event) public static void renderHand(RenderHandEvent event)
{ {
Player player = Minecraft.getInstance().player; Player player = Minecraft.getInstance().player;
MultiBufferSource buffer = event.getMultiBufferSource();
PoseStack matrix = event.getPoseStack(); PoseStack matrix = event.getPoseStack();
int light = event.getPackedLight(); int light = event.getPackedLight();
float partialTicks = event.getPartialTick(); float partialTicks = event.getPartialTick();
SubmitNodeCollector nodes =event.getSubmitNodeCollector();
if(CarriedObjectRender.drawFirstPerson(player, buffer, matrix, light, partialTicks) && CarryRenderHelper.getPerspective() == 0) if(CarriedObjectRender.draw(player, matrix, light, partialTicks,nodes,true) && CarryRenderHelper.getPerspective() == 0)
event.setCanceled(true); event.setCanceled(true);
} }
@OnlyIn(Dist.CLIENT)
@SubscribeEvent
public static void onRenderLevel(RenderLevelStageEvent event)
{
if(event.getStage() == RenderLevelStageEvent.Stage.AFTER_PARTICLES)
CarriedObjectRender.drawThirdPerson(event.getPartialTick().getGameTimeDeltaPartialTick(true), event.getPoseStack().last().pose());
}
@OnlyIn(Dist.CLIENT)
@SubscribeEvent @SubscribeEvent
public static void onGuiInit(ScreenEvent.Init.Pre event) public static void onGuiInit(ScreenEvent.Init.Pre event)
{ {
@ -90,7 +77,6 @@ public class ClientEvents {
} }
} }
@OnlyIn(Dist.CLIENT)
@SubscribeEvent @SubscribeEvent
public static void onClientTick(ClientTickEvent.Post event) public static void onClientTick(ClientTickEvent.Post event)
{ {

View File

@ -21,8 +21,9 @@
package tschipp.carryon.events; package tschipp.carryon.events;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.TriState;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.EntitySpawnReason;
@ -30,15 +31,16 @@ import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.ServerLevelAccessor;
import net.neoforged.bus.api.Event;
import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.EventPriority;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.common.util.BlockSnapshot; import net.neoforged.neoforge.common.util.BlockSnapshot;
import net.neoforged.neoforge.common.util.TriState; import net.neoforged.neoforge.event.AddServerReloadListenersEvent;
import net.neoforged.neoforge.event.*; import net.neoforged.neoforge.event.OnDatapackSyncEvent;
import net.neoforged.neoforge.event.RegisterCommandsEvent;
import net.neoforged.neoforge.event.TagsUpdatedEvent;
import net.neoforged.neoforge.event.entity.living.LivingDeathEvent;
import net.neoforged.neoforge.event.entity.living.MobSpawnEvent; import net.neoforged.neoforge.event.entity.living.MobSpawnEvent;
import net.neoforged.neoforge.event.entity.player.AttackEntityEvent; import net.neoforged.neoforge.event.entity.player.AttackEntityEvent;
import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent;
@ -55,7 +57,7 @@ import tschipp.carryon.common.carry.PlacementHandler;
import tschipp.carryon.common.scripting.ScriptReloadListener; import tschipp.carryon.common.scripting.ScriptReloadListener;
import tschipp.carryon.config.ConfigLoader; import tschipp.carryon.config.ConfigLoader;
@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, modid = Constants.MOD_ID) @EventBusSubscriber(modid = Constants.MOD_ID)
public class CommonEvents public class CommonEvents
{ {
@SubscribeEvent(priority = EventPriority.HIGH) @SubscribeEvent(priority = EventPriority.HIGH)
@ -68,7 +70,7 @@ public class CommonEvents
Level level = event.getLevel(); Level level = event.getLevel();
BlockPos pos = event.getPos(); BlockPos pos = event.getPos();
if (level.isClientSide) if (level.isClientSide())
return; return;
boolean success = false; boolean success = false;
@ -122,7 +124,7 @@ public class CommonEvents
Level level = event.getLevel(); Level level = event.getLevel();
Entity target = event.getTarget(); Entity target = event.getTarget();
if (level.isClientSide) if (level.isClientSide())
return; return;
CarryOnData carry = CarryOnDataManager.getCarryData(player); CarryOnData carry = CarryOnDataManager.getCarryData(player);
@ -150,7 +152,7 @@ public class CommonEvents
@SubscribeEvent @SubscribeEvent
public static void onDatapackRegister(AddServerReloadListenersEvent event) public static void onDatapackRegister(AddServerReloadListenersEvent event)
{ {
event.addListener(ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "scripts"), new ScriptReloadListener()); event.addListener(Identifier.fromNamespaceAndPath(Constants.MOD_ID, "scripts"), new ScriptReloadListener());
} }
@SubscribeEvent @SubscribeEvent
@ -180,7 +182,7 @@ public class CommonEvents
@SubscribeEvent @SubscribeEvent
public static void onClone(PlayerEvent.Clone event) public static void onClone(PlayerEvent.Clone event)
{ {
if (!event.getOriginal().level().isClientSide) if (!event.getOriginal().level().isClientSide())
PlacementHandler.placeCarriedOnDeath((ServerPlayer) event.getOriginal(), (ServerPlayer) event.getEntity(), event.isWasDeath()); PlacementHandler.placeCarriedOnDeath((ServerPlayer) event.getOriginal(), (ServerPlayer) event.getEntity(), event.isWasDeath());
} }
@ -213,4 +215,17 @@ public class CommonEvents
CarryOnCommon.onPlayerAttacked(player); CarryOnCommon.onPlayerAttacked(player);
} }
@SubscribeEvent
public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) {
if(event.getEntity() instanceof ServerPlayer player)
CarryOnCommon.onRiderDisconnected(player);
}
@SubscribeEvent
public static void onPlayerDie(LivingDeathEvent event) {
if(event.getEntity() instanceof ServerPlayer sp) {
CarryOnCommon.onRiderDisconnected(sp);
}
}
} }

View File

@ -24,15 +24,13 @@ import net.neoforged.bus.api.EventPriority;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.InterModComms; import net.neoforged.fml.InterModComms;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.event.lifecycle.InterModProcessEvent; import net.neoforged.fml.event.lifecycle.InterModProcessEvent;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.client.modeloverride.ModelOverrideHandler;
import tschipp.carryon.common.config.ListHandler; import tschipp.carryon.common.config.ListHandler;
import java.util.stream.Stream; import java.util.stream.Stream;
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD, modid = Constants.MOD_ID) @EventBusSubscriber(modid = Constants.MOD_ID)
public class ModBusEvents { public class ModBusEvents {
@SubscribeEvent(priority = EventPriority.LOW) @SubscribeEvent(priority = EventPriority.LOW)

View File

@ -21,18 +21,15 @@
package tschipp.carryon.events; package tschipp.carryon.events;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent;
import tschipp.carryon.Constants; import tschipp.carryon.Constants;
import tschipp.carryon.client.keybinds.CarryOnKeybinds; import tschipp.carryon.client.keybinds.CarryOnKeybinds;
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD, modid = Constants.MOD_ID, value = Dist.CLIENT) @EventBusSubscriber(modid = Constants.MOD_ID, value = Dist.CLIENT)
public class ModClientEvents public class ModClientEvents
{ {
@OnlyIn(Dist.CLIENT)
@SubscribeEvent @SubscribeEvent
public static void registerKeybinds(RegisterKeyMappingsEvent event) public static void registerKeybinds(RegisterKeyMappingsEvent event)
{ {

View File

@ -20,14 +20,11 @@
package tschipp.carryon.platform; package tschipp.carryon.platform;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.codec.StreamDecoder;
import net.minecraft.network.codec.StreamMemberEncoder;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.neoforged.fml.ModList; import net.neoforged.fml.ModList;
@ -36,14 +33,15 @@ import net.neoforged.neoforge.network.PacketDistributor;
import net.neoforged.neoforge.network.handling.IPayloadHandler; import net.neoforged.neoforge.network.handling.IPayloadHandler;
import net.neoforged.neoforge.network.registration.PayloadRegistrar; import net.neoforged.neoforge.network.registration.PayloadRegistrar;
import tschipp.carryon.CarryOnCommonClient; import tschipp.carryon.CarryOnCommonClient;
import tschipp.carryon.CarryOnNeoForge;
import tschipp.carryon.CarryOnNeoForgeClient;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.config.BuiltConfig; import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.neoforge.ConfigLoaderImpl; import tschipp.carryon.config.neoforge.ConfigLoaderImpl;
import tschipp.carryon.networking.PacketBase; import tschipp.carryon.networking.PacketBase;
import tschipp.carryon.networking.serverbound.ServerboundCarryKeyPressedPacket;
import tschipp.carryon.platform.services.IPlatformHelper; import tschipp.carryon.platform.services.IPlatformHelper;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Function;
public class NeoForgePlatformHelper implements IPlatformHelper { public class NeoForgePlatformHelper implements IPlatformHelper {
@ -62,7 +60,7 @@ public class NeoForgePlatformHelper implements IPlatformHelper {
@Override @Override
public boolean isDevelopmentEnvironment() { public boolean isDevelopmentEnvironment() {
return !FMLLoader.isProduction(); return !FMLLoader.getCurrent().isProduction();
} }
@Override @Override
@ -70,6 +68,7 @@ public class NeoForgePlatformHelper implements IPlatformHelper {
ConfigLoaderImpl.registerConfig(cfg); ConfigLoaderImpl.registerConfig(cfg);
} }
@SuppressWarnings("unchecked")
@Override @Override
public <T extends PacketBase, B extends FriendlyByteBuf> void registerServerboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args) { public <T extends PacketBase, B extends FriendlyByteBuf> void registerServerboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args) {
PayloadRegistrar registrar = (PayloadRegistrar) args[0]; PayloadRegistrar registrar = (PayloadRegistrar) args[0];
@ -83,6 +82,7 @@ public class NeoForgePlatformHelper implements IPlatformHelper {
registrar.playToServer(type, (StreamCodec<RegistryFriendlyByteBuf, T>)codec, serverHandler); registrar.playToServer(type, (StreamCodec<RegistryFriendlyByteBuf, T>)codec, serverHandler);
} }
@SuppressWarnings("unchecked")
@Override @Override
public <T extends PacketBase, B extends FriendlyByteBuf> void registerClientboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args) public <T extends PacketBase, B extends FriendlyByteBuf> void registerClientboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args)
{ {
@ -99,12 +99,22 @@ public class NeoForgePlatformHelper implements IPlatformHelper {
@Override @Override
public void sendPacketToServer(ResourceLocation id, PacketBase packet) { public void sendPacketToServer(Identifier id, PacketBase packet) {
PacketDistributor.sendToServer(packet); CarryOnNeoForgeClient.sendPacketToServer(packet);
} }
@Override @Override
public void sendPacketToPlayer(ResourceLocation id, PacketBase packet, ServerPlayer player) { public void sendPacketToPlayer(Identifier id, PacketBase packet, ServerPlayer player) {
PacketDistributor.sendToPlayer(player, packet); PacketDistributor.sendToPlayer(player, packet);
} }
@Override
public CarryOnData getCarryData(Player player) {
return player.getData(CarryOnNeoForge.CARRY_ON_DATA_ATTACHMENT);
}
@Override
public void setCarryData(Player player, CarryOnData data) {
player.setData(CarryOnNeoForge.CARRY_ON_DATA_ATTACHMENT, data);
}
} }

View File

@ -12,5 +12,4 @@
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1
} }
//"refmap": "${refmap_target}refmap.json"
} }

Some files were not shown because too many files have changed in this diff Show More