Added networking, Scripting
This commit is contained in:
parent
cf6a14f5d9
commit
375eb8dcc3
|
|
@ -4,7 +4,7 @@ plugins {
|
|||
id 'maven-publish'
|
||||
}
|
||||
|
||||
archivesBaseName = "${mod_name}-common-${minecraft_version}"
|
||||
archivesBaseName = "${mod_id}-common-${minecraft_version}"
|
||||
|
||||
minecraft {
|
||||
version(minecraft_version)
|
||||
|
|
|
|||
58
Common/src/main/java/tschipp/carryon/CarryOnCommon.java
Normal file
58
Common/src/main/java/tschipp/carryon/CarryOnCommon.java
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package tschipp.carryon;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import tschipp.carryon.common.command.CommandCarryOn;
|
||||
import tschipp.carryon.config.ConfigLoader;
|
||||
import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket;
|
||||
import tschipp.carryon.networking.clientbound.ClientboundSyncScriptsPacket;
|
||||
import tschipp.carryon.networking.serverbound.ServerboundCarryKeyPressedPacket;
|
||||
import tschipp.carryon.platform.Services;
|
||||
|
||||
public class CarryOnCommon
|
||||
{
|
||||
public static void registerServerPackets()
|
||||
{
|
||||
Services.PLATFORM.registerServerboundPacket(
|
||||
Constants.PACKET_ID_KEY_PRESSED,
|
||||
0,
|
||||
ServerboundCarryKeyPressedPacket.class,
|
||||
ServerboundCarryKeyPressedPacket::toBytes,
|
||||
ServerboundCarryKeyPressedPacket::new,
|
||||
ServerboundCarryKeyPressedPacket::handle
|
||||
);
|
||||
}
|
||||
|
||||
public static void registerClientPackets()
|
||||
{
|
||||
Services.PLATFORM.registerClientboundPacket(
|
||||
Constants.PACKET_ID_START_RIDING,
|
||||
1,
|
||||
ClientboundStartRidingPacket.class,
|
||||
ClientboundStartRidingPacket::toBytes,
|
||||
ClientboundStartRidingPacket::new,
|
||||
ClientboundStartRidingPacket::handle
|
||||
);
|
||||
|
||||
Services.PLATFORM.registerClientboundPacket(
|
||||
Constants.PACKET_ID_SYNC_SCRIPTS,
|
||||
2,
|
||||
ClientboundSyncScriptsPacket.class,
|
||||
ClientboundSyncScriptsPacket::toBytes,
|
||||
ClientboundSyncScriptsPacket::new,
|
||||
ClientboundSyncScriptsPacket::handle
|
||||
);
|
||||
}
|
||||
|
||||
public static void registerConfig()
|
||||
{
|
||||
ConfigLoader.registerConfig(Constants.COMMON_CONFIG);
|
||||
ConfigLoader.registerConfig(Constants.CLIENT_CONFIG);
|
||||
}
|
||||
|
||||
public static void registerCommands(CommandDispatcher<CommandSourceStack> dispatcher)
|
||||
{
|
||||
CommandCarryOn.register(dispatcher);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package tschipp.carryon;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import tschipp.carryon.client.keybinds.CarryOnKeybinds;
|
||||
import tschipp.carryon.common.carry.CarryOnData;
|
||||
import tschipp.carryon.common.carry.CarryOnDataManager;
|
||||
|
||||
public class CarryOnCommonClient
|
||||
{
|
||||
public static void checkForKeybinds()
|
||||
{
|
||||
Player player = Minecraft.getInstance().player;
|
||||
if(player != null) {
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if (CarryOnKeybinds.carryKey.isDown() && !carry.isKeyPressed()) {
|
||||
CarryOnKeybinds.onCarryKey(true);
|
||||
carry.setKeyPressed(true);
|
||||
CarryOnDataManager.setCarryData(player, carry);
|
||||
} else if (!CarryOnKeybinds.carryKey.isDown() && carry.isKeyPressed()) {
|
||||
CarryOnKeybinds.onCarryKey(false);
|
||||
carry.setKeyPressed(false);
|
||||
CarryOnDataManager.setCarryData(player, carry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package tschipp.carryon;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tschipp.carryon.common.config.CarryConfig;
|
||||
import tschipp.carryon.config.ConfigLoader;
|
||||
|
||||
public class Constants {
|
||||
|
||||
|
|
@ -14,8 +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();
|
||||
|
||||
static {
|
||||
ConfigLoader.registerConfig(COMMON_CONFIG);
|
||||
ConfigLoader.registerConfig(CLIENT_CONFIG);
|
||||
}
|
||||
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");
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package tschipp.carryon.client;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
||||
public class CarryOnClient
|
||||
{
|
||||
public static Player getPlayer()
|
||||
{
|
||||
return Minecraft.getInstance().player;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package tschipp.carryon.client.keybinds;
|
||||
|
||||
import net.minecraft.client.KeyMapping;
|
||||
import tschipp.carryon.Constants;
|
||||
import tschipp.carryon.networking.serverbound.ServerboundCarryKeyPressedPacket;
|
||||
import tschipp.carryon.platform.Services;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class CarryOnKeybinds
|
||||
{
|
||||
public static KeyMapping carryKey;
|
||||
|
||||
public static void registerKeybinds(Consumer<KeyMapping> registrar)
|
||||
{
|
||||
carryKey = new KeyMapping("key.carry.desc", 340, "key.carry.category");
|
||||
registrar.accept(carryKey);
|
||||
}
|
||||
|
||||
public static void onCarryKey(boolean pressed)
|
||||
{
|
||||
Services.PLATFORM.sendPacketToServer(Constants.PACKET_ID_KEY_PRESSED, new ServerboundCarryKeyPressedPacket(pressed));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,26 +2,28 @@ package tschipp.carryon.client.render;
|
|||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
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.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.MultiBufferSource.BufferSource;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.HumanoidArm;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
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 java.util.Optional;
|
||||
|
||||
|
|
@ -32,9 +34,19 @@ public class CarriedObjectRender
|
|||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if(carry.isCarrying(CarryType.BLOCK))
|
||||
drawFirstPersonBlock(player, buffer, matrix, light, carry.getBlock());
|
||||
drawFirstPersonBlock(player, buffer, matrix, light, CarryRenderHelper.getRenderState(player));
|
||||
else if (carry.isCarrying(CarryType.ENTITY))
|
||||
drawFirstPersonEntity(player, buffer, matrix, light, carry.getEntity(player.level), partialTicks);
|
||||
drawFirstPersonEntity(player, buffer, matrix, light, partialTicks);
|
||||
|
||||
if(carry.getActiveScript().isPresent())
|
||||
{
|
||||
ScriptRender render = carry.getActiveScript().get().scriptRender();
|
||||
if(!render.renderLeftArm() && player.getMainArm() == HumanoidArm.LEFT)
|
||||
return false;
|
||||
|
||||
if(!render.renderRightArm() && player.getMainArm() == HumanoidArm.RIGHT)
|
||||
return false;
|
||||
}
|
||||
|
||||
return carry.isCarrying();
|
||||
}
|
||||
|
|
@ -46,44 +58,34 @@ public class CarriedObjectRender
|
|||
matrix.translate(0, -0.5, -1);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.disableCull();
|
||||
int perspective = CarryRenderHelper.getPerspective();
|
||||
|
||||
if (Constants.CLIENT_CONFIG.facePlayer && isChest(state.getBlock())) {
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
//
|
||||
// CarryOnOverride carryOverride = ScriptChecker.getOverride(player);
|
||||
// if (carryOverride != null) {
|
||||
// CarryRenderHelper.performOverrideTransformation(matrix, carryOverride);
|
||||
//
|
||||
// if (!carryOverride.getRenderNameBlock().isEmpty()) {
|
||||
// Block b = StringParser.getBlock(carryOverride.getRenderNameBlock());
|
||||
// if (b != null) {
|
||||
// ItemStack s = new ItemStack(b, 1);
|
||||
// s.setTag(carryOverride.getRenderNBT());
|
||||
// model = Minecraft.getInstance().getItemRenderer().getModel(s, level, player, 0);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if(carry.getActiveScript().isPresent())
|
||||
CarryRenderHelper.performScriptTransformation(matrix, carry.getActiveScript().get());
|
||||
|
||||
RenderSystem.setShaderTexture(0, InventoryMenu.BLOCK_ATLAS);
|
||||
|
||||
ItemStack stack = new ItemStack(state.getBlock().asItem());
|
||||
//TODO: Model overrides
|
||||
BakedModel model = Minecraft.getInstance().getItemRenderer().getModel(stack, player.level, player, 0);
|
||||
CarryRenderHelper.renderItem(state, null, stack, matrix, buffer, light, model);
|
||||
BakedModel model = CarryRenderHelper.getRenderBlock(player);
|
||||
CarryRenderHelper.renderBakedModel(stack, matrix, buffer, light, model);
|
||||
|
||||
RenderSystem.enableCull();
|
||||
RenderSystem.disableBlend();
|
||||
matrix.popPose();
|
||||
}
|
||||
|
||||
private static void drawFirstPersonEntity(Player player, MultiBufferSource buffer, PoseStack matrix, int light, Entity entity, float partialTicks) {
|
||||
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)
|
||||
{
|
||||
|
|
@ -102,58 +104,121 @@ public class CarriedObjectRender
|
|||
matrix.mulPose(Vector3f.YP.rotationDegrees(180));
|
||||
matrix.translate(0.0, -height - .1, width + 0.1);
|
||||
|
||||
// RenderSystem.enableAlphaTest();
|
||||
manager.setRenderShadow(false);
|
||||
|
||||
// Lighting.en
|
||||
manager.setRenderShadow(false);
|
||||
|
||||
//TODO: Scripts
|
||||
/*
|
||||
CarryOnOverride carryOverride = ScriptChecker.getOverride(player);
|
||||
if (carryOverride != null)
|
||||
{
|
||||
CarryRenderHelper.performOverrideTransformation(matrix, carryOverride);
|
||||
|
||||
String entityname = carryOverride.getRenderNameEntity();
|
||||
if (entityname != null)
|
||||
{
|
||||
Entity newEntity = null;
|
||||
|
||||
Optional<EntityType<?>> type = EntityType.byString(entityname);
|
||||
if (type.isPresent())
|
||||
newEntity = type.get().create(level);
|
||||
|
||||
if (newEntity != null)
|
||||
{
|
||||
CompoundTag nbttag = carryOverride.getRenderNBT();
|
||||
if (nbttag != null)
|
||||
newEntity.deserializeNBT(nbttag);
|
||||
entity = newEntity;
|
||||
entity.setPos(playerpos.x, playerpos.y, playerpos.z);
|
||||
entity.xRotO = 0.0f;
|
||||
entity.yRotO = 0.0f;
|
||||
entity.setYHeadRot(0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
if (entity instanceof LivingEntity)
|
||||
((LivingEntity) entity).hurtTime = 0;
|
||||
|
||||
manager.render(entity, 0, 0, 0, 0f, 0, matrix, buffer, light);
|
||||
manager.setRenderShadow(true);
|
||||
Optional<CarryOnScript> res = carry.getActiveScript();
|
||||
if(res.isPresent())
|
||||
{
|
||||
CarryOnScript script = res.get();
|
||||
CarryRenderHelper.performScriptTransformation(matrix, script);
|
||||
}
|
||||
|
||||
// RenderSystem.disableAlphaTest();
|
||||
matrix.popPose();
|
||||
if (entity instanceof LivingEntity)
|
||||
((LivingEntity) entity).hurtTime = 0;
|
||||
|
||||
manager.render(entity, 0, 0, 0, 0f, 0, matrix, buffer, light);
|
||||
manager.setRenderShadow(true);
|
||||
}
|
||||
|
||||
// RenderSystem.disableAlphaTest();
|
||||
matrix.popPose();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
BufferSource buffer = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder());
|
||||
int light = 0;
|
||||
int perspective = CarryRenderHelper.getPerspective();
|
||||
EntityRenderDispatcher manager = mc.getEntityRenderDispatcher();
|
||||
|
||||
private static boolean isChest(Block block)
|
||||
{
|
||||
return block == Blocks.CHEST || block == Blocks.ENDER_CHEST || block == Blocks.TRAPPED_CHEST;
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.disableCull();
|
||||
RenderSystem.disableDepthTest();
|
||||
|
||||
for (Player player : level.players())
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
|
||||
if (perspective == 0 && player == mc.player)
|
||||
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);
|
||||
buffer.endBatch();
|
||||
|
||||
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);
|
||||
buffer.endBatch();
|
||||
|
||||
matrix.popPose();
|
||||
manager.setRenderShadow(true);
|
||||
matrix.popPose();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.enableCull();
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,15 +9,26 @@ 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.nbt.CompoundTag;
|
||||
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.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.RenderShape;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
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;
|
||||
|
||||
public class CarryRenderHelper
|
||||
{
|
||||
|
|
@ -28,8 +39,11 @@ public class CarryRenderHelper
|
|||
|
||||
public static float getExactBodyRotationDegrees(LivingEntity entity, float partialticks)
|
||||
{
|
||||
if (entity.getVehicle() != null && entity.getVehicle() instanceof LivingEntity)
|
||||
return -(entity.yHeadRotO + (entity.yHeadRot - entity.yHeadRotO) * partialticks);
|
||||
if (entity.getVehicle() != null && entity.getVehicle() instanceof LivingEntity vehicle)
|
||||
if(vehicle instanceof Player player)
|
||||
return -(player.yBodyRotO + (player.yBodyRot - player.yBodyRotO) * partialticks);
|
||||
else
|
||||
return -(entity.yHeadRotO + (entity.yHeadRot - entity.yHeadRotO) * partialticks);
|
||||
else
|
||||
return -(entity.yBodyRotO + (entity.yBodyRot - entity.yBodyRotO) * partialticks);
|
||||
}
|
||||
|
|
@ -99,14 +113,14 @@ public class CarryRenderHelper
|
|||
matrix.mulPose(Vector3f.XN.rotationDegrees(f2 * (-90.0F - player.xRotO)));
|
||||
}
|
||||
|
||||
Vec3 Vector3d = player.getViewVector(partialticks);
|
||||
Vec3 Vector3d1 = player.getDeltaMovement();
|
||||
double d0 = Vector3d1.horizontalDistanceSqr();
|
||||
double d1 = Vector3d1.horizontalDistanceSqr();
|
||||
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 = (Vector3d1.x * Vector3d.x + Vector3d1.z * Vector3d.z) / (Math.sqrt(d0) * Math.sqrt(d1));
|
||||
double d3 = Vector3d1.x * Vector3d.z - Vector3d1.z * Vector3d.x;
|
||||
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))));
|
||||
}
|
||||
|
|
@ -119,43 +133,182 @@ public class CarryRenderHelper
|
|||
matrix.translate(0, 1.6, 0.65);
|
||||
}
|
||||
|
||||
public static void applyBlockTransformations(Player player, float partialticks, PoseStack matrix, Block block)
|
||||
{
|
||||
int perspective = CarryRenderHelper.getPerspective();
|
||||
|
||||
//TODO: Scripting
|
||||
// public static void performOverrideTransformation(PoseStack matrix, CarryOnOverride override)
|
||||
// {
|
||||
// int perspective = getPerspective();
|
||||
//
|
||||
// float[] translation = ScriptParseHelper.getXYZArray(override.getRenderTranslation());
|
||||
// float[] rotation = ScriptParseHelper.getXYZArray(override.getRenderRotation());
|
||||
// float[] scaled = ScriptParseHelper.getScaled(override.getRenderScaled());
|
||||
//
|
||||
// Quaternion rot = Vector3f.XP.rotationDegrees(rotation[0]);
|
||||
// rot.mul(Vector3f.YP.rotationDegrees(rotation[1]));
|
||||
// rot.mul(Vector3f.ZP.rotationDegrees(rotation[2]));
|
||||
// matrix.mulPose(rot);
|
||||
//
|
||||
// matrix.translate(translation[0], translation[1], perspective == 1 && override.isBlock() ? -translation[2] : translation[2]);
|
||||
//
|
||||
// matrix.scale(scaled[0], scaled[1], scaled[2]);
|
||||
// }
|
||||
applyGeneralTransformations(player, partialticks, matrix);
|
||||
|
||||
public static void renderItem(BlockState state, CompoundTag tag, ItemStack stack, PoseStack matrix, MultiBufferSource buffer, int light, BakedModel model)
|
||||
if (!Constants.CLIENT_CONFIG.facePlayer && isChest(block))
|
||||
{
|
||||
//if ((ModList.get().isLoaded("realrender") || ModList.get().isLoaded("rfpr")) && perspective == 0)
|
||||
// matrix.translate(0, 0, -0.4);
|
||||
matrix.mulPose(Vector3f.YP.rotationDegrees(180));
|
||||
}
|
||||
//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 applyEntityTransformations(Player player, float partialticks, PoseStack matrix, Entity entity)
|
||||
{
|
||||
int perspective = CarryRenderHelper.getPerspective();
|
||||
Pose pose = player.getPose();
|
||||
|
||||
applyGeneralTransformations(player, partialticks, matrix);
|
||||
|
||||
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 = height * width;
|
||||
entity.yo = 0.0f;
|
||||
entity.yRotO = 0.0f;
|
||||
entity.setYHeadRot(0.0f);
|
||||
entity.xo = 0.0f;
|
||||
entity.xRotO = 0.0f;
|
||||
|
||||
if (perspective == 2)
|
||||
matrix.mulPose(Vector3f.YP.rotationDegrees(180));
|
||||
|
||||
matrix.scale((10 - multiplier) * 0.08f, (10 - multiplier) * 0.08f, (10 - multiplier) * 0.08f);
|
||||
matrix.translate(0.0, height / 2 + -(height / 2) + 1, width - 0.1 < 0.7 ? width - 0.1 + (0.7 - (width - 0.1)) : width - 0.1);
|
||||
|
||||
if (pose == Pose.SWIMMING || pose == Pose.FALL_FLYING)
|
||||
{
|
||||
matrix.mulPose(Vector3f.XN.rotationDegrees(90));
|
||||
matrix.translate(0, -0.2 * height, 0);
|
||||
|
||||
if (pose == Pose.FALL_FLYING)
|
||||
matrix.translate(0, 0, 0.2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void performScriptTransformation(PoseStack matrix, CarryOnScript script)
|
||||
{
|
||||
int perspective = getPerspective();
|
||||
|
||||
ScriptRender render = script.scriptRender();
|
||||
|
||||
Vec3 translation = render.renderTranslation().getVec();
|
||||
Vec3 rotation = render.renderRotation().getVec();
|
||||
Vec3 scale = render.renderscale().getVec(1);
|
||||
|
||||
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);
|
||||
|
||||
matrix.scale((float) scale.x, (float) scale.y, (float) scale.z);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void renderBakedModel(ItemStack stack, PoseStack matrix, MultiBufferSource buffer, int light, BakedModel model)
|
||||
{
|
||||
ItemRenderer renderer = Minecraft.getInstance().getItemRenderer();
|
||||
// if (ModelOverridesHandler.hasCustomOverrideModel(state, tag))
|
||||
// {
|
||||
// Object override = ModelOverridesHandler.getOverrideObject(state, tag);
|
||||
|
||||
// if (override instanceof ItemStack)
|
||||
// {
|
||||
// renderer.render((ItemStack) override, TransformType.NONE, false, matrix, buffer, light, OverlayTexture.NO_OVERLAY, model);
|
||||
// return;
|
||||
//// }
|
||||
// }
|
||||
|
||||
renderer.render(stack, TransformType.NONE, false, matrix, buffer, light, OverlayTexture.NO_OVERLAY, model);
|
||||
}
|
||||
|
||||
public static BlockState getRenderState(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 = Registry.BLOCK.get(render.renderNameBlock().get()).defaultBlockState();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public static BakedModel getRenderBlock(Player player)
|
||||
{
|
||||
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 = Minecraft.getInstance().getItemRenderer().getModel(stack, player.level, player, 0);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
public static Entity getRenderEntity(Player player)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
Entity entity = carry.getEntity(player.level);
|
||||
|
||||
if(carry.getActiveScript().isPresent())
|
||||
{
|
||||
CarryOnScript script = carry.getActiveScript().get();
|
||||
ScriptRender render = script.scriptRender();
|
||||
if(render.renderNameEntity().isPresent())
|
||||
entity = Registry.ENTITY_TYPE.get(render.renderNameEntity().get()).create(player.level);
|
||||
|
||||
if(render.renderNBT().isPresent())
|
||||
entity.load(render.renderNBT().get());
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
public static float getRenderWidth(Player player)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if(carry.isCarrying(CarryType.BLOCK))
|
||||
{
|
||||
VoxelShape shape = getRenderState(player).getShape(player.level, player.blockPosition());
|
||||
if(shape == null)
|
||||
return 1f;
|
||||
float width = (float)Math.abs(shape.bounds().maxX - shape.bounds().minX);
|
||||
return width;
|
||||
}
|
||||
else if(carry.isCarrying(CarryType.ENTITY))
|
||||
{
|
||||
Entity entity = getRenderEntity(player);
|
||||
return entity.getBbWidth();
|
||||
}
|
||||
else
|
||||
return 1f;
|
||||
}
|
||||
|
||||
public static float getRenderHeight(Player player)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if(carry.isCarrying(CarryType.BLOCK))
|
||||
{
|
||||
VoxelShape shape = getRenderState(player).getShape(player.level, player.blockPosition());
|
||||
if(shape == null)
|
||||
return 1f;
|
||||
float height = (float)Math.abs(shape.bounds().maxY - shape.bounds().minY);
|
||||
return height;
|
||||
}
|
||||
else if(carry.isCarrying(CarryType.ENTITY))
|
||||
{
|
||||
Entity entity = getRenderEntity(player);
|
||||
return entity.getBbHeight();
|
||||
}
|
||||
else
|
||||
return 1f;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
public static int getPerspective()
|
||||
{
|
||||
|
|
@ -176,4 +329,10 @@ public class CarryRenderHelper
|
|||
|
||||
return player.isShiftKeyDown() || player.isCrouching();
|
||||
}
|
||||
|
||||
public static boolean isChest(Block block)
|
||||
{
|
||||
return block == Blocks.CHEST || block == Blocks.ENDER_CHEST || block == Blocks.TRAPPED_CHEST;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,28 @@
|
|||
package tschipp.carryon.common.carry;
|
||||
|
||||
import com.mojang.serialization.DataResult;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
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 tschipp.carryon.common.scripting.CarryOnScript;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CarryOnData {
|
||||
|
||||
private CarryType type;
|
||||
private CompoundTag nbt;
|
||||
private boolean keyPressed = false;
|
||||
private CarryOnScript activeScript;
|
||||
|
||||
public CarryOnData(CompoundTag data)
|
||||
{
|
||||
|
|
@ -25,11 +32,27 @@ public class CarryOnData {
|
|||
this.type = CarryType.INVALID;
|
||||
|
||||
this.nbt = data;
|
||||
|
||||
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(false, (s) -> {throw new RuntimeException("Failed to decode activeScript during CarryOnData serialization: " + s);});
|
||||
}
|
||||
}
|
||||
|
||||
public CompoundTag getNbt()
|
||||
{
|
||||
nbt.putString("type", type.toString());
|
||||
nbt.putBoolean("keyPressed", keyPressed);
|
||||
if(activeScript != null)
|
||||
{
|
||||
DataResult<Tag> res = CarryOnScript.CODEC.encodeStart(NbtOps.INSTANCE, activeScript);
|
||||
Tag tag = res.getOrThrow(false, (s) -> {throw new RuntimeException("Failed to encode activeScript during CarryOnData serialization: " + s);});
|
||||
nbt.put("activeScript", tag);
|
||||
}
|
||||
return nbt;
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +106,23 @@ public class CarryOnData {
|
|||
if(this.type != CarryType.ENTITY)
|
||||
throw new IllegalStateException("Called getEntity on data that contained " + this.type);
|
||||
|
||||
return EntityType.create(nbt.getCompound("entity"), level).orElseThrow();
|
||||
return EntityType.create(nbt.getCompound("entity"), level).orElseThrow(() -> new IllegalStateException("Called EntityType#create even though no entity data was present. Data: " + nbt.toString()));
|
||||
}
|
||||
|
||||
public Optional<CarryOnScript> getActiveScript()
|
||||
{
|
||||
if(activeScript == null)
|
||||
return Optional.empty();
|
||||
return Optional.of(activeScript);
|
||||
}
|
||||
|
||||
public void setActiveScript(CarryOnScript script)
|
||||
{
|
||||
this.activeScript = script;
|
||||
}
|
||||
|
||||
public void setCarryingPlayer() {
|
||||
this.type = CarryType.PLAYER;
|
||||
}
|
||||
|
||||
public boolean isCarrying()
|
||||
|
|
@ -96,10 +135,18 @@ public class CarryOnData {
|
|||
return this.type == type;
|
||||
}
|
||||
|
||||
public boolean isKeyPressed() {return this.keyPressed;}
|
||||
|
||||
public void setKeyPressed(boolean val) {
|
||||
this.keyPressed = val;
|
||||
this.nbt.putBoolean("keyPressed", val);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
this.type = CarryType.INVALID;
|
||||
this.nbt = new CompoundTag();
|
||||
this.activeScript = null;
|
||||
}
|
||||
|
||||
public int getTick()
|
||||
|
|
@ -112,6 +159,7 @@ public class CarryOnData {
|
|||
public enum CarryType {
|
||||
BLOCK,
|
||||
ENTITY,
|
||||
PLAYER,
|
||||
INVALID
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ 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 org.apache.commons.lang3.ObjectUtils;
|
||||
|
||||
public class CarryOnDataManager {
|
||||
|
||||
|
|
@ -22,10 +21,7 @@ public class CarryOnDataManager {
|
|||
{
|
||||
CompoundTag nbt = data.getNbt();
|
||||
nbt.putInt("tick", player.tickCount);
|
||||
System.out.println(player.getEntityData().isDirty());
|
||||
System.out.println("Old: " + player.getEntityData().get(CARRY_DATA_KEY) + ", New: " + nbt + ", NotEqual: " + ObjectUtils.notEqual(player.getEntityData().get(CARRY_DATA_KEY), nbt));
|
||||
player.getEntityData().set(CARRY_DATA_KEY, nbt);
|
||||
System.out.println(player.getEntityData().isDirty());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,4 +191,34 @@ public class ListHandler {
|
|||
return containsAll;
|
||||
}
|
||||
|
||||
public static void addForbiddenTiles(String toAdd)
|
||||
{
|
||||
FORBIDDEN_TILES.add(toAdd);
|
||||
}
|
||||
|
||||
public static void addForbiddenEntities(String toAdd)
|
||||
{
|
||||
FORBIDDEN_ENTITIES.add(toAdd);
|
||||
}
|
||||
|
||||
public static void addForbiddenStacking(String toAdd)
|
||||
{
|
||||
FORBIDDEN_STACKING.add(toAdd);
|
||||
}
|
||||
|
||||
public static void addAllowedTiles(String toAdd)
|
||||
{
|
||||
ALLOWED_TILES.add(toAdd);
|
||||
}
|
||||
|
||||
public static void addAllowedEntities(String toAdd)
|
||||
{
|
||||
ALLOWED_ENTITIES.add(toAdd);
|
||||
}
|
||||
|
||||
public static void addAllowedStacking(String toAdd)
|
||||
{
|
||||
ALLOWED_ENTITIES.add(toAdd);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,17 +19,18 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import tschipp.carryon.Constants;
|
||||
import tschipp.carryon.common.scripting.CarryOnScript;
|
||||
import tschipp.carryon.common.scripting.ScriptManager;
|
||||
import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket;
|
||||
import tschipp.carryon.platform.Services;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PickupHandler {
|
||||
|
||||
public static boolean canCarryGeneral(ServerPlayer player, Vec3 pos)
|
||||
{
|
||||
//TODO: Check carry key
|
||||
if(!player.isShiftKeyDown())
|
||||
return false;
|
||||
|
||||
if(!player.getMainHandItem().isEmpty() || !player.getOffhandItem().isEmpty())
|
||||
return false;
|
||||
|
||||
|
|
@ -40,6 +41,9 @@ public class PickupHandler {
|
|||
if(carry.isCarrying())
|
||||
return false;
|
||||
|
||||
if(!carry.isKeyPressed())
|
||||
return false;
|
||||
|
||||
//Needed so that we don't pick up and place in the same tick
|
||||
if(player.tickCount == carry.getTick())
|
||||
return false;
|
||||
|
|
@ -61,6 +65,9 @@ public class PickupHandler {
|
|||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||
BlockState state = level.getBlockState(pos);
|
||||
CompoundTag nbt = null;
|
||||
if(blockEntity != null)
|
||||
nbt = blockEntity.saveWithId();
|
||||
|
||||
if(!ListHandler.isPermitted(state.getBlock()))
|
||||
return false;
|
||||
|
|
@ -74,17 +81,28 @@ public class PickupHandler {
|
|||
//Check if TE is locked
|
||||
if(blockEntity != null)
|
||||
{
|
||||
CompoundTag nbt = blockEntity.saveWithId();
|
||||
if(nbt.contains("Lock") && !nbt.getString("Lock").equals(""))
|
||||
return false;
|
||||
}
|
||||
|
||||
//TODO: Script conditions
|
||||
|
||||
//TODO: Gamestages conditions check
|
||||
|
||||
//TODO: Protections
|
||||
|
||||
Optional<CarryOnScript> result = ScriptManager.inspectBlock(state, level, pos, nbt);
|
||||
if(result.isPresent())
|
||||
{
|
||||
CarryOnScript script = result.get();
|
||||
if(!script.fulfillsConditions(player))
|
||||
return false;
|
||||
|
||||
carry.setActiveScript(script);
|
||||
|
||||
String cmd = script.scriptEffects().commandInit();
|
||||
if(!cmd.isEmpty())
|
||||
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd);
|
||||
}
|
||||
|
||||
carry.setBlock(state, blockEntity);
|
||||
|
||||
level.removeBlockEntity(pos);
|
||||
|
|
@ -106,9 +124,6 @@ public class PickupHandler {
|
|||
if (entity.invulnerableTime != 0)
|
||||
return false;
|
||||
|
||||
if (entity instanceof Player)
|
||||
return false;
|
||||
|
||||
if (entity instanceof TamableAnimal tame)
|
||||
{
|
||||
UUID owner = tame.getOwnerUUID();
|
||||
|
|
@ -130,21 +145,65 @@ public class PickupHandler {
|
|||
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())
|
||||
if(Constants.COMMON_CONFIG.settings.maxEntityHeight < entity.getBbHeight() || Constants.COMMON_CONFIG.settings.maxEntityWidth < entity.getBbWidth())
|
||||
return false;
|
||||
}
|
||||
|
||||
//TODO: Script conditions
|
||||
|
||||
//TODO: Gamestages conditions check
|
||||
|
||||
//TODO: Protections
|
||||
|
||||
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
|
||||
Optional<CarryOnScript> result = ScriptManager.inspectEntity(entity);
|
||||
if(result.isPresent())
|
||||
{
|
||||
CarryOnScript script = result.get();
|
||||
if(!script.fulfillsConditions(player))
|
||||
return false;
|
||||
|
||||
carry.setActiveScript(script);
|
||||
}
|
||||
|
||||
if (entity instanceof Player otherPlayer) {
|
||||
if (!Constants.COMMON_CONFIG.settings.pickupPlayers)
|
||||
return false;
|
||||
|
||||
if (!player.isCreative() && otherPlayer.isCreative())
|
||||
return false;
|
||||
|
||||
otherPlayer.ejectPassengers();
|
||||
otherPlayer.stopRiding();
|
||||
|
||||
if (result.isPresent()) {
|
||||
String cmd = result.get().scriptEffects().commandInit();
|
||||
if (!cmd.isEmpty())
|
||||
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd);
|
||||
}
|
||||
|
||||
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, SoundSource.AMBIENT, 1.0f, 0.5f);
|
||||
CarryOnDataManager.setCarryData(player, carry);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
entity.ejectPassengers();
|
||||
if (entity instanceof Animal animal)
|
||||
entity.stopRiding();
|
||||
if (entity instanceof Animal animal) {
|
||||
animal.dropLeash(true, true);
|
||||
}
|
||||
|
||||
if(result.isPresent())
|
||||
{
|
||||
String cmd = result.get().scriptEffects().commandInit();
|
||||
if(!cmd.isEmpty())
|
||||
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd);
|
||||
}
|
||||
|
||||
carry.setEntity(entity);
|
||||
entity.remove(RemovalReason.UNLOADED_WITH_PLAYER);
|
||||
|
|
@ -155,4 +214,18 @@ public class PickupHandler {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static void onCarryTick(ServerPlayer player)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if(carry.isCarrying())
|
||||
{
|
||||
if(carry.getActiveScript().isPresent())
|
||||
{
|
||||
String cmd = carry.getActiveScript().get().scriptEffects().commandLoop();
|
||||
if(!cmd.isEmpty())
|
||||
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@ package tschipp.carryon.common.carry;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
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.entity.Entity;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
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.Level;
|
||||
|
|
@ -19,9 +21,12 @@ import net.minecraft.world.level.block.state.properties.Property;
|
|||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import tschipp.carryon.Constants;
|
||||
import tschipp.carryon.common.carry.CarryOnData.CarryType;
|
||||
import tschipp.carryon.common.scripting.CarryOnScript.ScriptEffects;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class PlacementHandler
|
||||
|
|
@ -50,7 +55,10 @@ public class PlacementHandler
|
|||
|
||||
boolean canPlace = state.canSurvive(level, pos) && level.mayInteract(player, pos) && level.getBlockState(pos).canBeReplaced(context) && level.isUnobstructed(state, pos, CollisionContext.of(player));
|
||||
if (!canPlace)
|
||||
{
|
||||
level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.LAVA_POP, SoundSource.PLAYERS, 0.5F, 0.5F);
|
||||
return false;
|
||||
}
|
||||
|
||||
state = getPlacementState(state, player, context, pos);
|
||||
boolean doPlace = placementCallback == null || placementCallback.apply(pos, state);
|
||||
|
|
@ -58,6 +66,14 @@ public class PlacementHandler
|
|||
if (!doPlace)
|
||||
return false;
|
||||
|
||||
if(carry.getActiveScript().isPresent())
|
||||
{
|
||||
ScriptEffects effects = carry.getActiveScript().get().scriptEffects();
|
||||
String cmd = effects.commandPlace();
|
||||
if(!cmd.isEmpty())
|
||||
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd);
|
||||
}
|
||||
|
||||
level.setBlock(pos, state, 3);
|
||||
if (blockEntity != null)
|
||||
level.setBlockEntity(blockEntity);
|
||||
|
|
@ -72,7 +88,6 @@ public class PlacementHandler
|
|||
private static BlockState getPlacementState(BlockState state, ServerPlayer player, BlockPlaceContext context, BlockPos pos)
|
||||
{
|
||||
BlockState placementState = state.getBlock().getStateForPlacement(context);
|
||||
System.out.println(placementState);
|
||||
|
||||
for (var prop : placementState.getProperties()) {
|
||||
if (prop instanceof DirectionProperty) {
|
||||
|
|
@ -88,8 +103,6 @@ public class PlacementHandler
|
|||
}
|
||||
}
|
||||
|
||||
System.out.println(state);
|
||||
|
||||
state = Block.updateFromNeighbourShapes(state, player.level, pos);
|
||||
|
||||
if (placementState.hasProperty(BlockStateProperties.WATERLOGGED))
|
||||
|
|
@ -107,7 +120,8 @@ public class PlacementHandler
|
|||
public static boolean tryPlaceEntity(ServerPlayer player, BlockPos pos, Direction facing, @Nullable BiFunction<Vec3, Entity, Boolean> placementCallback)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if (!carry.isCarrying(CarryType.ENTITY))
|
||||
|
||||
if (!carry.isCarrying(CarryType.ENTITY) && !carry.isCarrying(CarryType.PLAYER))
|
||||
return false;
|
||||
|
||||
if (player.tickCount == carry.getTick())
|
||||
|
|
@ -121,6 +135,18 @@ public class PlacementHandler
|
|||
|
||||
Vec3 placementPos = Vec3.atBottomCenterOf(pos);
|
||||
|
||||
if(carry.isCarrying(CarryType.PLAYER))
|
||||
{
|
||||
Entity otherPlayer = player.getFirstPassenger();
|
||||
player.ejectPassengers();
|
||||
carry.clear();
|
||||
CarryOnDataManager.setCarryData(player, carry);
|
||||
if(otherPlayer == null)
|
||||
return true;
|
||||
otherPlayer.teleportTo(placementPos.x, placementPos.y, placementPos.z);
|
||||
player.swing(InteractionHand.MAIN_HAND, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
Entity entity = carry.getEntity(level);
|
||||
entity.setPos(placementPos);
|
||||
|
|
@ -129,6 +155,14 @@ public class PlacementHandler
|
|||
if (!doPlace)
|
||||
return false;
|
||||
|
||||
if(carry.getActiveScript().isPresent())
|
||||
{
|
||||
ScriptEffects effects = carry.getActiveScript().get().scriptEffects();
|
||||
String cmd = effects.commandPlace();
|
||||
if(!cmd.isEmpty())
|
||||
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd);
|
||||
}
|
||||
|
||||
level.addFreshEntity(entity);
|
||||
if(entity instanceof Mob mob)
|
||||
mob.playAmbientSound();
|
||||
|
|
@ -139,4 +173,115 @@ public class PlacementHandler
|
|||
return true;
|
||||
}
|
||||
|
||||
public static void tryStackEntity(ServerPlayer player, Entity entityClicked)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if(!carry.isCarrying(CarryType.ENTITY) && !carry.isCarrying(CarryType.PLAYER))
|
||||
return;
|
||||
|
||||
Level level = player.level;
|
||||
Entity entityHeld;
|
||||
if(carry.isCarrying(CarryType.ENTITY))
|
||||
entityHeld = carry.getEntity(level);
|
||||
else
|
||||
entityHeld = player.getFirstPassenger();
|
||||
|
||||
|
||||
double sizeHeldEntity = entityHeld.getBbHeight() * entityHeld.getBbWidth();
|
||||
double distance = entityClicked.blockPosition().distSqr(player.blockPosition());
|
||||
Entity lowestEntity = entityClicked.getRootVehicle();
|
||||
int numPassengers = getPassengerCount(lowestEntity);
|
||||
if (numPassengers < Constants.COMMON_CONFIG.settings.maxEntityStackLimit - 1)
|
||||
{
|
||||
Entity topEntity = getTopPassenger(lowestEntity);
|
||||
|
||||
if(topEntity == entityHeld)
|
||||
return;
|
||||
|
||||
if (ListHandler.isStackingPermitted(topEntity))
|
||||
{
|
||||
double sizeEntity = topEntity.getBbHeight() * topEntity.getBbWidth();
|
||||
if (Constants.COMMON_CONFIG.settings.entitySizeMattersStacking && sizeHeldEntity <= sizeEntity || !Constants.COMMON_CONFIG.settings.entitySizeMattersStacking)
|
||||
{
|
||||
if (topEntity instanceof Horse horse)
|
||||
horse.setTamed(true);
|
||||
|
||||
if (distance < 6)
|
||||
{
|
||||
double tempX = entityClicked.getX();
|
||||
double tempY = entityClicked.getY();
|
||||
double tempZ = entityClicked.getZ();
|
||||
if(carry.isCarrying(CarryType.ENTITY)) {
|
||||
entityHeld.setPos(tempX, tempY + 2.6, tempZ);
|
||||
level.addFreshEntity(entityHeld);
|
||||
entityHeld.teleportTo(tempX, tempY, tempZ);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
if(carry.getActiveScript().isPresent())
|
||||
{
|
||||
ScriptEffects effects = carry.getActiveScript().get().scriptEffects();
|
||||
String cmd = effects.commandPlace();
|
||||
if(!cmd.isEmpty())
|
||||
player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd);
|
||||
}
|
||||
|
||||
player.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);
|
||||
}
|
||||
else
|
||||
{
|
||||
level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.LAVA_POP, SoundSource.PLAYERS, 0.5F, 0.5F);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.LAVA_POP, SoundSource.PLAYERS, 0.5F, 0.5F);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getPassengerCount(Entity entity)
|
||||
{
|
||||
int passengers = 0;
|
||||
while (entity.isVehicle())
|
||||
{
|
||||
List<Entity> pass = entity.getPassengers();
|
||||
if (!pass.isEmpty())
|
||||
{
|
||||
entity = pass.get(0);
|
||||
passengers++;
|
||||
}
|
||||
}
|
||||
|
||||
return passengers;
|
||||
}
|
||||
|
||||
private static Entity getTopPassenger(Entity entity)
|
||||
{
|
||||
Entity top = entity;
|
||||
while (entity.isVehicle())
|
||||
{
|
||||
List<Entity> pass = entity.getPassengers();
|
||||
if (!pass.isEmpty())
|
||||
{
|
||||
entity = pass.get(0);
|
||||
top = entity;
|
||||
}
|
||||
}
|
||||
|
||||
return top;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
package tschipp.carryon.common.command;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.commands.arguments.EntityArgument;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import tschipp.carryon.Constants;
|
||||
import tschipp.carryon.common.carry.CarryOnData;
|
||||
import tschipp.carryon.common.carry.CarryOnData.CarryType;
|
||||
import tschipp.carryon.common.carry.CarryOnDataManager;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public class CommandCarryOn
|
||||
{
|
||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
|
||||
{
|
||||
LiteralArgumentBuilder<CommandSourceStack> builder = Commands.literal("carryon")
|
||||
|
||||
.then(Commands.literal("debug").executes(cmd -> handleDebug(cmd.getSource())))
|
||||
|
||||
.then(Commands.literal("clear").executes(cmd -> handleClear(cmd.getSource(), Collections.singleton(cmd.getSource().getPlayerOrException()))))
|
||||
|
||||
.then(Commands.literal("clear").then(Commands.argument("target", EntityArgument.players()).requires(src -> src.hasPermission(2)).executes(cmd -> handleClear(cmd.getSource(), EntityArgument.getPlayers(cmd, "target")))))
|
||||
|
||||
;
|
||||
|
||||
dispatcher.register(builder);
|
||||
|
||||
}
|
||||
|
||||
private static int handleDebug(CommandSourceStack source)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (source.getEntityOrException() != null)
|
||||
{
|
||||
ServerPlayer player = source.getPlayerOrException();
|
||||
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if (carry.isCarrying(CarryType.BLOCK))
|
||||
{
|
||||
log(source,"Block: " + carry.getBlock().getBlock());
|
||||
log(source,"BlockState: " + carry.getBlock());
|
||||
log(source,"NBT: " + carry.getNbt());
|
||||
|
||||
//TODO
|
||||
// if (ModelOverridesHandler.hasCustomOverrideModel(ItemCarryonBlock.getBlockState(main), ItemCarryonBlock.getTileData(main)))
|
||||
// source.sendSuccess(Component.literal("Override Model: " + ModelOverridesHandler.getOverrideObject(ItemCarryonBlock.getBlockState(main), ItemCarryonBlock.getTileData(main))), true);
|
||||
|
||||
// if (CustomPickupOverrideHandler.hasSpecialPickupConditions(ItemCarryonBlock.getBlockState(main)))
|
||||
// source.sendSuccess(Component.literal("Custom Pickup Condition: " + CustomPickupOverrideHandler.getPickupCondition(ItemCarryonBlock.getBlockState(main))), true);
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if (carry.isCarrying(CarryType.ENTITY))
|
||||
{
|
||||
log(source,"Entity: " + carry.getEntity(player.level));
|
||||
log(source,"Entity Name: " + carry.getEntity(player.level).getType());
|
||||
log(source,"NBT: " + carry.getNbt());
|
||||
|
||||
// if (CustomPickupOverrideHandler.hasSpecialPickupConditions(ItemCarryonEntity.getEntity(main, player.level)))
|
||||
// source.sendSuccess(Component.literal("Custom Pickup Condition: " + CustomPickupOverrideHandler.getPickupCondition(ItemCarryonEntity.getEntity(main, player.level))), true);
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if(carry.isCarrying(CarryType.PLAYER))
|
||||
{
|
||||
log(source, "Carrying Player.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int handleClear(CommandSourceStack source, Collection<ServerPlayer> players)
|
||||
{
|
||||
int cleared = 0;
|
||||
for (ServerPlayer player : players)
|
||||
{
|
||||
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
carry.clear();
|
||||
CarryOnDataManager.setCarryData(player, carry);
|
||||
|
||||
cleared++;
|
||||
}
|
||||
|
||||
if (cleared != 1)
|
||||
source.sendSuccess(Component.literal("Cleared " + cleared + " Items!"), true);
|
||||
else
|
||||
source.sendSuccess(Component.literal("Cleared " + cleared + " Item!"), true);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static void log(CommandSourceStack source, String toLog)
|
||||
{
|
||||
source.sendSuccess(Component.literal(toLog), true);
|
||||
Constants.LOG.info(toLog);
|
||||
}
|
||||
}
|
||||
|
|
@ -153,6 +153,12 @@ public class CarryConfig {
|
|||
public String[] placementStateExceptions = {
|
||||
"minecraft:chest[type]"
|
||||
};
|
||||
|
||||
@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(
|
||||
|
|
@ -196,7 +202,7 @@ public class CarryConfig {
|
|||
description = "Blocks that cannot be picked up"
|
||||
)
|
||||
public String[] forbiddenTiles = {
|
||||
"#forge:immovable", "#forge:relocation_not_supported", "minecraft:end_portal",
|
||||
"#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",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,185 @@
|
|||
package tschipp.carryon.common.scripting;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import tschipp.carryon.common.scripting.CarryOnScript.ScriptObject.ScriptObjectBlock;
|
||||
import tschipp.carryon.common.scripting.CarryOnScript.ScriptObject.ScriptObjectEntity;
|
||||
import tschipp.carryon.common.scripting.Matchables.*;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public record CarryOnScript(
|
||||
long priority,
|
||||
ScriptObject scriptObject,
|
||||
ScriptConditions scriptConditions,
|
||||
ScriptRender scriptRender,
|
||||
ScriptEffects scriptEffects)
|
||||
{
|
||||
|
||||
public boolean isValid()
|
||||
{
|
||||
return (isBlock() ^ isEntity()) && (scriptConditions != ScriptConditions.EMPTY || scriptRender != ScriptRender.EMPTY || scriptEffects != ScriptEffects.EMPTY);
|
||||
}
|
||||
|
||||
public boolean isBlock()
|
||||
{
|
||||
return scriptObject.block() != ScriptObjectBlock.EMPTY;
|
||||
}
|
||||
|
||||
public boolean isEntity()
|
||||
{
|
||||
return scriptObject.entity() != ScriptObjectEntity.EMPTY;
|
||||
}
|
||||
|
||||
public static final Codec<CarryOnScript> CODEC = RecordCodecBuilder.create(instance -> // Given an instance
|
||||
instance.group(
|
||||
Codec.LONG.optionalFieldOf("priority", 0L).forGetter(CarryOnScript::priority),
|
||||
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)
|
||||
).apply(instance, CarryOnScript::new)
|
||||
);
|
||||
|
||||
public boolean fulfillsConditions(ServerPlayer player)
|
||||
{
|
||||
ScriptConditions cond = this.scriptConditions();
|
||||
|
||||
boolean achievement = cond.conditionAchievement.matches(player);
|
||||
boolean gamemode = cond.conditionGamemode.matches(player.gameMode.getGameModeForPlayer().getId());
|
||||
boolean gamestage = cond.conditionGamestage.matches(player);
|
||||
boolean position = cond.conditionPosition.matches(player);
|
||||
boolean xp = cond.conditionXp.matches(player.experienceLevel);
|
||||
boolean scoreboard = cond.conditionScoreboard.matches(player);
|
||||
boolean effects = cond.conditionEffects.matches(player);
|
||||
|
||||
return achievement && gamemode && gamestage && position && xp && scoreboard && effects;
|
||||
}
|
||||
|
||||
|
||||
public record ScriptObject(ScriptObjectBlock block, ScriptObjectEntity entity)
|
||||
{
|
||||
public static final Codec<ScriptObject> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
ScriptObjectBlock.CODEC.optionalFieldOf("block", ScriptObjectBlock.EMPTY).forGetter(ScriptObject::block),
|
||||
ScriptObjectEntity.CODEC.optionalFieldOf("entity", ScriptObjectEntity.EMPTY).forGetter(ScriptObject::entity)
|
||||
).apply(instance, ScriptObject::new)
|
||||
);
|
||||
|
||||
public record ScriptObjectBlock(
|
||||
Optional<ResourceKey<Block>> typeNameBlock,
|
||||
MaterialCondition typeMaterial,
|
||||
NumberBoundCondition typeHardness,
|
||||
NumberBoundCondition typeResistance,
|
||||
NBTCondition typeBlockTag
|
||||
){
|
||||
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(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)
|
||||
).apply(instance, ScriptObjectBlock::new)
|
||||
);
|
||||
}
|
||||
|
||||
public record ScriptObjectEntity(
|
||||
Optional<ResourceKey<EntityType<?>>> typeNameEntity,
|
||||
NumberBoundCondition typeHealth,
|
||||
NumberBoundCondition typeHeight,
|
||||
NumberBoundCondition typeWidth,
|
||||
NBTCondition typeEntityTag
|
||||
){
|
||||
public static final ScriptObjectEntity EMPTY = new ScriptObjectEntity(Optional.empty(), NumberBoundCondition.NONE, NumberBoundCondition.NONE, NumberBoundCondition.NONE, NBTCondition.NONE);
|
||||
|
||||
public static final Codec<ScriptObjectEntity> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
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),
|
||||
NBTCondition.CODEC.optionalFieldOf("nbt", NBTCondition.NONE).forGetter(ScriptObjectEntity::typeEntityTag)
|
||||
).apply(instance, ScriptObjectEntity::new)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public record ScriptConditions(
|
||||
GamestageCondition conditionGamestage,
|
||||
AdvancementCondition conditionAchievement,
|
||||
NumberBoundCondition conditionXp,
|
||||
NumberBoundCondition conditionGamemode,
|
||||
ScoreboardCondition conditionScoreboard,
|
||||
PositionCondition conditionPosition,
|
||||
EffectsCondition conditionEffects
|
||||
){
|
||||
public static final ScriptConditions EMPTY = new ScriptConditions(GamestageCondition.NONE, AdvancementCondition.NONE, NumberBoundCondition.NONE, NumberBoundCondition.NONE, ScoreboardCondition.NONE, PositionCondition.NONE, EffectsCondition.NONE);
|
||||
|
||||
public static final Codec<ScriptConditions> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
GamestageCondition.CODEC.optionalFieldOf("gamestage", GamestageCondition.NONE).forGetter(ScriptConditions::conditionGamestage),
|
||||
AdvancementCondition.CODEC.optionalFieldOf("advancement", AdvancementCondition.NONE).forGetter(ScriptConditions::conditionAchievement),
|
||||
NumberBoundCondition.CODEC.optionalFieldOf("xp", NumberBoundCondition.NONE).forGetter(ScriptConditions::conditionXp),
|
||||
NumberBoundCondition.CODEC.optionalFieldOf("gamemode", NumberBoundCondition.NONE).forGetter(ScriptConditions::conditionGamemode),
|
||||
ScoreboardCondition.CODEC.optionalFieldOf("scoreboard", ScoreboardCondition.NONE).forGetter(ScriptConditions::conditionScoreboard),
|
||||
PositionCondition.CODEC.optionalFieldOf("position", PositionCondition.NONE).forGetter(ScriptConditions::conditionPosition),
|
||||
EffectsCondition.CODEC.optionalFieldOf("effects", EffectsCondition.NONE).forGetter(ScriptConditions::conditionEffects)
|
||||
).apply(instance, ScriptConditions::new)
|
||||
);
|
||||
}
|
||||
|
||||
public record ScriptRender(
|
||||
Optional<ResourceKey<Block>> renderNameBlock,
|
||||
Optional<ResourceKey<EntityType<?>>> renderNameEntity,
|
||||
Optional<CompoundTag> renderNBT,
|
||||
OptionalVec3 renderTranslation,
|
||||
OptionalVec3 renderRotation,
|
||||
OptionalVec3 renderscale,
|
||||
OptionalVec3 renderRotationLeftArm,
|
||||
OptionalVec3 renderRotationRightArm,
|
||||
boolean renderLeftArm,
|
||||
boolean renderRightArm
|
||||
){
|
||||
public static final ScriptRender EMPTY = new ScriptRender(Optional.empty(), Optional.empty(), Optional.empty(), OptionalVec3.NONE, OptionalVec3.NONE, OptionalVec3.NONE, OptionalVec3.NONE, OptionalVec3.NONE, true, true);
|
||||
|
||||
public static final Codec<ScriptRender> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
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),
|
||||
OptionalVec3.CODEC.optionalFieldOf("scale", OptionalVec3.NONE).forGetter(ScriptRender::renderscale),
|
||||
OptionalVec3.CODEC.optionalFieldOf("rotation_left_arm", OptionalVec3.NONE).forGetter(ScriptRender::renderRotationLeftArm),
|
||||
OptionalVec3.CODEC.optionalFieldOf("rotation_right_arm", OptionalVec3.NONE).forGetter(ScriptRender::renderRotationRightArm),
|
||||
Codec.BOOL.optionalFieldOf("render_left_arm", true).forGetter(ScriptRender::renderLeftArm),
|
||||
Codec.BOOL.optionalFieldOf("render_right_arm", true).forGetter(ScriptRender::renderRightArm)
|
||||
).apply(instance, ScriptRender::new)
|
||||
);
|
||||
}
|
||||
|
||||
public record ScriptEffects(
|
||||
String commandInit,
|
||||
String commandLoop,
|
||||
String commandPlace
|
||||
){
|
||||
public static final ScriptEffects EMPTY = new ScriptEffects("", "", "");
|
||||
|
||||
public static final Codec<ScriptEffects> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
Codec.STRING.optionalFieldOf("commandPickup", "").forGetter(ScriptEffects::commandInit),
|
||||
Codec.STRING.optionalFieldOf("commandLoop", "").forGetter(ScriptEffects::commandLoop),
|
||||
Codec.STRING.optionalFieldOf("commandPlace", "").forGetter(ScriptEffects::commandPlace)
|
||||
).apply(instance, ScriptEffects::new)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,402 @@
|
|||
package tschipp.carryon.common.scripting;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
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.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.Map;
|
||||
|
||||
public final class Matchables
|
||||
{
|
||||
public interface Matchable<T>
|
||||
{
|
||||
boolean matches(T elem);
|
||||
}
|
||||
|
||||
private static float getValueFromString(String toGetFrom, String key, float defaultValue)
|
||||
{
|
||||
if (toGetFrom == null || toGetFrom.isEmpty())
|
||||
return defaultValue;
|
||||
|
||||
String[] s = toGetFrom.split(",");
|
||||
for (String string : s)
|
||||
{
|
||||
if (string.contains(key) && string.contains("="))
|
||||
{
|
||||
float numb = 0;
|
||||
string = string.replace(key + "=", "");
|
||||
|
||||
try
|
||||
{
|
||||
numb = Float.parseFloat(string);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
|
||||
return numb;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public record NumberBoundCondition(String bounds) implements Matchable<Number>
|
||||
{
|
||||
public static final Codec<NumberBoundCondition> CODEC = Codec.STRING.xmap(NumberBoundCondition::new, NumberBoundCondition::bounds);
|
||||
|
||||
public static final NumberBoundCondition NONE = new NumberBoundCondition("");
|
||||
|
||||
@Override
|
||||
public boolean matches(Number num)
|
||||
{
|
||||
double number = num.doubleValue();
|
||||
|
||||
if (bounds == null || bounds.isEmpty())
|
||||
return true;
|
||||
|
||||
try
|
||||
{
|
||||
if (bounds.contains("<="))
|
||||
return number <= Double.parseDouble(bounds.replace("<=", ""));
|
||||
if (bounds.contains(">="))
|
||||
return number >= Double.parseDouble(bounds.replace(">=", ""));
|
||||
if (bounds.contains("<"))
|
||||
return number < Double.parseDouble(bounds.replace("<", ""));
|
||||
if (bounds.contains(">"))
|
||||
return number > Double.parseDouble(bounds.replace(">", ""));
|
||||
if (bounds.contains("="))
|
||||
return number == Double.parseDouble(bounds.replace("=", ""));
|
||||
else
|
||||
return number == Double.parseDouble(bounds);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException("Error while parsing Number bound for string: "+ bounds + ". Error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
public static final AdvancementCondition NONE = new AdvancementCondition("");
|
||||
|
||||
@Override
|
||||
public boolean matches(ServerPlayer player)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
public record GamestageCondition(String gamestage) implements Matchable<ServerPlayer>
|
||||
{
|
||||
public static final Codec<GamestageCondition> CODEC = Codec.STRING.xmap(GamestageCondition::new, GamestageCondition::gamestage);
|
||||
|
||||
public static final GamestageCondition NONE = new GamestageCondition("");
|
||||
|
||||
@Override
|
||||
public boolean matches(ServerPlayer elem)
|
||||
{
|
||||
if(!Services.PLATFORM.isModLoaded("gamestages"))
|
||||
return true;
|
||||
|
||||
//TODO: Gamestages
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public record ScoreboardCondition(String cond) implements Matchable<ServerPlayer>
|
||||
{
|
||||
public static final Codec<ScoreboardCondition> CODEC = Codec.STRING.xmap(ScoreboardCondition::new, ScoreboardCondition::cond);
|
||||
|
||||
public static final ScoreboardCondition NONE = new ScoreboardCondition("");
|
||||
|
||||
|
||||
@Override
|
||||
public boolean matches(ServerPlayer player)
|
||||
{
|
||||
if (cond == null || cond.isEmpty())
|
||||
return true;
|
||||
|
||||
Scoreboard score = player.getScoreboard();
|
||||
String numb;
|
||||
String scorename;
|
||||
int iE = cond.indexOf("=");
|
||||
int iG = cond.indexOf(">");
|
||||
int iL = cond.indexOf("<");
|
||||
|
||||
if (iG == -1 ? true : iE < iG && iL == -1 ? true : iE < iL && iE != -1)
|
||||
numb = cond.substring(iE);
|
||||
else if (iE == -1 ? true : iG < iE && iL == -1 ? true : iG < iL && iG != -1)
|
||||
numb = cond.substring(iG);
|
||||
else
|
||||
numb = cond.substring(iL);
|
||||
|
||||
scorename = cond.replace(numb, "");
|
||||
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(points);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public record PositionCondition(String cond) implements Matchable<ServerPlayer>
|
||||
{
|
||||
public static final Codec<PositionCondition> CODEC = Codec.STRING.xmap(PositionCondition::new, PositionCondition::cond);
|
||||
|
||||
public static final PositionCondition NONE = new PositionCondition("");
|
||||
|
||||
|
||||
@Override
|
||||
public boolean matches(ServerPlayer elem)
|
||||
{
|
||||
if (cond == null || cond.isEmpty())
|
||||
return true;
|
||||
|
||||
BlockPos blockpos = new BlockPos(getValueFromString(cond, "x", 0), getValueFromString(cond, "y", 0), getValueFromString(cond, "z", 0));
|
||||
BlockPos expand = new BlockPos(getValueFromString(cond, "dx", 0), getValueFromString(cond, "dy", 0), getValueFromString(cond, "dz", 0));
|
||||
BlockPos expanded = blockpos.offset(expand);
|
||||
BlockPos pos = elem.blockPosition();
|
||||
|
||||
boolean x = pos.getX() >= blockpos.getX() && pos.getX() <= expanded.getX() || blockpos.getX() == 0;
|
||||
boolean y = pos.getY() >= blockpos.getY() && pos.getY() <= expanded.getY() || blockpos.getY() == 0;
|
||||
boolean z = pos.getZ() >= blockpos.getZ() && pos.getZ() <= expanded.getZ() || blockpos.getZ() == 0;
|
||||
|
||||
return x && y && z;
|
||||
}
|
||||
}
|
||||
|
||||
public record EffectsCondition(String effects) implements Matchable<ServerPlayer>
|
||||
{
|
||||
public static final Codec<EffectsCondition> CODEC = Codec.STRING.xmap(EffectsCondition::new, EffectsCondition::effects);
|
||||
|
||||
public static final EffectsCondition NONE = new EffectsCondition("");
|
||||
|
||||
@Override
|
||||
public boolean matches(ServerPlayer player)
|
||||
{
|
||||
if (effects == null || effects.isEmpty())
|
||||
return true;
|
||||
|
||||
Collection<MobEffectInstance> fx = player.getActiveEffects();
|
||||
String[] potions = effects.split(",");
|
||||
|
||||
List<String> names = new ArrayList<>();
|
||||
List<Integer> levels = new ArrayList<>();
|
||||
|
||||
for (String pot : potions)
|
||||
{
|
||||
if (pot.contains("#"))
|
||||
{
|
||||
String level = pot.substring(pot.indexOf("#"));
|
||||
String name = pot.substring(0, pot.indexOf("#"));
|
||||
level = level.replace("#", "");
|
||||
int lev = 0;
|
||||
try
|
||||
{
|
||||
lev = Integer.parseInt(level);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
|
||||
levels.add(lev);
|
||||
names.add(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
levels.add(0);
|
||||
names.add(pot);
|
||||
}
|
||||
}
|
||||
|
||||
int matches = 0;
|
||||
for (MobEffectInstance effect : fx)
|
||||
{
|
||||
int amp = effect.getAmplifier();
|
||||
String name = Registry.MOB_EFFECT.getKey(effect.getEffect()).toString();
|
||||
|
||||
if (names.contains(name))
|
||||
{
|
||||
int idx = names.indexOf(name);
|
||||
int lev = levels.get(idx);
|
||||
|
||||
if (lev == amp)
|
||||
matches++;
|
||||
}
|
||||
}
|
||||
|
||||
return matches == potions.length;
|
||||
}
|
||||
}
|
||||
|
||||
public record NBTCondition(CompoundTag tag) implements Matchable<CompoundTag>
|
||||
{
|
||||
public static final Codec<NBTCondition> CODEC = CompoundTag.CODEC.xmap(NBTCondition::new, NBTCondition::tag);
|
||||
|
||||
public static final NBTCondition NONE = new NBTCondition(new CompoundTag());
|
||||
|
||||
@Override
|
||||
public boolean matches(CompoundTag other)
|
||||
{
|
||||
if(other == null)
|
||||
return true;
|
||||
return NbtUtils.compareNbt(tag, other, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static class OptionalVec3 {
|
||||
|
||||
public static final Codec<OptionalVec3> CODEC = Codec.STRING.xmap(OptionalVec3::new, OptionalVec3::source);
|
||||
|
||||
public static final OptionalVec3 NONE = new OptionalVec3("");
|
||||
|
||||
String source;
|
||||
Vec3 vec;
|
||||
|
||||
public OptionalVec3(String source)
|
||||
{
|
||||
this.source = source;
|
||||
double x = getValueFromString(source, "x", 0);
|
||||
double y = getValueFromString(source, "y", 0);
|
||||
double z = getValueFromString(source, "z", 0);
|
||||
vec = new Vec3(x, y, z);
|
||||
}
|
||||
|
||||
private String source()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
public Vec3 getVec()
|
||||
{
|
||||
return vec;
|
||||
}
|
||||
|
||||
public Vec3 getVec(double defaultValue)
|
||||
{
|
||||
double x = vec.x == 0f ? defaultValue : vec.x;
|
||||
double y = vec.y == 0f ? defaultValue : vec.y;
|
||||
double z = vec.z == 0f ? defaultValue : vec.z;
|
||||
return new Vec3(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
package tschipp.carryon.common.scripting;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
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.material.Material;
|
||||
import tschipp.carryon.Constants;
|
||||
import tschipp.carryon.common.scripting.CarryOnScript.ScriptObject.ScriptObjectBlock;
|
||||
import tschipp.carryon.common.scripting.CarryOnScript.ScriptObject.ScriptObjectEntity;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ScriptManager
|
||||
{
|
||||
public static final List<CarryOnScript> SCRIPTS = new ArrayList<>();
|
||||
|
||||
public static Optional<CarryOnScript> inspectBlock(BlockState state, Level level, BlockPos pos, @Nullable CompoundTag tag)
|
||||
{
|
||||
if (!Constants.COMMON_CONFIG.settings.useScripts)
|
||||
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, material, hardness, resistance, tag))
|
||||
return Optional.of(script);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public static Optional<CarryOnScript> inspectEntity(Entity entity)
|
||||
{
|
||||
if (!Constants.COMMON_CONFIG.settings.useScripts)
|
||||
return Optional.empty();
|
||||
|
||||
float height = entity.getBbHeight();
|
||||
float width = entity.getBbWidth();
|
||||
float health = entity instanceof LivingEntity ? ((LivingEntity) entity).getHealth() : 0.0f;
|
||||
CompoundTag tag = new CompoundTag();
|
||||
entity.save(tag);
|
||||
|
||||
for (CarryOnScript script : SCRIPTS)
|
||||
{
|
||||
if (script.isEntity() && matchesAll(script, entity, height, width, health, tag))
|
||||
return Optional.of(script);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private static boolean matchesAll(CarryOnScript script, Entity entity, float height, float width, float health, CompoundTag tag)
|
||||
{
|
||||
ScriptObjectEntity scEntity = script.scriptObject().entity();
|
||||
|
||||
boolean matchname = true;
|
||||
if(scEntity.typeNameEntity().isPresent())
|
||||
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);
|
||||
boolean matchnbt = scEntity.typeEntityTag().matches(tag);
|
||||
|
||||
return matchname && matchheight && matchwidth && matchhealth && matchnbt;
|
||||
}
|
||||
|
||||
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 == 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 && matchmaterial && matchhardness && matchresistance;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
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.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 tschipp.carryon.Constants;
|
||||
import tschipp.carryon.networking.clientbound.ClientboundSyncScriptsPacket;
|
||||
import tschipp.carryon.platform.Services;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public class ScriptReloadListener extends SimpleJsonResourceReloadListener
|
||||
{
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
|
||||
public ScriptReloadListener()
|
||||
{
|
||||
super(GSON, "carryon/scripts");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void apply(Map<ResourceLocation, JsonElement> objects, ResourceManager manager, ProfilerFiller profiler)
|
||||
{
|
||||
ScriptManager.SCRIPTS.clear();
|
||||
|
||||
try {
|
||||
objects.forEach((path, jsonElem) -> {
|
||||
DataResult<CarryOnScript> res = CarryOnScript.CODEC.parse(JsonOps.INSTANCE, jsonElem);
|
||||
CarryOnScript script = res.getOrThrow(false, (s) -> {throw new RuntimeException(s);});
|
||||
|
||||
if (script.isValid())
|
||||
ScriptManager.SCRIPTS.add(script);
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
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(false, s -> {throw new RuntimeException("Error while synching Carry On Scripts: " + s);});
|
||||
|
||||
Services.PLATFORM.sendPacketToPlayer(Constants.PACKET_ID_SYNC_SCRIPTS, new ClientboundSyncScriptsPacket(tag), player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
87
Common/src/main/java/tschipp/carryon/mixin/EntityMixin.java
Normal file
87
Common/src/main/java/tschipp/carryon/mixin/EntityMixin.java
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
package tschipp.carryon.mixin;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Entity.MoveFunction;
|
||||
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;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
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.networking.clientbound.ClientboundStartRidingPacket;
|
||||
import tschipp.carryon.platform.Services;
|
||||
|
||||
@Mixin(Entity.class)
|
||||
public abstract class EntityMixin
|
||||
{
|
||||
@Shadow
|
||||
public boolean hasPassenger(Entity pEntity) {throw new IllegalStateException("EntityMixin application failed");}
|
||||
|
||||
@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)
|
||||
private void onPositionPassenger(Entity entity, MoveFunction move, CallbackInfo ci)
|
||||
{
|
||||
if((Object)this instanceof Player thisPlayer && entity instanceof Player otherPlayer)
|
||||
{
|
||||
if(hasPassenger(otherPlayer) && CarryOnDataManager.getCarryData(thisPlayer).isCarrying(CarryType.PLAYER))
|
||||
{
|
||||
Vec3 forward = new Vec3(0, 0, 0.6);
|
||||
Vec3 otherPos = thisPlayer.position().add(forward.yRot((float) Math.toRadians(-thisPlayer.yBodyRot)));
|
||||
otherPos = otherPos.add(0, 0.4,0);
|
||||
move.accept(otherPlayer, otherPos.x, otherPos.y, otherPos.z);
|
||||
((Entity)((Object)this)).onPassengerTurned(otherPlayer);
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject(method = "getDismountLocationForPassenger(Lnet/minecraft/world/entity/LivingEntity;)Lnet/minecraft/world/phys/Vec3;", at = @At("HEAD"))
|
||||
private void onDismountPassenger(LivingEntity living, CallbackInfoReturnable<Vec3> cir)
|
||||
{
|
||||
if((Object)this instanceof Player thisPlayer && living instanceof Player otherPlayer)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(thisPlayer);
|
||||
if(carry.isCarrying(CarryType.PLAYER))
|
||||
{
|
||||
carry.clear();
|
||||
CarryOnDataManager.setCarryData(thisPlayer, carry);
|
||||
Services.PLATFORM.sendPacketToPlayer(Constants.PACKET_ID_START_RIDING, new ClientboundStartRidingPacket(otherPlayer.getId(), false), (ServerPlayer) thisPlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "onPassengerTurned(Lnet/minecraft/world/entity/Entity;)V", at = @At("HEAD"))
|
||||
private void onPassengerTurned(Entity toUpdate, CallbackInfo ci)
|
||||
{
|
||||
if((Object)this instanceof Player thisPlayer && toUpdate instanceof Player otherPlayer)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(thisPlayer);
|
||||
if(carry.isCarrying(CarryType.PLAYER)) {
|
||||
this.clampRotation(toUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void clampRotation(Entity pEntityToUpdate) {
|
||||
Entity thisEntity = (Entity)((Object)this);
|
||||
pEntityToUpdate.setYBodyRot(thisEntity.getYRot());
|
||||
float f = Mth.wrapDegrees(pEntityToUpdate.getYRot() - thisEntity.getYRot());
|
||||
float f1 = Mth.clamp(f, -30.0F, 30.0F);
|
||||
pEntityToUpdate.yRotO += f1 - f;
|
||||
pEntityToUpdate.setYRot(pEntityToUpdate.getYRot() + f1 - f);
|
||||
pEntityToUpdate.setYHeadRot(pEntityToUpdate.getYRot());
|
||||
}
|
||||
}
|
||||
|
|
@ -4,13 +4,17 @@ import net.minecraft.client.model.HumanoidModel;
|
|||
import net.minecraft.client.model.geom.ModelPart;
|
||||
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;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import tschipp.carryon.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)
|
||||
public class HumanoidModelMixin {
|
||||
|
|
@ -24,32 +28,50 @@ public class HumanoidModelMixin {
|
|||
@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)
|
||||
{
|
||||
System.out.println("Reached model injectiob");
|
||||
if(living instanceof Player player)
|
||||
{
|
||||
System.out.println("Model is player");
|
||||
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if(carry.isCarrying() && !player.isVisuallySwimming() && !player.isFallFlying())
|
||||
{
|
||||
System.out.println("Player is carrying");
|
||||
|
||||
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.15f;
|
||||
float x = 1.0f + (sneaking ? 0.2f : 0.0f) + (carry.isCarrying(CarryOnData.CarryType.BLOCK) ? 0.0f : 0.3f);
|
||||
float z = 0.05f;
|
||||
|
||||
rightArm.yRot = 0;
|
||||
leftArm.yRot = 0;
|
||||
float width = CarryRenderHelper.getRenderWidth(player);
|
||||
float offset = Math.min((width - 1) / 1.5f, 0.2f);
|
||||
|
||||
rightArm.xRot = -x;
|
||||
leftArm.xRot = -x;
|
||||
if(carry.getActiveScript().isPresent())
|
||||
{
|
||||
ScriptRender render = carry.getActiveScript().get().scriptRender();
|
||||
boolean renderLeft = render.renderLeftArm();
|
||||
boolean renderRight = render.renderRightArm();
|
||||
|
||||
Vec3 rotLeft = render.renderRotationLeftArm().getVec();
|
||||
Vec3 rotRight = render.renderRotationRightArm().getVec();
|
||||
|
||||
if(renderLeft)
|
||||
changeRotation(leftArm, (float) rotLeft.x, (float) rotLeft.y, (float) rotLeft.z);
|
||||
|
||||
if(renderRight)
|
||||
changeRotation(rightArm, (float) rotRight.x, (float) rotRight.y, (float) rotRight.z);
|
||||
}
|
||||
else {
|
||||
changeRotation(rightArm, -x, offset, -z);
|
||||
changeRotation(leftArm, -x, -offset, z);
|
||||
}
|
||||
|
||||
rightArm.zRot = z;
|
||||
leftArm.zRot = -z;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void changeRotation(ModelPart part, float x, float y, float z)
|
||||
{
|
||||
part.xRot = x;
|
||||
part.yRot = y;
|
||||
part.zRot = z;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
package tschipp.carryon.mixin;
|
||||
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
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.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.CarryOnDataManager;
|
||||
|
||||
|
|
@ -15,16 +19,26 @@ public class InventoryMixin
|
|||
@Shadow
|
||||
public Player player;
|
||||
|
||||
// @Redirect(method = "selected:I", at = @At())
|
||||
// private void setSelected(Inventory inv, int value)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
@Shadow
|
||||
public int selected;
|
||||
|
||||
@Shadow
|
||||
public NonNullList<ItemStack> items;
|
||||
|
||||
@Redirect(method = "getFreeSlot()I", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/core/NonNullList;get(I)Ljava/lang/Object;"))
|
||||
private <E> E getFreeSlotEmptyCheck(NonNullList<E> instance, int i)
|
||||
{
|
||||
if(i == selected && CarryOnDataManager.getCarryData(player).isCarrying())
|
||||
{
|
||||
return (E) new ItemStack(Blocks.STONE, 1);
|
||||
}
|
||||
else
|
||||
return instance.get(i);
|
||||
}
|
||||
|
||||
@Inject(method = "setPickedItem(Lnet/minecraft/world/item/ItemStack;)V", at = @At("HEAD"), cancellable = true)
|
||||
private void onPickBlock(CallbackInfo info)
|
||||
{
|
||||
System.out.println("onPickBlock");
|
||||
if(CarryOnDataManager.getCarryData(player).isCarrying())
|
||||
info.cancel();
|
||||
}
|
||||
|
|
@ -32,7 +46,6 @@ public class InventoryMixin
|
|||
@Inject(method = "pickSlot(I)V", at = @At("HEAD"), cancellable = true)
|
||||
private void onPickSlot(int slot, CallbackInfo info)
|
||||
{
|
||||
System.out.println("onPickSlot");
|
||||
if(CarryOnDataManager.getCarryData(player).isCarrying())
|
||||
info.cancel();
|
||||
}
|
||||
|
|
@ -40,9 +53,6 @@ public class InventoryMixin
|
|||
@Inject(method = "swapPaint(D)V", at = @At("HEAD"), cancellable = true)
|
||||
private void onSwapPaint(double direction, CallbackInfo info)
|
||||
{
|
||||
System.out.println(player);
|
||||
System.out.println(CarryOnDataManager.getCarryData(player).getNbt());
|
||||
System.out.println("onSwapPaint");
|
||||
if(CarryOnDataManager.getCarryData(player).isCarrying())
|
||||
info.cancel();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,10 +36,9 @@ public abstract class PlayerMixin extends LivingEntity {
|
|||
@Inject(method = "readAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("RETURN"))
|
||||
private void onReadAdditionalSaveData(CompoundTag tag, CallbackInfo info)
|
||||
{
|
||||
if(tag.contains("CarryOnData"))
|
||||
{
|
||||
if (tag.contains("CarryOnData")) {
|
||||
CarryOnData data = new CarryOnData(tag.getCompound("CarryOnData"));
|
||||
CarryOnDataManager.setCarryData((Player)(Object)this, data);
|
||||
CarryOnDataManager.setCarryData((Player) (Object) this, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
package tschipp.carryon.networking;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
||||
public abstract class PacketBase
|
||||
{
|
||||
public abstract void toBytes(FriendlyByteBuf buf);
|
||||
|
||||
public abstract void handle(Player player);
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package tschipp.carryon.networking.clientbound;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import tschipp.carryon.networking.PacketBase;
|
||||
|
||||
public class ClientboundStartRidingPacket extends PacketBase
|
||||
{
|
||||
int entityId;
|
||||
boolean ride;
|
||||
|
||||
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.entityId);
|
||||
if(otherPlayer != null)
|
||||
if(ride)
|
||||
otherPlayer.startRiding(player);
|
||||
else
|
||||
otherPlayer.stopRiding();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package tschipp.carryon.networking.clientbound;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import tschipp.carryon.common.scripting.CarryOnScript;
|
||||
import tschipp.carryon.common.scripting.ScriptManager;
|
||||
import tschipp.carryon.networking.PacketBase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ClientboundSyncScriptsPacket extends PacketBase
|
||||
{
|
||||
private Tag serialized;
|
||||
|
||||
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(false, (s) -> {throw new RuntimeException("Failed deserializing carry on scripts on the client: " + s);});
|
||||
ScriptManager.SCRIPTS.clear();
|
||||
ScriptManager.SCRIPTS.addAll(scripts);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package tschipp.carryon.networking.serverbound;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import tschipp.carryon.common.carry.CarryOnData;
|
||||
import tschipp.carryon.common.carry.CarryOnDataManager;
|
||||
import tschipp.carryon.networking.PacketBase;
|
||||
|
||||
public class ServerboundCarryKeyPressedPacket extends PacketBase
|
||||
{
|
||||
boolean 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)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
carry.setKeyPressed(this.pressed);
|
||||
CarryOnDataManager.setCarryData(player, carry);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,14 @@
|
|||
package tschipp.carryon.platform.services;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import tschipp.carryon.config.BuiltConfig;
|
||||
import tschipp.carryon.networking.PacketBase;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public interface IPlatformHelper {
|
||||
|
||||
|
|
@ -27,4 +35,13 @@ public interface IPlatformHelper {
|
|||
boolean isDevelopmentEnvironment();
|
||||
|
||||
void registerConfig(BuiltConfig cfg);
|
||||
|
||||
<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> void registerClientboundPacket(ResourceLocation id, int numericalId, Class<T> clazz, BiConsumer<T, FriendlyByteBuf> writer, Function<FriendlyByteBuf, T> reader, BiConsumer<T, Player> handler);
|
||||
|
||||
void sendPacketToServer(ResourceLocation id, PacketBase packet);
|
||||
|
||||
void sendPacketToPlayer(ResourceLocation id, PacketBase packet, ServerPlayer player);
|
||||
|
||||
}
|
||||
|
|
|
|||
16
Common/src/main/resources/assets/carryon/lang/en_ud.json
Normal file
16
Common/src/main/resources/assets/carryon/lang/en_ud.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"carryon.category.settings": "sᵷuᴉʇʇǝS",
|
||||
"carryon.category.blacklist": "ʇsᴉꞁʞɔɐꞁᗺ",
|
||||
"carryon.category.modeloverrides": "(pǝɔuɐʌpⱯ) sǝpᴉɹɹǝʌO ꞁǝpoW",
|
||||
"carryon.category.custompickupconditions": "(pǝɔuɐʌpⱯ) suoᴉʇᴉpuoƆ dnʞɔᴉԀ ɯoʇsnƆ",
|
||||
"carryon.category.whitelist": "ʇsᴉꞁǝʇᴉɥM",
|
||||
|
||||
"carryon.general.modeloverrides.modeloverrides": "sǝpᴉɹɹǝʌO ꞁǝpoW",
|
||||
"carryon.general.blacklist.forbiddenentities": "dn ʞɔᴉd ʇouuɐɔ ɹǝʎɐꞁԀ ǝɥʇ ʇɐɥʇ sǝᴉʇᴉʇuƎ",
|
||||
"carryon.general.blacklist.forbiddentiles": "dn ʞɔᴉd ʇouuɐɔ ɹǝʎɐꞁԀ ǝɥʇ ʇɐɥʇ sʞɔoꞁᗺ",
|
||||
"carryon.category.custompickupconditions.custompickupconditionsblocks": "suoᴉʇᴉpuoƆ dnʞɔᴉԀ ʞɔoꞁᗺ ɯoʇsnƆ",
|
||||
"carryon.category.custompickupconditions.custompickupconditionsentities": "suoᴉʇᴉpuoƆ dnʞɔᴉԀ ʎʇᴉʇuƎ ɯoʇsnƆ",
|
||||
|
||||
"key.carry.desc": "ʎɹɹɐƆ",
|
||||
"key.carry.category": "uO ʎɹɹɐƆ"
|
||||
}
|
||||
16
Common/src/main/resources/assets/carryon/lang/en_us.json
Normal file
16
Common/src/main/resources/assets/carryon/lang/en_us.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"carryon.category.settings": "Settings",
|
||||
"carryon.category.blacklist": "Blacklist",
|
||||
"carryon.category.modeloverrides": "Model Overrides (Advanced)",
|
||||
"carryon.category.custompickupconditions": "Custom Pickup Conditions (Advanced)",
|
||||
"carryon.category.whitelist": "Whitelist",
|
||||
|
||||
"carryon.general.modeloverrides.modeloverrides": "Model Overrides",
|
||||
"carryon.general.blacklist.forbiddenentities": "Entities that the Player cannot pick up",
|
||||
"carryon.general.blacklist.forbiddentiles": "Blocks that the Player cannot pick up",
|
||||
"carryon.category.custompickupconditions.custompickupconditionsblocks": "Custom Block Pickup Conditions",
|
||||
"carryon.category.custompickupconditions.custompickupconditionsentities": "Custom Entity Pickup Conditions",
|
||||
|
||||
"key.carry.desc": "Carry",
|
||||
"key.carry.category": "Carry On"
|
||||
}
|
||||
16
Common/src/main/resources/assets/carryon/lang/es_es.json
Normal file
16
Common/src/main/resources/assets/carryon/lang/es_es.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"carryon.category.settings": "Configuración",
|
||||
"carryon.category.blacklist": "Lista negra",
|
||||
"carryon.category.modeloverrides": "Reescribir modelo (Avanzado)",
|
||||
"carryon.category.custompickupconditions": "Customizar condiciones de recoger (Avanzado)",
|
||||
"carryon.category.whitelist": "Lista blanca",
|
||||
|
||||
"carryon.general.modeloverrides.modeloverrides": "Reescribir 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": "Customizar condiciones para recoger bloques",
|
||||
"carryon.category.custompickupconditions.custompickupconditionsentities": "Customizar condiciones para recoger entidades",
|
||||
|
||||
"key.carry.desc": "Agarrar",
|
||||
"key.carry.category": "Carry On"
|
||||
}
|
||||
16
Common/src/main/resources/assets/carryon/lang/it_it.json
Normal file
16
Common/src/main/resources/assets/carryon/lang/it_it.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"carryon.category.settings": "Inpostazioni",
|
||||
"carryon.category.blacklist": "Blacklist",
|
||||
"carryon.category.modeloverrides": "Sostituzioni modello (avanzate)",
|
||||
"carryon.category.custompickupconditions": "Condizioni di prelievo personalizzate (avanzate)",
|
||||
"carryon.category.whitelist": "Whitelist",
|
||||
|
||||
"carryon.general.modeloverrides.modeloverrides": "Sostituzioni modello",
|
||||
"carryon.general.blacklist.forbiddenentities": "Entità che il giocatore non può raccogliere",
|
||||
"carryon.general.blacklist.forbiddentiles": "Blocchi che il giocatore non può raccogliere",
|
||||
"carryon.category.custompickupconditions.custompickupconditionsblocks": "Condizioni di prelievo blocco personalizzate",
|
||||
"carryon.category.custompickupconditions.custompickupconditionsentities": "Condizioni di prelievo entità personalizzate",
|
||||
|
||||
"key.carry.desc": "Afferra",
|
||||
"key.carry.category": "Carry On Mod"
|
||||
}
|
||||
16
Common/src/main/resources/assets/carryon/lang/ko_kr.json
Normal file
16
Common/src/main/resources/assets/carryon/lang/ko_kr.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"carryon.category.settings": "설정",
|
||||
"carryon.category.blacklist": "블랙리스트",
|
||||
"carryon.category.modeloverrides": "모델 오버라이딩 (고급)",
|
||||
"carryon.category.custompickupconditions": "커스텀 들기 컨디션 (고급)",
|
||||
"carryon.category.whitelist": "화이트리스트",
|
||||
|
||||
"carryon.general.modeloverrides.modeloverrides": "모델 오버라이딩",
|
||||
"carryon.general.blacklist.forbiddenentities": "플레이어가 들 수 없는 엔티티",
|
||||
"carryon.general.blacklist.forbiddentiles": "플레이어가 들 수 없는 블록",
|
||||
"carryon.category.custompickupconditions.custompickupconditionsblocks": "커스텀 블록 들기 컨디션",
|
||||
"carryon.category.custompickupconditions.custompickupconditionsentities": "커스텀 엔티티 들기 컨디션",
|
||||
|
||||
"key.carry.desc": "들고 나르기",
|
||||
"key.carry.category": "Carry On"
|
||||
}
|
||||
16
Common/src/main/resources/assets/carryon/lang/ru_ru.json
Normal file
16
Common/src/main/resources/assets/carryon/lang/ru_ru.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"carryon.category.settings": "Настройки",
|
||||
"carryon.category.blacklist": "Чёрный список",
|
||||
"carryon.category.modeloverrides": "Переопределения модели (Улучшенное)",
|
||||
"carryon.category.custompickupconditions": "Индивидуальные условия поднятия (Улучшенное)",
|
||||
"carryon.category.whitelist": "Белый список",
|
||||
|
||||
"carryon.general.modeloverrides.modeloverrides": "Переопределения модели",
|
||||
"carryon.general.blacklist.forbiddenentities": "Сущности, которых игрок не может поднять",
|
||||
"carryon.general.blacklist.forbiddentiles": "Блоки, которые игрок не может поднять",
|
||||
"carryon.category.custompickupconditions.custompickupconditionsblocks": "Пользовательские условия поднятия блока",
|
||||
"carryon.category.custompickupconditions.custompickupconditionsentities": "Пользовательские условия поднятия сущности",
|
||||
|
||||
"key.carry.desc": "Поднять",
|
||||
"key.carry.category": "Carry On"
|
||||
}
|
||||
|
|
@ -4,12 +4,13 @@
|
|||
"package": "tschipp.carryon.mixin",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"EntityMixin",
|
||||
"InventoryMixin",
|
||||
"PlayerMixin"
|
||||
],
|
||||
"client": [
|
||||
"MinecraftMixin",
|
||||
"HumanoidModelMixin"
|
||||
"HumanoidModelMixin",
|
||||
"MinecraftMixin"
|
||||
],
|
||||
"server": [
|
||||
],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
]
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ plugins {
|
|||
id 'idea'
|
||||
}
|
||||
|
||||
archivesBaseName = "${mod_name}-fabric-${minecraft_version}"
|
||||
archivesBaseName = "${mod_id}-fabric-${minecraft_version}"
|
||||
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:${minecraft_version}"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
package tschipp.carryon;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.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
|
||||
{
|
||||
@Override
|
||||
public void onInitializeClient()
|
||||
{
|
||||
CarryOnKeybinds.registerKeybinds(KeyBindingHelper::registerKeyBinding);
|
||||
ClientEvents.registerEvents();
|
||||
CarryOnCommon.registerClientPackets();
|
||||
}
|
||||
|
||||
public static void sendPacketToServer(ResourceLocation id, PacketBase packet)
|
||||
{
|
||||
FriendlyByteBuf buf = PacketByteBufs.create();
|
||||
packet.toBytes(buf);
|
||||
ClientPlayNetworking.send(id, buf);
|
||||
}
|
||||
|
||||
public static <T extends PacketBase> void registerClientboundPacket(ResourceLocation id, Function<FriendlyByteBuf, T> reader, BiConsumer<T, Player> handler)
|
||||
{
|
||||
ClientPlayNetworking.registerGlobalReceiver(id, (client, packetHandler, buf, responseSender) -> {
|
||||
T packet = reader.apply(buf);
|
||||
client.execute(() -> {
|
||||
handler.accept(packet, client.player);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -14,9 +14,9 @@ public class CarryOnFabricMod implements ModInitializer {
|
|||
// This method is invoked by the Fabric mod loader when it is ready
|
||||
// to load your mod. You can access Fabric and Common code in this
|
||||
// project.
|
||||
CarryOnCommon.registerConfig();
|
||||
|
||||
|
||||
// Use Fabric to bootstrap the Common mod.
|
||||
Constants.LOG.info("Hello Fabric world!");
|
||||
try {
|
||||
ConfigLoaderImpl.initialize();
|
||||
} catch (IOException e) {
|
||||
|
|
@ -24,7 +24,7 @@ public class CarryOnFabricMod implements ModInitializer {
|
|||
}
|
||||
|
||||
CommonEvents.registerEvents();
|
||||
|
||||
CarryOnCommon.registerServerPackets();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,15 @@
|
|||
package tschipp.carryon.events;
|
||||
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import tschipp.carryon.CarryOnCommonClient;
|
||||
|
||||
public class ClientEvents {
|
||||
|
||||
public static void registerEvents()
|
||||
{
|
||||
ClientTickEvents.END_CLIENT_TICK.register(mc -> {
|
||||
CarryOnCommonClient.checkForKeybinds();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,24 @@
|
|||
package tschipp.carryon.events;
|
||||
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||
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.UseBlockCallback;
|
||||
import net.fabricmc.fabric.api.event.player.UseEntityCallback;
|
||||
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import tschipp.carryon.CarryOnCommon;
|
||||
import tschipp.carryon.common.carry.CarryOnData;
|
||||
import tschipp.carryon.common.carry.CarryOnData.CarryType;
|
||||
import tschipp.carryon.common.carry.CarryOnDataManager;
|
||||
import tschipp.carryon.common.carry.PickupHandler;
|
||||
import tschipp.carryon.common.carry.PlacementHandler;
|
||||
import tschipp.carryon.common.scripting.ScriptReloadListener;
|
||||
import tschipp.carryon.scripting.IdentifiableScriptReloadListener;
|
||||
|
||||
public class CommonEvents {
|
||||
|
||||
|
|
@ -62,14 +71,32 @@ public class CommonEvents {
|
|||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
else if(carry.isCarrying(CarryOnData.CarryType.ENTITY))
|
||||
else if(carry.isCarrying(CarryOnData.CarryType.ENTITY) || carry.isCarrying(CarryType.PLAYER))
|
||||
{
|
||||
//TODO: Stacking
|
||||
PlacementHandler.tryStackEntity((ServerPlayer) player, entity);
|
||||
}
|
||||
|
||||
return InteractionResult.PASS;
|
||||
});
|
||||
|
||||
|
||||
CommandRegistrationCallback.EVENT.register(((dispatcher, registryAccess, environment) -> {
|
||||
CarryOnCommon.registerCommands(dispatcher);
|
||||
}));
|
||||
|
||||
|
||||
ResourceManagerHelper.get(PackType.SERVER_DATA).registerReloadListener(new IdentifiableScriptReloadListener());
|
||||
|
||||
|
||||
ServerLifecycleEvents.SYNC_DATA_PACK_CONTENTS.register((player, joined) -> {
|
||||
ScriptReloadListener.syncScriptsWithClient(player);
|
||||
});
|
||||
|
||||
ServerTickEvents.END_SERVER_TICK.register(server -> {
|
||||
for(ServerPlayer player : server.getPlayerList().getPlayers())
|
||||
PickupHandler.onCarryTick(player);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
package tschipp.carryon.mixin;
|
||||
|
||||
import tschipp.carryon.Constants;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
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;
|
||||
|
||||
@Mixin(TitleScreen.class)
|
||||
public class ExampleMixin {
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "init()V")
|
||||
private void init(CallbackInfo info) {
|
||||
|
||||
Constants.LOG.info("This line is printed by an example mod mixin from Fabric!");
|
||||
Constants.LOG.info("MC Version: {}", Minecraft.getInstance().getVersionType());
|
||||
Constants.LOG.info("Classloader: {}", this.getClass().getClassLoader());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package tschipp.carryon.mixin;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.player.AbstractClientPlayer;
|
||||
import net.minecraft.client.renderer.ItemInHandRenderer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
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.Redirect;
|
||||
import tschipp.carryon.client.render.CarriedObjectRender;
|
||||
import tschipp.carryon.client.render.CarryRenderHelper;
|
||||
|
||||
@Mixin(ItemInHandRenderer.class)
|
||||
public class ItemInHandRendererMixin
|
||||
{
|
||||
|
||||
@Shadow
|
||||
private void renderArmWithItem(AbstractClientPlayer player, float partialTicks, float f2, InteractionHand hand, float f3, ItemStack stack, float f4, PoseStack poseStack, MultiBufferSource source, int light) {throw new RuntimeException("CarryOn InHandRendererMixin failed");}
|
||||
|
||||
|
||||
@Redirect(at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/renderer/ItemInHandRenderer;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"), method = "renderHandsWithItems(FLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;Lnet/minecraft/client/player/LocalPlayer;I)V")
|
||||
private void onRenderHand(ItemInHandRenderer instance, AbstractClientPlayer player, float partialTicks, float f2, InteractionHand hand, float f3, ItemStack stack, float f4, PoseStack poseStack, MultiBufferSource source, int light)
|
||||
{
|
||||
if(!CarriedObjectRender.drawFirstPerson(player, source, poseStack, light, partialTicks) && CarryRenderHelper.getPerspective() == 0)
|
||||
renderArmWithItem(player, partialTicks, f2, hand, f3, stack, f4, poseStack, source, light);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
28
Fabric/src/main/java/tschipp/carryon/mixin/ScreenMixin.java
Normal file
28
Fabric/src/main/java/tschipp/carryon/mixin/ScreenMixin.java
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
package tschipp.carryon.mixin;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
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.CallbackInfo;
|
||||
import tschipp.carryon.common.carry.CarryOnData;
|
||||
import tschipp.carryon.common.carry.CarryOnDataManager;
|
||||
|
||||
@Mixin(Screen.class)
|
||||
public class ScreenMixin
|
||||
{
|
||||
@Inject(at = @At(value = "TAIL"), method = "init(Lnet/minecraft/client/Minecraft;II)V")
|
||||
private void onInit(Minecraft mc, int i, int j, CallbackInfo ci)
|
||||
{
|
||||
Player player = mc.player;
|
||||
if((Object)this instanceof AbstractContainerScreen && player != null)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if(carry.isCarrying())
|
||||
mc.setScreen((Screen)null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,20 @@
|
|||
package tschipp.carryon.platform;
|
||||
|
||||
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.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import tschipp.carryon.CarryOnFabricClientMod;
|
||||
import tschipp.carryon.config.BuiltConfig;
|
||||
import tschipp.carryon.config.fabric.ConfigLoaderImpl;
|
||||
import tschipp.carryon.networking.PacketBase;
|
||||
import tschipp.carryon.platform.services.IPlatformHelper;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class FabricPlatformHelper implements IPlatformHelper {
|
||||
|
||||
|
|
@ -28,4 +39,35 @@ public class FabricPlatformHelper implements IPlatformHelper {
|
|||
public void registerConfig(BuiltConfig cfg) {
|
||||
ConfigLoaderImpl.registerConfig(cfg);
|
||||
}
|
||||
|
||||
@Override
|
||||
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)
|
||||
{
|
||||
ServerPlayNetworking.registerGlobalReceiver(id, (server, player, packetHandler, buf, responseSender) -> {
|
||||
T packet = reader.apply(buf);
|
||||
server.execute(() -> {
|
||||
handler.accept(packet, player);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
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)
|
||||
{
|
||||
CarryOnFabricClientMod.registerClientboundPacket(id, reader, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacketToServer(ResourceLocation id, PacketBase packet)
|
||||
{
|
||||
CarryOnFabricClientMod.sendPacketToServer(id, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacketToPlayer(ResourceLocation id, PacketBase packet, ServerPlayer player)
|
||||
{
|
||||
FriendlyByteBuf buf = PacketByteBufs.create();
|
||||
packet.toBytes(buf);
|
||||
ServerPlayNetworking.send(player, id, buf);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
package tschipp.carryon.scripting;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import tschipp.carryon.Constants;
|
||||
import tschipp.carryon.common.scripting.ScriptReloadListener;
|
||||
|
||||
public class IdentifiableScriptReloadListener extends ScriptReloadListener implements IdentifiableResourceReloadListener
|
||||
{
|
||||
@Override
|
||||
public ResourceLocation getFabricId()
|
||||
{
|
||||
return new ResourceLocation(Constants.MOD_ID, "carryon_scripts");
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,9 @@
|
|||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
"ItemInHandRendererMixin",
|
||||
"LevelRendererMixin",
|
||||
"ScreenMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@
|
|||
"entrypoints": {
|
||||
"main": [
|
||||
"tschipp.carryon.CarryOnFabricMod"
|
||||
],
|
||||
"client": [
|
||||
"tschipp.carryon.CarryOnFabricClientMod"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@ buildscript {
|
|||
repositories {
|
||||
maven { url = 'https://maven.minecraftforge.net' }
|
||||
maven { url = 'https://repo.spongepowered.org/repository/maven-public/' }
|
||||
maven { url = 'https://maven.parchmentmc.org' }
|
||||
mavenCentral()
|
||||
}
|
||||
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.+'
|
||||
}
|
||||
}
|
||||
apply plugin: 'java'
|
||||
|
|
@ -14,8 +16,9 @@ apply plugin: 'net.minecraftforge.gradle'
|
|||
apply plugin: 'eclipse'
|
||||
apply plugin: 'org.spongepowered.mixin'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'org.parchmentmc.librarian.forgegradle'
|
||||
|
||||
archivesBaseName = "${mod_name}-forge-${minecraft_version}"
|
||||
archivesBaseName = "${mod_id}-forge-${minecraft_version}"
|
||||
|
||||
mixin {
|
||||
add sourceSets.main, "${mod_id}.refmap.json"
|
||||
|
|
@ -25,7 +28,7 @@ mixin {
|
|||
}
|
||||
|
||||
minecraft {
|
||||
mappings channel: 'official', version: minecraft_version
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -1,11 +1,20 @@
|
|||
package tschipp.carryon;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
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.NetworkRegistry;
|
||||
import net.minecraftforge.network.simple.SimpleChannel;
|
||||
import tschipp.carryon.config.forge.ConfigLoaderImpl;
|
||||
|
||||
@Mod(Constants.MOD_ID)
|
||||
@EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||
public class CarryOnForge {
|
||||
|
||||
|
||||
public static SimpleChannel network;
|
||||
|
||||
public CarryOnForge() {
|
||||
|
||||
// This method is invoked by the Forge mod loader when it is ready
|
||||
|
|
@ -13,9 +22,19 @@ public class CarryOnForge {
|
|||
// project.
|
||||
|
||||
// Use Forge to bootstrap the Common mod.
|
||||
Constants.LOG.info("Hello Forge world!");
|
||||
CarryOnCommon.registerConfig();
|
||||
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
|
||||
|
||||
ConfigLoaderImpl.initialize();
|
||||
}
|
||||
|
||||
private void setup(final FMLCommonSetupEvent event)
|
||||
{
|
||||
network = NetworkRegistry.newSimpleChannel(new ResourceLocation(Constants.MOD_ID, "carryonpackets"), () -> "1.0", "1.0"::equals, "1.0"::equals);
|
||||
|
||||
CarryOnCommon.registerServerPackets();
|
||||
CarryOnCommon.registerClientPackets();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,16 +2,25 @@ package tschipp.carryon.events;
|
|||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.client.event.RenderHandEvent;
|
||||
import net.minecraftforge.client.event.RenderLevelStageEvent;
|
||||
import net.minecraftforge.client.event.RenderLevelStageEvent.Stage;
|
||||
import net.minecraftforge.client.event.ScreenEvent;
|
||||
import net.minecraftforge.event.TickEvent.ClientTickEvent;
|
||||
import net.minecraftforge.event.TickEvent.Phase;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import tschipp.carryon.CarryOnCommonClient;
|
||||
import tschipp.carryon.Constants;
|
||||
import tschipp.carryon.client.render.CarriedObjectRender;
|
||||
import tschipp.carryon.client.render.CarryRenderHelper;
|
||||
import tschipp.carryon.common.carry.CarryOnData;
|
||||
import tschipp.carryon.common.carry.CarryOnDataManager;
|
||||
|
||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Constants.MOD_ID, value = Dist.CLIENT)
|
||||
public class ClientEvents {
|
||||
|
|
@ -29,4 +38,47 @@ public class ClientEvents {
|
|||
if(CarriedObjectRender.drawFirstPerson(player, buffer, matrix, light, partialTicks) && CarryRenderHelper.getPerspective() == 0)
|
||||
event.setCanceled(true);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@SubscribeEvent
|
||||
public static void onRenderLevel(RenderLevelStageEvent event)
|
||||
{
|
||||
if(event.getStage() == Stage.AFTER_PARTICLES)
|
||||
CarriedObjectRender.drawThirdPerson(event.getPartialTick(), event.getPoseStack());
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@SubscribeEvent
|
||||
public static void onGuiInit(ScreenEvent.Init.Pre event)
|
||||
{
|
||||
if (event.getScreen() != null)
|
||||
{
|
||||
boolean inventory = event.getScreen() instanceof AbstractContainerScreen;
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
Player player = mc.player;
|
||||
|
||||
if (player != null && inventory)
|
||||
{
|
||||
CarryOnData carry = CarryOnDataManager.getCarryData(player);
|
||||
if (carry.isCarrying())
|
||||
{
|
||||
mc.player.closeContainer();
|
||||
mc.screen = null;
|
||||
mc.mouseHandler.grabMouse();
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@SubscribeEvent
|
||||
public static void onClientTick(ClientTickEvent event)
|
||||
{
|
||||
if(event.phase == Phase.END)
|
||||
{
|
||||
CarryOnCommonClient.checkForKeybinds();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,19 +8,28 @@ import net.minecraft.world.entity.player.Player;
|
|||
import net.minecraft.world.level.Level;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.util.BlockSnapshot;
|
||||
import net.minecraftforge.event.AddReloadListenerEvent;
|
||||
import net.minecraftforge.event.OnDatapackSyncEvent;
|
||||
import net.minecraftforge.event.RegisterCommandsEvent;
|
||||
import net.minecraftforge.event.TickEvent.Phase;
|
||||
import net.minecraftforge.event.TickEvent.ServerTickEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraftforge.event.level.BlockEvent.EntityPlaceEvent;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.eventbus.api.Event.Result;
|
||||
import net.minecraftforge.eventbus.api.EventPriority;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.InterModComms;
|
||||
import net.minecraftforge.fml.InterModComms.IMCMessage;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent;
|
||||
import tschipp.carryon.CarryOnCommon;
|
||||
import tschipp.carryon.Constants;
|
||||
import tschipp.carryon.common.carry.CarryOnData;
|
||||
import tschipp.carryon.common.carry.*;
|
||||
import tschipp.carryon.common.carry.CarryOnData.CarryType;
|
||||
import tschipp.carryon.common.carry.CarryOnDataManager;
|
||||
import tschipp.carryon.common.carry.PickupHandler;
|
||||
import tschipp.carryon.common.carry.PlacementHandler;
|
||||
import tschipp.carryon.common.scripting.ScriptReloadListener;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Constants.MOD_ID)
|
||||
public class CommonEvents
|
||||
|
|
@ -95,10 +104,86 @@ public class CommonEvents
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if(carry.isCarrying(CarryType.ENTITY))
|
||||
else if(carry.isCarrying(CarryType.ENTITY) || carry.isCarrying(CarryType.PLAYER))
|
||||
{
|
||||
//TODO: Stacking
|
||||
PlacementHandler.tryStackEntity((ServerPlayer)player, target);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onRegisterCommands(RegisterCommandsEvent event)
|
||||
{
|
||||
CarryOnCommon.registerCommands(event.getDispatcher());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOW)
|
||||
public void serverLoad(FMLDedicatedServerSetupEvent event)
|
||||
{
|
||||
Stream<IMCMessage> messages = InterModComms.getMessages(Constants.MOD_ID);
|
||||
|
||||
messages.forEach(msg -> {
|
||||
|
||||
String method = msg.method();
|
||||
Object obj = msg.messageSupplier().get();
|
||||
|
||||
if (!(obj instanceof String str))
|
||||
return;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case "blacklistBlock":
|
||||
ListHandler.addForbiddenTiles(str);
|
||||
break;
|
||||
case "blacklistEntity":
|
||||
ListHandler.addForbiddenEntities(str);
|
||||
break;
|
||||
case "whitelistBlock":
|
||||
ListHandler.addAllowedTiles(str);
|
||||
break;
|
||||
case "whitelistEntity":
|
||||
ListHandler.addAllowedEntities(str);
|
||||
break;
|
||||
case "blacklistStacking":
|
||||
ListHandler.addForbiddenStacking(str);
|
||||
break;
|
||||
case "whitelistStacking":
|
||||
ListHandler.addAllowedStacking(str);
|
||||
break;
|
||||
//TODO
|
||||
// case "addModelOverride":
|
||||
// ModelOverridesHandler.parseOverride(str, 0);
|
||||
// break;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onDatapackRegister(AddReloadListenerEvent event)
|
||||
{
|
||||
event.addListener(new ScriptReloadListener());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onDatapackSync(OnDatapackSyncEvent event)
|
||||
{
|
||||
ServerPlayer player = event.getPlayer();
|
||||
if(player == null)
|
||||
{
|
||||
for(ServerPlayer p : event.getPlayerList().getPlayers())
|
||||
ScriptReloadListener.syncScriptsWithClient(p);
|
||||
}
|
||||
else
|
||||
ScriptReloadListener.syncScriptsWithClient(player);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onServerTick(ServerTickEvent event)
|
||||
{
|
||||
if(event.phase == Phase.END)
|
||||
for(ServerPlayer player : event.getServer().getPlayerList().getPlayers())
|
||||
PickupHandler.onCarryTick(player);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package tschipp.carryon.events;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
||||
import tschipp.carryon.Constants;
|
||||
import tschipp.carryon.client.keybinds.CarryOnKeybinds;
|
||||
|
||||
@Mod.EventBusSubscriber(bus = Bus.MOD, modid = Constants.MOD_ID, value = Dist.CLIENT)
|
||||
public class ModClientEvents
|
||||
{
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@SubscribeEvent
|
||||
public static void registerKeybinds(RegisterKeyMappingsEvent event)
|
||||
{
|
||||
CarryOnKeybinds.registerKeybinds(event::register);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,25 @@
|
|||
package tschipp.carryon.platform;
|
||||
|
||||
import tschipp.carryon.config.BuiltConfig;
|
||||
import tschipp.carryon.config.forge.ConfigLoaderImpl;
|
||||
import tschipp.carryon.platform.services.IPlatformHelper;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.network.NetworkDirection;
|
||||
import net.minecraftforge.network.NetworkEvent.Context;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import tschipp.carryon.CarryOnForge;
|
||||
import tschipp.carryon.client.CarryOnClient;
|
||||
import tschipp.carryon.config.BuiltConfig;
|
||||
import tschipp.carryon.config.forge.ConfigLoaderImpl;
|
||||
import tschipp.carryon.networking.PacketBase;
|
||||
import tschipp.carryon.platform.services.IPlatformHelper;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ForgePlatformHelper implements IPlatformHelper {
|
||||
|
||||
|
|
@ -30,4 +45,49 @@ public class ForgePlatformHelper implements IPlatformHelper {
|
|||
public void registerConfig(BuiltConfig cfg) {
|
||||
ConfigLoaderImpl.registerConfig(cfg);
|
||||
}
|
||||
|
||||
@Override
|
||||
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)
|
||||
{
|
||||
BiConsumer<T, Supplier<Context>> serverHandler = (packet, ctx) -> {
|
||||
if(ctx.get().getDirection().getReceptionSide().isServer())
|
||||
{
|
||||
ctx.get().setPacketHandled(true);
|
||||
ctx.get().enqueueWork(() -> {
|
||||
handler.accept(packet, ctx.get().getSender());
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
CarryOnForge.network.registerMessage(numericalId, clazz, writer, reader, serverHandler, Optional.of(NetworkDirection.PLAY_TO_SERVER));
|
||||
}
|
||||
|
||||
@Override
|
||||
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)
|
||||
{
|
||||
BiConsumer<T, Supplier<Context>> clientHandler = (packet, ctx) -> {
|
||||
if(ctx.get().getDirection().getReceptionSide().isClient())
|
||||
{
|
||||
ctx.get().setPacketHandled(true);
|
||||
ctx.get().enqueueWork(() -> {
|
||||
handler.accept(packet, CarryOnClient.getPlayer());
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
CarryOnForge.network.registerMessage(numericalId, clazz, writer, reader, clientHandler, Optional.of(NetworkDirection.PLAY_TO_CLIENT));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void sendPacketToServer(ResourceLocation id, PacketBase packet)
|
||||
{
|
||||
CarryOnForge.network.sendToServer(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacketToPlayer(ResourceLocation id, PacketBase packet, ServerPlayer player)
|
||||
{
|
||||
CarryOnForge.network.send(PacketDistributor.PLAYER.with(() -> player), packet);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ group=tschipp.carryon
|
|||
|
||||
# Common
|
||||
minecraft_version=1.19.2
|
||||
parchment_mappings=2022.09.18
|
||||
common_runs_enabled=false
|
||||
common_client_run_name=Common Client
|
||||
common_server_run_name=Common Server
|
||||
|
||||
# Forge
|
||||
forge_version=43.1.30
|
||||
parchment_mappings=2022.11.20-1.19.2
|
||||
//forge_ats_enabled=true
|
||||
|
||||
# Fabric
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import net.minecraftforge.registries.ForgeRegistries;
|
|||
public class ScriptParseHelper
|
||||
{
|
||||
|
||||
|
||||
|
||||
public static boolean matches(double number, String cond)
|
||||
{
|
||||
if (cond == null || cond.isEmpty())
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user