Compare commits

..

14 Commits

Author SHA1 Message Date
Tschipp
c5e3c55384 updated config 2024-02-27 23:35:04 +01:00
Tschipp
52252107a0 Fixed tags not loading, updated configs 2024-02-27 23:28:42 +01:00
Tschipp
e68553e2d2 Fixed memory leak, updated blacklist 2023-11-19 23:25:40 +01:00
Tschipp
7c559cddb9 fixed bugs relating to placement 2023-08-30 22:37:25 +02:00
Tschipp
ee510adc4b stopped shipping amecs 2023-07-25 13:56:17 +02:00
Tschipp
5fe65552ef updated version number 2023-07-09 21:47:00 +02:00
Tschipp
5c27a735b5 fixed crash with amecs on 1.19.2 2023-07-09 21:45:04 +02:00
Tschipp
1ca409c43d Fixed IMC, Keybinds, other bugs 2023-07-06 17:25:45 +02:00
Tschipp
9ed3268e30
Update build.gradle 2023-04-28 22:06:05 +02:00
Tschipp
89653e84ad
Update build.gradle 2023-04-28 22:05:17 +02:00
Tschipp
f2101ae6ab
Update gradle.properties 2023-04-28 22:04:31 +02:00
Tschipp
84b303a7fd
Update build.gradle 2023-04-28 22:04:11 +02:00
Tschipp
9f0f26eb83 Fixed Bugs 2023-04-24 22:51:30 +02:00
Tschipp
e06962c125 Fixed MixinExtras by using JarJar 2023-02-01 18:28:10 +01:00
143 changed files with 1597 additions and 5228 deletions

View File

@ -1,22 +0,0 @@
---
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:

View File

@ -1,28 +0,0 @@
---
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

@ -1,20 +0,0 @@
---
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.

4
.gitignore vendored
View File

