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 1643 additions and 1372 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
run
runs
# vscode
.vscode/*

View File

@ -1,58 +1,51 @@
plugins {
id 'idea'
id 'java'
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"))
}
id 'multiloader-common'
id 'net.neoforged.moddev'
}
repositories {
maven {
name = "Shedaniel"
url "https://maven.shedaniel.me/"
}
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 {
compileOnly group:'org.spongepowered', name:'mixin', version:'0.8.5'
implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1'
compileOnly group: 'org.spongepowered', name: 'mixin', version: '0.8.5'
// fabric and neoforge both bundle mixinextras, so it is safe to use it in common
implementation("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}")
}
processResources {
def buildProps = project.properties.clone()
filesMatching(['pack.mcmeta']) {
expand buildProps
configurations {
commonJava {
canBeResolved = false
canBeConsumed = true
}
commonResources {
canBeResolved = false
canBeConsumed = true
}
}
publishing {
publications {
mavenJava(MavenPublication) {
groupId project.group
artifactId base.archivesName .get()
version project.version
from components.java
}
}
repositories {
maven {
url "file://" + System.getenv("local_maven")
}
}
artifacts {
commonJava sourceSets.main.java.sourceDirectories.singleFile
commonResources sourceSets.main.resources.sourceDirectories.singleFile
}

View File

@ -26,10 +26,7 @@ import net.minecraft.core.HolderLookup;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.RegistrySetBuilder;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
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.player.Inventory;
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.command.CommandCarryOn;
import tschipp.carryon.config.ConfigLoader;
import tschipp.carryon.networking.clientbound.ClientboundStartRidingOtherPlayerPacket;
import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket;
import tschipp.carryon.networking.clientbound.ClientboundSyncScriptsPacket;
import tschipp.carryon.networking.serverbound.ServerboundCarryKeyPressedPacket;
@ -83,6 +81,14 @@ public class CarryOnCommon
ClientboundSyncScriptsPacket::handle,
args
);
Services.PLATFORM.registerClientboundPacket(
ClientboundStartRidingOtherPlayerPacket.TYPE,
ClientboundStartRidingOtherPlayerPacket.class,
ClientboundStartRidingOtherPlayerPacket.CODEC,
ClientboundStartRidingOtherPlayerPacket::handle,
args
);
}
public static void registerConfig()
@ -102,20 +108,19 @@ public class CarryOnCommon
CarryOnData carry = CarryOnDataManager.getCarryData(player);
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())
{
String cmd = carry.getActiveScript().get().scriptEffects().commandLoop();
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();
inv.selected = carry.getSelected();
inv.setSelectedSlot(carry.getSelected());
}
}
@ -149,7 +154,7 @@ public class CarryOnCommon
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);
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))
return 1;

View File

@ -34,11 +34,11 @@ public class CarryOnCommonClient
Player player = mc.player;
if(player != null) {
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);
carry.setKeyPressed(true);
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);
carry.setKeyPressed(false);
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;
if(player != null) {
if (player != null) {
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if(carry.isCarrying())
{
player.getInventory().selected = carry.getSelected();
if (carry.isCarrying()) {
int wantedSlot = carry.getSelected();
if (player.getInventory().getSelectedSlot() != wantedSlot) {
player.getInventory().setSelectedSlot(wantedSlot);
}
}
}
}
@ -68,4 +64,4 @@ public class CarryOnCommonClient
{
return Minecraft.getInstance().player;
}
}
}

View File

@ -20,7 +20,7 @@
package tschipp.carryon;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.Client CLIENT_CONFIG = new CarryConfig.Client();
public static final ResourceLocation PACKET_ID_KEY_PRESSED = ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "key_pressed");
public static final ResourceLocation PACKET_ID_START_RIDING = ResourceLocation.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_KEY_PRESSED = Identifier.fromNamespaceAndPath(Constants.MOD_ID, "key_pressed");
public static final Identifier PACKET_ID_START_RIDING = Identifier.fromNamespaceAndPath(Constants.MOD_ID, "start_riding");
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 net.minecraft.client.KeyMapping;
import net.minecraft.client.KeyMapping.Category;
import net.minecraft.resources.Identifier;
import tschipp.carryon.Constants;
import tschipp.carryon.networking.serverbound.ServerboundCarryKeyPressedPacket;
import tschipp.carryon.platform.Services;
@ -34,10 +36,9 @@ public class CarryOnKeybinds
public static void registerKeybinds(Consumer<KeyMapping> registrar)
{
if(Services.PLATFORM.isModLoaded("amecsapi"))
carryKey = new ConflictFreeKeyMapping("key.carry.desc", InputConstants.KEY_LSHIFT, "key.carry.category");
else
carryKey = new ConflictFreeKeyMapping("key.carry.desc", Services.PLATFORM.getPlatformName().equals("Forge") ? InputConstants.KEY_LSHIFT : InputConstants.UNKNOWN.getValue(), "key.carry.category");
Category category = Category.register(Identifier.fromNamespaceAndPath(Constants.MOD_ID,"key.carry.category"));
carryKey = new KeyMapping("key.carry.desc", InputConstants.KEY_LSHIFT, category);
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.exceptions.CommandSyntaxException;
import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import net.minecraft.commands.arguments.blocks.BlockStateParser;
import net.minecraft.commands.arguments.blocks.BlockStateParser.BlockResult;
@ -40,22 +39,13 @@ import tschipp.carryon.common.scripting.Matchables.NBTCondition;
import javax.annotation.Nullable;
import java.util.Map;
public class ModelOverride
{
//public static Codec<ModelOverride> CODEC = Codec.STRING.comapFlatMap(ModelOverride::of, override -> override.raw);
private String raw;
public class ModelOverride {
private BlockResult parsedBlock;
private Type type;
private Either<ItemResult, BlockResult> parsedRHS;
private Either<ItemStack, BlockState> renderObject;
private ModelOverride(String raw, BlockResult parsedBlock, Type type, Either<ItemResult, BlockResult> parsedRHS)
{
this.raw = raw;
this.parsedBlock = parsedBlock;
this.type = type;
this.parsedRHS = parsedRHS;
parsedRHS.ifLeft(res -> {
ItemStack stack = new ItemStack(res.item());

View File

@ -20,67 +20,42 @@
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.Tesselator;
import com.mojang.math.Axis;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.MultiBufferSource.BufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.SubmitNodeCollector;
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.rendertype.RenderTypes;
import net.minecraft.client.renderer.state.CameraRenderState;
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.HumanoidArm;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
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.CarryType;
import tschipp.carryon.common.carry.CarryOnDataManager;
import tschipp.carryon.common.scripting.CarryOnScript;
import tschipp.carryon.common.scripting.CarryOnScript.ScriptRender;
import tschipp.carryon.platform.Services;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.SequencedMap;
public class CarriedObjectRender
{
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)
public static boolean draw(Player player, PoseStack matrix, int light, float partialTicks,SubmitNodeCollector nodeCollector, boolean firstPerson)
{
if(Services.PLATFORM.isModLoaded("firstperson") || Services.PLATFORM.isModLoaded("firstpersonmod"))
if(Services.PLATFORM.isModLoaded("firstperson") || Services.PLATFORM.isModLoaded("firstpersonmod") || player == null)
return false;
CarryOnData carry = CarryOnDataManager.getCarryData(player);
try {
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))
drawFirstPersonEntity(player, buffer, matrix, light, partialTicks);
drawEntity(player, matrix, light, partialTicks, nodeCollector, firstPerson);
}
catch (Exception e)
{
@ -100,193 +75,59 @@ public class CarriedObjectRender
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);
ItemStackRenderState renderState = new ItemStackRenderState();
var layer = renderState.newLayer();
layer.setRenderType(RenderTypes.glint());
if (Constants.CLIENT_CONFIG.facePlayer != CarryRenderHelper.isChest(state.getBlock())) {
matrix.mulPose(Axis.YP.rotationDegrees(180));
matrix.mulPose(Axis.XN.rotationDegrees(8));
} else {
matrix.mulPose(Axis.XP.rotationDegrees(8));
}
matrix.pushPose();
if(carry.getActiveScript().isPresent())
CarryRenderHelper.performScriptTransformation(matrix, carry.getActiveScript().get());
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_BLOCKS);
PoseStack renderPose = CarryRenderHelper.setupBlockTransformations(player, matrix, carry, firstPerson);
ItemStack renderStack = CarryRenderHelper.getRenderItemStack(player);
Minecraft.getInstance().getItemModelResolver().updateForTopItem(renderState, renderStack, ItemDisplayContext.NONE, false, player.level(), null, 0);
renderState.render(matrix, buffer, light, OverlayTexture.NO_OVERLAY);
RenderSystem.enableCull();
RenderSystem.disableBlend();
Minecraft.getInstance().getItemModelResolver().updateForTopItem(renderState, renderStack, ItemDisplayContext.NONE, player.level(), null, 0);
renderState.submit(renderPose, nodeCollector, light, OverlayTexture.NO_OVERLAY, 0);
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();
Entity entity = CarryRenderHelper.getRenderEntity(player);
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (entity != null)
{
Vec3 playerpos = CarryRenderHelper.getExactPos(player, partialTicks);
if (entity == null)
return;
entity.setPos(playerpos.x, playerpos.y, playerpos.z);
entity.xRotO = 0.0f;
entity.yRotO = 0.0f;
entity.setYHeadRot(0.0f);
Vec3 playerpos = CarryRenderHelper.getExactPos(player, partialTicks);
float height = entity.getBbHeight();
float width = entity.getBbWidth();
entity.setPos(playerpos.x, playerpos.y, playerpos.z);
entity.xRotO = 0.0f;
entity.yRotO = 0.0f;
entity.setYHeadRot(0.0f);
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);
matrix.pushPose();
manager.setRenderShadow(false);
CarryRenderHelper.setupEntityTransformations(player, matrix, carry, firstPerson);
Optional<CarryOnScript> res = carry.getActiveScript();
if(res.isPresent())
{
CarryOnScript script = res.get();
CarryRenderHelper.performScriptTransformation(matrix, script);
}
if (entity instanceof LivingEntity)
((LivingEntity) entity).hurtTime = 0;
if (entity instanceof LivingEntity)
((LivingEntity) entity).hurtTime = 0;
try {
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 {
manager.render(entity, 0, 0, 0, 0f, matrix, buffer, light);
}
catch (Exception e)
{
}
manager.setRenderShadow(true);
matrix.popPose();
if(!firstPerson)
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.math.Axis;
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.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
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.storage.TagValueInput;
import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.joml.Quaternionf;
@ -80,91 +74,60 @@ public class CarryRenderHelper
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();
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.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))
{
matrix.translate(0, -0.4, 0);
}
if (pose == Pose.SWIMMING)
if (pose == Pose.SWIMMING || pose == Pose.FALL_FLYING)
{
float f = player.getSwimAmount(partialticks);
float f3 = player.isInWater() ? -90.0F - player.xRotO : -90.0F;
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);
matrix.translate(0, 0, 2.5);
matrix.mulPose(Axis.XP.rotationDegrees(90));
}
if (pose == Pose.FALL_FLYING)
{
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);
matrix.translate(0, -0.5, 0.65);
}
public static void applyBlockTransformations(Player player, float partialticks, PoseStack matrix, Block block)
{
int perspective = CarryRenderHelper.getPerspective();
public static PoseStack setupBlockTransformations(Player player, PoseStack matrix, CarryOnData carry, boolean firstPerson) {
if (firstPerson) {
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))
{
@ -173,61 +136,72 @@ public class CarryRenderHelper
// matrix.translate(0, 0, -0.4);
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 offset = (height - 1f) / 1.2f;
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();
applyGeneralTransformations(player, partialticks, matrix);
applyGeneralTransformations(player, matrix);
if (perspective == 2)
matrix.translate(0, -1.6, 0.65);
else
matrix.translate(0, -1.6, -0.65);
matrix.mulPose(Axis.XP.rotationDegrees(180));
matrix.translate(0, -3.1, -0.65);
matrix.scale(1.666f, 1.666f, 1.666f);
float height = entity.getBbHeight();
float width = entity.getBbWidth();
float multiplier = height * width;
float multiplier = Math.min(9.9f, height * width) ;
entity.yo = 0.0f;
entity.yRotO = 0.0f;
entity.setYHeadRot(0.0f);
entity.xo = 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.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)
{
matrix.mulPose(Axis.XN.rotationDegrees(90));
matrix.translate(0, -0.2 * height, 0);
if (pose == Pose.FALL_FLYING)
matrix.translate(0, 0, 0.2);
matrix.mulPose(Axis.XN.rotationDegrees(180));
matrix.translate(0, 0.2 * height - 2, -0.5);
}
if(Constants.CLIENT_CONFIG.rotateEntitiesSideways)
matrix.mulPose(Axis.YP.rotationDegrees(90));
}
@ -374,8 +348,10 @@ public class CarryRenderHelper
if(render.renderNameEntity().isPresent())
entity = BuiltInRegistries.ENTITY_TYPE.get(render.renderNameEntity().get()).get().value().create(player.level(), EntitySpawnReason.EVENT);
if(render.renderNBT().isPresent())
entity.load(render.renderNBT().get());
if(render.renderNBT().isPresent()) {
ValueInput input = TagValueInput.create(new ProblemReporter.ScopedCollector(Constants.LOG), player.registryAccess(), render.renderNBT().get());
entity.load(input);
}
}
return entity;
@ -403,7 +379,10 @@ public class CarryRenderHelper
else if(carry.isCarrying(CarryType.ENTITY))
{
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
return 1f;
@ -461,7 +440,7 @@ public class CarryRenderHelper
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;
import net.minecraft.world.entity.player.Player;
import tschipp.carryon.common.carry.CarryOnData;
public interface ICarryOnRenderState {
@ -12,4 +13,8 @@ public interface ICarryOnRenderState {
void setRenderWidth(float val);
Player getPlayer();
void setPlayer(Player player);
}

View File

@ -20,6 +20,7 @@
package tschipp.carryon.common.carry;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
@ -28,20 +29,29 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.NbtUtils;
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.util.ProblemReporter;
import net.minecraft.world.entity.AreaEffectCloud;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
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.common.scripting.CarryOnScript;
import javax.annotation.Nullable;
import java.util.Optional;
import java.util.UUID;
public class CarryOnData {
@ -50,18 +60,40 @@ public class CarryOnData {
private boolean keyPressed = false;
private CarryOnScript activeScript;
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)
{
if(data.contains("type"))
this.type = CarryType.valueOf(data.getString("type"));
this.type = CarryType.valueOf(data.getStringOr("type", "INVALID"));
else
this.type = CarryType.INVALID;
this.nbt = data;
if(data.contains("keyPressed"))
this.keyPressed = data.getBoolean("keyPressed");
this.keyPressed = data.getBooleanOr("keyPressed", false);
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);});
}
if(data.contains("selected"))
this.selectedSlot = data.getInt("selected");
this.selectedSlot = data.getIntOr("selected", 0);
}
public CarryType getType()
{
return this.type;
}
public CompoundTag getNbt()
{
nbt.putString("type", type.toString());
@ -91,9 +127,9 @@ public class CarryOnData {
public CompoundTag getContentNbt()
{
if(type == CarryType.BLOCK && nbt.contains("block"))
return nbt.getCompound("block");
return nbt.getCompoundOrEmpty("block");
else if(type == CarryType.ENTITY && nbt.contains("entity"))
return nbt.getCompound("entity");
return nbt.getCompoundOrEmpty("entity");
return null;
}
@ -109,7 +145,9 @@ public class CarryOnData {
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);
}
}
@ -119,7 +157,7 @@ public class CarryOnData {
if(this.type != CarryType.BLOCK)
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
@ -131,14 +169,15 @@ public class CarryOnData {
if(!nbt.contains("tile"))
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)
{
this.type = CarryType.ENTITY;
CompoundTag entityData = new CompoundTag();
entity.save(entityData);
TagValueOutput output = TagValueOutput.createWithContext(new ProblemReporter.ScopedCollector(Constants.LOG), entity.registryAccess());
entity.save(output);
Tag entityData = output.buildResult();
nbt.put("entity", entityData);
}
@ -147,7 +186,8 @@ public class CarryOnData {
if(this.type != CarryType.ENTITY)
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())
return optionalEntity.get();
@ -168,8 +208,20 @@ public class CarryOnData {
this.activeScript = script;
}
public void setCarryingPlayer() {
public void setCarryingPlayer(Player 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()
@ -210,11 +262,14 @@ public class CarryOnData {
public int getTick()
{
if(!this.nbt.contains("tick"))
return -1;
return this.nbt.getInt("tick");
return this.nbt.getIntOr("tick", -1);
}
public void setTick(int tick) {
this.nbt.putInt("tick", tick);
}
public enum CarryType {
BLOCK,
ENTITY,

View File

@ -20,29 +20,21 @@
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 tschipp.carryon.platform.Services;
public class CarryOnDataManager {
public static CarryOnData getCarryData(Player player)
{
return ((ICarrying)player).getCarryOnData();
return Services.PLATFORM.getCarryData(player);
}
public static void setCarryData(Player player, CarryOnData data)
{
((ICarrying)player).setCarryOnData(data);
}
public interface ICarrying {
void setCarryOnData(CarryOnData data);
CarryOnData getCarryOnData();
data.setSelected(player.getInventory().getSelectedSlot());
data.setTick(player.tickCount);
Services.PLATFORM.setCarryData(player, data);
}
}

View File

@ -25,26 +25,30 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.AgeableMob;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.*;
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.player.Player;
import net.minecraft.world.level.GameType;
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.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 tschipp.carryon.CarryOnCommon;
import tschipp.carryon.Constants;
import tschipp.carryon.common.config.ListHandler;
import tschipp.carryon.common.pickupcondition.PickupCondition;
import tschipp.carryon.common.pickupcondition.PickupConditionHandler;
import tschipp.carryon.common.scripting.CarryOnScript;
import tschipp.carryon.common.scripting.ScriptManager;
import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket;
import tschipp.carryon.networking.clientbound.ClientboundStartRidingOtherPlayerPacket;
import tschipp.carryon.platform.Services;
import javax.annotation.Nullable;
@ -92,16 +96,26 @@ public class PickupHandler {
BlockEntity blockEntity = level.getBlockEntity(pos);
BlockState state = level.getBlockState(pos);
CompoundTag nbt = null;
if(blockEntity != null)
nbt = blockEntity.saveWithId(level.registryAccess());
if(blockEntity != null) {
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()))
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;
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;
//Check if TE is locked
@ -122,7 +136,6 @@ public class PickupHandler {
if(!doPickup)
return false;
Optional<CarryOnScript> result = ScriptManager.inspectBlock(state, level, pos, nbt);
if(result.isPresent())
{
CarryOnScript script = result.get();
@ -133,7 +146,7 @@ public class PickupHandler {
String cmd = script.scriptEffects().commandInit();
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);
@ -144,6 +157,8 @@ public class PickupHandler {
CarryOnDataManager.setCarryData(player, carry);
level.playSound(null, pos, state.getSoundType().getHitSound(), SoundSource.BLOCKS, 1.0f, 0.5f);
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;
}
@ -162,23 +177,29 @@ public class PickupHandler {
if (entity instanceof TamableAnimal tame)
{
UUID owner = tame.getOwnerUUID();
UUID playerID = player.getGameProfile().getId();
if (owner != null && !owner.equals(playerID))
return false;
EntityReference<LivingEntity> ref = tame.getOwnerReference();
if (ref != null) {
UUID owner = ref.getUUID();
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))
{
//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;
}
//Non-Creative only guards
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;
if(Constants.COMMON_CONFIG.settings.maxEntityHeight < entity.getBbHeight() || Constants.COMMON_CONFIG.settings.maxEntityWidth < entity.getBbWidth())
@ -192,13 +213,12 @@ public class PickupHandler {
return false;
}
boolean doPickup = pickupCallback == null ? true : pickupCallback.apply(entity);
boolean doPickup = pickupCallback == null || pickupCallback.apply(entity);
if(!doPickup)
return false;
CarryOnData carry = CarryOnDataManager.getCarryData(player);
Optional<CarryOnScript> result = ScriptManager.inspectEntity(entity);
if(result.isPresent())
{
CarryOnScript script = result.get();
@ -221,15 +241,17 @@ public class PickupHandler {
if (result.isPresent()) {
String cmd = result.get().scriptEffects().commandInit();
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);
Services.PLATFORM.sendPacketToPlayer(Constants.PACKET_ID_START_RIDING, new ClientboundStartRidingPacket(otherPlayer.getId(), true), player);
carry.setCarryingPlayer();
otherPlayer.startRiding(player, true, false);
Services.PLATFORM.sendPacketToAllPlayers(Constants.PACKET_ID_START_RIDING_OTHER, new ClientboundStartRidingOtherPlayerPacket(player.getId(), otherPlayer.getId(), true), player.level());
carry.setCarryingPlayer(otherPlayer);
player.swing(InteractionHand.MAIN_HAND, true);
player.level().playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC.value(), SoundSource.AMBIENT, 1.0f, 0.5f);
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;
}
@ -244,7 +266,7 @@ public class PickupHandler {
{
String cmd = result.get().scriptEffects().commandInit();
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);
@ -253,7 +275,17 @@ public class PickupHandler {
player.level().playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC.value(), SoundSource.AMBIENT, 1.0f, 0.5f);
CarryOnDataManager.setCarryData(player, carry);
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;
}
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.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
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.context.BlockPlaceContext;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
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.Property;
import net.minecraft.world.level.gamerules.GameRules;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
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.config.ListHandler;
import tschipp.carryon.common.scripting.CarryOnScript.ScriptEffects;
import tschipp.carryon.networking.clientbound.ClientboundStartRidingOtherPlayerPacket;
import tschipp.carryon.platform.Services;
import javax.annotation.Nullable;
import java.util.ArrayList;
@ -90,11 +92,14 @@ public class PlacementHandler
if (!doPlace)
return false;
if(level.isOutsideBuildHeight(pos))
return false;
if (carry.getActiveScript().isPresent()) {
ScriptEffects effects = carry.getActiveScript().get().scriptEffects();
String cmd = effects.commandPlace();
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);
@ -109,6 +114,7 @@ public class PlacementHandler
player.playSound(state.getSoundType().getPlaceSound(), 1.0f, 0.5f);
level.playSound(null, pos, state.getSoundType().getPlaceSound(), SoundSource.BLOCKS, 1.0f, 0.5f);
player.swing(InteractionHand.MAIN_HAND, true);
player.removeEffect(MobEffects.SLOWNESS);
return true;
}
@ -171,14 +177,14 @@ public class PlacementHandler
Vec3 placementPos = Vec3.atBottomCenterOf(pos);
if (carry.isCarrying(CarryType.PLAYER)) {
Entity otherPlayer = player.getFirstPassenger();
Entity otherPlayer = carry.getCarryingPlayer(level);
player.ejectPassengers();
Services.PLATFORM.sendPacketToAllPlayers(Constants.PACKET_ID_START_RIDING_OTHER, new ClientboundStartRidingOtherPlayerPacket(player.getId(), otherPlayer.getId(), false), player.level());
carry.clear();
CarryOnDataManager.setCarryData(player, carry);
if (otherPlayer == null)
return true;
otherPlayer.teleportTo(placementPos.x, placementPos.y, placementPos.z);
otherPlayer.teleportTo(placementPos.x, placementPos.y, placementPos.z);
player.swing(InteractionHand.MAIN_HAND, true);
player.removeEffect(MobEffects.SLOWNESS);
return true;
}
@ -193,7 +199,7 @@ public class PlacementHandler
ScriptEffects effects = carry.getActiveScript().get().scriptEffects();
String cmd = effects.commandPlace();
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);
@ -203,6 +209,7 @@ public class PlacementHandler
player.swing(InteractionHand.MAIN_HAND, true);
carry.clear();
CarryOnDataManager.setCarryData(player, carry);
player.removeEffect(MobEffects.SLOWNESS);
return true;
}
@ -222,6 +229,8 @@ public class PlacementHandler
else
entityHeld = player.getFirstPassenger();
if(entityHeld == null)
return;
double sizeHeldEntity = entityHeld.getBbHeight() * entityHeld.getBbWidth();
double distance = entityClicked.blockPosition().distSqr(player.blockPosition());
@ -248,26 +257,27 @@ public class PlacementHandler
level.addFreshEntity(entityHeld);
entityHeld.teleportTo(tempX, tempY, tempZ);
}
entityHeld.startRiding(topEntity, false);
entityHeld.startRiding(topEntity, false,false);
} else {
if (carry.isCarrying(CarryType.ENTITY)) {
entityHeld.setPos(entityClicked.getX(), entityClicked.getY(), entityClicked.getZ());
level.addFreshEntity(entityHeld);
}
entityHeld.startRiding(topEntity, false);
entityHeld.startRiding(topEntity, false,false);
}
if (carry.getActiveScript().isPresent()) {
ScriptEffects effects = carry.getActiveScript().get().scriptEffects();
String cmd = effects.commandPlace();
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);
carry.clear();
CarryOnDataManager.setCarryData(player, carry);
level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.HORSE_SADDLE, SoundSource.PLAYERS, 0.5F, 1.5F);
player.removeEffect(MobEffects.SLOWNESS);
} else {
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)
{
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)) {
CarryOnDataManager.setCarryData(newPlayer, carry);
newPlayer.getInventory().selected = oldPlayer.getInventory().selected;
newPlayer.getInventory().setSelectedSlot(oldPlayer.getInventory().getSelectedSlot());
return;
}
}
@ -311,6 +321,7 @@ public class PlacementHandler
}
carry.clear();
CarryOnDataManager.setCarryData(player, carry);
player.removeEffect(MobEffects.SLOWNESS);
}
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.network.chat.Component;
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.level.block.state.BlockState;
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").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",
"yigd:*", "domum_ornamentum:*", "connectiblechains:*",
"cobblemon:*", "snowrealmagic:*"
"cobblemon:*", "snowrealmagic:*", "forbidden_arcanus:black_hole", "domum_ornamentum:*", "sgjourney:*", "copycats:*", "expandedstorage:*", "replication:*"
};
@Property(
@ -302,7 +302,7 @@ public class CarryConfig
"animania:hamster", "animania:ferret*", "animania:hedgehog*", "animania:cart",
"animania:wagon", "mynko:*", "pixelmon:*", "mocreatures:*", "quark:totem", "vehicle:*",
"securitycraft:*", "taterzens:npc", "easy_npc:*", "bodiesbodies:dead_body", "littletiles:*",
"connectiblechains:*", "cobblemon:*", "create:*"
"connectiblechains:*", "cobblemon:*", "create:*", "swem:*", "toms_mobs:*"
};
@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_]*)?)"
)
public String[] forbiddenStacking = {
"minecraft:horse"
"minecraft:horse",
"minecraft:ender_dragon"
};
}
@ -351,6 +352,12 @@ public class CarryConfig
)
public boolean facePlayer = false;
@Property(
type = PropertyType.BOOLEAN,
description = "If Entities should be rotated sideways when carried"
)
public boolean rotateEntitiesSideways = false;
@Property(
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)"

View File

@ -22,7 +22,7 @@ package tschipp.carryon.common.config;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.tags.TagKey;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
@ -119,8 +119,8 @@ public class ListHandler {
ALLOWED_TILES_TAGS.clear();
PROPERTY_EXCEPTION_CLASSES.clear();
Map<ResourceLocation, 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<Block>> blocktags = BuiltInRegistries.BLOCK.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));
forbidden.add("#carryon:block_blacklist");
@ -152,7 +152,7 @@ public class ListHandler {
continue;
String name = propString.substring(0, 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 (Property<?> prop : blk.defaultBlockState().getProperties()) {
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);
TagKey<T> t = tagMap.get(ResourceLocation.parse(sub));
TagKey<T> t = tagMap.get(Identifier.parse(sub));
if (t != null)
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++)
{
String curr = entries.get(i);
@ -181,7 +181,7 @@ public class ListHandler {
{
String[] filter = curr.replace("*", ",").split(",");
for (ResourceLocation key : keys)
for (Identifier key : keys)
{
if (containsAll(key.toString(), filter))

View File

@ -39,12 +39,13 @@ public record CarryOnScript(
ScriptObject scriptObject,
ScriptConditions scriptConditions,
ScriptRender scriptRender,
ScriptEffects scriptEffects)
ScriptEffects scriptEffects,
boolean overrideChecks)
{
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()
@ -63,7 +64,8 @@ public record CarryOnScript(
ScriptObject.CODEC.fieldOf("object").forGetter(CarryOnScript::scriptObject),
ScriptConditions.CODEC.optionalFieldOf("conditions", ScriptConditions.EMPTY).forGetter(CarryOnScript::scriptConditions),
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)
);

View File

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

View File

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

View File

@ -20,28 +20,21 @@
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.DataResult;
import com.mojang.serialization.JsonOps;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag;
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.packs.resources.ResourceManager;
import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener;
import net.minecraft.util.profiling.ProfilerFiller;
import org.jetbrains.annotations.NotNull;
import tschipp.carryon.Constants;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.networking.clientbound.ClientboundSyncScriptsPacket;
import tschipp.carryon.platform.Services;
import java.util.Collections;
import java.util.Map;
public class ScriptReloadListener extends SimpleJsonResourceReloadListener<CarryOnScript>
@ -52,7 +45,7 @@ public class ScriptReloadListener extends SimpleJsonResourceReloadListener<Carry
}
@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();

View File

@ -4,13 +4,11 @@ import me.shedaniel.clothconfig2.api.ConfigBuilder;
import me.shedaniel.clothconfig2.api.ConfigCategory;
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
import me.shedaniel.clothconfig2.impl.builders.SubCategoryBuilder;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import tschipp.carryon.config.AnnotationData;
import tschipp.carryon.config.BuiltCategory;
import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.ConfigLoader;
import javax.annotation.Nullable;
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) {
ConfigBuilder builder = ConfigBuilder.create()
.setParentScreen(parentScreen)
.setTitle(Component.translatable("key.carry.category"));
.setTitle(Component.translatable("key.category.carryon.key.carry.category"));
buildConfigType(client, builder, "Client 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;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
@ -47,6 +48,13 @@ public abstract class EntityMixin
@Shadow
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);
@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"))
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);
if(carry.isCarrying(CarryType.PLAYER)) {

View File

@ -23,13 +23,14 @@ public class EntityRendererMixin {
shift = At.Shift.AFTER
), 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) {
if (entity instanceof Player player) {
CarryOnData carry = CarryOnDataManager.getCarryData(player);
ICarryOnRenderState carryOnRenderState = (ICarryOnRenderState) state;
carryOnRenderState.setCarryOnData(carry);
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.geom.ModelPart;
import net.minecraft.client.renderer.entity.state.HumanoidRenderState;
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
import net.minecraft.world.phys.Vec3;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@ -51,7 +50,7 @@ public class HumanoidModelMixin {
if(state instanceof ICarryOnRenderState carryOnRenderState && Constants.CLIENT_CONFIG.renderArms)
{
CarryOnData carry = carryOnRenderState.getCarryOnData();
if(carry.isCarrying() && !state.isVisuallySwimming && !state.isFallFlying)
if(carry != null && carry.isCarrying() && !state.isVisuallySwimming && !state.isFallFlying)
{
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.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnDataManager;
@Mixin(Inventory.class)
@ -76,10 +76,11 @@ public class InventoryMixin
info.cancel();
}
@Inject(method = "setSelectedHotbarSlot(I)V", at = @At("HEAD"), cancellable = true)
private void onSwapPaint(int $$0, CallbackInfo info)
@Inject(method = "setSelectedSlot(I)V", at = @At("HEAD"), cancellable = true)
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();
}
}

View File

@ -25,15 +25,27 @@ import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.player.Inventory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import tschipp.carryon.common.carry.CarryOnDataManager;
@Mixin(Minecraft.class)
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
private boolean allowSlotSelection(Inventory inv,int slot)
{
return !CarryOnDataManager.getCarryData(inv.player).isCarrying();
}
public class MinecraftMixin {
@WrapWithCondition(
method = "handleKeybinds()V",
at = @At(
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;
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.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.storage.ValueInput;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnData.CarryType;
import tschipp.carryon.common.carry.CarryOnDataManager;
import java.util.Optional;
@Mixin(Player.class)
public abstract class PlayerMixin extends LivingEntity implements CarryOnDataManager.ICarrying {
@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();
public abstract class PlayerMixin extends LivingEntity {
private PlayerMixin(EntityType<? extends LivingEntity> type, Level level) {
super(type, level);
}
@Inject(method = "defineSynchedData(Lnet/minecraft/network/syncher/SynchedEntityData$Builder;)V", at = @At("RETURN"))
private void onDefineSynchedData(SynchedEntityData.Builder builder, CallbackInfo ci) {
builder.define(CARRY_DATA_KEY, new CompoundTag());
//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 = "readAdditionalSaveData(Lnet/minecraft/world/level/storage/ValueInput;)V", at = @At("RETURN"))
private void onReadAdditionalSaveData(ValueInput input, CallbackInfo ci)
{
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"))
private void onAddAdditionalSaveData(CompoundTag tag, CallbackInfo info)
{
CarryOnData carry = CarryOnDataManager.getCarryData((Player)(Object)this);
tag.put("CarryOnData", carry.getNbt());
}
@Inject(method = "readAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("RETURN"))
private void onReadAdditionalSaveData(CompoundTag tag, CallbackInfo info)
{
if (tag.contains("CarryOnData")) {
CarryOnData data = new CarryOnData(tag.getCompound("CarryOnData"));
setCarryOnData(data);
@Override
public void stopRiding() {
Entity entity = this.getVehicle();
if (entity instanceof Player && entity.getPassengers().size() < 2){
CarryOnData carry = CarryOnDataManager.getCarryData((Player) entity);
if (carry.getType() == CarryType.PLAYER){
carry.clear();
((Player) entity).removeEffect(MobEffects.SLOWNESS);
}
}
super.stopRiding();
}
}

View File

@ -1,12 +1,13 @@
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.Unique;
import tschipp.carryon.client.render.ICarryOnRenderState;
import tschipp.carryon.common.carry.CarryOnData;
@Mixin(PlayerRenderState.class)
@Mixin(HumanoidRenderState.class)
public class PlayerRenderStateMixin implements ICarryOnRenderState {
@Unique
@ -15,6 +16,10 @@ public class PlayerRenderStateMixin implements ICarryOnRenderState {
@Unique
public float renderWidth = 0f;
@Unique
public Player player = null;
@Unique
@Override
public CarryOnData getCarryOnData() {
@ -38,4 +43,14 @@ public class PlayerRenderStateMixin implements ICarryOnRenderState {
public void setRenderWidth(float 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;
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.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
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;
import net.minecraft.network.FriendlyByteBuf;
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.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
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.DataResult;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import tschipp.carryon.Constants;
import tschipp.carryon.common.scripting.CarryOnScript;

View File

@ -20,20 +20,15 @@
package tschipp.carryon.networking.serverbound;
import net.minecraft.network.FriendlyByteBuf;
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.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import tschipp.carryon.Constants;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnDataManager;
import tschipp.carryon.networking.PacketBase;
import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket;
import tschipp.carryon.networking.clientbound.ClientboundSyncScriptsPacket;
public record ServerboundCarryKeyPressedPacket(boolean pressed) implements PacketBase
{

View File

@ -20,19 +20,18 @@
package tschipp.carryon.platform.services;
import net.minecraft.core.HolderLookup;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
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.world.entity.player.Player;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.networking.PacketBase;
import java.util.function.BiConsumer;
import java.util.function.Function;
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);
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",
"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Ɔ",
"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",
"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": "Condiciones Personalizadas de Recogida de Entidades",
"key.carry.desc": "Cargar",
"key.carry.category": "Carry On"
"key.category.carryon.key.carry.category": "Carry On"
}

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "Condiciones Personalizadas para Recoger Entidades",
"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",
"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",
"key.carry.desc": "Saisir",
"key.carry.category": "Carry On"
"key.category.carryon.key.carry.category": "Carry On"
}

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "Egyedi entitás felvételi feltételek",
"key.carry.desc": "Cipelés",
"key.carry.category": "Carry On"
"key.category.carryon.key.carry.category": "Carry On"
}

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "Condizioni di prelievo entità personalizzate",
"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": "カスタムエンティティ持ち上げ条件",
"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": "맞춤형 개체 들기 조건",
"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": "Пользовательские условия поднятия сущности",
"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ı",
"key.carry.desc": "Taşı",
"key.carry.category": "Carry On"
"key.category.carryon.key.carry.category": "Carry On"
}

View File

@ -12,5 +12,5 @@
"carryon.category.custompickupconditions.custompickupconditionsentities": "Користувацькі умови підбору сутностей",
"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": "自定义抱起实体条件",
"key.carry.desc": "抱起",
"key.carry.category": "搬运"
"key.category.carryon.key.carry.category": "搬运"
}

View File

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

View File

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

View File

@ -1,35 +1,24 @@
plugins {
id 'java'
id 'maven-publish'
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')
id 'multiloader-loader'
id 'fabric-loom' version "${loom_version}"
}
repositories {
maven {
url "https://maven.siphalor.de/"
name "Siphalor's Maven"
name = "Shedaniel"
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 {
minecraft "com.mojang:minecraft:${minecraft_version}"
mappings loom.layered() {
@ -39,19 +28,17 @@ dependencies {
modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}"
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}") {
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 {
if (project(":Common").file("src/main/resources/${mod_id}.accesswidener").exists()) {
accessWidenerPath.set(project(":Common").file("src/main/resources/${mod_id}.accesswidener"))
def aw = project(':Common').file("src/main/resources/${mod_id}.accesswidener")
if (aw.exists()) {
accessWidenerPath.set(aw)
}
mixin {
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.fabric.api.client.keybinding.v1.KeyBindingHelper;
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.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import tschipp.carryon.client.keybinds.CarryOnKeybinds;
import tschipp.carryon.events.ClientEvents;
import tschipp.carryon.networking.PacketBase;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class CarryOnFabricClientMod implements ClientModInitializer
{

View File

@ -21,13 +21,36 @@
package tschipp.carryon;
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.events.CommonEvents;
import java.io.IOException;
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
public void onInitialize() {

View File

@ -20,7 +20,6 @@
package tschipp.carryon.compat;
import net.fabricmc.fabric.api.event.Event;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
@ -39,6 +38,7 @@ public class ArchitecturyCompat {
private static Method PLACE_BLOCK;
private static Method IS_FALSE;
@SuppressWarnings("unchecked")
private static void setup( ) {
try {
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 net.fabricmc.loader.api.FabricLoader;
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.config.*;
@ -32,7 +30,10 @@ import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
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 {
@ -149,6 +150,7 @@ public class ConfigLoaderImpl {
builder.add(category.category, categoryJson);
}
@SuppressWarnings("unchecked")
private static void buildProperty(JsonObject builder, PropertyData data) throws IllegalAccessException {
AnnotationData annotationData = data.getData();
builder.addProperty("//"+data.getId(), annotationData.description());

View File

@ -20,11 +20,8 @@
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.rendering.v1.WorldRenderEvents;
import tschipp.carryon.CarryOnCommonClient;
import tschipp.carryon.client.render.CarriedObjectRender;
public class ClientEvents {
@ -34,10 +31,6 @@ public class ClientEvents {
CarryOnCommonClient.checkForKeybinds();
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;
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.event.lifecycle.v1.CommonLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.event.player.*;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@ -54,7 +56,7 @@ public class CommonEvents {
UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> {
if(world.isClientSide)
if(world.isClientSide())
return InteractionResult.PASS;
BlockPos pos = hitResult.getBlockPos();
@ -95,7 +97,7 @@ public class CommonEvents {
UseEntityCallback.EVENT.register((player, level, hand, entity, hitResult) -> {
if(level.isClientSide)
if(level.isClientSide())
return InteractionResult.PASS;
CarryOnData carry = CarryOnDataManager.getCarryData(player);
@ -131,12 +133,10 @@ public class CommonEvents {
CarryOnCommon.onCarryTick(player);
});
ServerPlayerEvents.COPY_FROM.register(((oldPlayer, newPlayer, alive) -> {
PlacementHandler.placeCarriedOnDeath(oldPlayer, newPlayer, !alive);
}));
PlayerBlockBreakEvents.BEFORE.register(((world, player, pos, state, blockEntity) -> {
if(!CarryOnCommon.onTryBreakBlock(player))
return false;
@ -155,7 +155,23 @@ public class CommonEvents {
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;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.ItemInHandRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderBuffers;
import net.minecraft.client.renderer.SubmitNodeCollector;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import tschipp.carryon.client.render.CarriedObjectRender;
import tschipp.carryon.client.render.CarryRenderHelper;
import tschipp.carryon.platform.Services;
@Mixin(ItemInHandRenderer.class)
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)
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)
@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 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();
}

View File

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

View File

@ -20,28 +20,25 @@
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.ServerPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking.PlayPayloadHandler;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
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.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import tschipp.carryon.CarryOnFabricClientMod;
import tschipp.carryon.CarryOnFabricMod;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.fabric.ConfigLoaderImpl;
import tschipp.carryon.networking.PacketBase;
import tschipp.carryon.platform.services.IPlatformHelper;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class FabricPlatformHelper implements IPlatformHelper {
@ -67,6 +64,7 @@ public class FabricPlatformHelper implements IPlatformHelper {
ConfigLoaderImpl.registerConfig(cfg);
}
@SuppressWarnings("unchecked")
@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)
{
@ -79,6 +77,7 @@ public class FabricPlatformHelper implements IPlatformHelper {
});
}
@SuppressWarnings("unchecked")
@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)
{
@ -91,14 +90,25 @@ public class FabricPlatformHelper implements IPlatformHelper {
}
@Override
public void sendPacketToServer(ResourceLocation id, PacketBase packet)
public void sendPacketToServer(Identifier id, PacketBase packet)
{
CarryOnFabricClientMod.sendPacketToServer(packet);
}
@Override
public void sendPacketToPlayer(ResourceLocation id, PacketBase packet, ServerPlayer player)
public void sendPacketToPlayer(Identifier id, PacketBase packet, ServerPlayer player)
{
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;
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import tschipp.carryon.Constants;
import tschipp.carryon.common.scripting.ScriptReloadListener;
public class IdentifiableScriptReloadListener extends ScriptReloadListener implements IdentifiableResourceReloadListener
{
@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": {
"fabricloader": ">=${fabric_loader_version}",
"fabric-api": "*",
"minecraft": "${minecraft_version}",
"java": ">=21"
"minecraft": "${minecraft_version_range_fabric}",
"java": ">=${java_version}"
}
}

View File

@ -1,26 +1,10 @@
plugins {
id 'idea'
id 'java'
id 'maven-publish'
id 'net.minecraftforge.gradle' version '[6.0.24,6.2)'
id 'multiloader-loader'
id 'net.minecraftforge.gradle' version '[6.0.46,6.2)'
id 'org.spongepowered.mixin' version '0.7-SNAPSHOT'
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 {
archivesName = "${mod_id}-forge-${minecraft_version}"
}
@ -32,16 +16,25 @@ mixin {
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()
build.dependsOn tasks.jarJar
minecraft {
mappings channel: 'official', version: "1.21.4"
mappings channel: 'parchment', version: parchment_mappings
copyIdeResources = true
reobf = false
if (file('src/main/resources/META-INF/accesstransformer.cfg').exists()) {
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
def at = file('src/main/resources/META-INF/accesstransformer.cfg')
if (at.exists()) {
accessTransformer = at
}
runs {
@ -51,6 +44,7 @@ minecraft {
taskName 'Client'
property 'mixin.env.remapRefMap', 'true'
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"
mods {
modClientRun {
@ -66,6 +60,7 @@ minecraft {
taskName 'Server'
property 'mixin.env.remapRefMap', 'true'
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"
mods {
modServerRun {
@ -82,6 +77,7 @@ minecraft {
taskName 'Data'
property 'mixin.env.remapRefMap', 'true'
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"
mods {
modDataRun {
@ -96,17 +92,25 @@ minecraft {
sourceSets.main.resources.srcDir 'src/generated/resources'
repositories {
maven {
name = "Shedaniel"
url "https://maven.shedaniel.me/"
}
maven { url 'https://jitpack.io' }
flatDir {
dirs 'libs'
}
maven { url 'https://jitpack.io' }
}
dependencies {
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
compileOnly project(":Common")
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+
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("me.shedaniel.cloth:cloth-config-forge:${cloth_config_version}"))
compileOnly(fg.deobf("me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}"))
fileTree("libs").matching {
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 {
publications {
mavenJava(MavenPublication) {
artifactId base.archivesName.get()
from components.java
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 {
def dir = layout.buildDirectory.dir("sourcesSets/$it.name")
it.output.resourcesDir = dir

View File

@ -20,7 +20,8 @@
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.EventBusSubscriber;
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.SimpleChannel;
import tschipp.carryon.config.forge.ConfigLoaderImpl;
import tschipp.carryon.networking.ClientboundSyncCarryDataPacket;
import tschipp.carryon.platform.Services;
@Mod(Constants.MOD_ID)
@EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
@ -43,17 +46,23 @@ public class CarryOnForge {
// Use Forge to bootstrap the Common mod.
CarryOnCommon.registerConfig();
context.getModEventBus().addListener(this::setup);
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.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.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.util.LogicalSidedProvider;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.config.IConfigSpec;
import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.event.config.ModConfigEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.loading.FMLServiceProvider;
import net.minecraftforge.server.ServerLifecycleHooks;
import tschipp.carryon.config.*;
import tschipp.carryon.Constants;
import tschipp.carryon.config.AnnotationData;
import tschipp.carryon.config.BuiltCategory;
import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.PropertyData;
import java.util.*;
@Mod.EventBusSubscriber(modid = Constants.MOD_ID)
public class ConfigLoaderImpl {
public static final Map<ForgeConfigSpec, BuiltConfig> CONFIGS = new HashMap<>();
public static void initialize(FMLJavaModLoadingContext context) {
IEventBus bus = context.getModEventBus();
bus.addListener(ConfigLoaderImpl::onConfigLoad);
bus.addListener(ConfigLoaderImpl::onConfigReload);
ConfigLoaderImpl.CONFIGS.forEach((spec, config) -> {
if(config.fileName.contains("client"))
context.registerConfig(ModConfig.Type.CLIENT, spec, config.fileName+".toml");
@ -58,10 +51,12 @@ public class ConfigLoaderImpl {
});
}
@SubscribeEvent
public static void onConfigLoad(ModConfigEvent.Loading loading) {
loadConfig(loading.getConfig().getSpec());
}
@SubscribeEvent
public static void onConfigReload(ModConfigEvent.Reloading loading) {
loadConfig(loading.getConfig().getSpec());
}
@ -119,6 +114,7 @@ public class ConfigLoaderImpl {
builder.pop();
}
@SuppressWarnings("unchecked")
private static void buildProperty(ForgeConfigSpec.Builder builder, PropertyData data) throws IllegalAccessException {
AnnotationData annotationData = data.getData();
builder.comment(annotationData.description());

View File

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

View File

@ -21,6 +21,7 @@
package tschipp.carryon.events;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionResult;
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.level.Level;
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.event.AddReloadListenerEvent;
import net.minecraftforge.event.OnDatapackSyncEvent;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.TagsUpdatedEvent;
import net.minecraftforge.event.TickEvent.Phase;
import net.minecraftforge.common.util.Result;
import net.minecraftforge.event.*;
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.LivingDeathEvent;
import net.minecraftforge.event.entity.living.MobSpawnEvent.FinalizeSpawn;
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.Clone;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.level.BlockEvent;
import net.minecraftforge.event.level.BlockEvent.BreakEvent;
import net.minecraftforge.event.level.BlockEvent.EntityPlaceEvent;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.Event.Result;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.listener.Priority;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import tschipp.carryon.CarryOnCommon;
import tschipp.carryon.Constants;
import tschipp.carryon.carry.CarryOnDataCapabilityProvider;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnData.CarryType;
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.scripting.ScriptReloadListener;
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)
public class CommonEvents
{
@SubscribeEvent(priority = EventPriority.HIGH)
public static void onBlockClick(PlayerInteractEvent.RightClickBlock event)
@SubscribeEvent(priority = Priority.HIGH)
public static boolean onBlockClick(PlayerInteractEvent.RightClickBlock event)
{
if (event.isCanceled())
return;
Player player = event.getEntity();
Level level = event.getLevel();
BlockPos pos = event.getPos();
if (level.isClientSide)
return;
if (level.isClientSide())
return false;
boolean success = false;
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (!carry.isCarrying()) {
if (PickupHandler.tryPickUpBlock((ServerPlayer) player, pos, level, (pState, pPos) -> {
BlockEvent.BreakEvent breakEvent = new BreakEvent(level, pPos, pState, player);
MinecraftForge.EVENT_BUS.post(breakEvent);
return !breakEvent.isCanceled();
BlockEvent.BreakEvent breakEvent = new BreakEvent(level, pPos, pState, player, Result.DEFAULT);
return !BreakEvent.BUS.post(breakEvent);
})) {
success = true;
}
@ -93,15 +90,13 @@ public class CommonEvents
PlacementHandler.tryPlaceBlock((ServerPlayer) player, pos, event.getFace(), (pos2, state) -> {
BlockSnapshot snapshot = BlockSnapshot.create(level.dimension(), level, pos2);
EntityPlaceEvent event1 = new EntityPlaceEvent(snapshot, level.getBlockState(pos), player);
MinecraftForge.EVENT_BUS.post(event1);
return !event1.isCanceled();
return !EntityPlaceEvent.BUS.post(event1);
});
} else {
PlacementHandler.tryPlaceEntity((ServerPlayer) player, pos, event.getFace(), (pPos, toPlace) -> {
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);
MinecraftForge.EVENT_BUS.post(checkSpawn);
return event.getResult() != Result.DENY;
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);
return !FinalizeSpawn.BUS.post(checkSpawn);
}
return true;
});
@ -110,40 +105,38 @@ public class CommonEvents
}
if (success) {
event.setUseBlock(Event.Result.DENY);
event.setUseItem(Event.Result.DENY);
event.setUseBlock(Result.DENY);
event.setUseItem(Result.DENY);
event.setCancellationResult(InteractionResult.SUCCESS);
event.setCanceled(true);
return true;
}
return false;
}
@SubscribeEvent(priority = EventPriority.HIGH)
public static void onEntityRightClick(PlayerInteractEvent.EntityInteract event)
@SubscribeEvent(priority = Priority.HIGH)
public static boolean onEntityRightClick(PlayerInteractEvent.EntityInteract event)
{
if (event.isCanceled())
return;
Player player = event.getEntity();
Level level = event.getLevel();
Entity target = event.getTarget();
if (level.isClientSide)
return;
if (level.isClientSide())
return false;
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (!carry.isCarrying()) {
if (PickupHandler.tryPickupEntity((ServerPlayer) player, target, (toPickup) -> {
EntityPickupEvent pickupEvent = new EntityPickupEvent((ServerPlayer) player, toPickup);
MinecraftForge.EVENT_BUS.post(pickupEvent);
return !pickupEvent.isCanceled();
return !EntityPickupEvent.BUS.post(pickupEvent);
})) {
event.setCancellationResult(InteractionResult.SUCCESS);
event.setCanceled(true);
return;
return true;
}
} else if (carry.isCarrying(CarryType.ENTITY) || carry.isCarrying(CarryType.PLAYER)) {
PlacementHandler.tryStackEntity((ServerPlayer) player, target);
}
return false;
}
@SubscribeEvent
@ -178,15 +171,23 @@ public class CommonEvents
@SubscribeEvent
public static void onServerTick(ServerTickEvent.Post event)
{
for (ServerPlayer player : event.getServer().getPlayerList().getPlayers())
for (ServerPlayer player : event.server().getPlayerList().getPlayers())
CarryOnCommon.onCarryTick(player);
}
@SubscribeEvent
public static void onClone(Clone event)
{
if (!event.getOriginal().level().isClientSide)
PlacementHandler.placeCarriedOnDeath((ServerPlayer) event.getOriginal(), (ServerPlayer) event.getEntity(), event.isWasDeath());
if (!event.getOriginal().level().isClientSide()) {
Player newPlayer = event.getEntity();
Player oldPlayer = event.getOriginal();
oldPlayer.reviveCaps();
PlacementHandler.placeCarriedOnDeath((ServerPlayer) oldPlayer, (ServerPlayer) newPlayer, event.isWasDeath());
oldPlayer.invalidateCaps();
}
}
@SubscribeEvent
@ -197,19 +198,16 @@ public class CommonEvents
}
@SubscribeEvent
public static void attackEntity(AttackEntityEvent event)
public static boolean attackEntity(AttackEntityEvent event)
{
if(!CarryOnCommon.onAttackedByPlayer(event.getEntity()))
event.setCanceled(true);
}
return !CarryOnCommon.onAttackedByPlayer(event.getEntity());
}
@SubscribeEvent
public static void onBreakBlock(BreakEvent event)
public static boolean onBreakBlock(BreakEvent event)
{
if (!CarryOnCommon.onTryBreakBlock(event.getPlayer())) {
event.setCanceled(true);
}
}
return !CarryOnCommon.onTryBreakBlock(event.getPlayer());
}
@SubscribeEvent
public static void playerAttack(LivingAttackEvent event)
@ -218,4 +216,38 @@ public class CommonEvents
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.world.entity.Entity;
import net.minecraftforge.eventbus.api.Cancelable;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.bus.CancellableEventBus;
import net.minecraftforge.eventbus.api.event.RecordEvent;
import net.minecraftforge.eventbus.api.event.characteristic.Cancellable;
@Cancelable
public class EntityPickupEvent extends Event {
public record EntityPickupEvent(ServerPlayer player, Entity target) implements Cancellable, RecordEvent {
public final ServerPlayer player;
public final Entity target;
public EntityPickupEvent(ServerPlayer player, Entity target) {
this.player = player;
this.target = target;
}
public static final CancellableEventBus<EntityPickupEvent> BUS = CancellableEventBus.create(EntityPickupEvent.class);
}

View File

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

View File

@ -21,17 +21,13 @@
package tschipp.carryon.events;
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.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import tschipp.carryon.Constants;
import tschipp.carryon.client.keybinds.CarryOnKeybinds;
import tschipp.carryon.compat.ClothConfigCompatForge;
import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.forge.ConfigLoaderImpl;
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)
public class ModClientEvents
{
@SubscribeEvent
public static void registerKeybinds(RegisterKeyMappingsEvent event)
{
CarryOnKeybinds.registerKeybinds(event::register);
static{
RegisterKeyMappingsEvent.BUS.addListener((e)->CarryOnKeybinds.registerKeybinds(e::register));
}
@SubscribeEvent
public static void clientSetup(FMLClientSetupEvent event)
{
if(Services.PLATFORM.isModLoaded("cloth_config")) {
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)));
ConfigLoaderImpl.CONFIGS.values().toArray(new BuiltConfig[0]);
}
}
}

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;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
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.world.entity.player.Player;
import net.minecraftforge.event.network.CustomPayloadEvent;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.PacketDistributor;
import tschipp.carryon.CarryOnCommonClient;
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.forge.ConfigLoaderImpl;
import tschipp.carryon.networking.ClientboundSyncCarryDataPacket;
import tschipp.carryon.networking.PacketBase;
import tschipp.carryon.platform.services.IPlatformHelper;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class ForgePlatformHelper implements IPlatformHelper {
@ -67,6 +70,7 @@ public class ForgePlatformHelper implements IPlatformHelper {
ConfigLoaderImpl.registerConfig(cfg);
}
@SuppressWarnings("unchecked")
@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)
{
@ -83,6 +87,7 @@ public class ForgePlatformHelper implements IPlatformHelper {
CarryOnForge.network.messageBuilder(clazz).codec((StreamCodec<FriendlyByteBuf, T>) codec).consumerMainThread(serverHandler).add();
}
@SuppressWarnings("unchecked")
@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)
{
@ -101,14 +106,29 @@ public class ForgePlatformHelper implements IPlatformHelper {
@Override
public void sendPacketToServer(ResourceLocation id, PacketBase packet)
public void sendPacketToServer(Identifier id, PacketBase packet)
{
CarryOnForge.network.send(packet, PacketDistributor.SERVER.noArg());
}
@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));
}
@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
mandatory=true #mandatory
# 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
ordering="NONE"
# Side this dependency is applied on - BOTH, CLIENT or SERVER

View File

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

View File

@ -1,120 +1,174 @@
plugins {
id 'idea'
id 'maven-publish'
id 'net.neoforged.gradle.userdev' version '7.0.168'
id 'java-library'
id 'multiloader-loader'
id 'net.neoforged.moddev'
}
if (System.getenv('BUILD_NUMBER') != null) {
version += "." + System.getenv('BUILD_NUMBER')
}
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
repositories {
maven {
name = "Shedaniel"
url "https://maven.shedaniel.me/"
}
client {
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
maven { url 'https://jitpack.io' }
}
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)
}
server {
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
programArgument '--nogui'
parchment {
minecraftVersion = parchment_game_version
mappingsVersion = parchment_version
}
// 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
runs {
configureEach {
systemProperty('neoforge.enabledGameTestNamespaces', mod_id)
ideName = "NeoForge ${it.name.capitalize()} (${project.path})" // Unify the run config names with fabric
}
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.
programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
}*/
dependencies {
compileOnly "me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}"
}
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")
}
}
}
//plugins {
// id 'idea'
// id 'maven-publish'
// id 'net.neoforged.gradle.userdev' version '7.0.168'
// id 'java-library'
//}
//
//
//if (System.getenv('BUILD_NUMBER') != null) {
// version += "." + System.getenv('BUILD_NUMBER')
//}
//
//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 {
// // Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
// systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
// }
//
// 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;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.bus.api.SubscribeEvent;
import net.minecraft.nbt.CompoundTag;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.client.gui.ConfigurationScreen;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.attachment.AttachmentType;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
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 java.util.function.Supplier;
@Mod(Constants.MOD_ID)
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) {
// 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);
ConfigLoaderImpl.initialize(container);
ATTACHMENT_TYPES.register(container.getEventBus());
}
private void setup(final FMLCommonSetupEvent event)
@ -57,6 +73,8 @@ public class CarryOnNeoForge {
CarryOnCommon.registerServerPackets(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.common.Mod;
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
import net.neoforged.neoforge.client.network.ClientPacketDistributor;
import tschipp.carryon.compat.ClothConfigCompatNeo;
import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.neoforge.ConfigLoaderImpl;
import tschipp.carryon.networking.PacketBase;
import tschipp.carryon.platform.Services;
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;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.neoforged.fml.ModContainer;
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.neoforge.ConfigLoaderImpl;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Optional;
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.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.fml.ModContainer;
import net.neoforged.fml.ModLoadingContext;
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.event.config.ModConfigEvent;
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.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.function.Consumer;
@EventBusSubscriber(modid = Constants.MOD_ID, bus = EventBusSubscriber.Bus.MOD)
@EventBusSubscriber(modid = Constants.MOD_ID)
public class ConfigLoaderImpl {
public static final Map<ModConfigSpec, BuiltConfig> CONFIGS = new LinkedHashMap<>();
@ -120,6 +114,7 @@ public class ConfigLoaderImpl {
builder.pop();
}
@SuppressWarnings("unchecked")
private static void buildProperty(ModConfigSpec.Builder builder, PropertyData data) throws IllegalAccessException {
AnnotationData annotationData = data.getData();
builder.comment(annotationData.description());

View File

@ -23,16 +23,13 @@ package tschipp.carryon.events;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
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.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.bus.api.SubscribeEvent;
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.RenderHandEvent;
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
import net.neoforged.neoforge.client.event.ScreenEvent;
import tschipp.carryon.CarryOnCommonClient;
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.CarryOnDataManager;
@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, modid = Constants.MOD_ID, value = Dist.CLIENT)
@EventBusSubscriber(modid = Constants.MOD_ID, value = Dist.CLIENT)
public class ClientEvents {
@OnlyIn(Dist.CLIENT)
@SubscribeEvent
public static void renderHand(RenderHandEvent event)
{
Player player = Minecraft.getInstance().player;
MultiBufferSource buffer = event.getMultiBufferSource();
PoseStack matrix = event.getPoseStack();
int light = event.getPackedLight();
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);
}
@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
public static void onGuiInit(ScreenEvent.Init.Pre event)
{
@ -90,7 +77,6 @@ public class ClientEvents {
}
}
@OnlyIn(Dist.CLIENT)
@SubscribeEvent
public static void onClientTick(ClientTickEvent.Post event)
{

View File

@ -21,8 +21,9 @@
package tschipp.carryon.events;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.TriState;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
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.level.Level;
import net.minecraft.world.level.ServerLevelAccessor;
import net.neoforged.bus.api.Event;
import net.neoforged.bus.api.EventPriority;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.common.util.BlockSnapshot;
import net.neoforged.neoforge.common.util.TriState;
import net.neoforged.neoforge.event.*;
import net.neoforged.neoforge.event.AddServerReloadListenersEvent;
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.player.AttackEntityEvent;
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.config.ConfigLoader;
@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, modid = Constants.MOD_ID)
@EventBusSubscriber(modid = Constants.MOD_ID)
public class CommonEvents
{
@SubscribeEvent(priority = EventPriority.HIGH)
@ -68,7 +70,7 @@ public class CommonEvents
Level level = event.getLevel();
BlockPos pos = event.getPos();
if (level.isClientSide)
if (level.isClientSide())
return;
boolean success = false;
@ -122,7 +124,7 @@ public class CommonEvents
Level level = event.getLevel();
Entity target = event.getTarget();
if (level.isClientSide)
if (level.isClientSide())
return;
CarryOnData carry = CarryOnDataManager.getCarryData(player);
@ -150,7 +152,7 @@ public class CommonEvents
@SubscribeEvent
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
@ -180,7 +182,7 @@ public class CommonEvents
@SubscribeEvent
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());
}
@ -213,4 +215,17 @@ public class CommonEvents
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.fml.InterModComms;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.event.lifecycle.InterModProcessEvent;
import tschipp.carryon.Constants;
import tschipp.carryon.client.modeloverride.ModelOverrideHandler;
import tschipp.carryon.common.config.ListHandler;
import java.util.stream.Stream;
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD, modid = Constants.MOD_ID)
@EventBusSubscriber(modid = Constants.MOD_ID)
public class ModBusEvents {
@SubscribeEvent(priority = EventPriority.LOW)

View File

@ -21,18 +21,15 @@
package tschipp.carryon.events;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent;
import tschipp.carryon.Constants;
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
{
@OnlyIn(Dist.CLIENT)
@SubscribeEvent
public static void registerKeybinds(RegisterKeyMappingsEvent event)
{

View File

@ -20,14 +20,11 @@
package tschipp.carryon.platform;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
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.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
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.registration.PayloadRegistrar;
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.neoforge.ConfigLoaderImpl;
import tschipp.carryon.networking.PacketBase;
import tschipp.carryon.networking.serverbound.ServerboundCarryKeyPressedPacket;
import tschipp.carryon.platform.services.IPlatformHelper;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class NeoForgePlatformHelper implements IPlatformHelper {
@ -62,7 +60,7 @@ public class NeoForgePlatformHelper implements IPlatformHelper {
@Override
public boolean isDevelopmentEnvironment() {
return !FMLLoader.isProduction();
return !FMLLoader.getCurrent().isProduction();
}
@Override
@ -70,6 +68,7 @@ public class NeoForgePlatformHelper implements IPlatformHelper {
ConfigLoaderImpl.registerConfig(cfg);
}
@SuppressWarnings("unchecked")
@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) {
PayloadRegistrar registrar = (PayloadRegistrar) args[0];
@ -83,6 +82,7 @@ public class NeoForgePlatformHelper implements IPlatformHelper {
registrar.playToServer(type, (StreamCodec<RegistryFriendlyByteBuf, T>)codec, serverHandler);
}
@SuppressWarnings("unchecked")
@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)
{
@ -99,12 +99,22 @@ public class NeoForgePlatformHelper implements IPlatformHelper {
@Override
public void sendPacketToServer(ResourceLocation id, PacketBase packet) {
PacketDistributor.sendToServer(packet);
public void sendPacketToServer(Identifier id, PacketBase packet) {
CarryOnNeoForgeClient.sendPacketToServer(packet);
}
@Override
public void sendPacketToPlayer(ResourceLocation id, PacketBase packet, ServerPlayer player) {
public void sendPacketToPlayer(Identifier id, PacketBase packet, ServerPlayer player) {
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": {
"defaultRequire": 1
}
//"refmap": "${refmap_target}refmap.json"
}

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