@ -21,7 +21,3 @@ build
# other
eclipse
run
runs
# vscode
.vscode/*

View File

@ -1,51 +1,60 @@
plugins {
id 'multiloader-common'
id 'net.neoforged.moddev'
id 'java'
id 'org.spongepowered.gradle.vanilla' version '0.2.1-SNAPSHOT'
id 'maven-publish'
}
archivesBaseName = "${mod_id}-common-${minecraft_version}"
minecraft {
version(minecraft_version)
runs {
if (project.hasProperty('common_runs_enabled') ? project.findProperty('common_runs_enabled').toBoolean() : true) {
server(project.hasProperty('common_server_run_name') ? project.findProperty('common_server_run_name') : 'vanilla_server') {
workingDirectory(this.file("run"))
}
client(project.hasProperty('common_client_run_name') ? project.findProperty('common_client_run_name') : 'vanilla_client') {
workingDirectory(this.file("run"))
}
}
}
}
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'
// 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}")
compileOnly group:'org.spongepowered', name:'mixin', version:'0.8.5'
implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1'
implementation("com.github.llamalad7.mixinextras:mixinextras-common:${mixinextras_version}")
annotationProcessor("com.github.llamalad7.mixinextras:mixinextras-common:${mixinextras_version}")
}
configurations {
commonJava {
canBeResolved = false
canBeConsumed = true
}
commonResources {
canBeResolved = false
canBeConsumed = true
processResources {
def buildProps = project.properties.clone()
filesMatching(['pack.mcmeta']) {
expand buildProps
}
}
artifacts {
commonJava sourceSets.main.java.sourceDirectories.singleFile
commonResources sourceSets.main.resources.sourceDirectories.singleFile
}
publishing {
publications {
mavenJava(MavenPublication) {
groupId project.group
artifactId project.archivesBaseName
version project.version
from components.java
}
}
repositories {
maven {
url "file://" + System.getenv("local_maven")
}
}
}

View File

@ -1,32 +1,10 @@
/*
* 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;
import com.mojang.brigadier.CommandDispatcher;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.RegistrySetBuilder;
import net.minecraft.core.registries.BuiltInRegistries;
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;
@ -37,7 +15,6 @@ 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;
@ -45,49 +22,36 @@ import tschipp.carryon.platform.Services;
public class CarryOnCommon
{
public static final RegistrySetBuilder BUILDER = new RegistrySetBuilder();
public static HolderLookup.Provider createLookup() {
RegistryAccess.Frozen registryaccess$frozen = RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY);
HolderLookup.Provider holderlookup$provider = BUILDER.build(registryaccess$frozen);
return holderlookup$provider;
}
public static void registerServerPackets(Object... args)
public static void registerServerPackets()
{
Services.PLATFORM.registerServerboundPacket(
ServerboundCarryKeyPressedPacket.TYPE,
Constants.PACKET_ID_KEY_PRESSED,
0,
ServerboundCarryKeyPressedPacket.class,
ServerboundCarryKeyPressedPacket.CODEC,
ServerboundCarryKeyPressedPacket::handle,
args
ServerboundCarryKeyPressedPacket::toBytes,
ServerboundCarryKeyPressedPacket::new,
ServerboundCarryKeyPressedPacket::handle
);
}
public static void registerClientPackets(Object... args)
public static void registerClientPackets()
{
Services.PLATFORM.registerClientboundPacket(
ClientboundStartRidingPacket.TYPE,
Constants.PACKET_ID_START_RIDING,
1,
ClientboundStartRidingPacket.class,
ClientboundStartRidingPacket.CODEC,
ClientboundStartRidingPacket::handle,
args
ClientboundStartRidingPacket::toBytes,
ClientboundStartRidingPacket::new,
ClientboundStartRidingPacket::handle
);
Services.PLATFORM.registerClientboundPacket(
ClientboundSyncScriptsPacket.TYPE,
Constants.PACKET_ID_SYNC_SCRIPTS,
2,
ClientboundSyncScriptsPacket.class,
ClientboundSyncScriptsPacket.CODEC,
ClientboundSyncScriptsPacket::handle,
args
);
Services.PLATFORM.registerClientboundPacket(
ClientboundStartRidingOtherPlayerPacket.TYPE,
ClientboundStartRidingOtherPlayerPacket.class,
ClientboundStartRidingOtherPlayerPacket.CODEC,
ClientboundStartRidingOtherPlayerPacket::handle,
args
ClientboundSyncScriptsPacket::toBytes,
ClientboundSyncScriptsPacket::new,
ClientboundSyncScriptsPacket::handle
);
}
@ -108,19 +72,20 @@ 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.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " 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.setSelectedSlot(carry.getSelected());
inv.selected = carry.getSelected();
}
}
@ -154,7 +119,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())
@ -165,18 +130,8 @@ 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);
}
}
}
public static int potionLevel(CarryOnData carry, Level level)
private static int potionLevel(CarryOnData carry, Level level)
{
if(carry.isCarrying(CarryType.PLAYER))
return 1;

View File

@ -1,23 +1,3 @@
/*
* 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;
import net.minecraft.client.Minecraft;
@ -34,11 +14,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())) && !carry.isKeyPressed()) {
if ((CarryOnKeybinds.carryKey.isUnbound() ? player.isShiftKeyDown() : (CarryOnKeybinds.carryKey.isDown() || checkMouse())) && !carry.isKeyPressed()) {
CarryOnKeybinds.onCarryKey(true);
carry.setKeyPressed(true);
CarryOnDataManager.setCarryData(player, carry);
} else if (!(CarryOnKeybinds.carryKey.isUnbound() ? player.isShiftKeyDown() : (CarryOnKeybinds.carryKey.isDown() ) ) && carry.isKeyPressed()) {
} else if (!(CarryOnKeybinds.carryKey.isUnbound() ? player.isShiftKeyDown() : (CarryOnKeybinds.carryKey.isDown() || checkMouse()) ) && carry.isKeyPressed()) {
CarryOnKeybinds.onCarryKey(false);
carry.setKeyPressed(false);
CarryOnDataManager.setCarryData(player, carry);
@ -46,16 +26,20 @@ 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()) {
int wantedSlot = carry.getSelected();
if (player.getInventory().getSelectedSlot() != wantedSlot) {
player.getInventory().setSelectedSlot(wantedSlot);
}
if(carry.isCarrying())
{
player.getInventory().selected = carry.getSelected();
}
}
}
@ -64,4 +48,4 @@ public class CarryOnCommonClient
{
return Minecraft.getInstance().player;
}
}
}

View File

@ -1,26 +1,6 @@
/*
* 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;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceLocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tschipp.carryon.common.config.CarryConfig;
@ -34,10 +14,8 @@ 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 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");
public static final ResourceLocation PACKET_ID_KEY_PRESSED = new ResourceLocation(Constants.MOD_ID, "key_pressed");
public static final ResourceLocation PACKET_ID_START_RIDING = new ResourceLocation(Constants.MOD_ID, "start_riding");
public static final ResourceLocation PACKET_ID_SYNC_SCRIPTS = new ResourceLocation(Constants.MOD_ID, "sync_scripts");
}

View File

@ -1,29 +1,7 @@
/*
* 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;
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;
@ -36,9 +14,10 @@ public class CarryOnKeybinds
public static void registerKeybinds(Consumer<KeyMapping> registrar)
{
Category category = Category.register(Identifier.fromNamespaceAndPath(Constants.MOD_ID,"key.carry.category"));
carryKey = new KeyMapping("key.carry.desc", InputConstants.KEY_LSHIFT, category);
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");
registrar.accept(carryKey);
}

View File

@ -0,0 +1,23 @@
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

@ -1,35 +1,16 @@
/*
* 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.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;
import net.minecraft.commands.arguments.item.ItemParser;
import net.minecraft.commands.arguments.item.ItemParser.ItemResult;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.Registry;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState;
@ -39,18 +20,27 @@ import tschipp.carryon.common.scripting.Matchables.NBTCondition;
import javax.annotation.Nullable;
import java.util.Map;
public class ModelOverride {
public class ModelOverride
{
public static Codec<ModelOverride> CODEC = Codec.STRING.comapFlatMap(ModelOverride::of, override -> override.raw);
private String raw;
private BlockResult parsedBlock;
private 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());
if(res.components() != null)
stack.applyComponents(res.components());
if(res.nbt() != null)
stack.setTag(res.nbt());
this.renderObject = Either.left(stack);
});
@ -60,10 +50,10 @@ public class ModelOverride {
});
}
public static DataResult<ModelOverride> of(String str, HolderLookup.Provider provider)
public static DataResult<ModelOverride> of(String str)
{
if(!str.contains("->"))
return DataResult.error(() -> str + " must contain -> Arrow!");
return DataResult.error(str + " must contain -> Arrow!");
String[] split = str.split("->");
String from = split[0];
String to = split[1];
@ -71,9 +61,9 @@ public class ModelOverride {
BlockResult res;
try {
res = BlockStateParser.parseForBlock(BuiltInRegistries.BLOCK, from, true);
} catch (Exception e) {
return DataResult.error(() -> "Error while parsing " + from + ":" + e.getMessage());
res = BlockStateParser.parseForBlock(Registry.BLOCK, from, true);
} catch (CommandSyntaxException e) {
return DataResult.error("Error while parsing " + from + ":" + e.getMessage());
}
Type type = Type.ITEM;
@ -89,12 +79,11 @@ public class ModelOverride {
Either<ItemResult, BlockResult> either;
try {
if(type == Type.ITEM)
either = Either.left(new ItemParser(provider).parse(new StringReader(to)));
either = Either.left(ItemParser.parseForItem(HolderLookup.forRegistry(Registry.ITEM), new StringReader(to)));
else
either = Either.right(BlockStateParser.parseForBlock(BuiltInRegistries.BLOCK, to, true));
either = Either.right(BlockStateParser.parseForBlock(Registry.BLOCK, to, true));
}catch (CommandSyntaxException e) {
String finalTo = to;
return DataResult.error(() -> "Error while parsing " + finalTo + ":" + e.getMessage());
return DataResult.error("Error while parsing " + to + ":" + e.getMessage());
}
return DataResult.success(new ModelOverride(str, res, type, either));

View File

@ -1,27 +1,6 @@
/*
* 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.modeloverride;
import com.mojang.serialization.DataResult;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.state.BlockState;
import tschipp.carryon.Constants;
@ -35,13 +14,13 @@ public class ModelOverrideHandler
{
private static List<ModelOverride> OVERRIDES = new ArrayList<>();
public static void initModelOverrides(HolderLookup.Provider provider)
public static void initModelOverrides()
{
OVERRIDES.clear();
for(String ov : Constants.CLIENT_CONFIG.modelOverrides)
{
addFromString(ov, provider);
addFromString(ov);
}
}
@ -55,9 +34,9 @@ public class ModelOverrideHandler
return Optional.empty();
}
public static void addFromString(String str, HolderLookup.Provider provider)
public static void addFromString(String str)
{
DataResult<ModelOverride> res = ModelOverride.of(str, provider);
DataResult<ModelOverride> res = ModelOverride.of(str);
if(res.result().isPresent())
{
ModelOverride override = res.result().get();

View File

@ -1,61 +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.client.render;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.math.Vector3f;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.SubmitNodeCollector;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.MultiBufferSource.BufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.client.renderer.entity.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.item.ItemDisplayContext;
import net.minecraft.world.inventory.InventoryMenu;
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 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.Map;
import java.util.Optional;
public class CarriedObjectRender
{
public static boolean draw(Player player, PoseStack matrix, int light, float partialTicks,SubmitNodeCollector nodeCollector, boolean firstPerson)
private static Map<RenderType, BufferBuilder> builders = Map.of(
RenderType.glint(), new BufferBuilder(RenderType.glint().bufferSize()),
RenderType.glintDirect(), new BufferBuilder(RenderType.glintDirect().bufferSize()),
RenderType.glintTranslucent(), new BufferBuilder(RenderType.glintTranslucent().bufferSize()),
RenderType.entityGlint(), new BufferBuilder(RenderType.entityGlint().bufferSize()),
RenderType.entityGlintDirect(), new BufferBuilder(RenderType.entityGlintDirect().bufferSize())
);
public static boolean drawFirstPerson(Player player, MultiBufferSource buffer, PoseStack matrix, int light, float partialTicks)
{
if(Services.PLATFORM.isModLoaded("firstperson") || Services.PLATFORM.isModLoaded("firstpersonmod") || player == null)
if(Services.PLATFORM.isModLoaded("firstperson") || Services.PLATFORM.isModLoaded("firstpersonmod"))
return false;
CarryOnData carry = CarryOnDataManager.getCarryData(player);
try {
if (carry.isCarrying(CarryType.BLOCK))
drawBlock(player, matrix, light, CarryRenderHelper.getRenderState(player), nodeCollector, firstPerson, partialTicks);
drawFirstPersonBlock(player, buffer, matrix, light, CarryRenderHelper.getRenderState(player));
else if (carry.isCarrying(CarryType.ENTITY))
drawEntity(player, matrix, light, partialTicks, nodeCollector, firstPerson);
drawFirstPersonEntity(player, buffer, matrix, light, partialTicks);
}
catch (Exception e)
{
@ -75,59 +73,187 @@ public class CarriedObjectRender
return carry.isCarrying();
}
private static void drawBlock(Player player, PoseStack matrix, int light, BlockState state, SubmitNodeCollector nodeCollector, boolean firstPerson, float partialTicks)
private static void drawFirstPersonBlock(Player player, MultiBufferSource buffer, PoseStack matrix, int light, BlockState state)
{
CarryOnData carry = CarryOnDataManager.getCarryData(player);
ItemStackRenderState renderState = new ItemStackRenderState();
var layer = renderState.newLayer();
layer.setRenderType(RenderTypes.glint());
matrix.pushPose();
matrix.scale(2.5f, 2.5f, 2.5f);
matrix.translate(0, -0.5, -1);
RenderSystem.enableBlend();
RenderSystem.disableCull();
PoseStack renderPose = CarryRenderHelper.setupBlockTransformations(player, matrix, carry, firstPerson);
CarryOnData carry = CarryOnDataManager.getCarryData(player);
ItemStack renderStack = CarryRenderHelper.getRenderItemStack(player);
Minecraft.getInstance().getItemModelResolver().updateForTopItem(renderState, renderStack, ItemDisplayContext.NONE, player.level(), null, 0);
renderState.submit(renderPose, nodeCollector, light, OverlayTexture.NO_OVERLAY, 0);
if (Constants.CLIENT_CONFIG.facePlayer != CarryRenderHelper.isChest(state.getBlock())) {
matrix.mulPose(Vector3f.YP.rotationDegrees(180));
matrix.mulPose(Vector3f.XN.rotationDegrees(8));
} else {
matrix.mulPose(Vector3f.XP.rotationDegrees(8));
}
if(carry.getActiveScript().isPresent())
CarryRenderHelper.performScriptTransformation(matrix, carry.getActiveScript().get());
RenderSystem.setShaderTexture(0, InventoryMenu.BLOCK_ATLAS);
ItemStack stack = new ItemStack(state.getBlock().asItem());
BakedModel model = CarryRenderHelper.getRenderBlock(player);
CarryRenderHelper.renderBakedModel(stack, matrix, buffer, light, model);
RenderSystem.enableCull();
RenderSystem.disableBlend();
matrix.popPose();
}
private static void drawEntity(Player player, PoseStack matrix, int light, float partialTicks,SubmitNodeCollector nodeCollector, boolean firstPerson) {
private static void drawFirstPersonEntity(Player player, MultiBufferSource buffer, PoseStack matrix, int light, float partialTicks) {
EntityRenderDispatcher manager = Minecraft.getInstance().getEntityRenderDispatcher();
Entity entity = CarryRenderHelper.getRenderEntity(player);
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (entity == null)
return;
if (entity != null)
{
Vec3 playerpos = CarryRenderHelper.getExactPos(player, partialTicks);
Vec3 playerpos = CarryRenderHelper.getExactPos(player, partialTicks);
entity.setPos(playerpos.x, playerpos.y, playerpos.z);
entity.xRotO = 0.0f;
entity.yRotO = 0.0f;
entity.setYHeadRot(0.0f);
entity.setPos(playerpos.x, playerpos.y, playerpos.z);
entity.xRotO = 0.0f;
entity.yRotO = 0.0f;
entity.setYHeadRot(0.0f);
float height = entity.getBbHeight();
float width = entity.getBbWidth();
matrix.pushPose();
matrix.pushPose();
matrix.scale(0.8f, 0.8f, 0.8f);
matrix.mulPose(Vector3f.YP.rotationDegrees(180));
matrix.translate(0.0, -height - .1, width + 0.1);
CarryRenderHelper.setupEntityTransformations(player, matrix, carry, firstPerson);
manager.setRenderShadow(false);
if (entity instanceof LivingEntity)
((LivingEntity) entity).hurtTime = 0;
Optional<CarryOnScript> res = carry.getActiveScript();
if(res.isPresent())
{
CarryOnScript script = res.get();
CarryRenderHelper.performScriptTransformation(matrix, script);
}
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)
{
}
if (entity instanceof LivingEntity)
((LivingEntity) entity).hurtTime = 0;
matrix.popPose();
if(!firstPerson)
try {
manager.render(entity, 0, 0, 0, 0f, 0, matrix, buffer, light);
}
catch (Exception e)
{
}
manager.setRenderShadow(true);
matrix.popPose();
}
}
// RenderSystem.disableAlphaTest();
}
/**
* Draws the third person view of entities and blocks
* @param partialticks
* @param matrix
*/
public static void drawThirdPerson(float partialticks, PoseStack matrix) {
Minecraft mc = Minecraft.getInstance();
Level level = mc.level;
int light = 0;
int perspective = CarryRenderHelper.getPerspective();
EntityRenderDispatcher manager = mc.getEntityRenderDispatcher();
RenderSystem.enableBlend();
RenderSystem.disableCull();
RenderSystem.disableDepthTest();
BufferSource buffer = MultiBufferSource.immediateWithBuffers(builders, Tesselator.getInstance().getBuilder());
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")))
continue;
light = manager.getPackedLightCoords(player, partialticks);
if (carry.isCarrying(CarryType.BLOCK)) {
BlockState state = CarryRenderHelper.getRenderState(player);
CarryRenderHelper.applyBlockTransformations(player, partialticks, matrix, state.getBlock());
ItemStack tileItem = new ItemStack(state.getBlock().asItem());
BakedModel model = CarryRenderHelper.getRenderBlock(player);
//ModelOverridesHandler.hasCustomOverrideModel(state, tag) ? ModelOverridesHandler.getCustomOverrideModel(state, tag, level, player) : tileItem.isEmpty() ? mc.getBlockRenderer().getBlockModel(state) : mc.getItemRenderer().getModel(tileItem, level, player, 0);
//
Optional<CarryOnScript> res = carry.getActiveScript();
if (res.isPresent()) {
CarryOnScript script = res.get();
CarryRenderHelper.performScriptTransformation(matrix, script);
}
RenderSystem.setShaderTexture(0, InventoryMenu.BLOCK_ATLAS);
RenderSystem.enableCull();
PoseStack.Pose p = matrix.last();
PoseStack copy = new PoseStack();
copy.mulPoseMatrix(p.pose());
matrix.popPose();
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
CarryRenderHelper.renderBakedModel(tileItem, copy, buffer, light, model);
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, 0, 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

@ -1,45 +1,28 @@
/*
* 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.render;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
import net.minecraft.client.Minecraft;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.util.ProblemReporter;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.Registry;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
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.ItemStack;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.ChestBlock;
import net.minecraft.world.level.block.RenderShape;
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;
import tschipp.carryon.Constants;
import tschipp.carryon.client.modeloverride.ModelOverride;
import tschipp.carryon.client.modeloverride.ModelOverrideHandler;
@ -69,138 +52,158 @@ public class CarryRenderHelper
return -(entity.yBodyRotO + (entity.yBodyRot - entity.yBodyRotO) * partialticks);
}
public static Quaternionf getExactBodyRotation(LivingEntity entity, float partialticks)
public static Quaternion getExactBodyRotation(LivingEntity entity, float partialticks)
{
return Axis.YP.rotationDegrees(getExactBodyRotationDegrees(entity, partialticks));
return Vector3f.YP.rotationDegrees(getExactBodyRotationDegrees(entity, partialticks));
}
public static void applyGeneralTransformations(Player player, PoseStack matrix)
public static void applyGeneralTransformations(Player player, float partialticks, PoseStack matrix)
{
int perspective = CarryRenderHelper.getPerspective();
Quaternion 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(Vector3f.YP.rotationDegrees(180));
matrix.mulPose(playerrot);
matrix.pushPose();
matrix.scale(0.6f, 0.6f, 0.6f);
matrix.translate(0, 0, -1.35);
if (perspective == 2)
matrix.translate(0, 0, -1.35);
if (doSneakCheck(player))
{
matrix.translate(0, -0.4, 0);
}
if (pose == Pose.SWIMMING || pose == Pose.FALL_FLYING)
if (pose == Pose.SWIMMING)
{
matrix.translate(0, 0, 2.5);
matrix.mulPose(Axis.XP.rotationDegrees(90));
}
matrix.translate(0, -0.5, 0.65);
}
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);
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));
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(Vector3f.XP.rotationDegrees(f4));
}
carry.getActiveScript().ifPresent(script -> CarryRenderHelper.performScriptTransformation(matrix, script));
else
matrix.mulPose(Vector3f.XN.rotationDegrees(f4));
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;
matrix.translate(0, -1.5, -1.848);
if (perspective == 2)
matrix.translate(0, 0, 2.38);
}
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(Vector3f.XP.rotationDegrees(f2 * (-90.0F - player.xRotO)));
else
matrix.mulPose(Vector3f.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(Vector3f.YP.rotation((float) (Math.signum(d3) * Math.acos(d2))));
}
if (perspective != 2)
matrix.translate(0, 0, -1.35);
matrix.translate(0, -0.2, 0);
}
matrix.translate(0, 1.6, 0.65);
}
public static void applyBlockTransformations(Player player, PoseStack matrix, Block block)
public static void applyBlockTransformations(Player player, float partialticks, PoseStack matrix, Block block)
{
matrix.mulPose(Axis.ZN.rotationDegrees(180));
applyGeneralTransformations(player, matrix);
int perspective = CarryRenderHelper.getPerspective();
applyGeneralTransformations(player, partialticks, matrix);
if (Constants.CLIENT_CONFIG.facePlayer != CarryRenderHelper.isChest(block))
{
//TODO: RealFirstPersonRender
//if ((ModList.get().isLoaded("realrender") || ModList.get().isLoaded("rfpr")) && perspective == 0)
// matrix.translate(0, 0, -0.4);
matrix.mulPose(Axis.YP.rotationDegrees(180));
matrix.mulPose(Vector3f.YP.rotationDegrees(180));
}
// if(perspective == 1)
// {
// matrix.pushPose();
// //matrix.mulPose(Vector3f.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(Vector3f.YP.rotationDegrees(180));
float height = getRenderHeight(player);
float offset = (height - 1f) / 1.2f;
matrix.translate(0, -offset, 0);
}
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)
public static void applyEntityTransformations(Player player, float partialticks, PoseStack matrix, Entity entity)
{
int perspective = CarryRenderHelper.getPerspective();
Pose pose = player.getPose();
applyGeneralTransformations(player, matrix);
applyGeneralTransformations(player, partialticks, matrix);
matrix.mulPose(Axis.XP.rotationDegrees(180));
matrix.translate(0, -3.1, -0.65);
if (perspective == 2)
matrix.translate(0, -1.6, 0.65);
else
matrix.translate(0, -1.6, -0.65);
matrix.scale(1.666f, 1.666f, 1.666f);
float height = entity.getBbHeight();
float width = entity.getBbWidth();
float multiplier = Math.min(9.9f, height * width) ;
float multiplier = height * width;
entity.yo = 0.0f;
entity.yRotO = 0.0f;
entity.setYHeadRot(0.0f);
entity.xo = 0.0f;
entity.xRotO = 0.0f;
matrix.scale((10 - multiplier) * 0.08f, (10 - multiplier) * 0.08f, (10 - multiplier) * 0.08f);
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 (perspective == 2)
matrix.mulPose(Vector3f.YP.rotationDegrees(180));
if(doSneakCheck(player))
matrix.translate(0, -0.4, 0);
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);
if (pose == Pose.SWIMMING || pose == Pose.FALL_FLYING)
{
matrix.mulPose(Axis.XN.rotationDegrees(180));
matrix.translate(0, 0.2 * height - 2, -0.5);
}
matrix.mulPose(Vector3f.XN.rotationDegrees(90));
matrix.translate(0, -0.2 * height, 0);
if(Constants.CLIENT_CONFIG.rotateEntitiesSideways)
matrix.mulPose(Axis.YP.rotationDegrees(90));
if (pose == Pose.FALL_FLYING)
matrix.translate(0, 0, 0.2);
}
}
@ -215,9 +218,9 @@ public class CarryRenderHelper
Vec3 rotation = render.renderRotation().getVec();
Vec3 scale = render.renderscale().getVec(1, 1, 1);
Quaternionf rot = Axis.XP.rotationDegrees((float) rotation.x);
rot.mul(Axis.YP.rotationDegrees((float) rotation.y));
rot.mul(Axis.ZP.rotationDegrees((float) rotation.z));
Quaternion rot = Vector3f.XP.rotationDegrees((float) rotation.x);
rot.mul(Vector3f.YP.rotationDegrees((float) rotation.y));
rot.mul(Vector3f.ZP.rotationDegrees((float) rotation.z));
matrix.mulPose(rot);
matrix.translate(translation.x, translation.y, perspective == 1 && script.isBlock() ? -translation.z : translation.z);
@ -225,64 +228,18 @@ public class CarryRenderHelper
matrix.scale((float) scale.x, (float) scale.y, (float) scale.z);
}
/*
@Deprecated
public static void renderBakedModel(ItemStack stack, PoseStack matrix, MultiBufferSource buffer, int light, BakedModel model)
{
ItemStackRenderState state = new ItemStackRenderState();
try {
ItemStackRenderState.LayerRenderState layer = state.newLayer();
if(stack.hasFoil())
layer.setFoilType(ItemStackRenderState.FoilType.STANDARD);
layer.setupBlockModel(model, RenderType.translucent());
state.render(matrix, buffer, light, OverlayTexture.NO_OVERLAY);
ItemRenderer renderer = Minecraft.getInstance().getItemRenderer();
renderer.renderStatic(stack, ItemDisplayContext.NONE, light, OverlayTexture.NO_OVERLAY, matrix, buffer, null, model, 0);
renderer.render(stack, ItemDisplayContext.NONE, false, matrix, buffer, light, OverlayTexture.NO_OVERLAY, model);
renderer.render(stack, TransformType.NONE, false, matrix, buffer, light, OverlayTexture.NO_OVERLAY, model);
}
catch (Exception e)
{
}
}
*/
public static ItemStack getRenderItemStack(Player player)
{
CarryOnData carry = CarryOnDataManager.getCarryData(player);
BlockState state = carry.getBlock().getBlock().defaultBlockState();
if(carry.getActiveScript().isPresent())
{
ScriptRender render = carry.getActiveScript().get().scriptRender();
if(render.renderNameBlock().isPresent())
{
state = BuiltInRegistries.BLOCK.get(render.renderNameBlock().get()).get().value().defaultBlockState();
}
}
ItemStack renderStack = ItemStack.EMPTY;
Optional<ModelOverride> ov = ModelOverrideHandler.getModelOverride(state, carry.getContentNbt());
if(ov.isPresent())
{
var renderObj = ov.get().getRenderObject();
if(renderObj.right().isPresent())
state = renderObj.right().get();
else if (renderObj.left().isPresent())
renderStack = renderObj.left().get();
}
if(renderStack.isEmpty())
renderStack = new ItemStack(state.getBlock());
return renderStack;
}
public static BlockState getRenderState(Player player)
{
@ -292,9 +249,7 @@ public class CarryRenderHelper
{
ScriptRender render = carry.getActiveScript().get().scriptRender();
if(render.renderNameBlock().isPresent())
{
state = BuiltInRegistries.BLOCK.get(render.renderNameBlock().get()).get().value().defaultBlockState();
}
state = Registry.BLOCK.get(render.renderNameBlock().get()).defaultBlockState();
}
Optional<ModelOverride> ov = ModelOverrideHandler.getModelOverride(state, carry.getContentNbt());
@ -308,20 +263,16 @@ public class CarryRenderHelper
return state;
}
/*
@Deprecated
public static BakedModel getRenderBlock(Player player)
{
CarryOnData carry = CarryOnDataManager.getCarryData(player);
ItemRenderer renderer = Minecraft.getInstance().getItemRenderer();
Minecraft.getInstance().getModelManager().specialBlockModelRenderer().get().
BlockState state = getRenderState(player);
BakedModel model = Minecraft.getInstance().getBlockRenderer().getBlockModel(state);
if(state.getRenderShape() != RenderShape.MODEL || model.isCustomRenderer() || model.getQuads(state, null, RandomSource.create()).size() <= 0) {
ItemStack stack = new ItemStack(state.getBlock());
model = renderer.getModel(stack, player.level(), player, 0);
model = renderer.getModel(stack, player.level, player, 0);
}
Optional<ModelOverride> ov = ModelOverrideHandler.getModelOverride(state, carry.getContentNbt());
@ -329,29 +280,26 @@ public class CarryRenderHelper
{
var renderObj = ov.get().getRenderObject();
if(renderObj.left().isPresent())
model = renderer.getModel(renderObj.left().get(), player.level(), player, 0);
model = renderer.getModel(renderObj.left().get(), player.level, player, 0);
}
return model;
}
*/
public static Entity getRenderEntity(Player player)
{
CarryOnData carry = CarryOnDataManager.getCarryData(player);
Entity entity = carry.getEntity(player.level());
Entity entity = carry.getEntity(player.level);
if(carry.getActiveScript().isPresent())
{
CarryOnScript script = carry.getActiveScript().get();
ScriptRender render = script.scriptRender();
if(render.renderNameEntity().isPresent())
entity = BuiltInRegistries.ENTITY_TYPE.get(render.renderNameEntity().get()).get().value().create(player.level(), EntitySpawnReason.EVENT);
entity = Registry.ENTITY_TYPE.get(render.renderNameEntity().get()).create(player.level);
if(render.renderNBT().isPresent()) {
ValueInput input = TagValueInput.create(new ProblemReporter.ScopedCollector(Constants.LOG), player.registryAccess(), render.renderNBT().get());
entity.load(input);
}
if(render.renderNBT().isPresent())
entity.load(render.renderNBT().get());
}
return entity;
@ -363,7 +311,7 @@ public class CarryRenderHelper
if(carry.isCarrying(CarryType.BLOCK))
{
BlockState state = getRenderState(player);
VoxelShape shape = state.getShape(player.level(), player.blockPosition());
VoxelShape shape = state.getShape(player.level, player.blockPosition());
if(shape == null || shape.isEmpty())
return 1f;
Optional<ModelOverride> ov = ModelOverrideHandler.getModelOverride(state, carry.getContentNbt());
@ -379,10 +327,7 @@ public class CarryRenderHelper
else if(carry.isCarrying(CarryType.ENTITY))
{
Entity entity = getRenderEntity(player);
float w = entity.getBbWidth();
if (Constants.CLIENT_CONFIG.rotateEntitiesSideways)
return w - (w*w) * 0.35f;
return w * 0.9f;
return entity.getBbWidth();
}
else
return 1f;
@ -394,7 +339,7 @@ public class CarryRenderHelper
if(carry.isCarrying(CarryType.BLOCK))
{
BlockState state = getRenderState(player);
VoxelShape shape = state.getShape(player.level(), player.blockPosition());
VoxelShape shape = state.getShape(player.level, player.blockPosition());
if(shape == null || shape.isEmpty())
return 1f;
Optional<ModelOverride> ov = ModelOverrideHandler.getModelOverride(state, carry.getContentNbt());
@ -440,7 +385,7 @@ public class CarryRenderHelper
public static boolean isChest(Block block)
{
return block == Blocks.CHEST || block == Blocks.ENDER_CHEST || block == Blocks.TRAPPED_CHEST || block instanceof ChestBlock;
return block == Blocks.CHEST || block == Blocks.ENDER_CHEST || block == Blocks.TRAPPED_CHEST;
}
}

View File

@ -1,22 +0,0 @@
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,20 +0,0 @@
package tschipp.carryon.client.render;
import net.minecraft.world.entity.player.Player;
import tschipp.carryon.common.carry.CarryOnData;
public interface ICarryOnRenderState {
CarryOnData getCarryOnData();
void setCarryOnData(CarryOnData data);
float getRenderWidth();
void setRenderWidth(float val);
Player getPlayer();
void setPlayer(Player player);
}

View File

@ -1,57 +1,23 @@
/*
* 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.common.carry;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.BuiltInRegistries;
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 {
@ -60,56 +26,30 @@ 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.getStringOr("type", "INVALID"));
this.type = CarryType.valueOf(data.getString("type"));
else
this.type = CarryType.INVALID;
this.nbt = data;
this.keyPressed = data.getBooleanOr("keyPressed", false);
if(data.contains("keyPressed"))
this.keyPressed = data.getBoolean("keyPressed");
if(data.contains("activeScript"))
{
DataResult<CarryOnScript> res = CarryOnScript.CODEC.parse(NbtOps.INSTANCE, data.get("activeScript"));
this.activeScript = res.getOrThrow((s) -> {throw new RuntimeException("Failed to decode activeScript during CarryOnData serialization: " + s);});
this.activeScript = res.getOrThrow(false, (s) -> {throw new RuntimeException("Failed to decode activeScript during CarryOnData serialization: " + s);});
}
this.selectedSlot = data.getIntOr("selected", 0);
if(data.contains("selected"))
this.selectedSlot = data.getInt("selected");
}
public CarryType getType()
{
return this.type;
}
public CompoundTag getNbt()
{
nbt.putString("type", type.toString());
@ -117,7 +57,7 @@ public class CarryOnData {
if(activeScript != null)
{
DataResult<Tag> res = CarryOnScript.CODEC.encodeStart(NbtOps.INSTANCE, activeScript);
Tag tag = res.getOrThrow((s) -> {throw new RuntimeException("Failed to encode activeScript during CarryOnData serialization: " + s);});
Tag tag = res.getOrThrow(false, (s) -> {throw new RuntimeException("Failed to encode activeScript during CarryOnData serialization: " + s);});
nbt.put("activeScript", tag);
}
nbt.putInt("selected", this.selectedSlot);
@ -127,13 +67,13 @@ public class CarryOnData {
public CompoundTag getContentNbt()
{
if(type == CarryType.BLOCK && nbt.contains("block"))
return nbt.getCompoundOrEmpty("block");
return nbt.getCompound("block");
else if(type == CarryType.ENTITY && nbt.contains("entity"))
return nbt.getCompoundOrEmpty("entity");
return nbt.getCompound("entity");
return null;
}
public void setBlock(BlockState state, @Nullable BlockEntity tile, ServerPlayer player, BlockPos pos)
public void setBlock(BlockState state, @Nullable BlockEntity tile)
{
this.type = CarryType.BLOCK;
@ -145,9 +85,7 @@ public class CarryOnData {
if(tile != null)
{
TagValueOutput output = TagValueOutput.createWithContext(problemReporter, player.registryAccess());
tile.saveWithId(output);
Tag tileData = output.buildResult();
CompoundTag tileData = tile.saveWithId();
nbt.put("tile", tileData);
}
}
@ -157,11 +95,11 @@ 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.getCompoundOrEmpty("block"));
return NbtUtils.readBlockState(nbt.getCompound("block"));
}
@Nullable
public BlockEntity getBlockEntity(BlockPos pos, HolderLookup.Provider lookup)
public BlockEntity getBlockEntity(BlockPos pos)
{
if(this.type != CarryType.BLOCK)
throw new IllegalStateException("Called getBlockEntity on data that contained " + this.type);
@ -169,15 +107,14 @@ public class CarryOnData {
if(!nbt.contains("tile"))
return null;
return BlockEntity.loadStatic(pos, this.getBlock(), nbt.getCompoundOrEmpty("tile"), lookup);
return BlockEntity.loadStatic(pos, this.getBlock(), nbt.getCompound("tile"));
}
public void setEntity(Entity entity)
{
this.type = CarryType.ENTITY;
TagValueOutput output = TagValueOutput.createWithContext(new ProblemReporter.ScopedCollector(Constants.LOG), entity.registryAccess());
entity.save(output);
Tag entityData = output.buildResult();
CompoundTag entityData = new CompoundTag();
entity.save(entityData);
nbt.put("entity", entityData);
}
@ -186,8 +123,7 @@ public class CarryOnData {
if(this.type != CarryType.ENTITY)
throw new IllegalStateException("Called getEntity on data that contained " + this.type);
ValueInput in = TagValueInput.create(problemReporter, level.registryAccess(), nbt.getCompoundOrEmpty("entity"));
var optionalEntity = EntityType.create(in, level, EntitySpawnReason.BUCKET);
var optionalEntity = EntityType.create(nbt.getCompound("entity"), level);
if(optionalEntity.isPresent())
return optionalEntity.get();
@ -208,20 +144,8 @@ public class CarryOnData {
this.activeScript = script;
}
public void setCarryingPlayer(Player player)
{
public void setCarryingPlayer() {
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()
@ -256,20 +180,13 @@ public class CarryOnData {
this.activeScript = null;
}
public CarryOnData clone() {
return new CarryOnData(nbt.copy());
}
public int getTick()
{
return this.nbt.getIntOr("tick", -1);
if(!this.nbt.contains("tick"))
return -1;
return this.nbt.getInt("tick");
}
public void setTick(int tick) {
this.nbt.putInt("tick", tick);
}
public enum CarryType {
BLOCK,
ENTITY,

View File

@ -1,40 +1,28 @@
/*
* 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.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 final EntityDataAccessor<CompoundTag> CARRY_DATA_KEY = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG);
public static CarryOnData getCarryData(Player player)
{
return Services.PLATFORM.getCarryData(player);
CompoundTag data = player.getEntityData().get(CARRY_DATA_KEY);
return new CarryOnData(data.copy());
}
public static void setCarryData(Player player, CarryOnData data)
{
data.setSelected(player.getInventory().getSelectedSlot());
data.setTick(player.tickCount);
Services.PLATFORM.setCarryData(player, data);
data.setSelected(player.getInventory().selected);
CompoundTag nbt = data.getNbt();
nbt.putInt("tick", player.tickCount);
player.getEntityData().set(CARRY_DATA_KEY, nbt);
}
}

View File

@ -1,23 +1,3 @@
/*
* 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.common.carry;
import net.minecraft.core.BlockPos;
@ -25,30 +5,26 @@ 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.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.*;
import net.minecraft.world.entity.AgeableMob;
import net.minecraft.world.entity.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.ClientboundStartRidingOtherPlayerPacket;
import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket;
import tschipp.carryon.platform.Services;
import javax.annotation.Nullable;
@ -96,26 +72,16 @@ public class PickupHandler {
BlockEntity blockEntity = level.getBlockEntity(pos);
BlockState state = level.getBlockState(pos);
CompoundTag nbt = null;
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(blockEntity != null)
nbt = blockEntity.saveWithId();
if(!ListHandler.isPermitted(state.getBlock()))
return false;
// Reject pickup of Double blocks, if they use the vanilla property
if(hasPropertyType(state, DoorBlock.HALF))
if(state.getDestroySpeed(level, pos) == -1 && !player.isCreative())
return false;
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))
if(blockEntity == null && !Constants.COMMON_CONFIG.settings.pickupAllBlocks)
return false;
//Check if TE is locked
@ -136,6 +102,7 @@ public class PickupHandler {
if(!doPickup)
return false;
Optional<CarryOnScript> result = ScriptManager.inspectBlock(state, level, pos, nbt);
if(result.isPresent())
{
CarryOnScript script = result.get();
@ -146,10 +113,10 @@ public class PickupHandler {
String cmd = script.scriptEffects().commandInit();
if(!cmd.isEmpty())
player.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd);
}
carry.setBlock(state, blockEntity, player, pos);
carry.setBlock(state, blockEntity);
level.removeBlockEntity(pos);
level.removeBlock(pos, false);
@ -157,8 +124,6 @@ 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;
}
@ -177,29 +142,23 @@ public class PickupHandler {
if (entity instanceof TamableAnimal tame)
{
EntityReference<LivingEntity> ref = tame.getOwnerReference();
if (ref != null) {
UUID owner = ref.getUUID();
UUID playerID = player.getGameProfile().id();
if (!owner.equals(playerID))
return false;
}
UUID owner = tame.getOwnerUUID();
UUID playerID = player.getGameProfile().getId();
if (owner != null && !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(!overrideChecks && (!(entity instanceof AgeableMob ageableMob && Constants.COMMON_CONFIG.settings.allowBabies && (ageableMob.getAge() < 0 || ageableMob.isBaby()))))
if(!(entity instanceof AgeableMob ageableMob && Constants.COMMON_CONFIG.settings.allowBabies && (ageableMob.getAge() < 0 || ageableMob.isBaby())))
return false;
}
//Non-Creative only guards
if(!player.isCreative())
{
if(!overrideChecks && (!Constants.COMMON_CONFIG.settings.pickupHostileMobs && entity.getType().getCategory() == MobCategory.MONSTER))
if(!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())
@ -213,12 +172,13 @@ public class PickupHandler {
return false;
}
boolean doPickup = pickupCallback == null || pickupCallback.apply(entity);
boolean doPickup = pickupCallback == null ? true : 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();
@ -241,17 +201,15 @@ public class PickupHandler {
if (result.isPresent()) {
String cmd = result.get().scriptEffects().commandInit();
if (!cmd.isEmpty())
player.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd);
}
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);
otherPlayer.startRiding(player);
Services.PLATFORM.sendPacketToPlayer(Constants.PACKET_ID_START_RIDING, new ClientboundStartRidingPacket(otherPlayer.getId(), true), player);
carry.setCarryingPlayer();
player.swing(InteractionHand.MAIN_HAND, true);
player.level().playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC.value(), SoundSource.AMBIENT, 1.0f, 0.5f);
player.level.playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC, 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;
}
@ -259,33 +217,23 @@ public class PickupHandler {
entity.ejectPassengers();
entity.stopRiding();
if (entity instanceof Animal animal) {
animal.dropLeash();
animal.dropLeash(true, true);
}
if(result.isPresent())
{
String cmd = result.get().scriptEffects().commandInit();
if(!cmd.isEmpty())
player.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd);
}
carry.setEntity(entity);
entity.remove(RemovalReason.UNLOADED_WITH_PLAYER);
player.level().playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC.value(), SoundSource.AMBIENT, 1.0f, 0.5f);
player.level.playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC, 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

@ -1,23 +1,3 @@
/*
* 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.common.carry;
import net.minecraft.core.BlockPos;
@ -26,19 +6,19 @@ 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.equine.Horse;
import net.minecraft.world.entity.animal.horse.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.DirectionProperty;
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,8 +26,6 @@ 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;
@ -67,7 +45,7 @@ public class PlacementHandler
if (player.tickCount == carry.getTick())
return false;
Level level = player.level();
Level level = player.getLevel();
BlockState state = carry.getBlock();
BlockPlaceContext context = new BlockPlaceContext(player, InteractionHand.MAIN_HAND, ItemStack.EMPTY, BlockHitResult.miss(player.position(), facing, pos));
@ -77,7 +55,7 @@ public class PlacementHandler
context = new BlockPlaceContext(player, InteractionHand.MAIN_HAND, ItemStack.EMPTY, BlockHitResult.miss(player.position(), facing, pos));
BlockEntity blockEntity = carry.getBlockEntity(pos, level.registryAccess());
BlockEntity blockEntity = carry.getBlockEntity(pos);
state = getPlacementState(state, player, context, pos);
@ -92,14 +70,11 @@ 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.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd);
}
level.setBlockAndUpdate(pos, state);
@ -114,7 +89,6 @@ 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;
}
@ -125,7 +99,7 @@ public class PlacementHandler
placementState = state;
for (var prop : placementState.getProperties()) {
if (prop.getValueClass() == Direction.class)
if (prop instanceof DirectionProperty)
state = updateProperty(state, placementState, prop);
if (prop.getValueClass() == Direction.Axis.class)
state = updateProperty(state, placementState, prop);
@ -135,7 +109,7 @@ public class PlacementHandler
}
}
BlockState updatedState = Block.updateFromNeighbourShapes(state, player.level(), pos);
BlockState updatedState = Block.updateFromNeighbourShapes(state, player.level, pos);
if (updatedState.getBlock() == state.getBlock())
state = updatedState;
@ -161,30 +135,23 @@ public class PlacementHandler
if (player.tickCount == carry.getTick())
return false;
Level level = player.level();
Level level = player.getLevel();
BlockPlaceContext context = new BlockPlaceContext(player, InteractionHand.MAIN_HAND, ItemStack.EMPTY, BlockHitResult.miss(player.position(), facing, pos));
if (!level.getBlockState(pos).canBeReplaced(context)) {
if (!level.getBlockState(pos).canBeReplaced(context))
pos = pos.relative(facing);
context = new BlockPlaceContext(player, InteractionHand.MAIN_HAND, ItemStack.EMPTY, BlockHitResult.miss(player.position(), facing, pos));
}
if (!level.getBlockState(pos).canBeReplaced(context)) {
level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.LAVA_POP, SoundSource.PLAYERS, 0.5F, 0.5F);
return false;
}
Vec3 placementPos = Vec3.atBottomCenterOf(pos);
if (carry.isCarrying(CarryType.PLAYER)) {
Entity otherPlayer = carry.getCarryingPlayer(level);
Entity otherPlayer = player.getFirstPassenger();
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);
otherPlayer.teleportTo(placementPos.x, placementPos.y, placementPos.z);
if (otherPlayer == null)
return true;
otherPlayer.teleportTo(placementPos.x, placementPos.y, placementPos.z);
player.swing(InteractionHand.MAIN_HAND, true);
player.removeEffect(MobEffects.SLOWNESS);
return true;
}
@ -199,7 +166,7 @@ public class PlacementHandler
ScriptEffects effects = carry.getActiveScript().get().scriptEffects();
String cmd = effects.commandPlace();
if (!cmd.isEmpty())
player.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd);
}
level.addFreshEntity(entity);
@ -209,7 +176,6 @@ public class PlacementHandler
player.swing(InteractionHand.MAIN_HAND, true);
carry.clear();
CarryOnDataManager.setCarryData(player, carry);
player.removeEffect(MobEffects.SLOWNESS);
return true;
}
@ -222,15 +188,13 @@ public class PlacementHandler
if (!carry.isCarrying(CarryType.ENTITY) && !carry.isCarrying(CarryType.PLAYER))
return;
Level level = player.level();
Level level = player.level;
Entity entityHeld;
if (carry.isCarrying(CarryType.ENTITY))
entityHeld = carry.getEntity(level);
else
entityHeld = player.getFirstPassenger();
if(entityHeld == null)
return;
double sizeHeldEntity = entityHeld.getBbHeight() * entityHeld.getBbWidth();
double distance = entityClicked.blockPosition().distSqr(player.blockPosition());
@ -244,7 +208,7 @@ public class PlacementHandler
if (ListHandler.isStackingPermitted(topEntity)) {
double sizeEntity = topEntity.getBbHeight() * topEntity.getBbWidth();
if (!Constants.COMMON_CONFIG.settings.entitySizeMattersStacking || sizeHeldEntity <= sizeEntity) {
if (Constants.COMMON_CONFIG.settings.entitySizeMattersStacking && sizeHeldEntity <= sizeEntity || !Constants.COMMON_CONFIG.settings.entitySizeMattersStacking) {
if (topEntity instanceof Horse horse)
horse.setTamed(true);
@ -257,27 +221,26 @@ public class PlacementHandler
level.addFreshEntity(entityHeld);
entityHeld.teleportTo(tempX, tempY, tempZ);
}
entityHeld.startRiding(topEntity, false,false);
entityHeld.startRiding(topEntity, false);
} else {
if (carry.isCarrying(CarryType.ENTITY)) {
entityHeld.setPos(entityClicked.getX(), entityClicked.getY(), entityClicked.getZ());
level.addFreshEntity(entityHeld);
}
entityHeld.startRiding(topEntity, false,false);
entityHeld.startRiding(topEntity, false);
}
if (carry.getActiveScript().isPresent()) {
ScriptEffects effects = carry.getActiveScript().get().scriptEffects();
String cmd = effects.commandPlace();
if (!cmd.isEmpty())
player.level().getServer().getCommands().performPrefixedCommand(player.level().getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().name() + " run " + cmd);
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " 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);
}
@ -290,10 +253,10 @@ public class PlacementHandler
public static void placeCarriedOnDeath(ServerPlayer oldPlayer, ServerPlayer newPlayer, boolean died)
{
CarryOnData carry = CarryOnDataManager.getCarryData(oldPlayer);
if (oldPlayer.level().getGameRules().get(GameRules.KEEP_INVENTORY) || !died) {
if (oldPlayer.level.getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || !died) {
if (!carry.isCarrying(CarryType.PLAYER)) {
CarryOnDataManager.setCarryData(newPlayer, carry);
newPlayer.getInventory().setSelectedSlot(oldPlayer.getInventory().getSelectedSlot());
newPlayer.getInventory().selected = oldPlayer.getInventory().selected;
return;
}
}
@ -305,23 +268,22 @@ public class PlacementHandler
{
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (carry.isCarrying(CarryType.ENTITY)) {
Entity entity = carry.getEntity(player.level());
Entity entity = carry.getEntity(player.level);
entity.setPos(player.position());
player.level().addFreshEntity(entity);
player.level.addFreshEntity(entity);
} else if (carry.isCarrying(CarryType.BLOCK)) {
BlockPlaceContext context = new BlockPlaceContext(player, InteractionHand.MAIN_HAND, ItemStack.EMPTY, BlockHitResult.miss(Vec3.atCenterOf(player.blockPosition()), Direction.DOWN, player.blockPosition()));
BlockState state = getPlacementState(carry.getBlock(), player, context, player.blockPosition());
BlockPos pos = getDeathPlacementPos(state, player);
BlockEntity blockEntity = carry.getBlockEntity(pos, player.level().registryAccess());
player.level().setBlock(pos, state, 3);
BlockEntity blockEntity = carry.getBlockEntity(pos);
player.level.setBlock(pos, state, 3);
if (blockEntity != null)
player.level().setBlockEntity(blockEntity);
player.level.setBlockEntity(blockEntity);
} else if (carry.isCarrying(CarryType.PLAYER)) {
player.ejectPassengers();
}
carry.clear();
CarryOnDataManager.setCarryData(player, carry);
player.removeEffect(MobEffects.SLOWNESS);
}
private static BlockPos getDeathPlacementPos(BlockState state, ServerPlayer player)
@ -343,12 +305,12 @@ public class PlacementHandler
}
}
potentialPositions.sort(Comparator.comparingDouble(posA -> player.distanceToSqr(posA.getCenter())));
potentialPositions.sort(Comparator.comparingDouble(posA -> posA.distToCenterSqr(player.position())));
for(BlockPos potential : potentialPositions)
{
BlockPlaceContext context = new BlockPlaceContext(player, InteractionHand.MAIN_HAND, ItemStack.EMPTY, BlockHitResult.miss(Vec3.atCenterOf(potential), Direction.DOWN, potential));
boolean canPlace = state.canSurvive(player.level(), potential) && player.level().getBlockState(potential).canBeReplaced(context) && player.level().isUnobstructed(state, potential, CollisionContext.of(player));
boolean canPlace = state.canSurvive(player.level, potential) && player.level.getBlockState(potential).canBeReplaced(context) && player.level.isUnobstructed(state, potential, CollisionContext.of(player));
if (canPlace)
return potential;

View File

@ -1,25 +0,0 @@
package tschipp.carryon.common.carry.compat;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import javax.annotation.Nullable;
public class CarryOnModHooks {
public record CanPickupBlockHook(ServerPlayer player, BlockPos pos, BlockState state) {
}
public record CanPickupEntityHook(ServerPlayer player, Entity entity) {
}
public record SaveBlockHook(ServerPlayer player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity) {
}
}

View File

@ -1,23 +1,3 @@
/*
* 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.common.command;
import com.mojang.brigadier.CommandDispatcher;
@ -28,8 +8,6 @@ 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;
@ -56,11 +34,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.permissions().hasPermission(new Permission.HasCommandLevel(PermissionLevel.GAMEMASTERS))).executes(cmd -> handleClear(cmd.getSource(), EntityArgument.getPlayers(cmd, "target")))))
.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("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").requires(src -> src.hasPermission(2)).executes(cmd -> handlePlace(cmd.getSource(), Collections.singleton(cmd.getSource().getPlayerOrException()))))
.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")))))
.then(Commands.literal("place").then(Commands.argument("target", EntityArgument.players()).requires(src -> src.hasPermission(2)).executes(cmd -> handlePlace(cmd.getSource(), EntityArgument.getPlayers(cmd, "target")))))
;
@ -97,7 +75,7 @@ public class CommandCarryOn
}
else if (carry.isCarrying(CarryType.ENTITY))
{
Entity entity = carry.getEntity(player.level());
Entity entity = carry.getEntity(player.level);
log(source,"Entity: " + entity);
log(source,"Entity Name: " + entity.getType());
log(source,"NBT: " + carry.getNbt());
@ -134,14 +112,11 @@ public class CommandCarryOn
cleared++;
}
int finalCleared = cleared;
if (cleared != 1) {
source.sendSuccess(() -> Component.literal("Cleared " + finalCleared + " Items!"), true);
}
else {
source.sendSuccess(() -> Component.literal("Cleared " + finalCleared + " Item!"), true);
}
if (cleared != 1)
source.sendSuccess(Component.literal("Cleared " + cleared + " Items!"), true);
else
source.sendSuccess(Component.literal("Cleared " + cleared + " Item!"), true);
return 1;
}
@ -154,20 +129,18 @@ public class CommandCarryOn
PlacementHandler.placeCarried(player);
cleared++;
}
int finalCleared = cleared;
if (cleared != 1) {
source.sendSuccess(() -> Component.literal("Placed " + finalCleared + " Items!"), true);
}
if (cleared != 1)
source.sendSuccess(Component.literal("Placed " + cleared + " Items!"), true);
else
source.sendSuccess(() -> Component.literal("Placed " + finalCleared + " Item!"), true);
source.sendSuccess(Component.literal("Placed " + cleared + " Item!"), true);
return 1;
}
private static void log(CommandSourceStack source, String toLog)
{
source.sendSuccess(() -> Component.literal(toLog), true);
source.sendSuccess(Component.literal(toLog), true);
Constants.LOG.info(toLog);
}
}

View File

@ -1,23 +1,3 @@
/*
* 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.common.config;
import tschipp.carryon.config.PropertyType;
@ -38,7 +18,7 @@ public class CarryConfig
)
public Settings settings = new Settings();
@Category(value="settings", translation = "carryon.category.settings")
@Category("settings")
public static class Settings
{
@Property(
@ -171,8 +151,7 @@ public class CarryConfig
@Property(
type = PropertyType.STRING_ARRAY,
description = "Usually all the block state information is retained when placing a block that was picked up. But some information is changed to a modified property, like rotation or orientation. In this list, add additional properties that should NOT be saved and instead be updated when placed. Format: modid:block[propertyname]. Note: You don't need to add an entry for every subtype of a same block. For example, we only add an entry for one type of slab, but the change is applied to all slabs.",
validationRegex = "([a-zA-Z0-9_]+:[a-zA-Z0-9_]+)\\[([a-zA-Z0-9_,]+)\\]"
description = "Usually all the block state information is retained when placing a block that was picked up. But some information is changed to a modified property, like rotation or orientation. In this list, add additional properties that should NOT be saved and instead be updated when placed. Format: modid:block[propertyname]. Note: You don't need to add an entry for every subtype of a same block. For example, we only add an entry for one type of slab, but the change is applied to all slabs."
)
public String[] placementStateExceptions = {
"minecraft:chest[type]",
@ -184,18 +163,12 @@ public class CarryConfig
"minecraft:oak_trapdoor[half]",
};
@Property(
type = PropertyType.BOOLEAN,
description = "Whether Players can be picked up. Creative players can't be picked up in Survival Mode"
)
public boolean pickupPlayers = true;
@Property(
type = PropertyType.BOOLEAN,
description = "Whether players in Survival Mode can pick up unbreakable blocks. Creative players always can."
)
public boolean pickupUnbreakableBlocks = false;
}
@Property(
type = PropertyType.BOOLEAN,
description = "Whether Players can be picked up. Creative players can't be picked up in Survival Mode"
)
public boolean pickupPlayers = true;
}
@Property(
type = PropertyType.CATEGORY,
@ -205,27 +178,24 @@ public class CarryConfig
//Whitelist
public Whitelist whitelist = new Whitelist();
@Category(value="whitelist", translation = "carryon.category.whitelist")
@Category("whitelist")
public static class Whitelist
{
@Property(
type = PropertyType.STRING_ARRAY,
description = "Entities that CAN be picked up (useWhitelistEntities must be true)",
validationRegex = "(#?[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]*(?:\\*|[a-zA-Z0-9_]*)(?:\\*|[a-zA-Z0-9_]*)?)"
description = "Entities that CAN be picked up (useWhitelistEntities must be true)"
)
public String[] allowedEntities = {};
@Property(
type = PropertyType.STRING_ARRAY,
description = "Blocks that CAN be picked up (useWhitelistBlocks must be true)",
validationRegex = "(#?[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]*(?:\\*|[a-zA-Z0-9_]*)(?:\\*|[a-zA-Z0-9_]*)?)"
description = "Blocks that CAN be picked up (useWhitelistBlocks must be true)"
)
public String[] allowedBlocks = {};
@Property(
type = PropertyType.STRING_ARRAY,
description = "Entities that CAN have other entities stacked on top of them (useWhitelistStacking must be true)",
validationRegex = "(#?[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]*(?:\\*|[a-zA-Z0-9_]*)(?:\\*|[a-zA-Z0-9_]*)?)"
description = "Entities that CAN have other entities stacked on top of them (useWhitelistStacking must be true)"
)
public String[] allowedStacking = {};
}
@ -237,17 +207,15 @@ public class CarryConfig
)
public Blacklist blacklist = new Blacklist();
@Category(value="blacklist", translation = "carryon.category.blacklist")
@Category("blacklist")
public static class Blacklist
{
@Property(
type = PropertyType.STRING_ARRAY,
description = "Blocks that cannot be picked up",
validationRegex = "(#?[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]*(?:\\*|[a-zA-Z0-9_]*)(?:\\*|[a-zA-Z0-9_]*)?)"
description = "Blocks that cannot be picked up"
)
public String[] forbiddenTiles = {
"#forge:immovable", "#forge:relocation_not_supported", "#neoforge:immovable", "#neoforge:relocation_not_supported", "minecraft:end_portal", "minecraft:piston_head",
"#c:relocation_not_supported",
"#forge:immovable", "#forge:relocation_not_supported", "minecraft:end_portal", "minecraft:piston_head",
"minecraft:end_gateway", "minecraft:tall_grass", "minecraft:large_fern", "minecraft:peony",
"minecraft:rose_bush", "minecraft:lilac", "minecraft:sunflower", "minecraft:*_bed",
"minecraft:*_door", "minecraft:big_dripleaf_stem", "minecraft:waterlily", "minecraft:cake",
@ -274,45 +242,29 @@ public class CarryConfig
"mekanismgenerators:wind_generator", "cookingforblockheads:cabinet", "cookingforblockheads:corner", "cookingforblockheads:counter",
"cookingforblockheads:oven", "cookingforblockheads:toaster", "cookingforblockheads:milk_jar", "cookingforblockheads:cow_jar",
"cookingforblockheads:fruit_basket", "cookingforblockheads:cooking_table", "cookingforblockheads:fridge", "cookingforblockheads:sink",
"chipped:*", "irons_spellbooks:*", "create*:*", "simple_pipes:*", "libmultipart:*", "quark:tiny_potato", "ait:*",
"vampirism:*", "extrastorage:*", "relics:researching_table", "sophisticatedstorage:*chest",
"powah:*", "advancementtrophies:trophy", "mekanismgenerators:heat_generator", "mna:filler_block", "create_enchantment_industry:*", "graveyard:*", "immersivepetroleum:*",
"tardis:interior_door", "cuffed:*", "littletiles:*",
"butchersdelight:*", "irons_spellbooks:*", "extended_drawers:*", "functionalstorage:*", "sophisticatedstorage:*", "farmersdelight:*",
"modern_industrialization:*_cable",
"modern_industrialization:item_pipe",
"modern_industrialization:*_item_pipe",
"modern_industrialization:fluid_pipe",
"modern_industrialization:*_fluid_pipe",
"yigd:*", "domum_ornamentum:*", "connectiblechains:*",
"cobblemon:*", "snowrealmagic:*", "forbidden_arcanus:black_hole", "domum_ornamentum:*", "sgjourney:*", "copycats:*", "expandedstorage:*", "replication:*"
"chipped:*",
"powah:*", "advancementtrophies:trophy", "mekanismgenerators:heat_generator", "mna:filler_block", "create_enchantment_industry:*", "graveyard:*", "immersivepetroleum:*", "tardis:interior_door"
};
@Property(
type = PropertyType.STRING_ARRAY,
description = "Entities that cannot be picked up",
validationRegex = "(#?[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]*(?:\\*|[a-zA-Z0-9_]*)(?:\\*|[a-zA-Z0-9_]*)?)"
description = "Entities that cannot be picked up"
)
public String[] forbiddenEntities = {
"#c:capturing_not_supported", "#c:teleporting_not_supported",
"minecraft:end_crystal", "minecraft:ender_dragon", "minecraft:ghast", "minecraft:fireball", "minecraft:small_fireball", "minecraft:whither_skull",
"minecraft:shulker", "minecraft:leash_knot", "minecraft:armor_stand", "minecraft:whither_skull_dangerous", "minecraft:dragon_fireball",
"minecraft:item_frame", "minecraft:painting", "minecraft:shulker_bullet", "minecraft:evoker_fangs", "minecraft:glow_item_frame", "minecraft:tnt", "minecraft:trident", "minecraft:arrow", "minecraft:spectral_arrow",
"minecraft:interaction", "minecraft:marker", "minecraft:block_display", "minecraft:item_display", "minecraft:text_display",
"minecraft:end_crystal", "minecraft:ender_dragon", "minecraft:ghast",
"minecraft:shulker", "minecraft:leash_knot", "minecraft:armor_stand",
"minecraft:item_frame", "minecraft:painting", "minecraft:shulker_bullet",
"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:*", "swem:*", "toms_mobs:*"
"securitycraft:*", "taterzens:npc", "easy_npc:*", "bodiesbodies:dead_body"
};
@Property(
type = PropertyType.STRING_ARRAY,
description = "Entities that cannot have other entities stacked on top of them",
validationRegex = "(#?[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]*(?:\\*|[a-zA-Z0-9_]*)(?:\\*|[a-zA-Z0-9_]*)?)"
description = "Entities that cannot have other entities stacked on top of them"
)
public String[] forbiddenStacking = {
"minecraft:horse",
"minecraft:ender_dragon"
"minecraft:horse"
};
}
@ -323,20 +275,18 @@ public class CarryConfig
)
public CustomPickupConditions customPickupConditions = new CustomPickupConditions();
@Category(value="customPickupConditions", translation = "carryon.category.custompickupconditions")
@Category("customPickupConditions")
public static class CustomPickupConditions
{
@Property(
type = PropertyType.STRING_ARRAY,
description = "Custom Pickup Conditions for Blocks",
validationRegex = "([a-zA-Z0-9_*\\-:]+(?:\\[[^\\]]*\\])?)\\(([\\w_]+)\\)"
description = "Custom Pickup Conditions for Blocks"
)
public String[] customPickupConditionsBlocks = {};
@Property(
type = PropertyType.STRING_ARRAY,
description = "Custom Pickup Conditions for Entities",
validationRegex = "([a-zA-Z0-9_*\\-:]+(?:\\[[^\\]]*\\])?)\\(([\\w_]+)\\)"
description = "Custom Pickup Conditions for Entities"
)
public String[] customPickupConditionsEntities = {};
}
@ -352,12 +302,6 @@ 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)"
@ -366,8 +310,7 @@ public class CarryConfig
@Property(
type = PropertyType.STRING_ARRAY,
description = "Model Overrides based on NBT or Meta. Advanced users only! Read about the format here: https://github.com/Tschipp/CarryOn/wiki/Model-Override-Config",
validationRegex = "([a-zA-Z0-9_]+:[a-zA-Z0-9_]+(?:\\[[^\\]]*\\])?(?:\\{[^}]*\\})?)(?:;(\\d+))?->(?:\\((item|block)\\))?([a-zA-Z0-9_]+:[a-zA-Z0-9_]+(?:\\[[^\\]]*\\])?(?:\\{[^}]*\\})?)(?:;(\\d+))?"
description = "Model Overrides based on NBT or Meta. Advanced users only! Read about the format here: https://github.com/Tschipp/CarryOn/wiki/Model-Override-Config"
)
public String[] modelOverrides = {
"minecraft:redstone_wire->(item)minecraft:redstone",

View File

@ -1,28 +1,7 @@
/*
* 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.common.config;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
@ -83,7 +62,7 @@ public class ListHandler {
private static boolean doCheck(Block block, Set<String> regular, List<TagKey<Block>> tags)
{
String name = BuiltInRegistries.BLOCK.getKey(block).toString();
String name = Registry.BLOCK.getKey(block).toString();
if(regular.contains(name))
return true;
for(TagKey<Block> tag : tags)
@ -94,7 +73,7 @@ public class ListHandler {
private static boolean doCheck(Entity entity, Set<String> regular, List<TagKey<EntityType<?>>> tags)
{
String name = BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString();
String name = Registry.ENTITY_TYPE.getKey(entity.getType()).toString();
if(regular.contains(name))
return true;
for(TagKey<EntityType<?>> tag : tags)
@ -119,32 +98,32 @@ public class ListHandler {
ALLOWED_TILES_TAGS.clear();
PROPERTY_EXCEPTION_CLASSES.clear();
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));
Map<ResourceLocation, TagKey<Block>> blocktags = Registry.BLOCK.getTagNames().collect(Collectors.toMap(t -> t.location(), t -> t));
Map<ResourceLocation, TagKey<EntityType<?>>> entitytags = Registry.ENTITY_TYPE.getTagNames().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");
addWithWildcards(forbidden, FORBIDDEN_TILES, BuiltInRegistries.BLOCK, blocktags, FORBIDDEN_TILES_TAGS);
addWithWildcards(forbidden, FORBIDDEN_TILES, Registry.BLOCK, blocktags, FORBIDDEN_TILES_TAGS);
List<String> forbiddenEntity = new ArrayList<>(List.of(Constants.COMMON_CONFIG.blacklist.forbiddenEntities));
forbiddenEntity.add("#carryon:entity_blacklist");
addWithWildcards(forbiddenEntity, FORBIDDEN_ENTITIES, BuiltInRegistries.ENTITY_TYPE, entitytags, FORBIDDEN_ENTITIES_TAGS);
addWithWildcards(forbiddenEntity, FORBIDDEN_ENTITIES, Registry.ENTITY_TYPE, entitytags, FORBIDDEN_ENTITIES_TAGS);
List<String> allowedEntities = new ArrayList<>(List.of(Constants.COMMON_CONFIG.whitelist.allowedEntities));
allowedEntities.add("#carryon:entity_whitelist");
addWithWildcards(allowedEntities, ALLOWED_ENTITIES, BuiltInRegistries.ENTITY_TYPE, entitytags, ALLOWED_ENTITIES_TAGS);
addWithWildcards(allowedEntities, ALLOWED_ENTITIES, Registry.ENTITY_TYPE, entitytags, ALLOWED_ENTITIES_TAGS);
List<String> allowedBlocks = new ArrayList<>(List.of(Constants.COMMON_CONFIG.whitelist.allowedBlocks));
allowedBlocks.add("#carryon:block_whitelist");
addWithWildcards(allowedBlocks, ALLOWED_TILES, BuiltInRegistries.BLOCK, blocktags, ALLOWED_TILES_TAGS);
addWithWildcards(allowedBlocks, ALLOWED_TILES, Registry.BLOCK, blocktags, ALLOWED_TILES_TAGS);
List<String> forbiddenStacking = new ArrayList<>(List.of(Constants.COMMON_CONFIG.blacklist.forbiddenStacking));
forbiddenStacking.add("#carryon:stacking_blacklist");
addWithWildcards(forbiddenStacking, FORBIDDEN_STACKING, BuiltInRegistries.ENTITY_TYPE, entitytags, FORBIDDEN_STACKING_TAGS);
addWithWildcards(forbiddenStacking, FORBIDDEN_STACKING, Registry.ENTITY_TYPE, entitytags, FORBIDDEN_STACKING_TAGS);
List<String> allowedStacking = new ArrayList<>(List.of(Constants.COMMON_CONFIG.whitelist.allowedStacking));
allowedStacking.add("#carryon:stacking_whitelist");
addWithWildcards(allowedStacking, ALLOWED_STACKING, BuiltInRegistries.ENTITY_TYPE, entitytags, ALLOWED_STACKING_TAGS);
addWithWildcards(allowedStacking, ALLOWED_STACKING, Registry.ENTITY_TYPE, entitytags, ALLOWED_STACKING_TAGS);
for(String propString : Constants.COMMON_CONFIG.settings.placementStateExceptions)
{
@ -152,7 +131,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(Identifier.parse(name)).get().value();
Block blk = Registry.BLOCK.get(new ResourceLocation(name));
for(String propName : props.split(",")) {
for (Property<?> prop : blk.defaultBlockState().getProperties()) {
if (prop.getName().equals(propName))
@ -162,16 +141,16 @@ public class ListHandler {
}
}
private static <T> void addTag(String tag, Map<Identifier, TagKey<T>> tagMap, List<TagKey<T>> tags) {
private static <T> void addTag(String tag, Map<ResourceLocation, TagKey<T>> tagMap, List<TagKey<T>> tags) {
String sub = tag.substring(1);
TagKey<T> t = tagMap.get(Identifier.parse(sub));
TagKey<T> t = tagMap.get(new ResourceLocation(sub));
if (t != null)
tags.add(t);
}
private static <T> void addWithWildcards(List<String> entries, Set<String> toAddTo, Registry<T> registry, Map<Identifier, TagKey<T>> tags, List<TagKey<T>> toAddTags) {
private static <T> void addWithWildcards(List<String> entries, Set<String> toAddTo, Registry<T> registry, Map<ResourceLocation, TagKey<T>> tags, List<TagKey<T>> toAddTags) {
Identifier[] keys = registry.keySet().toArray(new Identifier[0]);
ResourceLocation[] keys = registry.keySet().toArray(new ResourceLocation[0]);
for (int i = 0; i < entries.size(); i++)
{
String curr = entries.get(i);
@ -181,7 +160,7 @@ public class ListHandler {
{
String[] filter = curr.replace("*", ",").split(",");
for (Identifier key : keys)
for (ResourceLocation key : keys)
{
if (containsAll(key.toString(), filter))

View File

@ -1,23 +1,3 @@
/*
* 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.common.pickupcondition;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@ -25,7 +5,7 @@ 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;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.Registry;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.state.BlockState;
@ -52,7 +32,7 @@ public class PickupCondition
public static DataResult<PickupCondition> of(String str)
{
if(!(str.contains("(") && str.endsWith(")")))
return DataResult.error(() -> "Error while parsing: "+ str +". Pickup Condition must contain proper brackets.");
return DataResult.error("Error while parsing: "+ str +". Pickup Condition must contain proper brackets.");
String cond = str.substring(str.indexOf("(") + 1, str.length()-1);
@ -71,7 +51,7 @@ public class PickupCondition
{
String name = match.contains("[") ? match.substring(0, match.indexOf("[")) : match;
String[] split = name.replace("*", ",").split(",");
String stateName = BuiltInRegistries.BLOCK.getKey(state.getBlock()).toString();
String stateName = Registry.BLOCK.getKey(state.getBlock()).toString();
if(StringHelper.matchesWildcards(stateName, split))
{
@ -96,7 +76,7 @@ public class PickupCondition
public boolean matches(Entity entity)
{
String entityName = BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString();
String entityName = Registry.ENTITY_TYPE.getKey(entity.getType()).toString();
if(wildcards)
{
String[] split = match.replace("*", ",").split(",");
@ -119,7 +99,7 @@ public class PickupCondition
private BlockResult parseState(String state)
{
try {
BlockResult result = BlockStateParser.parseForBlock(BuiltInRegistries.BLOCK, state, false);
BlockResult result = BlockStateParser.parseForBlock(Registry.BLOCK, state, false);
return result;
} catch (CommandSyntaxException e) {
e.printStackTrace();

View File

@ -1,23 +1,3 @@
/*
* 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.common.pickupcondition;
import com.mojang.serialization.DataResult;

View File

@ -1,28 +1,8 @@
/*
* 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.common.scripting;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.registries.Registries;
import net.minecraft.core.Registry;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerPlayer;
@ -39,13 +19,12 @@ public record CarryOnScript(
ScriptObject scriptObject,
ScriptConditions scriptConditions,
ScriptRender scriptRender,
ScriptEffects scriptEffects,
boolean overrideChecks)
ScriptEffects scriptEffects)
{
public boolean isValid()
{
return (isBlock() ^ isEntity()) && (scriptConditions != ScriptConditions.EMPTY || scriptRender != ScriptRender.EMPTY || scriptEffects != ScriptEffects.EMPTY || overrideChecks);
return (isBlock() ^ isEntity()) && (scriptConditions != ScriptConditions.EMPTY || scriptRender != ScriptRender.EMPTY || scriptEffects != ScriptEffects.EMPTY);
}
public boolean isBlock()
@ -64,8 +43,7 @@ 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),
Codec.BOOL.optionalFieldOf("override_checks", false).forGetter(CarryOnScript::overrideChecks)
ScriptEffects.CODEC.optionalFieldOf("effects", ScriptEffects.EMPTY).forGetter(CarryOnScript::scriptEffects)
).apply(instance, CarryOnScript::new)
);
@ -96,15 +74,17 @@ public record CarryOnScript(
public record ScriptObjectBlock(
Optional<ResourceKey<Block>> typeNameBlock,
MaterialCondition typeMaterial,
NumberBoundCondition typeHardness,
NumberBoundCondition typeResistance,
NBTCondition typeBlockTag
){
public static final ScriptObjectBlock EMPTY = new ScriptObjectBlock(Optional.empty(), NumberBoundCondition.NONE, NumberBoundCondition.NONE, NBTCondition.NONE);
public static final ScriptObjectBlock EMPTY = new ScriptObjectBlock(Optional.empty(), MaterialCondition.NONE, NumberBoundCondition.NONE, NumberBoundCondition.NONE, NBTCondition.NONE);
public static final Codec<ScriptObjectBlock> CODEC = RecordCodecBuilder.create(instance ->
instance.group(
ResourceKey.codec(Registries.BLOCK).optionalFieldOf("name").forGetter(ScriptObjectBlock::typeNameBlock),
ResourceKey.codec(Registry.BLOCK_REGISTRY).optionalFieldOf("name").forGetter(ScriptObjectBlock::typeNameBlock),
MaterialCondition.CODEC.optionalFieldOf("material", MaterialCondition.NONE).forGetter(ScriptObjectBlock::typeMaterial),
NumberBoundCondition.CODEC.optionalFieldOf("hardness", NumberBoundCondition.NONE).forGetter(ScriptObjectBlock::typeHardness),
NumberBoundCondition.CODEC.optionalFieldOf("resistance", NumberBoundCondition.NONE).forGetter(ScriptObjectBlock::typeResistance),
NBTCondition.CODEC.optionalFieldOf("nbt", NBTCondition.NONE).forGetter(ScriptObjectBlock::typeBlockTag)
@ -123,7 +103,7 @@ public record CarryOnScript(
public static final Codec<ScriptObjectEntity> CODEC = RecordCodecBuilder.create(instance ->
instance.group(
ResourceKey.codec(Registries.ENTITY_TYPE).optionalFieldOf("name").forGetter(ScriptObjectEntity::typeNameEntity),
ResourceKey.codec(Registry.ENTITY_TYPE_REGISTRY).optionalFieldOf("name").forGetter(ScriptObjectEntity::typeNameEntity),
NumberBoundCondition.CODEC.optionalFieldOf("health", NumberBoundCondition.NONE).forGetter(ScriptObjectEntity::typeHealth),
NumberBoundCondition.CODEC.optionalFieldOf("height", NumberBoundCondition.NONE).forGetter(ScriptObjectEntity::typeHeight),
NumberBoundCondition.CODEC.optionalFieldOf("width", NumberBoundCondition.NONE).forGetter(ScriptObjectEntity::typeWidth),
@ -173,8 +153,8 @@ public record CarryOnScript(
public static final Codec<ScriptRender> CODEC = RecordCodecBuilder.create(instance ->
instance.group(
ResourceKey.codec(Registries.BLOCK).optionalFieldOf("name_block").forGetter(ScriptRender::renderNameBlock),
ResourceKey.codec(Registries.ENTITY_TYPE).optionalFieldOf("name_entity").forGetter(ScriptRender::renderNameEntity),
ResourceKey.codec(Registry.BLOCK_REGISTRY).optionalFieldOf("name_block").forGetter(ScriptRender::renderNameBlock),
ResourceKey.codec(Registry.ENTITY_TYPE_REGISTRY).optionalFieldOf("name_entity").forGetter(ScriptRender::renderNameEntity),
CompoundTag.CODEC.optionalFieldOf("nbt").forGetter(ScriptRender::renderNBT),
OptionalVec3.CODEC.optionalFieldOf("translation", OptionalVec3.NONE).forGetter(ScriptRender::renderTranslation),
OptionalVec3.CODEC.optionalFieldOf("rotation", OptionalVec3.NONE).forGetter(ScriptRender::renderRotation),

View File

@ -1,44 +1,23 @@
/*
* 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.common.scripting;
import com.mojang.serialization.Codec;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.advancements.AdvancementHolder;
import net.minecraft.advancements.Advancement;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.ServerAdvancementManager;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.level.material.Material;
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.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.*;
public final class Matchables
{
@ -118,6 +97,91 @@ public final class Matchables
}
}
public record MaterialCondition(String material) implements Matchable<Material>
{
public static final Codec<MaterialCondition> CODEC = Codec.STRING.xmap(MaterialCondition::new, MaterialCondition::material);
public static final MaterialCondition NONE = new MaterialCondition("");
@Override
public boolean matches(Material material)
{
if (this.material == null || this.material.isEmpty())
return true;
switch (this.material) {
case "air":
return material == Material.AIR;
case "anvil":
return material == Material.HEAVY_METAL;
case "barrier":
return material == Material.BARRIER;
case "cactus":
return material == Material.CACTUS;
case "cake":
return material == Material.CAKE;
case "carpet":
return material == Material.CLOTH_DECORATION;
case "clay":
return material == Material.CLAY;
case "cloth":
return material == Material.WOOL;
case "dragon_egg":
return material == Material.EGG;
case "fire":
return material == Material.FIRE;
case "glass":
return material == Material.GLASS;
case "gourd":
return material == Material.VEGETABLE;
case "grass":
return material == Material.GRASS;
case "ground":
return material == Material.GRASS;
case "ice":
return material == Material.ICE;
case "iron":
return material == Material.METAL;
case "lava":
return material == Material.LAVA;
case "leaves":
return material == Material.LEAVES;
case "packed_ice":
return material == Material.ICE_SOLID;
case "piston":
return material == Material.PISTON;
case "plants":
return material == Material.PLANT;
case "portal":
return material == Material.PORTAL;
case "redstone_light":
return material == Material.BUILDABLE_GLASS;
case "rock":
return material == Material.STONE;
case "sand":
return material == Material.SAND;
case "snow":
return material == Material.TOP_SNOW;
case "sponge":
return material == Material.SPONGE;
case "structure_void":
return material == Material.STRUCTURAL_AIR;
case "tnt":
return material == Material.EXPLOSIVE;
case "vine":
return material == Material.PLANT;
case "water":
return material == Material.WATER;
case "web":
return material == Material.WEB;
case "wood":
return material == Material.WOOD;
default:
return false;
}
}
}
public record AdvancementCondition(String advancement) implements Matchable<ServerPlayer>
{
public static final Codec<AdvancementCondition> CODEC = Codec.STRING.xmap(AdvancementCondition::new, AdvancementCondition::advancement);
@ -127,8 +191,8 @@ public final class Matchables
@Override
public boolean matches(ServerPlayer player)
{
ServerAdvancementManager manager = player.level().getServer().getAdvancements();
AdvancementHolder adv = manager.get(Identifier.parse(advancement.isEmpty() ? "" : advancement));
ServerAdvancementManager manager = player.server.getAdvancements();
Advancement adv = manager.getAdvancement(new ResourceLocation(advancement.isEmpty() ? "" : advancement));
boolean achievement = adv == null ? true : player.getAdvancements().getOrStartProgress(adv).isDone();
return achievement;
@ -167,7 +231,7 @@ public final class Matchables
if (cond == null || cond.isEmpty())
return true;
Scoreboard score = player.level().getScoreboard();
Scoreboard score = player.getScoreboard();
String numb;
String scorename;
int iE = cond.indexOf("=");
@ -182,10 +246,19 @@ public final class Matchables
numb = cond.substring(iL);
scorename = cond.replace(numb, "");
Object2IntMap<Objective> scores = score.listPlayerScores(player);
int scoreVal = scores.getInt(score.getObjective(scorename));
Map<Objective, Score> o = score.getPlayerScores(player.getGameProfile().getName());
if (o != null)
{
Score sc = o.get(score.getObjective(scorename));
if (sc != null)
{
int points = sc.getScore();
return new NumberBoundCondition(numb).matches(scoreVal);
return new NumberBoundCondition(numb).matches(points);
}
}
return false;
}
}
@ -263,7 +336,7 @@ public final class Matchables
for (MobEffectInstance effect : fx)
{
int amp = effect.getAmplifier();
String name = effect.getEffect().getRegisteredName();
String name = Registry.MOB_EFFECT.getKey(effect.getEffect()).toString();
if (names.contains(name))
{

View File

@ -1,35 +1,14 @@
/*
* 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.common.scripting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.Registry;
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 net.minecraft.world.level.material.Material;
import tschipp.carryon.Constants;
import tschipp.carryon.common.scripting.CarryOnScript.ScriptObject.ScriptObjectBlock;
import tschipp.carryon.common.scripting.CarryOnScript.ScriptObject.ScriptObjectEntity;
@ -49,12 +28,13 @@ public class ScriptManager
return Optional.empty();
Block block = state.getBlock();
Material material = state.getMaterial();
float hardness = state.getDestroySpeed(level, pos);
float resistance = block.getExplosionResistance();
for (CarryOnScript script : SCRIPTS)
{
if (script.isBlock() && matchesAll(script, block, hardness, resistance, tag))
if (script.isBlock() && matchesAll(script, block, material, hardness, resistance, tag))
return Optional.of(script);
}
@ -69,9 +49,8 @@ public class ScriptManager
float height = entity.getBbHeight();
float width = entity.getBbWidth();
float health = entity instanceof LivingEntity ? ((LivingEntity) entity).getHealth() : 0.0f;
TagValueOutput output = TagValueOutput.createWithContext(new ProblemReporter.ScopedCollector(Constants.LOG), entity.registryAccess());
entity.save(output);
CompoundTag tag = output.buildResult();
CompoundTag tag = new CompoundTag();
entity.save(tag);
for (CarryOnScript script : SCRIPTS)
{
@ -88,7 +67,7 @@ public class ScriptManager
boolean matchname = true;
if(scEntity.typeNameEntity().isPresent())
matchname = entity.getType().equals(BuiltInRegistries.ENTITY_TYPE.get(scEntity.typeNameEntity().get()));
matchname = entity.getType().equals(Registry.ENTITY_TYPE.get(scEntity.typeNameEntity().get()));
boolean matchheight = scEntity.typeHeight().matches(height);
boolean matchwidth = scEntity.typeWidth().matches(width);
boolean matchhealth = scEntity.typeHealth().matches(health);
@ -97,17 +76,18 @@ public class ScriptManager
return matchname && matchheight && matchwidth && matchhealth && matchnbt;
}
private static boolean matchesAll(CarryOnScript script, Block block, float hardness, float resistance, CompoundTag nbt)
private static boolean matchesAll(CarryOnScript script, Block block, Material material, float hardness, float resistance, CompoundTag nbt)
{
ScriptObjectBlock scBlock = script.scriptObject().block();
boolean matchblock = true;
if(scBlock.typeNameBlock().isPresent())
matchblock = block == BuiltInRegistries.BLOCK.get(scBlock.typeNameBlock().get()).get().value();
matchblock = block == Registry.BLOCK.get(scBlock.typeNameBlock().get());
boolean matchnbt = scBlock.typeBlockTag().matches(nbt);
boolean matchmaterial = scBlock.typeMaterial().matches(material);
boolean matchhardness = scBlock.typeHardness().matches(hardness);
boolean matchresistance = scBlock.typeResistance().matches(resistance);
return matchnbt && matchblock && matchhardness && matchresistance;
return matchnbt && matchblock && matchmaterial && matchhardness && matchresistance;
}
}

View File

@ -1,69 +1,67 @@
/*
* 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.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.NbtOps;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.FileToIdConverter;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceLocation;
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>
public class ScriptReloadListener extends SimpleJsonResourceReloadListener
{
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
public ScriptReloadListener()
{
super(CarryOnScript.CODEC, FileToIdConverter.json("carryon/scripts"));
super(GSON, "carryon/scripts");
}
@Override
protected void apply(Map<Identifier, CarryOnScript> scripts, @NotNull ResourceManager resourceManager, @NotNull ProfilerFiller profilerFiller)
protected void apply(Map<ResourceLocation, JsonElement> objects, ResourceManager manager, ProfilerFiller profiler)
{
ScriptManager.SCRIPTS.clear();
scripts.forEach((path, script) -> {
if (script.isValid())
ScriptManager.SCRIPTS.add(script);
});
try {
objects.forEach((path, jsonElem) -> {
DataResult<CarryOnScript> res = CarryOnScript.CODEC.parse(JsonOps.INSTANCE, jsonElem);
if(res.result().isPresent())
{
CarryOnScript script = res.result().get();
if (script.isValid())
ScriptManager.SCRIPTS.add(script);
}
else
Constants.LOG.warn("Error while parsing script: " + res.error().get().message());
});
}
catch (Exception e)
{
e.printStackTrace();
}
ScriptManager.SCRIPTS.sort((s1, s2) -> Long.compare(s2.priority(), s1.priority()));
Collections.sort(ScriptManager.SCRIPTS, (s1, s2) -> Long.compare(s2.priority(), s1.priority()));
}
public static void syncScriptsWithClient(ServerPlayer player)
{
if (player != null)
{
DataResult<Tag> result = Codec.list(CarryOnScript.CODEC).encodeStart(NbtOps.INSTANCE, ScriptManager.SCRIPTS);
Tag tag = result.getOrThrow(s -> {throw new RuntimeException("Error while synching Carry On Scripts: " + s);});
Tag tag = result.getOrThrow(false, s -> {throw new RuntimeException("Error while synching Carry On Scripts: " + s);});
Services.PLATFORM.sendPacketToPlayer(Constants.PACKET_ID_SYNC_SCRIPTS, new ClientboundSyncScriptsPacket(tag), player);
}

View File

@ -1,107 +0,0 @@
package tschipp.carryon.compat;
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.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 javax.annotation.Nullable;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
public record ClothConfigCompat(BuiltConfig client, BuiltConfig common, Runnable onSave) {
public static Screen getConfigScreen(BuiltConfig client, BuiltConfig common, Screen parentScreen, Runnable onSave) {
ConfigBuilder builder = ConfigBuilder.create()
.setParentScreen(parentScreen)
.setTitle(Component.translatable("key.category.carryon.key.carry.category"));
buildConfigType(client, builder, "Client Config");
buildConfigType(common, builder, "Common Config");
builder.setSavingRunnable(onSave);
return builder.build();
}
private static void buildConfigType(BuiltConfig cfg, ConfigBuilder builder, String name) {
ConfigCategory configCategory = builder.getOrCreateCategory(Component.literal(name));
buildProperties(cfg, configCategory, builder, null);
}
private static void buildCategory(BuiltCategory category, ConfigCategory categoryBuilder, ConfigBuilder builder) {
ConfigEntryBuilder entryBuilder = builder.entryBuilder();
SubCategoryBuilder subBuilder = entryBuilder.startSubCategory(Component.translatable(category.translation));
buildProperties(category, categoryBuilder, builder, subBuilder);
}
private static void buildProperties(BuiltCategory category, ConfigCategory categoryBuilder, ConfigBuilder builder, @Nullable SubCategoryBuilder subBuilder) {
category.categories.forEach(cat -> {
buildCategory(cat, categoryBuilder, builder);
});
ConfigEntryBuilder entryBuilder = builder.entryBuilder();
category.properties.forEach(propertyData -> {
try {
AnnotationData data = propertyData.getData();
var entry =
switch (data.type()) {
case BOOLEAN ->
entryBuilder.startBooleanToggle(Component.literal(propertyData.getField().getName()), propertyData.getBoolean())
.setTooltip(Component.literal(data.description()))
.setDefaultValue(propertyData.getDefaultBoolean())
.setSaveConsumer((Consumer<Boolean>) propertyData.getSetter())
.build();
case INT ->
entryBuilder.startIntField(Component.literal(propertyData.getField().getName()), propertyData.getInt())
.setTooltip(Component.literal(data.description()))
.setDefaultValue(propertyData.getDefaultInt())
.setMin(data.min())
.setMax(data.max())
.setSaveConsumer((Consumer<Integer>) propertyData.getSetter())
.build();
case DOUBLE ->
entryBuilder.startDoubleField(Component.literal(propertyData.getField().getName()), propertyData.getDouble())
.setTooltip(Component.literal(data.description()))
.setDefaultValue(propertyData.getDefaultDouble())
.setMin(data.minD())
.setMax(data.maxD())
.setSaveConsumer((Consumer<Double>) propertyData.getSetter())
.build();
case STRING_ARRAY ->
entryBuilder.startStrList(Component.literal(propertyData.getField().getName()), List.of(propertyData.getStringArray()))
.setTooltip(Component.literal(data.description()))
.setInsertInFront(true)
.setDefaultValue(List.of(propertyData.getDefaultStringArray()))
.setCellErrorSupplier(str -> str.matches(data.validationRegex()) ? Optional.empty() : Optional.of(Component.literal("Invalid Format")))
.setSaveConsumer((Consumer<List<String>>) propertyData.getSetter())
.build();
default -> null;
};
if(subBuilder == null)
categoryBuilder.addEntry(entry);
else
subBuilder.add(entry);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
});
if(subBuilder != null)
categoryBuilder.addEntry(subBuilder.build());
}
}

View File

@ -1,23 +1,3 @@
/*
* 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.config;
@ -29,8 +9,7 @@ public record AnnotationData(
PropertyType type,
String description,
int min, int max,
double minD, double maxD,
String validationRegex
double minD, double maxD
) {
public static AnnotationData getData(Field field) {
@ -39,8 +18,7 @@ public record AnnotationData(
annotation.type(),
annotation.description(),
annotation.min(), annotation.max(),
annotation.minD(), annotation.maxD(),
annotation.validationRegex()
annotation.minD(), annotation.maxD()
);
}
}

View File

@ -1,23 +1,3 @@
/*
* 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.config;
import java.util.ArrayList;
@ -32,12 +12,9 @@ public class BuiltCategory {
public final String categoryDesc;
public final String category;
public final String translation;
public BuiltCategory(String categoryDesc, String category, String translation) {
public BuiltCategory(String categoryDesc, String category) {
this.categoryDesc = categoryDesc;
this.category = category;
this.translation = translation;
}
public Optional<PropertyData> getProperty(String id) {

View File

@ -1,23 +1,3 @@
/*
* 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.config;
public class BuiltConfig extends BuiltCategory {
@ -25,7 +5,7 @@ public class BuiltConfig extends BuiltCategory {
public final String fileName;
public BuiltConfig(String fileName) {
super(null, fileName, "key.carry.category");
super(null, fileName);
this.fileName = fileName;
}
}

View File

@ -1,28 +1,7 @@
/*
* 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.config;
//Many Thanks to ThatGravyBoat for this template!
import net.minecraft.core.HolderLookup;
import tschipp.carryon.client.modeloverride.ModelOverrideHandler;
import tschipp.carryon.common.config.ListHandler;
import tschipp.carryon.common.pickupcondition.PickupConditionHandler;
@ -54,10 +33,10 @@ public class ConfigLoader {
Services.PLATFORM.registerConfig(config);
}
public static void onConfigLoaded(HolderLookup.Provider provider) {
public static void onConfigLoaded() {
ListHandler.initConfigLists();
PickupConditionHandler.initPickupConditions();
ModelOverrideHandler.initModelOverrides(provider);
ModelOverrideHandler.initModelOverrides();
}
public static BuiltCategory buildCategory(String categoryDesc, Object object) throws IllegalAccessException {
@ -66,7 +45,7 @@ public class ConfigLoader {
if (configClass.isAnnotationPresent(Config.class)) {
category = new BuiltConfig(configClass.getAnnotation(Config.class).value());
} else if (configClass.isAnnotationPresent(Category.class)) {
category = new BuiltCategory(categoryDesc, configClass.getAnnotation(Category.class).value(), configClass.getAnnotation(Category.class).translation());
category = new BuiltCategory(categoryDesc, configClass.getAnnotation(Category.class).value());
} else {
throw new IllegalStateException("Config does not contain any @Config annotation or @Category");
}
@ -77,7 +56,7 @@ public class ConfigLoader {
if (type.equals(PropertyType.CATEGORY)) {
category.categories.add(buildCategory(field.getAnnotation(Property.class).description(), field.get(object)));
} else {
category.properties.add(new PropertyData(object, field, AnnotationData.getData(field), field.get(object)));
category.properties.add(new PropertyData(object, field, AnnotationData.getData(field)));
}
}
}

View File

@ -1,69 +1,15 @@
/*
* 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.config;
import java.lang.reflect.Field;
import java.util.function.Consumer;
public class PropertyData {
Object fieldClass;
Field field;
AnnotationData data;
Object defaultValue;
Consumer<?> setter;
public PropertyData(Object fieldClass, Field field, AnnotationData data, Object defaultValue) {
this.fieldClass = fieldClass;
this.field = field;
this.data = data;
this.defaultValue = defaultValue;
}
public Consumer<?> getSetter() {
return setter;
}
public void setSetter(Consumer<?> setter) {
this.setter = setter;
}
public AnnotationData getData() {
return data;
}
public Field getField() {
return field;
}
public Object getFieldClass() {
return fieldClass;
}
public record PropertyData(Object fieldClass, Field field, AnnotationData data) {
public String getId() {
return field.getName();
return field().getName();
}
public boolean getBoolean() throws IllegalAccessException {
return field.getBoolean(fieldClass);
return field().getBoolean(fieldClass());
}
public void setBoolean(boolean _boolean) {
@ -74,12 +20,8 @@ public class PropertyData {
}
}
public boolean getDefaultBoolean() {
return (boolean)defaultValue;
}
public int getInt() throws IllegalAccessException {
return field.getInt(fieldClass);
return field().getInt(fieldClass());
}
public void setInt(int _int) {
@ -90,12 +32,8 @@ public class PropertyData {
}
}
public int getDefaultInt() {
return (int)defaultValue;
}
public double getDouble() throws IllegalAccessException {
return field.getDouble(fieldClass);
return field().getDouble(fieldClass());
}
public void setDouble(double _double) {
@ -106,12 +44,8 @@ public class PropertyData {
}
}
public double getDefaultDouble() {
return (double)defaultValue;
}
public String[] getStringArray() throws IllegalAccessException {
return (String[])field.get(fieldClass);
return (String[])field().get(fieldClass());
}
public void setStringArray(String[] arr)
@ -122,8 +56,4 @@ public class PropertyData {
//Ignore
}
}
public String[] getDefaultStringArray() {
return (String[])defaultValue;
}
}

View File

@ -1,23 +1,3 @@
/*
* 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.config;
public enum PropertyType {

View File

@ -1,23 +1,3 @@
/*
* 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.config.annotations;
import java.lang.annotation.ElementType;
@ -29,5 +9,4 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
public @interface Category {
String value();
String translation() default "";
}

View File

@ -1,23 +1,3 @@
/*
* 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.config.annotations;
import java.lang.annotation.ElementType;

View File

@ -1,23 +1,3 @@
/*
* 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.config.annotations;
import tschipp.carryon.config.PropertyType;
@ -32,6 +12,7 @@ import java.lang.annotation.Target;
public @interface Property {
PropertyType type();
String description();
@ -40,6 +21,4 @@ public @interface Property {
double minD() default Double.MIN_VALUE;
double maxD() default Double.MAX_VALUE;
String validationRegex() default ".*";
}

View File

@ -1,29 +0,0 @@
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

@ -1,26 +1,5 @@
/*
* 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.llamalad7.mixinextras.injector.ModifyExpressionValue;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
@ -48,13 +27,6 @@ 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)
@ -93,7 +65,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)
if((Object)this instanceof Player thisPlayer && toUpdate instanceof Player otherPlayer)
{
CarryOnData carry = CarryOnDataManager.getCarryData(thisPlayer);
if(carry.isCarrying(CarryType.PLAYER)) {

View File

@ -1,36 +0,0 @@
package tschipp.carryon.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.state.EntityRenderState;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import tschipp.carryon.client.render.CarryRenderHelper;
import tschipp.carryon.client.render.ICarryOnRenderState;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnDataManager;
@Mixin(EntityRenderer.class)
public class EntityRendererMixin {
@Inject(at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/entity/EntityRenderer;extractRenderState(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/client/renderer/entity/state/EntityRenderState;F)V",
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

@ -1,28 +1,9 @@
/*
* 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 net.minecraft.client.model.HumanoidModel;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.renderer.entity.state.HumanoidRenderState;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@ -31,8 +12,9 @@ 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.Constants;
import tschipp.carryon.client.render.ICarryOnRenderState;
import tschipp.carryon.client.render.CarryRenderHelper;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnDataManager;
import tschipp.carryon.common.scripting.CarryOnScript.ScriptRender;
@Mixin(HumanoidModel.class)
@ -44,20 +26,20 @@ public class HumanoidModelMixin {
@Shadow
public ModelPart leftArm;
@Inject(at = @At("RETURN"), method = "setupAnim(Lnet/minecraft/client/renderer/entity/state/HumanoidRenderState;)V")
private void onSetupAnimations(HumanoidRenderState state, CallbackInfo ci)
@Inject(at = @At("RETURN"), method = "setupAnim(Lnet/minecraft/world/entity/LivingEntity;FFFFF)V")
private void onSetupAnimations(LivingEntity living, float f1, float f2, float f3, float f4, float f5, CallbackInfo ci)
{
if(state instanceof ICarryOnRenderState carryOnRenderState && Constants.CLIENT_CONFIG.renderArms)
if(living instanceof Player player && Constants.CLIENT_CONFIG.renderArms)
{
CarryOnData carry = carryOnRenderState.getCarryOnData();
if(carry != null && carry.isCarrying() && !state.isVisuallySwimming && !state.isFallFlying)
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if(carry.isCarrying() && !player.isVisuallySwimming() && !player.isFallFlying())
{
boolean sneaking = state.isCrouching;
boolean sneaking = !player.getAbilities().flying && player.isShiftKeyDown() || player.isCrouching();
float x = 1.0f + (sneaking ? 0.2f : 0.0f) + (carry.isCarrying(CarryOnData.CarryType.BLOCK) ? 0.0f : 0.3f);
float z = 0.05f;
float width = carryOnRenderState.getRenderWidth();
float width = CarryRenderHelper.getRenderWidth(player);
float offset = Math.min((width - 1) / 1.5f, 0.2f);
if(carry.getActiveScript().isPresent())

View File

@ -1,23 +1,3 @@
/*
* 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.llamalad7.mixinextras.injector.wrapoperation.Operation;
@ -29,17 +9,15 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Blocks;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import tschipp.carryon.common.carry.CarryOnData;
import tschipp.carryon.common.carry.CarryOnDataManager;
@Mixin(Inventory.class)
public class InventoryMixin
{
@Unique
private static final ItemStack DUMMY_STACK = new ItemStack(Blocks.COBBLESTONE, 1);
@Shadow
@ -62,7 +40,7 @@ public class InventoryMixin
return original.call(instance, slot);
}
@Inject(method = "addAndPickItem(Lnet/minecraft/world/item/ItemStack;)V", at = @At("HEAD"), cancellable = true)
@Inject(method = "setPickedItem(Lnet/minecraft/world/item/ItemStack;)V", at = @At("HEAD"), cancellable = true)
private void onPickBlock(CallbackInfo info)
{
if(CarryOnDataManager.getCarryData(player).isCarrying())
@ -76,11 +54,10 @@ public class InventoryMixin
info.cancel();
}
@Inject(method = "setSelectedSlot(I)V", at = @At("HEAD"), cancellable = true)
private void onSwapPaint(int slot, CallbackInfo info)
@Inject(method = "swapPaint(D)V", at = @At("HEAD"), cancellable = true)
private void onSwapPaint(double direction, CallbackInfo info)
{
CarryOnData data = CarryOnDataManager.getCarryData(player);
if(data.isCarrying() && data.getSelected() != slot)
if(CarryOnDataManager.getCarryData(player).isCarrying())
info.cancel();
}
}

View File

@ -1,51 +1,19 @@
/*
* 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.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.injector.WrapWithCondition;
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 = "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;
}
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();
}
}

View File

@ -1,68 +1,44 @@
/*
* 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 net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
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.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 {
public abstract class PlayerMixin extends LivingEntity {
private PlayerMixin(EntityType<? extends LivingEntity> type, Level level) {
super(type, level);
}
//We leave this in here to ensure cross-compatibility if world are upgraded from <1.21.8. Should be removed in the future.
@Inject(method = "readAdditionalSaveData(Lnet/minecraft/world/level/storage/ValueInput;)V", at = @At("RETURN"))
private void onReadAdditionalSaveData(ValueInput input, CallbackInfo ci)
@Inject(method = "defineSynchedData()V", at = @At("RETURN"))
private void onDefineSynchedData(CallbackInfo info) {
this.entityData.define(CarryOnDataManager.CARRY_DATA_KEY, new CompoundTag());
}
@Inject(method = "addAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("RETURN"))
private void onAddAdditionalSaveData(CompoundTag tag, CallbackInfo info)
{
Optional<CarryOnData> res = input.read("CarryOnData", CarryOnData.CODEC);
res.ifPresent(data -> CarryOnDataManager.setCarryData((Player)((Object)this), data));
CarryOnData carry = CarryOnDataManager.getCarryData((Player)(Object)this);
tag.put("CarryOnData", carry.getNbt());
}
@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);
}
@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"));
CarryOnDataManager.setCarryData((Player) (Object) this, data);
}
super.stopRiding();
}
}

View File

@ -1,56 +0,0 @@
package tschipp.carryon.mixin;
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(HumanoidRenderState.class)
public class PlayerRenderStateMixin implements ICarryOnRenderState {
@Unique
public CarryOnData carryOnData = null;
@Unique
public float renderWidth = 0f;
@Unique
public Player player = null;
@Unique
@Override
public CarryOnData getCarryOnData() {
return carryOnData;
}
@Unique
@Override
public void setCarryOnData(CarryOnData data) {
carryOnData = data;
}
@Unique
@Override
public float getRenderWidth() {
return renderWidth;
}
@Unique
@Override
public void setRenderWidth(float val) {
renderWidth = val;
}
@Override
public Player getPlayer() {
return player;
}
@Override
public void setPlayer(Player player) {
this.player = player;
}
}

View File

@ -1,29 +1,11 @@
/*
* 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;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Player;
public interface PacketBase extends CustomPacketPayload {
public abstract class PacketBase
{
public abstract void toBytes(FriendlyByteBuf buf);
void handle(Player player);
public abstract void handle(Player player);
}

View File

@ -1,59 +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.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

@ -1,57 +1,42 @@
/*
* 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.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import tschipp.carryon.Constants;
import tschipp.carryon.networking.PacketBase;
public record ClientboundStartRidingPacket(int iden, boolean ride) implements PacketBase
public class ClientboundStartRidingPacket extends PacketBase
{
public static final StreamCodec<RegistryFriendlyByteBuf, ClientboundStartRidingPacket> CODEC = StreamCodec.composite(
ByteBufCodecs.INT, ClientboundStartRidingPacket::iden,
ByteBufCodecs.BOOL, ClientboundStartRidingPacket::ride,
ClientboundStartRidingPacket::new
);
int entityId;
boolean ride;
public static final CustomPacketPayload.Type<ClientboundStartRidingPacket> TYPE = new Type<>(Constants.PACKET_ID_START_RIDING);
public ClientboundStartRidingPacket(FriendlyByteBuf buf)
{
this.entityId = buf.readInt();
this.ride = buf.readBoolean();
}
public ClientboundStartRidingPacket(int id, boolean ride)
{
this.entityId = id;
this.ride = ride;
}
@Override
public void toBytes(FriendlyByteBuf buf)
{
buf.writeInt(entityId);
buf.writeBoolean(ride);
}
@Override
public void handle(Player player)
{
Entity otherPlayer = player.level().getEntity(this.iden);
Entity otherPlayer = player.level.getEntity(this.entityId);
if(otherPlayer != null)
if(ride)
otherPlayer.startRiding(player);
else
otherPlayer.stopRiding();
}
@Override
public Type<ClientboundStartRidingPacket> type() {
return TYPE;
}
}

View File

@ -1,61 +1,46 @@
/*
* 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 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.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Player;
import tschipp.carryon.Constants;
import tschipp.carryon.common.scripting.CarryOnScript;
import tschipp.carryon.common.scripting.ScriptManager;
import tschipp.carryon.networking.PacketBase;
import java.util.List;
public record ClientboundSyncScriptsPacket(Tag serialized) implements PacketBase
public class ClientboundSyncScriptsPacket extends PacketBase
{
public static final StreamCodec<RegistryFriendlyByteBuf, ClientboundSyncScriptsPacket> CODEC = StreamCodec.composite(
ByteBufCodecs.TAG, ClientboundSyncScriptsPacket::serialized,
ClientboundSyncScriptsPacket::new
);
private Tag serialized;
public static final CustomPacketPayload.Type<ClientboundSyncScriptsPacket> TYPE = new Type<>(Constants.PACKET_ID_SYNC_SCRIPTS);
public ClientboundSyncScriptsPacket(FriendlyByteBuf buf)
{
this.serialized = buf.readNbt().get("data");
}
public ClientboundSyncScriptsPacket(Tag serialized)
{
this.serialized = serialized;
}
@Override
public void toBytes(FriendlyByteBuf buf)
{
CompoundTag tag = new CompoundTag();
tag.put("data", serialized);
buf.writeNbt(tag);
}
@Override
public void handle(Player player)
{
DataResult<List<CarryOnScript>> res = Codec.list(CarryOnScript.CODEC).parse(NbtOps.INSTANCE, serialized);
List<CarryOnScript> scripts = res.getOrThrow((s) -> {throw new RuntimeException("Failed deserializing carry on scripts on the client: " + s);});
List<CarryOnScript> scripts = res.getOrThrow(false, (s) -> {throw new RuntimeException("Failed deserializing carry on scripts on the client: " + s);});
ScriptManager.SCRIPTS.clear();
ScriptManager.SCRIPTS.addAll(scripts);
}
@Override
public Type<ClientboundSyncScriptsPacket> type() {
return TYPE;
}
}

View File

@ -1,43 +1,31 @@
/*
* 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.serverbound;
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.network.FriendlyByteBuf;
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;
public record ServerboundCarryKeyPressedPacket(boolean pressed) implements PacketBase
public class ServerboundCarryKeyPressedPacket extends PacketBase
{
public static final StreamCodec<RegistryFriendlyByteBuf, ServerboundCarryKeyPressedPacket> CODEC = StreamCodec.composite(
ByteBufCodecs.BOOL, ServerboundCarryKeyPressedPacket::pressed,
ServerboundCarryKeyPressedPacket::new
);
boolean pressed;
public static final CustomPacketPayload.Type<ServerboundCarryKeyPressedPacket> TYPE = new Type<>(Constants.PACKET_ID_KEY_PRESSED);
public ServerboundCarryKeyPressedPacket(FriendlyByteBuf buf)
{
this.pressed = buf.readBoolean();
}
public ServerboundCarryKeyPressedPacket(boolean pressed)
{
this.pressed = pressed;
}
@Override
public void toBytes(FriendlyByteBuf buf)
{
buf.writeBoolean(pressed);
}
@Override
public void handle(Player player)
@ -46,9 +34,4 @@ public record ServerboundCarryKeyPressedPacket(boolean pressed) implements Packe
carry.setKeyPressed(this.pressed);
CarryOnDataManager.setCarryData(player, carry);
}
@Override
public Type<ServerboundCarryKeyPressedPacket> type() {
return TYPE;
}
}

View File

@ -1,23 +1,3 @@
/*
* 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.platform;
import tschipp.carryon.Constants;

View File

@ -1,23 +1,3 @@
/*
* 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.platform.services;
import net.minecraft.world.entity.player.Player;

View File

@ -1,37 +1,14 @@
/*
* 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.platform.services;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.resources.ResourceLocation;
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 {
@ -59,21 +36,12 @@ public interface IPlatformHelper {
void registerConfig(BuiltConfig cfg);
<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);
<T extends PacketBase> void registerServerboundPacket(ResourceLocation id, int numericalId, Class<T> clazz, BiConsumer<T, FriendlyByteBuf> writer, Function<FriendlyByteBuf, T> reader, BiConsumer<T, Player> handler);
<T extends PacketBase, B extends FriendlyByteBuf> void registerClientboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args);
<T extends PacketBase> void registerClientboundPacket(ResourceLocation id, int numericalId, Class<T> clazz, BiConsumer<T, FriendlyByteBuf> writer, Function<FriendlyByteBuf, T> reader, BiConsumer<T, Player> handler);
void sendPacketToServer(Identifier id, PacketBase packet);
void sendPacketToServer(ResourceLocation 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

@ -1,23 +1,3 @@
/*
* 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.utils;
public class StringHelper

View File

@ -1,16 +0,0 @@
{
"carryon.category.settings": "Einstellungen",
"carryon.category.blacklist": "Blacklist",
"carryon.category.modeloverrides": "Modellüberschreibungen (Fortgeschritten)",
"carryon.category.custompickupconditions": "Benutzerdefinierte Bedingungen (Fortgeschritten)",
"carryon.category.whitelist": "Whitelist",
"carryon.general.modeloverrides.modeloverrides": "Modellüberschreibungen",
"carryon.general.blacklist.forbiddenentities": "Entitäten, die Spieler nicht aufheben dürfen",
"carryon.general.blacklist.forbiddentiles": "Blöcke, die Spieler nicht aufheben dürfen",
"carryon.category.custompickupconditions.custompickupconditionsblocks": "Benutzerdefinierte Bedingungen für Blöcke",
"carryon.category.custompickupconditions.custompickupconditionsentities": "Benutzerdefinierte Bedingungen für Entitäten",
"key.carry.desc": "Carry",
"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.category.carryon.key.carry.category": "uO ʎɹɹɐƆ"
"key.carry.category": "uO ʎɹɹɐƆ"
}

View File

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

View File

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

View File

@ -1,16 +0,0 @@
{
"carryon.category.settings": "Ajustes",
"carryon.category.blacklist": "Lista Negra",
"carryon.category.modeloverrides": "Reemplazos de Modelo (Avanzado)",
"carryon.category.custompickupconditions": "Condiciones Personalizadas para Recoger (Avanzado)",
"carryon.category.whitelist": "Lista Blanca",
"carryon.general.modeloverrides.modeloverrides": "Reemplazos de Modelo",
"carryon.general.blacklist.forbiddenentities": "Entidades que el jugador no puede recoger",
"carryon.general.blacklist.forbiddentiles": "Bloques que el jugador no puede recoger",
"carryon.category.custompickupconditions.custompickupconditionsblocks": "Condiciones Personalizadas para Recoger Bloques",
"carryon.category.custompickupconditions.custompickupconditionsentities": "Condiciones Personalizadas para Recoger Entidades",
"key.carry.desc": "Recoger",
"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.category.carryon.key.carry.category": "Carry On"
"key.carry.category": "Carry On"
}

View File

@ -1,16 +1,16 @@
{
"carryon.category.settings": "Paramètres",
"carryon.category.blacklist": "Liste noire",
"carryon.category.modeloverrides": "Modèle de Remplacement (Avancé)",
"carryon.category.custompickupconditions": "Conditions de ramassage personalisés (Avancé)",
"carryon.category.whitelist": "Liste blanche",
"carryon.category.settings": "Paramètres",
"carryon.category.blacklist": "Liste noire",
"carryon.category.modeloverrides": "Modèle de Remplacement (Avancé)",
"carryon.category.custompickupconditions": "Conditions de ramassage personalisés (Avancé)",
"carryon.category.whitelist": "Liste blanche",
"carryon.general.modeloverrides.modeloverrides": "Modèle de Remplacement",
"carryon.general.blacklist.forbiddenentities": "Entités que le joueur ne peut pas saisir",
"carryon.general.blacklist.forbiddentiles": "Blocs que le joueur ne peut pas saisir",
"carryon.category.custompickupconditions.custompickupconditionsblocks": "Conditions de ramassage de blocs personalisés",
"carryon.category.custompickupconditions.custompickupconditionsentities": "Conditions de ramassage d'entités personalisés",
"carryon.general.modeloverrides.modeloverrides": "Modèle de Remplacement",
"carryon.general.blacklist.forbiddenentities": "Entités que le joueur ne peut pas saisir",
"carryon.general.blacklist.forbiddentiles": "Blocs que le joueur ne peut pas saisir",
"carryon.category.custompickupconditions.custompickupconditionsblocks": "Conditions de ramassage de blocs personalisés",
"carryon.category.custompickupconditions.custompickupconditionsentities": "Conditions de ramassage d'entités personalisés",
"key.carry.desc": "Saisir",
"key.category.carryon.key.carry.category": "Carry On"
"key.carry.desc": "Saisir",
"key.carry.category": "Carry On"
}

View File

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

View File

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

View File

@ -1,16 +0,0 @@
{
"carryon.category.settings": "設定",
"carryon.category.blacklist": "ブラックリスト",
"carryon.category.modeloverrides": "モデルの上書き(上級)",
"carryon.category.custompickupconditions": "カスタム持ち上げ条件(上級)",
"carryon.category.whitelist": "ホワイトリスト",
"carryon.general.modeloverrides.modeloverrides": "モデルの上書き",
"carryon.general.blacklist.forbiddenentities": "プレイヤーが持ち上げられないエンティティ",
"carryon.general.blacklist.forbiddentiles": "プレーヤーが持ち上げられないブロック",
"carryon.category.custompickupconditions.custompickupconditionsblocks": "カスタムブロック持ち上げ条件",
"carryon.category.custompickupconditions.custompickupconditionsentities": "カスタムエンティティ持ち上げ条件",
"key.carry.desc": "Carry",
"key.category.carryon.key.carry.category": "Carry On"
}

View File

@ -1,16 +1,16 @@
{
"carryon.category.settings": "설정",
"carryon.category.blacklist": "블랙리스트",
"carryon.category.modeloverrides": "모델 재정의 (고급)",
"carryon.category.custompickupconditions": "맞춤형 들기 조건 (고급)",
"carryon.category.modeloverrides": "모델 오버라이딩 (고급)",
"carryon.category.custompickupconditions": "커스텀 들기 컨디션 (고급)",
"carryon.category.whitelist": "화이트리스트",
"carryon.general.modeloverrides.modeloverrides": "모델 재정의",
"carryon.general.blacklist.forbiddenentities": "플레이어가 들 수 없는 개체",
"carryon.general.modeloverrides.modeloverrides": "모델 오버라이딩",
"carryon.general.blacklist.forbiddenentities": "플레이어가 들 수 없는 엔티티",
"carryon.general.blacklist.forbiddentiles": "플레이어가 들 수 없는 블록",
"carryon.category.custompickupconditions.custompickupconditionsblocks": "맞춤형 블록 들기 조건",
"carryon.category.custompickupconditions.custompickupconditionsentities": "맞춤형 개체 들기 조건",
"carryon.category.custompickupconditions.custompickupconditionsblocks": "커스텀 블록 들기 컨디션",
"carryon.category.custompickupconditions.custompickupconditionsentities": "커스텀 엔티티 들기 컨디션",
"key.carry.desc": "들고 나르기",
"key.category.carryon.key.carry.category": "Carry On"
"key.carry.category": "Carry On"
}

View File

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

View File

@ -1,17 +0,0 @@
{
"__comment__": "Translated by @alpeerkaraca",
"carryon.category.settings": "Ayarlar",
"carryon.category.blacklist": "Kara Liste",
"carryon.category.modeloverrides": "Üzerine Yazılan Modeller (Gelişmiş)",
"carryon.category.custompickupconditions": "Özel Yerden Alma Durumları (Gelişmiş)",
"carryon.category.whitelist": "Beyaz Liste",
"carryon.general.modeloverrides.modeloverrides": "Modellerin Üzerine Yaz",
"carryon.general.blacklist.forbiddenentities": "Oyuncunun Alamayacağı Varlıklar",
"carryon.general.blacklist.forbiddentiles": "Oyuncunun Alamayacağı Bloklar",
"carryon.category.custompickupconditions.custompickupconditionsblocks": "Özel Blok Alma Durumları",
"carryon.category.custompickupconditions.custompickupconditionsentities": "Özel Varlık Alma Durumları",
"key.carry.desc": "Taşı",
"key.category.carryon.key.carry.category": "Carry On"
}

View File

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

View File

@ -1,16 +0,0 @@
{
"carryon.category.settings": "设置",
"carryon.category.blacklist": "黑名单",
"carryon.category.modeloverrides": "模型覆盖(高级设置)",
"carryon.category.custompickupconditions": "自定义抱起条件(高级设置)",
"carryon.category.whitelist": "白名单",
"carryon.general.modeloverrides.modeloverrides": "模型覆盖",
"carryon.general.blacklist.forbiddenentities": "玩家不能抱起的实体",
"carryon.general.blacklist.forbiddentiles": "玩家不能抱起的方块",
"carryon.category.custompickupconditions.custompickupconditionsblocks": "自定义抱起方块条件",
"carryon.category.custompickupconditions.custompickupconditionsentities": "自定义抱起实体条件",
"key.carry.desc": "抱起",
"key.category.carryon.key.carry.category": "搬运"
}

View File

@ -1,16 +0,0 @@
{
"carryon.category.settings": "設定",
"carryon.category.blacklist": "黑名單",
"carryon.category.modeloverrides": "模型覆蓋(進階)",
"carryon.category.custompickupconditions": "自訂拾取條件(進階)",
"carryon.category.whitelist": "白名單",
"carryon.general.modeloverrides.modeloverrides": "模型覆蓋",
"carryon.general.blacklist.forbiddenentities": "玩家無法拾取的實體",
"carryon.general.blacklist.forbiddentiles": "玩家無法拾取的方塊",
"carryon.category.custompickupconditions.custompickupconditionsblocks": "自訂方塊拾取條件",
"carryon.category.custompickupconditions.custompickupconditionsentities": "自訂實體拾取條件",
"key.carry.desc": "攜帶",
"key.category.carryon.key.carry.category": "Carry On"
}

View File

@ -2,18 +2,15 @@
"required": true,
"minVersion": "0.8",
"package": "tschipp.carryon.mixin",
"compatibilityLevel": "JAVA_21",
"compatibilityLevel": "JAVA_17",
"mixins": [
"EntityMixin",
"InventoryMixin",
"PlayerMixin"
],
"client": [
"AvatarRendererMixin",
"EntityRendererMixin",
"HumanoidModelMixin",
"MinecraftMixin",
"PlayerRenderStateMixin"
"MinecraftMixin"
],
"server": [
],
@ -21,5 +18,5 @@
"injectors": {
"defaultRequire": 1
},
"refmap": "${mod_id}.refmap.json"
"refmap": "${refmap_target}refmap.json"
}

View File

@ -1,6 +1,6 @@
{
"pack": {
"description": "${mod_name}",
"pack_format": 34
"pack_format": 8
}
}

View File

@ -1,24 +1,28 @@
plugins {
id 'multiloader-loader'
id 'fabric-loom' version "${loom_version}"
id 'fabric-loom' version '0.12-SNAPSHOT'
id 'maven-publish'
id 'idea'
}
archivesBaseName = "${mod_id}-fabric-${minecraft_version}"
apply from: 'https://raw.githubusercontent.com/MinecraftModDevelopment/Gradle-Collection/22e7d543a18cd30675277fbfa3669e3d9e206010/generic/secrets.gradle'
if (project.hasProperty('secretFile')) {
loadSecrets(new File((String) findProperty('secretFile')))
}
if (System.getenv('BUILD_NUMBER') != null) {
version += "." + System.getenv('BUILD_NUMBER')
}
repositories {
maven {
name = "Shedaniel"
url "https://maven.shedaniel.me/"
}
maven { url 'https://jitpack.io' }
maven {
name = "Terraformers"
url = "https://maven.terraformersmc.com/"
url "https://maven.siphalor.de/"
name "Siphalor's Maven"
}
}
dependencies {
minecraft "com.mojang:minecraft:${minecraft_version}"
mappings loom.layered() {
@ -28,21 +32,13 @@ 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'
modApi("me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}") {
exclude(group: "net.fabricmc.fabric-api")
}
modApi "com.terraformersmc:modmenu:17.0.0-beta.1"
implementation project(":Common")
modRuntimeOnly "de.siphalor:amecsapi-1.19:1.5.0+mc22w17a"
include implementation("com.github.llamalad7.mixinextras:mixinextras-fabric:${mixinextras_version}")
annotationProcessor("com.github.llamalad7.mixinextras:mixinextras-fabric:${mixinextras_version}")
}
loom {
def aw = project(':Common').file("src/main/resources/${mod_id}.accesswidener")
if (aw.exists()) {
accessWidenerPath.set(aw)
}
mixin {
defaultRefmapName.set("${mod_id}.refmap.json")
}
runs {
client {
client()
@ -58,3 +54,41 @@ loom {
}
}
}
var refmap_target = archivesBaseName + "-"
processResources {
from project(":Common").sourceSets.main.resources
inputs.property "version", project.version
inputs.property "refmap_target", refmap_target
filesMatching("fabric.mod.json") {
expand "version": project.version
}
filesMatching("carryon.mixins.json") {
expand "refmap_target": refmap_target
}
}
tasks.withType(JavaCompile) {
source(project(":Common").sourceSets.main.allSource)
}
publishing {
publications {
mavenJava(MavenPublication) {
groupId project.group
artifactId project.archivesBaseName
version project.version
from components.java
}
}
repositories {
maven {
url "file://" + System.getenv("local_maven")
}
}
}

View File

@ -1,35 +1,18 @@
/*
* 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;
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.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.minecraft.network.FriendlyByteBuf;
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
{
@ -38,19 +21,22 @@ public class CarryOnFabricClientMod implements ClientModInitializer
{
CarryOnKeybinds.registerKeybinds(KeyBindingHelper::registerKeyBinding);
ClientEvents.registerEvents();
CarryOnCommon.registerClientPackets(true);
CarryOnCommon.registerClientPackets();
}
public static void sendPacketToServer(PacketBase packet)
public static void sendPacketToServer(ResourceLocation id, PacketBase packet)
{
ClientPlayNetworking.send(packet);
FriendlyByteBuf buf = PacketByteBufs.create();
packet.toBytes(buf);
ClientPlayNetworking.send(id, buf);
}
public static <T extends PacketBase> void registerClientboundPacket(CustomPacketPayload.Type<T> id, BiConsumer<T, Player> handler)
public static <T extends PacketBase> void registerClientboundPacket(ResourceLocation id, Function<FriendlyByteBuf, T> reader, BiConsumer<T, Player> handler)
{
ClientPlayNetworking.registerGlobalReceiver(id, (T packet, ClientPlayNetworking.Context context) -> {
context.client().execute(() -> {
handler.accept(packet, context.player());
ClientPlayNetworking.registerGlobalReceiver(id, (client, packetHandler, buf, responseSender) -> {
T packet = reader.apply(buf);
client.execute(() -> {
handler.accept(packet, client.player);
});
});
}

View File

@ -1,56 +1,13 @@
/*
* 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;
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() {
@ -68,7 +25,6 @@ public class CarryOnFabricMod implements ModInitializer {
CommonEvents.registerEvents();
CarryOnCommon.registerServerPackets();
CarryOnCommon.registerClientPackets(false);
}
}

View File

@ -1,25 +1,6 @@
/*
* 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.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;
@ -38,7 +19,6 @@ 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

@ -1,16 +0,0 @@
package tschipp.carryon.compat;
import net.minecraft.client.gui.screens.Screen;
import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.fabric.ConfigLoaderImpl;
public class ClothConfigCompatFabric {
public static Screen createScreen(BuiltConfig client, BuiltConfig common, Screen screen) {
return ClothConfigCompat.getConfigScreen(client, common, screen, ConfigLoaderImpl::saveConfigs);
}
}

View File

@ -1,17 +0,0 @@
package tschipp.carryon.compat;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import tschipp.carryon.config.BuiltConfig;
import tschipp.carryon.config.fabric.ConfigLoaderImpl;
public class ModMenuCompat implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
BuiltConfig[] configs = ConfigLoaderImpl.CONFIGS.values().toArray(new BuiltConfig[0]);
return (parent) -> ClothConfigCompatFabric.createScreen(configs[1], configs[0], parent);
}
}

View File

@ -1,29 +1,8 @@
/*
* 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.config.fabric;
import com.google.gson.*;
import net.fabricmc.loader.api.FabricLoader;
import org.apache.commons.io.FileUtils;
import tschipp.carryon.common.config.ListHandler;
import tschipp.carryon.config.*;
import java.io.File;
@ -31,7 +10,7 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -40,7 +19,7 @@ public class ConfigLoaderImpl {
private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
//Default JSON and config data.
public static final Map<JsonObject, BuiltConfig> CONFIGS = new LinkedHashMap<>();
public static final Map<JsonObject, BuiltConfig> CONFIGS = new HashMap<>();
public static void initialize() throws IOException {
Path cfgPath = FabricLoader.getInstance().getConfigDir();
@ -69,11 +48,11 @@ public class ConfigLoaderImpl {
JsonElement value = entry.getValue();
if (value instanceof JsonPrimitive configValue) {
category.getProperty(id).ifPresent(data -> {
if (configValue.isBoolean() && data.getData().type().equals(PropertyType.BOOLEAN))
if (configValue.isBoolean() && data.data().type().equals(PropertyType.BOOLEAN))
data.setBoolean(configValue.getAsBoolean());
if (configValue.isNumber() && data.getData().type().equals(PropertyType.INT)) {
if (configValue.isNumber() && data.data().type().equals(PropertyType.INT)) {
int configInt = configValue.getAsInt();
if (configInt > data.getData().max() || configInt < data.getData().min()) {
if (configInt > data.data().max() || configInt < data.data().min()) {
try {
config.addProperty(id, data.getInt());
} catch (IllegalAccessException ignored) {
@ -82,9 +61,9 @@ public class ConfigLoaderImpl {
data.setInt(configInt);
}
}
if (configValue.isNumber() && data.getData().type().equals(PropertyType.DOUBLE)) {
if (configValue.isNumber() && data.data().type().equals(PropertyType.DOUBLE)) {
double configDouble = configValue.getAsDouble();
if (configDouble > data.getData().maxD() || configDouble < data.getData().minD()) {
if (configDouble > data.data().maxD() || configDouble < data.data().minD()) {
try {
config.addProperty(id, data.getDouble());
} catch (IllegalAccessException ignored) {
@ -98,7 +77,7 @@ public class ConfigLoaderImpl {
category.getCategory(id).ifPresent(cat -> loadConfig(cat, subConfig));
} else if (value instanceof JsonArray list) {
category.getProperty(id).ifPresent(data -> {
if(data.getData().type() == PropertyType.STRING_ARRAY)
if(data.data().type() == PropertyType.STRING_ARRAY)
{
List<String> ls = new ArrayList<>();
for(JsonElement arrEle : list)
@ -117,20 +96,6 @@ public class ConfigLoaderImpl {
return config;
}
public static void saveConfigs() {
try {
Path cfgPath = FabricLoader.getInstance().getConfigDir();
for (Map.Entry<JsonObject, BuiltConfig> entry : CONFIGS.entrySet()) {
File cfgFile = new File(cfgPath.toFile(), entry.getValue().fileName+".json");
cfgPath.toFile().mkdirs();
FileUtils.write(cfgFile, GSON.toJson(entry.getKey()), StandardCharsets.UTF_8);
}
ListHandler.initConfigLists();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void registerConfig(BuiltConfig config) {
try {
JsonObject configJson = new JsonObject();
@ -150,39 +115,21 @@ public class ConfigLoaderImpl {
builder.add(category.category, categoryJson);
}
@SuppressWarnings("unchecked")
private static void buildProperty(JsonObject builder, PropertyData data) throws IllegalAccessException {
AnnotationData annotationData = data.getData();
AnnotationData annotationData = data.data();
builder.addProperty("//"+data.getId(), annotationData.description());
switch (annotationData.type()) {
case BOOLEAN:
builder.addProperty(data.getId(), data.getBoolean());
data.setSetter((b) -> {builder.addProperty(data.getId(), (boolean)b); data.setBoolean((boolean)b);});
break;
case INT:
builder.addProperty(data.getId(), data.getInt());
data.setSetter((b) -> {builder.addProperty(data.getId(), (int)b); data.setInt((int)b);});
break;
case DOUBLE:
builder.addProperty(data.getId(), data.getDouble());
data.setSetter((b) -> {builder.addProperty(data.getId(), (double)b); data.setDouble((double)b);});
break;
case STRING_ARRAY:
case BOOLEAN -> builder.addProperty(data.getId(), data.getBoolean());
case INT -> builder.addProperty(data.getId(), data.getInt());
case DOUBLE -> builder.addProperty(data.getId(), data.getDouble());
case STRING_ARRAY -> {
JsonArray arr = new JsonArray();
for(String s : data.getStringArray())
arr.add(s);
builder.add(data.getId(), arr);
data.setSetter(list -> {
JsonArray overwrite = new JsonArray();
for(String s : (List<String>)list)
overwrite.add(s);
builder.add(data.getId(), overwrite);
data.setStringArray(((List<?>) list).toArray(new String[0]));
});
break;
default:
throw new IllegalAccessException("Unknown property type.");
}
default -> throw new IllegalAccessException("Unknown property type.");
}
}
}

View File

@ -1,23 +1,3 @@
/*
* 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.events;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;

View File

@ -1,33 +1,11 @@
/*
* 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.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;
@ -51,12 +29,12 @@ public class CommonEvents {
CommonLifecycleEvents.TAGS_LOADED.register((registries, client) -> {
if(!client)
ConfigLoader.onConfigLoaded(registries);
ConfigLoader.onConfigLoaded();
});
UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> {
if(world.isClientSide())
if(world.isClientSide)
return InteractionResult.PASS;
BlockPos pos = hitResult.getBlockPos();
@ -97,7 +75,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);
@ -133,10 +111,12 @@ 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,23 +135,7 @@ public class CommonEvents {
return InteractionResult.PASS;
}));
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;
});
//TODO: drop carried when attacked
}
}

View File

@ -1,23 +1,3 @@
/*
* 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;

View File

@ -1,44 +1,31 @@
/*
* 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.Minecraft;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.ItemInHandRenderer;
import net.minecraft.client.renderer.SubmitNodeCollector;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderBuffers;
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/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)
@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)
{
if(CarriedObjectRender.draw(player, poseStack, packedLight, partialTick,nodeCollector,true))
if(CarryRenderHelper.getPerspective() == 0 && CarriedObjectRender.drawFirstPerson(player, buffer, poseStack, light, partialTicks))
ci.cancel();
}

View File

@ -0,0 +1,23 @@
package tschipp.carryon.mixin;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import net.minecraft.client.Camera;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.LightTexture;
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(LevelRenderer.class)
public class LevelRendererMixin
{
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleEngine;render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;Lnet/minecraft/client/renderer/LightTexture;Lnet/minecraft/client/Camera;F)V"), method = "renderLevel(Lcom/mojang/blaze3d/vertex/PoseStack;FJZLnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/GameRenderer;Lnet/minecraft/client/renderer/LightTexture;Lcom/mojang/math/Matrix4f;)V")
private void onRenderLevel(PoseStack poseStack, float f, long l, boolean bl, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f matrix4f, CallbackInfo ci)
{
CarriedObjectRender.drawThirdPerson(gameRenderer.getMinecraft().getFrameTime(), poseStack);
}
}

View File

@ -1,26 +1,5 @@
/*
* 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 net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.player.Player;
@ -36,13 +15,13 @@ import tschipp.carryon.common.carry.PlacementHandler;
@Mixin(Player.class)
public class PlayerMixinFabric
{
@Inject(at = @At("HEAD"), method = "hurtServer(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/damagesource/DamageSource;F)Z")
private void onHurt(ServerLevel level, DamageSource damageSource, float amount, CallbackInfoReturnable<Boolean> cir) {
@Inject(at = @At("HEAD"), method = "hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z")
private void onHurt(DamageSource damageSource, float f, CallbackInfoReturnable<Boolean> cir) {
if(Constants.COMMON_CONFIG.settings.dropCarriedWhenHit)
{
Player player = ((Player)(Object)this);
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if(carry.isCarrying())
if(carry.isCarrying() && !player.level.isClientSide)
PlacementHandler.placeCarried((ServerPlayer)player);
}

View File

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

View File

@ -1,23 +1,3 @@
/*
* 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.platform;
import net.minecraft.world.entity.player.Player;

View File

@ -1,44 +1,20 @@
/*
* 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.platform;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
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.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceLocation;
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 {
@ -64,51 +40,34 @@ 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)
public <T extends PacketBase> void registerServerboundPacket(ResourceLocation id, int numericalId, Class<T> clazz, BiConsumer<T, FriendlyByteBuf> writer, Function<FriendlyByteBuf, T> reader, BiConsumer<T, Player> handler)
{
PayloadTypeRegistry.playC2S().register(type, (StreamCodec<RegistryFriendlyByteBuf, T>)codec);
ServerPlayNetworking.registerGlobalReceiver(type, (T packet, ServerPlayNetworking.Context context) -> {
context.server().execute(() -> {
handler.accept(packet, context.player());
ServerPlayNetworking.registerGlobalReceiver(id, (server, player, packetHandler, buf, responseSender) -> {
T packet = reader.apply(buf);
server.execute(() -> {
handler.accept(packet, player);
});
});
}
@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)
public <T extends PacketBase> void registerClientboundPacket(ResourceLocation id, int numericalId, Class<T> clazz, BiConsumer<T, FriendlyByteBuf> writer, Function<FriendlyByteBuf, T> reader, BiConsumer<T, Player> handler)
{
boolean client = (boolean)args[0];
if(!client)
PayloadTypeRegistry.playS2C().register(type, (StreamCodec<RegistryFriendlyByteBuf, T>)codec);
else
CarryOnFabricClientMod.registerClientboundPacket(type, handler);
CarryOnFabricClientMod.registerClientboundPacket(id, reader, handler);
}
@Override
public void sendPacketToServer(Identifier id, PacketBase packet)
public void sendPacketToServer(ResourceLocation id, PacketBase packet)
{
CarryOnFabricClientMod.sendPacketToServer(packet);
CarryOnFabricClientMod.sendPacketToServer(id, packet);
}
@Override
public void sendPacketToPlayer(Identifier id, PacketBase packet, ServerPlayer player)
public void sendPacketToPlayer(ResourceLocation 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);
FriendlyByteBuf buf = PacketByteBufs.create();
packet.toBytes(buf);
ServerPlayNetworking.send(player, id, buf);
}
}

View File

@ -1,35 +1,15 @@
/*
* 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.scripting;
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceLocation;
import tschipp.carryon.Constants;
import tschipp.carryon.common.scripting.ScriptReloadListener;
public class IdentifiableScriptReloadListener extends ScriptReloadListener implements IdentifiableResourceReloadListener
{
@Override
public Identifier getFabricId()
public ResourceLocation getFabricId()
{
return Identifier.fromNamespaceAndPath(Constants.MOD_ID, "carryon_scripts");
return new ResourceLocation(Constants.MOD_ID, "carryon_scripts");
}
}

View File

@ -2,13 +2,14 @@
"required": true,
"minVersion": "0.8",
"package": "tschipp.carryon.mixin",
"compatibilityLevel": "JAVA_21",
"compatibilityLevel": "JAVA_17",
"mixins": [
"PlayerMixinFabric"
],
"client": [
"ItemInHandRendererMixin",
"ScreenMixin"
"LevelRendererMixin",
"ScreenMixin"
],
"injectors": {
"defaultRequire": 1

View File

@ -1,11 +1,11 @@
{
"schemaVersion": 1,
"id": "${mod_id}",
"id": "carryon",
"version": "${version}",
"name": "${mod_name}",
"description": "${description}",
"name": "Carry On",
"description": "Carry On is a simple mod that improves game interaction by allowing players to pick up, carry, and place single block Tile Entities using only their empty hands.",
"authors": [
"Tschipp", "Purplicious_Cow"
"Tschipp", "Purplicious_Cow", "cy4n"
],
"contact": {
"homepage": "https://tschipp.ch/",
@ -13,7 +13,7 @@
"issues": "https://github.com/Tschipp/CarryOn/issues"
},
"license": "${license}",
"license": "GNU LGPLv3",
"icon": "logo.png",
"environment": "*",
@ -23,9 +23,6 @@
],
"client": [
"tschipp.carryon.CarryOnFabricClientMod"
],
"modmenu" : [
"tschipp.carryon.compat.ModMenuCompat"
]
},
"mixins": [
@ -34,10 +31,10 @@
],
"depends": {
"fabricloader": ">=${fabric_loader_version}",
"fabric-api": "*",
"minecraft": "${minecraft_version_range_fabric}",
"java": ">=${java_version}"
"fabricloader": ">=0.14",
"fabric": "*",
"minecraft": "1.19.x",
"java": ">=17"
}
}

View File

@ -1,13 +1,38 @@
plugins {
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.+'
buildscript {
repositories {
maven { url = 'https://maven.minecraftforge.net' }
maven { url = 'https://repo.spongepowered.org/repository/maven-public/' }
maven { url = 'https://maven.parchmentmc.org' }
mavenCentral()
gradlePluginPortal()
}
dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT'
classpath 'org.parchmentmc:librarian:1.+'
classpath 'gradle.plugin.com.github.johnrengelman:shadow:7.1.2'
}
}
apply plugin: 'java'
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse'
apply plugin: 'org.spongepowered.mixin'
apply plugin: 'maven-publish'
apply plugin: 'org.parchmentmc.librarian.forgegradle'
apply plugin: 'com.github.johnrengelman.shadow'
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}"
}
jarJar.enable()
archivesBaseName = "${mod_id}-forge-${minecraft_version}"
mixin {
add sourceSets.main, "${mod_id}.refmap.json"
@ -16,25 +41,14 @@ 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: 'parchment', version: parchment_mappings
copyIdeResources = true
reobf = false
def at = file('src/main/resources/META-INF/accesstransformer.cfg')
if (at.exists()) {
accessTransformer = at
mappings channel: 'parchment', version: "${parchment_mappings}"
if (project.hasProperty('forge_ats_enabled') && project.findProperty('forge_ats_enabled').toBoolean()) {
// This location is hardcoded in Forge and can not be changed.
// https://github.com/MinecraftForge/MinecraftForge/blob/be1698bb1554f9c8fa2f58e32b9ab70bc4385e60/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java#L123
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
project.logger.debug('Forge Access Transformers are enabled for this project.')
}
runs {
@ -44,7 +58,6 @@ 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 {
@ -60,7 +73,6 @@ 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 {
@ -77,7 +89,6 @@ 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 {
@ -93,59 +104,71 @@ sourceSets.main.resources.srcDir 'src/generated/resources'
repositories {
maven {
name = "Shedaniel"
url "https://maven.shedaniel.me/"
url 'https://maven.blamejared.com'
}
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' } }
testCompileOnly(compileOnly(annotationProcessor("io.github.llamalad7:mixinextras-common:${mixinextras_version}")))
implementation(jarJar("io.github.llamalad7:mixinextras-forge:${mixinextras_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.2:16.1.9")
//minecraftLibrary("com.github.LlamaLad7:MixinExtras:${mixinextras_version}")
//jarJar(group: 'com.github.LlamaLad7', name: 'MixinExtras', version: "[${mixinextras_version},)")
//annotationProcessor("com.github.LlamaLad7:MixinExtras:${mixinextras_version}")
implementation(annotationProcessor("com.github.llamalad7.mixinextras:mixinextras-common:${mixinextras_version}"))
implementation(jarJar("com.github.llamalad7.mixinextras:mixinextras-forge:${mixinextras_version}")) {
jarJar.ranged(it, "[${mixinextras_version},)")
}
//implementation fg.deobf("net.darkhax.gamestages:GameStages-Forge-1.19.2:11.0.2")
compileOnly(fg.deobf("me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}"))
annotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor'
fileTree("libs").matching {
include "*.jar"
include "*.jar"
}.each {
String filename = it.getName();
filename = filename.substring(0, filename.length() - 4);
int lastDash = filename.lastIndexOf("-");
filename = filename.substring(0, lastDash) + ":" + filename.substring(lastDash+1, filename.length());
implementation fg.deobf("blank:${filename}")
String filename = it.getName();
filename = filename.substring(0, filename.length() - 4);
int lastDash = filename.lastIndexOf("-");
filename = filename.substring(0, lastDash) + ":" + filename.substring(lastDash+1, filename.length());
implementation fg.deobf("blank:${filename}")
}
}
reobf {
jarJar {}
}
tasks.withType(JavaCompile) {
source(project(":Common").sourceSets.main.allSource)
}
processResources {
from project(":Common").sourceSets.main.resources
filesMatching('*.mixins.json') {
expand "refmap_target": "${mod_id}."
}
}
jar.finalizedBy('reobfJar')
publishing {
publications {
mavenJava(MavenPublication) {
fg.component(it)
groupId project.group
artifactId project.archivesBaseName
version project.version
artifact jar
}
}
repositories {
maven {
url "file://" + System.getenv("local_maven")
}
}
}
sourceSets.each {
def dir = layout.buildDirectory.dir("sourcesSets/$it.name")
it.output.resourcesDir = dir
it.java.destinationDirectory = dir
}

View File

@ -1,36 +1,14 @@
/*
* 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;
import net.minecraft.resources.Identifier;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.fml.InterModComms;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.network.ChannelBuilder;
import net.minecraftforge.network.SimpleChannel;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.simple.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)
@ -38,7 +16,7 @@ public class CarryOnForge {
public static SimpleChannel network;
public CarryOnForge(FMLJavaModLoadingContext context) {
public CarryOnForge() {
// This method is invoked by the Forge mod loader when it is ready
// to load your mod. You can access Forge and Common code in this
@ -46,23 +24,17 @@ public class CarryOnForge {
// Use Forge to bootstrap the Common mod.
CarryOnCommon.registerConfig();
ConfigLoaderImpl.initialize(context);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
ConfigLoaderImpl.initialize();
}
@SubscribeEvent
public static void setup(final FMLCommonSetupEvent event)
private void setup(final FMLCommonSetupEvent event)
{
network = ChannelBuilder.named(Identifier.fromNamespaceAndPath(Constants.MOD_ID, "carryonpackets")).simpleChannel();
network = NetworkRegistry.newSimpleChannel(new ResourceLocation(Constants.MOD_ID, "carryonpackets"), () -> "1.0", "1.0"::equals, "1.0"::equals);
CarryOnCommon.registerServerPackets();
CarryOnCommon.registerClientPackets();
Services.PLATFORM.registerClientboundPacket(
ClientboundSyncCarryDataPacket.TYPE,
ClientboundSyncCarryDataPacket.class,
ClientboundSyncCarryDataPacket.CODEC,
ClientboundSyncCarryDataPacket::handle
);
}
}

View File

@ -1,23 +0,0 @@
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

@ -1,38 +0,0 @@
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

@ -1,13 +0,0 @@
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,54 +1,12 @@
/*
* 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.compat;
import net.darkhax.gamestages.GameStageHelper;
import net.minecraft.world.entity.player.Player;
import tschipp.carryon.Constants;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class GamestageCompat
{
private static Method hasStage;
static {
try {
Class<?> gamestageHelper = Class.forName("net.darkhax.gamestages.GameStageHelper");
hasStage = gamestageHelper.getMethod("hasStage", Player.class, String.class);
} catch (Exception e) {
Constants.LOG.info("Gamestages not found. Disabling.");
}
}
public static boolean hasStage(Player player, String stage)
{
if(hasStage == null)
return true;
try {
return (boolean) hasStage.invoke(null, player, stage);
} catch (IllegalAccessException | InvocationTargetException e) {
}
return true;
return GameStageHelper.hasStage(player, stage);
}
}

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